From 4cabfa52e0652329d91ebd5c7f5c48c356c20114 Mon Sep 17 00:00:00 2001 From: Riley Shott Date: Mon, 30 Nov 2015 11:53:16 -0800 Subject: [PATCH 1/4] Added support for choosing selinux state Using the selinux state attribute (from the selinux cookbook) to specify what state selinux should be in. Also changed the default state to 'permissive'. Addresses #242. --- attributes/default.rb | 6 ++++++ recipes/default.rb | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/attributes/default.rb b/attributes/default.rb index 151615c7..3c3fd834 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -51,3 +51,9 @@ '0.5.2_windows_386' => '2e866812de16f1a6138a0fd1eebc76143f1314826e3b52597a55ac510ae94be6', '0.5.2_web_ui' => 'ad883aa52e1c0136ab1492bbcedad1210235f26d59719fb6de3ef6464f1ff3b1' } + +### +# selinux +### + +default['selinux']['state'] = 'permissive' \ No newline at end of file diff --git a/recipes/default.rb b/recipes/default.rb index 6c5f5914..9f6cdd9b 100644 --- a/recipes/default.rb +++ b/recipes/default.rb @@ -4,7 +4,7 @@ # # Copyright 2014, 2015 Bloomberg Finance L.P. # -include_recipe 'selinux::disabled' if node['os'] == 'linux' +include_recipe 'selinux::default' if node['os'] == 'linux' if node['firewall']['allow_consul'] include_recipe 'firewall::default' From 6a5bcdc5a2843b7b8e5d773200c7324638567d79 Mon Sep 17 00:00:00 2001 From: Riley Shott Date: Mon, 30 Nov 2015 11:55:11 -0800 Subject: [PATCH 2/4] Added spec tests for default recipe & selinux state --- test/spec/recipes/default_spec.rb | 55 +++++++++++++ test/spec/spec_helper.rb | 1 + .../automatic_resource_matcher.rb | 77 +++++++++++++++++++ 3 files changed, 133 insertions(+) create mode 100644 test/spec/recipes/default_spec.rb create mode 100644 test/spec/support/chefspec_extensions/automatic_resource_matcher.rb diff --git a/test/spec/recipes/default_spec.rb b/test/spec/recipes/default_spec.rb new file mode 100644 index 00000000..12f0c5be --- /dev/null +++ b/test/spec/recipes/default_spec.rb @@ -0,0 +1,55 @@ +require 'spec_helper' + +describe 'consul::default' do + context 'When all attributes are default, on an unspecified platform' do + let(:chef_run) do + ChefSpec::SoloRunner.new.converge(described_recipe) + end + + it 'converges successfully' do + chef_run # This should not raise an error + end + end + + context 'When selinux is set to be permissive, on a RHEL distribution' do + let(:chef_run) do + ChefSpec::SoloRunner.new do |node, server| + node.automatic['os'] = 'linux' + node.automatic['platform_family'] = 'rhel' + node.set['selinux']['state'] = 'permissive' + end.converge(described_recipe) + end + + it 'selinux_state action is permissive' do + expect(chef_run).to permissive_selinux_state('SELinux Permissive') + end + end + + context 'When selinux is set to be disabled, on a RHEL distribution' do + let(:chef_run) do + ChefSpec::SoloRunner.new do |node, server| + node.automatic['os'] = 'linux' + node.automatic['platform_family'] = 'rhel' + node.set['selinux']['state'] = 'disabled' + end.converge(described_recipe) + end + + it 'selinux_state action is disabled' do + expect(chef_run).to disabled_selinux_state('SELinux Disabled') + end + end + + context 'When selinux is set to be enforcing, on a RHEL distribution' do + let(:chef_run) do + ChefSpec::SoloRunner.new do |node, server| + node.automatic['os'] = 'linux' + node.automatic['platform_family'] = 'rhel' + node.set['selinux']['state'] = 'enforcing' + end.converge(described_recipe) + end + + it 'selinux_state action is enforcing' do + expect(chef_run).to enforcing_selinux_state('SELinux Enforcing') + end + end +end diff --git a/test/spec/spec_helper.rb b/test/spec/spec_helper.rb index 92092e0f..a03b087e 100644 --- a/test/spec/spec_helper.rb +++ b/test/spec/spec_helper.rb @@ -1,3 +1,4 @@ require 'chefspec' require 'chefspec/berkshelf' require 'poise_boiler/spec_helper' +require_relative('support/chefspec_extensions/automatic_resource_matcher') diff --git a/test/spec/support/chefspec_extensions/automatic_resource_matcher.rb b/test/spec/support/chefspec_extensions/automatic_resource_matcher.rb new file mode 100644 index 00000000..788af65d --- /dev/null +++ b/test/spec/support/chefspec_extensions/automatic_resource_matcher.rb @@ -0,0 +1,77 @@ +# Modified for styling +module ChefSpec + # https://github.com/lynx44/chefspec_extensions + module AutomaticResourceMatcher + def method_missing(meth, *args, &block) + method_name = meth.to_s + if resource_matcher_candidate?(method_name, args) + cookbook_candidates = get_cookbook_candidates(method_name) + cookbook_matches = find_cookbooks_with_matching_resources(cookbook_candidates, method_name) + if cookbook_matches.length == 1 + cookbook = cookbook_matches.first + return create_matcher(args, cookbook[:name], method_name) + end + end + super + end + + private + + def resource_matcher_candidate?(method_name, args) + method_name.count('_') >= 1 && args.length == 1 + end + + def cookbooks + @@cookbooks ||= + cookbook_paths + .map { |cookbook_path| Dir.glob("#{cookbook_path}/*") } + .flatten + .select { |c| File.directory? c } + .map { |c| { name: Pathname.new(c).basename.to_s, path: c } } + .flatten + end + + def cookbook_paths + Chef::Config[:cookbook_path].is_a?(Array) ? Chef::Config[:cookbook_path] : [Chef::Config[:cookbook_path]] + end + + def get_cookbook_candidates(method_name) + cookbooks.select { |c| method_name.include? c[:name] } + end + + def parse_lwrp(cookbook, method_name) + if (method_name.count('_') == 1) + method_name = "#{method_name}_default" + end + + parts = method_name.split("_#{cookbook}_") + { action: parts[0], cookbook: cookbook, resource_name: parts[1] } + end + + def find_cookbooks_with_matching_resources(cookbook_candidates, method_name) + cookbook_matches = [] + cookbook_candidates.each do |cookbook| + resource_parts = parse_lwrp(cookbook[:name], method_name) + cookbook_matches.push(cookbook) if cookbook_has_resource?(cookbook, resource_parts[:resource_name]) + end + cookbook_matches + end + + def cookbook_has_resource?(cookbook, resource_name) + Dir.glob("#{cookbook[:path]}/resources/#{resource_name}.rb").length == 1 + end + + def create_matcher(args, cookbook, method_name) + resource_definition = parse_lwrp(cookbook, method_name) + resource_name = "#{cookbook}_#{resource_definition[:resource_name]}" + if (resource_definition[:resource_name] == 'default') + resource_name = cookbook + end + ChefSpec::Matchers::ResourceMatcher.new(resource_name.to_sym, resource_definition[:action].to_sym, args[0]) + end + end +end + +RSpec.configure do |c| + c.include ChefSpec::AutomaticResourceMatcher +end From 72c25d3a7bf384e0df76c366464e1657a8eb6162 Mon Sep 17 00:00:00 2001 From: Riley Shott Date: Mon, 30 Nov 2015 12:03:00 -0800 Subject: [PATCH 3/4] Added newline for rubocop --- attributes/default.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/attributes/default.rb b/attributes/default.rb index 3c3fd834..4bd4c479 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -56,4 +56,4 @@ # selinux ### -default['selinux']['state'] = 'permissive' \ No newline at end of file +default['selinux']['state'] = 'permissive' From 383824969f4136eb34d003dac1a444b41e5713d7 Mon Sep 17 00:00:00 2001 From: Riley Shott Date: Wed, 2 Dec 2015 18:01:40 -0800 Subject: [PATCH 4/4] Setting selinux state attribute in default.rb --- attributes/default.rb | 6 ------ recipes/default.rb | 6 +++++- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/attributes/default.rb b/attributes/default.rb index 4bd4c479..151615c7 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -51,9 +51,3 @@ '0.5.2_windows_386' => '2e866812de16f1a6138a0fd1eebc76143f1314826e3b52597a55ac510ae94be6', '0.5.2_web_ui' => 'ad883aa52e1c0136ab1492bbcedad1210235f26d59719fb6de3ef6464f1ff3b1' } - -### -# selinux -### - -default['selinux']['state'] = 'permissive' diff --git a/recipes/default.rb b/recipes/default.rb index 9f6cdd9b..158327d9 100644 --- a/recipes/default.rb +++ b/recipes/default.rb @@ -4,7 +4,11 @@ # # Copyright 2014, 2015 Bloomberg Finance L.P. # -include_recipe 'selinux::default' if node['os'] == 'linux' + +if node['os'] == 'linux' + node.default['selinux']['state'] = 'permissive' + include_recipe 'selinux::default' +end if node['firewall']['allow_consul'] include_recipe 'firewall::default'