Skip to content

Commit

Permalink
Merge pull request #19228 from jvlcek/miq_config_sssd_bz1745775
Browse files Browse the repository at this point in the history
 Add support to automate external auth config for ldap
  • Loading branch information
abellotti authored Oct 30, 2019
2 parents 4d3d171 + 4efc07e commit eb7b294
Show file tree
Hide file tree
Showing 30 changed files with 536 additions and 188 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
$LOAD_PATH << Rails.root.join("tools").to_s

require "miqldap_to_sssd"
require "miq_config_sssd_ldap"

describe MiqLdapToSssd::AuthEstablish do
describe MiqConfigSssdLdap::AuthEstablish do
describe '#run_auth_establish' do
before do
@initial_settings = {:mode => "bob", :ldaphost => ["hostname"], :ldapport => 22}
Expand All @@ -22,10 +22,10 @@
end

it 'handles authconfig failures' do
expect(MiqLdapToSssd::LOGGER).to receive(:fatal)
expect(MiqConfigSssdLdap::LOGGER).to receive(:fatal)
expect(AwesomeSpawn).to receive(:run)
.and_return(double(:command_line => "authselect", :failure? => true, :error => "malfunction"))
expect { @auth_establish.run_auth_establish }.to raise_error(MiqLdapToSssd::AuthEstablishError)
expect { @auth_establish.run_auth_establish }.to raise_error(MiqConfigSssdLdap::AuthEstablishError)
end
end

Expand Down Expand Up @@ -53,10 +53,10 @@
end

it 'handles authconfig failures' do
expect(MiqLdapToSssd::LOGGER).to receive(:fatal)
expect(MiqConfigSssdLdap::LOGGER).to receive(:fatal)
expect(AwesomeSpawn).to receive(:run)
.and_return(double(:command_line => "authconfig", :failure? => true, :error => "malfunction"))
expect { @auth_establish.run_auth_establish }.to raise_error(MiqLdapToSssd::AuthEstablishError)
expect { @auth_establish.run_auth_establish }.to raise_error(MiqConfigSssdLdap::AuthEstablishError)
end
end
end
Expand Down
124 changes: 124 additions & 0 deletions spec/tools/miq_config_sssd_ldap/cli_config_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
$LOAD_PATH << Rails.root.join("tools").to_s

require "miq_config_sssd_ldap/cli_config"

describe MiqConfigSssdLdap::CliConfig do
before do
@all_opts = :tls_cacert, :tls_cacertdir, :domain, :ldaphost, :ldapport, :user_type, :user_suffix, :mode,
:bind_dn, :bind_pwd, :only_change_userids, :skip_post_conversion_userid_change
@all_required_opts = %w[-H ldaphost -T dn-cn -S user_suffix -M ldap -d example.com -b cn=Manager,dc=example,dc=com -p password]
allow(TCPSocket).to receive(:new).and_return(double(:close => nil))

stub_const("LOGGER", double)
allow(LOGGER).to receive(:debug)
end

describe "#parse" do
it "should assign defaults" do
opts = described_class.new.parse(@all_required_opts).opts.slice(*@all_opts)
expect(opts).to include(:ldapport => 389, :skip_post_conversion_userid_change => false)
end

it "should assign all required options when mode is ldap" do
opts = described_class.new.parse(@all_required_opts).opts.slice(*@all_opts)
expect(opts).to eq(:bind_dn => "cn=Manager,dc=example,dc=com",
:bind_pwd => "password",
:domain => "example.com",
:ldaphost => ["ldaphost"],
:ldapport => 389,
:mode => "ldap",
:only_change_userids => false,
:skip_post_conversion_userid_change => false,
:user_suffix => "user_suffix",
:user_type => "dn-cn")
end

it "should assign default non-secure ldapport" do
opts = described_class.new.parse(@all_required_opts).opts.slice(:ldapport)
expect(opts).to eq(:ldapport => 389)
end

it "should assign default secure ldapport" do
opts = described_class.new.parse(@all_required_opts - %w[-M ldap] + %w[-M ldaps]).opts.slice(:ldapport)
expect(opts).to eq(:ldapport => 636)
end

it "should parse ldaphost" do
opts = described_class.new.parse(@all_required_opts).opts.slice(:ldaphost)
expect(opts).to eq(:ldaphost => ["ldaphost"])
end

it "should parse ldapport" do
opts = described_class.new.parse(@all_required_opts + %w[-P 8675309]).opts.slice(:ldapport)
expect(opts).to eq(:ldapport => "8675309")
end

it "should parse user_type" do
opts = described_class.new.parse(@all_required_opts).opts.slice(:user_type)
expect(opts).to eq(:user_type => "dn-cn")
end

it "should parse user_suffix" do
opts = described_class.new.parse(@all_required_opts).opts.slice(:user_suffix)
expect(opts).to eq(:user_suffix => "user_suffix")
end

it "should parse mode" do
opts = described_class.new.parse(@all_required_opts).opts.slice(:mode)
expect(opts).to eq(:mode => "ldap")
end

it "should parse base DN domain names" do
opts = described_class.new.parse(@all_required_opts).opts.slice(:domain)
expect(opts).to eq(:domain => "example.com")
end

it "should parse bind DN" do
opts = described_class.new.parse(@all_required_opts).opts.slice(:bind_dn)
expect(opts).to eq(:bind_dn => "cn=Manager,dc=example,dc=com")
end

it "should parse bind pwd" do
opts = described_class.new.parse(@all_required_opts).opts.slice(:bind_pwd)
expect(opts).to eq(:bind_pwd => "password")
end

it "should parse TLS cacert path and directory" do
opts = described_class.new.parse(@all_required_opts + %w[-c /a/path/to/a/cacert]).opts.slice(:tls_cacert, :tls_cacertdir)
expect(opts).to eq(:tls_cacert => "/a/path/to/a/cacert", :tls_cacertdir => "/a/path/to/a")
end

it "can skip updating the userids after the conversion" do
opts = described_class.new.parse(@all_required_opts + %w[-s]).opts.slice(*@all_opts)
expect(opts).to include(:skip_post_conversion_userid_change => true)
end

context "When mode is ldap" do
it "requires bind_dn" do
expect(Optimist).to receive(:die)
described_class.new.parse(@all_required_opts - %w[-b cn=Manager,dc=example,dc=com])
end

it "requires bind_pwd" do
expect(Optimist).to receive(:die)
described_class.new.parse(@all_required_opts - %w[-p password])
end
end

context "When ldap_role is true" do
before do
@ldap_role_ldaps_opts = @all_required_opts - %w[-M ldap] + %w[-M ldaps -g]
end

it "requires bind_dn" do
expect(Optimist).to receive(:die)
described_class.new.parse(@ldap_role_ldaps_opts - %w[-b cn=Manager,dc=example,dc=com])
end

it "requires bind_pwd" do
expect(Optimist).to receive(:die)
described_class.new.parse(@ldap_role_ldaps_opts - %w[-p password])
end
end
end
end
Original file line number Diff line number Diff line change
@@ -1,47 +1,47 @@
$LOAD_PATH << Rails.root.join("tools").to_s

require "miqldap_to_sssd/cli"
require "miq_config_sssd_ldap/cli_convert"

describe MiqLdapToSssd::Cli do
describe MiqConfigSssdLdap::CliConvert do
before do
@all_options = :tls_cacert, :tls_cacertdir, :domain, :only_change_userids, :skip_post_conversion_userid_change
@all_opts = :tls_cacert, :tls_cacertdir, :domain, :only_change_userids, :skip_post_conversion_userid_change
stub_const("LOGGER", double)
allow(LOGGER).to receive(:debug)
end

describe "#parse" do
it "should assign defaults" do
opts = described_class.new.parse([]).options.slice(*@all_options)
opts = described_class.new.parse([]).opts.slice(*@all_opts)
expect(opts).to eq(:only_change_userids => false, :skip_post_conversion_userid_change => false)
end

it "should parse base DN domain names" do
opts = described_class.new.parse(%w(-d example.com)).options.slice(:domain)
opts = described_class.new.parse(%w[-d example.com]).opts.slice(:domain)
expect(opts).to eq(:domain => "example.com")
end

it "should parse bind DN" do
opts = described_class.new.parse(%w(-b cn=Manager,dc=example,dc=com)).options.slice(:bind_dn)
opts = described_class.new.parse(%w[-b cn=Manager,dc=example,dc=com]).opts.slice(:bind_dn)
expect(opts).to eq(:bind_dn => "cn=Manager,dc=example,dc=com")
end

it "should parse bind pwd" do
opts = described_class.new.parse(%w(-p password)).options.slice(:bind_pwd)
opts = described_class.new.parse(%w[-p password]).opts.slice(:bind_pwd)
expect(opts).to eq(:bind_pwd => "password")
end

it "should parse TLS cacert path and directory" do
opts = described_class.new.parse(%w(-c /a/path/to/a/cacert)).options.slice(:tls_cacert, :tls_cacertdir)
opts = described_class.new.parse(%w[-c /a/path/to/a/cacert]).opts.slice(:tls_cacert, :tls_cacertdir)
expect(opts).to eq(:tls_cacert => "/a/path/to/a/cacert", :tls_cacertdir => "/a/path/to/a")
end

it "can only updating the userids" do
opts = described_class.new.parse(%w(-n)).options.slice(*@all_options)
opts = described_class.new.parse(%w[-n]).opts.slice(*@all_opts)
expect(opts).to eq(:only_change_userids => true, :skip_post_conversion_userid_change => false)
end

it "can skip updating the userids after the conversion" do
opts = described_class.new.parse(%w(-s)).options.slice(*@all_options)
opts = described_class.new.parse(%w[-s]).opts.slice(*@all_opts)
expect(opts).to eq(:only_change_userids => false, :skip_post_conversion_userid_change => true)
end
end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
$LOAD_PATH << Rails.root.join("tools").to_s

require "miqldap_to_sssd"
require "miq_config_sssd_ldap"
require "tempfile"
require "fileutils"
require 'auth_template_files'

describe MiqLdapToSssd::ConfigureApache do
describe MiqConfigSssdLdap::ConfigureApache do
before do
@spec_name = File.basename(__FILE__).split(".rb").first.freeze
end
Expand Down Expand Up @@ -53,17 +53,17 @@

@test_dir = "#{Dir.tmpdir}/#{@spec_name}"
@template_dir = "#{@test_dir}/TEMPLATE"
stub_const("MiqLdapToSssd::AuthTemplateFiles::TEMPLATE_DIR", @template_dir)
stub_const("MiqConfigSssdLdap::AuthTemplateFiles::TEMPLATE_DIR", @template_dir)

@httpd_conf_dir = "#{@test_dir}/etc/httpd/conf.d"
FileUtils.mkdir_p @httpd_conf_dir
@httpd_template_dir = FileUtils.mkdir_p("#{@template_dir}/#{@httpd_conf_dir}")[0]
stub_const("MiqLdapToSssd::AuthTemplateFiles::HTTPD_CONF_DIR", @httpd_conf_dir)
stub_const("MiqConfigSssdLdap::AuthTemplateFiles::HTTPD_CONF_DIR", @httpd_conf_dir)

@pam_conf_dir = "#{@test_dir}/etc/pam.d"
FileUtils.mkdir_p @pam_conf_dir
@pam_template_dir = FileUtils.mkdir_p("#{@template_dir}/#{@pam_conf_dir}")[0]
stub_const("MiqLdapToSssd::AuthTemplateFiles::PAM_CONF_DIR", @pam_conf_dir)
stub_const("MiqConfigSssdLdap::AuthTemplateFiles::PAM_CONF_DIR", @pam_conf_dir)

File.open("#{@pam_template_dir}/httpd-auth", "w") { |f| f.write(manageiq_pam_conf) }
File.open("#{@httpd_template_dir}/manageiq-remote-user.conf", "w") { |f| f.write(manageiq_remote_user_conf) }
Expand Down Expand Up @@ -94,8 +94,8 @@

it 'raises an error when a TEMPLATE file is missing' do
FileUtils.rm_f("#{@pam_template_dir}/httpd-auth")
expect(MiqLdapToSssd::LOGGER).to receive(:fatal)
expect { described_class.new(@initial_settings).configure }.to raise_error(MiqLdapToSssd::ConfigureApacheError)
expect(MiqConfigSssdLdap::LOGGER).to receive(:fatal)
expect { described_class.new(@initial_settings).configure }.to raise_error(MiqConfigSssdLdap::ConfigureApacheError)
end
end
end
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
$LOAD_PATH << Rails.root.join("tools", "miqldap_to_sssd").to_s
$LOAD_PATH << Rails.root.join("tools", "miq_config_sssd_ldap").to_s

require "configure_appliance_settings"

describe MiqLdapToSssd::ConfigureApplianceSettings do
describe MiqConfigSssdLdap::ConfigureApplianceSettings do
before do
stub_const("LOGGER", double)
allow(LOGGER).to receive(:debug)
Expand All @@ -28,12 +28,28 @@
Vmdb::Settings.save!(miq_server, @auth_config)
Settings.reload!

described_class.new.configure
described_class.new(:ldap_role => nil).configure

settings = miq_server.settings
expect(settings.fetch_path(:authentication, :mode)).to eq("httpd")
expect(settings.fetch_path(:authentication, :ldap_role)).to eq(false)
expect(settings.fetch_path(:authentication, :httpd_role)).to eq(true)
end

it 'sets httpd_role to ldap_role if ldap_role is specified' do
# Needed to avoid pitfalls of not running on a live appliance with real settings
allow_any_instance_of(Vmdb::Settings).to receive(:activate)
allow_any_instance_of(ConfigurationManagementMixin).to receive(:reload_all_server_settings)

Vmdb::Settings.save!(miq_server, @auth_config)
Settings.reload!

described_class.new(:ldap_role => false).configure

settings = miq_server.settings
expect(settings.fetch_path(:authentication, :mode)).to eq("httpd")
expect(settings.fetch_path(:authentication, :ldap_role)).to eq(false)
expect(settings.fetch_path(:authentication, :httpd_role)).to eq(false)
end
end
end
45 changes: 45 additions & 0 deletions spec/tools/miq_config_sssd_ldap/configure_selinux_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
$LOAD_PATH << Rails.root.join("tools").to_s

require "miq_config_sssd_ldap"

describe MiqConfigSssdLdap::ConfigureSELinux do
describe '#configure' do
before do
@initial_settings = {:ldapport => '22'}
@success = double(:command_line => "semanage", :failure? => false)
@semanage_params = {nil => "port", :a => nil, :t => "ldap_port_t", :p => %w[tcp 22]}
@failure1 = double(:command_line => "semanage", :failure? => true, :error => "malfunction already defined")
@failure2 = double(:command_line => "semanage", :failure? => true, :error => "malfunction")
end

it 'invokes semanage and setsebool with valid parameters' do
expect(AwesomeSpawn).to receive(:run).once.with("semanage", :params => @semanage_params).and_return(@success)
expect(AwesomeSpawn).to receive(:run).once.with("setsebool", :params => {:P=>%w[allow_httpd_mod_auth_pam on]}).and_return(@success)
expect(AwesomeSpawn).to receive(:run).once.with("setsebool", :params => {:P=>%w[httpd_dbus_sssd on]}).and_return(@success)
expect { described_class.new(@initial_settings).configure }.to_not raise_error
end

it 'handles semanage already defined result' do
expect(MiqConfigSssdLdap::LOGGER).to_not receive(:fatal)
expect(AwesomeSpawn).to receive(:run).once.and_return(@failure1)
expect(AwesomeSpawn).to receive(:run).once.with("setsebool", :params => {:P=>%w[allow_httpd_mod_auth_pam on]}).and_return(@success)
expect(AwesomeSpawn).to receive(:run).once.with("setsebool", :params => {:P=>%w[httpd_dbus_sssd on]}).and_return(@success)
expect { described_class.new(@initial_settings).configure }.to_not raise_error
end

it 'handles semanage failures' do
expect(MiqConfigSssdLdap::LOGGER).to receive(:fatal).with("semanage failed with: malfunction")
expect(AwesomeSpawn).to receive(:run).and_return(@failure2)
expect { described_class.new(@initial_settings).configure }.to raise_error(MiqConfigSssdLdap::ConfigureSELinuxError)
end

it 'handles setsebool failures' do
expect(MiqConfigSssdLdap::LOGGER).to receive(:fatal).with("setsebool failed with: malfunction")
expect(AwesomeSpawn).to receive(:run).once.with("semanage", :params => @semanage_params).and_return(@success)

expect(AwesomeSpawn).to receive(:run)
.and_return(double(:command_line => "setsebool", :failure? => true, :error => "malfunction"))
expect { described_class.new(@initial_settings).configure }.to raise_error(MiqConfigSssdLdap::ConfigureSELinuxError)
end
end
end
34 changes: 34 additions & 0 deletions spec/tools/miq_config_sssd_ldap/configure_sssd_rules_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
$LOAD_PATH << Rails.root.join("tools").to_s

require "miq_config_sssd_ldap"
require "tempfile"
require "fileutils"
require 'auth_template_files'

describe MiqConfigSssdLdap::ConfigureSssdRules do
before do
@spec_name = File.basename(__FILE__).split(".rb").first.freeze
end

describe '#disable_tls' do
let(:disable_tls_conf) do
<<-CFG_RULES_CONF.strip_heredoc
option = ldap_auth_disable_tls_never_use_in_production
CFG_RULES_CONF
end

before do
@test_dir = "#{Dir.tmpdir}/#{@spec_name}"
stub_const("MiqConfigSssdLdap::ConfigureSssdRules::CFG_RULES_FILE", @test_dir)
end

after do
FileUtils.rm_rf(@test_dir)
end

it 'appends the disable tls option to the sssd config file' do
described_class.disable_tls
expect(File.read(@test_dir)).to eq(disable_tls_conf)
end
end
end
Loading

0 comments on commit eb7b294

Please sign in to comment.