Skip to content

Commit 4d4f9df

Browse files
zlesnrJonathan Thurmanctrombley
authored
feat(application): implement newrelic_application resource (#558)
* feat(application): implement newrelic_application resource resolves: #52 * refactor(application): rename resource to application_settings * fix(application_settings): Remove delete, as it is not possible * chore(test): update resource name in test * chore(test): Update test email addresses (NR is not filitering invalids) * tests: fix broken integration tests * chore: update terraform SDK * chore: vendor modules Co-authored-by: Jonathan Thurman <[email protected]> Co-authored-by: Chris Trombley <[email protected]>
1 parent 9338337 commit 4d4f9df

File tree

428 files changed

+31453
-98252
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

428 files changed

+31453
-98252
lines changed

go.mod

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ go 1.13
55
require (
66
github.com/bflad/tfproviderlint v0.14.0
77
github.com/client9/misspell v0.3.4
8-
github.com/golangci/golangci-lint v1.26.0
9-
github.com/hashicorp/terraform-plugin-sdk v1.8.0
8+
github.com/golangci/golangci-lint v1.27.0
9+
github.com/hashicorp/terraform-plugin-sdk v1.12.0
1010
github.com/newrelic/go-agent/v3 v3.4.0
1111
github.com/newrelic/go-insights v1.0.3
12-
github.com/newrelic/newrelic-client-go v0.23.3
12+
github.com/newrelic/newrelic-client-go v0.23.4
1313
github.com/stretchr/testify v1.5.1
1414
)

go.sum

+40-14
Large diffs are not rendered by default.

newrelic/data_source_newrelic_application.go

+20-8
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ func dataSourceNewRelicApplicationRead(d *schema.ResourceData, meta interface{})
4545
}
4646

4747
applications, err := client.APM.ListApplications(&params)
48-
4948
if err != nil {
5049
return err
5150
}
@@ -63,14 +62,27 @@ func dataSourceNewRelicApplicationRead(d *schema.ResourceData, meta interface{})
6362
return fmt.Errorf("the name '%s' does not match any New Relic applications", name)
6463
}
6564

66-
flattenApplication(application, d)
67-
68-
return nil
65+
return flattenApplicationData(application, d)
6966
}
7067

71-
func flattenApplication(a *apm.Application, d *schema.ResourceData) {
68+
func flattenApplicationData(a *apm.Application, d *schema.ResourceData) error {
7269
d.SetId(strconv.Itoa(a.ID))
73-
d.Set("name", a.Name)
74-
d.Set("instance_ids", a.Links.InstanceIDs)
75-
d.Set("host_ids", a.Links.HostIDs)
70+
var err error
71+
72+
err = d.Set("name", a.Name)
73+
if err != nil {
74+
return err
75+
}
76+
77+
err = d.Set("instance_ids", a.Links.InstanceIDs)
78+
if err != nil {
79+
return err
80+
}
81+
82+
err = d.Set("host_ids", a.Links.HostIDs)
83+
if err != nil {
84+
return err
85+
}
86+
87+
return nil
7688
}

newrelic/data_source_newrelic_application_test.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,22 @@ import (
88
"github.com/hashicorp/terraform-plugin-sdk/terraform"
99
)
1010

11-
func TestAccNewRelicApplication_Basic(t *testing.T) {
11+
func TestAccNewRelicApplicationData_Basic(t *testing.T) {
1212
resource.ParallelTest(t, resource.TestCase{
1313
PreCheck: func() { testAccPreCheck(t) },
1414
Providers: testAccProviders,
1515
Steps: []resource.TestStep{
1616
{
17-
Config: testAccNewRelicApplicationConfig(),
17+
Config: testAccNewRelicApplicationDataConfig(),
1818
Check: resource.ComposeTestCheckFunc(
19-
testAccCheckNewRelicApplicationExists("data.newrelic_application.app"),
19+
testAccCheckNewRelicApplicationDataExists("data.newrelic_application.app"),
2020
),
2121
},
2222
},
2323
})
2424
}
2525

26-
func testAccCheckNewRelicApplicationExists(n string) resource.TestCheckFunc {
26+
func testAccCheckNewRelicApplicationDataExists(n string) resource.TestCheckFunc {
2727
return func(s *terraform.State) error {
2828
r := s.RootModule().Resources[n]
2929
a := r.Primary.Attributes
@@ -41,7 +41,7 @@ func testAccCheckNewRelicApplicationExists(n string) resource.TestCheckFunc {
4141
}
4242

4343
// The test application for this data source is created in provider_test.go
44-
func testAccNewRelicApplicationConfig() string {
44+
func testAccNewRelicApplicationDataConfig() string {
4545
return fmt.Sprintf(`
4646
data "newrelic_application" "app" {
4747
name = "%s"

newrelic/provider.go

+1
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ func Provider() terraform.ResourceProvider {
116116
"newrelic_alert_condition": resourceNewRelicAlertCondition(),
117117
"newrelic_alert_policy_channel": resourceNewRelicAlertPolicyChannel(),
118118
"newrelic_alert_policy": resourceNewRelicAlertPolicy(),
119+
"newrelic_application_settings": resourceNewRelicApplicationSettings(),
119120
"newrelic_application_label": resourceNewRelicApplicationLabel(),
120121
"newrelic_plugins_alert_condition": resourceNewRelicPluginsAlertCondition(),
121122
"newrelic_dashboard": resourceNewRelicDashboard(),

newrelic/resource_newrelic_alert_policy_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ resource "newrelic_alert_channel" "channel_a" {
208208
type = "email"
209209
210210
config {
211-
recipients = "test@testing.com"
211+
recipients = "no-reply+a@newrelic.com"
212212
include_json_attachment = "1"
213213
}
214214
}
@@ -218,7 +218,7 @@ resource "newrelic_alert_channel" "channel_b" {
218218
type = "email"
219219
220220
config {
221-
recipients = "example@testing.com"
221+
recipients = "no-reply+b@newrelic.com"
222222
include_json_attachment = "1"
223223
}
224224
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package newrelic
2+
3+
import (
4+
"fmt"
5+
"log"
6+
"strconv"
7+
8+
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
9+
"github.com/newrelic/newrelic-client-go/pkg/apm"
10+
)
11+
12+
func resourceNewRelicApplicationSettings() *schema.Resource {
13+
return &schema.Resource{
14+
Create: resourceNewRelicApplicationSettingsCreate,
15+
Read: resourceNewRelicApplicationSettingsRead,
16+
Update: resourceNewRelicApplicationSettingsUpdate,
17+
Delete: resourceNewRelicApplicationSettingsDelete,
18+
Importer: &schema.ResourceImporter{
19+
State: schema.ImportStatePassthrough,
20+
},
21+
Schema: map[string]*schema.Schema{
22+
"name": {
23+
Type: schema.TypeString,
24+
Required: true,
25+
},
26+
"app_apdex_threshold": {
27+
Type: schema.TypeFloat,
28+
Required: true,
29+
},
30+
"end_user_apdex_threshold": {
31+
Type: schema.TypeFloat,
32+
Required: true,
33+
},
34+
"enable_real_user_monitoring": {
35+
Type: schema.TypeBool,
36+
Required: true,
37+
},
38+
},
39+
}
40+
}
41+
42+
func resourceNewRelicApplicationSettingsCreate(d *schema.ResourceData, meta interface{}) error {
43+
client := meta.(*ProviderConfig).NewClient
44+
45+
userApp := expandApplication(d)
46+
47+
listParams := apm.ListApplicationsParams{
48+
Name: userApp.Name,
49+
}
50+
51+
result, err := client.APM.ListApplications(&listParams)
52+
if err != nil {
53+
return err
54+
}
55+
56+
if len(result) != 1 {
57+
return fmt.Errorf("more/less than one result from query for %s", userApp.Name)
58+
}
59+
60+
app := *result[0]
61+
62+
if app.Name != userApp.Name {
63+
return fmt.Errorf("the result name %s does not match requested name %s", app.Name, userApp.Name)
64+
}
65+
66+
d.SetId(strconv.Itoa(app.ID))
67+
68+
log.Printf("[INFO] Importing New Relic application %v", userApp.Name)
69+
return resourceNewRelicApplicationSettingsUpdate(d, meta)
70+
}
71+
72+
func resourceNewRelicApplicationSettingsRead(d *schema.ResourceData, meta interface{}) error {
73+
client := meta.(*ProviderConfig).NewClient
74+
75+
userApp := expandApplication(d)
76+
log.Printf("[INFO] Reading New Relic application %+v", userApp)
77+
78+
app, err := client.APM.GetApplication(userApp.ID)
79+
if err != nil {
80+
return err
81+
}
82+
83+
log.Printf("[INFO] Read found New Relic application %+v\n\n\n", app)
84+
85+
return flattenApplication(app, d)
86+
}
87+
88+
func resourceNewRelicApplicationSettingsUpdate(d *schema.ResourceData, meta interface{}) error {
89+
client := meta.(*ProviderConfig).NewClient
90+
91+
userApp := expandApplication(d)
92+
93+
updateParams := apm.UpdateApplicationParams{
94+
Name: userApp.Name,
95+
Settings: userApp.Settings,
96+
}
97+
98+
log.Printf("[INFO] Updating New Relic application %+v with params: %+v", userApp, updateParams)
99+
100+
_, err := client.APM.UpdateApplication(userApp.ID, updateParams)
101+
if err != nil {
102+
return err
103+
}
104+
105+
return resourceNewRelicApplicationSettingsRead(d, meta)
106+
}
107+
108+
func resourceNewRelicApplicationSettingsDelete(d *schema.ResourceData, meta interface{}) error {
109+
// You can not delete application settings
110+
return nil
111+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package newrelic
2+
3+
import (
4+
"fmt"
5+
"strconv"
6+
"testing"
7+
8+
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
9+
"github.com/hashicorp/terraform-plugin-sdk/terraform"
10+
)
11+
12+
func TestAccNewRelicApplicationSettings_Basic(t *testing.T) {
13+
resourceName := "newrelic_application_settings.app"
14+
15+
resource.ParallelTest(t, resource.TestCase{
16+
PreCheck: func() { testAccPreCheck(t) },
17+
Providers: testAccProviders,
18+
CheckDestroy: testAccCheckNewRelicApplicationDestroy,
19+
Steps: []resource.TestStep{
20+
{
21+
Config: testAccNewRelicApplicationConfig(),
22+
Check: resource.ComposeTestCheckFunc(
23+
testAccCheckNewRelicApplicationExists(resourceName),
24+
),
25+
},
26+
// Test: Update
27+
{
28+
Config: testAccNewRelicApplicationConfigUpdated(testAccExpectedApplicationName),
29+
Check: resource.ComposeTestCheckFunc(
30+
testAccCheckNewRelicApplicationExists(resourceName),
31+
),
32+
},
33+
// Test: Import
34+
{
35+
ResourceName: resourceName,
36+
ImportState: true,
37+
ImportStateVerify: true,
38+
},
39+
},
40+
})
41+
}
42+
43+
func testAccCheckNewRelicApplicationDestroy(s *terraform.State) error {
44+
// We expect the application to still exist
45+
return nil
46+
}
47+
48+
// The test application for this data source is created in provider_test.go
49+
func testAccNewRelicApplicationConfig() string {
50+
return fmt.Sprintf(`
51+
resource "newrelic_application_settings" "app" {
52+
name = "%s"
53+
app_apdex_threshold = "0.9"
54+
end_user_apdex_threshold = "0.8"
55+
enable_real_user_monitoring = true
56+
}
57+
`, testAccExpectedApplicationName)
58+
}
59+
60+
func testAccNewRelicApplicationConfigUpdated(name string) string {
61+
return fmt.Sprintf(`
62+
resource "newrelic_application_settings" "app" {
63+
name = "%s-updated"
64+
app_apdex_threshold = "0.8"
65+
end_user_apdex_threshold = "0.7"
66+
enable_real_user_monitoring = false
67+
}
68+
`, name)
69+
}
70+
71+
func testAccCheckNewRelicApplicationExists(n string) resource.TestCheckFunc {
72+
return func(s *terraform.State) error {
73+
74+
rs, ok := s.RootModule().Resources[n]
75+
if !ok {
76+
return fmt.Errorf("not found: %s", n)
77+
}
78+
79+
if rs.Primary.ID == "" {
80+
return fmt.Errorf("no application ID is set")
81+
}
82+
83+
id, err := strconv.ParseInt(rs.Primary.ID, 10, 32)
84+
if err != nil {
85+
return nil
86+
}
87+
88+
client := testAccProvider.Meta().(*ProviderConfig).NewClient
89+
_, err = client.APM.GetApplication(int(id))
90+
if err != nil {
91+
return err
92+
}
93+
94+
return nil
95+
}
96+
}

newrelic/resource_newrelic_insights_event.go

+1
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ func resourceNewRelicInsightsEventCreate(d *schema.ResourceData, meta interface{
120120
client := meta.(*ProviderConfig).InsightsInsertClient
121121
var eventsPayload []*InsightsEvent
122122

123+
// nolint: staticcheck
123124
if v, ok := d.GetOkExists("event"); ok {
124125
events := v.(*schema.Set).List()
125126
eventsPayload = make([]*InsightsEvent, len(events))

newrelic/resource_newrelic_synthetics_monitor.go

+6
Original file line numberDiff line numberDiff line change
@@ -120,14 +120,17 @@ func buildSyntheticsMonitorStruct(d *schema.ResourceData) synthetics.Monitor {
120120
monitor.Options.ValidationString = validationString.(string)
121121
}
122122

123+
// nolint: staticcheck
123124
if verifySSL, ok := d.GetOkExists("verify_ssl"); ok {
124125
monitor.Options.VerifySSL = verifySSL.(bool)
125126
}
126127

128+
// nolint: staticcheck
127129
if bypassHeadRequest, ok := d.GetOkExists("bypass_head_request"); ok {
128130
monitor.Options.BypassHEADRequest = bypassHeadRequest.(bool)
129131
}
130132

133+
// nolint: staticcheck
131134
if treatRedirectAsFailure, ok := d.GetOkExists("treat_redirect_as_failure"); ok {
132135
monitor.Options.TreatRedirectAsFailure = treatRedirectAsFailure.(bool)
133136
}
@@ -160,14 +163,17 @@ func buildSyntheticsUpdateMonitorArgs(d *schema.ResourceData) *synthetics.Monito
160163
monitor.Options.ValidationString = validationString.(string)
161164
}
162165

166+
// nolint: staticcheck
163167
if verifySSL, ok := d.GetOkExists("verify_ssl"); ok {
164168
monitor.Options.VerifySSL = verifySSL.(bool)
165169
}
166170

171+
// nolint: staticcheck
167172
if bypassHeadRequest, ok := d.GetOkExists("bypass_head_request"); ok {
168173
monitor.Options.BypassHEADRequest = bypassHeadRequest.(bool)
169174
}
170175

176+
// nolint: staticcheck
171177
if treatRedirectAsFailure, ok := d.GetOkExists("treat_redirect_as_failure"); ok {
172178
monitor.Options.TreatRedirectAsFailure = treatRedirectAsFailure.(bool)
173179
}

0 commit comments

Comments
 (0)