provider/ns1: Add notify list resource (#12373)
* Allow for local development with ns1 provider. * Adds first implementation of ns1 notification list resource. * NS1 record.use_client_subnet defaults to true, and added test for field. * Adds more test cases for monitoring jobs. * Adds webhook/datafeed notifier types and acctests for notifylists. * Adds docs for notifylists resource. * Updates ns1-go rest client via govendor * Fix typos in record docs
This commit is contained in:
parent
120e3af178
commit
ce633f2321
|
@ -1,6 +1,7 @@
|
|||
package ns1
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"net/http"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
|
@ -19,6 +20,18 @@ func Provider() terraform.ResourceProvider {
|
|||
DefaultFunc: schema.EnvDefaultFunc("NS1_APIKEY", nil),
|
||||
Description: descriptions["api_key"],
|
||||
},
|
||||
"endpoint": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
DefaultFunc: schema.EnvDefaultFunc("NS1_ENDPOINT", nil),
|
||||
Description: descriptions["endpoint"],
|
||||
},
|
||||
"ignore_ssl": &schema.Schema{
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
DefaultFunc: schema.EnvDefaultFunc("NS1_IGNORE_SSL", nil),
|
||||
Description: descriptions["ignore_ssl"],
|
||||
},
|
||||
},
|
||||
ResourcesMap: map[string]*schema.Resource{
|
||||
"ns1_zone": zoneResource(),
|
||||
|
@ -26,6 +39,7 @@ func Provider() terraform.ResourceProvider {
|
|||
"ns1_datasource": dataSourceResource(),
|
||||
"ns1_datafeed": dataFeedResource(),
|
||||
"ns1_monitoringjob": monitoringJobResource(),
|
||||
"ns1_notifylist": notifyListResource(),
|
||||
"ns1_user": userResource(),
|
||||
"ns1_apikey": apikeyResource(),
|
||||
"ns1_team": teamResource(),
|
||||
|
@ -36,7 +50,19 @@ func Provider() terraform.ResourceProvider {
|
|||
|
||||
func ns1Configure(d *schema.ResourceData) (interface{}, error) {
|
||||
httpClient := &http.Client{}
|
||||
n := ns1.NewClient(httpClient, ns1.SetAPIKey(d.Get("apikey").(string)))
|
||||
decos := []func(*ns1.Client){}
|
||||
decos = append(decos, ns1.SetAPIKey(d.Get("apikey").(string)))
|
||||
if v, ok := d.GetOk("endpoint"); ok {
|
||||
decos = append(decos, ns1.SetEndpoint(v.(string)))
|
||||
}
|
||||
if _, ok := d.GetOk("ignore_ssl"); ok {
|
||||
tr := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
}
|
||||
httpClient.Transport = tr
|
||||
}
|
||||
|
||||
n := ns1.NewClient(httpClient, decos...)
|
||||
n.RateLimitStrategySleep()
|
||||
return n, nil
|
||||
}
|
||||
|
|
|
@ -166,6 +166,7 @@ func monitoringJobToResourceData(d *schema.ResourceData, r *monitor.Job) error {
|
|||
m["key"] = r.Key
|
||||
rules[i] = m
|
||||
}
|
||||
d.Set("rules", rules)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -31,8 +31,11 @@ func TestAccMonitoringJob_basic(t *testing.T) {
|
|||
testAccCheckMonitoringJobRapidRecheck(&mj, false),
|
||||
testAccCheckMonitoringJobPolicy(&mj, "quorum"),
|
||||
testAccCheckMonitoringJobConfigSend(&mj, "HEAD / HTTP/1.0\r\n\r\n"),
|
||||
testAccCheckMonitoringJobConfigPort(&mj, 80),
|
||||
testAccCheckMonitoringJobConfigHost(&mj, "1.1.1.1"),
|
||||
testAccCheckMonitoringJobConfigPort(&mj, 443),
|
||||
testAccCheckMonitoringJobConfigHost(&mj, "1.2.3.4"),
|
||||
testAccCheckMonitoringJobRuleValue(&mj, "200 OK"),
|
||||
testAccCheckMonitoringJobRuleComparison(&mj, "contains"),
|
||||
testAccCheckMonitoringJobRuleKey(&mj, "output"),
|
||||
),
|
||||
},
|
||||
},
|
||||
|
@ -58,8 +61,11 @@ func TestAccMonitoringJob_updated(t *testing.T) {
|
|||
testAccCheckMonitoringJobRapidRecheck(&mj, false),
|
||||
testAccCheckMonitoringJobPolicy(&mj, "quorum"),
|
||||
testAccCheckMonitoringJobConfigSend(&mj, "HEAD / HTTP/1.0\r\n\r\n"),
|
||||
testAccCheckMonitoringJobConfigPort(&mj, 80),
|
||||
testAccCheckMonitoringJobConfigHost(&mj, "1.1.1.1"),
|
||||
testAccCheckMonitoringJobConfigPort(&mj, 443),
|
||||
testAccCheckMonitoringJobConfigHost(&mj, "1.2.3.4"),
|
||||
testAccCheckMonitoringJobRuleValue(&mj, "200 OK"),
|
||||
testAccCheckMonitoringJobRuleComparison(&mj, "contains"),
|
||||
testAccCheckMonitoringJobRuleKey(&mj, "output"),
|
||||
),
|
||||
},
|
||||
resource.TestStep{
|
||||
|
@ -76,6 +82,9 @@ func TestAccMonitoringJob_updated(t *testing.T) {
|
|||
testAccCheckMonitoringJobConfigSend(&mj, "HEAD / HTTP/1.0\r\n\r\n"),
|
||||
testAccCheckMonitoringJobConfigPort(&mj, 443),
|
||||
testAccCheckMonitoringJobConfigHost(&mj, "1.1.1.1"),
|
||||
testAccCheckMonitoringJobRuleValue(&mj, "200"),
|
||||
testAccCheckMonitoringJobRuleComparison(&mj, "<="),
|
||||
testAccCheckMonitoringJobRuleKey(&mj, "connect"),
|
||||
),
|
||||
},
|
||||
},
|
||||
|
@ -242,6 +251,33 @@ func testAccCheckMonitoringJobConfigHost(mj *monitor.Job, expected string) resou
|
|||
}
|
||||
}
|
||||
|
||||
func testAccCheckMonitoringJobRuleValue(mj *monitor.Job, expected string) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
if mj.Rules[0].Value.(string) != expected {
|
||||
return fmt.Errorf("Rules[0].Value: got: %#v want: %#v", mj.Rules[0].Value.(string), expected)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccCheckMonitoringJobRuleComparison(mj *monitor.Job, expected string) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
if mj.Rules[0].Comparison != expected {
|
||||
return fmt.Errorf("Rules[0].Comparison: got: %#v want: %#v", mj.Rules[0].Comparison, expected)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccCheckMonitoringJobRuleKey(mj *monitor.Job, expected string) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
if mj.Rules[0].Key != expected {
|
||||
return fmt.Errorf("Rules[0].Key: got: %#v want: %#v", mj.Rules[0].Key, expected)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
const testAccMonitoringJobBasic = `
|
||||
resource "ns1_monitoringjob" "it" {
|
||||
job_type = "tcp"
|
||||
|
@ -250,10 +286,16 @@ resource "ns1_monitoringjob" "it" {
|
|||
regions = ["lga"]
|
||||
frequency = 60
|
||||
|
||||
config {
|
||||
config = {
|
||||
ssl = "1",
|
||||
send = "HEAD / HTTP/1.0\r\n\r\n"
|
||||
port = 80
|
||||
host = "1.1.1.1"
|
||||
port = 443
|
||||
host = "1.2.3.4"
|
||||
}
|
||||
rules = {
|
||||
value = "200 OK"
|
||||
comparison = "contains"
|
||||
key = "output"
|
||||
}
|
||||
}
|
||||
`
|
||||
|
@ -269,10 +311,16 @@ resource "ns1_monitoringjob" "it" {
|
|||
rapid_recheck = true
|
||||
policy = "all"
|
||||
|
||||
config {
|
||||
config = {
|
||||
ssl = "1",
|
||||
send = "HEAD / HTTP/1.0\r\n\r\n"
|
||||
port = 443
|
||||
host = "1.1.1.1"
|
||||
}
|
||||
rules = {
|
||||
value = 200
|
||||
comparison = "<="
|
||||
key = "connect"
|
||||
}
|
||||
}
|
||||
`
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
package ns1
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
|
||||
ns1 "gopkg.in/ns1/ns1-go.v2/rest"
|
||||
"gopkg.in/ns1/ns1-go.v2/rest/model/monitor"
|
||||
)
|
||||
|
||||
func notifyListResource() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"id": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"name": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
"notifications": &schema.Schema{
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"type": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
"config": &schema.Schema{
|
||||
Type: schema.TypeMap,
|
||||
Required: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Create: NotifyListCreate,
|
||||
Read: NotifyListRead,
|
||||
Update: NotifyListUpdate,
|
||||
Delete: NotifyListDelete,
|
||||
}
|
||||
}
|
||||
|
||||
func notifyListToResourceData(d *schema.ResourceData, nl *monitor.NotifyList) error {
|
||||
d.SetId(nl.ID)
|
||||
d.Set("name", nl.Name)
|
||||
|
||||
if len(nl.Notifications) > 0 {
|
||||
notifications := make([]map[string]interface{}, len(nl.Notifications))
|
||||
for i, n := range nl.Notifications {
|
||||
ni := make(map[string]interface{})
|
||||
ni["type"] = n.Type
|
||||
if n.Config != nil {
|
||||
ni["config"] = n.Config
|
||||
}
|
||||
notifications[i] = ni
|
||||
}
|
||||
d.Set("notifications", notifications)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceDataToNotifyList(nl *monitor.NotifyList, d *schema.ResourceData) error {
|
||||
nl.ID = d.Id()
|
||||
|
||||
if rawNotifications := d.Get("notifications").([]interface{}); len(rawNotifications) > 0 {
|
||||
ns := make([]*monitor.Notification, len(rawNotifications))
|
||||
for i, notificationRaw := range rawNotifications {
|
||||
ni := notificationRaw.(map[string]interface{})
|
||||
config := ni["config"].(map[string]interface{})
|
||||
|
||||
switch ni["type"].(string) {
|
||||
case "webhook":
|
||||
ns[i] = monitor.NewWebNotification(config["url"].(string))
|
||||
case "email":
|
||||
ns[i] = monitor.NewEmailNotification(config["email"].(string))
|
||||
case "datafeed":
|
||||
ns[i] = monitor.NewFeedNotification(config["sourceid"].(string))
|
||||
}
|
||||
}
|
||||
nl.Notifications = ns
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NotifyListCreate creates an ns1 notifylist
|
||||
func NotifyListCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*ns1.Client)
|
||||
nl := monitor.NewNotifyList(d.Get("name").(string))
|
||||
|
||||
if err := resourceDataToNotifyList(nl, d); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := client.Notifications.Create(nl); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return notifyListToResourceData(d, nl)
|
||||
}
|
||||
|
||||
// NotifyListRead fetches info for the given notifylist from ns1
|
||||
func NotifyListRead(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*ns1.Client)
|
||||
|
||||
nl, _, err := client.Notifications.Get(d.Id())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return notifyListToResourceData(d, nl)
|
||||
}
|
||||
|
||||
// NotifyListDelete deletes the given notifylist from ns1
|
||||
func NotifyListDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*ns1.Client)
|
||||
|
||||
_, err := client.Notifications.Delete(d.Id())
|
||||
d.SetId("")
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// NotifyListUpdate updates the notifylist with given parameters
|
||||
func NotifyListUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*ns1.Client)
|
||||
|
||||
nl := monitor.NewNotifyList(d.Get("name").(string))
|
||||
|
||||
if err := resourceDataToNotifyList(nl, d); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := client.Notifications.Update(nl); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return notifyListToResourceData(d, nl)
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
package ns1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
|
||||
ns1 "gopkg.in/ns1/ns1-go.v2/rest"
|
||||
"gopkg.in/ns1/ns1-go.v2/rest/model/monitor"
|
||||
)
|
||||
|
||||
func TestAccNotifyList_basic(t *testing.T) {
|
||||
var nl monitor.NotifyList
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckNotifyListDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccNotifyListBasic,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckNotifyListExists("ns1_notifylist.test", &nl),
|
||||
testAccCheckNotifyListName(&nl, "terraform test"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccNotifyList_updated(t *testing.T) {
|
||||
var nl monitor.NotifyList
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckNotifyListDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccNotifyListBasic,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckNotifyListExists("ns1_notifylist.test", &nl),
|
||||
testAccCheckNotifyListName(&nl, "terraform test"),
|
||||
),
|
||||
},
|
||||
resource.TestStep{
|
||||
Config: testAccNotifyListUpdated,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckNotifyListExists("ns1_notifylist.test", &nl),
|
||||
testAccCheckNotifyListName(&nl, "terraform test"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccCheckNotifyListState(key, value string) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
rs, ok := s.RootModule().Resources["ns1_notifylist.test"]
|
||||
if !ok {
|
||||
return fmt.Errorf("Not found: %s", "ns1_notifylist.test")
|
||||
}
|
||||
|
||||
if rs.Primary.ID == "" {
|
||||
return fmt.Errorf("No ID is set")
|
||||
}
|
||||
|
||||
p := rs.Primary
|
||||
if p.Attributes[key] != value {
|
||||
return fmt.Errorf(
|
||||
"%s != %s (actual: %s)", key, value, p.Attributes[key])
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccCheckNotifyListExists(n string, nl *monitor.NotifyList) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
rs, ok := s.RootModule().Resources[n]
|
||||
|
||||
if !ok {
|
||||
return fmt.Errorf("Resource not found: %v", n)
|
||||
}
|
||||
|
||||
id := rs.Primary.ID
|
||||
if id == "" {
|
||||
return fmt.Errorf("ID is not set")
|
||||
}
|
||||
|
||||
client := testAccProvider.Meta().(*ns1.Client)
|
||||
|
||||
foundNl, _, err := client.Notifications.Get(id)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if foundNl.ID != id {
|
||||
return fmt.Errorf("Notify List not found want: %#v, got %#v", id, foundNl)
|
||||
}
|
||||
|
||||
*nl = *foundNl
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccCheckNotifyListDestroy(s *terraform.State) error {
|
||||
client := testAccProvider.Meta().(*ns1.Client)
|
||||
|
||||
for _, rs := range s.RootModule().Resources {
|
||||
if rs.Type != "ns1_notifylist" {
|
||||
continue
|
||||
}
|
||||
|
||||
nl, _, err := client.Notifications.Get(rs.Primary.Attributes["id"])
|
||||
|
||||
if err == nil {
|
||||
return fmt.Errorf("Notify List still exists %#v: %#v", err, nl)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func testAccCheckNotifyListName(nl *monitor.NotifyList, expected string) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
if nl.Name != expected {
|
||||
return fmt.Errorf("Name: got: %#v want: %#v", nl.Name, expected)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
const testAccNotifyListBasic = `
|
||||
resource "ns1_notifylist" "test" {
|
||||
name = "terraform test"
|
||||
notifications = {
|
||||
type = "webhook"
|
||||
config = {
|
||||
url = "http://localhost:9090"
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const testAccNotifyListUpdated = `
|
||||
resource "ns1_notifylist" "test" {
|
||||
name = "terraform test"
|
||||
notifications = {
|
||||
type = "webhook"
|
||||
config = {
|
||||
url = "http://localhost:9091"
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
|
@ -69,7 +69,7 @@ func recordResource() *schema.Resource {
|
|||
"use_client_subnet": &schema.Schema{
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Default: false,
|
||||
Default: true,
|
||||
},
|
||||
"answers": &schema.Schema{
|
||||
Type: schema.TypeSet,
|
||||
|
@ -264,10 +264,8 @@ func resourceDataToRecord(r *dns.Record, d *schema.ResourceData) error {
|
|||
// if v, ok := d.GetOk("meta"); ok {
|
||||
// metaDynamicToStruct(r.Meta, v)
|
||||
// }
|
||||
if v, ok := d.GetOk("use_client_subnet"); ok {
|
||||
copy := v.(bool)
|
||||
r.UseClientSubnet = ©
|
||||
}
|
||||
useClientSubnet := d.Get("use_client_subnet").(bool)
|
||||
r.UseClientSubnet = &useClientSubnet
|
||||
|
||||
if rawFilters := d.Get("filters").([]interface{}); len(rawFilters) > 0 {
|
||||
f := make([]*filter.Filter, len(rawFilters))
|
||||
|
|
|
@ -26,6 +26,7 @@ func TestAccRecord_basic(t *testing.T) {
|
|||
testAccCheckRecordExists("ns1_record.it", &record),
|
||||
testAccCheckRecordDomain(&record, "test.terraform-record-test.io"),
|
||||
testAccCheckRecordTTL(&record, 60),
|
||||
testAccCheckRecordUseClientSubnet(&record, true),
|
||||
testAccCheckRecordRegionName(&record, []string{"cal"}),
|
||||
// testAccCheckRecordAnswerMetaWeight(&record, 10),
|
||||
testAccCheckRecordAnswerRdata(&record, "test1.terraform-record-test.io"),
|
||||
|
@ -48,6 +49,7 @@ func TestAccRecord_updated(t *testing.T) {
|
|||
testAccCheckRecordExists("ns1_record.it", &record),
|
||||
testAccCheckRecordDomain(&record, "test.terraform-record-test.io"),
|
||||
testAccCheckRecordTTL(&record, 60),
|
||||
testAccCheckRecordUseClientSubnet(&record, true),
|
||||
testAccCheckRecordRegionName(&record, []string{"cal"}),
|
||||
// testAccCheckRecordAnswerMetaWeight(&record, 10),
|
||||
testAccCheckRecordAnswerRdata(&record, "test1.terraform-record-test.io"),
|
||||
|
@ -59,6 +61,7 @@ func TestAccRecord_updated(t *testing.T) {
|
|||
testAccCheckRecordExists("ns1_record.it", &record),
|
||||
testAccCheckRecordDomain(&record, "test.terraform-record-test.io"),
|
||||
testAccCheckRecordTTL(&record, 120),
|
||||
testAccCheckRecordUseClientSubnet(&record, false),
|
||||
testAccCheckRecordRegionName(&record, []string{"ny", "wa"}),
|
||||
// testAccCheckRecordAnswerMetaWeight(&record, 5),
|
||||
testAccCheckRecordAnswerRdata(&record, "test2.terraform-record-test.io"),
|
||||
|
@ -143,6 +146,15 @@ func testAccCheckRecordTTL(r *dns.Record, expected int) resource.TestCheckFunc {
|
|||
}
|
||||
}
|
||||
|
||||
func testAccCheckRecordUseClientSubnet(r *dns.Record, expected bool) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
if *r.UseClientSubnet != expected {
|
||||
return fmt.Errorf("UseClientSubnet: got: %#v want: %#v", *r.UseClientSubnet, expected)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccCheckRecordRegionName(r *dns.Record, expected []string) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
regions := make([]string, len(r.Regions))
|
||||
|
@ -240,7 +252,7 @@ resource "ns1_record" "it" {
|
|||
domain = "test.${ns1_zone.test.zone}"
|
||||
type = "CNAME"
|
||||
ttl = 120
|
||||
use_client_subnet = true
|
||||
use_client_subnet = false
|
||||
|
||||
// meta {
|
||||
// weight = 5
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
.PHONY: all clean
|
||||
|
||||
all: .git/hooks/pre-commit
|
||||
go build .
|
||||
|
||||
clean:
|
||||
rm -f terraform-provider-nsone
|
||||
|
||||
.git/hooks/pre-commit:
|
||||
if [ ! -f .git/hooks/pre-commit ]; then ln -s ../../git-hooks/pre-commit .git/hooks/pre-commit; fi
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
# NS1 Golang SDK
|
||||
|
||||
The golang client for the NS1 API: https://api.nsone.net/
|
||||
The golang client for the NS1 API: https://ns1.com/api/
|
||||
|
||||
# Installing
|
||||
|
||||
|
|
|
@ -137,7 +137,7 @@ func (s *APIKeysService) Delete(keyID string) (*http.Response, error) {
|
|||
|
||||
var (
|
||||
// ErrKeyExists bundles PUT create error.
|
||||
ErrKeyExists = errors.New("Key already exists.")
|
||||
ErrKeyExists = errors.New("key already exists")
|
||||
// ErrKeyMissing bundles GET/POST/DELETE error.
|
||||
ErrKeyMissing = errors.New("Key does not exist.")
|
||||
ErrKeyMissing = errors.New("key does not exist")
|
||||
)
|
||||
|
|
|
@ -136,7 +136,7 @@ func (s *TeamsService) Delete(id string) (*http.Response, error) {
|
|||
|
||||
var (
|
||||
// ErrTeamExists bundles PUT create error.
|
||||
ErrTeamExists = errors.New("Team already exists.")
|
||||
ErrTeamExists = errors.New("team already exists")
|
||||
// ErrTeamMissing bundles GET/POST/DELETE error.
|
||||
ErrTeamMissing = errors.New("Team does not exist.")
|
||||
ErrTeamMissing = errors.New("team does not exist")
|
||||
)
|
||||
|
|
|
@ -136,7 +136,7 @@ func (s *UsersService) Delete(username string) (*http.Response, error) {
|
|||
|
||||
var (
|
||||
// ErrUserExists bundles PUT create error.
|
||||
ErrUserExists = errors.New("User already exists.")
|
||||
ErrUserExists = errors.New("user already exists")
|
||||
// ErrUserMissing bundles GET/POST/DELETE error.
|
||||
ErrUserMissing = errors.New("User does not exist.")
|
||||
ErrUserMissing = errors.New("user does not exist")
|
||||
)
|
||||
|
|
|
@ -271,3 +271,18 @@ func parseRate(resp *http.Response) RateLimit {
|
|||
|
||||
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) }
|
||||
}
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
package rest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestRateLimit(t *testing.T) {
|
||||
r := RateLimit{
|
||||
Limit: 10,
|
||||
Remaining: 10,
|
||||
Period: 10,
|
||||
}
|
||||
if r.WaitTime() != time.Second {
|
||||
t.Error("WaitTime is wrong duration ", r.WaitTime())
|
||||
}
|
||||
if r.PercentageLeft() != 100 {
|
||||
t.Error("PercentLeft != 100")
|
||||
}
|
||||
r.Remaining = 5
|
||||
if r.PercentageLeft() != 50 {
|
||||
t.Error("PercentLeft != 50")
|
||||
}
|
||||
if r.WaitTime() != time.Second {
|
||||
t.Error("WaitTime is wrong duration ", r.WaitTime())
|
||||
}
|
||||
if r.WaitTimeRemaining() != (time.Duration(2) * time.Second) {
|
||||
t.Error("WaitTimeRemaining is wrong duration ", r.WaitTimeRemaining())
|
||||
}
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
package account
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestUnmarshalUsers(t *testing.T) {
|
||||
d := []byte(`[
|
||||
{
|
||||
"permissions": {},
|
||||
"teams": [],
|
||||
"email": "support@nsone.net",
|
||||
"last_access": 1376325771.0,
|
||||
"notify": {
|
||||
"billing": true
|
||||
},
|
||||
"name": "API Example",
|
||||
"username": "apiexample"
|
||||
},
|
||||
{
|
||||
"permissions": {
|
||||
"dns": {
|
||||
"view_zones": true,
|
||||
"manage_zones": true,
|
||||
"zones_allow_by_default": false,
|
||||
"zones_deny": [],
|
||||
"zones_allow": ["example.com"]
|
||||
},
|
||||
"data": {
|
||||
"push_to_datafeeds": false,
|
||||
"manage_datasources": false,
|
||||
"manage_datafeeds": false
|
||||
},
|
||||
"account": {
|
||||
"manage_payment_methods": false,
|
||||
"manage_plan": false,
|
||||
"manage_teams": false,
|
||||
"manage_apikeys": false,
|
||||
"manage_account_settings": false,
|
||||
"view_activity_log": false,
|
||||
"view_invoices": false,
|
||||
"manage_users": false
|
||||
},
|
||||
"monitoring": {
|
||||
"manage_lists": false,
|
||||
"manage_jobs": false,
|
||||
"view_jobs": false
|
||||
}
|
||||
},
|
||||
"teams": ["520422919f782d37dffb588a"],
|
||||
"email": "newuser@example.com",
|
||||
"last_access": null,
|
||||
"notify": {
|
||||
"billing": true
|
||||
},
|
||||
"name": "New User",
|
||||
"username": "newuser"
|
||||
}
|
||||
]
|
||||
`)
|
||||
ul := []*User{}
|
||||
if err := json.Unmarshal(d, &ul); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
assert.Equal(t, len(ul), 2, "Userlist should have 2 users")
|
||||
|
||||
u := ul[0]
|
||||
assert.Equal(t, u.TeamIDs, []string{}, "User should have empty teams")
|
||||
assert.Equal(t, u.Email, "support@nsone.net", "User wrong email")
|
||||
assert.Equal(t, u.LastAccess, 1376325771.0, "User wrong last access")
|
||||
assert.Equal(t, u.Name, "API Example", "User wrong name")
|
||||
assert.Equal(t, u.Username, "apiexample", "User wrong username")
|
||||
assert.Equal(t, u.Notify, NotificationSettings{true}, "User wrong notify")
|
||||
assert.Equal(t, u.Permissions, PermissionsMap{}, "User should have empty permissions")
|
||||
|
||||
u2 := ul[1]
|
||||
assert.Equal(t, u2.TeamIDs, []string{"520422919f782d37dffb588a"}, "User should have empty teams")
|
||||
assert.Equal(t, u2.Email, "newuser@example.com", "User wrong email")
|
||||
assert.Equal(t, u2.LastAccess, 0.0, "User wrong last access")
|
||||
assert.Equal(t, u2.Name, "New User", "User wrong name")
|
||||
assert.Equal(t, u2.Username, "newuser", "User wrong username")
|
||||
assert.Equal(t, u.Notify, NotificationSettings{true}, "User wrong notify")
|
||||
|
||||
permMap := PermissionsMap{
|
||||
DNS: PermissionsDNS{
|
||||
ViewZones: true,
|
||||
ManageZones: true,
|
||||
ZonesAllowByDefault: false,
|
||||
ZonesDeny: []string{},
|
||||
ZonesAllow: []string{"example.com"},
|
||||
},
|
||||
Data: PermissionsData{
|
||||
PushToDatafeeds: false,
|
||||
ManageDatasources: false,
|
||||
ManageDatafeeds: false,
|
||||
},
|
||||
Account: PermissionsAccount{
|
||||
ManagePaymentMethods: false,
|
||||
ManagePlan: false,
|
||||
ManageTeams: false,
|
||||
ManageApikeys: false,
|
||||
ManageAccountSettings: false,
|
||||
ViewActivityLog: false,
|
||||
ViewInvoices: false,
|
||||
ManageUsers: false,
|
||||
},
|
||||
Monitoring: PermissionsMonitoring{
|
||||
ManageLists: false,
|
||||
ManageJobs: false,
|
||||
ViewJobs: false,
|
||||
},
|
||||
}
|
||||
assert.Equal(t, u2.Permissions, permMap, "User wrong permissions")
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
package data_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gopkg.in/ns1/ns1-go.v2/rest/model/data"
|
||||
)
|
||||
|
||||
func ExampleSource() {
|
||||
// Construct an NSONE API data source.
|
||||
source := data.NewSource("my api source", "nsone_v1")
|
||||
fmt.Println(source.ID) // will be empty string
|
||||
fmt.Println(source.Name)
|
||||
fmt.Println(source.Type)
|
||||
// Output:
|
||||
// my api source
|
||||
// nsone_v1
|
||||
}
|
||||
|
||||
func ExampleFeed() {
|
||||
|
||||
// Construct the london data feed.
|
||||
feed := data.NewFeed(
|
||||
"London Feed",
|
||||
data.Config{"label": "London-UK"})
|
||||
fmt.Println(feed.ID) // will be empty string
|
||||
fmt.Println(feed.Name)
|
||||
fmt.Println(feed.Config)
|
||||
// Output:
|
||||
// London Feed
|
||||
// map[label:London-UK]
|
||||
}
|
||||
|
||||
func ExampleMeta() {
|
||||
feedID := "feed_id"
|
||||
|
||||
meta := data.Meta{}
|
||||
meta.Priority = 1
|
||||
meta.Up = data.FeedPtr{FeedID: feedID}
|
||||
fmt.Println(meta.Connections) // will be nil
|
||||
fmt.Println(meta.Priority)
|
||||
fmt.Println(meta.Up)
|
||||
// Output:
|
||||
// <nil>
|
||||
// 1
|
||||
// {feed_id}
|
||||
}
|
||||
|
||||
func ExampleRegions() {
|
||||
feedPtr := data.FeedPtr{FeedID: "feed_id"}
|
||||
|
||||
regions := data.Regions{}
|
||||
// Set a regions' 'up' metavalue to false('down').
|
||||
regions["some_region"] = data.Region{
|
||||
Meta: data.Meta{Up: false},
|
||||
}
|
||||
// Set a regions' 'connections' metavalue to receive from a feed.
|
||||
regions["other_region"] = data.Region{
|
||||
Meta: data.Meta{Connections: feedPtr},
|
||||
}
|
||||
fmt.Println(regions["some_region"].Meta.Up)
|
||||
fmt.Println(regions["some_region"].Meta.Priority)
|
||||
fmt.Println(regions["other_region"].Meta.Connections)
|
||||
fmt.Println(regions["other_region"].Meta.Priority)
|
||||
// Output:
|
||||
// false
|
||||
// <nil>
|
||||
// {feed_id}
|
||||
// <nil>
|
||||
}
|
|
@ -38,7 +38,7 @@ type Meta struct {
|
|||
// Indicates the "load average".
|
||||
// Values must be positive, and will be rounded to the nearest tenth.
|
||||
// float64 or FeedPtr.
|
||||
LoadAvg interface{} `json:",loadavg,omitempty"`
|
||||
LoadAvg interface{} `json:"loadavg,omitempty"`
|
||||
|
||||
// The Job ID of a Pulsar telemetry gathering job and routing granularities
|
||||
// to associate with.
|
||||
|
|
|
@ -1,141 +0,0 @@
|
|||
package dns_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"gopkg.in/ns1/ns1-go.v2/rest/model/data"
|
||||
"gopkg.in/ns1/ns1-go.v2/rest/model/dns"
|
||||
"gopkg.in/ns1/ns1-go.v2/rest/model/filter"
|
||||
)
|
||||
|
||||
func ExampleZone() {
|
||||
z := dns.NewZone("example.com")
|
||||
|
||||
fmt.Println(z)
|
||||
// Output:
|
||||
// example.com
|
||||
}
|
||||
|
||||
// Example references https://ns1.com/articles/primary-dns-with-ns1
|
||||
func ExamplePrimaryZone() {
|
||||
// Secondary/slave dns server info.
|
||||
secondary := dns.ZoneSecondaryServer{
|
||||
IP: "1.2.3.4",
|
||||
Port: 53,
|
||||
Notify: true,
|
||||
}
|
||||
|
||||
// Construct the primary/master zone.
|
||||
domain := "masterzone.example"
|
||||
|
||||
masterZone := dns.NewZone(domain)
|
||||
masterZone.MakePrimary(secondary)
|
||||
|
||||
b, _ := json.MarshalIndent(masterZone, "", " ")
|
||||
|
||||
fmt.Println(string(b))
|
||||
// Output:
|
||||
// {
|
||||
// "zone": "masterzone.example",
|
||||
// "primary": {
|
||||
// "enabled": true,
|
||||
// "secondaries": [
|
||||
// {
|
||||
// "ip": "1.2.3.4",
|
||||
// "port": 53,
|
||||
// "notify": true
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
func ExampleRecord() {
|
||||
// Construct the A record
|
||||
record := dns.NewRecord("test.com", "a", "A")
|
||||
record.TTL = 300
|
||||
|
||||
// Construct primary answer(higher priority)
|
||||
pAns := dns.NewAv4Answer("1.1.1.1")
|
||||
pAns.Meta.Priority = 1
|
||||
pAns.Meta.Up = data.FeedPtr{FeedID: "feed1_id"}
|
||||
|
||||
// Construct secondary answer(lower priority)
|
||||
sAns := dns.NewAv4Answer("2.2.2.2")
|
||||
sAns.Meta.Priority = 2
|
||||
sAns.Meta.Up = data.FeedPtr{FeedID: "feed2_id"}
|
||||
|
||||
// Add both answers to record
|
||||
record.AddAnswer(pAns)
|
||||
record.AddAnswer(sAns)
|
||||
|
||||
// Construct and add both filters to the record(ORDER MATTERS)
|
||||
record.AddFilter(filter.NewUp())
|
||||
record.AddFilter(filter.NewSelFirstN(1))
|
||||
|
||||
// Add region 'test' to record(set as down)
|
||||
record.Regions["test"] = data.Region{Meta: data.Meta{Up: false}}
|
||||
|
||||
fmt.Println(record)
|
||||
fmt.Println(record.TTL)
|
||||
|
||||
fmt.Println("Primary answer:")
|
||||
fmt.Println(record.Answers[0])
|
||||
fmt.Println(record.Answers[0].Meta.Priority)
|
||||
fmt.Println(record.Answers[0].Meta.Up)
|
||||
|
||||
fmt.Println("Secondary answer:")
|
||||
fmt.Println(record.Answers[1])
|
||||
fmt.Println(record.Answers[1].Meta.Priority)
|
||||
fmt.Println(record.Answers[1].Meta.Up)
|
||||
|
||||
fmt.Println("First Filter in Chain:")
|
||||
fmt.Println(record.Filters[0].Type)
|
||||
fmt.Println(record.Filters[0].Config)
|
||||
|
||||
fmt.Println("Second Filter in Chain:")
|
||||
fmt.Println(record.Filters[1].Type)
|
||||
fmt.Println(record.Filters[1].Config)
|
||||
|
||||
fmt.Println("Regions:")
|
||||
fmt.Println(record.Regions["test"].Meta.Up)
|
||||
|
||||
// Output:
|
||||
// a.test.com A
|
||||
// 300
|
||||
// Primary answer:
|
||||
// 1.1.1.1
|
||||
// 1
|
||||
// {feed1_id}
|
||||
// Secondary answer:
|
||||
// 2.2.2.2
|
||||
// 2
|
||||
// {feed2_id}
|
||||
// First Filter in Chain:
|
||||
// up
|
||||
// map[]
|
||||
// Second Filter in Chain:
|
||||
// select_first_n
|
||||
// map[N:1]
|
||||
// Regions:
|
||||
// false
|
||||
}
|
||||
|
||||
func ExampleRecordLink() {
|
||||
// Construct the src record
|
||||
srcRecord := dns.NewRecord("test.com", "a", "A")
|
||||
srcRecord.TTL = 300
|
||||
srcRecord.Meta.Priority = 2
|
||||
|
||||
linkedRecord := dns.NewRecord("test.com", "l", "A")
|
||||
linkedRecord.LinkTo(srcRecord.Domain)
|
||||
fmt.Println(linkedRecord)
|
||||
fmt.Println(linkedRecord.Meta)
|
||||
fmt.Println(linkedRecord.Answers)
|
||||
// Output:
|
||||
// l.test.com A
|
||||
// <nil>
|
||||
// []
|
||||
}
|
|
@ -19,10 +19,10 @@ type Job struct {
|
|||
Config Config `json:"config"`
|
||||
|
||||
// The current status of the monitor.
|
||||
Status map[string]Status `json:"status,omitempty"`
|
||||
Status map[string]*Status `json:"status,omitempty"`
|
||||
|
||||
// Rules for determining failure conditions.
|
||||
Rules []*Rule `json:"rules"`
|
||||
Rules []*Rule `json:"rules,omitempty"`
|
||||
|
||||
// List of regions in which to run the monitor.
|
||||
// eg, ["dal", "sin", "sjc", "lga", "ams"]
|
||||
|
@ -66,7 +66,7 @@ type Job struct {
|
|||
|
||||
// If true, notifications are sent for any regional failure (and failback if desired),
|
||||
// in addition to global state notifications.
|
||||
NotifyRegional bool `json:"notidy_regional"`
|
||||
NotifyRegional bool `json:"notify_regional"`
|
||||
|
||||
// If true, a notification is sent when a job returns to an "up" state.
|
||||
NotifyFailback bool `json:"notify_failback"`
|
||||
|
@ -99,6 +99,15 @@ type Status struct {
|
|||
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"`
|
||||
|
|
|
@ -1,97 +0,0 @@
|
|||
package monitor
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestUnmarshalJobs(t *testing.T) {
|
||||
data := []byte(`[
|
||||
{
|
||||
"id": "52a27d4397d5f07003fdbe7b",
|
||||
"config": {
|
||||
"host": "1.2.3.4"
|
||||
},
|
||||
"status": {
|
||||
"lga": {
|
||||
"since": 1389407609,
|
||||
"status": "up"
|
||||
},
|
||||
"global": {
|
||||
"since": 1389407609,
|
||||
"status": "up"
|
||||
},
|
||||
"sjc": {
|
||||
"since": 1389404014,
|
||||
"status": "up"
|
||||
}
|
||||
},
|
||||
"rules": [
|
||||
{
|
||||
"key": "rtt",
|
||||
"value": 100,
|
||||
"comparison": "<"
|
||||
}
|
||||
],
|
||||
"job_type": "ping",
|
||||
"regions": [
|
||||
"lga",
|
||||
"sjc"
|
||||
],
|
||||
"active": true,
|
||||
"frequency": 60,
|
||||
"policy": "quorum",
|
||||
"region_scope": "fixed"
|
||||
}
|
||||
]`)
|
||||
mjl := []*Job{}
|
||||
if err := json.Unmarshal(data, &mjl); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if len(mjl) != 1 {
|
||||
fmt.Println(mjl)
|
||||
t.Error("Do not have any jobs")
|
||||
}
|
||||
j := mjl[0]
|
||||
if j.ID != "52a27d4397d5f07003fdbe7b" {
|
||||
t.Error("Wrong ID")
|
||||
}
|
||||
conf := j.Config
|
||||
if conf["host"] != "1.2.3.4" {
|
||||
t.Error("Wrong host")
|
||||
}
|
||||
status := j.Status["global"]
|
||||
if status.Since != 1389407609 {
|
||||
t.Error("since has unexpected value")
|
||||
}
|
||||
if status.Status != "up" {
|
||||
t.Error("Status is not up")
|
||||
}
|
||||
r := j.Rules[0]
|
||||
assert.Equal(t, r.Key, "rtt", "RTT rule key is wrong")
|
||||
assert.Equal(t, r.Value.(float64), float64(100), "RTT rule value is wrong")
|
||||
if r.Comparison != "<" {
|
||||
t.Error("RTT rule comparison is wrong")
|
||||
}
|
||||
if j.Type != "ping" {
|
||||
t.Error("Jobtype is wrong")
|
||||
}
|
||||
if j.Regions[0] != "lga" {
|
||||
t.Error("First region is not lga")
|
||||
}
|
||||
if !j.Active {
|
||||
t.Error("Job is not active")
|
||||
}
|
||||
if j.Frequency != 60 {
|
||||
t.Error("Job frequency != 60")
|
||||
}
|
||||
if j.Policy != "quorum" {
|
||||
t.Error("Job policy is not quorum")
|
||||
}
|
||||
if j.RegionScope != "fixed" {
|
||||
t.Error("Job region scope is not fixed")
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ package rest
|
|||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"gopkg.in/ns1/ns1-go.v2/rest/model/monitor"
|
||||
)
|
||||
|
@ -106,3 +107,28 @@ func (s *JobsService) Delete(id string) (*http.Response, error) {
|
|||
|
||||
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
|
||||
}
|
||||
|
|
|
@ -122,7 +122,7 @@ func (s *NotificationsService) Delete(listID string) (*http.Response, error) {
|
|||
|
||||
var (
|
||||
// ErrListExists bundles PUT create error.
|
||||
ErrListExists = errors.New("Notify List already exists.")
|
||||
ErrListExists = errors.New("notify List already exists")
|
||||
// ErrListMissing bundles GET/POST/DELETE error.
|
||||
ErrListMissing = errors.New("Notify List does not exist.")
|
||||
ErrListMissing = errors.New("notify List does not exist")
|
||||
)
|
||||
|
|
|
@ -128,7 +128,7 @@ func (s *RecordsService) Delete(zone string, domain string, t string) (*http.Res
|
|||
|
||||
var (
|
||||
// ErrRecordExists bundles PUT create error.
|
||||
ErrRecordExists = errors.New("Record already exists.")
|
||||
ErrRecordExists = errors.New("record already exists")
|
||||
// ErrRecordMissing bundles GET/POST/DELETE error.
|
||||
ErrRecordMissing = errors.New("Record does not exist.")
|
||||
ErrRecordMissing = errors.New("record does not exist")
|
||||
)
|
||||
|
|
|
@ -138,7 +138,7 @@ func (s *ZonesService) Delete(zone string) (*http.Response, error) {
|
|||
|
||||
var (
|
||||
// ErrZoneExists bundles PUT create error.
|
||||
ErrZoneExists = errors.New("Zone already exists.")
|
||||
ErrZoneExists = errors.New("zone already exists")
|
||||
// ErrZoneMissing bundles GET/POST/DELETE error.
|
||||
ErrZoneMissing = errors.New("Zone does not exist.")
|
||||
ErrZoneMissing = errors.New("zone does not exist")
|
||||
)
|
||||
|
|
|
@ -3270,10 +3270,52 @@
|
|||
"revisionTime": "2017-01-17T13:00:17Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "U0s6Vq/AxUhEEsnORw2DnZ4cw1c=",
|
||||
"checksumSHA1": "IOhjrvLMN5Mw8PeiRF/xAfSxvew=",
|
||||
"path": "gopkg.in/ns1/ns1-go.v2",
|
||||
"revision": "d8d10b7f448291ddbdce48d4594fb1b667014c8b",
|
||||
"revisionTime": "2016-11-05T01:14:08Z"
|
||||
"revision": "49e3a8a0b594e847e01cdac77810ba49f9564ccf",
|
||||
"revisionTime": "2017-03-02T13:56:36Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "t20/HSVruhTb/TVwgc9mpw/oMTA=",
|
||||
"path": "gopkg.in/ns1/ns1-go.v2/rest",
|
||||
"revision": "49e3a8a0b594e847e01cdac77810ba49f9564ccf",
|
||||
"revisionTime": "2017-03-02T13:56:36Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "euh1cYwe0t2erigdvOMueyniPH0=",
|
||||
"path": "gopkg.in/ns1/ns1-go.v2/rest/model",
|
||||
"revision": "49e3a8a0b594e847e01cdac77810ba49f9564ccf",
|
||||
"revisionTime": "2017-03-02T13:56:36Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "tdMxXKsUHn3yZpur14ZNLMVyQJM=",
|
||||
"path": "gopkg.in/ns1/ns1-go.v2/rest/model/account",
|
||||
"revision": "49e3a8a0b594e847e01cdac77810ba49f9564ccf",
|
||||
"revisionTime": "2017-03-02T13:56:36Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "gBVND8veklEQV0gxF3lERV6mSZk=",
|
||||
"path": "gopkg.in/ns1/ns1-go.v2/rest/model/data",
|
||||
"revision": "49e3a8a0b594e847e01cdac77810ba49f9564ccf",
|
||||
"revisionTime": "2017-03-02T13:56:36Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "GbL7ThrBZfKs1lhzguxzscIynac=",
|
||||
"path": "gopkg.in/ns1/ns1-go.v2/rest/model/dns",
|
||||
"revision": "49e3a8a0b594e847e01cdac77810ba49f9564ccf",
|
||||
"revisionTime": "2017-03-02T13:56:36Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "CuurmNep8iMdYFodxRxAeewowsQ=",
|
||||
"path": "gopkg.in/ns1/ns1-go.v2/rest/model/filter",
|
||||
"revision": "49e3a8a0b594e847e01cdac77810ba49f9564ccf",
|
||||
"revisionTime": "2017-03-02T13:56:36Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "B0C8F5th11AHl1fo8k0I8+DvrjE=",
|
||||
"path": "gopkg.in/ns1/ns1-go.v2/rest/model/monitor",
|
||||
"revision": "49e3a8a0b594e847e01cdac77810ba49f9564ccf",
|
||||
"revisionTime": "2017-03-02T13:56:36Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "mkLQOQwQwoUc9Kr9+PaVGrKUzI4=",
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
---
|
||||
layout: "ns1"
|
||||
page_title: "NS1: ns1_notifylist"
|
||||
sidebar_current: "docs-ns1-resource-notifylist"
|
||||
description: |-
|
||||
Provides a NS1 Notify List resource.
|
||||
---
|
||||
|
||||
# ns1\_notifylist
|
||||
|
||||
Provides a NS1 Notify List resource. This can be used to create, modify, and delete notify lists.
|
||||
|
||||
## Example Usage
|
||||
|
||||
```
|
||||
resource "ns1_notifylist" "nl" {
|
||||
name = "my notify list"
|
||||
notifications = {
|
||||
type = "webhook"
|
||||
config = {
|
||||
url = "http://www.mywebhook.com"
|
||||
}
|
||||
}
|
||||
|
||||
notifications = {
|
||||
type = "email"
|
||||
config = {
|
||||
email = "test@test.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Argument Reference
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
* `name` - (Required) The free-form display name for the notify list.
|
||||
* `notifications` - (Optional) A list of notifiers. All notifiers in a notification list will receive notifications whenever an event is send to the list (e.g., when a monitoring job fails). Notifiers are documented below.
|
||||
|
||||
Notify List Notifiers (`notifications`) support the following:
|
||||
|
||||
* `type` - (Required) The type of notifier. Available notifiers are indicated in /notifytypes endpoint.
|
||||
* `config` - (Required) Configuration details for the given notifier type.
|
||||
|
|
@ -24,11 +24,11 @@ resource "ns1_record" "www" {
|
|||
ttl = 60
|
||||
|
||||
answers = {
|
||||
answer = ["sub1.${ns1_zone.tld.zone}"]
|
||||
answer = "sub1.${ns1_zone.tld.zone}"
|
||||
}
|
||||
|
||||
answer = {
|
||||
answer = ["sub2.${ns1_zone.tld.zone}"]
|
||||
answers = {
|
||||
answer = "sub2.${ns1_zone.tld.zone}"
|
||||
}
|
||||
|
||||
filters = {
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
<li<%= sidebar_current("docs-ns1-resource-monitoringjob") %>>
|
||||
<a href="/docs/providers/ns1/r/monitoringjob.html">ns1_monitoringjob</a>
|
||||
</li>
|
||||
<li<%= sidebar_current("docs-ns1-resource-notifylist") %>>
|
||||
<a href="/docs/providers/ns1/r/notifylist.html">ns1_notifylist</a>
|
||||
</li>
|
||||
<li<%= sidebar_current("docs-ns1-resource-datasource") %>>
|
||||
<a href="/docs/providers/ns1/r/datasource.html">ns1_datasource</a>
|
||||
</li>
|
||||
|
|
Loading…
Reference in New Issue