Skip to content
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

New Resource: azurerm_metric_alertrule #478

Merged

Conversation

dominik-lekse
Copy link
Contributor

@dominik-lekse dominik-lekse commented Oct 31, 2017

This pull request adds the resource azurerm_metric_alertrule to manage Azure Monitor metric-based alert rules.

Azure Monitor alert supports three different conditions as part of an alert rule: ThresholdRuleCondition, LocationThresholdRuleCondition, and ManagementEventRuleCondition (see API documentation). Each of these conditions use a subset of the parameters of the REST resource. This Terraform resource only implements the ThresholdRuleCondition which correspond to metric-based alert rules. This allows for more rigor validation in the Terraform resource.

Open tasks

Acceptance tests

make testacc TEST=./azurerm TESTARGS='-run=TestAccAzureRMMetricAlertRule_virtualMachineCpu'
make testacc TEST=./azurerm TESTARGS='-run=TestAccAzureRMMetricAlertRule_importVirtualMachineCpu'
make testacc TEST=./azurerm TESTARGS='-run=TestAccAzureRMMetricAlertRule_sqlDatabaseStorage'

Executed in Azure region West Europe:

=== RUN   TestAccAzureRMMetricAlertRule_importVirtualMachineCpu
--- PASS: TestAccAzureRMMetricAlertRule_importVirtualMachineCpu (467.06s)
=== RUN   TestAccAzureRMMetricAlertRule_virtualMachineCpu
--- PASS: TestAccAzureRMMetricAlertRule_virtualMachineCpu (430.68s)
=== RUN   TestAccAzureRMMetricAlertRule_sqlDatabaseStorage
--- PASS: TestAccAzureRMMetricAlertRule_sqlDatabaseStorage (185.65s)
PASS
ok  	github.com/terraform-providers/terraform-provider-azurerm/azurerm	1083.410s

Issues

Runtime error in AlertRulesClient in UnmarshalJSON

.Using the methods provided by the AlertRulesClient raises a runtime error due invalid memory address or nil pointer dereference. The error occurs during marshalling the json response in Get or CreateOrUpdate.

The reason appears to be that the field AlertRule of type AlertRuleResource is generated as an embedded field (vendor/github.com/Azure/azure-sdk-for-go/arm/monitor/models.go:397). This lead to nil being passed to monitor.(*AlertRule).UnmarshalJSON when unmarshalling.

Changing the field AlertRule to an explicitly defined field solves the problem. Either we use the AlertRulesClient in the wrong manner or there is a bug in the Azure Go SDK client generator.

This pull request includes a separate commit with the described fix in the vendor dependencies.

@tombuildsstuff Would be great if you could take a look at this issue.

@dominik-lekse
Copy link
Contributor Author

The make vendor-status fails since I modified the vendor dependencies. 🎃

@dominik-lekse dominik-lekse changed the title WIP: Add resource azurerm_metric_alertrule Add resource azurerm_metric_alertrule Nov 5, 2017
@dominik-lekse
Copy link
Contributor Author

@tombuildsstuff Did you get a chance to look into the runtime error of the AlertRulesClient which affects this pull request?

@tombuildsstuff tombuildsstuff changed the title Add resource azurerm_metric_alertrule New Resource: azurerm_metric_alertrule Dec 8, 2017
# Conflicts:
#	azurerm/config.go
#	azurerm/provider.go
#	vendor/vendor.json
#	website/azurerm.erb
@dominik-lekse
Copy link
Contributor Author

I have rebased the pull request to the latest master and also updated azure-sdk-for-go/arm/monitor to version v11.2.2-beta. However, the issue still exists.

@tombuildsstuff
Copy link
Contributor

@dominik-lekse apologies for the delayed review here - I'm going to take a look at this today

On an unrelated note - would you be able to reach out via email when you get a moment? I'm [email protected]

Thanks!

@dominik-lekse
Copy link
Contributor Author

According to @jhendrixMSFT, the JSON unmarshalling error will be fixed in the Azure Go SDK v12. I will pick up this pull request again when the provider has been upgraded to this version.

Copy link
Contributor

@tombuildsstuff tombuildsstuff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @dominik-lekse

Thanks for this PR - apologies for the delayed review of this!

I've taken a look through and left some comments in-line but this is off to a good start. Regarding upgrading to SDK v12, I'll be looking into this next - so hopefully we should have this in soon.

Thanks!

Default: true,
},

"resource": {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this'd be clearer as resource_id or target_resource_id?


`email_action` supports the following:

* `service_owners` - (Optional) If true, the administrators (service and co-administrators) of the subscription are notified when the alert is triggered. Defaults to false.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we quote the true and false values here to match the other docs?


* `service_owners` - (Optional) If true, the administrators (service and co-administrators) of the subscription are notified when the alert is triggered. Defaults to false.

* `custom_emails` - (Optional) A list of email addresses to be notified when the alert is triggered. Defaults to an empty list.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we remove the defaults to an empty list (since that's not necessarily true with it being computed)


---

* `email_action` - (Optional) An `email_action` block as defined below.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we change "(Optional) An email_action block" -> "(Optional) A email_action block" for consistency with the other docs?


* `description` - (Optional) A verbose description of the alert rule that will be included in the alert email.

* `enabled` - (Optional) If true, the alert rule is enabled. Defaults to true.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we quote the true and false values here for consistency?


alertRule := resp.AlertRule

if alertRule != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor we can actually in-line these as if alertRule := resp.AlertRule; alertRule != nil :)

metricDataSource, _ := dataSource.AsRuleMetricDataSource()

d.Set("resource", *metricDataSource.ResourceURI)
d.Set("metric_name", *metricDataSource.MetricName)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

d.Set should handle setting the value from a pointer for us, so I don't believe we need the * on most of these values?

if emailAction, ok := ruleAction.AsRuleEmailAction(); ok {
email_action := make(map[string]interface{}, 1)

email_action["service_owners"] = *emailAction.SendToServiceOwners
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(alas, that isn't true within a nested object that's assigning to a map)

given these values could potentially be nil for older Metric Alert Rules - could we make these:

if sendToOwners := emailAction.SendToServiceOwners; sendToOwners != nil {
  email_action["service_owners"] = *sendToOwners
}


_, err = client.Delete(resGroup, name)

return err
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we change this to the following to handle displaying connection drops:

resp, err := client.Delete(resGroup, name)
if resp != nil {
  if utils.ResponseWasNotFound(resp) {
    return nil
  }

  return fmt.Errorf("Error deleting Metric Alert Rule %q (resource group %q): %+v", name, resGroup, err)
}

return nil

@@ -74,3 +74,20 @@ func validateStringLength(maxLength int) schema.SchemaValidateFunc {
return
}
}

func validateIso8601Duration() schema.SchemaValidateFunc {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we add a unit test for this validation function?

@dominik-lekse
Copy link
Contributor Author

Hi @tombuildsstuff, I picked up your review comments and resolved them with the recent changes. Also, I upgraded the SDK dependency to v12 which also solved the JSON unmarshalling error as @jhendrixMSFT promised. From my perspective, this is ready to merge.

Acceptance tests

=== RUN   TestAccAzureRMMetricAlertRule_importVirtualMachineCpu
--- PASS: TestAccAzureRMMetricAlertRule_importVirtualMachineCpu (505.97s)
=== RUN   TestAccAzureRMMetricAlertRule_virtualMachineCpu
--- PASS: TestAccAzureRMMetricAlertRule_virtualMachineCpu (539.93s)
=== RUN   TestAccAzureRMMetricAlertRule_sqlDatabaseStorage
--- PASS: TestAccAzureRMMetricAlertRule_sqlDatabaseStorage (193.84s)
PASS

Unit tests

make testacc TEST=./azurerm TESTARGS='-run=TestValidateIso8601Duration'

Copy link
Contributor

@tombuildsstuff tombuildsstuff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @dominik-lekse

Thanks for pushing those updates - I've taken a look through and left a couple of minor comments, but this otherwise LGTM. If we can rename the field service_owners to send_to_service_owners (to match Azure) then this should be good to merge 👍

Thanks!

Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"service_owners": {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor on reflection I think it might be worth making this send_to_service_owners?

location := d.Get("location").(string)
tags := d.Get("tags").(map[string]interface{})

alertRule, _ := expandAzureRmMetricThresholdAlertRule(d)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we raise this error?

ruleCondition := alertRule.Condition

if ruleCondition != nil {
thresholdRuleCondition, _ := ruleCondition.AsThresholdRuleCondition()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we raise this error (or remove it if it's not returned)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The second return parameter of AsThresholdRuleCondition is always "true" according to /Users/lekse/Projects/terraform/src/github.com/terraform-providers/terraform-provider-azurerm/vendor/github.com/Azure/azure-sdk-for-go/services/monitor/mgmt/2017-05-01-preview/insights/models.go:2251

thresholdRuleCondition, _ := ruleCondition.AsThresholdRuleCondition()

d.Set("operator", string(thresholdRuleCondition.Operator))
d.Set("threshold", float64(*thresholdRuleCondition.Threshold))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

given this is a potential crash point, could we add a check around this? e.g.

if threshold := thresholdRuleCondition.Threshold; threshold != nil {
  d.Set("threshold", float64(*threshold))
}

dataSource := thresholdRuleCondition.DataSource

if dataSource != nil {
metricDataSource, _ := dataSource.AsRuleMetricDataSource()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(as above) can we raise this error, or remove it if it's not raised?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above

} else if webhookAction, ok := ruleAction.AsRuleWebhookAction(); ok {
webhook_action := make(map[string]interface{}, 1)

webhook_action["service_uri"] = *webhookAction.ServiceURI
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we add a nil-check around this?

webhook_action["service_uri"] = *webhookAction.ServiceURI

properties := make(map[string]string, len(*webhookAction.Properties))
for k, v := range *webhookAction.Properties {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we add a nil-check around these lines incase properties is nil?

@tombuildsstuff tombuildsstuff added this to the 1.0.2 milestone Jan 22, 2018
@dominik-lekse
Copy link
Contributor Author

Hi @tombuildsstuff, the recent commit includes the changes based on your review. I did not rebase to the latest master this time since I assumed there will be more changes to the config.go before this pull request will be merged. Could you please resolve the conflicts in config.go shortly before you merge the pull request?

Copy link
Contributor

@paultyng paultyng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some minor issues with the import blocks.

"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
"log"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you fix the ordering here to match other files:

import (
  "fmt"
  "log"

  "github...."
  "other imports"
  "these should all be alphabetical within their respective group"
)

"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
"strconv"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this import should be with "fmt" and "testing"

Copy link
Contributor

@tombuildsstuff tombuildsstuff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hey @dominik-lekse

Thanks for pushing those updates - this now LGTM, I'll push a commit to remove the commented out code (which should be no longer needed) and then kick off the test suite

Thanks!

}
//else {
// properties = make(map[string]string, 0)
//}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll push a commit to remove this commented out code, since it's not needed


webhook_action["service_uri"] = *webhookAction.ServiceURI

//var properties map[string]string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(same here)

@tombuildsstuff
Copy link
Contributor

Tests pass:

screen shot 2018-01-24 at 09 27 57

@tombuildsstuff tombuildsstuff dismissed paultyng’s stale review January 24, 2018 08:29

requested changes have been made

@tombuildsstuff
Copy link
Contributor

I've resolved the merge conflicts (by merging in the branch, since pushing a rebase to a fork which you don't have access to has historically broken PR's)

@tombuildsstuff
Copy link
Contributor

@dominik-lekse thanks for this contribution - this now LGTM :)

@tombuildsstuff tombuildsstuff merged commit bbf16e9 into hashicorp:master Jan 24, 2018
tombuildsstuff added a commit that referenced this pull request Jan 24, 2018
@dominik-lekse
Copy link
Contributor Author

@tombuildsstuff Thanks for merging this pull requests and resolving the conflicts. I left them intentionally since there were sdk migration pull requests pending.

@ghost
Copy link

ghost commented Mar 31, 2020

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 feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. If you feel I made an error 🤖 🙉 , please reach out to my human friends 👉 [email protected]. Thanks!

@ghost ghost locked and limited conversation to collaborators Mar 31, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants