commit 2de7832d6970797dc2e7c8247502d8bf130445b2
Author: Ohad Levy <ohadlevy@gmail.com>
Date:   Thu Jan 9 11:41:38 2014 +0200

    fixes #3099 - Adding parameters to locations and organizations

diff --git a/app/assets/javascripts/host_edit.js b/app/assets/javascripts/host_edit.js
index d1e185044..7720adfee 100644
--- a/app/assets/javascripts/host_edit.js
+++ b/app/assets/javascripts/host_edit.js
@@ -420,7 +420,7 @@ function override_param(item){
   var v = param.find('[id^=value_]').val();
 
   $('#parameters').find('.btn-success').click();
-  var new_param = param.closest('.tab-pane').find('[id*=host_host_parameters]:visible').last().parent();
+  var new_param = param.closest('.tab-pane').find('[id*=host_host_parameters]:visible').last().parent().parent();
   new_param.find('[id$=_name]').val(n);
   new_param.find('[id$=_value]').val(v);
   mark_params_override();
diff --git a/app/controllers/api/v2/parameters_controller.rb b/app/controllers/api/v2/parameters_controller.rb
index 07546aa76..bdc395631 100644
--- a/app/controllers/api/v2/parameters_controller.rb
+++ b/app/controllers/api/v2/parameters_controller.rb
@@ -20,10 +20,14 @@ module Api
       api :GET, "/hostgroups/:hostgroup_id/parameters", "List all parameters for hostgroup"
       api :GET, "/domains/:domain_id/parameters", "List all parameters for domain"
       api :GET, "/operatingsystems/:operatingsystem_id/parameters", "List all parameters for operating system"
+      api :GET, "/locations/:location_id/parameters", "List all parameters for location"
+      api :GET, "/organizations/:organization_id/parameters", "List all parameters for organization"
       param :host_id, String, :desc => "id of host"
       param :hostgroup_id, String, :desc => "id of hostgroup"
       param :domain_id, String, :desc => "id of domain"
       param :operatingsystem_id, String, :desc => "id of operating system"
+      param :location_id, String, :desc => "id of location"
+      param :organization_id, String, :desc => "id of organization"
       param :page, String, :desc => "paginate results"
       param :per_page, String, :desc => "number of entries per request"
 
@@ -35,10 +39,14 @@ module Api
       api :GET, "/hostgroups/:hostgroup_id/parameters/:id", "Show a nested parameter for hostgroup"
       api :GET, "/domains/:domain_id/parameters/:id", "Show a nested parameter for domain"
       api :GET, "/operatingsystems/:operatingsystem_id/parameters/:id", "Show a nested parameter for operating system"
+      api :GET, "/locations/:location_id/parameters/:id", "Show a nested parameter for location"
+      api :GET, "/organizations/:organization_id/parameters/:id", "Show a nested parameter for organization"
       param :host_id, String, :desc => "id of host"
       param :hostgroup_id, String, :desc => "id of hostgroup"
       param :domain_id, String, :desc => "id of domain"
       param :operatingsystem_id, String, :desc => "id of operating system"
+      param :location_id, String, :desc => "id of location"
+      param :organization_id, String, :desc => "id of organization"
       param :id, String, :required => true, :desc => "id of parameter"
 
       def show
@@ -48,10 +56,14 @@ module Api
       api :POST, "/hostgroups/:hostgroup_id/parameters/", "Create a nested parameter for hostgroup"
       api :POST, "/domains/:domain_id/parameters/", "Create a nested parameter for domain"
       api :POST, "/operatingsystems/:operatingsystem_id/parameters/", "Create a nested parameter for operating system"
+      api :POST, "/locations/:location_id/parameters/", "Create a nested parameter for location"
+      api :POST, "/organizations/:organization_id/parameters/", "Create a nested parameter for organization"
       param :host_id, String, :desc => "id of host"
       param :hostgroup_id, String, :desc => "id of hostgroup"
       param :domain_id, String, :desc => "id of domain"
       param :operatingsystem_id, String, :desc => "id of operating system"
+      param :location_id, String, :desc => "id of location"
+      param :organization_id, String, :desc => "id of organization"
       param :parameter, Hash, :required => true do
         param :name, String
         param :value, String
@@ -66,10 +78,14 @@ module Api
       api :PUT, "/hostgroups/:hostgroup_id/parameters/:id", "Update a nested parameter for hostgroup"
       api :PUT, "/domains/:domain_id/parameters/:id", "Update a nested parameter for domain"
       api :PUT, "/operatingsystems/:operatingsystem_id/parameters/:id", "Update a nested parameter for operating system"
+      api :PUT, "/locations/:location_id/parameters/:id", "Update a nested parameter for location"
+      api :PUT, "/organizations/:organization_id/parameters/:id", "Update a nested parameter for organization"
       param :host_id, String, :desc => "id of host"
       param :hostgroup_id, String, :desc => "id of hostgroup"
       param :domain_id, String, :desc => "id of domain"
       param :operatingsystem_id, String, :desc => "id of operating system"
+      param :location_id, String, :desc => "id of location"
+      param :organization_id, String, :desc => "id of organization"
       param :id, String, :required => true, :desc => "id of parameter"
       param :parameter, Hash, :required => true do
         param :name, String
@@ -84,10 +100,14 @@ module Api
       api :DELETE, "/hostgroups/:hostgroup_id/parameters/:id", "Delete a nested parameter for hostgroup"
       api :DELETE, "/domains/:domain_id/parameters/:id", "Delete a nested parameter for domain"
       api :DELETE, "/operatingsystems/:operatingsystem_id/parameters/:id", "Delete a nested parameter for operating system"
+      api :DELETE, "/locations/:location_id/parameters/:id", "Delete a nested parameter for location"
+      api :DELETE, "/organizations/:organization_id/parameters/:id", "Delete a nested parameter for organization"
       param :host_id, String, :desc => "id of host"
       param :hostgroup_id, String, :desc => "id of hostgroup"
       param :domain_id, String, :desc => "id of domain"
       param :operatingsystem_id, String, :desc => "id of operating system"
+      param :location_id, String, :desc => "id of location"
+      param :organization_id, String, :desc => "id of organization"
       param :id, String, :required => true, :desc => "id of parameter"
 
       def destroy
@@ -98,6 +118,14 @@ module Api
       api :DELETE, "/hostgroups/:hostgroup_id/parameters", "Delete all nested parameters for hostgroup"
       api :DELETE, "/domains/:domain_id/parameters", "Delete all nested parameters for domain"
       api :DELETE, "/operatingsystems/:operatingsystem_id/parameters", "Delete all nested parameters for operating system"
+      api :DELETE, "/locations/:location_id/parameters", "Delete all nested parameter for location"
+      api :DELETE, "/organizations/:organization_id/parameters", "Delete all nested parameter for organization"
+      param :host_id, String, :desc => "id of host"
+      param :hostgroup_id, String, :desc => "id of hostgroup"
+      param :domain_id, String, :desc => "id of domain"
+      param :operatingsystem_id, String, :desc => "id of operating system"
+      param :location_id, String, :desc => "id of location"
+      param :organization_id, String, :desc => "id of organization"
 
       def reset
         @parameter = nested_obj.send(parameters_method)
@@ -112,7 +140,7 @@ module Api
       end
 
       def allowed_nested_id
-        %w(host_id hostgroup_id domain_id operatingsystem_id)
+        %w(host_id hostgroup_id domain_id operatingsystem_id location_id organization_id)
       end
 
       def find_parameter
diff --git a/app/helpers/common_parameters_helper.rb b/app/helpers/common_parameters_helper.rb
index 7ae6b8185..a0fc1f4e1 100644
--- a/app/helpers/common_parameters_helper.rb
+++ b/app/helpers/common_parameters_helper.rb
@@ -15,7 +15,7 @@ module CommonParametersHelper
     content_tag :div, :class => "form-group condensed"  do
       text_area_tag("value_#{value[:value]}", value[:value], :rows => (value[:value].to_s.lines.count || 1 rescue 1),
                     :class => "col-md-5", :disabled => true) +
-      content_tag(:span, :class => "help-block") { popover(_("Additional info"), _("<b>Source:</b> %s") % (value[:source]))}
+      content_tag(:span, :class => "help-block") { popover(_("Additional info"), _("<b>Source:</b> %s") % _(value[:source].to_s))}
     end
   end
 
diff --git a/app/models/host/managed.rb b/app/models/host/managed.rb
index 7226b6216..0fdff7af5 100644
--- a/app/models/host/managed.rb
+++ b/app/models/host/managed.rb
@@ -333,11 +333,19 @@ class Host::Managed < Host::Base
   def host_inherited_params include_source = false
     hp = {}
     # read common parameters
-    CommonParameter.all.each {|p| hp.update Hash[p.name => include_source ? {:value => p.value, :source => :common} : p.value] }
+    CommonParameter.all.each {|p| hp.update Hash[p.name => include_source ? {:value => p.value, :source => N_('common').to_sym} : p.value] }
+    if SETTINGS[:organizations_enabled] && organization
+      # read organization parameters
+      organization.parameters.each {|p| hp.update Hash[p.name => include_source ? {:value => p.value, :source => N_('organization').to_sym} : p.value] }
+    end
+    if SETTINGS[:locations_enabled] && location
+      # read location parameters
+      location.parameters.each {|p| hp.update Hash[p.name => include_source ? {:value => p.value, :source => N_('location').to_sym} : p.value] }
+    end
     # read domain parameters
-    domain.domain_parameters.each {|p| hp.update Hash[p.name => include_source ? {:value => p.value, :source => :domain} : p.value] } unless domain.nil?
+    domain.domain_parameters.each {|p| hp.update Hash[p.name => include_source ? {:value => p.value, :source => N_('domain').to_sym} : p.value] } unless domain.nil?
     # read OS parameters
-    operatingsystem.os_parameters.each {|p| hp.update Hash[p.name => include_source ? {:value => p.value, :source => :os} : p.value] } unless operatingsystem.nil?
+    operatingsystem.os_parameters.each {|p| hp.update Hash[p.name => include_source ? {:value => p.value, :source => N_('os').to_sym} : p.value] } unless operatingsystem.nil?
     # read group parameters only if a host belongs to a group
     hp.update hostgroup.parameters(include_source) unless hostgroup.nil?
     hp
diff --git a/app/models/hostgroup.rb b/app/models/hostgroup.rb
index 3f1a54794..e0d9ed654 100644
--- a/app/models/hostgroup.rb
+++ b/app/models/hostgroup.rb
@@ -113,7 +113,7 @@ class Hostgroup < ActiveRecord::Base
     # otherwise we might be overwriting the hash in the wrong order.
     groups = ids.size == 1 ? [self] : Hostgroup.includes(:group_parameters).sort_by_ancestry(Hostgroup.find(ids))
     groups.each do |hg|
-      hg.group_parameters.each {|p| hash[p.name] = include_source ? {:value => p.value, :source => :hostgroup} : p.value }
+      hg.group_parameters.each {|p| hash[p.name] = include_source ? {:value => p.value, :source => N_('hostgroup').to_sym} : p.value }
     end
     hash
   end
diff --git a/app/models/parameters/location_parameter.rb b/app/models/parameters/location_parameter.rb
new file mode 100644
index 000000000..dedfb218b
--- /dev/null
+++ b/app/models/parameters/location_parameter.rb
@@ -0,0 +1,16 @@
+class LocationParameter < Parameter
+  belongs_to :location, :foreign_key => :reference_id
+  audited :except => [:priority], :associated_with => :location, :allow_mass_assignment => true
+  validates :name, :uniqueness => {:scope => :reference_id}
+
+  private
+  def enforce_permissions operation
+    # We get called again with the operation being set to create
+    return true if operation == "edit" and new_record?
+    return true if User.current.allowed_to?("#{operation}_locations".to_sym)
+
+    errors.add(:base, _("You do not have permission to %s this location parameter") % operation)
+    false
+  end
+
+end
diff --git a/app/models/parameters/organization_parameter.rb b/app/models/parameters/organization_parameter.rb
new file mode 100644
index 000000000..aeec4c134
--- /dev/null
+++ b/app/models/parameters/organization_parameter.rb
@@ -0,0 +1,16 @@
+class OrganizationParameter < Parameter
+  belongs_to :organization, :foreign_key => :reference_id
+  audited :except => [:priority], :associated_with => :organization, :allow_mass_assignment => true
+  validates :name, :uniqueness => {:scope => :reference_id}
+
+  private
+  def enforce_permissions operation
+    # We get called again with the operation being set to create
+    return true if operation == "edit" and new_record?
+    return true if User.current.allowed_to?("#{operation}_organizations".to_sym)
+
+    errors.add(:base, _("You do not have permission to %s this organization parameter") % operation)
+    false
+  end
+
+end
diff --git a/app/models/taxonomies/location.rb b/app/models/taxonomies/location.rb
index 7d0b21c15..d7e976e31 100644
--- a/app/models/taxonomies/location.rb
+++ b/app/models/taxonomies/location.rb
@@ -4,6 +4,9 @@ class Location < Taxonomy
   has_and_belongs_to_many :organizations
   has_many_hosts :dependent => :nullify
 
+  has_many :parameters, :dependent => :destroy, :foreign_key => :reference_id, :class_name => "LocationParameter"
+  accepts_nested_attributes_for :parameters, :reject_if => lambda { |a| a[:value].blank? }, :allow_destroy => true
+
   scope :completer_scope, lambda { |opts| my_locations }
 
   scope :my_locations, lambda {
diff --git a/app/models/taxonomies/organization.rb b/app/models/taxonomies/organization.rb
index 0a5b85016..745403f5a 100644
--- a/app/models/taxonomies/organization.rb
+++ b/app/models/taxonomies/organization.rb
@@ -3,6 +3,8 @@ class Organization < Taxonomy
 
   has_and_belongs_to_many :locations
   has_many_hosts :dependent => :nullify
+  has_many :parameters, :dependent => :destroy, :foreign_key => :reference_id, :class_name => "OrganizationParameter"
+  accepts_nested_attributes_for :parameters, :reject_if => lambda { |a| a[:value].blank? }, :allow_destroy => true
 
   scope :completer_scope, lambda { |opts| my_organizations }
 
diff --git a/app/views/common_parameters/_parameter.html.erb b/app/views/common_parameters/_parameter.html.erb
index de72f40e2..834793f66 100644
--- a/app/views/common_parameters/_parameter.html.erb
+++ b/app/views/common_parameters/_parameter.html.erb
@@ -1,9 +1,11 @@
 <div class="fields">
   <table class="row">
   <tr class="form-group <%= 'error' if f.object.errors.any? %>">
-    <td class="col-md-3">
-      <%= content_tag(:input, '', :class => "form-control", :disabled => true,  :value => _('Global'), :type=> :text ) if controller_name =~ /(host|hostgroup)/ %>
+    <% if controller_name =~ /(host|hostgroup)/ %>
+    <td class="col-md-2">
+      <%= content_tag(:input, '', :class => "form-control", :disabled => true,  :value => _('Global'), :type=> :text ) %>
     </td>
+    <% end %>
     <td class="col-md-2">
       <%= f.text_field(:name,  :class => "form-control", :disabled => (not authorized_via_my_scope("host_editing", "edit_params")), :placeholder => _("Name")) %>
     </td>
diff --git a/app/views/taxonomies/_form.html.erb b/app/views/taxonomies/_form.html.erb
index 558c70d0e..6a0d30af4 100644
--- a/app/views/taxonomies/_form.html.erb
+++ b/app/views/taxonomies/_form.html.erb
@@ -1,8 +1,9 @@
 <% javascript 'taxonomy' %>
 <%= form_for taxonomy do |f| %>
-    <%= base_errors_for taxonomy %>
-    <%= text_f f, :name %>
-    <ul class="nav nav-tabs" data-tabs="tabs">
+  <%= base_errors_for taxonomy %>
+  <%= text_f f, :name %>
+  <div class="form-group row">
+    <ul class="nav nav-pills nav-stacked col-md-3" data-tabs="pills">
       <li class="active"><a href="#users" data-toggle="tab"><%= _("Users") %></a></li>
       <li><a href="#smart_proxies" data-toggle="tab"><%= _("Smart Proxies") %></a></li>
       <% if SETTINGS[:unattended] %>
@@ -19,88 +20,94 @@
       <% elsif taxonomy.is_a?(Location) && SETTINGS[:organizations_enabled] %>
         <li><a href="#organizations" data-toggle="tab"><%= _("Organizations") %></a></li>
     <% end %>
+      <li><a href="#params" data-toggle="tab"><%= _("Parameters") %></a></li>
     </ul>
 
-    <div class="tab-content">
+    <div class="tab-content col-md-9">
       <div class="tab-pane active" id="users">
-        <%= checkbox_f(f, :ignore_types, {:label => "", :help_text => _("All Users"), :multiple => true, :onchange => 'ignore_checked(this)'}, "User") %>
+        <%= checkbox_f(f, :ignore_types, {:label => _("All users"), :multiple => true, :onchange => 'ignore_checked(this)'}, "User") %>
         <%= multiple_selects f, :users, User.except_admin, taxonomy.selected_ids[:user_ids],
-           {:disabled => taxonomy.used_and_selected_ids[:user_ids], :label => ''},
+           {:disabled => taxonomy.used_and_selected_ids[:user_ids], :label => _('Select users')},
            {'data-mismatches' => taxonomy.need_to_be_selected_ids[:user_ids].to_json} %>
       </div>
 
       <div class="tab-pane" id="smart_proxies">
-        <%= checkbox_f(f, :ignore_types, {:label => "", :help_text => _("All Smart Proxies"), :multiple => true, :onchange => 'ignore_checked(this)'}, "SmartProxy") %>
+        <%= checkbox_f(f, :ignore_types, {:label => _("All smart proxies"), :multiple => true, :onchange => 'ignore_checked(this)'}, "SmartProxy") %>
         <%= multiple_selects f, :smart_proxies, SmartProxy, taxonomy.selected_ids[:smart_proxy_ids],
-           {:disabled => taxonomy.used_and_selected_ids[:smart_proxy_ids], :label => ''},
+           {:disabled => taxonomy.used_and_selected_ids[:smart_proxy_ids], :label => _('Select smart proxies')},
            {'data-mismatches' => taxonomy.need_to_be_selected_ids[:smart_proxy_ids].to_json} %>
       </div>
 
       <% if SETTINGS[:unattended] %>
         <div class="tab-pane" id="subnets">
-          <%= checkbox_f(f, :ignore_types, {:label => "", :help_text => _("All Subnets"), :multiple => true, :onchange => 'ignore_checked(this)'}, "Subnet") %>
+          <%= checkbox_f(f, :ignore_types, {:label => _("All subnets"), :multiple => true, :onchange => 'ignore_checked(this)'}, "Subnet") %>
           <%= multiple_selects f, :subnets, Subnet, taxonomy.selected_ids[:subnet_ids],
-            {:disabled => taxonomy.used_and_selected_ids[:subnet_ids], :label => ''},
+            {:disabled => taxonomy.used_and_selected_ids[:subnet_ids], :label => _('Select subnets')},
             {'data-mismatches' => taxonomy.need_to_be_selected_ids[:subnet_ids].to_json} %>
         </div>
 
         <div class="tab-pane" id="compute_resources">
-          <%= checkbox_f(f, :ignore_types, {:label => "", :help_text => _("All Compute Resources"), :multiple => true, :onchange => 'ignore_checked(this)'}, "ComputeResource") %>
+          <%= checkbox_f(f, :ignore_types, {:label => _("All compute resources"), :multiple => true, :onchange => 'ignore_checked(this)'}, "ComputeResource") %>
           <%= multiple_selects f, :compute_resources, ComputeResource, taxonomy.selected_ids[:compute_resource_ids],
-            {:disabled => taxonomy.used_and_selected_ids[:compute_resource_ids], :label => ''},
+            {:disabled => taxonomy.used_and_selected_ids[:compute_resource_ids], :label => _('Select compute resources')},
             {'data-mismatches' => taxonomy.need_to_be_selected_ids[:compute_resource_ids].to_json} %>
         </div>
 
         <div class="tab-pane" id="media">
-          <%= checkbox_f(f, :ignore_types, {:label => "", :help_text => _("All Media"), :multiple => true, :onchange => 'ignore_checked(this)'}, "Medium") %>
+          <%= checkbox_f(f, :ignore_types, {:label => _("All media"), :multiple => true, :onchange => 'ignore_checked(this)'}, "Medium") %>
           <%= multiple_selects f, :media, Medium, taxonomy.selected_ids[:medium_ids],
-            {:disabled => taxonomy.used_and_selected_ids[:medium_ids], :label => ''},
+            {:disabled => taxonomy.used_and_selected_ids[:medium_ids], :label => _('Select media')},
             {'data-mismatches' => taxonomy.need_to_be_selected_ids[:medium_ids].to_json} %>
         </div>
 
         <div class="tab-pane" id="template">
-          <%= checkbox_f(f, :ignore_types, {:label => "", :help_text => _("All Templates"), :multiple => true, :onchange => 'ignore_checked(this)'}, "ConfigTemplate") %>
+          <%= checkbox_f(f, :ignore_types, {:label => _("All templates"), :multiple => true, :onchange => 'ignore_checked(this)'}, "ConfigTemplate") %>
           <%= multiple_selects f, :config_templates, ConfigTemplate, taxonomy.selected_ids[:config_template_ids],
-            {:disabled => taxonomy.used_and_selected_ids[:config_template_ids], :label => ''},
+            {:disabled => taxonomy.used_and_selected_ids[:config_template_ids], :label => _('Select templates')},
             {'data-mismatches' => taxonomy.need_to_be_selected_ids[:config_template_ids].to_json} %>
         </div>
 
         <div class="tab-pane" id="domains">
-          <%= checkbox_f(f, :ignore_types, {:label => "", :help_text => _("All Domains"), :multiple => true, :onchange => 'ignore_checked(this)'}, "Domain") %>
+          <%= checkbox_f(f, :ignore_types, {:label => _("All domains"), :multiple => true, :onchange => 'ignore_checked(this)'}, "Domain") %>
           <%= multiple_selects f, :domains, Domain, taxonomy.selected_ids[:domain_ids],
-            {:disabled => taxonomy.used_and_selected_ids[:domain_ids], :label => ''},
+            {:disabled => taxonomy.used_and_selected_ids[:domain_ids], :label => _('Select domains')},
             {'data-mismatches' => taxonomy.need_to_be_selected_ids[:domain_ids].to_json} %>
         </div>
       <% end %>
 
       <div class="tab-pane" id="environments">
-        <%= checkbox_f(f, :ignore_types, {:label => "", :help_text => _("All Environments"), :multiple => true, :onchange => 'ignore_checked(this)'}, "Environment") %>
+        <%= checkbox_f(f, :ignore_types, {:label => _("All environments"), :multiple => true, :onchange => 'ignore_checked(this)'}, "Environment") %>
         <%= multiple_selects f, :environments, Environment, taxonomy.selected_ids[:environment_ids],
-          {:disabled => taxonomy.used_and_selected_ids[:environment_ids], :label => ''},
+          {:disabled => taxonomy.used_and_selected_ids[:environment_ids], :label => _('Select environments')},
           {'data-mismatches' => taxonomy.need_to_be_selected_ids[:environment_ids].to_json} %>
       </div>
 
       <div class="tab-pane" id="hostgroups">
-        <%= checkbox_f(f, :ignore_types, {:label => "", :help_text => _("All Host Groups"), :multiple => true, :onchange => 'ignore_checked(this)'}, "Hostgroup") %>
+        <%= checkbox_f(f, :ignore_types, {:label => _("All host groups"), :multiple => true, :onchange => 'ignore_checked(this)'}, "Hostgroup") %>
         <%= multiple_selects f, :hostgroups, Hostgroup, taxonomy.selected_ids[:hostgroup_ids],
-          {:disabled => taxonomy.used_and_selected_ids[:hostgroup_ids], :label => ''},
+          {:disabled => taxonomy.used_and_selected_ids[:hostgroup_ids], :label => _('Select host groups')},
           {'data-mismatches' => taxonomy.need_to_be_selected_ids[:hostgroup_ids].to_json} %>
      </div>
 
       <% if taxonomy.is_a?(Location) && SETTINGS[:locations_enabled] %>
         <div class="tab-pane" id="organizations">
           <%= organization_selects f, taxonomy.selected_ids[:organization_ids],
-                                   { :disabled => taxonomy.used_and_selected_ids[:organization_ids], :label => '' },
+                                   { :disabled => taxonomy.used_and_selected_ids[:organization_ids], :label => _('Select organizations')},
                                    { 'data-mismatches' => taxonomy.need_to_be_selected_ids[:organization_ids].to_json } %>
         </div>
       <% elsif taxonomy.is_a?(Organization) && SETTINGS[:organizations_enabled] %>
         <div class="tab-pane" id="locations">
           <%= location_selects f, taxonomy.selected_ids[:location_ids],
-                               { :disabled => taxonomy.used_and_selected_ids[:location_ids], :label => '' },
+                               { :disabled => taxonomy.used_and_selected_ids[:location_ids], :label => _('Select locations')},
                                { 'data-mismatches' => taxonomy.need_to_be_selected_ids[:location_ids].to_json } %>
         </div>
       <% end %>
 
+      <div class="tab-pane" id="params">
+        <%= render "common_parameters/parameters", { :f => f, :type => :parameters } %>
+      </div>
+
       <%= submit_or_cancel f %>
     </div>
+  </div>
 <% end %>
diff --git a/config/routes/api/v2.rb b/config/routes/api/v2.rb
index 5ff0084fb..bb005a8a7 100644
--- a/config/routes/api/v2.rb
+++ b/config/routes/api/v2.rb
@@ -208,7 +208,13 @@ Foreman::Application.routes.draw do
           resources :media, :only => [:index, :show]
           resources :smart_proxies, :only => [:index, :show]
 
-          # scoped by location AND organization
+          resources :parameters, :except => [:new, :edit] do
+            collection do
+              delete '/', :to => :reset
+            end
+          end
+
+           # scoped by location AND organization
           resources :organizations, :except => [:new, :edit] do
             resources :domains, :only => [:index, :show]
             resources :subnets, :only => [:index, :show]
@@ -238,6 +244,12 @@ Foreman::Application.routes.draw do
           resources :media, :only => [:index, :show]
           resources :smart_proxies, :only => [:index, :show]
 
+          resources :parameters, :except => [:new, :edit] do
+            collection do
+              delete '/', :to => :reset
+            end
+          end
+
           # scoped by location AND organization
           resources :locations, :except => [:new, :edit] do
             resources :domains, :only => [:index, :show]
diff --git a/test/fixtures/parameters.yml b/test/fixtures/parameters.yml
index 0efb32768..1c8fbd9f4 100644
--- a/test/fixtures/parameters.yml
+++ b/test/fixtures/parameters.yml
@@ -29,3 +29,14 @@ os:
   type: OsParameter
   operatingsystem: redhat
 
+location:
+  name: location
+  value: value
+  type: LocationParameter
+  location: location1
+
+org:
+  name: org
+  value: value
+  type: OrganizationParameter
+  organization: organization1
diff --git a/test/unit/location_parameter_test.rb b/test/unit/location_parameter_test.rb
new file mode 100644
index 000000000..e7c3a4eb9
--- /dev/null
+++ b/test/unit/location_parameter_test.rb
@@ -0,0 +1,35 @@
+require 'test_helper'
+
+class LocationParameterTest < ActiveSupport::TestCase
+
+  setup do
+    User.current = User.admin
+  end
+
+  test 'should have a reference_id' do
+    location_parameter       = LocationParameter.new
+    location_parameter.name  = 'valid'
+    location_parameter.value = 'valid'
+    assert_not location_parameter.save
+
+    location                        = Location.first
+    location_parameter.reference_id = location.id
+    assert location_parameter.save
+  end
+
+  test 'duplicate names cannot exist for a location' do
+    location = taxonomies(:location1)
+    parameter1 = LocationParameter.create! :name => 'some_parameter', :value => 'value', :reference_id => location.id
+    parameter2 = LocationParameter.create :name => 'some_parameter', :value => 'value', :reference_id => location.id
+    assert_not parameter2.valid?
+    assert_equal ['has already been taken'], parameter2.errors[:name]
+  end
+
+  test 'duplicate names can exist for different taxonomies' do
+    location1 = taxonomies(:location1)
+    location2 = taxonomies(:location2)
+    assert LocationParameter.create! :name => 'some_parameter', :value => 'value', :reference_id => location1.id
+    assert LocationParameter.create! :name => 'some_parameter', :value => 'value', :reference_id => location2.id
+  end
+
+end
diff --git a/test/unit/organization_parameter_test.rb b/test/unit/organization_parameter_test.rb
new file mode 100644
index 000000000..bd01538d4
--- /dev/null
+++ b/test/unit/organization_parameter_test.rb
@@ -0,0 +1,35 @@
+require 'test_helper'
+
+class OrganizationParameterTest < ActiveSupport::TestCase
+
+  setup do
+    User.current = User.admin
+  end
+
+  test 'should have a reference_id' do
+    organization_parameter       = OrganizationParameter.new
+    organization_parameter.name  = 'valid'
+    organization_parameter.value = 'valid'
+    assert_not organization_parameter.save
+
+    organization                        = Organization.first
+    organization_parameter.reference_id = organization.id
+    assert organization_parameter.save
+  end
+
+  test 'duplicate names cannot exist for a organization' do
+    organization = taxonomies(:organization1)
+    parameter1 = OrganizationParameter.create! :name => 'some_parameter', :value => 'value', :reference_id => organization.id
+    parameter2 = OrganizationParameter.create :name => 'some_parameter', :value => 'value', :reference_id => organization.id
+    assert_not parameter2.valid?
+    assert_equal ['has already been taken'], parameter2.errors[:name]
+  end
+
+  test 'duplicate names can exist for different taxonomies' do
+    organization1 = taxonomies(:organization1)
+    organization2 = taxonomies(:organization2)
+    assert OrganizationParameter.create! :name => 'some_parameter', :value => 'value', :reference_id => organization1.id
+    assert OrganizationParameter.create! :name => 'some_parameter', :value => 'value', :reference_id => organization2.id
+  end
+
+end
