Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #28436 - Add keycloak support #779

Merged
merged 1 commit into from
Feb 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions manifests/config.pp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@
passenger_start_timeout => $::foreman::passenger_start_timeout,
foreman_url => $::foreman::foreman_url,
ipa_authentication => $::foreman::ipa_authentication,
keycloak => $::foreman::keycloak,
keycloak_app_name => $::foreman::keycloak_app_name,
keycloak_realm => $::foreman::keycloak_realm,
}

contain foreman::config::apache
Expand Down
28 changes: 28 additions & 0 deletions manifests/config/apache.pp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@
Boolean $ipa_authentication = false,
Hash[String, Any] $http_vhost_options = {},
Hash[String, Any] $https_vhost_options = {},
Boolean $keycloak = false,
String[1] $keycloak_app_name = 'foreman-openidc',
String[1] $keycloak_realm = 'ssl-realm',
) {
$docroot = "${app_root}/public"

Expand Down Expand Up @@ -226,6 +229,31 @@
include ::apache::mod::intercept_form_submit
include ::apache::mod::lookup_identity
include ::apache::mod::auth_kerb
} elsif $keycloak {
# TODO: https://github.com/puppetlabs/puppetlabs-apache/commit/9f7f38ff21036c9a1ce4d669ccaea816941209ca
# adds apache::mod::auth_openidc which allows for proper integration but
# the current release (5.4.0) doesn't include this yet.
include ::apache::mod::authz_user
apache::mod { 'auth_openidc':
package => 'mod_auth_openidc',
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also install keycloak-httpd-client-install package too?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was debating that, but decided against it. I think the instruction should be:

  • yum install keycloak-httpd-client-install
  • keycloak-httpd-client-install ....
  • foreman-installer --foreman-keycloak true --foreman-keycloak-realm ...

In theory the installer could run the install command, but then we need to pass credentials and I think that's something we probably don't want.


# This file is generated by keycloak-httpd-client-install and that manages
# the content. The command would be:
#
# keycloak-httpd-client-install --app-name ${keycloak_app_name} --keycloak-server-url $KEYCLOAK_URL --keycloak-admin-username $KEYCLOAK_USER --keycloak-realm ${keycloak_realm} --keycloak-admin-realm master --keycloak-auth-role root-admin --client-type openidc --client-hostname ${servername} --protected-locations /users/extlogin
#
# If $suburi is used, --location-root should also be passed in
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what $suburi is and where/how it can we used. Can you share some insights?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how much it's used, but if foreman_url is passed in as https://foreman.example.com/foreman then $suburi will be set. Probably ok to ignore it for now.

#
# By defining it here we avoid purging it and also tighten the
# permissions so the world can't read its secrets.
# This is functionally equivalent to apache::custom_config without content/source
file { "${apache::confd_dir}/${keycloak_app_name}_oidc_keycloak_${keycloak_realm}.conf":
ensure => file,
owner => 'root',
group => 'root',
mode => '0640',
}
}

file { "${apache::confd_dir}/${priority}-foreman.d":
Expand Down
18 changes: 18 additions & 0 deletions manifests/init.pp
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,16 @@
#
# $foreman_service_puma_workers:: Number of workers for Puma. Relevant only when Puma service is used and ignored when Passenger is used.
#
# === Keycloak parameters:
#
# $keycloak:: Enable Keycloak support. Note this is limited
# to configuring Apache and still relies on manually
# running keycloak-httpd-client-install
#
# $keycloak_app_name:: The app name as passed to keycloak-httpd-client-install
#
# $keycloak_realm:: The realm as passed to keycloak-httpd-client-install
#
class foreman (
Stdlib::HTTPUrl $foreman_url = $::foreman::params::foreman_url,
Boolean $unattended = $::foreman::params::unattended,
Expand Down Expand Up @@ -304,6 +314,9 @@
Integer[0] $foreman_service_puma_threads_min = $::foreman::params::foreman_service_puma_threads_min,
Integer[0] $foreman_service_puma_threads_max = $::foreman::params::foreman_service_puma_threads_max,
Integer[0] $foreman_service_puma_workers = $::foreman::params::foreman_service_puma_workers,
Boolean $keycloak = $::foreman::params::keycloak,
String[1] $keycloak_app_name = $::foreman::params::keycloak_app_name,
String[1] $keycloak_realm = $::foreman::params::keycloak_realm,
) inherits foreman::params {
if $db_sslmode == 'UNSET' and $db_root_cert {
$db_sslmode_real = 'verify-full'
Expand Down Expand Up @@ -337,8 +350,13 @@

if $apache {
Class['foreman::database'] -> Class['apache::service']
if $ipa_authentication and $keycloak {
fail("${::hostname}: External authentication via IPA and Keycloak are mutually exclusive.")
}
} elsif $ipa_authentication {
fail("${::hostname}: External authentication via IPA can only be enabled when Apache is used.")
} elsif $keycloak {
fail("${::hostname}: External authentication via Keycloak can only be enabled when Apache is used.")
}

# Anchor these separately so as not to break
Expand Down
5 changes: 2 additions & 3 deletions manifests/install.pp
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@

if $::foreman::apache and $::foreman::passenger and $::foreman::passenger_ruby_package {
package { $::foreman::passenger_ruby_package:
ensure => installed,
require => Class['apache'],
before => Class['apache::service'],
ensure => installed,
before => Class['apache::service'],
}
}

Expand Down
4 changes: 4 additions & 0 deletions manifests/params.pp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@
$jobs_service_enable = true
$jobs_sidekiq_redis_url = undef

# Keycloak
$keycloak = false
$keycloak_app_name = 'foreman-openidc'
$keycloak_realm = 'ssl-realm'

$hsts_enabled = true

Expand Down
1 change: 1 addition & 0 deletions manifests/settings.pp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
$email_smtp_authentication = $::foreman::email_smtp_authentication,
$email_smtp_user_name = $::foreman::email_smtp_user_name,
$email_smtp_password = $::foreman::email_smtp_password,
$keycloak = $::foreman::keycloak,
) {
unless empty($email_delivery_method) {
foreman_config_entry { 'delivery_method':
Expand Down
9 changes: 9 additions & 0 deletions spec/classes/foreman_config_apache_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,15 @@
should contain_file('/usr/share/foreman/config/environment.rb').with_owner('foreman')
end
end

describe 'with keycloak' do
let(:params) { super().merge(keycloak: true) }

it { should compile.with_all_deps }
it { should contain_apache__mod('auth_openidc') }
it { should contain_class('apache::mod::authz_user') }
it { should contain_file("#{http_dir}/conf.d/foreman-openidc_oidc_keycloak_ssl-realm.conf") }
end
end

describe 'with ssl' do
Expand Down
12 changes: 11 additions & 1 deletion spec/classes/foreman_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@

should contain_class('foreman::config::apache')
.with_passenger_ruby(passenger_ruby)
.with_keycloak(false)
end

it { should contain_apache__vhost('foreman').without_custom_fragment(/Alias/) }
Expand Down Expand Up @@ -262,11 +263,20 @@
email_smtp_domain: 'example.com',
email_smtp_authentication: 'none',
email_smtp_user_name: 'root',
email_smtp_password: 'secret'
email_smtp_password: 'secret',
keycloak: true,
keycloak_app_name: 'cloak-app',
keycloak_realm: 'myrealm',
}
end

it { is_expected.to compile.with_all_deps }
it do
is_expected.to contain_class('foreman::config::apache')
.with_keycloak(true)
.with_keycloak_app_name('cloak-app')
.with_keycloak_realm('myrealm')
end
end

context 'with journald logging' do
Expand Down