From aeab110216d9b8c14d87425cb5fc319c6e76e8af Mon Sep 17 00:00:00 2001 From: Daniel Lobato Date: Tue, 15 Sep 2015 11:51:40 +0200 Subject: [PATCH] Fixes #7230, #12021 - Upgrade to Rails 4.1.5 This commits upgrades Rails to Rails 4.1.5. See a description of the changes included here, and go to the pull request in GitHub to see more detailed explanations: * Update gems to a Rails 4 compatible version, including dependencies * Fix counter cache columns * Remove conditions, order, limit from has_many relations * Remove test runner On minitest 5, the runner API was deprecated, so our custom test runner is no longer working. * Remove useless add_index on lookup_values match An index is added previously on lookup_values :priority, and on Rails 4 rename_column changes 'priority' to 'match' already changes the name of the index. * Alias assert_include to assert_includes. * Expire topbar cache * Subclass ApplicationMailer in test to avoid 'missing template' error * Fixes #12021 - Use .to_param to find parent object in LookupKeys controller On Rails 4, .find will not default to .friendly.find so find_hostgroup, find_environment and find_host will fail for non numeric IDs. However, we can use from_param to find these objects. This is something we can do both on Rails 3 and Rails 4, whereas using .friendly isn't an option until friendly_id 5.0, which depends on Rails 4. * Use explicit friendly ID search. * find_common finder uses from_param -> friendly -> find The finder needed to be refactored because with the new Friendly ID we have to use .friendly explicitely. It currently follows the strategy of searching like this: - from_param -> .friendly -> regular find * Remove RecordNotFound errors from parameterizable in rails 4 * Protect attributes using attr_accessible and protected_attributes * url_for doesn't append port when protocol is specified Some of our tests are checking if port 80 or 443 is included in the URL generated by lib/foreman/renderer.rb. However url_for has changed in Rails 4 and now it does not append the port even if explicitly added. If the protocol is specified, as it is in this case, then the url generated will just have the protocol (http or https) but not the port (80 or 443) * Validate object instead of _id column in join tables On Rails 4 such validations will fail when we try to create objects without explicitely assigning the id. Puppetclass.new(:config_group => config_group) would fail even for a valid config group, :config_group_id => config_group.id should be used instead. To avoid that, we validate the object, not the ID column * Rails 4 non backwards compatible syntax changes Changes that have to deal with how some of the internal Rails objects need a new syntax, like generating routes, exceptions, form builders. None of these are Rails 3 compatible. * Fixes #12199 - rails 4 migration errors There are actually two parts to the issue of not being able to migrate with this branch. The first is https://gist.github.com/eLobato/0f5db50b5c93cc6c277c and can be temporarily fixed with rails/sass-rails#136 (comment) I am not sure of a long term fix for that atm. Once that is patched, this error https://gist.github.com/johnpmitsch/96e5ba3629890931193a happens on a migration. This will fix that error by changing the Migrator class initializer arguments which have changed from rails 3 to rails 4 * Refactor fact value test to not modify user_roles directly * Return external usergroupsas an array * Use eager_load to preload associations to be used in where Fixes #7230, #12021 - Upgrade to Rails 4.1.5 This commits upgrades Rails to Rails 4.1.5. See a description of the changes included here, and go to the pull request in GitHub to see more detailed explanations: * Update gems to a Rails 4 compatible version, including dependencies * Fix counter cache columns * Remove conditions, order, limit from has_many relations * Remove test runner On minitest 5, the runner API was deprecated, so our custom test runner is no longer working. * Remove useless add_index on lookup_values match An index is added previously on lookup_values :priority, and on Rails 4 rename_column changes 'priority' to 'match' already changes the name of the index. * Alias assert_include to assert_includes. * Expire topbar cache * Subclass ApplicationMailer in test to avoid 'missing template' error * Fixes #12021 - Use .to_param to find parent object in LookupKeys controller On Rails 4, .find will not default to .friendly.find so find_hostgroup, find_environment and find_host will fail for non numeric IDs. However, we can use from_param to find these objects. This is something we can do both on Rails 3 and Rails 4, whereas using .friendly isn't an option until friendly_id 5.0, which depends on Rails 4. * Use explicit friendly ID search. * find_common finder uses from_param -> friendly -> find The finder needed to be refactored because with the new Friendly ID we have to use .friendly explicitely. It currently follows the strategy of searching like this: - from_param -> .friendly -> regular find * Remove RecordNotFound errors from parameterizable in rails 4 * Protect attributes using attr_accessible and protected_attributes * url_for doesn't append port when protocol is specified Some of our tests are checking if port 80 or 443 is included in the URL generated by lib/foreman/renderer.rb. However url_for has changed in Rails 4 and now it does not append the port even if explicitly added. If the protocol is specified, as it is in this case, then the url generated will just have the protocol (http or https) but not the port (80 or 443) * Validate object instead of _id column in join tables On Rails 4 such validations will fail when we try to create objects without explicitely assigning the id. Puppetclass.new(:config_group => config_group) would fail even for a valid config group, :config_group_id => config_group.id should be used instead. To avoid that, we validate the object, not the ID column * Rails 4 non backwards compatible syntax changes Changes that have to deal with how some of the internal Rails objects need a new syntax, like generating routes, exceptions, form builders. None of these are Rails 3 compatible. * Fixes #12199 - rails 4 migration errors There are actually two parts to the issue of not being able to migrate with this branch. The first is https://gist.github.com/eLobato/0f5db50b5c93cc6c277c and can be temporarily fixed with rails/sass-rails#136 (comment) I am not sure of a long term fix for that atm. Once that is patched, this error https://gist.github.com/johnpmitsch/96e5ba3629890931193a happens on a migration. This will fix that error by changing the Migrator class initializer arguments which have changed from rails 3 to rails 4 * Refactor fact value test to not modify user_roles directly * Return external usergroupsas an array * Use eager_load to preload associations to be used in where * Auto detect jenkins rake task in application.rb and set test RAILS_ENV in that case --- .gitignore | 1 - Gemfile | 16 +- app/assets/javascripts/topbar.js | 2 +- app/controllers/api/v1/reports_controller.rb | 2 +- .../api/v2/config_reports_controller.rb | 4 +- .../api/v2/host_classes_controller.rb | 6 +- app/controllers/api/v2/models_controller.rb | 6 + .../api/v2/parameters_controller.rb | 5 +- app/controllers/api/v2/reports_controller.rb | 2 +- .../api/v2/lookup_keys_common_controller.rb | 59 +- app/controllers/concerns/find_common.rb | 16 +- app/controllers/config_reports_controller.rb | 2 +- app/controllers/hosts_controller.rb | 6 +- app/controllers/settings_controller.rb | 2 +- app/controllers/unattended_controller.rb | 6 +- app/helpers/application_helper.rb | 8 + app/models/bookmark.rb | 2 +- app/models/compute_profile.rb | 1 + app/models/concerns/audit_extensions.rb | 3 +- app/models/concerns/has_many_common.rb | 10 +- app/models/concerns/host_common.rb | 2 +- app/models/concerns/host_params.rb | 3 +- app/models/concerns/parameterizable.rb | 4 +- app/models/concerns/taxonomix.rb | 14 +- app/models/config_group_class.rb | 6 +- app/models/domain.rb | 2 +- app/models/environment.rb | 4 +- app/models/host/base.rb | 10 +- app/models/host/managed.rb | 13 +- app/models/host_class.rb | 1 - app/models/hostgroup_class.rb | 1 - .../lookup_keys/puppetclass_lookup_key.rb | 2 +- app/models/operatingsystem.rb | 1 + app/models/puppetclass.rb | 8 +- app/models/report.rb | 2 +- app/models/subnet.rb | 2 +- app/models/user.rb | 5 +- app/models/user_mail_notification.rb | 2 +- app/models/user_role.rb | 2 +- app/models/usergroup.rb | 10 +- app/models/usergroup_member.rb | 2 +- app/services/foreman/plugin.rb | 11 +- app/services/tax_host.rb | 5 +- app/views/api/v2/interfaces/base.json.rabl | 1 + bundler.d/assets.rb | 15 +- bundler.d/console.rb | 3 - bundler.d/test.rb | 8 +- config/application.rb | 8 +- config/environments/development.rb | 12 +- config/environments/production.rb | 5 +- config/environments/test.rb | 3 + config/initializers/1_fast_gettext.rb | 3 + config/initializers/apipie.rb | 1 + config/initializers/routing_hash_for.rb | 29 + ...0444_add_look_up_key_id_to_puppet_class.rb | 1 - .../20140219183343_migrate_permissions.rb | 24 +- db/schema.rb | 860 ++++++++++++++++++ lib/foreman/logging.rb | 2 + lib/middleware/catch_json_parse_errors.rb | 2 +- lib/tasks/jenkins.rake | 11 +- lib/tasks/plugin_assets.rake | 75 +- lib/tasks/test.rake | 7 - .../api/base_controller_subclass_test.rb | 64 +- .../smart_class_parameters_controller_test.rb | 2 +- .../api/v2/smart_proxies_controller_test.rb | 2 +- .../provisioning_templates_controller_test.rb | 2 +- test/functional/unattended_controller_test.rb | 4 +- ...custom_runner.rb => custom_runner_test.rb} | 2 + test/test_helper.rb | 6 +- test/test_runner.rb | 35 - test/unit/application_mailer_test.rb | 12 +- test/unit/compute_resource_test.rb | 2 +- test/unit/fact_value_test.rb | 73 +- test/unit/helpers/layout_helper_test.rb | 4 +- test/unit/host_test.rb | 12 +- 75 files changed, 1226 insertions(+), 335 deletions(-) create mode 100644 config/initializers/routing_hash_for.rb create mode 100644 db/schema.rb rename test/lib/{custom_runner.rb => custom_runner_test.rb} (74%) delete mode 100644 test/test_runner.rb diff --git a/.gitignore b/.gitignore index 748c14a7b19..0dca61cc3cd 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,6 @@ log/*.log.age tmp/ jenkins/reports/* test/reports/* -db/schema.rb config/settings.yaml config/settings.plugins.d config/email.yaml diff --git a/Gemfile b/Gemfile index 19ceae4ce33..d4a5634a967 100644 --- a/Gemfile +++ b/Gemfile @@ -4,29 +4,28 @@ require File.expand_path('../lib/regexp_extensions', FOREMAN_GEMFILE) source 'https://rubygems.org' -gem 'rails', '3.2.22' -gem 'rack-cache', '< 1.3.0' +gem 'rails', '4.1.5' gem 'json', '~> 1.5' gem 'rest-client', '~> 1.6.0', :require => 'rest_client' -gem 'audited-activerecord', '3.0.0' +gem 'audited-activerecord', '~> 4.0' gem 'will_paginate', '~> 3.0' gem 'ancestry', '~> 2.0' -gem 'scoped_search', '~> 3.0' +gem 'scoped_search', '>= 3.2.2', '< 4' gem 'ldap_fluff', '>= 0.3.5', '< 1.0' gem 'net-ldap', '>= 0.8.0' -gem 'apipie-rails', '~> 0.2.5' +gem 'apipie-rails', '~> 0.3.4' gem 'rabl', '~> 0.11' gem 'oauth', '~> 0.4' gem 'deep_cloneable', '~> 2.0' gem 'foreigner', '~> 1.4' gem 'validates_lengths_from_database', '~> 0.2' -gem 'friendly_id', '~> 4.0' +gem 'friendly_id', '~> 5.0' gem 'secure_headers', '~> 1.3' gem 'safemode', '~> 1.2' gem 'fast_gettext', '~> 0.8' gem 'gettext_i18n_rails', '~> 1.0' gem 'i18n', '~> 0.6.4' -gem 'rails-i18n', '~> 3.0.0' +gem 'rails-i18n', '~> 4.0.0' gem 'turbolinks', '~> 2.5' gem 'logging', '>= 1.8.0', '< 3.0.0' gem 'fog-core', '1.34.0' @@ -36,6 +35,9 @@ if RUBY_VERSION.start_with? '1.9.' else gem 'net-ssh' end +gem 'activerecord-session_store', '~> 0.1.1' +gem 'rails-observers', '~> 0.1' +gem 'protected_attributes', '~> 1.1.1' Dir["#{File.dirname(FOREMAN_GEMFILE)}/bundler.d/*.rb"].each do |bundle| self.instance_eval(Bundler.read_file(bundle)) diff --git a/app/assets/javascripts/topbar.js b/app/assets/javascripts/topbar.js index 4499eb3ad4a..dc85785638b 100644 --- a/app/assets/javascripts/topbar.js +++ b/app/assets/javascripts/topbar.js @@ -50,7 +50,7 @@ $(document).on('mouseleave','.loc-submenu', function(){ function mark_active_menu() { var menus = $('.menu_tab_dropdown'), path = window.location.pathname + window.location.search, - link = $("[href='%s'".replace('%s', path)); + link = $("[href='%s']".replace('%s', path)); menus.removeClass('active'); $("[class^='menu_tab_']").removeClass('active'); diff --git a/app/controllers/api/v1/reports_controller.rb b/app/controllers/api/v1/reports_controller.rb index eaa8fa59e20..5165a6a2156 100644 --- a/app/controllers/api/v1/reports_controller.rb +++ b/app/controllers/api/v1/reports_controller.rb @@ -36,7 +36,7 @@ def destroy param :id, :identifier, :required => true def last - conditions = { :host_id => Host.authorized(:view_hosts).find(params[:host_id]).try(:id) } if params[:host_id].present? + conditions = { :host_id => Host.authorized(:view_hosts).friendly.find(params[:host_id]).try(:id) } if params[:host_id].present? max_id = resource_scope.where(conditions).maximum(:id) @report = resource_scope.includes(:logs => [:message, :source]).find(max_id) render :show diff --git a/app/controllers/api/v2/config_reports_controller.rb b/app/controllers/api/v2/config_reports_controller.rb index 46e4c8f7508..1da7141d673 100644 --- a/app/controllers/api/v2/config_reports_controller.rb +++ b/app/controllers/api/v2/config_reports_controller.rb @@ -54,7 +54,9 @@ def destroy param :id, :identifier, :required => true def last - conditions = { :host_id => Host.authorized(:view_hosts).find(params[:host_id]).try(:id) } if params[:host_id].present? + if params[:host_id].present? + conditions = { :host_id => resource_finder(Host.authorized(:view_hosts), params[:host_id]).try(:id) } + end max_id = resource_scope.where(conditions).maximum(:id) @config_report = resource_scope.includes(:logs => [:message, :source]).find(max_id) render :show diff --git a/app/controllers/api/v2/host_classes_controller.rb b/app/controllers/api/v2/host_classes_controller.rb index 28c4b82bcad..ff8dcdf38a1 100644 --- a/app/controllers/api/v2/host_classes_controller.rb +++ b/app/controllers/api/v2/host_classes_controller.rb @@ -35,8 +35,10 @@ def destroy # overwrite resource_name so it's host and and not host_class, since we want to return @host def find_host not_found and return false if params[:host_id].blank? - @host = Host.find(params[:host_id]) if Host::Managed.respond_to?(:authorized) && - Host::Managed.authorized("view_host", Host::Managed) + if Host::Managed.respond_to?(:authorized) && + Host::Managed.authorized("view_host", Host::Managed) + @host = resource_finder(Host.authorized(:view_hosts), params[:host_id]) + end end end end diff --git a/app/controllers/api/v2/models_controller.rb b/app/controllers/api/v2/models_controller.rb index 9554fe38959..1a288ab6e3b 100644 --- a/app/controllers/api/v2/models_controller.rb +++ b/app/controllers/api/v2/models_controller.rb @@ -47,6 +47,12 @@ def update def destroy process_response @model.destroy end + + private + + def find_resource + @model = Model.friendly.find(params[:id]) || super + end end end end diff --git a/app/controllers/api/v2/parameters_controller.rb b/app/controllers/api/v2/parameters_controller.rb index 0d3f536396b..fd0ebae7b48 100644 --- a/app/controllers/api/v2/parameters_controller.rb +++ b/app/controllers/api/v2/parameters_controller.rb @@ -165,8 +165,9 @@ def allowed_nested_id def find_parameter # nested_obj is required, so no need to check here @parameters = nested_obj.send(parameters_method) - @parameter = @parameters.find(params[:id]) - return @parameter if @parameter + @parameter = @parameters.from_param(params[:id]) + @parameter ||= @parameters.friendly.find(params[:id]) + return @parameter if @parameter.present? not_found end end diff --git a/app/controllers/api/v2/reports_controller.rb b/app/controllers/api/v2/reports_controller.rb index b432de0b0fd..ca5006c20cb 100644 --- a/app/controllers/api/v2/reports_controller.rb +++ b/app/controllers/api/v2/reports_controller.rb @@ -54,7 +54,7 @@ def destroy param :id, :identifier, :required => true def last - conditions = { :host_id => Host.authorized(:view_hosts).find(params[:host_id]).try(:id) } if params[:host_id].present? + conditions = { :host_id => resource_finder(Host.authorized(:view_hosts), params[:host_id]).try(:id) } if params[:host_id].present? max_id = resource_scope.where(conditions).maximum(:id) @report = resource_scope.includes(:logs => [:message, :source]).find(max_id) render :show diff --git a/app/controllers/concerns/api/v2/lookup_keys_common_controller.rb b/app/controllers/concerns/api/v2/lookup_keys_common_controller.rb index 009eef9d15f..5e76e13f01e 100644 --- a/app/controllers/concerns/api/v2/lookup_keys_common_controller.rb +++ b/app/controllers/concerns/api/v2/lookup_keys_common_controller.rb @@ -19,22 +19,6 @@ module Api::V2::LookupKeysCommonController before_filter :return_if_smart_mismatch, :only => [:show, :update, :destroy] end - def puppetclass_id? - params.keys.include?('puppetclass_id') - end - - def environment_id? - params.keys.include?('environment_id') - end - - def host_id? - params.keys.include?('host_id') - end - - def hostgroup_id? - params.keys.include?('hostgroup_id') - end - def smart_variable_id? params.keys.include?('smart_variable_id') || controller_name.match(/smart_variables/) end @@ -43,28 +27,22 @@ def smart_class_parameter_id? params.keys.include?('smart_class_parameter_id') || controller_name.match(/smart_class_parameters/) end - def find_puppetclass - @puppetclass = Puppetclass.authorized(:view_puppetclasses).find(params['puppetclass_id']) - rescue ActiveRecord::RecordNotFound - not_found({ :error => { :message => (_("Puppet class with id '%{id}' was not found") % { :id => params['puppetclass_id'] }) } }) - end + [Puppetclass, Environment, Host::Base, Hostgroup].each do |model| + model_string = model.to_s.split('::').first.downcase - def find_environment - @environment = Environment.authorized(:view_environments).find(params['environment_id']) - rescue ActiveRecord::RecordNotFound - not_found({ :error => { :message => (_("Environment with id '%{id}' was not found") % { :id => params['environment_id'] }) } }) - end - - def find_host - @host = Host::Base.authorized(:view_hosts).find(params['host_id']) - rescue ActiveRecord::RecordNotFound - not_found({ :error => { :message => (_("Host with id '%{id}' was not found") % { :id => params['host_id'] }) } }) - end + define_method("#{model_string}_id?") do + params.keys.include?("#{model_string}_id") + end - def find_hostgroup - @hostgroup = Hostgroup.authorized(:view_hostgroups).find(params['hostgroup_id']) - rescue ActiveRecord::RecordNotFound - not_found({ :error => { :message => (_("Hostgroup with id '%{id}' was not found") % { :id => params['hostgroup_id'] }) } }) + define_method("find_#{model_string}") do + scope = model.authorized(:"view_#{model_string.pluralize}") + begin + instance_variable_set("@#{model_string}", + resource_finder(scope, params["#{model_string}_id"])) + rescue ActiveRecord::RecordNotFound + model_not_found(model_string) + end + end end def find_smart_variable @@ -144,4 +122,13 @@ def return_if_smart_mismatch not_found "#{obj} not found by id '#{id}'" end end + + private + + def model_not_found(model) + error_message = ( + _("%{model} with id '%{id}' was not found") % + { :id => params["#{model}_id"], :model => model.capitalize } ) + not_found(:error => { :message => error_message } ) + end end diff --git a/app/controllers/concerns/find_common.rb b/app/controllers/concerns/find_common.rb index 5d8a5a30edd..a037251e762 100644 --- a/app/controllers/concerns/find_common.rb +++ b/app/controllers/concerns/find_common.rb @@ -1,12 +1,18 @@ -# this mixin is used by both ApplicationController and Api::BaseController -# searches for an object based on its id, name, label, etc and assign it to an instance variable +# This mixin is used by both ApplicationController and Api::BaseController +# Searches for an object based on its id, name, label, etc and assign it to an instance variable # friendly_id performs the logic if params[:id] is 'id' or 'id-name' or 'name' module FindCommon - # example: @host = Host.find(params[:id]) def find_resource - not_found and return if params[:id].blank? - instance_variable_set("@#{resource_name}", resource_scope.find(params[:id])) + instance_variable_set("@#{resource_name}", + resource_finder(resource_scope, params[:id])) + end + + def resource_finder(scope, id) + raise ActiveRecord::RecordNotFound if scope.empty? + result = scope.from_param(id) if scope.respond_to?(:from_param) + result ||= scope.friendly.find(id) if scope.respond_to?(:friendly) + result || scope.find(id) end def resource_name(resource = controller_name) diff --git a/app/controllers/config_reports_controller.rb b/app/controllers/config_reports_controller.rb index 436cf0b9a85..8b404ca971d 100644 --- a/app/controllers/config_reports_controller.rb +++ b/app/controllers/config_reports_controller.rb @@ -10,7 +10,7 @@ def index def show # are we searching for the last report? if params[:id] == "last" - conditions = { :host_id => Host.authorized(:view_hosts).find(params[:host_id]).try(:id) } if params[:host_id].present? + conditions = { :host_id => resource_finder(Host.authorized(:view_hosts), params[:host_id]).try(:id) } if params[:host_id].present? params[:id] = resource_base.where(conditions).maximum(:id) end diff --git a/app/controllers/hosts_controller.rb b/app/controllers/hosts_controller.rb index aeca21fc36e..e4e1f07dcca 100644 --- a/app/controllers/hosts_controller.rb +++ b/app/controllers/hosts_controller.rb @@ -169,7 +169,7 @@ def puppetclass_parameters def externalNodes certname = params[:name] @host ||= resource_base.find_by_certname certname - @host ||= resource_base.find certname + @host ||= resource_base.friendly.find certname not_found and return unless @host begin @@ -352,7 +352,7 @@ def update_multiple_parameters skipped = [] params[:name].each do |name, value| next if value.empty? - if (host_param = host.host_parameters.find(name)) + if (host_param = host.host_parameters.friendly.find(name)) counter += 1 if host_param.update_attribute(:value, value) else skipped << name @@ -698,7 +698,7 @@ def taxonomy_scope # overwrite application_controller def find_resource not_found and return false if (id = params[:id]).blank? - @host = resource_base.find(id) + @host = resource_base.friendly.find(id) @host ||= resource_base.find_by_mac params[:host][:mac] if params[:host] && params[:host][:mac] not_found and return(false) unless @host diff --git a/app/controllers/settings_controller.rb b/app/controllers/settings_controller.rb index ef4133685ef..57d7bd6686e 100644 --- a/app/controllers/settings_controller.rb +++ b/app/controllers/settings_controller.rb @@ -13,7 +13,7 @@ def index end def update - @setting = Setting.find(params[:id]) + @setting = Setting.friendly.find(params[:id]) if @setting.parse_string_value(params[:setting][:value]) && @setting.save render :json => @setting else diff --git a/app/controllers/unattended_controller.rb b/app/controllers/unattended_controller.rb index 0678436c17f..4d14e53198c 100644 --- a/app/controllers/unattended_controller.rb +++ b/app/controllers/unattended_controller.rb @@ -44,8 +44,8 @@ def built def template return head(:not_found) unless (params.has_key?("id") and params.has_key?(:hostgroup)) - template = ProvisioningTemplate.find(params['id']) - @host = Hostgroup.find(params['hostgroup']) + template = ProvisioningTemplate.find_by_name(params['id']) + @host = Hostgroup.find_by_name(params['hostgroup']) return head(:not_found) unless template and @host @@ -107,7 +107,7 @@ def get_host_details def find_host_by_spoof host = Nic::Base.primary.find_by_ip(params.delete('spoof')).try(:host) if params['spoof'].present? - host ||= Host.find(params.delete('hostname')) if params['hostname'].present? + host ||= Host.find_by_name(params.delete('hostname')) if params['hostname'].present? @spoof = host.present? host end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index b29f756a73d..887d3fb1d8f 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -32,6 +32,14 @@ def link_to(*args, &block) end end + def link_to_function(name, function, html_options = {}) + onclick_tag = "#{html_options[:onclick]}; " if html_options[:onclick] + onclick = "#{onclick_tag}#{function}; return false;" + href = html_options[:href] || '#' + + content_tag(:a, name, html_options.merge(:href => href, :onclick => onclick)) + end + protected def contract(model) diff --git a/app/models/bookmark.rb b/app/models/bookmark.rb index ffed9d221d6..1cccd037abd 100644 --- a/app/models/bookmark.rb +++ b/app/models/bookmark.rb @@ -7,7 +7,7 @@ class Bookmark < ActiveRecord::Base validates_lengths_from_database belongs_to :owner, :polymorphic => true - attr_accessible :name, :controller, :query, :public + attr_accessible :name, :query, :public, :controller audited :allow_mass_assignment => true validates :name, :uniqueness => {:scope => :controller}, :unless => Proc.new{|b| Bookmark.my_bookmarks.where(:name => b.name).empty?} diff --git a/app/models/compute_profile.rb b/app/models/compute_profile.rb index d30cc211f1e..20864e463d8 100644 --- a/app/models/compute_profile.rb +++ b/app/models/compute_profile.rb @@ -6,6 +6,7 @@ class ComputeProfile < ActiveRecord::Base validates_lengths_from_database attr_accessible :name + audited has_associated_audits diff --git a/app/models/concerns/audit_extensions.rb b/app/models/concerns/audit_extensions.rb index a1ec3226f7a..aef24f0a023 100644 --- a/app/models/concerns/audit_extensions.rb +++ b/app/models/concerns/audit_extensions.rb @@ -5,7 +5,8 @@ module AuditExtensions included do belongs_to :user, :class_name => 'User' belongs_to :search_users, :class_name => 'User', :foreign_key => :user_id - belongs_to :search_hosts, :class_name => 'Host', :foreign_key => :auditable_id, :conditions => { :audits => { :auditable_type => 'Host' } } + belongs_to :search_hosts, -> { where(:audits => { :auditable_type => 'Host' }) }, + :class_name => 'Host', :foreign_key => :auditable_id belongs_to :search_hostgroups, :class_name => 'Hostgroup', :foreign_key => :auditable_id belongs_to :search_parameters, :class_name => 'Parameter', :foreign_key => :auditable_id belongs_to :search_templates, :class_name => 'ProvisioningTemplate', :foreign_key => :auditable_id diff --git a/app/models/concerns/has_many_common.rb b/app/models/concerns/has_many_common.rb index 9b013d829cb..2fc55e62907 100644 --- a/app/models/concerns/has_many_common.rb +++ b/app/models/concerns/has_many_common.rb @@ -41,8 +41,9 @@ class << self; self end end #### has_many #### - def has_many(association, options = {}) - has_many_names_for(association, options) + def has_many(*args) + options = args.last.is_a?(Hash) ? args.last : {} + has_many_names_for(args.first, options) super end @@ -69,8 +70,9 @@ def has_many_names_for(association, options) end #### belongs_to #### - def belongs_to(association, options = {}) - belongs_to_name_for(association, options) + def belongs_to(*args) + options = args.last.is_a?(Hash) ? args.last : {} + belongs_to_name_for(args.first, options) super end diff --git a/app/models/concerns/host_common.rb b/app/models/concerns/host_common.rb index 69d9b606ec5..c7fadfeb585 100644 --- a/app/models/concerns/host_common.rb +++ b/app/models/concerns/host_common.rb @@ -209,7 +209,7 @@ def individual_puppetclasses end def available_puppetclasses - return Puppetclass.where(nil) if environment_id.blank? + return Puppetclass.where(nil) if environment.blank? environment.puppetclasses - parent_classes end diff --git a/app/models/concerns/host_params.rb b/app/models/concerns/host_params.rb index ff3f685bea2..37c0afedab4 100644 --- a/app/models/concerns/host_params.rb +++ b/app/models/concerns/host_params.rb @@ -7,6 +7,7 @@ module HostParams accepts_nested_attributes_for :host_parameters, :allow_destroy => true include ParameterValidators attr_reader :cached_host_params + attr_accessible :host_parameters_attributes def params host_params.update(lookup_keys_params) @@ -58,7 +59,7 @@ def host_inherited_params_objects def host_params_objects # Host parameters should always be first for the uniq order - (host_parameters + host_inherited_params_objects.reverse!).uniq {|param| param.name} + (host_parameters + host_inherited_params_objects.to_a.reverse!).uniq {|param| param.name} end end end diff --git a/app/models/concerns/parameterizable.rb b/app/models/concerns/parameterizable.rb index 4a0c63e3648..0fb27066e47 100644 --- a/app/models/concerns/parameterizable.rb +++ b/app/models/concerns/parameterizable.rb @@ -12,7 +12,7 @@ def to_param end def self.from_param(id) - self.find(id.to_i) + self.find_by_id(id.to_i) end end end @@ -27,7 +27,7 @@ def to_param end def self.from_param(id_name) - self.find(id_name.to_i) + self.find_by_id(id_name.to_i) end end end diff --git a/app/models/concerns/taxonomix.rb b/app/models/concerns/taxonomix.rb index 45019c254cd..75f116a14c6 100644 --- a/app/models/concerns/taxonomix.rb +++ b/app/models/concerns/taxonomix.rb @@ -3,12 +3,14 @@ module Taxonomix include DirtyAssociations included do - taxonomy_join_table = "taxable_taxonomies" - has_many taxonomy_join_table, :dependent => :destroy, :as => :taxable - has_many :locations, :through => taxonomy_join_table, :source => :taxonomy, - :conditions => "taxonomies.type='Location'", :validate => false - has_many :organizations, :through => taxonomy_join_table, :source => :taxonomy, - :conditions => "taxonomies.type='Organization'", :validate => false + taxonomy_join_table = :taxable_taxonomies + has_many taxonomy_join_table.to_sym, :dependent => :destroy, :as => :taxable + has_many :locations, -> { where(:type => 'Location') }, + :through => taxonomy_join_table, :source => :taxonomy, + :validate => false + has_many :organizations, -> { where(:type => 'Organization') }, + :through => taxonomy_join_table, :source => :taxonomy, + :validate => false after_initialize :set_current_taxonomy scoped_search :in => :locations, :on => :name, :rename => :location, :complete_value => true diff --git a/app/models/config_group_class.rb b/app/models/config_group_class.rb index 904d58fd4a4..2e22eb5f9b3 100644 --- a/app/models/config_group_class.rb +++ b/app/models/config_group_class.rb @@ -9,7 +9,7 @@ class ConfigGroupClass < ActiveRecord::Base belongs_to :puppetclass belongs_to :config_group, :counter_cache => true - validates :puppetclass_id, :presence => true - validates :config_group_id, :presence => true, - :uniqueness => {:scope => :puppetclass_id} + validates :puppetclass, :presence => true + validates :config_group, :presence => true, + :uniqueness => {:scope => :puppetclass} end diff --git a/app/models/domain.rb b/app/models/domain.rb index be367e0c178..2ea9fa2cb0e 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -21,7 +21,7 @@ class Domain < ActiveRecord::Base has_many :domain_parameters, :dependent => :destroy, :foreign_key => :reference_id, :inverse_of => :domain has_many :parameters, :dependent => :destroy, :foreign_key => :reference_id, :class_name => "DomainParameter" has_many :interfaces, :class_name => 'Nic::Base' - has_many :primary_interfaces, :class_name => 'Nic::Base', :conditions => { :primary => true } + has_many :primary_interfaces, -> { where(:primary => true) }, :class_name => 'Nic::Base' has_many :hosts, :through => :interfaces has_many :primary_hosts, :through => :primary_interfaces, :source => :host diff --git a/app/models/environment.rb b/app/models/environment.rb index fdf3007b88a..045abe5c05a 100644 --- a/app/models/environment.rb +++ b/app/models/environment.rb @@ -11,12 +11,12 @@ class Environment < ActiveRecord::Base before_destroy EnsureNotUsedBy.new(:hosts, :hostgroups) has_many :environment_classes, :dependent => :destroy - has_many :puppetclasses, :through => :environment_classes, :uniq => true + has_many :puppetclasses, -> { uniq }, :through => :environment_classes has_many_hosts has_many :hostgroups - has_many :trends, :as => :trendable, :class_name => "ForemanTrend" validates :name, :uniqueness => true, :presence => true, :alphanumeric => true + has_many :trends, :as => :trendable, :class_name => "ForemanTrend" has_many :template_combinations, :dependent => :destroy has_many :provisioning_templates, :through => :template_combinations diff --git a/app/models/host/base.rb b/app/models/host/base.rb index 41d3c1a2d8d..9b41c504f9f 100644 --- a/app/models/host/base.rb +++ b/app/models/host/base.rb @@ -39,12 +39,10 @@ class Base < ActiveRecord::Base belongs_to :model, :counter_cache => :hosts_count has_many :fact_values, :dependent => :destroy, :foreign_key => :host_id has_many :fact_names, :through => :fact_values - has_many :interfaces, :dependent => :destroy, :inverse_of => :host, :class_name => 'Nic::Base', - :foreign_key => :host_id, :order => 'identifier' - has_one :primary_interface, :class_name => 'Nic::Base', :foreign_key => 'host_id', - :conditions => { :primary => true } - has_one :provision_interface, :class_name => 'Nic::Base', :foreign_key => 'host_id', - :conditions => { :provision => true } + has_many :interfaces, -> { order(:identifier) }, :dependent => :destroy, :inverse_of => :host, :class_name => 'Nic::Base', + :foreign_key => :host_id + has_one :primary_interface, -> { where(:primary => true) }, :class_name => 'Nic::Base', :foreign_key => 'host_id' + has_one :provision_interface, -> { where(:provision => true) }, :class_name => 'Nic::Base', :foreign_key => 'host_id' has_one :domain, :through => :primary_interface has_one :subnet, :through => :primary_interface accepts_nested_attributes_for :interfaces, :allow_destroy => true diff --git a/app/models/host/managed.rb b/app/models/host/managed.rb index 4e7969496ba..d16c36e844b 100644 --- a/app/models/host/managed.rb +++ b/app/models/host/managed.rb @@ -12,10 +12,8 @@ class Host::Managed < Host::Base belongs_to :owner, :polymorphic => true belongs_to :compute_resource belongs_to :image - has_many :host_statuses, :class_name => 'HostStatus::Status', :foreign_key => 'host_id', :inverse_of => :host, - :dependent => :destroy + has_many :host_statuses, :class_name => 'HostStatus::Status', :foreign_key => 'host_id', :inverse_of => :host, :dependent => :destroy has_one :configuration_status_object, :class_name => 'HostStatus::ConfigurationStatus', :foreign_key => 'host_id' - has_one :token, :foreign_key => :host_id, :dependent => :destroy before_destroy :remove_reports @@ -155,7 +153,8 @@ class Jail < ::Safemode::Jail audited :except => [:last_report, :puppet_status, :last_compile, :lookup_value_matcher], :allow_mass_assignment => true has_associated_audits #redefine audits relation because of the type change (by default the relation will look for auditable_type = 'Host::Managed') - has_many :audits, :foreign_key => :auditable_id, :class_name => Audited.audit_class.name, :conditions => { :auditable_type => 'Host' } + has_many :audits, -> { where(:auditable_type => 'Host') }, :foreign_key => :auditable_id, + :class_name => Audited.audit_class.name # some shortcuts alias_attribute :os, :operatingsystem @@ -589,7 +588,7 @@ def apply_inherited_attributes(attributes, initialized = true) new_hostgroup = self.hostgroup if initialized unless [new_hostgroup.try(:id), new_hostgroup.try(:friendly_id)].include? new_hostgroup_id - new_hostgroup = Hostgroup.find(new_hostgroup_id) + new_hostgroup = Hostgroup.friendly.find(new_hostgroup_id) end return attributes unless new_hostgroup @@ -814,11 +813,11 @@ def available_template_kinds(provisioning = nil) cr = ComputeResource.find_by_id(self.compute_resource_id) images = cr.try(:images) if images.blank? - [TemplateKind.find('finish')] + [TemplateKind.friendly.find('finish')] else uuid = self.compute_attributes[cr.image_param_name] image_kind = images.find_by_uuid(uuid).try(:user_data) ? 'user_data' : 'finish' - [TemplateKind.find(image_kind)] + [TemplateKind.friendly.find(image_kind)] end else TemplateKind.all diff --git a/app/models/host_class.rb b/app/models/host_class.rb index e1d078b94c2..e6f8953dcf6 100644 --- a/app/models/host_class.rb +++ b/app/models/host_class.rb @@ -7,7 +7,6 @@ class HostClass < ActiveRecord::Base belongs_to_host belongs_to :puppetclass - validates :host, :presence => true validates :puppetclass_id, :presence => true, :uniqueness => {:scope => :host_id} def name diff --git a/app/models/hostgroup_class.rb b/app/models/hostgroup_class.rb index 26efa1074b5..ca1203a5f7d 100644 --- a/app/models/hostgroup_class.rb +++ b/app/models/hostgroup_class.rb @@ -8,7 +8,6 @@ class HostgroupClass < ActiveRecord::Base belongs_to :puppetclass, :counter_cache => :hostgroups_count attr_accessible :hostgroup_id, :hostgroup, :puppetclass_id, :puppetclass - validates :hostgroup, :presence => true validates :puppetclass_id, :presence => true, :uniqueness => {:scope => :hostgroup_id} diff --git a/app/models/lookup_keys/puppetclass_lookup_key.rb b/app/models/lookup_keys/puppetclass_lookup_key.rb index ffb1f8ead15..6cfd122e8a4 100644 --- a/app/models/lookup_keys/puppetclass_lookup_key.rb +++ b/app/models/lookup_keys/puppetclass_lookup_key.rb @@ -1,6 +1,6 @@ class PuppetclassLookupKey < LookupKey has_many :environment_classes, :dependent => :destroy - has_many :environments, :through => :environment_classes, :uniq => true + has_many :environments, -> { uniq }, :through => :environment_classes has_many :param_classes, :through => :environment_classes, :source => :puppetclass scoped_search :in => :param_classes, :on => :name, :rename => :puppetclass, :complete_value => true diff --git a/app/models/operatingsystem.rb b/app/models/operatingsystem.rb index 3678045511b..382521033e5 100644 --- a/app/models/operatingsystem.rb +++ b/app/models/operatingsystem.rb @@ -34,6 +34,7 @@ class Operatingsystem < ActiveRecord::Base accepts_nested_attributes_for :os_parameters, :allow_destroy => true include ParameterValidators has_many :trends, :as => :trendable, :class_name => "ForemanTrend" + attr_name :to_label validates :minor, :numericality => {:greater_than_or_equal_to => 0}, :allow_nil => true, :allow_blank => true validates :name, :presence => true, :no_whitespace => true, diff --git a/app/models/puppetclass.rb b/app/models/puppetclass.rb index cc4fbe0d186..7a5f9cc5fa5 100644 --- a/app/models/puppetclass.rb +++ b/app/models/puppetclass.rb @@ -8,7 +8,7 @@ class Puppetclass < ActiveRecord::Base validates_lengths_from_database before_destroy EnsureNotUsedBy.new(:hosts, :hostgroups) has_many :environment_classes, :dependent => :destroy - has_many :environments, :through => :environment_classes, :uniq => true + has_many :environments, -> { uniq }, :through => :environment_classes has_and_belongs_to_many :operatingsystems has_many :hostgroup_classes has_many :hostgroups, :through => :hostgroup_classes, :dependent => :destroy @@ -19,8 +19,8 @@ class Puppetclass < ActiveRecord::Base has_many :lookup_keys, :inverse_of => :puppetclass, :dependent => :destroy, :class_name => 'VariableLookupKey' accepts_nested_attributes_for :lookup_keys, :reject_if => ->(a) { a[:key].blank? }, :allow_destroy => true # param classes - has_many :class_params, :through => :environment_classes, :uniq => true, - :source => :puppetclass_lookup_key, :conditions => 'environment_classes.puppetclass_lookup_key_id is NOT NULL' + has_many :class_params, -> { where('environment_classes.puppetclass_lookup_key_id is NOT NULL').uniq }, + :through => :environment_classes, :source => :puppetclass_lookup_key accepts_nested_attributes_for :class_params, :reject_if => ->(a) { a[:key].blank? }, :allow_destroy => true validates :name, :uniqueness => true, :presence => true, :no_whitespace => true @@ -202,7 +202,7 @@ def self.prepare_rdoc(root) def self.search_by_host(key, operator, value) conditions = sanitize_sql_for_conditions(["hosts.name #{operator} ?", value_to_sql(operator, value)]) - direct = Puppetclass.joins(:hosts).where(conditions).uniq.pluck('puppetclasses.id') + direct = Puppetclass.joins(:hosts).where(conditions).pluck('puppetclasses.id').uniq hostgroup = Hostgroup.joins(:hosts).where(conditions).first indirect = hostgroup.blank? ? [] : HostgroupClass.where(:hostgroup_id => hostgroup.path_ids).uniq.pluck('puppetclass_id') return { :conditions => "1=0" } if direct.blank? && indirect.blank? diff --git a/app/models/report.rb b/app/models/report.rb index 806fe34a073..9d5b7484b34 100644 --- a/app/models/report.rb +++ b/app/models/report.rb @@ -31,7 +31,7 @@ class Report < ActiveRecord::Base # returns reports for hosts in the User's filter set scope :my_reports, lambda { if !User.current.admin? || Organization.expand(Organization.current).present? || Location.expand(Location.current).present? - joins_authorized(Host, :view_hosts, :where => Host.taxonomy_conditions) + joins_authorized(Host, :view_hosts) end } diff --git a/app/models/subnet.rb b/app/models/subnet.rb index 735ba11cedd..9b5d709e016 100644 --- a/app/models/subnet.rb +++ b/app/models/subnet.rb @@ -23,7 +23,7 @@ class Subnet < ActiveRecord::Base has_many :subnet_domains, :dependent => :destroy has_many :domains, :through => :subnet_domains has_many :interfaces, :class_name => 'Nic::Base' - has_many :primary_interfaces, :class_name => 'Nic::Base', :conditions => { :primary => true } + has_many :primary_interfaces, -> { where(:primary => true) }, :class_name => 'Nic::Base' has_many :hosts, :through => :interfaces has_many :primary_hosts, :through => :primary_interfaces, :source => :host validates :network, :mask, :name, :presence => true diff --git a/app/models/user.rb b/app/models/user.rb index 29e2616d055..ebc5af10c90 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -25,10 +25,10 @@ class User < ActiveRecord::Base has_many :auditable_changes, :class_name => '::Audit', :as => :user has_many :direct_hosts, :class_name => 'Host', :as => :owner has_many :usergroup_member, :dependent => :destroy, :as => :member - has_many :user_roles, :dependent => :destroy, :foreign_key => 'owner_id', :conditions => {:owner_type => self.to_s} + has_many :user_roles, -> { where(:owner_type => 'User') }, :dependent => :destroy, :foreign_key => 'owner_id' has_many :cached_user_roles, :dependent => :destroy has_many :cached_usergroups, :through => :cached_usergroup_members, :source => :usergroup - has_many :cached_roles, :through => :cached_user_roles, :source => :role, :uniq => true + has_many :cached_roles, -> { uniq }, :through => :cached_user_roles, :source => :role has_many :usergroups, :through => :usergroup_member, :dependent => :destroy has_many :roles, :through => :user_roles, :dependent => :destroy has_many :filters, :through => :cached_roles @@ -393,6 +393,7 @@ def self.random_password(size = 16) end def expire_topbar_cache(sweeper) + return if sweeper.controller.nil? sweeper.expire_fragment(TopbarSweeper.fragment_name(id)) end diff --git a/app/models/user_mail_notification.rb b/app/models/user_mail_notification.rb index b3869fb43d1..041b2122e34 100644 --- a/app/models/user_mail_notification.rb +++ b/app/models/user_mail_notification.rb @@ -4,7 +4,7 @@ class UserMailNotification < ActiveRecord::Base belongs_to :user belongs_to :mail_notification - validates :user_id, :presence => true + validates :user, :presence => true validates :mail_notification, :presence => true scope :daily, -> { where(:interval => 'Daily') } diff --git a/app/models/user_role.rb b/app/models/user_role.rb index 5478a528c40..b49180c46eb 100644 --- a/app/models/user_role.rb +++ b/app/models/user_role.rb @@ -59,7 +59,7 @@ def cache_user_roles! end def build_user_role_cache - [ self.cached_user_roles.build(:user => owner, :role => role) ] + [ self.cached_user_roles.build(:user_id => owner.id, :role_id => role.id) ] end def build_user_group_role_cache(owner) diff --git a/app/models/usergroup.rb b/app/models/usergroup.rb index 1570670d78b..c255fd15f20 100644 --- a/app/models/usergroup.rb +++ b/app/models/usergroup.rb @@ -11,7 +11,7 @@ class Usergroup < ActiveRecord::Base validates_lengths_from_database before_destroy EnsureNotUsedBy.new(:hosts), :ensure_last_admin_group_is_not_deleted - has_many :user_roles, :dependent => :destroy, :foreign_key => 'owner_id', :conditions => {:owner_type => self.to_s} + has_many :user_roles, -> { where(:owner_type => 'Usergroup') }, :dependent => :destroy, :foreign_key => 'owner_id' has_many :roles, :through => :user_roles, :dependent => :destroy has_many :usergroup_members, :dependent => :destroy @@ -19,12 +19,14 @@ class Usergroup < ActiveRecord::Base has_many :usergroups, :through => :usergroup_members, :source => :member, :source_type => 'Usergroup', :dependent => :destroy has_many :external_usergroups, :dependent => :destroy, :inverse_of => :usergroup - has_many :cached_usergroup_members - has_many :usergroup_parents, :dependent => :destroy, :foreign_key => 'member_id', - :conditions => "member_type = 'Usergroup'", :class_name => 'UsergroupMember' + has_many :cached_usergroups, :through => :cached_usergroup_members, :source => :usergroup + has_many :cached_usergroup_members, :foreign_key => 'usergroup_id' + has_many :usergroup_parents, -> { where("member_type = 'Usergroup'") }, :dependent => :destroy, + :foreign_key => 'member_id', :class_name => 'UsergroupMember' has_many :parents, :through => :usergroup_parents, :source => :usergroup, :dependent => :destroy has_many_hosts :as => :owner + validates :name, :uniqueness => true, :presence => true # The text item to see in a select dropdown menu diff --git a/app/models/usergroup_member.rb b/app/models/usergroup_member.rb index e27c25c99dd..781bf438f35 100644 --- a/app/models/usergroup_member.rb +++ b/app/models/usergroup_member.rb @@ -100,7 +100,7 @@ def find_all_user_roles end def find_all_user_roles_for(usergroup) - usergroup.user_roles + usergroup.parents.map { |g| find_all_user_roles_for(g) } + (UserRole.where(:owner => usergroup )+ usergroup.parents.map { |g| find_all_user_roles_for(g) }).flatten end def find_all_usergroups diff --git a/app/services/foreman/plugin.rb b/app/services/foreman/plugin.rb index 0899b1fc33f..853a57b4515 100644 --- a/app/services/foreman/plugin.rb +++ b/app/services/foreman/plugin.rb @@ -176,6 +176,9 @@ def delete_menu_item(menu, item) end def tests_to_skip(hash) + Rails.logger.warn "Minitest 5 deprecated the runner API and plugin tests \ +can't be skipped right now. Future versions of Foreman might bring back this \ +feature" # Format is { "testclass" => [ "skip1", "skip2" ] } hash.each do |testclass,tests| if self.class.tests_to_skip[testclass].nil? @@ -219,8 +222,12 @@ def role(name, permissions) end def pending_migrations - migrations = ActiveRecord::Migrator.new(:up, ActiveRecord::Migrator.migrations_paths).pending_migrations - migrations.size > 0 + migration_paths = ActiveRecord::Migrator.migrations( + ActiveRecord::Migrator.migrations_paths) + pending_migrations = ActiveRecord::Migrator.new(:up, migration_paths). + pending_migrations + + pending_migrations.size > 0 end # List of helper methods allowed for templates in safe mode diff --git a/app/services/tax_host.rb b/app/services/tax_host.rb index 010b40d0372..11c8a1ec17f 100644 --- a/app/services/tax_host.rb +++ b/app/services/tax_host.rb @@ -154,8 +154,9 @@ def non_inherited_ids(v1 = self.selected_ids, v2 = self.inherited_ids) # populate used_ids for 3 non-standard_id's def user_ids(hosts = self.hosts) - #TODO: when migrating to rails 3.1+ switch to inner select on users. - User.unscoped.joins(:direct_hosts).where({ :hosts => { :id => hosts }, :users => { :admin => false } }).pluck('DISTINCT users.id') + User.unscoped.except_admin. + eager_load(:direct_hosts).where(:hosts => { :id => hosts.map(&:id) }). + pluck('DISTINCT users.id') end def provisioning_template_ids(hosts = self.hosts) diff --git a/app/views/api/v2/interfaces/base.json.rabl b/app/views/api/v2/interfaces/base.json.rabl index 43dcaf324f2..2181267775c 100644 --- a/app/views/api/v2/interfaces/base.json.rabl +++ b/app/views/api/v2/interfaces/base.json.rabl @@ -2,5 +2,6 @@ object @interface attributes :id, :name, :ip, :mac, :identifier, :primary, :provision node :type do |i| + next if i.is_a? Symbol i.class.humanized_name.downcase end diff --git a/bundler.d/assets.rb b/bundler.d/assets.rb index 319985db144..fdad5db1f00 100644 --- a/bundler.d/assets.rb +++ b/bundler.d/assets.rb @@ -1,21 +1,18 @@ group :assets do gem 'ace-rails-ap', '~> 4.0.0' - gem 'sass-rails', '~> 3.2' + gem 'sass-rails', '~> 4.0' gem 'uglifier', '>= 1.0.3' gem 'execjs', '>= 1.4.0', '<2.5.0' - gem 'jquery-rails', '2.0.3' + gem 'jquery-rails', '~> 3.1' gem 'jquery-ui-rails', '< 5.0.0' gem 'bootstrap-sass', '3.0.3.0' - gem 'spice-html5-rails', '~> 0.1.4' + gem 'spice-html5-rails', '~> 0.1.5' gem 'flot-rails', '0.0.3' gem 'quiet_assets', '~> 1.0' - gem 'gettext_i18n_rails_js', '~> 0.0', '>= 0.0.8' - # unspecified dep of gettext_i18n_rails_js - # https://github.com/nubis/gettext_i18n_rails_js/pull/23 - gem 'gettext', '~> 3.1', :require => false + gem 'gettext_i18n_rails_js', '~> 1.0' gem 'multi-select-rails', '~> 0.9' - gem 'gridster-rails', '~> 0.5' - gem 'jquery_pwstrength_bootstrap', '~> 1.2' + gem 'gridster-rails', '0.5.6' + gem 'jquery_pwstrength_bootstrap_4', :require => 'jquery_pwstrength_bootstrap' gem 'jquery-turbolinks', '~> 2.1' gem 'select2-rails', '~> 3.5' gem 'underscore-rails', '~> 1.8' diff --git a/bundler.d/console.rb b/bundler.d/console.rb index 40d40e295c2..1affb5c30be 100644 --- a/bundler.d/console.rb +++ b/bundler.d/console.rb @@ -2,7 +2,4 @@ gem 'wirb', '~> 1.0' gem 'hirb-unicode', '~> 0.0.5' gem 'awesome_print', '~> 1.0', :require => 'ap' - - # minitest - workaround until Rails 4.0 (#2650) - gem 'minitest', '~> 4.7', :require => 'minitest/unit' end diff --git a/bundler.d/test.rb b/bundler.d/test.rb index 526ad8b9f41..7a819a37f27 100644 --- a/bundler.d/test.rb +++ b/bundler.d/test.rb @@ -3,13 +3,13 @@ gem 'simplecov', '~> 0.9' gem 'spork-minitest', '0.0.3' gem 'single_test', '~> 0.6' - gem 'minitest', '~> 4.7' - gem 'minitest-spec-rails', '~> 4.7' - gem 'ci_reporter', '>= 1.6.3', '< 2.0.0', :require => false + gem 'minitest', '~> 5.1.0' + gem 'minitest-spec-rails', '~> 5.3' + gem 'ci_reporter_minitest', :require => false gem 'capybara', '~> 2.0' gem 'database_cleaner', '~> 1.3' gem 'launchy', '~> 2.4' - gem 'spork', '~> 0.9' + gem 'spork-rails', '~> 4.0.0' gem 'factory_girl_rails', '~> 4.5', :require => false gem 'rubocop-checkstyle_formatter', '~> 0.2' gem "poltergeist" diff --git a/config/application.rb b/config/application.rb index 8734ca1a7ce..83aef6f4edd 100644 --- a/config/application.rb +++ b/config/application.rb @@ -1,6 +1,8 @@ +if defined?(Rake.application) && Rake.application.top_level_tasks.grep(/jenkins/).any? + ENV['RAILS_ENV'] ||= 'test' +end require File.expand_path('../boot', __FILE__) require 'apipie/middleware/checksum_in_headers' - require 'rails/all' require File.expand_path('../../config/settings', __FILE__) @@ -85,7 +87,9 @@ module Foreman class Application < Rails::Application # Setup additional routes by loading all routes file from routes directory - config.paths["config/routes"] += Dir[Rails.root.join("config/routes/**/*.rb")] + Dir["#{Rails.root}/config/routes/**/*.rb"].each do |route_file| + config.paths['config/routes.rb'] << route_file + end # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers diff --git a/config/environments/development.rb b/config/environments/development.rb index dee9b93b32e..cf9e3944dec 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -24,18 +24,18 @@ # Should ANSI color codes be used when logging information config.colorize_logging = Foreman::Logging.config[:colorize] - # Do not compress assets - config.assets.compress = false - # Expands the lines which load the assets config.assets.debug = true # Raise exception on mass assignment protection for Active Record models config.active_record.mass_assignment_sanitizer = :strict - # Log the query plan for queries taking more than this (works - # with SQLite, MySQL, and PostgreSQL) - config.active_record.auto_explain_threshold_in_seconds = 0.5 + # Force Rails to not create an initial schema automatically. + # This is necessary to avoid Jenkins throwing an error 'schema.rb does not + # exist yet' when there is no db and it tries to run: + # bundle exec rake db:drop db:create db:migrate + # + # config.active_record.maintain_test_schema = false config.after_initialize do Bullet.enable = true diff --git a/config/environments/production.rb b/config/environments/production.rb index a024ffb0eca..e3cbed2eecb 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -42,6 +42,7 @@ # Eager load all classes under lib directory config.eager_load_paths += ["#{config.root}/lib"] + config.eager_load = true # Enable locale fallbacks for I18n (makes lookups for any locale fall back to # the I18n.default_locale when a translation can not be found) @@ -51,11 +52,11 @@ config.active_support.deprecation = :notify # Compress JavaScripts and CSS - config.assets.compress = true + config.assets.js_compressor = :uglifier # Fallback to assets pipeline if a precompiled asset is missed: # that's the case when an engine with it's own assets is added to Foreman later in production. - config.assets.compile = true + config.assets.compile = false # Generate digests for assets URLs config.assets.digest = true diff --git a/config/environments/test.rb b/config/environments/test.rb index 8f97d032ef2..475dc8eafe1 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -49,4 +49,7 @@ # Use separate cache stores for parallel_tests config.cache_store = :file_store, Rails.root.join("tmp", "cache", "paralleltests#{ENV['TEST_ENV_NUMBER']}") + + # Enable automatic creation/migration of the test DB when running tests + config.active_record.maintain_test_schema = true end diff --git a/config/initializers/1_fast_gettext.rb b/config/initializers/1_fast_gettext.rb index c2014cf8444..ead96f4a80b 100644 --- a/config/initializers/1_fast_gettext.rb +++ b/config/initializers/1_fast_gettext.rb @@ -7,6 +7,9 @@ Foreman::Gettext::Support.register_available_locales locale_domain, locale_dir Foreman::Gettext::Support.add_text_domain locale_domain, locale_dir +I18n.config.enforce_available_locales = false +I18n.config.available_locales = FastGettext.default_available_locales + FastGettext.default_text_domain = locale_domain FastGettext.locale = "en" diff --git a/config/initializers/apipie.rb b/config/initializers/apipie.rb index eb2cffd2c51..30c07da3df9 100644 --- a/config/initializers/apipie.rb +++ b/config/initializers/apipie.rb @@ -15,6 +15,7 @@ config.default_locale = FastGettext.default_locale config.locale = ->(loc) { loc ? FastGettext.set_locale(loc) : FastGettext.locale } + ActiveRecord::Migration.maintain_test_schema! substitutions = { :operatingsystem_families => Operatingsystem.families.join(", "), :providers => ComputeResource.providers.join(', '), diff --git a/config/initializers/routing_hash_for.rb b/config/initializers/routing_hash_for.rb new file mode 100644 index 00000000000..9c163e265bf --- /dev/null +++ b/config/initializers/routing_hash_for.rb @@ -0,0 +1,29 @@ +module ActionDispatch + module Routing + class RouteSet + class NamedRouteCollection + def define_url_helper(route, name, options) + helper = UrlHelper.create(route, options.dup) + + @module.remove_possible_method name + @module.module_eval do + define_method(name) do |*args| + helper.call self, args + end + + #because we heavily rely on the removed hash_for method in routes, we must add this monkey patch. + define_method("hash_for_#{name}") do |*args| + unless args.first.is_a? Hash + id = args.first.try(:to_param) + options[:id] = id if id.present? + end + helper.send(:handle_positional_args, self, args, options, []) + end + end + + helpers << name + end + end + end + end +end diff --git a/db/migrate/20110616080444_add_look_up_key_id_to_puppet_class.rb b/db/migrate/20110616080444_add_look_up_key_id_to_puppet_class.rb index e38216b4bb5..0aa75dad8b8 100644 --- a/db/migrate/20110616080444_add_look_up_key_id_to_puppet_class.rb +++ b/db/migrate/20110616080444_add_look_up_key_id_to_puppet_class.rb @@ -11,7 +11,6 @@ def up add_column :lookup_keys, :validator_type, :string add_column :lookup_keys, :validator_rule, :string rename_column :lookup_values, :priority, :match - add_index :lookup_values, :match end def down diff --git a/db/migrate/20140219183343_migrate_permissions.rb b/db/migrate/20140219183343_migrate_permissions.rb index 08efe504367..f15d3509f75 100644 --- a/db/migrate/20140219183343_migrate_permissions.rb +++ b/db/migrate/20140219183343_migrate_permissions.rb @@ -22,12 +22,12 @@ def resource_type @resource_type ||= permissions.first.try(:resource_type) end - taxonomy_join_table = "taxable_taxonomies" + taxonomy_join_table = :taxable_taxonomies has_many taxonomy_join_table, :dependent => :destroy, :as => :taxable, :foreign_key => 'taxable_id' - has_many :locations, :through => taxonomy_join_table, :source => :taxonomy, - :conditions => "taxonomies.type='Location'", :validate => false - has_many :organizations, :through => taxonomy_join_table, :source => :taxonomy, - :conditions => "taxonomies.type='Organization'", :validate => false + has_many :locations, -> { where(:type => 'Location') }, :through => taxonomy_join_table, :source => :taxonomy, + :validate => false + has_many :organizations, -> { where(:type => 'Organization') }, :through => taxonomy_join_table, :source => :taxonomy, + :validate => false end class FakeUserRole < ActiveRecord::Base @@ -61,15 +61,15 @@ def self.name has_many :hostgroups, :through => :user_hostgroups has_many :user_facts, :dependent => :destroy, :foreign_key => 'user_id' has_many :facts, :through => :user_facts, :source => :fact_name - has_many :user_roles, :dependent => :destroy, :foreign_key => 'owner_id', - :conditions => {:owner_type => 'User'}, :class_name => 'FakeUserRole' + has_many :user_roles, -> { where(:owner_type => 'User') }, :dependent => :destroy, :foreign_key => 'owner_id', + :class_name => 'FakeUserRole' has_many :roles, :through => :user_roles, :dependent => :destroy, :class_name => 'FakeRole' - taxonomy_join_table = "taxable_taxonomies" + taxonomy_join_table = :taxable_taxonomies has_many taxonomy_join_table, :dependent => :destroy, :as => :taxable, :foreign_key => 'taxable_id' - has_many :locations, :through => taxonomy_join_table, :source => :taxonomy, - :conditions => "taxonomies.type='Location'", :validate => false - has_many :organizations, :through => taxonomy_join_table, :source => :taxonomy, - :conditions => "taxonomies.type='Organization'", :validate => false + has_many :locations, -> { where(:type => 'Location') }, :through => taxonomy_join_table, :source => :taxonomy, + :validate => false + has_many :organizations, -> { where(:type => 'Organization') }, :through => taxonomy_join_table, :source => :taxonomy, + :validate => false has_many :cached_usergroup_members, :foreign_key => 'user_id' has_many :cached_usergroups, :through => :cached_usergroup_members, :source => :usergroup end diff --git a/db/schema.rb b/db/schema.rb new file mode 100644 index 00000000000..a8e9e87ea4f --- /dev/null +++ b/db/schema.rb @@ -0,0 +1,860 @@ +# encoding: UTF-8 +# This file is auto-generated from the current state of the database. Instead +# of editing this file, please use the migrations feature of Active Record to +# incrementally modify your database, and then regenerate this schema definition. +# +# Note that this schema.rb definition is the authoritative source for your +# database schema. If you need to create the application database on another +# system, you should be using db:schema:load, not running all the migrations +# from scratch. The latter is a flawed and unsustainable approach (the more migrations +# you'll amass, the slower it'll run and the greater likelihood for issues). +# +# It's strongly recommended that you check this file into your version control system. + +ActiveRecord::Schema.define(version: 20151109152507) do + + create_table "architectures", force: true do |t| + t.string "name", null: false + t.datetime "created_at" + t.datetime "updated_at" + t.integer "hosts_count", default: 0 + t.integer "hostgroups_count", default: 0 + end + + create_table "architectures_operatingsystems", id: false, force: true do |t| + t.integer "architecture_id", null: false + t.integer "operatingsystem_id", null: false + end + + create_table "audits", force: true do |t| + t.integer "auditable_id" + t.string "auditable_type" + t.integer "user_id" + t.string "user_type" + t.string "username" + t.string "action" + t.text "audited_changes" + t.integer "version", default: 0 + t.string "comment" + t.integer "associated_id" + t.string "associated_type" + t.string "request_uuid" + t.datetime "created_at" + t.string "remote_address" + t.text "auditable_name" + t.string "associated_name" + end + + add_index "audits", ["associated_id", "associated_type"], name: "associated_index" + add_index "audits", ["associated_id", "associated_type"], name: "auditable_parent_index" + add_index "audits", ["auditable_id", "auditable_type"], name: "auditable_index" + add_index "audits", ["created_at"], name: "index_audits_on_created_at" + add_index "audits", ["id"], name: "index_audits_on_id" + add_index "audits", ["request_uuid"], name: "index_audits_on_request_uuid" + add_index "audits", ["user_id", "user_type"], name: "user_index" + + create_table "auth_sources", force: true do |t| + t.string "type", default: "", null: false + t.string "name", default: "", null: false + t.string "host" + t.integer "port" + t.string "account" + t.string "account_password" + t.string "base_dn" + t.string "attr_login" + t.string "attr_firstname" + t.string "attr_lastname" + t.string "attr_mail" + t.boolean "onthefly_register", default: false, null: false + t.boolean "tls", default: false, null: false + t.datetime "created_at" + t.datetime "updated_at" + t.string "ldap_filter" + t.string "attr_photo" + t.string "server_type", default: "posix" + t.string "groups_base" + t.boolean "usergroup_sync", default: true, null: false + end + + create_table "bookmarks", force: true do |t| + t.string "name" + t.text "query" + t.string "controller" + t.boolean "public" + t.integer "owner_id" + t.string "owner_type" + end + + add_index "bookmarks", ["controller"], name: "index_bookmarks_on_controller" + add_index "bookmarks", ["name"], name: "index_bookmarks_on_name" + add_index "bookmarks", ["owner_id", "owner_type"], name: "index_bookmarks_on_owner_id_and_owner_type" + + create_table "cached_user_roles", force: true do |t| + t.integer "user_id", null: false + t.integer "role_id", null: false + t.integer "user_role_id", null: false + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "cached_user_roles", ["role_id"], name: "index_cached_user_roles_on_role_id" + add_index "cached_user_roles", ["user_id"], name: "index_cached_user_roles_on_user_id" + add_index "cached_user_roles", ["user_role_id"], name: "index_cached_user_roles_on_user_role_id" + + create_table "cached_usergroup_members", force: true do |t| + t.integer "user_id" + t.integer "usergroup_id" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "cached_usergroup_members", ["user_id"], name: "index_cached_usergroup_members_on_user_id" + add_index "cached_usergroup_members", ["usergroup_id"], name: "index_cached_usergroup_members_on_usergroup_id" + + create_table "compute_attributes", force: true do |t| + t.integer "compute_profile_id" + t.integer "compute_resource_id" + t.string "name" + t.text "vm_attrs" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "compute_attributes", ["compute_profile_id"], name: "index_compute_attributes_on_compute_profile_id" + add_index "compute_attributes", ["compute_resource_id"], name: "index_compute_attributes_on_compute_resource_id" + + create_table "compute_profiles", force: true do |t| + t.string "name" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "compute_resources", force: true do |t| + t.string "name" + t.text "description" + t.string "url" + t.string "user" + t.text "password" + t.string "uuid" + t.string "type" + t.datetime "created_at" + t.datetime "updated_at" + t.text "attrs" + end + + create_table "config_group_classes", force: true do |t| + t.integer "puppetclass_id" + t.integer "config_group_id" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "config_groups", force: true do |t| + t.string "name" + t.datetime "created_at" + t.datetime "updated_at" + t.integer "hosts_count", default: 0 + t.integer "hostgroups_count", default: 0 + t.integer "config_group_classes_count", default: 0 + end + + create_table "domains", force: true do |t| + t.string "name", default: "", null: false + t.string "fullname" + t.datetime "created_at" + t.datetime "updated_at" + t.integer "dns_id" + t.integer "total_hosts", default: 0 + t.integer "hostgroups_count", default: 0 + end + + create_table "environment_classes", force: true do |t| + t.integer "puppetclass_id", null: false + t.integer "environment_id", null: false + t.integer "puppetclass_lookup_key_id" + end + + add_index "environment_classes", ["environment_id"], name: "index_environment_classes_on_environment_id" + add_index "environment_classes", ["puppetclass_id"], name: "index_environment_classes_on_puppetclass_id" + + create_table "environments", force: true do |t| + t.string "name", null: false + t.datetime "created_at" + t.datetime "updated_at" + t.integer "hosts_count", default: 0 + t.integer "hostgroups_count", default: 0 + end + + create_table "external_usergroups", force: true do |t| + t.string "name", null: false + t.integer "auth_source_id", null: false + t.integer "usergroup_id", null: false + end + + add_index "external_usergroups", ["usergroup_id"], name: "index_external_usergroups_on_usergroup_id" + + create_table "fact_names", force: true do |t| + t.string "name", null: false + t.datetime "updated_at" + t.datetime "created_at" + t.boolean "compose", default: false, null: false + t.string "short_name" + t.string "type", default: "FactName" + t.string "ancestry" + end + + add_index "fact_names", ["ancestry"], name: "index_fact_names_on_ancestry" + add_index "fact_names", ["name", "type"], name: "index_fact_names_on_name_and_type", unique: true + + create_table "fact_values", force: true do |t| + t.text "value" + t.integer "fact_name_id", null: false + t.integer "host_id", null: false + t.datetime "updated_at" + t.datetime "created_at" + end + + add_index "fact_values", ["fact_name_id", "host_id"], name: "index_fact_values_on_fact_name_id_and_host_id", unique: true + add_index "fact_values", ["fact_name_id"], name: "index_fact_values_on_fact_name_id" + add_index "fact_values", ["host_id"], name: "index_fact_values_on_host_id" + + create_table "features", force: true do |t| + t.string "name" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "features_smart_proxies", id: false, force: true do |t| + t.integer "smart_proxy_id" + t.integer "feature_id" + end + + create_table "filterings", force: true do |t| + t.integer "filter_id" + t.integer "permission_id" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "filterings", ["filter_id"], name: "index_filterings_on_filter_id" + add_index "filterings", ["permission_id"], name: "index_filterings_on_permission_id" + + create_table "filters", force: true do |t| + t.text "search" + t.integer "role_id" + t.datetime "created_at" + t.datetime "updated_at" + t.text "taxonomy_search" + end + + create_table "host_classes", force: true do |t| + t.integer "puppetclass_id", null: false + t.integer "host_id", null: false + end + + create_table "host_config_groups", force: true do |t| + t.integer "config_group_id" + t.integer "host_id" + t.string "host_type" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "host_status", force: true do |t| + t.string "type" + t.integer "status", limit: 8, default: 0, null: false + t.integer "host_id", null: false + t.datetime "reported_at", null: false + end + + add_index "host_status", ["host_id"], name: "index_host_status_on_host_id" + add_index "host_status", ["type", "host_id"], name: "index_host_status_on_type_and_host_id", unique: true + + create_table "hostgroup_classes", force: true do |t| + t.integer "hostgroup_id", null: false + t.integer "puppetclass_id", null: false + end + + add_index "hostgroup_classes", ["hostgroup_id"], name: "index_hostgroup_classes_on_hostgroup_id" + add_index "hostgroup_classes", ["puppetclass_id"], name: "index_hostgroup_classes_on_puppetclass_id" + + create_table "hostgroups", force: true do |t| + t.string "name" + t.datetime "created_at" + t.datetime "updated_at" + t.integer "environment_id" + t.integer "operatingsystem_id" + t.integer "architecture_id" + t.integer "medium_id" + t.integer "ptable_id" + t.string "root_pass" + t.integer "puppet_ca_proxy_id" + t.boolean "use_image" + t.string "image_file", limit: 128 + t.string "ancestry" + t.text "vm_defaults" + t.integer "subnet_id" + t.integer "domain_id" + t.integer "puppet_proxy_id" + t.string "title" + t.integer "realm_id" + t.integer "compute_profile_id" + t.string "grub_pass", default: "" + t.string "lookup_value_matcher" + t.integer "hosts_count", default: 0 + end + + add_index "hostgroups", ["ancestry"], name: "index_hostgroups_on_ancestry" + add_index "hostgroups", ["compute_profile_id"], name: "index_hostgroups_on_compute_profile_id" + + create_table "hosts", force: true do |t| + t.string "name", null: false + t.datetime "last_compile" + t.datetime "last_report" + t.datetime "updated_at" + t.datetime "created_at" + t.string "root_pass" + t.integer "architecture_id" + t.integer "operatingsystem_id" + t.integer "environment_id" + t.integer "ptable_id" + t.integer "medium_id" + t.boolean "build", default: false + t.text "comment" + t.text "disk" + t.datetime "installed_at" + t.integer "model_id" + t.integer "hostgroup_id" + t.integer "owner_id" + t.string "owner_type" + t.boolean "enabled", default: true + t.integer "puppet_ca_proxy_id" + t.boolean "managed", default: false, null: false + t.boolean "use_image" + t.string "image_file", limit: 128 + t.string "uuid" + t.integer "compute_resource_id" + t.integer "puppet_proxy_id" + t.string "certname" + t.integer "image_id" + t.integer "organization_id" + t.integer "location_id" + t.string "type" + t.string "otp" + t.integer "realm_id" + t.integer "compute_profile_id" + t.string "provision_method" + t.string "grub_pass", default: "" + t.integer "global_status", default: 0, null: false + t.string "lookup_value_matcher" + end + + add_index "hosts", ["architecture_id"], name: "host_arch_id_ix" + add_index "hosts", ["certname"], name: "index_hosts_on_certname" + add_index "hosts", ["compute_profile_id"], name: "index_hosts_on_compute_profile_id" + add_index "hosts", ["environment_id"], name: "host_env_id_ix" + add_index "hosts", ["hostgroup_id"], name: "host_group_id_ix" + add_index "hosts", ["installed_at"], name: "index_hosts_on_installed_at" + add_index "hosts", ["last_report"], name: "index_hosts_on_last_report" + add_index "hosts", ["medium_id"], name: "host_medium_id_ix" + add_index "hosts", ["name"], name: "index_hosts_on_name" + add_index "hosts", ["operatingsystem_id"], name: "host_os_id_ix" + add_index "hosts", ["type"], name: "index_hosts_on_type" + + create_table "images", force: true do |t| + t.integer "operatingsystem_id" + t.integer "compute_resource_id" + t.integer "architecture_id" + t.string "uuid" + t.string "username" + t.string "name" + t.datetime "created_at" + t.datetime "updated_at" + t.string "iam_role" + t.boolean "user_data", default: false + t.string "password" + end + + create_table "key_pairs", force: true do |t| + t.text "secret" + t.integer "compute_resource_id" + t.string "name" + t.datetime "created_at" + t.datetime "updated_at" + t.text "public" + end + + create_table "locations_organizations", id: false, force: true do |t| + t.integer "location_id" + t.integer "organization_id" + end + + create_table "logs", force: true do |t| + t.integer "source_id" + t.integer "message_id" + t.integer "report_id" + t.integer "level_id" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "logs", ["level_id"], name: "index_logs_on_level_id" + add_index "logs", ["message_id"], name: "index_logs_on_message_id" + add_index "logs", ["report_id"], name: "index_logs_on_report_id" + add_index "logs", ["source_id"], name: "index_logs_on_source_id" + + create_table "lookup_keys", force: true do |t| + t.string "key" + t.datetime "created_at" + t.datetime "updated_at" + t.integer "puppetclass_id" + t.text "default_value" + t.string "path" + t.text "description" + t.string "validator_type" + t.string "validator_rule" + t.string "key_type" + t.boolean "override", default: false + t.boolean "required", default: false + t.integer "lookup_values_count", default: 0 + t.boolean "merge_overrides" + t.boolean "avoid_duplicates" + t.boolean "use_puppet_default" + t.string "type" + t.boolean "merge_default", default: false, null: false + t.boolean "hidden_value", default: false + end + + add_index "lookup_keys", ["key"], name: "index_lookup_keys_on_key" + add_index "lookup_keys", ["path"], name: "index_lookup_keys_on_path" + add_index "lookup_keys", ["puppetclass_id"], name: "index_lookup_keys_on_puppetclass_id" + add_index "lookup_keys", ["type"], name: "index_lookup_keys_on_type" + + create_table "lookup_values", force: true do |t| + t.string "match" + t.text "value" + t.integer "lookup_key_id" + t.datetime "created_at" + t.datetime "updated_at" + t.boolean "use_puppet_default", default: false + end + + add_index "lookup_values", ["match"], name: "index_lookup_values_on_match" + + create_table "mail_notifications", force: true do |t| + t.string "name" + t.text "description" + t.string "mailer" + t.string "method" + t.boolean "subscriptable", default: true + t.string "default_interval" + t.datetime "created_at" + t.datetime "updated_at" + t.string "subscription_type" + t.boolean "queryable", default: false + end + + create_table "media", force: true do |t| + t.string "name", default: "", null: false + t.string "path", default: "", null: false + t.datetime "created_at" + t.datetime "updated_at" + t.string "media_path" + t.string "config_path" + t.string "image_path" + t.string "os_family" + end + + create_table "media_operatingsystems", id: false, force: true do |t| + t.integer "medium_id", null: false + t.integer "operatingsystem_id", null: false + end + + create_table "messages", force: true do |t| + t.text "value" + t.string "digest" + end + + add_index "messages", ["digest"], name: "index_messages_on_digest" + + create_table "models", force: true do |t| + t.string "name", null: false + t.text "info" + t.datetime "created_at" + t.datetime "updated_at" + t.string "vendor_class" + t.string "hardware_model" + t.integer "hosts_count", default: 0 + end + + create_table "nics", force: true do |t| + t.string "mac" + t.string "ip" + t.string "type" + t.string "name" + t.integer "host_id" + t.integer "subnet_id" + t.integer "domain_id" + t.text "attrs" + t.datetime "created_at" + t.datetime "updated_at" + t.string "provider" + t.string "username" + t.string "password" + t.boolean "virtual", default: false, null: false + t.boolean "link", default: true, null: false + t.string "identifier" + t.string "tag", default: "", null: false + t.string "attached_to", default: "", null: false + t.boolean "managed", default: true + t.string "mode", default: "balance-rr", null: false + t.string "attached_devices", default: "", null: false + t.string "bond_options", default: "", null: false + t.boolean "primary", default: false + t.boolean "provision", default: false + t.text "compute_attributes" + end + + add_index "nics", ["host_id"], name: "index_by_host" + add_index "nics", ["type", "id"], name: "index_by_type_and_id" + add_index "nics", ["type"], name: "index_by_type" + + create_table "operatingsystems", force: true do |t| + t.string "major", limit: 5, default: "", null: false + t.string "name", null: false + t.string "minor", limit: 16, default: "", null: false + t.string "nameindicator", limit: 3 + t.datetime "created_at" + t.datetime "updated_at" + t.string "release_name" + t.string "type" + t.text "description" + t.integer "hosts_count", default: 0 + t.integer "hostgroups_count", default: 0 + t.string "password_hash", default: "SHA256" + t.string "title" + end + + add_index "operatingsystems", ["name", "major", "minor"], name: "index_operatingsystems_on_name_and_major_and_minor", unique: true + add_index "operatingsystems", ["title"], name: "index_operatingsystems_on_title", unique: true + add_index "operatingsystems", ["type"], name: "index_operatingsystems_on_type" + + create_table "operatingsystems_provisioning_templates", id: false, force: true do |t| + t.integer "provisioning_template_id", null: false + t.integer "operatingsystem_id", null: false + end + + create_table "operatingsystems_ptables", id: false, force: true do |t| + t.integer "ptable_id", null: false + t.integer "operatingsystem_id", null: false + end + + create_table "operatingsystems_puppetclasses", id: false, force: true do |t| + t.integer "puppetclass_id", null: false + t.integer "operatingsystem_id", null: false + end + + create_table "os_default_templates", force: true do |t| + t.integer "provisioning_template_id" + t.integer "template_kind_id" + t.integer "operatingsystem_id" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "parameters", force: true do |t| + t.string "name" + t.text "value" + t.integer "reference_id" + t.datetime "created_at" + t.datetime "updated_at" + t.string "type" + t.integer "priority" + t.boolean "hidden_value", default: false + end + + add_index "parameters", ["reference_id", "type"], name: "index_parameters_on_reference_id_and_type" + add_index "parameters", ["type", "reference_id", "name"], name: "index_parameters_on_type_and_reference_id_and_name", unique: true + add_index "parameters", ["type"], name: "index_parameters_on_type" + + create_table "permissions", force: true do |t| + t.string "name", null: false + t.string "resource_type" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "permissions", ["name", "resource_type"], name: "index_permissions_on_name_and_resource_type" + + create_table "puppetclasses", force: true do |t| + t.string "name" + t.datetime "created_at" + t.datetime "updated_at" + t.integer "total_hosts", default: 0 + t.integer "hostgroups_count", default: 0 + t.integer "global_class_params_count", default: 0 + t.integer "variable_lookup_keys_count", default: 0 + end + + add_index "puppetclasses", ["name"], name: "index_puppetclasses_on_name" + + create_table "realms", force: true do |t| + t.string "name", default: "", null: false + t.string "realm_type" + t.integer "realm_proxy_id" + t.integer "hosts_count", default: 0 + t.integer "hostgroups_count", default: 0 + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "realms", ["name"], name: "index_realms_on_name", unique: true + + create_table "reports", force: true do |t| + t.integer "host_id", null: false + t.datetime "reported_at", null: false + t.datetime "created_at" + t.datetime "updated_at" + t.integer "status", limit: 8 + t.text "metrics" + t.string "type", default: "ConfigReport", null: false + end + + add_index "reports", ["host_id"], name: "index_reports_on_host_id" + add_index "reports", ["reported_at", "host_id"], name: "index_reports_on_reported_at_and_host_id" + add_index "reports", ["reported_at"], name: "index_reports_on_reported_at" + add_index "reports", ["status"], name: "index_reports_on_status" + + create_table "roles", force: true do |t| + t.string "name" + t.integer "builtin" + t.text "permissions" + end + + create_table "sessions", force: true do |t| + t.string "session_id", null: false + t.text "data" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "sessions", ["session_id"], name: "index_sessions_on_session_id" + add_index "sessions", ["updated_at"], name: "index_sessions_on_updated_at" + + create_table "settings", force: true do |t| + t.string "name" + t.text "value" + t.text "description" + t.string "category" + t.string "settings_type" + t.text "default", null: false + t.datetime "created_at" + t.datetime "updated_at" + t.string "full_name" + end + + add_index "settings", ["category"], name: "index_settings_on_category" + add_index "settings", ["name"], name: "index_settings_on_name", unique: true + + create_table "smart_proxies", force: true do |t| + t.string "name" + t.string "url" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "sources", force: true do |t| + t.text "value" + t.string "digest" + end + + add_index "sources", ["digest"], name: "index_sources_on_digest" + + create_table "subnet_domains", force: true do |t| + t.integer "domain_id" + t.integer "subnet_id" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "subnets", force: true do |t| + t.string "network", limit: 15 + t.string "mask", limit: 15 + t.integer "priority" + t.text "name" + t.string "vlanid", limit: 10 + t.datetime "created_at" + t.datetime "updated_at" + t.integer "dhcp_id" + t.integer "tftp_id" + t.string "gateway" + t.string "dns_primary" + t.string "dns_secondary" + t.string "from" + t.string "to" + t.integer "dns_id" + t.string "boot_mode", default: "DHCP", null: false + t.string "ipam", default: "DHCP", null: false + end + + create_table "taxable_taxonomies", force: true do |t| + t.integer "taxonomy_id" + t.integer "taxable_id" + t.string "taxable_type" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "taxable_taxonomies", ["taxable_id", "taxable_type", "taxonomy_id"], name: "taxable_index" + add_index "taxable_taxonomies", ["taxable_id", "taxable_type"], name: "index_taxable_taxonomies_on_taxable_id_and_taxable_type" + add_index "taxable_taxonomies", ["taxonomy_id"], name: "index_taxable_taxonomies_on_taxonomy_id" + + create_table "taxonomies", force: true do |t| + t.string "name" + t.string "type" + t.datetime "created_at" + t.datetime "updated_at" + t.text "ignore_types" + t.string "ancestry" + t.string "title" + t.text "description" + end + + add_index "taxonomies", ["ancestry"], name: "index_taxonomies_on_ancestry" + + create_table "template_combinations", force: true do |t| + t.integer "provisioning_template_id" + t.integer "hostgroup_id" + t.integer "environment_id" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "template_kinds", force: true do |t| + t.string "name" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "templates", force: true do |t| + t.string "name" + t.text "template" + t.boolean "snippet", default: false, null: false + t.integer "template_kind_id" + t.datetime "created_at" + t.datetime "updated_at" + t.boolean "locked", default: false + t.boolean "default", default: false + t.string "vendor" + t.string "type", default: "ConfigTemplate" + t.string "os_family" + end + + create_table "tokens", force: true do |t| + t.string "value" + t.datetime "expires" + t.integer "host_id" + end + + add_index "tokens", ["host_id"], name: "index_tokens_on_host_id", unique: true + add_index "tokens", ["value"], name: "index_tokens_on_value" + + create_table "trend_counters", force: true do |t| + t.integer "trend_id" + t.integer "count" + t.datetime "created_at" + t.datetime "updated_at" + t.datetime "interval_start" + t.datetime "interval_end" + end + + add_index "trend_counters", ["trend_id"], name: "index_trend_counters_on_trend_id" + + create_table "trends", force: true do |t| + t.string "trendable_type" + t.integer "trendable_id" + t.string "name" + t.string "type" + t.string "fact_value" + t.string "fact_name" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "trends", ["fact_value"], name: "index_trends_on_fact_value" + add_index "trends", ["trendable_type", "trendable_id"], name: "index_trends_on_trendable_type_and_trendable_id" + add_index "trends", ["type"], name: "index_trends_on_type" + + create_table "user_mail_notifications", force: true do |t| + t.integer "user_id" + t.integer "mail_notification_id" + t.datetime "last_sent" + t.string "interval" + t.datetime "created_at" + t.datetime "updated_at" + t.string "mail_query" + end + + create_table "user_roles", force: true do |t| + t.integer "owner_id", null: false + t.integer "role_id" + t.string "owner_type", default: "User", null: false + end + + add_index "user_roles", ["owner_id", "owner_type"], name: "index_user_roles_on_owner_id_and_owner_type" + add_index "user_roles", ["owner_id"], name: "index_user_roles_on_owner_id" + add_index "user_roles", ["owner_type"], name: "index_user_roles_on_owner_type" + + create_table "usergroup_members", force: true do |t| + t.integer "member_id" + t.string "member_type" + t.integer "usergroup_id" + end + + create_table "usergroups", force: true do |t| + t.string "name", null: false + t.datetime "created_at" + t.datetime "updated_at" + t.boolean "admin", default: false, null: false + end + + create_table "users", force: true do |t| + t.string "login" + t.string "firstname" + t.string "lastname" + t.string "mail" + t.boolean "admin", default: false, null: false + t.datetime "last_login_on" + t.integer "auth_source_id" + t.datetime "created_at" + t.datetime "updated_at" + t.string "password_hash", limit: 128 + t.string "password_salt", limit: 128 + t.string "locale", limit: 5 + t.string "avatar_hash", limit: 128 + t.integer "default_organization_id" + t.integer "default_location_id" + t.string "lower_login" + t.boolean "mail_enabled", default: true + t.string "timezone" + end + + add_index "users", ["lower_login"], name: "index_users_on_lower_login", unique: true + + create_table "widgets", force: true do |t| + t.integer "user_id" + t.string "template", null: false + t.string "name", null: false + t.text "data" + t.integer "sizex", default: 4 + t.integer "sizey", default: 1 + t.integer "col", default: 1 + t.integer "row", default: 1 + t.boolean "hide", default: false + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "widgets", ["user_id"], name: "index_widgets_on_user_id" + +end diff --git a/lib/foreman/logging.rb b/lib/foreman/logging.rb index d554b00427e..9ff7ec52169 100644 --- a/lib/foreman/logging.rb +++ b/lib/foreman/logging.rb @@ -1,6 +1,8 @@ require 'logging' require 'fileutils' +::Logging::Logger.send(:include, ActiveRecord::SessionStore::Extension::LoggerSilencer) + module Foreman class LoggingImpl private_class_method :new diff --git a/lib/middleware/catch_json_parse_errors.rb b/lib/middleware/catch_json_parse_errors.rb index 1fbab51cad6..9a5bdf591f6 100644 --- a/lib/middleware/catch_json_parse_errors.rb +++ b/lib/middleware/catch_json_parse_errors.rb @@ -7,7 +7,7 @@ def initialize(app) def call(env) begin @app.call(env) - rescue MultiJson::LoadError, MultiJson::ParseError => error + rescue ActionDispatch::ParamsParser::ParseError => error if env['HTTP_ACCEPT'] =~ /application\/json/ || env['CONTENT_TYPE'] =~ /application\/json/ error_output = "There was a problem in the JSON you submitted: #{error}" Rails.logger.debug(error_output) diff --git a/lib/tasks/jenkins.rake b/lib/tasks/jenkins.rake index a653b592be9..6a4d5ba8803 100644 --- a/lib/tasks/jenkins.rake +++ b/lib/tasks/jenkins.rake @@ -1,14 +1,8 @@ begin require "ci/reporter/rake/minitest" - namespace :foreman do - task :set_test_runner do - ENV['TESTOPTS'] = "#{ENV['TESTOPTS']} #{Rails.root}/test/test_runner.rb" - end - end - namespace :jenkins do - task :unit => ["jenkins:setup:minitest", 'rake:test:units', 'rake:test:lib', 'rake:test:functionals'] + task :unit => ['jenkins:setup:minitest', 'rake:test:units', 'rake:test:lib', 'rake:test:functionals'] task :integration => ["jenkins:setup:minitest", 'rake:test:integration'] task :lib => ["jenkins:setup:minitest", 'rake:test:lib'] task :functionals => ["jenkins:setup:minitest", 'rake:test:functionals'] @@ -19,7 +13,7 @@ begin ENV["CI_REPORTS"] = 'jenkins/reports/unit/' gem 'ci_reporter' end - task :minitest => [:pre_ci, "ci:setup:minitest", "foreman:set_test_runner"] + task :minitest => [:pre_ci, "ci:setup:minitest"] end task :rubocop do @@ -33,4 +27,3 @@ begin rescue LoadError # ci/reporter/rake/rspec not present, skipping this definition end - diff --git a/lib/tasks/plugin_assets.rake b/lib/tasks/plugin_assets.rake index 757d252ec44..ef8e7083b5e 100644 --- a/lib/tasks/plugin_assets.rake +++ b/lib/tasks/plugin_assets.rake @@ -1,5 +1,5 @@ desc 'Compile engine assets - called via rake plugin:assets:precompile[plugin_name]' -task 'plugin:assets:precompile', :engine do |t, args| +task 'plugin:assets:precompile', [:engine] do |t, args| # This task will generate assets for a plugin and namespace them in # plugin_name/public/assets/. The generated manifest.yaml found # in the assets directory of the plugin is used to add the asset digest paths @@ -34,60 +34,51 @@ task 'plugin:assets:precompile', :engine do |t, args| # } # } - def compile_assets(args = {}) - _ = ActionView::Base + module Foreman + class PluginAssetsTask < Sprockets::Rails::Task + attr_accessor :engine - app = Rails.application - assets = app.config.assets - env = app.assets - target = File.join(@engine_root, 'public', 'assets') + def initialize(engine_name) + @engine = "#{engine_name.camelize}::Engine".constantize + Rails.application.config.assets.precompile = SETTINGS[@engine.engine_name.to_sym][:assets][:precompile] + Rails.application.assets.js_compressor = :uglifier + super(Rails.application) + end - assets.digests = {} - assets.manifest = File.join(target, @engine.engine_name) - assets.compile = SETTINGS[@engine.engine_name.to_sym][:assets][:compile] || assets.compile - assets.compress = SETTINGS[@engine.engine_name.to_sym][:assets][:compress] || assets.compress - assets.digest = args.fetch(:digest, true) - assets.js_compressor = SETTINGS[@engine.engine_name.to_sym][:assets][:js_compressor] + def compile + with_logger do + manifest.compile(assets) + end + end - precompile = SETTINGS[@engine.engine_name.to_sym][:assets][:precompile] - precompile = fix_indexes(precompile) + def environment + env = Rails.application.assets + Rails.application.config.assets.paths.each do |path| + env.append_path path + end + env + end - Sprockets::Bootstrap.new(Rails.application).run - compiler = Sprockets::StaticCompiler.new(env, - target, - precompile, - :manifest_path => assets.manifest, - :digest => assets.digest, - :manifest => true) - compiler.compile - end + def output + File.join(@engine.root, 'public', 'assets') + end - # Used to add index manifest files to the paths for - # proper resolution and addition when running Rails 3.2.8 - # in the SCL - def fix_indexes(precompile) - if Rails.version == '3.2.8' - precompile.each do |asset| - if File.basename(asset)[/[^\.]+/, 0] == 'index' - asset.sub!(/\/index\./, '.') - precompile << asset - end + def manifest_path + File.join(output, @engine.engine_name, "#{@engine.engine_name}.json") end - end - precompile + def manifest + Sprockets::Manifest.new(index, output, manifest_path) + end + end end if args[:engine] # Partially load the Rails environment to avoid # the need of a database being setup Rails.application.initialize!(:assets) - - @engine = "#{args[:engine].camelize}::Engine".constantize - @engine_root = @engine.root - - compile_assets(:digest => false) - compile_assets + task = Foreman::PluginAssetsTask.new(args[:engine]) + task.compile else puts "You must specify the name of the plugin (e.g. rake plugin:assets:precompile['my_plugin'])" end diff --git a/lib/tasks/test.rake b/lib/tasks/test.rake index 03ae8123f07..b9ec3fb4f28 100644 --- a/lib/tasks/test.rake +++ b/lib/tasks/test.rake @@ -19,10 +19,3 @@ end Rake::Task[:test].enhance do Rake::Task['test:lib'].invoke end - -Rake::Task[:test].enhance ['foreman:set_test_runner'] -Rake::Task['test:units'].enhance ['foreman:set_test_runner'] -Rake::Task['test:functionals'].enhance ['foreman:set_test_runner'] -Rake::Task['test:integration'].enhance ['foreman:set_test_runner'] -Rake::Task['test:lib'].enhance ['foreman:set_test_runner'] -Rake::Task['test:api'].enhance ['foreman:set_test_runner'] diff --git a/test/functional/api/base_controller_subclass_test.rb b/test/functional/api/base_controller_subclass_test.rb index 989b6ba8ac8..ed5a3b3e805 100644 --- a/test/functional/api/base_controller_subclass_test.rb +++ b/test/functional/api/base_controller_subclass_test.rb @@ -211,48 +211,42 @@ class Api::TestableControllerTest < ActionController::TestCase assert_equal @response.status, 200 end - it 'should return nested resource for unauthorized resource' do - child_associacion = mock('child_associacion') - testable_scope1 = mock('testable_scope1') - testable_scope2 = mock('testable_scope2') - testable_obj = mock('testable1') - - Testable.stubs(:joins).returns(child_associacion) - Testable.stubs(:where).returns(testable_scope2) - Testable.stubs(:scoped).returns(testable_scope2) - testable_scope2.stubs(:merge).returns(testable_scope1) - child_associacion.stubs(:merge).returns(testable_scope1) - testable_scope1.stubs(:readonly).returns(testable_scope1) + context 'nested resource permissions' do + setup do + @child_associacion = mock('child_associacion') + @testable_scope1 = mock('testable_scope1') + @testable_scope2 = mock('testable_scope2') + @testable_obj = mock('testable1') + @testable_scope2.stubs(:merge).returns(@testable_scope1) + @child_associacion.stubs(:merge).returns(@testable_scope1) + @testable_scope1.stubs(:readonly).returns(@testable_scope1) + @testable_scope1.expects(:find).with('1').returns(@testable_obj) + @testable_scope1.expects(:empty?).returns(false) + Testable.stubs(:joins).returns(@child_associacion) + end - testable_scope1.expects(:find).with('1').returns(testable_obj) + it 'should return nested resource for unauthorized resource' do + Testable.stubs(:where).returns(@testable_scope2) + Testable.stubs(:scoped).returns(@testable_scope2) - get :nested_values, :domain_id => 1, :id => 1 + get :nested_values, :domain_id => 1, :id => 1 - assert_equal testable_obj, @controller.instance_variable_get('@testable') - assert_equal @nested_obj, @controller.instance_variable_get('@nested_obj') - end - - it 'should return nested resource scope for authorized resource' do - child_auth_scope = mock('child_auth_scope') - child_associacion = mock('child_associacion') - testable_scope1 = mock('testable_scope1') - testable_scope2 = mock('testable_scope2') - testable_obj = mock('testable1') + assert_equal @testable_obj, @controller.instance_variable_get('@testable') + assert_equal @nested_obj, @controller.instance_variable_get('@nested_obj') + end - Testable.stubs(:authorized).returns(child_auth_scope) - Testable.stubs(:joins).returns(child_associacion) - testable_scope2.stubs(:merge).returns(testable_scope1) - child_associacion.stubs(:merge).returns(testable_scope1) - child_auth_scope.stubs(:where).returns(testable_scope2) - child_auth_scope.stubs(:scoped).returns(testable_scope2) - testable_scope1.stubs(:readonly).returns(testable_scope1) + it 'should return nested resource scope for authorized resource' do + child_auth_scope = mock('child_auth_scope') - testable_scope1.expects(:find).with('1').returns(testable_obj) + Testable.stubs(:authorized).returns(child_auth_scope) + child_auth_scope.stubs(:where).returns(@testable_scope2) + child_auth_scope.stubs(:scoped).returns(@testable_scope2) - get :nested_values, :domain_id => 1, :id => 1 + get :nested_values, :domain_id => 1, :id => 1 - assert_equal testable_obj, @controller.instance_variable_get('@testable') - assert_equal @nested_obj, @controller.instance_variable_get('@nested_obj') + assert_equal @testable_obj, @controller.instance_variable_get('@testable') + assert_equal @nested_obj, @controller.instance_variable_get('@nested_obj') + end end end diff --git a/test/functional/api/v2/smart_class_parameters_controller_test.rb b/test/functional/api/v2/smart_class_parameters_controller_test.rb index c757be0acad..a153155648c 100644 --- a/test/functional/api/v2/smart_class_parameters_controller_test.rb +++ b/test/functional/api/v2/smart_class_parameters_controller_test.rb @@ -64,7 +64,7 @@ class Api::V2::SmartClassParametersControllerTest < ActionController::TestCase get :index, {:puppetclass_id => non_existing_id} assert_response :not_found results = ActiveSupport::JSON.decode(@response.body) - assert_equal "Puppet class with id '#{non_existing_id}' was not found", results["error"]["message"] + assert_equal "Puppetclass with id '#{non_existing_id}' was not found", results["error"]["message"] end test "should get smart class parameters for a specific environment" do diff --git a/test/functional/api/v2/smart_proxies_controller_test.rb b/test/functional/api/v2/smart_proxies_controller_test.rb index 8e5a48a773c..48c48e6f195 100644 --- a/test/functional/api/v2/smart_proxies_controller_test.rb +++ b/test/functional/api/v2/smart_proxies_controller_test.rb @@ -181,7 +181,7 @@ def setup_import_classes test "should obsolete puppetclasses" do setup_import_classes as_admin do - assert_difference('Environment.find("env1").puppetclasses.count', -2) do + assert_difference('Environment.find_by_name("env1").puppetclasses.count', -2) do post :import_puppetclasses, {:id => smart_proxies(:puppetmaster).id}, set_session_user end end diff --git a/test/functional/provisioning_templates_controller_test.rb b/test/functional/provisioning_templates_controller_test.rb index 7c5dd5088d4..680f3f61ee5 100644 --- a/test/functional/provisioning_templates_controller_test.rb +++ b/test/functional/provisioning_templates_controller_test.rb @@ -103,7 +103,7 @@ class ProvisioningTemplatesControllerTest < ActionController::TestCase Setting[:unattended_url] = "http://foreman.unattended.url" @request.env['HTTP_REFERER'] = provisioning_templates_path - ProxyAPI::TFTP.any_instance.expects(:create_default).with(has_entry(:menu, regexp_matches(/ks=http:\/\/foreman.unattended.url:80\/unattended\/template/))).returns(true) + ProxyAPI::TFTP.any_instance.expects(:create_default).with(has_entry(:menu, regexp_matches(/ks=http:\/\/foreman.unattended.url\/unattended\/template/))).returns(true) get :build_pxe_default, {}, set_session_user assert_redirected_to provisioning_templates_path diff --git a/test/functional/unattended_controller_test.rb b/test/functional/unattended_controller_test.rb index e8580f2528b..171f19f7759 100644 --- a/test/functional/unattended_controller_test.rb +++ b/test/functional/unattended_controller_test.rb @@ -243,7 +243,7 @@ class UnattendedControllerTest < ActionController::TestCase @request.env["REMOTE_ADDR"] = @ub_host.ip @ub_host.create_token(:value => token, :expires => Time.now + 5.minutes) get :provision, {'token' => @ub_host.token.value } - assert @response.body.include?("#{Setting[:unattended_url]}:443/unattended/finish?token=#{token}") + assert @response.body.include?("#{Setting[:unattended_url]}/unattended/finish?token=#{token}") end test "hosts with unknown ip and valid token should render a template" do @@ -314,7 +314,7 @@ class UnattendedControllerTest < ActionController::TestCase @request.env["REMOTE_ADDR"] = @ub_host.ip @ub_host.create_token(:value => "aaaaaa", :expires => Time.now + 5.minutes) get :provision - assert @response.body.include?("http://test.host:80/unattended/finish?token=aaaaaa") + assert @response.body.include?("http://test.host/unattended/finish?token=aaaaaa") end end # end of context "location or organizations are not enabled" diff --git a/test/lib/custom_runner.rb b/test/lib/custom_runner_test.rb similarity index 74% rename from test/lib/custom_runner.rb rename to test/lib/custom_runner_test.rb index bedb2d87085..3b0b2a95965 100644 --- a/test/lib/custom_runner.rb +++ b/test/lib/custom_runner_test.rb @@ -1,6 +1,8 @@ require 'test_helper' class CustomRunnerTest < ActiveSupport::TestCase + setup { skip 'Temporarily disabled since Minitest 5 deprecated runner API'} + test "custom runner is working" do # This should always be skipped if the runner is working assert false, "Custom runner has failed" diff --git a/test/test_helper.rb b/test/test_helper.rb index 551b9a139b0..929790352b9 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,7 +1,5 @@ require 'rubygems' require 'spork' -# $LOAD_PATH required for testdrb party of spork-minitest -$LOAD_PATH << "test" require 'simplecov' SimpleCov.start 'rails' do @@ -84,7 +82,9 @@ def clear_current_user alias_method :assert_no_match, :refute_match alias_method :assert_not_nil, :refute_nil alias_method :assert_not_equal, :refute_equal - alias_method :assert_raise, :assert_raises + alias_method :assert_raise, :assert_raises + alias_method :assert_include, :assert_includes + alias_method :assert_not_include, :assert_not_includes class < "test_0010_foo" and string => "foo" - if test[string] - puts "skipping #{self}##{test}" - string - end - end - end - end - end - end - end - - super(suites, type) - end - end -end - -MiniTest::Unit.runner = ForemanMiniTestRunner::Unit.new diff --git a/test/unit/application_mailer_test.rb b/test/unit/application_mailer_test.rb index ffc37f4e2e5..7d84dda404f 100644 --- a/test/unit/application_mailer_test.rb +++ b/test/unit/application_mailer_test.rb @@ -3,10 +3,16 @@ class ApplicationMailerTest < ActiveSupport::TestCase setup { ActionMailer::Base.deliveries = [] } + class TestMailer < ::ApplicationMailer + def test + mail(:to => 'nobody@example.com', :subject => 'Danger, Will Robinson!') do |format| + format.text { render :plain => "This is a test mail." } + end + end + end + def mail - ApplicationMailer.mail(:to => 'nobody@example.com', :subject => 'Danger, Will Robinson!') do |mail| - format.text "This is a test mail." - end.deliver + TestMailer.test.deliver ActionMailer::Base.deliveries.last end diff --git a/test/unit/compute_resource_test.rb b/test/unit/compute_resource_test.rb index f177eee86f5..360629fc4f0 100644 --- a/test/unit/compute_resource_test.rb +++ b/test/unit/compute_resource_test.rb @@ -20,7 +20,6 @@ def setup test "password is saved encrypted when created" do Fog.mock! - teardown { Fog.unmock! } ComputeResource.any_instance.expects(:encryption_key).at_least_once.returns('25d224dd383e92a7e0c82b8bf7c985e815f34cf5') compute_resource = ComputeResource.new_provider(:name => "new12345", :provider => "EC2", :url => "eu-west-1", :user => "username", :password => "abcdef") @@ -29,6 +28,7 @@ def setup end assert_equal compute_resource.password, "abcdef" refute_equal compute_resource.password_in_db, "abcdef" + Fog.unmock! end test "random_password should return nil when set_console_password is false" do diff --git a/test/unit/fact_value_test.rb b/test/unit/fact_value_test.rb index be7ab60b6a2..120585c1648 100644 --- a/test/unit/fact_value_test.rb +++ b/test/unit/fact_value_test.rb @@ -121,41 +121,60 @@ def setup end end - test "only return facts from host in user's taxonomies" do - user_role = FactoryGirl.create(:user_user_role) - FactoryGirl.create(:filter, :role => user_role.role, :permissions => Permission.where(:name => 'view_hosts'), :search => "hostgroup_id = #{target_host.hostgroup_id}") + context 'taxonomies' do + setup do + @orgs = FactoryGirl.create_pair(:organization) + @locs = FactoryGirl.create_pair(:location) + end - orgs = FactoryGirl.create_pair(:organization) - locs = FactoryGirl.create_pair(:location) - target_host.update_attributes(:location => locs.last, :organization => orgs.last) + context 'limited view permissions' do + setup do + setup_user('view', 'hosts', + "hostgroup_id = #{target_host.hostgroup_id}") - user_role.owner.update_attributes(:locations => [locs.first], :organizations => [orgs.first]) - as_user user_role.owner do - assert_equal [], FactValue.my_facts.map(&:id).sort - end + as_admin do + target_host.location = @locs.last + target_host.organization = @orgs.last + target_host.save - user_role.owner.update_attributes(:locations => [locs.last], :organizations => [orgs.last]) - as_user user_role.owner do - assert_equal target_host.fact_values.map(&:id).sort, FactValue.my_facts.map(&:id).sort + hostgroup = Hostgroup.find(target_host.hostgroup_id) + hostgroup.organizations = [@orgs.last] + hostgroup.locations = [@locs.last] + hostgroup.save + end + end + + test 'user cannot view host taxonomy, my_facts is empty' do + users(:one).locations = [@locs.first] + users(:one).organizations = [@orgs.first] + + assert_equal [], FactValue.my_facts.map(&:id).sort + end + + test 'user can view host taxonomy, my_facts contains host facts' do + users(:one).locations = [@locs.last] + users(:one).organizations = [@orgs.last] + + assert_equal target_host.fact_values.map(&:id).sort, + FactValue.my_facts.map(&:id).sort + end end - end - test "only return facts from host in admin's currently selected taxonomy" do - user = as_admin { FactoryGirl.create(:user, :admin) } - orgs = FactoryGirl.create_pair(:organization) - locs = FactoryGirl.create_pair(:location) - target_host.update_attributes(:location => locs.last, :organization => orgs.last) + test "only return facts from host in admin's currently selected taxonomy" do + user = as_admin { FactoryGirl.create(:user, :admin) } + target_host.update_attributes(:location => @locs.last, :organization => @orgs.last) - as_user user do - in_taxonomy(orgs.first) do - in_taxonomy(locs.first) do - refute_includes FactValue.my_facts, target_host.fact_values.first + as_user user do + in_taxonomy(@orgs.first) do + in_taxonomy(@locs.first) do + refute_includes FactValue.my_facts, target_host.fact_values.first + end end - end - in_taxonomy(orgs.last) do - in_taxonomy(locs.last) do - assert_includes FactValue.my_facts, target_host.fact_values.first + in_taxonomy(@orgs.last) do + in_taxonomy(@locs.last) do + assert_includes FactValue.my_facts, target_host.fact_values.first + end end end end diff --git a/test/unit/helpers/layout_helper_test.rb b/test/unit/helpers/layout_helper_test.rb index cf0658accbe..e54ab03182c 100644 --- a/test/unit/helpers/layout_helper_test.rb +++ b/test/unit/helpers/layout_helper_test.rb @@ -15,12 +15,12 @@ class LayoutHelperTest < ActionView::TestCase end test "is_required?(f, attr) method returns true if attribute is required and false if not required" do - f = ActionView::Helpers::FormBuilder.new(:hostgroup, Hostgroup.new, @hostgroup, {}, {}) + f = ActionView::Helpers::FormBuilder.new(:hostgroup, Hostgroup.new, @hostgroup, {}) assert is_required?(f, :name) assert is_required?(f, :title) refute is_required?(f, :environment_id) refute is_required?(f, :parent_id) - f = ActionView::Helpers::FormBuilder.new(:host, Host::Managed.new, @host, {}, {}) + f = ActionView::Helpers::FormBuilder.new(:host, Host::Managed.new, @host, {}) refute is_required?(f, :architecture_id) # not required because of :if refute is_required?(f, :mac) # not required because of :unless end diff --git a/test/unit/host_test.rb b/test/unit/host_test.rb index 38f5b60ef2b..5efd960f196 100644 --- a/test/unit/host_test.rb +++ b/test/unit/host_test.rb @@ -780,7 +780,7 @@ def teardown test "available_template_kinds finds templates for a PXE host" do os_dt = FactoryGirl.create(:os_default_template, - :template_kind=> TemplateKind.find('finish')) + :template_kind=> TemplateKind.friendly.find('finish')) host = FactoryGirl.create(:host, :operatingsystem => os_dt.operatingsystem) assert_equal [os_dt.provisioning_template], host.available_template_kinds('build') @@ -788,7 +788,7 @@ def teardown test "available_template_kinds finds templates for an image host" do os_dt = FactoryGirl.create(:os_default_template, - :template_kind=> TemplateKind.find('finish')) + :template_kind=> TemplateKind.friendly.find('finish')) host = FactoryGirl.create(:host, :on_compute_resource, :operatingsystem => os_dt.operatingsystem) FactoryGirl.create(:image, :uuid => 'abcde', @@ -802,7 +802,7 @@ def teardown provision_template = @host.provisioning_template({:kind => "provision"}) @host.expects(:load_template_vars) rendered_template = @host.render_template(provision_template) - assert(rendered_template.include?("http://foreman.some.host.fqdn:80/unattended/finish"), "rendred template should parse foreman_url") + assert(rendered_template.include?("http://foreman.some.host.fqdn/unattended/finish"), "rendred template should parse foreman_url") end end @@ -1824,6 +1824,8 @@ def teardown test "test tokens are not created until host is saved" do class Host::Test < Host::Base + attr_accessible :interfaces + def lookup_value_match 'no_match' end @@ -2547,7 +2549,9 @@ def to_managed! test 'should accept non-existing hostgroup' do host = FactoryGirl.build(:host, :managed, :with_hostgroup) - Hostgroup.expects(:find).with(1111).returns(nil) + hostgroup_friendly_scope = stub + hostgroup_friendly_scope.stubs(:find).with(1111).returns(nil) + Hostgroup.stubs(:friendly).returns(hostgroup_friendly_scope) attributes = { 'hostgroup_id' => 1111 } actual_attr = host.apply_inherited_attributes(attributes)