diff --git a/builtin/providers/ns1/provider.go b/builtin/providers/ns1/provider.go index f80f6a471..2f0e38344 100644 --- a/builtin/providers/ns1/provider.go +++ b/builtin/providers/ns1/provider.go @@ -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 } diff --git a/builtin/providers/ns1/resource_monitoringjob.go b/builtin/providers/ns1/resource_monitoringjob.go index bd9f1de5e..65d30501c 100644 --- a/builtin/providers/ns1/resource_monitoringjob.go +++ b/builtin/providers/ns1/resource_monitoringjob.go @@ -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 } diff --git a/builtin/providers/ns1/resource_monitoringjob_test.go b/builtin/providers/ns1/resource_monitoringjob_test.go index a196f61cc..c470e9ffb 100644 --- a/builtin/providers/ns1/resource_monitoringjob_test.go +++ b/builtin/providers/ns1/resource_monitoringjob_test.go @@ -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" + } } ` diff --git a/builtin/providers/ns1/resource_notifylist.go b/builtin/providers/ns1/resource_notifylist.go new file mode 100644 index 000000000..c6448d51f --- /dev/null +++ b/builtin/providers/ns1/resource_notifylist.go @@ -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) +} diff --git a/builtin/providers/ns1/resource_notifylist_test.go b/builtin/providers/ns1/resource_notifylist_test.go new file mode 100644 index 000000000..bd81a7fe1 --- /dev/null +++ b/builtin/providers/ns1/resource_notifylist_test.go @@ -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" + } + } +} +` diff --git a/builtin/providers/ns1/resource_record.go b/builtin/providers/ns1/resource_record.go index b9d035a57..88b1a96c9 100644 --- a/builtin/providers/ns1/resource_record.go +++ b/builtin/providers/ns1/resource_record.go @@ -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)) diff --git a/builtin/providers/ns1/resource_record_test.go b/builtin/providers/ns1/resource_record_test.go index 58c6c7f4f..294e74706 100644 --- a/builtin/providers/ns1/resource_record_test.go +++ b/builtin/providers/ns1/resource_record_test.go @@ -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 diff --git a/vendor/gopkg.in/ns1/ns1-go.v2/Makefile b/vendor/gopkg.in/ns1/ns1-go.v2/Makefile deleted file mode 100644 index 8bab00e51..000000000 --- a/vendor/gopkg.in/ns1/ns1-go.v2/Makefile +++ /dev/null @@ -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 - diff --git a/vendor/gopkg.in/ns1/ns1-go.v2/README.md b/vendor/gopkg.in/ns1/ns1-go.v2/README.md index ec854bca8..0f8d6bd2d 100644 --- a/vendor/gopkg.in/ns1/ns1-go.v2/README.md +++ b/vendor/gopkg.in/ns1/ns1-go.v2/README.md @@ -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 diff --git a/vendor/gopkg.in/ns1/ns1-go.v2/rest/account_apikey.go b/vendor/gopkg.in/ns1/ns1-go.v2/rest/account_apikey.go index 9985c9337..7343a1155 100644 --- a/vendor/gopkg.in/ns1/ns1-go.v2/rest/account_apikey.go +++ b/vendor/gopkg.in/ns1/ns1-go.v2/rest/account_apikey.go @@ -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") ) diff --git a/vendor/gopkg.in/ns1/ns1-go.v2/rest/account_team.go b/vendor/gopkg.in/ns1/ns1-go.v2/rest/account_team.go index 8f49b06e0..b307b412a 100644 --- a/vendor/gopkg.in/ns1/ns1-go.v2/rest/account_team.go +++ b/vendor/gopkg.in/ns1/ns1-go.v2/rest/account_team.go @@ -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") ) diff --git a/vendor/gopkg.in/ns1/ns1-go.v2/rest/account_user.go b/vendor/gopkg.in/ns1/ns1-go.v2/rest/account_user.go index a3d154bb8..2f6699f9a 100644 --- a/vendor/gopkg.in/ns1/ns1-go.v2/rest/account_user.go +++ b/vendor/gopkg.in/ns1/ns1-go.v2/rest/account_user.go @@ -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") ) diff --git a/vendor/gopkg.in/ns1/ns1-go.v2/rest/client.go b/vendor/gopkg.in/ns1/ns1-go.v2/rest/client.go index 866d038ae..ec20e0453 100644 --- a/vendor/gopkg.in/ns1/ns1-go.v2/rest/client.go +++ b/vendor/gopkg.in/ns1/ns1-go.v2/rest/client.go @@ -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) } +} diff --git a/vendor/gopkg.in/ns1/ns1-go.v2/rest/client_test.go b/vendor/gopkg.in/ns1/ns1-go.v2/rest/client_test.go deleted file mode 100644 index 64d1edf06..000000000 --- a/vendor/gopkg.in/ns1/ns1-go.v2/rest/client_test.go +++ /dev/null @@ -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()) - } -} diff --git a/vendor/gopkg.in/ns1/ns1-go.v2/rest/model/account/user_test.go b/vendor/gopkg.in/ns1/ns1-go.v2/rest/model/account/user_test.go deleted file mode 100644 index 374eed38c..000000000 --- a/vendor/gopkg.in/ns1/ns1-go.v2/rest/model/account/user_test.go +++ /dev/null @@ -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") -} diff --git a/vendor/gopkg.in/ns1/ns1-go.v2/rest/model/data/example_test.go b/vendor/gopkg.in/ns1/ns1-go.v2/rest/model/data/example_test.go deleted file mode 100644 index 4d44867b0..000000000 --- a/vendor/gopkg.in/ns1/ns1-go.v2/rest/model/data/example_test.go +++ /dev/null @@ -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: - // - // 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 - // - // {feed_id} - // -} diff --git a/vendor/gopkg.in/ns1/ns1-go.v2/rest/model/data/meta.go b/vendor/gopkg.in/ns1/ns1-go.v2/rest/model/data/meta.go index 1d1a7e335..8638c1c09 100644 --- a/vendor/gopkg.in/ns1/ns1-go.v2/rest/model/data/meta.go +++ b/vendor/gopkg.in/ns1/ns1-go.v2/rest/model/data/meta.go @@ -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. diff --git a/vendor/gopkg.in/ns1/ns1-go.v2/rest/model/dns/example_test.go b/vendor/gopkg.in/ns1/ns1-go.v2/rest/model/dns/example_test.go deleted file mode 100644 index 65c20d9c9..000000000 --- a/vendor/gopkg.in/ns1/ns1-go.v2/rest/model/dns/example_test.go +++ /dev/null @@ -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 - // - // [] -} diff --git a/vendor/gopkg.in/ns1/ns1-go.v2/rest/model/monitor/job.go b/vendor/gopkg.in/ns1/ns1-go.v2/rest/model/monitor/job.go index 6943f9cd4..4856072bf 100644 --- a/vendor/gopkg.in/ns1/ns1-go.v2/rest/model/monitor/job.go +++ b/vendor/gopkg.in/ns1/ns1-go.v2/rest/model/monitor/job.go @@ -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"` diff --git a/vendor/gopkg.in/ns1/ns1-go.v2/rest/model/monitor/job_test.go b/vendor/gopkg.in/ns1/ns1-go.v2/rest/model/monitor/job_test.go deleted file mode 100644 index aab21b656..000000000 --- a/vendor/gopkg.in/ns1/ns1-go.v2/rest/model/monitor/job_test.go +++ /dev/null @@ -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") - } -} diff --git a/vendor/gopkg.in/ns1/ns1-go.v2/rest/monitor_job.go b/vendor/gopkg.in/ns1/ns1-go.v2/rest/monitor_job.go index a58cab114..9ff927ef3 100644 --- a/vendor/gopkg.in/ns1/ns1-go.v2/rest/monitor_job.go +++ b/vendor/gopkg.in/ns1/ns1-go.v2/rest/monitor_job.go @@ -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 +} diff --git a/vendor/gopkg.in/ns1/ns1-go.v2/rest/monitor_notify.go b/vendor/gopkg.in/ns1/ns1-go.v2/rest/monitor_notify.go index e86ce2172..c8fea014b 100644 --- a/vendor/gopkg.in/ns1/ns1-go.v2/rest/monitor_notify.go +++ b/vendor/gopkg.in/ns1/ns1-go.v2/rest/monitor_notify.go @@ -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") ) diff --git a/vendor/gopkg.in/ns1/ns1-go.v2/rest/record.go b/vendor/gopkg.in/ns1/ns1-go.v2/rest/record.go index a3e2e7761..f24dc43f6 100644 --- a/vendor/gopkg.in/ns1/ns1-go.v2/rest/record.go +++ b/vendor/gopkg.in/ns1/ns1-go.v2/rest/record.go @@ -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") ) diff --git a/vendor/gopkg.in/ns1/ns1-go.v2/rest/zone.go b/vendor/gopkg.in/ns1/ns1-go.v2/rest/zone.go index e16aede19..ff21650ac 100644 --- a/vendor/gopkg.in/ns1/ns1-go.v2/rest/zone.go +++ b/vendor/gopkg.in/ns1/ns1-go.v2/rest/zone.go @@ -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") ) diff --git a/vendor/vendor.json b/vendor/vendor.json index d266ac975..d3b3f93c5 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -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=", diff --git a/website/source/docs/providers/ns1/r/notifylist.html.markdown b/website/source/docs/providers/ns1/r/notifylist.html.markdown new file mode 100644 index 000000000..35f6f67e8 --- /dev/null +++ b/website/source/docs/providers/ns1/r/notifylist.html.markdown @@ -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. + diff --git a/website/source/docs/providers/ns1/r/record.html.markdown b/website/source/docs/providers/ns1/r/record.html.markdown index 73b2c02ec..88f84cf40 100644 --- a/website/source/docs/providers/ns1/r/record.html.markdown +++ b/website/source/docs/providers/ns1/r/record.html.markdown @@ -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 = { diff --git a/website/source/layouts/ns1.erb b/website/source/layouts/ns1.erb index 8d1707ae7..b38894d13 100644 --- a/website/source/layouts/ns1.erb +++ b/website/source/layouts/ns1.erb @@ -22,6 +22,9 @@ > ns1_monitoringjob + > + ns1_notifylist + > ns1_datasource