commit e669d488e86301166a8f18de5d5f9eb0fd7bc386
Author: Alves Lobo Michael <michael.alveslobo@coreye.fr>
Date:   Fri Sep 11 10:37:04 2015 +0200

    Fixes #3650, #11600 - Compute Resource availability_zones, flavors, security_groups API v2 endpoints

diff --git a/app/controllers/api/v2/compute_resources_controller.rb b/app/controllers/api/v2/compute_resources_controller.rb
index 431f3c011..339a10251 100644
--- a/app/controllers/api/v2/compute_resources_controller.rb
+++ b/app/controllers/api/v2/compute_resources_controller.rb
@@ -13,8 +13,9 @@ module Api
       include Api::TaxonomyScope
 
       before_filter :find_resource, :only => [:show, :update, :destroy, :available_images, :associate,
-                                              :available_clusters, :available_folders, :available_networks,
-                                              :available_resource_pools, :available_storage_domains]
+                                              :available_clusters, :available_flavors, :available_folders,
+                                              :available_networks, :available_resource_pools, :available_security_groups, :available_storage_domains,
+                                              :available_zones]
 
       api :GET, "/compute_resources/", N_("List all compute resources")
       param_group :taxonomy_scope, ::Api::V2::BaseController
@@ -83,6 +84,13 @@ module Api
         render :available_clusters, :layout => 'api/v2/layouts/index_layout'
       end
 
+      api :GET, "/compute_resources/:id/available_flavors", N_("List available flavors for a compute resource")
+      param :id, :identifier, :required => true
+      def available_flavors
+        @available_flavors = @compute_resource.available_flavors
+        render :available_flavors, :layout => 'api/v2/layouts/index_layout'
+      end
+
       api :GET, "/compute_resources/:id/available_folders", N_("List available folders for a compute resource")
       param :id, :identifier, :required => true
       def available_folders
@@ -90,6 +98,13 @@ module Api
         render :available_folders, :layout => 'api/v2/layouts/index_layout'
       end
 
+      api :GET, "/compute_resources/:id/available_zones", N_("List available zone for a compute resource")
+      param :id, :identifier, :required => true
+      def available_zones
+        @available_zones = @compute_resource.available_zones
+        render :available_zones, :layout => 'api/v2/layouts/index_layout'
+      end
+
       api :GET, "/compute_resources/:id/available_networks", N_("List available networks for a compute resource")
       api :GET, "/compute_resources/:id/available_clusters/:cluster_id/available_networks", N_("List available networks for a compute resource cluster")
       param :id, :identifier, :required => true
@@ -117,6 +132,13 @@ module Api
         render :available_storage_domains, :layout => 'api/v2/layouts/index_layout'
       end
 
+      api :GET, "/compute_resources/:id/available_security_groups", N_("List available security groups for a compute resource")
+      param :id, :identifier, :required => true
+      def available_security_groups
+        @available_security_groups = @compute_resource.available_security_groups
+        render :available_security_groups, :layout => 'api/v2/layouts/index_layout'
+      end
+
       api :PUT, "/compute_resources/:id/associate/", N_("Associate VMs to Hosts")
       param :id, :identifier, :required => true
       def associate
@@ -139,7 +161,7 @@ module Api
 
       def action_permission
         case params[:action]
-          when 'available_images', 'available_clusters', 'available_folders', 'available_networks', 'available_resource_pools', 'available_storage_domains', 'associate'
+          when 'available_images', 'available_clusters', 'available_flavors', 'available_folders', 'available_networks', 'available_resource_pools', 'available_security_groups', 'available_storage_domains', 'available_zones', 'associate'
             :view
           else
             super
diff --git a/app/models/compute_resource.rb b/app/models/compute_resource.rb
index 5b6ed670d..e7b9318d3 100644
--- a/app/models/compute_resource.rb
+++ b/app/models/compute_resource.rb
@@ -199,6 +199,10 @@ class ComputeResource < ActiveRecord::Base
     false
   end
 
+  def available_zones
+    raise ::Foreman::Exception.new(N_("Not implemented for %s"), provider_friendly_name)
+  end
+
   def available_images
     []
   end
@@ -215,10 +219,18 @@ class ComputeResource < ActiveRecord::Base
     raise ::Foreman::Exception.new(N_("Not implemented for %s"), provider_friendly_name)
   end
 
+  def available_flavors
+    raise ::Foreman::Exception.new(N_("Not implemented for %s"), provider_friendly_name)
+  end
+
   def available_resource_pools
     raise ::Foreman::Exception.new(N_("Not implemented for %s"), provider_friendly_name)
   end
 
+  def available_security_groups
+    raise ::Foreman::Exception.new(N_("Not implemented for %s"), provider_friendly_name)
+  end
+
   def available_storage_domains(storage_domain = nil)
     raise ::Foreman::Exception.new(N_("Not implemented for %s"), provider_friendly_name)
   end
diff --git a/app/models/compute_resources/foreman/model/ec2.rb b/app/models/compute_resources/foreman/model/ec2.rb
index b04d14356..412893379 100644
--- a/app/models/compute_resources/foreman/model/ec2.rb
+++ b/app/models/compute_resources/foreman/model/ec2.rb
@@ -3,6 +3,7 @@ module Foreman::Model
     has_one :key_pair, :foreign_key => :compute_resource_id, :dependent => :destroy
 
     delegate :flavors, :subnets, :to => :client
+    delegate :security_groups, :flavors, :zones, :to => :self, :prefix => 'available'
     validates :user, :password, :presence => true
 
     after_create :setup_key_pair
diff --git a/app/services/foreman/access_permissions.rb b/app/services/foreman/access_permissions.rb
index ddf79f9e3..24209659d 100644
--- a/app/services/foreman/access_permissions.rb
+++ b/app/services/foreman/access_permissions.rb
@@ -81,7 +81,8 @@ Foreman::AccessControl.map do |permission_set|
     map.permission :view_compute_resources,    {:compute_resources => [:index, :show, :auto_complete_search, :ping, :available_images],
                                                 :"api/v1/compute_resources" => [:index, :show],
                                                 :"api/v2/compute_resources" => [:index, :show, :available_images, :available_clusters, :available_folders,
-                                                                                :available_networks, :available_resource_pools, :available_storage_domains]
+                                                                                :available_flavors, :available_networks, :available_resource_pools,
+                                                                                :available_security_groups, :available_storage_domains, :available_zones]
     }
     map.permission :create_compute_resources,  {:compute_resources => [:new, :create].push(*ajax_actions),
                                                 :"api/v1/compute_resources" => [:create],
diff --git a/app/views/api/v2/compute_resources/available_flavors.rabl b/app/views/api/v2/compute_resources/available_flavors.rabl
new file mode 100644
index 000000000..fcc806dd5
--- /dev/null
+++ b/app/views/api/v2/compute_resources/available_flavors.rabl
@@ -0,0 +1,3 @@
+collection @available_flavors
+
+attribute :name, :id
diff --git a/app/views/api/v2/compute_resources/available_security_groups.rabl b/app/views/api/v2/compute_resources/available_security_groups.rabl
new file mode 100644
index 000000000..d64ce69f2
--- /dev/null
+++ b/app/views/api/v2/compute_resources/available_security_groups.rabl
@@ -0,0 +1,3 @@
+collection @available_security_groups
+
+attribute :name, :group_id
diff --git a/app/views/api/v2/compute_resources/available_zones.rabl b/app/views/api/v2/compute_resources/available_zones.rabl
new file mode 100644
index 000000000..680223e68
--- /dev/null
+++ b/app/views/api/v2/compute_resources/available_zones.rabl
@@ -0,0 +1,5 @@
+collection @available_zones, root_object: false
+
+node :name do |name|
+  name
+end
diff --git a/config/routes/api/v2.rb b/config/routes/api/v2.rb
index f2a1b083c..1fb0b0acc 100644
--- a/config/routes/api/v2.rb
+++ b/config/routes/api/v2.rb
@@ -241,11 +241,14 @@ Foreman::Application.routes.draw do
           get :available_images, :on => :member
           get :available_clusters, :on => :member
           get :available_folders, :on => :member
+          get :available_flavors, :on => :member
           get :available_networks, :on => :member
+          get :available_security_groups, :on => :member
           get :available_storage_domains, :on => :member
           get 'available_storage_domains/(:storage_domain)', :to => 'compute_resources#available_storage_domains', :on => :member
           get 'available_clusters/(:cluster_id)/available_networks', :to => 'compute_resources#available_networks', :on => :member
           get 'available_clusters/(:cluster_id)/available_resource_pools', :to => 'compute_resources#available_resource_pools', :on => :member
+          get :available_zones, :on => :member
           put :associate, :on => :member
           (resources :locations, :only => [:index, :show]) if SETTINGS[:locations_enabled]
           (resources :organizations, :only => [:index, :show]) if SETTINGS[:organizations_enabled]
diff --git a/test/functional/api/v2/compute_resources_controller_test.rb b/test/functional/api/v2/compute_resources_controller_test.rb
index 3cf540164..fb917d4fc 100644
--- a/test/functional/api/v2/compute_resources_controller_test.rb
+++ b/test/functional/api/v2/compute_resources_controller_test.rb
@@ -148,6 +148,36 @@ class Api::V2::ComputeResourcesControllerTest < ActionController::TestCase
     assert !available_storage_domains.empty?
   end
 
+  context 'ec2' do
+    setup do
+      @ec2_object = Object.new
+      @ec2_object.stubs(:name).returns('test_ec2_object')
+    end
+
+    teardown do
+      assert_response :success
+      available_objects = ActiveSupport::JSON.decode(@response.body)
+      assert_not_empty available_objects
+    end
+
+    test "should get available flavors" do
+      @ec2_object.stubs(:id).returns('123')
+      Foreman::Model::EC2.any_instance.stubs(:available_flavors).returns([@ec2_object])
+      get :available_flavors, { :id => compute_resources(:ec2).to_param }
+    end
+
+    test "should get available security groups" do
+      @ec2_object.stubs(:group_id).returns('123')
+      Foreman::Model::EC2.any_instance.stubs(:available_security_groups).returns([@ec2_object])
+      get :available_security_groups, { :id => compute_resources(:ec2).to_param }
+    end
+
+    test "should get available zones" do
+      Foreman::Model::EC2.any_instance.stubs(:available_zones).returns(['test_ec2_object'])
+      get :available_zones, { :id => compute_resources(:ec2).to_param }
+    end
+  end
+
   context 'vmware' do
     setup do
       @vmware_object = Object.new
