diff --git a/app/controllers/api/flavors_controller.rb b/app/controllers/api/flavors_controller.rb index 8f0cc35aa0..b6a9ecf60c 100644 --- a/app/controllers/api/flavors_controller.rb +++ b/app/controllers/api/flavors_controller.rb @@ -1,4 +1,25 @@ module Api class FlavorsController < BaseController + def create_resource(_type, _id, data) + task_id = Flavor.create_flavor_queue(User.current_user.id, EmsCloud.find(data['ems']['id']), data) + action_result(true, 'Creating Flavor', :task_id => task_id) + rescue => err + action_result(false, err.to_s) + end + + def delete_resource(type, id, _data = {}) + flavor = resource_search(id, type, collection_class(:flavors)) + raise "Delete not supported for #{flavor_ident(flavor)}" unless flavor.respond_to?(:delete_flavor_queue) + task_id = flavor.delete_flavor_queue(User.current_user.id) + action_result(true, "Deleting #{flavor_ident(flavor)}", :task_id => task_id) + rescue => err + action_result(false, err.to_s) + end + + private + + def flavor_ident(flavor) + "Flavor id:#{flavor.id} name: '#{flavor.name}'" + end end end diff --git a/config/api.yml b/config/api.yml index 2950faf4ab..21cb6ae01e 100644 --- a/config/api.yml +++ b/config/api.yml @@ -794,19 +794,26 @@ :identifier: flavor :options: - :collection - :verbs: *gp + :verbs: *gpd :klass: Flavor :collection_actions: :get: - :name: read :identifier: flavor_show_list :post: + - :name: delete + :identifier: flavor_delete - :name: query :identifier: flavor_show_list + - :name: create + :identifier: flavor_create :resource_actions: :get: - :name: read :identifier: flavor_show + :delete: + - :name: delete + :identifier: flavor_delete :floating_ips: :description: Floating IPs :identifier: floating_ip diff --git a/spec/requests/flavors_spec.rb b/spec/requests/flavors_spec.rb new file mode 100644 index 0000000000..74d1efdf86 --- /dev/null +++ b/spec/requests/flavors_spec.rb @@ -0,0 +1,76 @@ +RSpec.describe 'Flavors API' do + let(:flavor) { FactoryGirl.create(:flavor_openstack) } + + describe 'GET/api/flavors' do + it 'lists all the flavor bases with an appropriate role' do + flavor = FactoryGirl.create(:flavor_openstack) + + api_basic_authorize collection_action_identifier(:flavors, :read, :get) + + run_get(api_flavors_url) + + expected = { + 'count' => 1, + 'subcount' => 1, + 'name' => 'flavors', + 'resources' => [hash_including('href' => a_string_matching(api_flavors_url(nil, flavor.compressed_id)))] + } + expect(response.parsed_body).to include(expected) + expect(response).to have_http_status(:ok) + end + + it 'forbids access to flavor bases without an appropriate role' do + api_basic_authorize + + run_get(api_flavors_url) + + expect(response).to have_http_status(:forbidden) + end + end + + describe 'GET /api/flavors/:id' do + it 'will show a flavor base' do + api_basic_authorize action_identifier(:flavors, :read, :resource_actions, :get) + + flavor = FactoryGirl.create(:flavor) + + run_get(api_flavor_url(nil, flavor)) + + expected = { + 'href' => a_string_matching(api_flavors_url(nil, flavor.compressed_id)) + } + expect(response.parsed_body).to include(expected) + expect(response).to have_http_status(:ok) + end + + it 'forbids access to a flavor base' do + api_basic_authorize + + run_get(api_flavors_url) + + expect(response).to have_http_status(:forbidden) + end + end + + describe 'DELETE /api/flavors/:id' do + it 'will delete a flavor' do + flavor = FactoryGirl.create(:flavor) + + api_basic_authorize action_identifier(:flavors, :delete, :resource_actions, :delete) + + run_delete api_flavor_url(nil, flavor) + + expect(response).to have_http_status(:no_content) + end + + it 'will not delete a flavor without an appropriate role' do + flavor = FactoryGirl.create(:flavor) + + api_basic_authorize + + run_delete api_flavor_url(nil, flavor) + + expect(response).to have_http_status(:forbidden) + end + end +end