-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
11347 supporting azurerm subscription tags #12287
Conversation
@jackofallops , can you please approve the workflow. we will close this topic. |
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 @crkg - Thanks for this PR, it's off to a good start. I've left some comments and changes in line below. If you can address those, I'll re-review asap.
Thanks!
@@ -10,6 +11,7 @@ type Client struct { | |||
Client *subscriptions.Client | |||
AliasClient *subscriptionAlias.AliasClient | |||
SubscriptionClient *subscriptionAlias.Client | |||
TagsClient *resources.TagsClient |
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.
This should belong in the resource
service, can you move it to that package?
Type: pluginsdk.TypeMap, | ||
Description: "The tags of the resource", | ||
Computed: true, | ||
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.
We should be able to use the common schema in the tags package here, e.g. :
"tags": tags.Schema(),
if d.HasChange("tags") { | ||
tagsDetails := d.Get("tags").(map[string]interface{}) | ||
resource_tags := resources.Tags{ | ||
Tags: tags.Expand(tagsDetails), | ||
} | ||
locks.ByID(subscriptionId) | ||
defer locks.UnlockByID(subscriptionId) | ||
tagParameters := resources.TagsPatchResource{Operation: "Merge", Properties: &resource_tags} | ||
updateTags, updateErr := tagsClient.UpdateAtScope(context.Background(), "subscriptions/"+subscriptionId, tagParameters) | ||
if updateErr != nil { | ||
if !utils.ResponseWasNotFound(updateTags.Response) { | ||
return fmt.Errorf("Adding tag value %q for subscription %q: %+v") | ||
} | ||
} | ||
d.Set("tags", *updateTags.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.
Setting the tags should be done before setting the ID, so that is only done when the full create operation is successful.
We can also skip the d.HasChange
and just read and send what we have here, as it's the Create
.
You can also remove the locking as that is already in place earlier in the function.
Something like this I think will be about right:
if d.HasChange("tags") { | |
tagsDetails := d.Get("tags").(map[string]interface{}) | |
resource_tags := resources.Tags{ | |
Tags: tags.Expand(tagsDetails), | |
} | |
locks.ByID(subscriptionId) | |
defer locks.UnlockByID(subscriptionId) | |
tagParameters := resources.TagsPatchResource{Operation: "Merge", Properties: &resource_tags} | |
updateTags, updateErr := tagsClient.UpdateAtScope(context.Background(), "subscriptions/"+subscriptionId, tagParameters) | |
if updateErr != nil { | |
if !utils.ResponseWasNotFound(updateTags.Response) { | |
return fmt.Errorf("Adding tag value %q for subscription %q: %+v") | |
} | |
} | |
d.Set("tags", *updateTags.ID) | |
} | |
t := tags.Expand(d.Get("tags").(map[string]interface{})) | |
tagsClient := meta.(*clients.Client).Resource.TagsClient | |
scope := fmt.Sprintf("subscription/%s", subscriptionId) | |
if _, err = tagsClient.CreateOrUpdateAtScope(ctx, scope, resources.TagsResource{Properties: &resources.Tags{Tags: t}}); err != nil { | |
return fmt.Errorf("setting tags on %s: %+v", id, err) | |
} | |
} | ||
|
||
func resourceSubscriptionRead(d *pluginsdk.ResourceData, meta interface{}) error { | ||
aliasClient := meta.(*clients.Client).Subscription.AliasClient | ||
client := meta.(*clients.Client).Subscription.Client | ||
// tagsClient := meta.(*clients.Client).Subscription.TagsClient |
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 we remove this?
// tagsClient := meta.(*clients.Client).Subscription.TagsClient |
@@ -314,13 +358,15 @@ func resourceSubscriptionRead(d *pluginsdk.ResourceData, meta interface{}) error | |||
} | |||
|
|||
t = resp.Tags | |||
fmt.Println("Read resp tags %q", t) |
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.
This looks like a left over debugging line that should be removed?
fmt.Println("Read resp tags %q", t) |
if d.HasChange("tags") { | ||
tagsDetails := d.Get("tags").(map[string]interface{}) | ||
resource_tags := resources.Tags{ | ||
Tags: tags.Expand(tagsDetails), | ||
} | ||
locks.ByID(subscriptionId) | ||
defer locks.UnlockByID(subscriptionId) | ||
tagPatchParamter := resources.TagsPatchResource{Operation: "Delete", Properties: &resource_tags} | ||
updateTags, delerr := tagsClient.UpdateAtScope(context.Background(), "subscriptions/"+subscriptionId, tagPatchParamter) | ||
if delerr != nil { | ||
return fmt.Errorf("Failed to Remove tags %q from subscription %q: %+v", tags.Flatten(resource_tags.Tags), subscriptionId, delerr) | ||
} | ||
d.Set("tags", *updateTags.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.
We shouldn't need to do anything with the tags here, as we will be disabling the subscription.
if d.HasChange("tags") { | |
tagsDetails := d.Get("tags").(map[string]interface{}) | |
resource_tags := resources.Tags{ | |
Tags: tags.Expand(tagsDetails), | |
} | |
locks.ByID(subscriptionId) | |
defer locks.UnlockByID(subscriptionId) | |
tagPatchParamter := resources.TagsPatchResource{Operation: "Delete", Properties: &resource_tags} | |
updateTags, delerr := tagsClient.UpdateAtScope(context.Background(), "subscriptions/"+subscriptionId, tagPatchParamter) | |
if delerr != nil { | |
return fmt.Errorf("Failed to Remove tags %q from subscription %q: %+v", tags.Flatten(resource_tags.Tags), subscriptionId, delerr) | |
} | |
d.Set("tags", *updateTags.ID) | |
} |
@@ -400,7 +462,7 @@ func resourceSubscriptionDelete(d *pluginsdk.ResourceData, meta interface{}) err | |||
return fmt.Errorf("failed to cancel Subscription %q (Alias %q): %+v", subscriptionId, id.Name, err) | |||
} | |||
|
|||
return nil | |||
return resourceSubscriptionRead(d, meta) |
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 only ever return nil at the end of a delete, returning read here will result in Terraform presenting an erroneous not-found error to the user on success.
return resourceSubscriptionRead(d, meta) | |
return nil |
assert.ExistsInAzure(r), | ||
assert.Key("tags.%").HasValue("2"), | ||
assert.Key("tags.cost_center").HasValue("MSFT"), | ||
assert.Key("tags.environment").HasValue("Production"), |
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 we keep these in long-hand form as with the rest of the test suite?
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.
Looks like this one was missed from the last review? Can we get these in the form:
assert.ExistsInAzure(r), | |
assert.Key("tags.%").HasValue("2"), | |
assert.Key("tags.cost_center").HasValue("MSFT"), | |
assert.Key("tags.environment").HasValue("Production"), | |
check.That(data.ResourceName).ExistsInAzure(r), | |
check.That(data.ResourceName).Key("tags.%").HasValue("2"), | |
check.That(data.ResourceName).Key("tags.cost_center").HasValue("MSFT"), | |
check.That(data.ResourceName).Key("tags.environment").HasValue("Production"), |
The consistency helps us make bulk changes if/when we update approaches to the test framework.
subscriptionId := state.Attributes["subscription_id"] | ||
// atags := state.Attributes["tags"] | ||
tagsResp, err := client.Subscription.TagsClient.GetAtScope(ctx, "subscriptions/"+subscriptionId) | ||
if err != nil { | ||
return nil, fmt.Errorf("retrieving tags from subscription %q: %+v", subscriptionId, err) | ||
} | ||
fmt.Println(tagsResp.Properties) |
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.
This shouldn't be necessary. The exists and implicit read/import functionality will check the values for the tags. The Exists
function itself is simply to check the resource is present, not for any particular setting / configuration
subscriptionId := state.Attributes["subscription_id"] | |
// atags := state.Attributes["tags"] | |
tagsResp, err := client.Subscription.TagsClient.GetAtScope(ctx, "subscriptions/"+subscriptionId) | |
if err != nil { | |
return nil, fmt.Errorf("retrieving tags from subscription %q: %+v", subscriptionId, err) | |
} | |
fmt.Println(tagsResp.Properties) |
tags = { | ||
environment = "Production" | ||
cost_center = "MSFT" | ||
} |
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.
This is not supported here and will create a test config error when run
tags = { | |
environment = "Production" | |
cost_center = "MSFT" | |
} |
Thanks Steve, i will work on the recommendation and push the changes. |
Hi Steve, PR is ready to be merged with no conflicts. please take a moment to review and merge. Thank you. |
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 @crkg - Thanks for the updates, I've left a couple more comments inline below. If you can address those I'll make time to test this as the Subscription resource isn't compatible with our CI test runner currently, so needs running by hand.
Thanks!
return fmt.Errorf("Updating tag value %q for subscription %q: %+v", tags.Flatten(resource_tags.Tags), *subscriptionId, updateErr) | ||
} | ||
} | ||
d.Set("tags", *updateTags.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.
We can remove this, it should be handled by the Read
.
d.Set("tags", *updateTags.ID) |
assert.ExistsInAzure(r), | ||
assert.Key("tags.%").HasValue("2"), | ||
assert.Key("tags.cost_center").HasValue("MSFT"), | ||
assert.Key("tags.environment").HasValue("Production"), |
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.
Looks like this one was missed from the last review? Can we get these in the form:
assert.ExistsInAzure(r), | |
assert.Key("tags.%").HasValue("2"), | |
assert.Key("tags.cost_center").HasValue("MSFT"), | |
assert.Key("tags.environment").HasValue("Production"), | |
check.That(data.ResourceName).ExistsInAzure(r), | |
check.That(data.ResourceName).Key("tags.%").HasValue("2"), | |
check.That(data.ResourceName).Key("tags.cost_center").HasValue("MSFT"), | |
check.That(data.ResourceName).Key("tags.environment").HasValue("Production"), |
The consistency helps us make bulk changes if/when we update approaches to the test framework.
Hi @crkg - There's still an outstanding change requested from the previous review, specifically updating the test cases where |
…form-provider-azurerm into support_of_tags_11347
Hi Steve, sorry i missed to commit those changes in previous commit. thank you for the suggestions. its fixed please approve the workflow. |
@jackofallops ( Steve) can you please review and approve the changes. |
Hi @crkg - We have an issue testing subscription creation/update currently, so I'm afraid this is blocked until that support ticket is resolved. I'll loop back to this just as soon as we're able to test. |
Hi Steve, thank you. let me know when we are good to loop back this PR. |
Hi Steve, may i know if this feature can be plugged back, I was waiting for a confirmation on a blocked support ticket if its resolved? |
It would be great to see this get implemented soon. Thanks! |
Looking forward to having this useful feature in the provider soon! |
Looking forward to have this feature enabled. @crkg @jackofallops |
Hey all, sorry that this PR has been languishing here for so long. We're still working to unblock our ability to test - but progress has finally been made on that front so are now working towards getting this queued up. No timeframe to share yet but hopefully sooner than later! |
Hello, |
Hi @crkg - we've been able to resolve the testing issues for this. A lot has changed in the provider structure since this was first opened, so I've had to take your work forward to another PR to add changes I found to be necessary. Thanks again for your work on this, and your continued patience in getting this through. I'm going to close this PR out, please subscribe to #14445 for further updates. |
Thank you for the feature, much appreciated. |
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. |
@jackofallops this is reference to - #11347 conversation to add tags to azurerm subscription resource. please approve the workflow.