-
Notifications
You must be signed in to change notification settings - Fork 898
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
Bulk tag multiple VMs #13581
Bulk tag multiple VMs #13581
Conversation
@@ -85,7 +85,7 @@ def parse_tag(data) | |||
|
|||
def parse_tag_from_href(data) | |||
href = data["href"] | |||
tag = if href && href.match(%r{^.*/tags/#{CID_OR_ID_MATCHER}$}) | |||
tag = if href && href.match(%r{^.*/tags/#{ArRegion::CID_OR_ID_MATCHER}$}) |
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.
why was this needed ?
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.
getting uninitialized constant Api::Subcollections::Tags::CID_OR_ID_MATCHER
without it in the tests
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.
wow!! so better code coverage with the tests you've added 😍
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 there's a few of these around....perhaps this could be addressed in separate PR so it could be backported if needed? I wonder if it regressed when this became a mixin?
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.
@imtayadeway sounds good, will do!
{ id => tag_results } | ||
rescue => err | ||
{ id => action_result(false, err.to_s) } | ||
end |
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.
See if this can't be generalized, will be easier to implement assign_tags/unassign_tags to all other collections that support the tags subcollection.
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.
Looking at the api.yml, I see bulk assign_tags and unassign_tags could be implemented to the following collections for completion:
blueprints
clusters
data_stores
groups
hosts
providers
resource_pools
service_templates
services
templates
tenants
users
so generalizing assign_tags_resource and unassign_tags_resource, maybe as a mixin would be a 👍
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.
@abellotti sounds good to me! will do 👍
@@ -1890,6 +1890,8 @@ | |||
:identifier: vm_scan | |||
- :name: delete | |||
:identifier: vm_delete | |||
- :name: assign_tags | |||
:identifier: vm_tag |
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 take it unassign_tags will be a separate PR ?
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.
correct 👍
} | ||
expect(response).to have_http_status(:ok) | ||
expect(response.parsed_body).to include(expected) | ||
end |
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 would prefer action results similar to when assigning/unassigning tags on a
resource i.e. vms/72/tags, i.e. even though we can target multiple resources,
it's still an action performed (thus result) per tag.
so instead of:
{
"results": [
{
"72": [
{
"success": true,
"message": "Assigning Tag: category:'department' name:'finance'",
"href": "http://localhost:3000/api/vms/",
"tag_category": "department",
"tag_name": "finance"
},
{
"success": true,
"message": "Assigning Tag: category:'location' name:'ny'",
"href": "http://localhost:3000/api/vms/",
"tag_category": "location",
"tag_name": "ny"
}
],
"75": [
{
"success": true,
"message": "Assigning Tag: category:'department' name:'finance'",
"href": "http://localhost:3000/api/vms/",
"tag_category": "department",
"tag_name": "finance"
}
]
}
]
}
I'd rather get:
{
"results": [
{
"success": true,
"message": "Assigning Tag: category:'department' name:'finance'",
"href": "http://localhost:3000/api/vms/72",
"tag_category": "department",
"tag_name": "finance"
},
{
"success": true,
"message": "Assigning Tag: category:'location' name:'ny'",
"href": "http://localhost:3000/api/vms/72",
"tag_category": "location",
"tag_name": "ny"
},
{
"success": true,
"message": "Assigning Tag: category:'department' name:'finance'",
"href": "http://localhost:3000/api/vms/75",
"tag_category": "department",
"tag_name": "finance"
}
]
}
klass = collection_class(:tags) | ||
klass.find(from_cid(href.split('/').last)) | ||
end | ||
href = parse_href(data['href']) |
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.
still some work left to do on this PR but I saw some room for refactoring / reuse which would negate the need for #13597. Thoughts on this approach @abellotti @imtayadeway?
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.
LGTM, although I can't tell from the context if we're saying here that this needs to be a tag url. @abellotti ?
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 code should only be defining tag if the href is indeed for a tag, so we can't just simply use parse_href. the code can be generalized if this is needed somewhere where where we send in the collection of interest, (i.e. :tags) then that drives the generalization of the old lines 88-91. Not sure where else we do this though.
@@ -478,7 +478,7 @@ def expect_resource_has_tags(resource, tag_names) | |||
|
|||
run_post("#{blueprints_url(blueprint.id)}/tags", | |||
:action => "assign", | |||
:catagory => tag1[:category], | |||
:category => tag1[:category], |
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.
The refactoring above effort also shed light on the typos in these specs
@@ -140,7 +140,7 @@ def update_multiple_collections(is_subcollection, target, type, resources) | |||
update_one_collection(is_subcollection, target, type, rid, r) | |||
end | |||
raise BadRequestError, "No #{type} resources were specified for the #{action} action" if processed == 0 | |||
{"results" => results} | |||
{"results" => results.flatten} |
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.
Interesting. How was this failing before?
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.
@imtayadeway it wasn't failing - I believe this is the first action where it is returning an array of results per resource, so the results were being returned in a nested array ([[]]
) rather than how they are now, but .flatten
fixes that. Does that make sense?
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 wonder if the flattening shouldn't be in lower level, maybe assign_tags_resource.
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.
@abellotti it can't be placed there, because it calls assign_tags_resource
for each resource. So even though that is flattened, it is still returning a single array, which results in the results being an array of an array
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 just double checked my logic just to be sure and am not sure my explanation above made sense, so here is the full results if the flatten is moved up:
{"results"=>
[[{"success"=>true,
"message"=>"Assigning Tag: category:'department' name:'finance'",
"href"=>"http://www.example.com/api/vms/",
"tag_category"=>"department",
"tag_name"=>"finance",
"tag_href"=>"http://www.example.com/api/tags/10000000002666"}],
[{"success"=>true,
"message"=>"Assigning Tag: category:'cc' name:'001'",
"href"=>"http://www.example.com/api/vms/",
"tag_category"=>"cc",
"tag_name"=>"001",
"tag_href"=>"http://www.example.com/api/tags/10000000002670"}]]}
This pull request is not mergeable. Please rebase and repush. |
update spec references
@@ -89,7 +89,7 @@ def update_raw_power_state(state, *vms) | |||
context "Vm software subcollection" do | |||
let(:sw1) { FactoryGirl.create(:guest_application, :vm_or_template_id => vm.id, :name => "Word") } | |||
let(:sw2) { FactoryGirl.create(:guest_application, :vm_or_template_id => vm.id, :name => "Excel") } | |||
let(:vm_software_url) { "#{vms_url(vm.id)}/software" } |
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.
Although I approve of this change, it doesn't seem related to the rest of this PR
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.
@imtayadeway sorry - an accidental commit
Checked commits jntullo/manageiq@ae60628~...aac19cb with ruby 2.2.6, rubocop 0.47.1, and haml-lint 0.20.0 |
LGTM!! |
This enhancement to the API gives the ability to tag multiple VMs with multiple tags with one call. Sample request:
It will also accept the ID or HREF of a tag.
Sample response:
Each individual VM resource will return an array of results for each tag resource passed to it.
Additional PRs will be added to create bulk unassign and bulk assigning on services.
cc: @imtayadeway
@miq-bot add_label enhancement, api, euwe/no
@miq-bot assign @abellotti
Links