-
Notifications
You must be signed in to change notification settings - Fork 9.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
provider/newrelic: Add a New Relic provider #10317
Conversation
The main issue was there was no good Go API client for New Relic alerts. So I've also been writing one of those as well. Their API is unfortunately pretty limited and not fully featured, so I've had to work around some of those in this implementation. They also only provide a Swagger 1.1 spec, and I couldn't get a great autogenerated client from it in any tools I tried, so I just went with hand coding for now. |
Hey @paultyng This is an exciting provider - ability to just bootstrap systems like this is awesome. In fairness, this is going to be a bit of a beast to review. It's a single commit with 225 files so far :) Can you break this up a bit? Something like a commit per resource and a commit for the SDK addition would be really awesome! Thoughts? Paul |
Yeah no problem, I was planning on rewriting the commits once I got this closer to an MVP, so I'll do it in the way you suggest. |
Awesome! That will help a lot :) P. |
@stack72 Updated with better commit messages and I think a good set of MVP resources. There are still some annoyances where you need magic ID's from new relic to make it work. I can add data sources to help in looking those up (like applications you have configured, etc). As far as I can tell though you can't create them via API so they can't be resources. Not sure exactly how much I should add to the PR as it will probably just make reviewing a pain. |
very exciting, awesome work @paultyng! on a slightly similar note, were there any thoughts/plans around the synthetics api as well? |
I've added some |
@tiny-dancer I don't currently use the Synthetics API so wasn't in my initial plan. I want to try to keep this PR small but useful, but once the provider is in, adding additional functionality should be a bit more streamlined and can look in to it then. |
@paultyng sound good. and yah wasn't thinking for this PR, just curious if it was in your plans. was about to implement a temp solution with jenkinsfile to bring source control to the pingers/scripted tests until i ran across this pr. if we can build off the start here, makes muuch more sense in terraform. on the surface would seem to build nicely for directly relating the policies defined here to the synthetic tests. 👍 |
@stack72 I'm not sure what to do in the acceptance tests about the data source testing, as it requires manually creating data in New Relic and testing to see if its present. (see here). I guess its possible I could fake creating an application by sending a metric ping to new relic, not sure if that works or not, I guess I can test it out. |
Seems like it will work, but it will require their go agent and the reporting api key for the acceptance tests, but seems a lot nicer than having to configure it in the UI for tests to pass. I'll add that. |
Ok, added app creation via the agent sdk just for testing. Can maybe eventually work that in to a resource instead of a data source but it requires a separate API key and integration, so a little annoying. I updated my acceptance test instructions above. |
@stack72 need anything from me on this? Anyone available for a code review? |
Hi @paultyng is this no longer considered a work in progress now? Paul |
Correct, I think this has enough for v1. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @paultyng
Overall, this is looking really good. I have left a few comments inline around Import and also test names - this related to all resources
If possible, please can you also look at the case where someone deletes something from the UI - currently, most of the Read funcs will error out on that as it's not found
We have a pattern in our AWS provider for this:
getResp, err := iamconn.ListAccessKeys(request)
if err != nil {
if iamerr, ok := err.(awserr.Error); ok && iamerr.Code() == "NoSuchEntity" { // XXX TEST ME
// the user does not exist, so the key can't exist.
d.SetId("")
return nil
}
return fmt.Errorf("Error reading IAM acces key: %s", err)
}
This refreshes the current resource from state, continues and terraform will then allow it to create a new one :)
Hope this helps
Paul
// This name must match the constant defined in provider_test.go | ||
const testAccNewRelicApplicationConfig = ` | ||
data "newrelic_application" "app" { | ||
name = "terraform-test-application" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should randomise this application name - this would stop any duplicate resource names
An example can be found here
|
||
d.Set("name", channel.Name) | ||
d.Set("type", channel.Type) | ||
d.Set("configuration", channel.Configuration) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As this is a complex structure - I think we should check for an error setting the value, e.g.
if err := d.Set("configuration", channel.Configuration); err != nil {
return fmt.Errorf("[DEBUG] Error setting Alert Channel Configuration: %#v", err)
}
return nil | ||
} | ||
|
||
func resourceNewRelicAlertChannelImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As we don't have any custom logic in this import, we should just add it to the schema as follows:
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
This calls the Read func by default :)
|
||
const testAccCheckNewRelicAlertChannelConfig = ` | ||
resource "newrelic_alert_channel" "foo" { | ||
name = "foo" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be randomized to avoid test collision
|
||
const testAccCheckNewRelicAlertChannelConfigUpdated = ` | ||
resource "newrelic_alert_channel" "foo" { | ||
name = "bar" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be randomized to avoid test collision
policyID := ids[0] | ||
id := ids[1] | ||
|
||
log.Printf("[INFO] Deleting New Relic alert condition %v", id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is %v correct for this? Wouldn't %s be better as it's a string?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its an int
in this case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can switch to %d
?
|
||
const testAccCheckNewRelicAlertConditionConfig = ` | ||
resource "newrelic_alert_policy" "foo" { | ||
name = "foo" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Randomize the test name :)
resource "newrelic_alert_condition" "foo" { | ||
policy_id = "${newrelic_alert_policy.foo.id}" | ||
|
||
name = "foo" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
randomize the test name :)
|
||
const testAccCheckNewRelicAlertConditionConfigUpdated = ` | ||
resource "newrelic_alert_policy" "foo" { | ||
name = "foo" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
randomize
// Update: Not currently supported in API | ||
Delete: resourceNewRelicAlertPolicyDelete, | ||
Importer: &schema.ResourceImporter{ | ||
State: resourceNewRelicAlertPolicyImport, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can just be a PassThrough
Most (if not all) of the names do not have unique constraints in new relic. Should I still randomize? |
@stack72 changes made, I went ahead and added the randomization to the names anyway. |
I imagine you are all very busy with 0.8, let me know if there is anything I can do before you take another pass at this to help expedite it. |
hi @paultyng Coming back to look at this again :) Give me like 30 mins and I will know the state of what is going on with it Paul |
Hi @paultyng This is looking wonderful now :) The tests all pass and I added the documentation link to the nav bar
Going to manually merge this as I am rebasing into 3 logical commits. Thanks for all the work you have put in here - it's great! Paul |
I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further. |
This is still a work in progress, but I wanted to get some feedback / thoughts on if this is desirable and ways to improve it as its my first larger contribution to terraform.
The provider allows you to manage your New Relic alert policies, notification channels, alert conditions, etc.
Coupled with the Pager Duty provider, you can even link up alerts to pager duty solely in terraform.
(Ignore the commit messages, I'll clean it up all up once its closer to complete)
Update: Running Acceptance Tests
To run acceptance tests, you'll need to setup a new New Relic account, and generate an Admin API key. You will also need the license key, only for acceptance tests though, its not used in the actual provider.
You can then pass the API key via the
NEWRELIC_API_KEY
environment var and the license key viaNEWRELIC_LICENSE_KEY