Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## 2.8.1 (Unreleased)
## 2.8.1 (February 12 2026)
ENHANCEMENTS
* Fix datadog and webcheck datafeed params
* Update documentation to contain the default values of the fields

## 2.8.0 (January 15 2026)
Expand Down
2 changes: 1 addition & 1 deletion ns1/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (
)

var (
clientVersion = "2.8.0"
clientVersion = "2.8.1"
providerUserAgent = "tf-ns1" + "/" + clientVersion
defaultRetryMax = 3
)
Expand Down
51 changes: 41 additions & 10 deletions ns1/resource_datafeed.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,33 @@ func dataFeedToResourceData(d *schema.ResourceData, f *data.Feed) {
func resourceDataToDataFeed(d *schema.ResourceData) (feed *data.Feed, e error) {
config := d.Get("config").(map[string]interface{})
if config != nil {
test_id := config["test_id"]
if test_id != nil {
test_id_int, err := strconv.Atoi(test_id.(string))
if testId := config["test_id"]; testId != nil {
intTestId, err := strconv.Atoi(testId.(string))
if err != nil {
return &data.Feed{}, fmt.Errorf("could not convert %v as int %w", test_id, err)
return &data.Feed{}, fmt.Errorf("could not convert test_id = %v as int: %w", testId, err)
}
config["test_id"] = test_id_int
config["test_id"] = intTestId
}
if checkId := config["check_id"]; checkId != nil {
intCheckId, err := strconv.Atoi(checkId.(string))
if err != nil {
return &data.Feed{}, fmt.Errorf("could not convert check_id = %v as int: %w", checkId, err)
}
config["check_id"] = intCheckId
}
if failOnWarning := config["fail_on_warning"]; failOnWarning != nil {
boolFailOnWarning, err := strconv.ParseBool(failOnWarning.(string))
if err != nil {
return &data.Feed{}, fmt.Errorf("could not convert fail_on_warning = %v as bool: %w", failOnWarning, err)
}
config["fail_on_warning"] = boolFailOnWarning
}
if failOnNoData := config["fail_on_no_data"]; failOnNoData != nil {
boolFailOnNoData, err := strconv.ParseBool(failOnNoData.(string))
if err != nil {
return &data.Feed{}, fmt.Errorf("could not convert fail_on_no_data = %v as bool: %w", failOnNoData, err)
}
config["fail_on_no_data"] = boolFailOnNoData
}
}

Expand Down Expand Up @@ -124,12 +144,23 @@ func DataFeedUpdate(d *schema.ResourceData, meta interface{}) error {
func configAdapterOut(f *data.Feed) {
config := f.Config
if config != nil {
test_id := config["test_id"]
if test_id != nil {
test_id_str := strconv.Itoa(int(test_id.(float64)))
config["test_id"] = test_id_str
f.Config = config
if testId := config["test_id"]; testId != nil {
strTestId := strconv.Itoa(int(testId.(float64)))
config["test_id"] = strTestId
}
if checkId := config["check_id"]; checkId != nil {
strCheckId := strconv.Itoa(int(checkId.(float64)))
config["check_id"] = strCheckId
}
if failOnWarning := config["fail_on_warning"]; failOnWarning != nil {
strFailOnWarning := strconv.FormatBool(failOnWarning.(bool))
config["fail_on_warning"] = strFailOnWarning
}
if failOnNoData := config["fail_on_no_data"]; failOnNoData != nil {
strFailOnNoData := strconv.FormatBool(failOnNoData.(bool))
config["fail_on_no_data"] = strFailOnNoData
}
f.Config = config
}
}

Expand Down
87 changes: 87 additions & 0 deletions ns1/resource_datafeed_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,44 @@ func TestThousandeyes_Basic(t *testing.T) {
})
}

func TestWebcheck_Basic(t *testing.T) {
var dataFeed data.Feed
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckDataFeedDestroy,
Steps: []resource.TestStep{
{
Config: testWebcheckBasic,
Check: resource.ComposeTestCheckFunc(
testAccCheckDataFeedExists("ns1_datafeed.uswest_feed", "ns1_datasource.api", &dataFeed, t),
testAccCheckDataFeedName(&dataFeed, "uswest_feed"),
testThousandeyesConfig(&dataFeed, "check_id", 123),
),
},
},
})
}

func TestDatadog_Basic(t *testing.T) {
var dataFeed data.Feed
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckDataFeedDestroy,
Steps: []resource.TestStep{
{
Config: testDatadogBasic,
Check: resource.ComposeTestCheckFunc(
testAccCheckDataFeedExists("ns1_datafeed.uswest_feed", "ns1_datasource.api", &dataFeed, t),
testAccCheckDataFeedName(&dataFeed, "uswest_feed"),
testDatadogConfig(&dataFeed, "DataDog Test", true, true),
),
},
},
})
}

func TestAccDataFeed_updated(t *testing.T) {
var dataFeed data.Feed
resource.Test(t, resource.TestCase{
Expand Down Expand Up @@ -208,6 +246,25 @@ func testThousandeyesConfig(dataFeed *data.Feed, key string, expected float64) r
}
}

func testDatadogConfig(dataFeed *data.Feed, name string, failOnWarning, failOnNoData bool) resource.TestCheckFunc {
return func(s *terraform.State) error {

if dataFeed.Config["test_name"] != name {
return fmt.Errorf("dataFeed.Config[name]: got: %#v, want: %s", dataFeed.Config["test_name"], name)
}

if dataFeed.Config["fail_on_warning"] != failOnWarning {
return fmt.Errorf("dataFeed.Config[fail_on_warning]: got: %#v, want: %t", dataFeed.Config["fail_on_warning"], failOnWarning)
}

if dataFeed.Config["fail_on_no_data"] != failOnNoData {
return fmt.Errorf("dataFeed.Config[fail_on_no_data]: got: %#v, want: %t", dataFeed.Config["fail_on_no_data"], failOnNoData)
}

return nil
}
}

// Simulate a manual deletion of a data feed.
func testAccManualDeleteDataFeed(dataFeed *data.Feed) func() {
return func() {
Expand Down Expand Up @@ -248,6 +305,36 @@ resource "ns1_datafeed" "uswest_feed" {
}
}`

const testDatadogBasic = `
resource "ns1_datasource" "api" {
name = "terraform test"
sourcetype = "datadog"
}

resource "ns1_datafeed" "uswest_feed" {
name = "uswest_feed"
source_id = "${ns1_datasource.api.id}"
config = {
fail_on_warning = true
fail_on_no_data = true
test_name = "DataDog Test"
}
}`

const testWebcheckBasic = `
resource "ns1_datasource" "api" {
name = "terraform test"
sourcetype = "webcheck"
}

resource "ns1_datafeed" "uswest_feed" {
name = "uswest_feed"
source_id = "${ns1_datasource.api.id}"
config = {
check_id = "123"
}
}`

const testAccDataFeedUpdated = `
resource "ns1_datasource" "api" {
name = "terraform test"
Expand Down
21 changes: 4 additions & 17 deletions ns1/resource_monitoringjob.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,19 +134,20 @@ func monitoringJobToResourceData(d *schema.ResourceData, r *monitor.Job) error {
d.Set("rapid_recheck", r.RapidRecheck)
config := make(map[string]string)
for k, v := range r.Config {
if k == "ssl" {
switch k {
case "ssl":
if v.(bool) {
config[k] = "1"
} else {
config[k] = "0"
}
} else if k == "follow_redirect" || k == "ipv6" || k == "tls_skip_verify" || k == "tls_add_verify" {
case "follow_redirect", "ipv6", "tls_skip_verify", "tls_add_verify":
if v.(bool) {
config[k] = "true"
} else {
config[k] = "false"
}
} else {
default:
switch t := v.(type) {
case string:
config[k] = t
Expand Down Expand Up @@ -194,7 +195,6 @@ func resourceDataToMonitoringJob(r *monitor.Job, d *schema.ResourceData) error {
}
r.Frequency = d.Get("frequency").(int)
r.RapidRecheck = d.Get("rapid_recheck").(bool)
var rawRules []interface{}
if rawRules := d.Get("rules"); rawRules != nil {
r.Rules = make([]*monitor.Rule, len(rawRules.([]interface{})))
for i, v := range rawRules.([]interface{}) {
Expand All @@ -208,19 +208,6 @@ func resourceDataToMonitoringJob(r *monitor.Job, d *schema.ResourceData) error {
} else {
r.Rules = make([]*monitor.Rule, 0)
}
for i, v := range rawRules {
rule := v.(map[string]interface{})
r.Rules[i] = &monitor.Rule{
Comparison: rule["comparison"].(string),
Key: rule["key"].(string),
}
value := rule["value"].(string)
if i, err := strconv.Atoi(value); err == nil {
r.Rules[i].Value = i
} else {
r.Rules[i].Value = value
}
}
config := make(map[string]interface{})
if rawConfig := d.Get("config"); rawConfig != nil {
for k, v := range rawConfig.(map[string]interface{}) {
Expand Down
21 changes: 0 additions & 21 deletions ns1/resource_monitoringjob_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,27 +147,6 @@ func TestAccMonitoringJob_ManualDelete(t *testing.T) {
})
}

func testAccCheckMonitoringJobState(key, value string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources["ns1_monitoringjob.it"]
if !ok {
return fmt.Errorf("not found: %s", "ns1_monitoringjob.it")
}

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 testAccCheckMonitoringJobExists(n string, monitoringJob *monitor.Job) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
Expand Down