-
Notifications
You must be signed in to change notification settings - Fork 301
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
Feature/issue 551 azuread_groups security_enabled flag #552
Feature/issue 551 azuread_groups security_enabled flag #552
Conversation
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 @Threpio, thanks for this PR, this is off to a great start!
If we're adding a security_enabled
flag, could we also add a mail_enabled
flag? M365 groups can be secuyrity-enabled so it's probably desired to be able to specify both security_enabled = true
and mail_enabled = false
.
For the implementation, I think it would be better to first build up a filter based on security_enabled
(and mail_enabled
) and include that in the main if-else block. We'd also need to explicitly check the results since the filter is useful for server-side filtering but we also need client-side checks.
"security_enabled": { | ||
Description: "Retrieve only groups that are security_enabled groups", | ||
Type: schema.TypeBool, | ||
Optional: true, |
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 think this should be mutually exclusive with the return_all
property?
Optional: true, | |
Optional: true, | |
ConflictsWith: []string{"return_all"}, |
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 think it should be possible to query for all groups that are security_enabled ?
I know it is a complication with regards to logic but the ability to just filter out 365 groups could be a useful tool.
(worth noting that I doubt I will be using the functionality defined here so if there is an end-user feel free to override me)
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.
Yeah the more I've thought about it, I agree it should be possible to specify return_all
and filter out mail and security groups.
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.
Filter-out or filter in?
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.
Sorry filter in, as in I should have written "filter for" :D
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 suppose what we should think about aswell is the oppertunity for future work - Perhaps people will want to specify mail_enabled=false
and only get non-mail_enabled groups
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.
Right, that's sort of what I was trying to get at with the inclusion of both properties. Someone may want to specify security_enabled=true
and mail_enabled=false
to get security groups that aren't mail enabled (e.g. effectively only get classic security groups and not potential M365 groups)
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.
(You should be able to use d.GetOk() to test if the property was specified versus just having it's default (unset) value)
return_all = true | ||
security_enabled = true |
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.
These should be mutually exclusive since return_all
implies all groups? Alternatively we could update the docs to reflect that return_all
excludes display_names
and object_ids
but can be used with security_enabled
to return all security-enabled groups.
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 think I agree with the alternative. Otherwise we can look to apply a number of filters for other fields at the same time.
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.
Sounds good to me!
Co-authored-by: Tom Bamford <[email protected]>
Would you like me to do the mail_enabled flag logic in this PR aswell or to have it's own? Also I have noted that I have missed the documentation for logic of the conflict between specified object_ids and this flag - I am right in thinking they would conflict right? |
Co-authored-by: Tom Bamford <[email protected]>
In this PR would be great since they are very related - and noting that M365 groups can be security enabled, having the mail_enabled property will be important. It would be good to also add the
Correct, |
… the logic be extracted then let me know
Just to check - is mail_enabled and security_enabled conflict? Can a group retain both of these flags to true |
A group (depending on its type) can be either mail_enabled / security_enabled or both. |
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.
@Threpio Thanks for the updates, this is looking mostly good. Just a few comments on the implementation, mainly the use of odata filters to get server-side filtering (we'll still keep the client-side filtering too). If you can take a look at these, this should be good to merge!
@@ -87,8 +105,7 @@ func groupsDataSourceRead(ctx context.Context, d *schema.ResourceData, meta inte | |||
if len(*result) == 0 { | |||
return tf.ErrorDiagPathF(err, "return_all", "No groups found") | |||
} | |||
|
|||
groups = append(groups, *result...) | |||
groups = filterResults(securityEnabled, mailEnabled, result) |
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.
Could we compose odata filters for this too, to minimise the number of unrelated results going over the wire? e.g. securityEnabled eq true
and/or mailEnabled eq true
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 may be being stupid and not understanding odata querying - But would this not lead to something like:
if securityEnabled && mailEnabled{
query := odata.Query{
Filter: fmt.Sprintf("displayName eq '%s', securityEnabled eq true, mailEnabled eq true", displayName),
}
} else if securityEnabled {
query := odata.Query{
Filter: fmt.Sprintf("displayName eq '%s', securityEnabled eq true", displayName),
}
} else if mailEnabled {
query := odata.Query{
Filter: fmt.Sprintf("displayName eq '%s', mailEnabled eq true", displayName),
}
} else {
query := odata.Query{
Filter: fmt.Sprintf("displayName eq '%s'", displayName),
}
}```
Or is there a way to construct the queries that will omit what we are not querying after? (I do 100% agree about the extra results and such)
@@ -102,13 +119,15 @@ func groupsDataSourceRead(ctx context.Context, d *schema.ResourceData, meta inte | |||
} | |||
|
|||
count := len(*result) | |||
if count > 1 { | |||
|
|||
//Could we make this a switch 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.
If think this is fine as an if-else block for now. Maybe one more case would make it eligible IMO
if count > 1 { | ||
|
||
//Could we make this a switch case? | ||
if !mailEnabled && !securityEnabled && count > 1 { |
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.
Assuming we use odata filters, I think this would be better left as if count > 1
?
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.
Yes - Using server side filtering would allow that to return correctly.
If we search for a group with displayname xyz-2 but there is a group xyz-23 does it return both groups or just the one with the exact matching display name? (I assume this is Hamilton and their server doing the clever querying.
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.
There are several operators and functions. eq
is a whole value check. there's also a startsWith
function which does what you'd expect (docs)
@@ -126,7 +145,7 @@ func groupsDataSourceRead(ctx context.Context, d *schema.ResourceData, meta inte | |||
} | |||
} | |||
|
|||
if !returnAll && len(groups) != expectedCount { | |||
if !returnAll && !securityEnabled && !mailEnabled && len(groups) != expectedCount { |
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 above, with server-side filtering, this can be left as-is
// Check if securityEnabled/mailEnabled has caused the number of returned groups to be 0 | ||
if len(newObjectIds) == 0 && (securityEnabled || mailEnabled) { | ||
return tf.ErrorDiagF(errors.New("No groups found with a filter flag applied"), "Unexpected Number of groups returned") | ||
} |
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.
Not sure what scenario this is intended to catch as this would already have errored in the main if-else block above?
func TestAccGroupsDataSource_securityEnabled(t *testing.T) { | ||
data := acceptance.BuildTestData(t, "data.azuread_groups", "test") | ||
|
||
data.DataSourceTest(t, []resource.TestStep{ | ||
{ | ||
Config: GroupsDataSource{}.securityEnabled(), | ||
Check: resource.ComposeTestCheckFunc( | ||
check.That(data.ResourceName).Key("display_names.#").Exists(), | ||
check.That(data.ResourceName).Key("object_ids.#").Exists(), | ||
), | ||
}, | ||
}) | ||
} | ||
|
||
func TestAccGroupsDataSource_mailEnabled(t *testing.T) { | ||
data := acceptance.BuildTestData(t, "data.azuread_groups", "test") | ||
|
||
data.DataSourceTest(t, []resource.TestStep{ | ||
{ | ||
Config: GroupsDataSource{}.mailEnabled(), | ||
Check: resource.ComposeTestCheckFunc( | ||
check.That(data.ResourceName).Key("display_names.#").Exists(), | ||
check.That(data.ResourceName).Key("object_ids.#").Exists(), | ||
), | ||
}, | ||
}) | ||
} |
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.
These are good, can we also add a test for security_enabled + mail_enabled to make sure these work together as expected?
docs/data-sources/groups.md
Outdated
## Argument Reference | ||
|
||
The following arguments are supported: | ||
|
||
* `display_names` - (Optional) The display names of the groups. | ||
* `object_ids` - (Optional) The object IDs of the groups. | ||
* `return_all` - (Optional) A flag to denote if all groups should be fetched and returned. | ||
* `security_enabled` - (Optional) A flag to denote if only `security_enabled=true` groups should be returned. | ||
* `mail_enabled` - (Optional) A flag to denote if only `mail_enabled=true` groups should be returned. |
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.
Could we move this up a few lines to maintain alphabetic sorting?
Co-authored-by: Tom Bamford <[email protected]>
Co-authored-by: Tom Bamford <[email protected]>
Co-authored-by: Tom Bamford <[email protected]>
Sorry @manicminer - My priorities at work have been changed and I will no longer be able to finish up this PR. Do you want me to close it or? |
@Threpio No problem, thanks for your work on it and for letting us know. Go ahead and close it, I'm sure it will be picked up again at some point :) |
This functionality has been released in v2.5.0 of the Terraform Provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading. For further feature requests or bug reports with this functionality, please create a new GitHub issue following the template. Thank you! |
I'm going to lock this pull request because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active contributions. |
Fixes #551
Added a
security_enabled=true
flag toazuread_groups
datasource. It currently does not implement any logic whensecurity_enabled=false
which some people might want in the future.This checks to ensure that atleast 1 result is returned - If one non security_enabled group is found but then dropped then an error suggesting the flag will be returned.
The test functionality for this and the return_all flag needs to be revisited by someone that understands this testing framwork more than me. There are single cases