diff --git a/manifests/config/apache.pp b/manifests/config/apache.pp index 3953a4699..889856a4c 100644 --- a/manifests/config/apache.pp +++ b/manifests/config/apache.pp @@ -82,6 +82,9 @@ Boolean $ipa_authentication = $::foreman::ipa_authentication, Hash[String, Any] $http_vhost_options = {}, Hash[String, Any] $https_vhost_options = {}, + Boolean $keycloak = $foreman::keycloak, + String[1] $keycloak_app_name = $foreman::keycloak_app_name, + String[1] $keycloak_realm = $foreman::keycloak_realm, ) { $docroot = "${app_root}/public" $suburi_parts = split($foreman_url, '/') @@ -184,6 +187,27 @@ include ::apache::mod::intercept_form_submit include ::apache::mod::lookup_identity include ::apache::mod::auth_kerb + } elsif $keycloak { + apache::mod { 'auth_openidc': + package => 'mod_auth_openidc', + } + + # 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 + # + # 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": diff --git a/manifests/init.pp b/manifests/init.pp index 36ca074fd..3246889f5 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -191,6 +191,16 @@ # # $cors_domains:: List of domains that show be allowed for Cross-Origin Resource Sharing. This requires Foreman 1.22+ # +# === 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, @@ -283,6 +293,9 @@ Boolean $jobs_service_enable = $::foreman::params::jobs_service_enable, Boolean $hsts_enabled = $::foreman::params::hsts_enabled, Array[Stdlib::HTTPUrl] $cors_domains = $::foreman::params::cors_domains, + Boolean $keycloak = false, + String[1] $keycloak_app_name = 'foreman-openidc', + String[1] $keycloak_realm = 'ssl-realm', ) inherits foreman::params { if $db_sslmode == 'UNSET' and $db_root_cert { $db_sslmode_real = 'verify-full' @@ -315,8 +328,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 diff --git a/manifests/settings.pp b/manifests/settings.pp index b7ab8980e..9991875ae 100644 --- a/manifests/settings.pp +++ b/manifests/settings.pp @@ -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': diff --git a/spec/classes/foreman_spec.rb b/spec/classes/foreman_spec.rb index b8b731c17..aae9785e4 100644 --- a/spec/classes/foreman_spec.rb +++ b/spec/classes/foreman_spec.rb @@ -244,7 +244,10 @@ 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