diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..2b941fc --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,18 @@ +inherit_gem: + theforeman-rubocop: + - default.yml + +inherit_mode: + merge: + - Exclude + +AllCops: + Exclude: + - 'vendor/bundle/**/*' + +Metrics/BlockLength: + Exclude: + - test/**/* + +Style/FrozenStringLiteralComment: + Enabled: false diff --git a/Rakefile b/Rakefile index b3a8da5..fe5fb47 100644 --- a/Rakefile +++ b/Rakefile @@ -1,10 +1,6 @@ require 'rake' require 'rake/testtask' - -begin - require 'bundler/gem_tasks' -rescue LoadError -end +require 'bundler/gem_tasks' desc 'Default: run unit tests.' task default: :test diff --git a/lib/smart_proxy_ansible/api.rb b/lib/smart_proxy_ansible/api.rb index b519625..350eed8 100644 --- a/lib/smart_proxy_ansible/api.rb +++ b/lib/smart_proxy_ansible/api.rb @@ -13,23 +13,19 @@ class Api < Sinatra::Base get '/roles/variables' do variables = {} RolesReader.list_roles.each do |role_name| - begin - variables[role_name] = extract_variables(role_name)[role_name] - rescue ReadVariablesException => e - # skip what cannot be parsed - logger.error e - end + variables[role_name] = extract_variables(role_name)[role_name] + rescue ReadVariablesException => e + # skip what cannot be parsed + logger.error e end variables.to_json end get '/roles/:role_name/variables' do |role_name| - begin - extract_variables(role_name).to_json - rescue ReadVariablesException => e - logger.error e - {}.to_json - end + extract_variables(role_name).to_json + rescue ReadVariablesException => e + logger.error e + {}.to_json end private diff --git a/lib/smart_proxy_ansible/exception.rb b/lib/smart_proxy_ansible/exception.rb index 0f9df3c..f33ebf4 100644 --- a/lib/smart_proxy_ansible/exception.rb +++ b/lib/smart_proxy_ansible/exception.rb @@ -6,16 +6,18 @@ module Ansible # exception class Exception < ::StandardError def initialize(message, *params) + super() @message = message @params = params end def self.calculate_error_code(classname, message) return 'ERF00-0000' if classname.nil? || message.nil? + basename = classname.split(':').last class_hash = Zlib.crc32(basename) % 100 msg_hash = Zlib.crc32(message) % 10_000 - format 'ERF%02d-%04d', class_hash, msg_hash + format 'ERF%02d-%04d', clshash: class_hash, msghash: msg_hash end def code @@ -35,7 +37,9 @@ def to_s end class ReadConfigFileException < Proxy::Ansible::Exception; end + class ReadRolesException < Proxy::Ansible::Exception; end + class ReadVariablesException < Proxy::Ansible::Exception; end end end diff --git a/lib/smart_proxy_ansible/http_config.ru b/lib/smart_proxy_ansible/http_config.ru index f4fef03..b876881 100644 --- a/lib/smart_proxy_ansible/http_config.ru +++ b/lib/smart_proxy_ansible/http_config.ru @@ -1,5 +1,5 @@ require 'smart_proxy_ansible/api' -map "/ansible" do +map '/ansible' do run Proxy::Ansible::Api end diff --git a/lib/smart_proxy_ansible/plugin.rb b/lib/smart_proxy_ansible/plugin.rb index 4e9b281..d9c3643 100644 --- a/lib/smart_proxy_ansible/plugin.rb +++ b/lib/smart_proxy_ansible/plugin.rb @@ -3,22 +3,20 @@ module Ansible # Calls for the smart-proxy API to register the plugin class Plugin < Proxy::Plugin http_rackup_path File.expand_path('http_config.ru', - File.expand_path('../', __FILE__)) + File.expand_path(__dir__)) https_rackup_path File.expand_path('http_config.ru', - File.expand_path('../', __FILE__)) + File.expand_path(__dir__)) settings_file 'ansible.yml' plugin :ansible, Proxy::Ansible::VERSION after_activation do - begin - require 'smart_proxy_dynflow_core' - require 'foreman_ansible_core' - ForemanAnsibleCore.initialize_settings(Proxy::Ansible::Plugin.settings.to_h) - rescue LoadError => _ - # Dynflow core is not available in the proxy, will be handled - # by standalone Dynflow core - end + require 'smart_proxy_dynflow_core' + require 'foreman_ansible_core' + ForemanAnsibleCore.initialize_settings(Proxy::Ansible::Plugin.settings.to_h) + rescue LoadError => _e + # Dynflow core is not available in the proxy, will be handled + # by standalone Dynflow core end end end diff --git a/lib/smart_proxy_ansible/roles_reader.rb b/lib/smart_proxy_ansible/roles_reader.rb index dd406f3..8edd530 100644 --- a/lib/smart_proxy_ansible/roles_reader.rb +++ b/lib/smart_proxy_ansible/roles_reader.rb @@ -15,9 +15,11 @@ def list_roles def roles_path(roles_line = roles_path_from_config) # Default to /etc/ansible/roles if none found return DEFAULT_ROLES_PATH if roles_line.empty? + roles_path_key = roles_line.first.split('=').first.strip # In case of commented roles_path key "#roles_path", return default return DEFAULT_ROLES_PATH unless roles_path_key == 'roles_path' + roles_line.first.split('=').last.strip end @@ -34,8 +36,7 @@ def logger private def read_roles(roles_path) - rescue_and_raise_file_exception ReadRolesException, - roles_path, 'roles' do + rescue_and_raise_file_exception(ReadRolesException, roles_path, 'roles') do Dir.glob("#{roles_path}/*").map do |path| path.split('/').last end @@ -44,7 +45,7 @@ def read_roles(roles_path) def roles_path_from_config rescue_and_raise_file_exception ReadConfigFileException, - DEFAULT_CONFIG_FILE, 'config file' do + DEFAULT_CONFIG_FILE, 'config file' do File.readlines(DEFAULT_CONFIG_FILE).select do |line| line =~ /^\s*roles_path/ end diff --git a/lib/smart_proxy_ansible/variables_extractor.rb b/lib/smart_proxy_ansible/variables_extractor.rb index 8ba375b..164932e 100644 --- a/lib/smart_proxy_ansible/variables_extractor.rb +++ b/lib/smart_proxy_ansible/variables_extractor.rb @@ -9,16 +9,19 @@ def extract_variables(role_path) role_files = Dir.glob("#{role_path}/defaults/**/*.yml") + Dir.glob("#{role_path}/defaults/**/*.yaml") role_files.reduce({}) do |memo, role_file| - loaded_yaml = {} - begin - loaded_yaml = YAML.load_file(role_file) - rescue Psych::SyntaxError - raise ReadVariablesException.new "#{role_file} is not YAML file" - end - raise ReadVariablesException.new "Could not parse YAML file: #{role_file}" unless loaded_yaml.is_a? Hash + loaded_yaml = load_role_file(role_file) + memo.merge loaded_yaml end end + + def load_role_file(file) + loaded_yaml = YAML.load_file(file) + raise ReadVariablesException, "Could not parse YAML file: #{file}" unless loaded_yaml.is_a? Hash + loaded_yaml + rescue Psych::SyntaxError + raise ReadVariablesException, "#{file} is not YAML file" + end end end end diff --git a/lib/smart_proxy_ansible/version.rb b/lib/smart_proxy_ansible/version.rb index b029d62..3fc51e5 100644 --- a/lib/smart_proxy_ansible/version.rb +++ b/lib/smart_proxy_ansible/version.rb @@ -2,6 +2,6 @@ module Proxy # Version, this allows the proxy and other plugins know # what version of the Ansible plugin is running module Ansible - VERSION = '3.0.1' + VERSION = '3.0.1'.freeze end end diff --git a/smart_proxy_ansible.gemspec b/smart_proxy_ansible.gemspec index 35b9a85..451947c 100644 --- a/smart_proxy_ansible.gemspec +++ b/smart_proxy_ansible.gemspec @@ -1,5 +1,4 @@ -# -*- encoding: utf-8 -*- -lib = File.expand_path('../lib', __FILE__) +lib = File.expand_path('lib', __dir__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'smart_proxy_ansible/version' @@ -10,26 +9,27 @@ Gem::Specification.new do |gem| gem.email = ['inecas@redhat.com', 'dlobatog@redhat.com'] gem.homepage = 'https://github.com/theforeman/smart_proxy_ansible' gem.summary = 'Smart-Proxy Ansible plugin' - gem.description = <<-EOS + gem.description = <<-DESCRIPTION Smart-Proxy ansible plugin - EOS + DESCRIPTION gem.files = Dir['bundler.d/ansible.rb', - 'settings.d/**/*', - 'LICENSE', 'README.md', 'bin/json_inventory.sh', - 'lib/smart_proxy_ansible.rb', - 'lib/smart_proxy_ansible/**/*'] + 'settings.d/**/*', + 'LICENSE', 'README.md', 'bin/json_inventory.sh', + 'lib/smart_proxy_ansible.rb', + 'lib/smart_proxy_ansible/**/*'] gem.extra_rdoc_files = ['README.md', 'LICENSE'] gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) gem.require_paths = ['lib'] gem.license = 'GPL-3.0' gem.required_ruby_version = '>= 2.5' - gem.add_development_dependency 'rake', '~> 13.0' + + gem.add_development_dependency('logger') gem.add_development_dependency('minitest', '~> 0') gem.add_development_dependency('mocha', '~> 1') - gem.add_development_dependency('webmock', '~> 3') gem.add_development_dependency('rack-test', '~> 0') - gem.add_development_dependency('logger') + gem.add_development_dependency('rake', '~> 13.0') + gem.add_development_dependency('webmock', '~> 3') gem.add_runtime_dependency('smart_proxy_dynflow', '~> 0.1') end diff --git a/test/roles_reader_test.rb b/test/roles_reader_test.rb index 025d798..3866890 100644 --- a/test/roles_reader_test.rb +++ b/test/roles_reader_test.rb @@ -11,35 +11,35 @@ class RolesReaderTest < Minitest::Test def self.expect_content_config(ansible_cfg_content) Proxy::Ansible::RolesReader.expects(:roles_path_from_config) - .returns(ansible_cfg_content) + .returns(ansible_cfg_content) end describe '#roles_path' do test 'detects commented roles_path' do RolesReaderTest.expect_content_config ['#roles_path = thisiscommented!'] assert_equal(ROLES_PATH, - Proxy::Ansible::RolesReader.roles_path) + Proxy::Ansible::RolesReader.roles_path) end test 'returns default path if no roles_path defined' do RolesReaderTest.expect_content_config ['norolepath!'] assert_equal(ROLES_PATH, - Proxy::Ansible::RolesReader.roles_path) + Proxy::Ansible::RolesReader.roles_path) end test 'returns roles_path if one is defined' do RolesReaderTest.expect_content_config [ - 'roles_path = /mycustom/ansibleroles/path' + 'roles_path = /mycustom/ansibleroles/path', ] assert_equal('/mycustom/ansibleroles/path', - Proxy::Ansible::RolesReader.roles_path) + Proxy::Ansible::RolesReader.roles_path) end end describe '#list_roles' do test 'reads roles from paths' do RolesReaderTest.expect_content_config ["roles_path = #{ROLES_PATH}"] - ROLES_PATH.split(":").map do |path| + ROLES_PATH.split(':').map do |path| Proxy::Ansible::RolesReader.expects(:read_roles).with(path) end Proxy::Ansible::RolesReader.list_roles @@ -51,7 +51,7 @@ def self.expect_content_config(ansible_cfg_content) Proxy::Ansible::RolesReader.expects(:read_roles).with(path) end RolesReaderTest.expect_content_config [ - "roles_path = #{roles_paths.join(':')}" + "roles_path = #{roles_paths.join(':')}", ] Proxy::Ansible::RolesReader.list_roles end diff --git a/test/test_helper.rb b/test/test_helper.rb index 020e218..b5fb29d 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -10,7 +10,8 @@ class << self def test(name, &block) test_name = "test_#{name.gsub(/\s+/, '_')}".to_sym defined = method_defined? test_name - fail "#{test_name} is already defined in #{self}" if defined + raise "#{test_name} is already defined in #{self}" if defined + if block_given? define_method(test_name, &block) else diff --git a/test/variables_extractor_test.rb b/test/variables_extractor_test.rb index e07b6f5..baae62a 100644 --- a/test/variables_extractor_test.rb +++ b/test/variables_extractor_test.rb @@ -9,7 +9,7 @@ class VariablesExtractorTest < Minitest::Test assert_equal Hash, res.class assert_equal 13, res.count - assert_equal "postgres", res["postgresql_user"] + assert_equal 'postgres', res['postgresql_user'] end test 'raises when fails to parse' do