Project

General

Profile

Download (10.9 KB) Statistics
| Branch: | Tag: | Revision:
# @summary Configure the foreman service using Apache
#
# @param app_root
# Root of the application.
#
# @param passenger_ruby
# Path to Ruby interpreter
#
# @param priority
# Apache vhost priority
#
# @param servername
# Servername for the vhost.
#
# @param serveraliases
# Serveraliases for the vhost.
#
# @param server_port
# Port for Apache to listen on HTTP requests
#
# @param server_ssl_port
# Port for Apache to listen on HTTPS requests
#
# @param ssl
# Whether to enable SSL.
#
# @param ssl_cert
# Location of the SSL certificate file.
#
# @param ssl_certs_dir
# Location of additional certificates for SSL client authentication.
#
# @param ssl_key
# Location of the SSL key file.
#
# @param ssl_ca
# Location of the SSL CA file
#
# @param ssl_chain
# Location of the SSL chain file
#
# @param ssl_crl
# Location of the SSL certificate revocation list file
#
# @param ssl_protocol
# SSLProtocol configuration to use
#
# @param ssl_verify_client
# The level of SSL client verification to apply
#
# @param user
# The user under which the application runs.
#
# @param passenger
# Whether to use passenger as an application server. If false, the reverse
# proxy setup is used.
#
# @param passenger_prestart
# Pre-start the first passenger worker instance process during httpd start.
#
# @param passenger_min_instances
# Minimum passenger worker instances to keep when application is idle.
#
# @param passenger_start_timeout
# Amount of seconds to wait for Ruby application boot.
#
# @param proxy_backend
# The backend service to proxy to. Only used when passenger is false
#
# @param proxy_params
# The proxy parameters to use when proxying. Only used when passenger is false
#
# @param proxy_no_proxy_uris
# URIs not to proxy. Only used when passenger is false
#
# @param foreman_url
# The URL Foreman should be reachable under. Used for loading the application
# on startup rather than on demand.
#
# @param access_log_format
# Apache log format to use
#
# @param ipa_authentication
# Whether to install support for IPA authentication
#
# @param http_vhost_options
# Direct options to apache::vhost for the http vhost
#
# @param https_vhost_options
# Direct options to apache::vhost for the https vhost
#
# @param keycloak
# Whether to enable keycloak support
#
# @param keycloak_app_name
# The app name as passed to keycloak-httpd-client-install
#
# @param keycloak_realm
# The realm as passed to keycloak-httpd-client-install
#
class foreman::config::apache(
Stdlib::Absolutepath $app_root = '/usr/share/foreman',
String $priority = '05',
Stdlib::Fqdn $servername = $facts['networking']['fqdn'],
Array[Stdlib::Fqdn] $serveraliases = [],
Stdlib::Port $server_port = 80,
Stdlib::Port $server_ssl_port = 443,
Stdlib::HTTPUrl $proxy_backend = 'http://localhost:3000/',
Hash $proxy_params = {'retry' => '0'},
Array[String] $proxy_no_proxy_uris = ['/pulp', '/pulp2', '/streamer', '/pub'],
Boolean $ssl = false,
Optional[Stdlib::Absolutepath] $ssl_ca = undef,
Optional[Stdlib::Absolutepath] $ssl_chain = undef,
Optional[Stdlib::Absolutepath] $ssl_cert = undef,
Variant[Undef, Enum[''], Stdlib::Absolutepath] $ssl_certs_dir = undef,
Optional[Stdlib::Absolutepath] $ssl_key = undef,
Variant[Undef, Enum[''], Stdlib::Absolutepath] $ssl_crl = undef,
Optional[String] $ssl_protocol = undef,
Enum['none','optional','require','optional_no_ca'] $ssl_verify_client = 'optional',
Optional[String] $user = undef,
Boolean $passenger = false,
Optional[String] $passenger_ruby = undef,
Boolean $passenger_prestart = false,
Integer[0] $passenger_min_instances = 1,
Integer[0] $passenger_start_timeout = 90,
Optional[Stdlib::HTTPUrl] $foreman_url = undef,
Optional[String] $access_log_format = undef,
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"

if $foreman_url {
$suburi_parts = split($foreman_url, '/')
$suburi_parts_count = size($suburi_parts) - 1
if $suburi_parts_count >= 3 {
$suburi_without_slash = join(values_at($suburi_parts, ["3-${suburi_parts_count}"]), '/')
if $suburi_without_slash {
$suburi = "/${suburi_without_slash}"
} else {
$suburi = undef
}
} else {
$suburi = undef
}
} else {
$suburi = undef
}

if $passenger {
if $suburi {
$custom_fragment = template('foreman/_suburi.conf.erb')
} else {
$custom_fragment = file('foreman/_assets.conf.erb')
}

$passenger_options = {
'passenger_app_root' => $app_root,
'passenger_min_instances' => $passenger_min_instances,
'passenger_start_timeout' => $passenger_start_timeout,
'passenger_ruby' => $passenger_ruby,
}

if $passenger_prestart {
$vhost_http_internal_options = $passenger_options + {'passenger_pre_start' => "http://${servername}:${server_port}"}
$vhost_https_internal_options = $passenger_options + {'passenger_pre_start' => "https://${servername}:${server_ssl_port}"}
} else {
$vhost_http_internal_options = $passenger_options
$vhost_https_internal_options = $passenger_options
}

if $app_root and $user {
file { ["${app_root}/config.ru", "${app_root}/config/environment.rb"]:
owner => $user,
}
}
} else {
if $suburi {
$custom_fragment = undef
} else {
$custom_fragment = file('foreman/_assets.conf.erb')
}

include ::apache::mod::proxy_wstunnel
$websockets_backend = regsubst($proxy_backend, 'http://', 'ws://')

$vhost_http_internal_options = {
'proxy_preserve_host' => true,
'proxy_add_headers' => true,
'request_headers' => [
'set X_FORWARDED_PROTO "http"',
'set SSL_CLIENT_S_DN ""',
'set SSL_CLIENT_CERT ""',
'set SSL_CLIENT_VERIFY ""',
],
'proxy_pass' => {
'no_proxy_uris' => $proxy_no_proxy_uris,
'path' => pick($suburi, '/'),
'url' => $proxy_backend,
'params' => $proxy_params,
},
'rewrites' => [
{
'comment' => 'Upgrade Websocket connections',
'rewrite_cond' => '%{HTTP:Upgrade} =websocket [NC]',
'rewrite_rule' => "/(.*) ${websockets_backend}\$1 [P,L]",
},
],
}

$vhost_https_internal_options = $vhost_http_internal_options + {
'ssl_proxyengine' => true,
'request_headers' => [
'set X_FORWARDED_PROTO "https"',
'set SSL_CLIENT_S_DN "%{SSL_CLIENT_S_DN}s"',
'set SSL_CLIENT_CERT "%{SSL_CLIENT_CERT}s"',
'set SSL_CLIENT_VERIFY "%{SSL_CLIENT_VERIFY}s"',
],
}

if $facts['selinux'] {
selboolean { 'httpd_can_network_connect':
persistent => true,
value => 'on',
}
}
}

include ::apache
include ::apache::mod::headers

if $ipa_authentication {
include ::apache::mod::authnz_pam
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',
}

# 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":
ensure => 'directory',
owner => 'root',
group => 'root',
mode => '0644',
purge => true,
recurse => true,
}

apache::vhost { 'foreman':
add_default_charset => 'UTF-8',
docroot => $docroot,
manage_docroot => false,
options => ['SymLinksIfOwnerMatch'],
port => $server_port,
priority => $priority,
servername => $servername,
serveraliases => $serveraliases,
access_log_format => $access_log_format,
additional_includes => ["${::apache::confd_dir}/${priority}-foreman.d/*.conf"],
use_optional_includes => true,
custom_fragment => $custom_fragment,
* => $vhost_http_internal_options + $http_vhost_options,
}

if $ssl {
if $ssl_crl and $ssl_crl != '' {
$ssl_crl_real = $ssl_crl
$ssl_crl_check = 'chain'
} else {
$ssl_crl_real = undef
$ssl_crl_check = undef
}

file { "${apache::confd_dir}/${priority}-foreman-ssl.d":
ensure => 'directory',
owner => 'root',
group => 'root',
mode => '0644',
purge => true,
recurse => true,
}

apache::vhost { 'foreman-ssl':
add_default_charset => 'UTF-8',
docroot => $docroot,
manage_docroot => false,
options => ['SymLinksIfOwnerMatch'],
port => $server_ssl_port,
priority => $priority,
servername => $servername,
serveraliases => $serveraliases,
ssl => true,
ssl_cert => $ssl_cert,
ssl_certs_dir => $ssl_certs_dir,
ssl_key => $ssl_key,
ssl_chain => $ssl_chain,
ssl_ca => $ssl_ca,
ssl_crl => $ssl_crl_real,
ssl_crl_check => $ssl_crl_check,
ssl_protocol => $ssl_protocol,
ssl_verify_client => $ssl_verify_client,
ssl_options => '+StdEnvVars +ExportCertData',
ssl_verify_depth => '3',
access_log_format => $access_log_format,
additional_includes => ["${::apache::confd_dir}/${priority}-foreman-ssl.d/*.conf"],
use_optional_includes => true,
custom_fragment => $custom_fragment,
* => $vhost_https_internal_options + $https_vhost_options,
}
}
}
    (1-1/1)