Page MenuHomeSoftware Heritage

No OneTemporary

diff --git a/README.md b/README.md
index f8aaf4e..2ca2445 100644
--- a/README.md
+++ b/README.md
@@ -1,307 +1,307 @@
# puppet-module-keycloak
[![Puppet Forge](http://img.shields.io/puppetforge/v/treydock/keycloak.svg)](https://forge.puppetlabs.com/treydock/keycloak)
[![Build Status](https://travis-ci.org/treydock/puppet-module-keycloak.png)](https://travis-ci.org/treydock/puppet-module-keycloak)
#### Table of Contents
1. [Overview](#overview)
* [Supported Versions of Keycloak](#supported-versions-of-keycloak)
2. [Usage - Configuration options](#usage)
3. [Reference - Parameter and detailed reference to all options](#reference)
4. [Limitations - OS compatibility, etc.](#limitations)
## Overview
The keycloak module allows easy installation and management of Keycloak.
### Supported Versions of Keycloak
| Keycloak Version | Keycloak Puppet module versions |
| ---------------- | ------------------------------- |
| 3.x | 2.x |
| 4.x - 6.x | 3.x |
| 6.x - 7.x | 4.x - 5.x |
## Usage
### keycloak
Install Keycloak using default `h2` database storage.
```puppet
class { 'keycloak': }
```
Install a specific version of Keycloak.
```puppet
class { 'keycloak':
version => '6.0.1',
datasource_driver => 'mysql',
}
```
Upgrading Keycloak version works by changing `version` parameter as long as the `datasource_driver` is not the default of `h2`. An upgrade involves installing the new version without touching the old version, updating the symlink which defaults to `/opt/keycloak`, applying all changes to new version and then restarting the `keycloak` service.
If the previous `version` was `6.0.1` using the following will upgrade to `7.0.0`:
```puppet
class { 'keycloak':
version => '7.0.0',
datasource_driver => 'mysql',
}
```
Install keycloak and use a local MySQL server for database storage
```puppet
include mysql::server
class { 'keycloak':
datasource_driver => 'mysql',
datasource_host => 'localhost',
datasource_port => 3306,
datasource_dbname => 'keycloak',
datasource_username => 'keycloak',
datasource_password => 'foobar',
}
```
The following example can be used to configure keycloak with a local PostgreSQL server.
```puppet
include postgresql::server
class { 'keycloak':
datasource_driver => 'postgresql',
datasource_host => 'localhost',
datasource_port => 5432,
datasource_dbname => 'keycloak',
datasource_username => 'keycloak',
datasource_password => 'foobar',
}
```
Configure a SSL certificate truststore and add a LDAP server's certificate to the truststore.
```puppet
class { 'keycloak':
truststore => true,
truststore_password => 'supersecret',
truststore_hostname_verification_policy => 'STRICT',
}
keycloak::truststore::host { 'ldap1.example.com':
certificate => '/etc/openldap/certs/0a00000.0',
}
```
Setup Keycloak to proxy through Apache HTTPS.
```puppet
class { 'keycloak':
proxy_https => true
}
apache::vhost { 'idp.example.com':
servername => 'idp.example.com',
port => '443',
ssl => true,
manage_docroot => false,
docroot => '/var/www/html',
proxy_preserve_host => true,
proxy_pass => [
{'path' => '/', 'url' => 'http://localhost:8080/'}
],
request_headers => [
'set X-Forwarded-Proto "https"',
'set X-Forwarded-Port "443"'
],
ssl_cert => '/etc/pki/tls/certs/idp.example.com/crt',
ssl_key => '/etc/pki/tls/private/idp.example.com.key',
}
```
Setup a host for theme development so that theme changes don't require a service restart, not recommended for production.
```puppet
class { 'keycloak':
theme_static_max_age => -1,
theme_cache_themes => false,
theme_cache_templates => false,
}
```
Run Keycloak using standalone clustered mode:
```puppet
class { 'keycloak':
operating_mode => 'clustered',
}
```
### keycloak_realm
Define a Keycloak realm that uses username and not email for login and to use a local branded theme.
```puppet
keycloak_realm { 'test':
ensure => 'present',
remember_me => true,
login_with_email_allowed => false,
login_theme => 'my_theme',
}
```
### keycloak\_ldap\_user_provider
Define a LDAP user provider so that authentication can be performed against LDAP. The example below uses two LDAP servers, disables importing of users and assumes the SSL certificates are trusted and do not require being in the truststore.
```puppet
keycloak_ldap_user_provider { 'LDAP on test':
ensure => 'present',
users_dn => 'ou=People,dc=example,dc=com',
connection_url => 'ldaps://ldap1.example.com:636 ldaps://ldap2.example.com:636',
import_enabled => false,
use_truststore_spi => 'never',
}
```
**NOTE** The `Id` for the above resource would be `LDAP-test` where the format is `${resource_name}-${realm}`.
### keycloak\_ldap_mapper
Use the LDAP attribute 'gecos' as the full name attribute.
```puppet
keycloak_ldap_mapper { 'full name for LDAP-test on test:
ensure => 'present',
resource_name => 'full name',
type => 'full-name-ldap-mapper',
ldap_attribute => 'gecos',
}
```
### keycloak\_sssd\_user\_provider
Define SSSD user provider. **NOTE** This type requires that SSSD be properly configured and Keycloak service restarted after SSSD ifp service is setup. Also requires `keycloak` class be called with `with_sssd_support` set to `true`.
```puppet
keycloak_sssd_user_provider { 'SSSD on test':
ensure => 'present',
}
```
### keycloak_client
Register a client.
```puppet
keycloak_client { 'www.example.com':
ensure => 'present',
realm => 'test',
redirect_uris => [
"https://www.example.com/oidc",
"https://www.example.com",
],
client_template => 'oidc-clients',
secret => 'supersecret',
}
```
### keycloak::client_scope::oidc
Defined type that can be used to define both `keycloak_client_scope` and `keycloak_protocol_mapper` resources for OpenID Connect.
```puppet
keycloak::client_scope::oidc { 'oidc-clients':
realm => 'test',
}
```
### keycloak::client_scope::saml
Defined type that can be used to define both `keycloak_client_scope` and `keycloak_protocol_mapper` resources for SAML.
```puppet
keycloak::client_scope::saml { 'saml-clients':
realm => 'test',
}
```
### keycloak\_client_scope
Define a Client Scope of `email` for realm `test` in Keycloak:
```puppet
keycloak_client_scope { 'email on test':
protocol => 'openid-connect',
}
```
### keycloak\_protocol_mapper
Associate a Protocol Mapper to a given Client Scope. The name in the following example will add the `email` protocol mapper to client scope `oidc-email` in the realm `test`.
```puppet
keycloak_protocol_mapper { "email for oidc-email on test":
claim_name => 'email',
user_attribute => 'email',
}
```
### keycloak\_client\_protocol\_mapper
Add `email` protocol mapper to `test.example.com` client in realm `test`
```puppet
keycloak_client_protocol_mapper { "email for test.example.com on test":
claim_name => 'email',
user_attribute => 'email',
}
```
### keycloak\_identity\_provider
Add `cilogon` identity provider to `test` realm
```puppet
keycloak_identity_provider { 'cilogon on test':
ensure => 'present',
display_name => 'CILogon',
provider_id => 'oidc',
first_broker_login_flow_alias => 'browser',
client_id => 'cilogon:/client_id/foobar',
client_secret => 'supersecret',
user_info_url => 'https://cilogon.org/oauth2/userinfo',
token_url => 'https://cilogon.org/oauth2/token',
authorization_url => 'https://cilogon.org/authorize',
}
```
### keycloak\_api
The keycloak_api type can be used to define how this module's types access the Keycloak API if this module is only used for the types/providers and the module's `kcadm-wrapper.sh` is not installed.
```puppet
keycloak_api { 'keycloak'
- install_base => '/opt/keycloak',
- server => 'http://localhost:8080/auth',
- realm => 'master',
- user => 'admin',
- password => 'changeme',
+ install_dir => '/opt/keycloak',
+ server => 'http://localhost:8080/auth',
+ realm => 'master',
+ user => 'admin',
+ password => 'changeme',
}
```
-The path for `install_base` will be joined with `bin/kcadm.sh` to produce the full path to `kcadm.sh`.
+The path for `install_dir` will be joined with `bin/kcadm.sh` to produce the full path to `kcadm.sh`.
## Reference
[http://treydock.github.io/puppet-module-keycloak/](http://treydock.github.io/puppet-module-keycloak/)
## Limitations
This module has been tested on:
* CentOS 7 x86_64
* RedHat 7 x86_64
* Debian 9 x86_64
* Ubuntu 18.04 x86_64
diff --git a/lib/puppet/provider/keycloak_api.rb b/lib/puppet/provider/keycloak_api.rb
index e640f13..8eef918 100644
--- a/lib/puppet/provider/keycloak_api.rb
+++ b/lib/puppet/provider/keycloak_api.rb
@@ -1,151 +1,151 @@
require 'puppet'
require 'json'
# Shared provider class
class Puppet::Provider::KeycloakAPI < Puppet::Provider
initvars
# Unused but defined anyways
commands kcadm_wrapper: '/opt/keycloak/bin/kcadm-wrapper.sh'
- @install_base = nil
+ @install_dir = nil
@server = nil
@realm = nil
@user = nil
@password = nil
@use_wrapper = true
class << self
- attr_accessor :install_base
+ attr_accessor :install_dir
attr_accessor :server
attr_accessor :realm
attr_accessor :user
attr_accessor :password
attr_accessor :use_wrapper
end
def self.type_properties
resource_type.validproperties.reject { |p| p.to_sym == :ensure }
end
def type_properties
self.class.type_properties
end
def self.camelize(value)
str = value.to_s.split('_').map(&:capitalize).join
str[0].downcase + str[1..-1]
end
def camelize(*args)
self.class.camelize(*args)
end
def convert_property_value(value)
case value
when :true
true
when :false
false
else
value
end
end
def self.kcadm(action, resource, realm = nil, file = nil, fields = nil)
kcadm_wrapper = '/opt/keycloak/bin/kcadm-wrapper.sh'
arguments = [action, resource]
if ['create', 'update'].include?(action)
arguments << '-o'
end
if realm
arguments << '-r'
arguments << realm
end
if file
arguments << '-f'
arguments << file
end
if fields
arguments << '--fields'
arguments << fields.join(',')
end
if use_wrapper == false || use_wrapper == :false
auth_arguments = [
'--no-config',
'--server', server,
'--realm', self.realm,
'--user', user,
'--password', password
]
- cmd = [File.join(install_base, 'bin/kcadm.sh')] + arguments + auth_arguments
+ cmd = [File.join(install_dir, 'bin/kcadm.sh')] + arguments + auth_arguments
else
cmd = [kcadm_wrapper] + arguments
end
execute(cmd, combine: false, failonfail: true)
end
def kcadm(*args)
self.class.kcadm(*args)
end
def self.realms
output = kcadm('get', 'realms', nil, nil, ['realm'])
data = JSON.parse(output)
realms = data.map { |r| r['realm'] }
realms
end
def self.name_uuid(name)
# Code lovingly taken from
# https://github.com/puppetlabs/marionette-collective/blob/master/lib/mcollective/ssl.rb
# This is the UUID version 5 type DNS name space which is as follows:
#
# 6ba7b810-9dad-11d1-80b4-00c04fd430c8
#
uuid_name_space_dns = [0x6b,
0xa7,
0xb8,
0x10,
0x9d,
0xad,
0x11,
0xd1,
0x80,
0xb4,
0x00,
0xc0,
0x4f,
0xd4,
0x30,
0xc8].map { |b| b.chr }.join
sha1 = Digest::SHA1.new
sha1.update(uuid_name_space_dns)
sha1.update(name)
# first 16 bytes..
bytes = sha1.digest[0, 16].bytes.to_a
# version 5 adjustments
bytes[6] &= 0x0f
bytes[6] |= 0x50
# variant is DCE 1.1
bytes[8] &= 0x3f
bytes[8] |= 0x80
bytes = [4, 2, 2, 2, 6].map do |i|
bytes.slice!(0, i).pack('C*').unpack('H*')
end
bytes.join('-')
end
def name_uuid(*args)
self.class.name_uuid(*args)
end
end
diff --git a/lib/puppet/type/keycloak_api.rb b/lib/puppet/type/keycloak_api.rb
index a90118d..af2140e 100644
--- a/lib/puppet/type/keycloak_api.rb
+++ b/lib/puppet/type/keycloak_api.rb
@@ -1,74 +1,74 @@
Dir[File.dirname(__FILE__) + '/keycloak*.rb'].each do |file|
next if file == __FILE__
next if File.basename(file) == 'keycloak_conn_validator.rb'
require file
end
Puppet::Type.newtype(:keycloak_api) do
desc <<-DESC
Type that configures API connection parameters for other keycloak types that use the Keycloak API.
@example Define API access
keycloak_api { 'keycloak'
- install_base => '/opt/keycloak',
+ install_dir => '/opt/keycloak',
server => 'http://localhost:8080/auth',
realm => 'master',
user => 'admin',
password => 'changeme',
}
DESC
newparam(:name, namevar: true) do
desc 'Keycloak API config'
end
- newparam(:install_base) do
+ newparam(:install_dir) do
desc 'Install location of Keycloak'
end
newparam(:server) do
desc 'Auth URL for Keycloak server'
defaultto('http://localhost:8080/auth')
end
newparam(:realm) do
desc 'Realm for authentication'
defaultto('master')
end
newparam(:user) do
desc 'User for authentication'
defaultto('admin')
end
newparam(:password) do
desc 'Password for authentication'
defaultto('changeme')
end
newparam(:use_wrapper, boolean: true) do
desc 'Boolean that determines if kcadm_wrapper.sh should be used'
newvalues(:true, :false)
defaultto :false
end
def generate
[
:keycloak_client_protocol_mapper,
:keycloak_client_scope,
:keycloak_client,
:keycloak_ldap_mapper,
:keycloak_ldap_user_provider,
:keycloak_protocol_mapper,
:keycloak_realm,
].each do |res_type|
provider_class = Puppet::Type.type(res_type).provider(:kcadm)
- provider_class.install_base = self[:install_base]
+ provider_class.install_dir = self[:install_dir]
provider_class.server = self[:server]
provider_class.realm = self[:realm]
provider_class.user = self[:user]
provider_class.password = self[:password]
provider_class.use_wrapper = self[:use_wrapper]
end
[]
end
end
diff --git a/manifests/config.pp b/manifests/config.pp
index b2735bc..5224b5f 100644
--- a/manifests/config.pp
+++ b/manifests/config.pp
@@ -1,94 +1,94 @@
# Private class.
class keycloak::config {
assert_private()
file { '/opt/keycloak':
ensure => 'link',
- target => $keycloak::install_base
+ target => $keycloak::install_base,
}
# Template uses:
# - $keycloak::install_base
# - $keycloak::admin_user
# - $keycloak::admin_user_password
file { 'kcadm-wrapper.sh':
ensure => 'file',
path => "${keycloak::install_base}/bin/kcadm-wrapper.sh",
owner => $keycloak::user,
group => $keycloak::group,
mode => '0750',
content => template('keycloak/kcadm-wrapper.sh.erb'),
show_diff => false,
}
$_add_user_keycloak_cmd = "${keycloak::install_base}/bin/add-user-keycloak.sh"
$_add_user_keycloak_args = "--user ${keycloak::admin_user} --password ${keycloak::admin_user_password} --realm master"
$_add_user_keycloak_state = "${keycloak::install_base}/.create-keycloak-admin-${keycloak::datasource_driver}"
exec { 'create-keycloak-admin':
command => "${_add_user_keycloak_cmd} ${_add_user_keycloak_args} && touch ${_add_user_keycloak_state}",
creates => $_add_user_keycloak_state,
notify => Class['keycloak::service'],
}
file { "${keycloak::install_base}/standalone/configuration":
ensure => 'directory',
owner => $keycloak::user,
group => $keycloak::group,
mode => '0750',
}
file { "${keycloak::install_base}/standalone/configuration/profile.properties":
ensure => 'file',
owner => $keycloak::user,
group => $keycloak::group,
content => template('keycloak/profile.properties.erb'),
mode => '0644',
notify => Class['keycloak::service'],
}
file { "${keycloak::install_base}/config.cli":
ensure => 'file',
owner => $keycloak::user,
group => $keycloak::group,
mode => '0600',
content => template('keycloak/config.cli.erb'),
notify => Exec['jboss-cli.sh --file=config.cli'],
show_diff => false,
}
exec { 'jboss-cli.sh --file=config.cli':
command => "${keycloak::install_base}/bin/jboss-cli.sh --file=config.cli",
cwd => $keycloak::install_base,
user => $keycloak::user,
group => $keycloak::group,
refreshonly => true,
logoutput => true,
notify => Class['keycloak::service'],
}
create_resources('keycloak::truststore::host', $keycloak::truststore_hosts)
if $keycloak::java_opts {
$java_opts_ensure = 'present'
} else {
$java_opts_ensure = 'absent'
}
if $keycloak::java_opts =~ Array {
$java_opts = join($keycloak::java_opts, ' ')
} else {
$java_opts = $keycloak::java_opts
}
if $keycloak::java_opts_append {
$_java_opts = "\$JAVA_OPTS ${java_opts}"
} else {
$_java_opts = $java_opts
}
file_line { 'standalone.conf-JAVA_OPTS':
ensure => $java_opts_ensure,
path => "${keycloak::install_base}/bin/standalone.conf",
line => "JAVA_OPTS=\"${_java_opts}\"",
match => '^JAVA_OPTS=',
notify => Class['keycloak::service'],
}
}
diff --git a/manifests/datasource/mysql.pp b/manifests/datasource/mysql.pp
index 726d0bf..5f14dfc 100644
--- a/manifests/datasource/mysql.pp
+++ b/manifests/datasource/mysql.pp
@@ -1,57 +1,57 @@
# @summary Manage MySQL datasource
#
# @api private
class keycloak::datasource::mysql {
assert_private()
$jar_source = pick($keycloak::datasource_jar_source, $keycloak::mysql_jar_source)
$module_source = pick($keycloak::datasource_module_source, 'puppet:///modules/keycloak/database/mysql/module.xml')
- $module_dir = "${keycloak::install_dir}/keycloak-${keycloak::version}/modules/system/layers/keycloak/com/mysql/jdbc/main"
+ $module_dir = "${keycloak::install_base}/modules/system/layers/keycloak/com/mysql/jdbc/main"
if $keycloak::datasource_package {
ensure_packages([$keycloak::datasource_package])
$jar_require = Package[$keycloak::datasource_package]
} else {
include ::mysql::bindings
include ::mysql::bindings::java
$jar_require = Class['::mysql::bindings::java']
}
exec { "mkdir -p ${module_dir}":
path => '/usr/bin:/bin',
creates => $module_dir,
user => $keycloak::user,
group => $keycloak::group,
}
-> file { $module_dir:
ensure => 'directory',
owner => $keycloak::user,
group => $keycloak::group,
mode => '0755',
}
file { "${$module_dir}/mysql-connector-java.jar":
ensure => 'link',
target => $jar_source,
owner => $keycloak::user,
group => $keycloak::group,
mode => '0644',
require => $jar_require,
}
file { "${$module_dir}/module.xml":
ensure => 'file',
source => $module_source,
owner => $keycloak::user,
group => $keycloak::group,
mode => '0644',
}
if $keycloak::manage_datasource {
mysql::db { $keycloak::datasource_dbname:
user => $keycloak::datasource_username,
password => $keycloak::datasource_password,
host => $keycloak::db_host,
grant => 'ALL',
}
}
}
diff --git a/manifests/datasource/oracle.pp b/manifests/datasource/oracle.pp
index d74f8f3..f6e70ff 100644
--- a/manifests/datasource/oracle.pp
+++ b/manifests/datasource/oracle.pp
@@ -1,39 +1,39 @@
# @summary Manage Oracle datasource
#
# @api private
#
class keycloak::datasource::oracle {
assert_private()
$module_source = pick($keycloak::datasource_module_source, 'puppet:///modules/keycloak/database/oracle/module.xml')
- $module_dir = "${keycloak::install_dir}/keycloak-${keycloak::version}/modules/system/layers/keycloak/org/oracle/main"
+ $module_dir = "${keycloak::install_base}/modules/system/layers/keycloak/org/oracle/main"
exec { "mkdir -p ${module_dir}":
path => '/usr/bin:/bin',
creates => $module_dir,
user => $keycloak::user,
group => $keycloak::group,
}
-> file { $module_dir:
ensure => 'directory',
owner => $keycloak::user,
group => $keycloak::group,
mode => '0755',
}
file { "${module_dir}/oracle.jar":
ensure => 'file',
source => $keycloak::datasource_jar_source,
owner => $keycloak::user,
group => $keycloak::group,
mode => '0644',
}
file { "${$module_dir}/module.xml":
ensure => 'file',
source => $module_source,
owner => $keycloak::user,
group => $keycloak::group,
mode => '0644',
}
}
diff --git a/manifests/datasource/postgresql.pp b/manifests/datasource/postgresql.pp
index 07cdfc0..ac3fd18 100644
--- a/manifests/datasource/postgresql.pp
+++ b/manifests/datasource/postgresql.pp
@@ -1,50 +1,50 @@
# @summary Manage postgresql datasource
#
# @api private
class keycloak::datasource::postgresql {
assert_private()
$jar_source = pick($keycloak::datasource_jar_source, $keycloak::postgresql_jar_source)
$module_source = pick($keycloak::datasource_module_source, 'puppet:///modules/keycloak/database/postgresql/module.xml')
- $module_dir = "${keycloak::install_dir}/keycloak-${keycloak::version}/modules/system/layers/keycloak/org/postgresql/main"
+ $module_dir = "${keycloak::install_base}/modules/system/layers/keycloak/org/postgresql/main"
include ::postgresql::lib::java
exec { "mkdir -p ${module_dir}":
path => '/usr/bin:/bin',
creates => $module_dir,
user => $keycloak::user,
group => $keycloak::group,
}
-> file { $module_dir:
ensure => 'directory',
owner => $keycloak::user,
group => $keycloak::group,
mode => '0755',
}
file { "${module_dir}/postgresql-jdbc.jar":
ensure => 'file',
source => $jar_source,
owner => $keycloak::user,
group => $keycloak::group,
mode => '0644',
require => Class['postgresql::lib::java'],
}
file { "${$module_dir}/module.xml":
ensure => 'file',
source => $module_source,
owner => $keycloak::user,
group => $keycloak::group,
mode => '0644',
}
if $keycloak::manage_datasource {
include ::postgresql::server
postgresql::server::db { $keycloak::datasource_dbname:
user => $keycloak::datasource_username,
password => postgresql_password($keycloak::datasource_username, $keycloak::datasource_password),
}
}
}
diff --git a/manifests/init.pp b/manifests/init.pp
index d0d92fe..188a684 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -1,350 +1,350 @@
# @summary Manage Keycloak
#
# @example
# include ::keycloak
#
# @param manage_install
# Install Keycloak from upstream Keycloak tarball.
# Set to false to manage installation of Keycloak outside
-# this module and set $install_dir and $version to match.
+# this module and set $install_dir to match.
# Defaults to true.
# @param version
# Version of Keycloak to install and manage.
# @param package_url
# URL of the Keycloak download.
# Default is based on version.
# @param install_dir
-# Parent directory of where to install Keycloak.
-# Default is `/opt`.
+# The directory of where to install Keycloak.
+# Default is `/opt/keycloak-${version}`.
# @param service_name
# Keycloak service name.
# Default is `keycloak`.
# @param service_ensure
# Keycloak service ensure property.
# Default is `running`.
# @param service_enable
# Keycloak service enable property.
# Default is `true`.
# @param service_hasstatus
# Keycloak service hasstatus parameter.
# Default is `true`.
# @param service_hasrestart
# Keycloak service hasrestart parameter.
# Default is `true`.
# @param service_bind_address
# Bind address for Keycloak service.
# Default is '0.0.0.0'.
# @param java_opts
# Sets additional options to Java virtual machine environment variable.
# @param java_opts_append
# Determine if $JAVA_OPTS should be appended to when setting `java_opts` parameter
# @param service_extra_opts
# Additional options added to the end of the service command-line.
# @param manage_user
# Defines if the module should manage the Linux user for Keycloak installation
# @param user
# Keycloak user name.
# Default is `keycloak`.
# @param user_shell
# Keycloak user shell.
# @param group
# Keycloak user group name.
# Default is `keycloak`.
# @param user_uid
# Keycloak user UID.
# Default is `undef`.
# @param group_gid
# Keycloak user group GID.
# Default is `undef`.
# @param admin_user
# Keycloak administrative username.
# Default is `admin`.
# @param admin_user_password
# Keycloak administrative user password.
# Default is `changeme`.
# @param manage_datasource
# Boolean that determines if configured datasource will be managed.
# Only applies when `datasource_driver` is `mysql`.
# Default is `true`.
# @param datasource_driver
# Datasource driver to use for Keycloak.
# Valid values are `h2`, `mysql`, 'oracle' and 'postgresql'
# Default is `h2`.
# @param datasource_host
# Datasource host.
# Only used when datasource_driver is `mysql`, 'oracle' or 'postgresql'
# Default is `localhost` for MySQL.
# @param datasource_port
# Datasource port.
# Only used when datasource_driver is `mysql`, 'oracle' or 'postgresql'
# Default is `3306` for MySQL.
# @param datasource_url
# Datasource url.
# Default datasource URLs are defined in init class.
# @param datasource_dbname
# Datasource database name.
# Default is `keycloak`.
# @param datasource_username
# Datasource user name.
# Default is `sa`.
# @param datasource_password
# Datasource user password.
# Default is `sa`.
# @param datasource_package
# Package to add specified datasource support
# @param datasource_jar_source
# Source for datasource JDBC driver - could be puppet link or local file on the node.
# Default is dependent on value for `datasource_driver`.
# This parameter is required if `datasource_driver` is `oracle`.
# @param datasource_module_source
# Source for datasource module.xml. Default depends on `datasource_driver`.
# @param datasource_xa_class
# MySQL Connector/J JDBC driver xa-datasource class name
# @param proxy_https
# Boolean that sets if HTTPS proxy should be enabled.
# Set to `true` if proxying traffic through Apache.
# Default is `false`.
# @param truststore
# Boolean that sets if truststore should be used.
# Default is `false`.
# @param truststore_hosts
# Hash that is used to define `keycloak::turststore::host` resources.
# Default is `{}`.
# @param truststore_password
# Truststore password.
# Default is `keycloak`.
# @param truststore_hostname_verification_policy
# Valid values are `WILDCARD`, `STRICT`, and `ANY`.
# Default is `WILDCARD`.
# @param http_port
# HTTP port used by Keycloak.
# Default is `8080`.
# @param theme_static_max_age
# Max cache age in seconds of static content.
# Default is `2592000`.
# @param theme_cache_themes
# Boolean that sets if themes should be cached.
# Default is `true`.
# @param theme_cache_templates
# Boolean that sets if templates should be cached.
# Default is `true`.
# @param realms
# Hash that is used to define keycloak_realm resources.
# Default is `{}`.
# @param realms_merge
# Boolean that sets if `realms` should be merged from Hiera.
# @param oidc_client_scopes
# Hash that is used to define keycloak::client_scope::oidc resources.
# Default is `{}`.
# @param oidc_client_scopes_merge
# Boolean that sets if `oidc_client_scopes` should be merged from Hiera.
# @param saml_client_scopes
# Hash that is used to define keycloak::client_scope::saml resources.
# Default is `{}`.
# @param saml_client_scopes_merge
# Boolean that sets if `saml_client_scopes` should be merged from Hiera.
# @param identity_providers
# Hash that is used to define keycloak_identity_provider resources.
# @param identity_providers_merge
# Boolean that sets if `identity_providers` should be merged from Hiera.
# @param client_scopes
# Hash that is used to define keycloak_client_scope resources.
# @param client_scopes_merge
# Boolean that sets if `client_scopes` should be merged from Hiera.
# @param protocol_mappers
# Hash that is used to define keycloak_protocol_mapper resources.
# @param protocol_mappers_merge
# Boolean that sets if `protocol_mappers` should be merged from Hiera.
# @param clients
# Hash that is used to define keycloak_client resources.
# @param clients_merge
# Boolean that sets if `clients` should be merged from Hiera.
# @param with_sssd_support
# Boolean that determines if SSSD user provider support should be available
# @param libunix_dbus_java_source
# Source URL of libunix-dbus-java
# @param install_libunix_dbus_java_build_dependencies
# Boolean that determines of libunix-dbus-java build dependencies are managed by this module
# @param libunix_dbus_java_build_dependencies
# Packages needed to build libunix-dbus-java
# @param libunix_dbus_java_libdir
# Path to directory to install libunix-dbus-java libraries
# @param jna_package_name
# Package name for jna
# @param manage_sssd_config
# Boolean that determines if SSSD ifp config for Keycloak is managed
# @param sssd_ifp_user_attributes
# user_attributes to define for SSSD ifp service
# @param restart_sssd
# Boolean that determines if SSSD should be restarted
# @param service_environment_file
# Path to the file with environment variables for the systemd service
# @param operating_mode
# Keycloak operating mode deployment
# @param tech_preview_features
# List of technology Preview features to enable
#
class keycloak (
Boolean $manage_install = true,
String $version = '6.0.1',
Optional[Variant[Stdlib::HTTPUrl, Stdlib::HTTPSUrl]]
$package_url = undef,
- Stdlib::Absolutepath $install_dir = '/opt',
+ Optional[Stdlib::Absolutepath] $install_dir = undef,
String $service_name = 'keycloak',
String $service_ensure = 'running',
Boolean $service_enable = true,
Boolean $service_hasstatus = true,
Boolean $service_hasrestart = true,
Stdlib::IP::Address $service_bind_address = '0.0.0.0',
Optional[Variant[String, Array]] $java_opts = undef,
Boolean $java_opts_append = true,
Optional[String] $service_extra_opts = undef,
Boolean $manage_user = true,
String $user = 'keycloak',
Stdlib::Absolutepath $user_shell = '/sbin/nologin',
String $group = 'keycloak',
Optional[Integer] $user_uid = undef,
Optional[Integer] $group_gid = undef,
String $admin_user = 'admin',
String $admin_user_password = 'changeme',
Boolean $manage_datasource = true,
Enum['h2', 'mysql', 'oracle', 'postgresql'] $datasource_driver = 'h2',
Optional[String] $datasource_host = undef,
Optional[Integer] $datasource_port = undef,
Optional[String] $datasource_url = undef,
Optional[String] $datasource_xa_class = undef,
String $datasource_dbname = 'keycloak',
String $datasource_username = 'sa',
String $datasource_password = 'sa',
Optional[String] $datasource_package = undef,
Optional[String] $datasource_jar_source = undef,
Optional[String] $datasource_module_source = undef,
Boolean $proxy_https = false,
Boolean $truststore = false,
Hash $truststore_hosts = {},
String $truststore_password = 'keycloak',
Enum['WILDCARD', 'STRICT', 'ANY'] $truststore_hostname_verification_policy = 'WILDCARD',
Integer $http_port = 8080,
Integer $theme_static_max_age = 2592000,
Boolean $theme_cache_themes = true,
Boolean $theme_cache_templates = true,
Hash $realms = {},
Boolean $realms_merge = false,
Hash $oidc_client_scopes = {},
Boolean $oidc_client_scopes_merge = false,
Hash $saml_client_scopes = {},
Boolean $saml_client_scopes_merge = false,
Hash $client_scopes = {},
Boolean $client_scopes_merge = false,
Hash $protocol_mappers = {},
Boolean $protocol_mappers_merge = false,
Hash $identity_providers = {},
Boolean $identity_providers_merge = false,
Hash $clients = {},
Boolean $clients_merge = false,
Boolean $with_sssd_support = false,
Variant[Stdlib::HTTPUrl, Stdlib::HTTPSUrl]
$libunix_dbus_java_source = 'https://github.com/keycloak/libunix-dbus-java/archive/libunix-dbus-java-0.8.0.tar.gz',
Boolean $install_libunix_dbus_java_build_dependencies = true,
Array $libunix_dbus_java_build_dependencies = [],
Stdlib::Absolutepath $libunix_dbus_java_libdir = '/usr/lib64',
String $jna_package_name = 'jna',
Boolean $manage_sssd_config = true,
Array $sssd_ifp_user_attributes = [],
Boolean $restart_sssd = true,
Optional[Stdlib::Absolutepath] $service_environment_file = undef,
Enum['standalone', 'clustered'] $operating_mode = 'standalone',
Array $tech_preview_features = [],
) {
if ! ($facts['os']['family'] in ['RedHat','Debian']) {
fail("Unsupported osfamily: ${facts['os']['family']}, module ${module_name} only support osfamilies Debian and Redhat")
}
$download_url = pick($package_url, "https://downloads.jboss.org/keycloak/${version}/keycloak-${version}.tar.gz")
case $datasource_driver {
'h2': {
$datasource_connection_url = pick($datasource_url, "jdbc:h2:\${jboss.server.data.dir}/${datasource_dbname};AUTO_SERVER=TRUE")
}
'mysql': {
$db_host = pick($datasource_host, 'localhost')
$db_port = pick($datasource_port, 3306)
$datasource_connection_url = pick($datasource_url, "jdbc:mysql://${db_host}:${db_port}/${datasource_dbname}")
}
'oracle': {
$db_host = pick($datasource_host, 'localhost')
$db_port = pick($datasource_port, 1521)
$datasource_connection_url = pick($datasource_url, "jdbc:oracle:thin:@${db_host}:${db_port}:${datasource_dbname}")
}
'postgresql': {
$db_host = pick($datasource_host, 'localhost')
$db_port = pick($datasource_port, 5432)
$datasource_connection_url = pick($datasource_url, "jdbc:postgresql://${db_host}:${db_port}/${datasource_dbname}")
}
default: {}
}
if ($datasource_driver == 'oracle') and ($datasource_jar_source == undef) {
fail('Using Oracle RDBMS requires definition datasource_jar_source for Oracle JDBC driver. Refer to module documentation')
}
case $facts['os']['family'] {
'RedHat': {
if versioncmp($facts['os']['release']['major'], '8') >= 0 {
$mysql_datasource_class = pick($datasource_xa_class, 'org.mariadb.jdbc.MariaDbDataSource')
$mysql_jar_source = '/usr/lib/java/mariadb-java-client.jar'
$postgresql_jar_source = '/usr/share/java/postgresql-jdbc/postgresql.jar'
} else {
$mysql_datasource_class = pick($datasource_xa_class, 'com.mysql.jdbc.jdbc2.optional.MysqlXADataSource')
$mysql_jar_source = '/usr/share/java/mysql-connector-java.jar'
$postgresql_jar_source = '/usr/share/java/postgresql-jdbc.jar'
}
}
'Debian': {
if $facts['os']['name'] == 'Debian' and versioncmp($facts['os']['release']['major'], '10') >= 0 {
$mysql_datasource_class = pick($datasource_xa_class, 'org.mariadb.jdbc.MariaDbDataSource')
$mysql_jar_source = '/usr/share/java/mariadb-java-client.jar'
} else {
$mysql_datasource_class = pick($datasource_xa_class, 'com.mysql.jdbc.jdbc2.optional.MysqlXADataSource')
$mysql_jar_source = '/usr/share/java/mysql-connector-java.jar'
}
$postgresql_jar_source = '/usr/share/java/postgresql.jar'
}
default: {
# do nothing
}
}
- $install_base = "${keycloak::install_dir}/keycloak-${keycloak::version}"
+ $install_base = pick($install_dir, "/opt/keycloak-${keycloak::version}")
include ::java
contain 'keycloak::install'
contain "keycloak::datasource::${datasource_driver}"
contain 'keycloak::config'
contain 'keycloak::service'
Class['::java']
-> Class['keycloak::install']
-> Class["keycloak::datasource::${datasource_driver}"]
-> Class['keycloak::config']
-> Class['keycloak::service']
Class["keycloak::datasource::${datasource_driver}"]~>Class['keycloak::service']
if $with_sssd_support {
contain 'keycloak::sssd'
Class['keycloak::sssd'] ~> Class['keycloak::service']
}
keycloak_conn_validator { 'keycloak':
keycloak_server => 'localhost',
keycloak_port => $http_port,
use_ssl => false,
timeout => 60,
test_url => '/auth/realms/master/.well-known/openid-configuration',
require => Class['keycloak::service'],
}
include keycloak::resources
}
diff --git a/manifests/install.pp b/manifests/install.pp
index ae0bdab..bcfd9e0 100644
--- a/manifests/install.pp
+++ b/manifests/install.pp
@@ -1,53 +1,51 @@
# Private class.
class keycloak::install {
assert_private()
if $keycloak::manage_user {
user { 'keycloak':
ensure => 'present',
name => $keycloak::user,
forcelocal => true,
shell => $keycloak::user_shell,
gid => $keycloak::group,
uid => $keycloak::user_uid,
home => '/var/lib/keycloak',
managehome => true,
}
group { 'keycloak':
ensure => 'present',
name => $keycloak::group,
forcelocal => true,
gid => $keycloak::group_gid,
}
}
- $install_base = "${keycloak::install_dir}/keycloak-${keycloak::version}"
-
if $::keycloak::manage_install {
- file { $install_base:
+ file { $::keycloak::install_base:
ensure => 'directory',
owner => $keycloak::user,
group => $keycloak::group,
mode => '0755',
}
-> archive { "keycloak-${keycloak::version}.tar.gz":
ensure => 'present',
extract => true,
path => "/tmp/keycloak-${keycloak::version}.tar.gz",
- extract_path => $install_base,
+ extract_path => $::keycloak::install_base,
extract_command => 'tar xfz %s --strip-components=1',
source => $keycloak::download_url,
- creates => "${install_base}/bin",
+ creates => "${::keycloak::install_base}/bin",
cleanup => true,
user => $keycloak::user,
group => $keycloak::group,
}
} else {
# Set permissions properly when using a package
exec { 'ensure-keycloak-dir-owner':
- command => "chown -R ${::keycloak::user}:${::keycloak::group} ${install_base}",
- unless => "test `stat -c %U ${install_base}` = ${::keycloak::user}",
+ command => "chown -R ${::keycloak::user}:${::keycloak::group} ${::keycloak::install_base}",
+ unless => "test `stat -c %U ${::keycloak::install_base}` = ${::keycloak::user}",
path => ['/bin','/usr/bin'],
}
}
}
diff --git a/spec/acceptance/99_keycloak_api_spec.rb b/spec/acceptance/99_keycloak_api_spec.rb
index 9d058e7..561530d 100644
--- a/spec/acceptance/99_keycloak_api_spec.rb
+++ b/spec/acceptance/99_keycloak_api_spec.rb
@@ -1,63 +1,63 @@
require 'spec_helper_acceptance'
describe 'keycloak_api:', if: RSpec.configuration.keycloak_full do
context 'bootstraps' do
it 'runs successfully' do
pp = <<-EOS
include mysql::server
class { 'keycloak':
datasource_driver => 'mysql',
}
EOS
apply_manifest(pp, catch_failures: true)
apply_manifest(pp, catch_changes: true)
end
end
context 'creates realm' do
it 'runs successfully' do
pp = <<-EOS
keycloak_api { 'keycloak':
- install_base => '/opt/keycloak',
+ install_dir => '/opt/keycloak',
}
keycloak_realm { 'test2': ensure => 'present' }
EOS
on hosts, 'rm -f /opt/keycloak/bin/kcadm-wrapper.sh'
apply_manifest(pp, catch_failures: true)
apply_manifest(pp, catch_changes: true)
end
it 'has created a realm' do
on hosts, '/opt/keycloak/bin/kcadm.sh get realms/test2 --no-config --server http://localhost:8080/auth --realm master --user admin --password changeme' do
data = JSON.parse(stdout)
expect(data['id']).to eq('test2')
end
end
end
context 'updates realm' do
it 'runs successfully' do
pp = <<-EOS
keycloak_api { 'keycloak':
- install_base => '/opt/keycloak',
+ install_dir => '/opt/keycloak',
}
keycloak_realm { 'test2':
ensure => 'present',
remember_me => true,
}
EOS
on hosts, 'rm -f /opt/keycloak/bin/kcadm-wrapper.sh'
apply_manifest(pp, catch_failures: true)
apply_manifest(pp, catch_changes: true)
end
it 'has updated a realm' do
on hosts, '/opt/keycloak/bin/kcadm.sh get realms/test2 --no-config --server http://localhost:8080/auth --realm master --user admin --password changeme' do
data = JSON.parse(stdout)
expect(data['rememberMe']).to eq(true)
end
end
end
end

File Metadata

Mime Type
text/x-diff
Expires
Mon, Aug 18, 9:54 PM (18 h, 45 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3261008

Event Timeline