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
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions app/controllers/api/services_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,25 @@ def edit_resource(type, id, data)
super(type, id, attributes)
end

def add_resource_resource(type, id, data)
raise "Must specify a service href or id to add_resource to" unless id
svc = resource_search(id, type, collection_class(type))

resource_href = data.fetch_path("resource", "href")
raise "Must specify a resource reference" unless resource_href

resource_type, resource_id = parse_href(resource_href)
raise "Invalid resource href specified #{resource_href}" unless resource_type && resource_id

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)
action_result(true, "Assigned resource #{resource_type} id:#{resource_id} to #{service_ident(svc)}")
rescue => err
action_result(false, err.to_s)
end

def reconfigure_resource(type, id = nil, data = nil)
raise BadRequestError, "Must specify an id for Reconfiguring a #{type} resource" unless id

Expand Down
4 changes: 4 additions & 0 deletions config/api.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1911,6 +1911,8 @@
:identifier: service_tag
- :name: unassign_tags
:identifier: service_tag
- :name: add_resource
:identifier: service_edit
:resource_actions:
:get:
- :name: read
Expand All @@ -1934,6 +1936,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

:delete:
- :name: delete
:identifier: service_delete
Expand Down
4 changes: 2 additions & 2 deletions spec/requests/api/custom_actions_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def expect_result_to_have_custom_actions_hash
run_get services_url(svc1.id)

expect_result_to_have_keys(%w(id href actions))
expect(response.parsed_body["actions"].collect { |a| a["name"] }).to match_array(%w(edit))
expect(response.parsed_body["actions"].collect { |a| a["name"] }).to match_array(%w(edit add_resource))
end
end

Expand All @@ -91,7 +91,7 @@ def expect_result_to_have_custom_actions_hash
run_get services_url(svc1.id)

expect_result_to_have_keys(%w(id href actions))
expect(response.parsed_body["actions"].collect { |a| a["name"] }).to match_array(%w(edit button1 button2 button3))
expect(response.parsed_body["actions"].collect { |a| a["name"] }).to match_array(%w(edit button1 button2 button3 add_resource))
end

it "supports the custom_actions attribute" do
Expand Down
125 changes: 125 additions & 0 deletions spec/requests/api/services_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -667,4 +667,129 @@ def expect_svc_with_vms
expect(response).to have_http_status(:forbidden)
end
end

describe 'add_resource' do
let(:vm1) { FactoryGirl.create(:vm_vmware) }
let(:vm2) { FactoryGirl.create(:vm_vmware) }

it 'can add vm to services by href with an appropriate role' do
api_basic_authorize(collection_action_identifier(:services, :add_resource))
request = {
'action' => 'add_resource',
'resources' => [
{ 'href' => services_url(svc.id), 'resource' => {'href' => vms_url(vm1.id)} },
{ 'href' => services_url(svc1.id), 'resource' => {'href' => vms_url(vm2.id)} }
]
}

run_post(services_url, request)

expected = {
'results' => [
{ 'success' => true, 'message' => "Assigned resource vms id:#{vm1.id} to Service id:#{svc.id} name:'#{svc.name}'"},
{ 'success' => true, 'message' => "Assigned resource vms id:#{vm2.id} to Service id:#{svc1.id} name:'#{svc1.name}'"}
]
}

expect(response).to have_http_status(:ok)
expect(response.parsed_body).to eq(expected)
expect(svc.reload.vms).to eq([vm1])
expect(svc1.reload.vms).to eq([vm2])
end

it 'returns individual success and failures' do
user = FactoryGirl.create(:user)
api_basic_authorize(collection_action_identifier(:services, :add_resource))
request = {
'action' => 'add_resource',
'resources' => [
{ 'href' => services_url(svc.id), 'resource' => {'href' => vms_url(vm1.id)} },
{ 'href' => services_url(svc1.id), 'resource' => {'href' => users_url(user.id)} }
]
}

run_post(services_url, request)

expected = {
'results' => [
{ 'success' => true, 'message' => "Assigned resource vms id:#{vm1.id} to Service id:#{svc.id} name:'#{svc.name}'"},
{ 'success' => false, 'message' => "Cannot assign users to Service id:#{svc1.id} name:'#{svc1.name}'"}
]
}

expect(response).to have_http_status(:ok)
expect(response.parsed_body).to eq(expected)
expect(svc.reload.vms).to eq([vm1])
end

it 'requires a valid resource' do
api_basic_authorize(collection_action_identifier(:services, :add_resource))
request = {
'action' => 'add_resource',
'resource' => { 'resource' => { 'href' => '1' } }
}

run_post(services_url(svc.id), request)

expected = { 'success' => false, 'message' => "Invalid resource href specified 1"}

expect(response).to have_http_status(:ok)
expect(response.parsed_body).to eq(expected)
end

it 'requires the resource to respond to add_to_service' do
user = FactoryGirl.create(:user)
api_basic_authorize(collection_action_identifier(:services, :add_resource))
request = {
'action' => 'add_resource',
'resource' => { 'resource' => { 'href' => users_url(user.id) } }
}

run_post(services_url(svc.id), request)

expected = { 'success' => false, 'message' => "Cannot assign users to Service id:#{svc.id} name:'#{svc.name}'"}

expect(response).to have_http_status(:ok)
expect(response.parsed_body).to eq(expected)
end

it 'requires a resource reference' do
api_basic_authorize(collection_action_identifier(:services, :add_resource))
request = {
'action' => 'add_resource',
'resource' => { 'resource' => {} }
}

run_post(services_url(svc.id), request)

expected = { 'success' => false, 'message' => "Must specify a resource reference"}

expect(response).to have_http_status(:ok)
expect(response.parsed_body).to eq(expected)
end

it 'can add a vm to a resource with appropriate role' do
api_basic_authorize(collection_action_identifier(:services, :add_resource))
request = {
'action' => 'add_resource',
'resource' => { 'resource' => {'href' => vms_url(vm1.id)} }
}

run_post(services_url(svc.id), request)

expected = { 'success' => true, 'message' => "Assigned resource vms id:#{vm1.id} to Service id:#{svc.id} name:'#{svc.name}'"}

expect(response).to have_http_status(:ok)
expect(response.parsed_body).to eq(expected)
expect(svc.reload.vms).to eq([vm1])
end

it 'cannot add multiple vms to multiple services by href without an appropriate role' do
api_basic_authorize

run_post(services_url, 'action' => 'add_resource')

expect(response).to have_http_status(:forbidden)
end
end
end