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

Introduce Action Group resource of Azure Monitor #1419

Merged
merged 12 commits into from
Aug 1, 2018

Conversation

JunyiYi
Copy link

@JunyiYi JunyiYi commented Jun 21, 2018

In this PR, I introduced a new simple action group resource of Azure monitor.
I enabled three receivers (Email, SMS and Webhook) which should cover most of the use cases.

This PR is a first step of #1252 , because the resource (signal based alert) proposed in it relies on Action Group.

(fixes #1252)

@JunyiYi JunyiYi self-assigned this Jun 21, 2018
@JunyiYi JunyiYi changed the title [WIP] Introduce Action Group resource of Azure Monitor Introduce Action Group resource of Azure Monitor Jun 22, 2018
@WodansSon WodansSon added this to the 1.10.0 milestone Jul 13, 2018
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could we add some validation here, like no empty values?

Copy link
Author

Choose a reason for hiding this comment

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

Done.

},

"location": locationSchema(),
"resource_group_name": resourceGroupNameSchema(),
Copy link
Collaborator

@WodansSon WodansSon Jul 13, 2018

Choose a reason for hiding this comment

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

This is really minor, but can we get a space between these two?

Copy link
Author

Choose a reason for hiding this comment

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

Sure.

"location": locationSchema(),
"resource_group_name": resourceGroupNameSchema(),

"short_name": {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we ensure that there is no empty value check here as well?

ValidateFunc: validation.NoZeroValues,

Copy link
Author

Choose a reason for hiding this comment

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

Nice catch 👍

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same as above? Can we please validate all values that should not be empty?

Copy link
Author

Choose a reason for hiding this comment

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

Tried with Azure APIs to see which fields should be non-empty.

parameters := insights.ActionGroupResource{
Location: utils.String(location),
ActionGroup: &insights.ActionGroup{
GroupShortName: utils.String(shortName),
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't think you need to use utils.String here you can just use & to get the value.

Copy link
Author

Choose a reason for hiding this comment

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

Resolved.


func expandActionGroupEmailReceiver(d *schema.ResourceData) *[]insights.EmailReceiver {
v, ok := d.GetOk("email_receiver")
if !ok {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could we always return a valid empty array here (i.e. and only if the value is not nil and the length is greater than 0). In all cases we should return an empty array rather than nil.

Copy link
Author

Choose a reason for hiding this comment

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

Absolutely.

return &receivers
}

func flattenActionGroupEmailReceiver(receivers *[]insights.EmailReceiver) []interface{} {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Minor, generally we group expand and flattens together. Could we reorder these so they are grouped together?

Copy link
Author

Choose a reason for hiding this comment

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

Definitely.

func expandActionGroupSmsReceiver(d *schema.ResourceData) *[]insights.SmsReceiver {
v, ok := d.GetOk("sms_receiver")
if !ok {
return nil
Copy link
Collaborator

Choose a reason for hiding this comment

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

Unless there is a reason to return nil here, can we return an empty array as above?

Copy link
Author

Choose a reason for hiding this comment

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

Done.

func expandActionGroupWebHookReceiver(d *schema.ResourceData) *[]insights.WebhookReceiver {
v, ok := d.GetOk("webhook_receiver")
if !ok {
return nil
Copy link
Collaborator

Choose a reason for hiding this comment

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

Unless there is a reason to return nil here, can we return an empty array as above?

Copy link
Author

Choose a reason for hiding this comment

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

Done.

"github.com/hashicorp/terraform/helper/resource"
)

func TestAccAzureRMActionGroup_importBasic(t *testing.T) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Minor, you could move the import tests in with the regular tests if you would like. It looks like this is the direction that other providers are going, so we may want to do this as well.

Copy link
Author

Choose a reason for hiding this comment

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

Moved to resource_arm_action_group_test.go

@tombuildsstuff tombuildsstuff modified the milestones: 1.10.0, Soon Jul 16, 2018
@JunyiYi JunyiYi dismissed WodansSon’s stale review July 18, 2018 02:04

Updated the code according to the reviews.

Copy link
Collaborator

@WodansSon WodansSon left a comment

Choose a reason for hiding this comment

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

Hey @JunyiYi , everything LGTM except for the import test part, I think I may not have been clear in my communication of what I suggested to be changed, my bad. Can you please update the PR per my new inline suggestion?

})
}

func TestAccAzureRMActionGroup_importBasic(t *testing.T) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we delete the import function and add the import test as an additional test step in the existing resource test? Sorta like this (do this for all import tests in the PR)...

Steps: []resource.TestStep{ 
	{ 
		Config: config, 
		Check: resource.ComposeTestCheckFunc( 
			testCheckAzureRMActionGroupExists(resourceName), 
			resource.TestCheckResourceAttr(resourceName, "enabled", "true"), 
			resource.TestCheckResourceAttr(resourceName, "email_receiver.#", "2"), 
			resource.TestCheckResourceAttr(resourceName, "email_receiver.0.email_address", "admin@contoso.com"), 
			resource.TestCheckResourceAttr(resourceName, "email_receiver.1.email_address", "devops@contoso.com"), 
			resource.TestCheckResourceAttr(resourceName, "sms_receiver.#", "1"), 
			resource.TestCheckResourceAttr(resourceName, "sms_receiver.0.country_code", "1"), 
			resource.TestCheckResourceAttr(resourceName, "sms_receiver.0.phone_number", "1231231234"), 
			resource.TestCheckResourceAttr(resourceName, "webhook_receiver.#", "1"), 
			resource.TestCheckResourceAttr(resourceName, "webhook_receiver.0.service_uri", "http://example.com/alert"), 
		), 
	},
	{ 
		ResourceName:      resourceName, 
		ImportState:       true, 
		ImportStateVerify: true, 
	}, 

Copy link
Author

Choose a reason for hiding this comment

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

I've changed the test cases.

@JunyiYi JunyiYi dismissed WodansSon’s stale review July 30, 2018 02:08

Alread updated code according to the feedback.

Copy link
Collaborator

@WodansSon WodansSon left a comment

Choose a reason for hiding this comment

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

@JunyiYi, Thanks for updating the tests. LGTM now!

@WodansSon
Copy link
Collaborator

image

@WodansSon WodansSon merged commit 054a76b into master Aug 1, 2018
@WodansSon WodansSon deleted the resource_actiongroup branch August 1, 2018 22:55
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.

hi @JunyiYi @jeffreyCline

Unfortunately this PR has several issues (which I've left comments for) - but primarily there's a number of potential crashes which could occur due to invalid API responses which need to be addressed; so that we're able to merge other PR's I'm going to have to revert this PR for the moment. In order to get this merged please open a new PR to address the comments and we'll be happy to take another look.

for _, receiver := range *receivers {
val := make(map[string]interface{}, 0)
val["name"] = *receiver.Name
val["service_uri"] = *receiver.ServiceURI
Copy link
Contributor

Choose a reason for hiding this comment

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

there's two potential crashes here - these should be nil-checked

Copy link
Author

Choose a reason for hiding this comment

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

Azure won't allow nil values for these fields.

val := make(map[string]interface{}, 0)
val["name"] = *receiver.Name
val["country_code"] = *receiver.CountryCode
val["phone_number"] = *receiver.PhoneNumber
Copy link
Contributor

Choose a reason for hiding this comment

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

there's three potential crashes here - can we nil-check these?

Copy link
Author

Choose a reason for hiding this comment

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

Azure won't allow nil values for these fields.

for _, receiver := range *receivers {
val := make(map[string]interface{}, 0)
val["name"] = *receiver.Name
val["email_address"] = *receiver.EmailAddress
Copy link
Contributor

Choose a reason for hiding this comment

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

there's two potential crashes here - can we nil-check these?

Copy link
Author

Choose a reason for hiding this comment

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

Azure won't allow nil values for these fields.

}

d.Set("short_name", *resp.GroupShortName)
d.Set("enabled", *resp.Enabled)
Copy link
Contributor

Choose a reason for hiding this comment

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

we don't need to de-pointer these; also we should be accessing these in the .Properties block

Copy link
Author

Choose a reason for hiding this comment

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

It is a shortcut in go instead of accessing .Properties.


id, err := parseAzureResourceID(d.Id())
if err != nil {
return fmt.Errorf("Error parsing action group resource ID \"%s\" during get: %+v", d.Id(), err)
Copy link
Contributor

Choose a reason for hiding this comment

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

we don't need to wrap this error message

Copy link
Author

Choose a reason for hiding this comment

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

That's my personal style. I don't think it really matters.

* `enabled` - (Optional) Whether this action group is enabled. If an action group is not enabled, then none of its receivers will receive communications. Defaults to `true`.
* `email_receiver` - (Optional) The list of `email_receiver` blocks as defined below that are part of this action group.
* `sms_receiver` - (Optional) The list of `sms_receiver` blocks as defined below that are part of this action group.
* `webhook_receiver` - (Optional) The list of `webhook_receiver` blocks as defined below that are part of this action group.
Copy link
Contributor

Choose a reason for hiding this comment

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

All three of these should be updated to match the other resources:

* `email_receiver ` - (Optional) One or more `email_receiver ` blocks as defined below.
* `sms_receiver ` - (Optional) One or more `sms_receiver ` blocks as defined below.
* `webhook_receiver` - (Optional) One or more `webhook_receiver` blocks as defined below.

Copy link
Author

Choose a reason for hiding this comment

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

Copy link
Contributor

@tombuildsstuff tombuildsstuff Aug 3, 2018

Choose a reason for hiding this comment

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


The following attributes are exported:

* `id` - The Route ID.
Copy link
Contributor

Choose a reason for hiding this comment

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

presumably this should be "The ID of the Action Group"?

resource.TestCheckResourceAttr(resourceName, "sms_receiver.0.country_code", "1"),
resource.TestCheckResourceAttr(resourceName, "sms_receiver.0.phone_number", "1231231234"),
resource.TestCheckResourceAttr(resourceName, "webhook_receiver.#", "1"),
resource.TestCheckResourceAttr(resourceName, "webhook_receiver.0.service_uri", "http://example.com/alert"),
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 some tests to go from empty -> basic and ensure these fields are set?

ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
Copy link
Contributor

Choose a reason for hiding this comment

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

in general we don't test importing the updates, but rather full configurations. in this case can we split this test into two: one to test with it in the disabled state, and one to ensure it can go from disabled -> enabled -> disabled


id, err := parseAzureResourceID(d.Id())
if err != nil {
return fmt.Errorf("Error parsing action group resource ID \"%s\" during delete: %+v", d.Id(), err)
Copy link
Contributor

Choose a reason for hiding this comment

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

we don't need to wrap this error message - so can we just return it directly?

Copy link
Author

Choose a reason for hiding this comment

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

Align with all other error messages in this code base would be a good style.

Copy link
Contributor

Choose a reason for hiding this comment

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

we consistently across the codebase don't wrap these error messages since they're an internal error users aren't going to be able to work around (vs a temporary issue in the Azure API in CRUD/Polling where they may be able to self-diagnose) - as such ID parsing error don't need wrapping.

@katbyte katbyte restored the resource_actiongroup branch August 2, 2018 23:11
@tombuildsstuff tombuildsstuff modified the milestones: Soon, Being Sorted Oct 25, 2018
@ghost
Copy link

ghost commented Mar 6, 2019

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 👉 hashibot-feedback@hashicorp.com. Thanks!

@ghost ghost locked and limited conversation to collaborators Mar 6, 2019
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.

New Resource: Azure Monitor Signal
3 participants