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

add_resource to Service api #14409

Merged
merged 4 commits into from
Mar 27, 2017
Merged

add_resource to Service api #14409

merged 4 commits into from
Mar 27, 2017

Conversation

jntullo
Copy link

@jntullo jntullo commented Mar 20, 2017

Adds "add_resource" action to Service resources

POST /api/services
{
   "action" : "add_resource",
   "resources" : [
      { "href" : "http://localhost:3000/api/services/3", "resource" : { "href" : "http://localhost:3000/api/load_balancers/12" }},
      { "href" : "http://localhost:3000/api/services/3", "resource" : { "href" : "http://localhot:3000/api/vms/4 }},
      { "href" : "http://localhost:3000/api/services/4", "resource" : { "href" : "http://localhost:3000/api/load_balancers/12" }},
      { "href" : "http://localhost:3000/api/services/5", "resource" : { "href" : "http://localhost:3000/api/load_balancers/12" }},
      ...
   ]
}
POST /api/services/:id
{
  "action" : "add_resource",
  "resources" : [
    { "resource" : { "href" : "http://localhost:3000/api/vms/11" }},
    { "resource" : { "href" : "http://localhost:3000/api/vms/12" }},
    { "resource" : { "href" : "http://localhost:3000/api/vms/13" }},
    ...
  ]
}

https://www.pivotaltracker.com/story/show/142057167

@miq-bot add_label enhancement, api, service
@miq-bot assign @abellotti
cc: @mkanoor

@miq-bot
Copy link
Member

miq-bot commented Mar 20, 2017

@jntullo Cannot apply the following label because they are not recognized: service

@@ -1932,6 +1932,8 @@
:identifier: service_admin
- :name: delete
:identifier: service_delete
- :name: add_resource
:identifier: service_edit
Copy link
Author

Choose a reason for hiding this comment

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

@mkanoor can you verify this product feature used? I didn't see one for assigning resources

Copy link
Member

Choose a reason for hiding this comment

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

@jntullo let's add this action on the collection too for completeness so we support bulk add_resources too. Thanks.

Copy link
Contributor

Choose a reason for hiding this comment

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

@jntullo I think the service_edit seems appropriate here

'message' => "Assigned resources to Service id:#{svc.id} name:'#{svc.name}'"
}
expect(response).to have_http_status(:ok)
expect(response.parsed_body).to eq(expected)
Copy link
Member

Choose a reason for hiding this comment

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

Hi @jntullo can you add an expect to make sure the svc got the vms added to it ? Thanks.

@mkanoor
Copy link
Contributor

mkanoor commented Mar 20, 2017

@jntullo @abellotti @gmcculloug
We have some concerns about adding any resource to service from external interfaces (Automate Method and now REST API). Previously this feature was available only from Automate Methods and exists as a method on the service model VM Object https://github.com/ManageIQ/manageiq/blob/master/lib/miq_automation_engine/service_models/miq_ae_service_vm.rb#L7

So one of the suggestions that @gmcculloug had was to move this method from the service model to app/models/vm.rb called 'add_to_service' so in this PR we would call

instead of

svc.add_resource(resource)

we would call

resource.add_to_service(service) if resource.respond_to?(:add_to_service)

This would allow us to create other models that can have the add_to_service method implemented if they allow the resource to be added to service and we would not have to change the REST API.

I can create a separate PR for the Vm.add_to_service which we can call from here.

@jntullo
Copy link
Author

jntullo commented Mar 20, 2017

sounds good @mkanoor

@mkanoor
Copy link
Contributor

mkanoor commented Mar 20, 2017

#14416

resource_type, resource_id = parse_href(resource_ref['href'])
resource = resource_search(resource_id, resource_type, collection_class(resource_type))
raise "Cannot assign #{resource_type} to #{service_ident(svc)}" unless resource.respond_to? :add_to_service
resource.add_to_service(svc)
Copy link
Contributor

Choose a reason for hiding this comment

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

@jntullo Should we make a validation pass first and make sure all elements in the array respond to :add_to_service before we even attempt to even add a single one. Otherwise we would have added some and raised an error for the first one that doesn't respond to :added_to_service and we can't undo.

Copy link
Author

Choose a reason for hiding this comment

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

@mkanoor hm. I can see the case for that. What do you think about sending back an individual response to each resource instead? so the response will tell you which ones failed and which ones succeeded

Copy link
Contributor

Choose a reason for hiding this comment

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

@abellotti What is the normal pattern in REST API, when we get an array of objects to work with do we send individual responses and how do we handle errors for one of the elements in the array, e.g. if the resource has been deleted?

Copy link
Author

Choose a reason for hiding this comment

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

@abellotti for other similar actions, ie bulk tagging, we limit it to the collection so that we can return all of the individual results. Should we do something similar here?

Copy link
Member

Choose a reason for hiding this comment

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

normal pattern as is an action result showing success/failure for each action. we do bend the rules on bulk assignment of tags on vms via the assign_tags, in which case we return one per assignment for the same reason you mentioned here above, see app/controllers/api/subcollections/tags.rb's assign_tags method. We could do something similar here.

svc = resource_search(id, type, collection_class(type))
data['resources'].each do |resource_ref|
resource_type, resource_id = parse_href(resource_ref['href'])
resource = resource_search(resource_id, resource_type, collection_class(resource_type))
Copy link
Contributor

Choose a reason for hiding this comment

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

@jntullo
Should we validate if the resource can be found, since we carry hrefs if the object is deleted in the meantime we won't have a resource?

@abellotti
Copy link
Member

with the change from:

svc.add_resource(resource)

to:

resource.add_to_service(service)

I wonder if the API signature should change and be an action on the vm, individual or bulk.

POST /api/vms
{
  "action" : "add_to_service",
  "resources" : [
    { "href" : "http://localhost:3000/api/vms/11", "service" : { "href" : "http://localhost:3000/api/services/101" } },
    { "href" : "http://localhost:3000/api/vms/12", "service" : { "href" : "http://localhost:3000/api/services/101" } },
    { "href" : "http://localhost:3000/api/vms/13", "service" : { "href" : "http://localhost:3000/api/services/101" } },
    ...
  ]
}

on individual vm:

POST /api/vms/11
{
  "action" : "add_to_service",
  "resource" : {
     "service" : { "href" : "http://localhost:3000/api/services/101" }
  }
}

supporting href and id in the service reference.

Thoughts ?

@jntullo
Copy link
Author

jntullo commented Mar 22, 2017

depends on if it will be extended to other resources that can be added or not, otherwise the API will need a new action on that resource.

@abellotti
Copy link
Member

@mkanoor are there plans to support adding other classes to services in the future ? any ideas on which ?

@abellotti
Copy link
Member

Ok, had a chat with @mkanoor, future resources could include orchestration_templates, load_balancers, and others. While some CI's are meant for the one service, things like load_balancers could be implemented to support multiple services.

@jntullo let's stick with the add_service action on services, but we do need to change the signature. Problem with using href for the vm above is problematic as it does not allow this action to be implemented for bulk, i.e. on the collection.

Could you update to support the following signature:

Targeting a single service:

POST /api/services/:id
{
  "action" : "add_resource",
  "resources" : [
    { "resource" : { "href" : "http://localhost:3000/api/vms/11" }},
    { "resource" : { "href" : "http://localhost:3000/api/vms/12" }},
    { "resource" : { "href" : "http://localhost:3000/api/vms/13" }},
    ...
  ]
}

Doing bulk add_service on multiple services:

POST /api/services
{
   "action" : "add_resource",
   "resources" : [
      { "href" : "http://localhost:3000/api/services/3", "resource" : { "href" : "http://localhost:3000/api/load_balancers/12" }},
      { "href" : "http://localhost:3000/api/services/4", "resource" : { "href" : "http://localhost:3000/api/load_balancers/12" }},
      { "href" : "http://localhost:3000/api/services/5", "resource" : { "href" : "http://localhost:3000/api/load_balancers/12" }},
      ...
   ]
}

And enable it for collection (and add collection level tests).

Thanks.

@jntullo
Copy link
Author

jntullo commented Mar 23, 2017

@abellotti I pushed up some changes, but I have some concerns about the use of this type of action on a resource because of the expected response (a single action result). I don't think that we have any other examples of returning multiple results for a single resource, unless I am mistaken, because bulk tagging is limited to a collection.

I played around with returning:

{
  "results": [
      { "success": true, "message": "Added resource..." },
      { "success": false, "message": "error message..." }
  ]
}

and wanted to get your thoughts around that. Another consideration is passing back the individual results within the single action result:

{
   "success": true,
   "message": "Added resources to service...",
   "results": [<individual action results>]
}

@abellotti
Copy link
Member

what do we do today with assign_tags, even though on a collection, for the one resource it targets, you can specify multiple tags with "tags" : [ ... ] ?

@jntullo
Copy link
Author

jntullo commented Mar 23, 2017

@abellotti we return the result of each individual tagging attempt. I think that it might be good to take that same approach with a descriptive description, ie Added resource <resource info> to Service <service info>

@abellotti
Copy link
Member

I see the issue with resources on the individual service, I still think we should support the same on both resource and for collection for bulk for consistency. Let's just support a single per request (or bulk) via "resource" : { "href" ... } in the payload, and drop the "resources" for now, we can enhance later.

See my diffs in abellotti@c4ab8d2

For adding multiple resources to the one service, this would simply be a bulk call to /api/services, with the href of the same service specified for each request.

POST /api/services/:id
{
  "action" : "add_resource",
  "resource" : {
    { "resource" : { "href" : "http://localhost:3000/api/vms/11" } }
  }
}

Doing bulk add_service on multiple services, also to add multiple vms to a service:

POST /api/services
{
   "action" : "add_resource",
   "resources" : [
      { "href" : "http://localhost:3000/api/services/3", "resource" : { "href" : "http://localhost:3000/api/load_balancers/12" }},
      { "href" : "http://localhost:3000/api/services/3", "resource" : { "href" : "http://localhot:3000/api/vms/4 }},
      { "href" : "http://localhost:3000/api/services/4", "resource" : { "href" : "http://localhost:3000/api/load_balancers/12" }},
      { "href" : "http://localhost:3000/api/services/5", "resource" : { "href" : "http://localhost:3000/api/load_balancers/12" }},
      ...
   ]
}

@abellotti
Copy link
Member

Thanks @jntullo for updating the PR. 😍 will merge when 🍏

more specs
@miq-bot
Copy link
Member

miq-bot commented Mar 24, 2017

Checked commits jntullo/manageiq@d755f99~...573c8c1 with ruby 2.2.6, rubocop 0.47.1, and haml-lint 0.20.0
3 files checked, 0 offenses detected
Everything looks good. 🍪

@abellotti abellotti merged commit be47178 into ManageIQ:master Mar 27, 2017
@abellotti abellotti added this to the Sprint 57 Ending Mar 27, 2017 milestone Mar 27, 2017
@jntullo jntullo deleted the enhancement/multiple_vms_to_service branch November 28, 2017 19:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants