Coder Social home page Coder Social logo

puppet-module-keycloak's Introduction

puppet-module-keycloak

Puppet Forge CI Status

Table of Contents

  1. Overview
  2. Usage - Configuration options
  3. Reference - Parameter and detailed reference to all options
  4. Limitations - OS compatibility, etc.

Overview

The keycloak module allows easy installation and management of Keycloak.

Upgrade to 8.x

This module underwent major changes in the 8.0.0 release to support Keycloak that uses Quarkus. The initial 8.0.0 release of this module only supports Keycloak 18.x.

Numerous parameters were changed or removed. Below is a list of the changes to parameters as well as some behavior changes.

Parameters removed

  • service_hasstatus, service_hasrestart
  • management_bind_address
  • java_opts_append
  • wildfly_user, wildfly_user_password
  • datasource_package, datasource_jar_source, datasource_jar_filename, datasource_module_source, datasource_xa_class
  • proxy_https
  • truststore_hostname_verification_policy
  • theme_static_max_age, theme_cache_themes, theme_cache_templates
  • operating_mode, enable_jdbc_ping, jboss_bind_public_address, jboss_bind_private_address
  • master_address, server_name, role, user_cache
  • tech_preview_features
  • auto_deploy_exploded, auto_deploy_zipped
  • syslog, syslog_app_name, syslog_facility, syslog_hostname, syslog_level
  • syslog_port, syslog_server_address, syslog_format

Parameters renamed

  • service_bind_address renamed to http_host and now defined in keycloak.conf instead of the systemd unit file
  • manage_datasource renamed to manage_db
  • datasource_driver renamed to db
  • datasource_host renamed to db_url_host
  • datasource_port renamed to db_url_port
  • datasource_url renamed to db_url
  • datasource_dbname renamed to db_url_database
  • datasource_username renamed to db_username
  • datasource_password renamed to db_password
  • mysql_database_charset renamed to db_charset
  • auth_url_path renamed to validator_test_url and default value changed

Parameters added

  • java_declare_method to make it easier for EL platforms to deploy working Keycloak with correct Java
  • java_package, java_home, java_alternative_path, java_alternative
  • start_command
  • configs
  • hostname, http_enabled, http_host, https_port, proxy
  • manage_db_server
  • features
  • features_disabled
  • providers_purge

Behavior changes

The SSSD parameters are no longer tested and likely won't work. If you use the SSSD user provider and SSSD related parameters, please open an issue on this repo.

This module no longer makes copies for DB driver jar files or install Java bindings, they are not necessary.

When db is set to mariadb, mysql or postgres this module will by default install the database server to the Keycloak host. If you run a remote DB server for Keycloak, set manage_db_server and manage_db to false.

There is no longer a need to define cluster or domain modes in the Quarkus deployment, all related functionality is removed.

Some basic configuration options are exposed using parameters but most configuration options for Keycloak will need to be passed into the configs parameter.

Drop Debian 9 support due to OS repos not having Java 11.

Changes to LDAP user provider IDs

If you had keycloak_ldap_user_provider resources defined the mechanism for defining the ID has changed and requires some migration. Also the ldap property for any keycloak_ldap_mapper resources will have to be adjusted.

WARNING The LDAP user provider ID is used to create user IDs for LDAP users. These will change if the ID is changed. This is to prevent messages such as this: The given key is not a valid key per specification, future migration might fail: f:OSC-LDAP-osc:tdockendorf. If you wish to keep the old style IDs you must provide the id parameter as $ldap-$realm to maintain old IDs.

It's advised to either Migrate to new IDs or Keep old IDs

Migrate to new IDs

Changes

  • Define old keycloak_ldap_user_provider resource as absent with new name and setting id and resource_name.
  • Define same keycloak_ldap_user_provider resource to get created with new ID
  • Update keycloak_ldap_mapper resources to point to just name of keycloak_ldap_user_provider.

Before:

keycloak_ldap_user_provider { 'LDAP on test':
  users_dn                  => 'ou=People,dc=test',
  connection_url            => 'ldap://localhost:389',
  custom_user_search_filter => '(objectClass=posixAccount)',
}
keycloak_ldap_mapper { "first name for LDAP-test on test":
  ensure               => 'present',
  type                 => 'user-attribute-ldap-mapper',
  user_model_attribute => 'firstName',
  ldap_attribute       => 'givenName',
}

After:

keycloak_ldap_user_provider { 'LDAP-remove on test':
  ensure        => 'absent',
  resource_name => 'LDAP',
  id            => 'LDAP-test',
}
keycloak_ldap_user_provider { 'LDAP on test':
  users_dn                  => 'ou=People,dc=test',
  connection_url            => 'ldap://localhost:389',
  custom_user_search_filter => '(objectClass=posixAccount)',
}
keycloak_ldap_mapper { "first name for LDAP on test":
  ensure               => 'present',
  type                 => 'user-attribute-ldap-mapper',
  user_model_attribute => 'firstName',
  ldap_attribute       => 'givenName',
}
Keep old IDs

If you wish to avoid re-creating keycloak_ldap_user_provider and keycloak_ldap_mapper resources then the ID parameters must be defined.

For keycloak_ldap_user_provider ensure the id property is set to match the old pattern. If name was LDAP and realm test or name was componsite LDAP on test then set id to LDAP-test.

For keycloak_ldap_mapper ensure the parent_id property is set to point to old ID for associated keycloak_ldap_user_provider. If the ldap value is LDAP and realm is test or composite name is first name for LDAP on test then ensure parent_id is set to LDAP-test.

Supported Versions of Keycloak

Currently this module supports Keycloak version 24.x. This module may work on earlier versions but this is the only version tested.

Keycloak Version Keycloak Puppet module versions
3.x 2.x
4.x - 6.x 3.x
6.x - 8.x 4.x - 5.x
8.x - 12.x 6.x
12.x - 16.x 7.x
18.x 8.x
19.x - 21.x 9.x
21.x 10.x
22.x - 24.x 11.x
24.x 12.x
----------------- ---------------------------------

Usage

keycloak

Install Keycloak using default dev-file database.

class { 'keycloak': }

Install a specific version of Keycloak.

class { 'keycloak':
  version => '24.0.0',
  db      => 'mariadb',
}

Upgrading Keycloak version works by changing version parameter as long as the db parameter is not the default of dev-file. 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 22.0.0 using the following will upgrade to 24.0.0:

class { 'keycloak':
  version => '24.0.0',
  db      => 'mariadb',
}

Install keycloak and use a local MariaDB server for database storage

include mysql::server
class { 'keycloak':
  db              => 'mariadb',
  db_url_host     => 'localhost',
  db_url_port     => 3306,
  db_url_database => 'keycloak',
  db_username     => 'keycloak',
  db_password     => 'foobar',
}

The following example can be used to configure keycloak with a local PostgreSQL server.

include postgresql::server
class { 'keycloak':
    db              => 'postgres',
    db_url_host     => 'localhost',
    db_url_port     => 5432,
    db_url_database => 'keycloak',
    db_username     => 'keycloak',
    db_password     => 'foobar',
}

Configure a SSL certificate truststore and add a LDAP server's certificate to the truststore.

class { 'keycloak':
  truststore          => true,
  truststore_password => 'supersecret',
}
keycloak::truststore::host { 'ldap1.example.com':
  certificate => '/etc/openldap/certs/0a00000.0',
}

Setup Keycloak to proxy through Apache HTTPS.

class { 'keycloak':
  http_host => '127.0.0.1',
  proxy     => 'edge',
}
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_add_headers   => 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',
}

NOTE: Can set hostname parameter to unset if you wish for that configuration to not be set in the Keycloak configuration if you wish for Keycloak to not use strict hostname checking and respond to multiple hostnames.

Deploy SPI

A simple example of deploying a custom SPI from a URL:

keycloak::spi_deployment { 'duo-spi':
  ensure        => 'present',
  deployed_name => 'DuoUniversalKeycloakAuthenticator-jar-with-dependencies.jar',
  source        => 'https://github.com/instipod/DuoUniversalKeycloakAuthenticator/releases/download/1.0.5/DuoUniversalKeycloakAuthenticator-jar-with-dependencies-1.0.5.jar',
}

The source can be a URL or a file path like /tmp/foo.jar or prefixed with file:// or puppet://

The following example will deploy a custom SPI then check the Keycloak API for the resource to exist. This is useful to ensure SPI is loaded into Keycloak before attempting to add custom resources.

keycloak::spi_deployment { 'duo-spi':
  deployed_name => 'DuoUniversalKeycloakAuthenticator-jar-with-dependencies.jar',
  source        => 'https://github.com/instipod/DuoUniversalKeycloakAuthenticator/releases/download/1.0.4/DuoUniversalKeycloakAuthenticator-jar-with-dependencies-1.0.4.jar',
  test_url      => 'authentication/authenticator-providers',
  test_key      => 'id',
  test_value    => 'duo-universal',
  test_realm    => 'test',
  test_before   => [
    'Keycloak_flow[form-browser-with-duo]',
    'Keycloak_flow_execution[duo-universal under form-browser-with-duo on test]',
  ],
}

Partial Import

This module supports Importing data from exported JSON files via the keycloak::partial_import defined type.

Example of importing a JSON file into the test realm:

keycloak::partial_import { 'mysettings':
  realm              => 'test',
  if_resource_exists => 'SKIP',
  source             => 'puppet:///modules/profile/keycloak/mysettings.json',
}

NOTE: By default the keycloak::partial_import defined type will require the Keycloak_realm resource used for the realm parameter. If you manage the realm a different way, pass require_realm => false.

keycloak_realm

Define a Keycloak realm that uses username and not email for login and to use a local branded theme.

keycloak_realm { 'test':
  ensure                   => 'present',
  remember_me              => true,
  login_with_email_allowed => false,
  login_theme              => 'my_theme',
}

NOTE: If the flow properties such as browser_flow are changed from their defaults then this value will not be set when a realm is first created. The value will also not be updated if the flow does not exist. For new realms you will have to run Puppet twice in order to create the flows then update the realm setting.

keycloak_role_mapping

Manage realm role mappings for users and groups. Example:

keycloak_role_mapping { 'roles for john on master':
  realm       => 'master',
  name        => 'john',
  realm_roles => ['role1', 'role2'],
}

keycloak_role_mapping { 'roles for mygroup on master':
  realm        => 'master',
  name         => 'mygroup',
  group        => true,
  realm_roles  => ['role1'],
}

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.

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',
}

If you're using FreeIPA you can use a defined resource that wraps keycloak_ldap_user_provider:

keycloak::freeipa_user_provider { 'ipa.example.org':
  ensure          => 'present',
  realm           => 'EXAMPLE.ORG',
  bind_dn         => 'uid=ldapproxy,cn=sysaccounts,cn=etc,dc=example,dc=org',
  bind_credential => 'secret',
  users_dn        => 'cn=users,cn=accounts,dc=example,dc=org',
  priority        => 10,
}

keycloak_ldap_mapper

Use the LDAP attribute 'gecos' as the full name attribute.

keycloak_ldap_mapper { 'full name for LDAP-test on test:
  ensure         => 'present',
  resource_name  => 'full name',
  type           => 'full-name-ldap-mapper',
  ldap_attribute => 'gecos',
}

If you're using FreeIPA you can use a defined resource that adds all the required attribute mappings automatically:

keycloak::freeipa_ldap_mappers { 'ipa.example.org':
  realm            => 'EXAMPLE.ORG',
  groups_dn        => 'cn=groups,cn=accounts,dc=example,dc=org',
  roles_dn         => 'cn=groups,cn=accounts,dc=example,dc=org'
}

keycloak_sssd_user_provider

WARNING This feature is no longer tested and likely stopped working when Keycloak began requiring Java 11+. If you rely on this feature, please open an issue or pull request. Likely need to build jna from source.

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.

keycloak_sssd_user_provider { 'SSSD on test':
  ensure => 'present',
}

keycloak_client

Register a client.

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.

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.

keycloak::client_scope::saml { 'saml-clients':
  realm => 'test',
}

keycloak_client_scope

Define a Client Scope of email for realm test in Keycloak:

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.

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

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

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 Flows

The following is an example of deploying a custom Flow. The name for the top level flow is $alias on $realm The name for an execution is $provider under $flow on $realm. The name for the flow under a top level flow is $alias under $flow_alias on $realm.

keycloak_flow { 'browser-with-duo on test':
  ensure => 'present',
}
keycloak_flow_execution { 'auth-cookie under browser-with-duo on test':
  ensure       => 'present',
  configurable => false,
  display_name => 'Cookie',
  index        => 0,
  requirement  => 'ALTERNATIVE',
}
keycloak_flow_execution { 'identity-provider-redirector under browser-with-duo on test':
  ensure       => 'present',
  configurable => true,
  display_name => 'Identity Provider Redirector',
  index        => 1,
  requirement  => 'ALTERNATIVE',
}
keycloak_flow { 'form-browser-with-duo under browser-with-duo on test':
  ensure      => 'present',
  index       => 2,
  requirement => 'ALTERNATIVE',
  top_level   => false,
}
keycloak_flow_execution { 'auth-username-password-form under form-browser-with-duo on test':
  ensure       => 'present',
  configurable => false,
  display_name => 'Username Password Form',
  index        => 0,
  requirement  => 'REQUIRED',
}
keycloak_flow_execution { 'duo-universal under form-browser-with-duo on test':
  ensure       => 'present',
  configurable => true,
  display_name => 'Duo Universal MFA',
  alias        => 'Duo',
  config       => {
    "duoApiHostname"    => "api-foo.duosecurity.com",
    "duoSecretKey"      => "secret",
    "duoIntegrationKey" => "foo-ikey",
    "duoGroups"         => "duo"
  },
  requirement  => 'REQUIRED',
  index        => 1,
}

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.

keycloak_api { 'keycloak'
 install_dir => '/opt/keycloak',
 server     => 'http://localhost:8080/auth',
 realm      => 'master',
 user       => 'admin',
 password   => 'changeme',
}

The path for install_dir will be joined with bin/kcadm.sh to produce the full path to kcadm.sh.

keycloak_required_action

The keycloak_required_action type can be used to define actions a user must perform during the authentication process. A user will not be able to complete the authentication process until these actions are complete. For instance, change a one-time password, accept T&C, etc.

The name for an action is $alias on $realm.

Important: actions from puppet config and from a server are matched based on a combination of alias and realm, so edition of aliases is not supported.

# Minimal example
keycloak_required_action { 'VERIFY_EMAIL on master':
 ensure => present,
 provider_id => 'webauthn-register',
}

# Full example

keycloak_required_action { 'webauthn-register on master':
 ensure => present,
 provider_id => 'webauthn-register',
 display_name => 'Webauthn Register',
 default => true,
 enabled => true,
 priority => 1,
 config => {
   'something' => 'true', # keep in mind that keycloak only supports strings for both keys and values
   'smth else' => '1',
 },
}

Reference

http://treydock.github.io/puppet-module-keycloak/

Limitations

This module has been tested on:

  • RedHat/Rocky/AlmaLinux 8 x86_64
  • RedHat/Rocky/AlmaLinux 9 x86_64
  • Debian 11 x86_64
  • Ubuntu 20.04 x86_64
  • Ubuntu 22.04 x86_64

UUID Generation

bundle exec irb
2.5.1 :001 > require File.expand_path(File.join(File.dirname(__FILE__), 'lib/puppet/provider/keycloak_api'))
 => true 
2.5.1 :002 > Puppet::Provider::KeycloakAPI.name_uuid('LDAP')
 => "bc7bc27f-39b8-5152-91c3-915d710fba35" 

puppet-module-keycloak's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

puppet-module-keycloak's Issues

Are the types in this module compatible with biemond/wildfly?

Hi

Just come across this module. I've been using biemond/wildfly to install keycloak. It works really well, and has lots of functionality for configuring the underlying wildfly server itself.

It doesn't have any types for configuring the keycloak application itself though. Do you think it should be possible for me to continue using biemond/wildfly, but use this module for configuring keycloak realms/clients etc?

Thanks.

Keycloak connection validator server address

Hey folks,

I want to run a standalone keycloak cluster with jdbc_ping. For this, the listen address has to be set explicitly, which causes the connection validation to fail.

A merge request for this is coming soon.

Best regards
Harm

Dependency error while installing Keycloak from scratch

Hi,
I'm trying to install and configure Keycloak using v3.3.0 of this module on a Centos7 host.

My manifest definition looks very similar to:

class { 'keycloak':
  version => '4.6.0.Final',
  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',
}

But I'm getting a dependency error:

Error: Could not set 'file' on ensure: No such file or directory @ dir_s_mkdir - /opt/keycloak-4.6.0.Final/bin/kcadm-wrapper.sh20190130-21238-1u9z6ck.lock at /mnt/puppetnfsdir/environments/dev_aaguadoc/modules/keycloak/manifests/config.pp:14
Error: Could not set 'file' on ensure: No such file or directory @ dir_s_mkdir - /opt/keycloak-4.6.0.Final/bin/kcadm-wrapper.sh20190130-21238-1u9z6ck.lock at /mnt/puppetnfsdir/environments/dev_aaguadoc/modules/keycloak/manifests/config.pp:14
Wrapped exception:
No such file or directory @ dir_s_mkdir - /opt/keycloak-4.6.0.Final/bin/kcadm-wrapper.sh20190130-21238-1u9z6ck.lock
Error: /Stage[main]/Keycloak::Config/File[kcadm-wrapper.sh]/ensure: change from absent to file failed: Could not set 'file' on ensure: No such file or directory @ dir_s_mkdir - /opt/keycloak-4.6.0.Final/bin/kcadm-wrapper.sh20190130-21238-1u9z6ck.lock at /mnt/puppetnfsdir/environments/dev_aaguadoc/modules/keycloak/manifests/config.pp:14
Error: Could not find command '/opt/keycloak-4.6.0.Final/bin/add-user-keycloak.sh'
Error: /Stage[main]/Keycloak::Config/Exec[create-keycloak-admin]/returns: change from notrun to 0 failed: Could not find command '/opt/keycloak-4.6.0.Final/bin/add-user-keycloak.sh'

We use Puppet v4.9.4 not sure if that might have something to do.
Thanks,
Daniel.

keycloak_flow: description is only applied to top level flows

The description attribute seems to be applied only to flows where top_level => true.

description is set:

keycloak_flow { 'browser-mfa on realm': 
  ensure      => 'present',
  description => 'A description',
}

description is empty:

keycloak_flow { 'sms under browser-mfa on realm': 
  ensure      => 'present',
  index       => 0,
  description => 'another description',
  requirement => 'ALTERNATIVE', 
  top_level   => false, 
}

Puppet module version: 7.11.0
Keycloak version: 15.0.2

The attribute 'login_with_email_allowed' has already been set

When creating a realm with 'login_with_email_allowed' set to true, an error is produced. This occurs no matter what is set on 'login_with_email_allowed' with the realm if it exists.

 Error: Error while evaluating a Resource Statement, Evaluation Error: The attribute 'login_with_email_allowed' has already been set

Keycloak connection validator server address

Hey folks,

I want to run a standalone Keycloak cluster with jdbc_ping. For this, the listen address has to be set explicitly, which causes the connection validation to fail.

A merge request for this is coming soon.

Best regards
Harm

parameter 'syslog_hostname' expects a Stdlib::Host [...] value, got String

Hi!

I upgraded the keycloak module and ran into an issue with the syslog_hostname variable
After a couple hours of searching I was unable to pin down the underlying issue so if you know anything I'd be super glad <3
Thanks in advance!

These are my installed packages:

/etc/puppetlabs/code/environments/production/modules
โ”œโ”€โ”€ abcdef (???)
โ”œโ”€โ”€ landcareresearch-solr (v7.0.1)
โ”œโ”€โ”€ puppet-archive (v4.6.0)
โ”œโ”€โ”€ puppet-systemd (v3.8.0)
โ”œโ”€โ”€ puppetlabs-accounts (v7.2.0)
โ”œโ”€โ”€ puppetlabs-apache (v7.0.0)
โ”œโ”€โ”€ puppetlabs-apt (v7.7.1)
โ”œโ”€โ”€ puppetlabs-augeas_core (v1.2.0)
โ”œโ”€โ”€ puppetlabs-concat (v6.4.0)
โ”œโ”€โ”€ puppetlabs-inifile (v4.4.0)
โ”œโ”€โ”€ puppetlabs-java (v7.3.0)
โ”œโ”€โ”€ puppetlabs-java_ks (v3.4.0)
โ”œโ”€โ”€ puppetlabs-mysql (v12.0.2)
โ”œโ”€โ”€ puppetlabs-ntp (v9.1.0)
โ”œโ”€โ”€ puppetlabs-postgresql (v8.0.0)
โ”œโ”€โ”€ puppetlabs-puppetserver_gem (v1.1.1)
โ”œโ”€โ”€ puppetlabs-resource_api (v1.1.0)
โ”œโ”€โ”€ puppetlabs-stdlib (v6.6.0)
โ”œโ”€โ”€ puppetlabs-translate (v2.2.0)
โ”œโ”€โ”€ puppetlabs-yumrepo_core (v1.1.0)
โ”œโ”€โ”€ abcdef (???)
โ”œโ”€โ”€ abcdef (???)
โ”œโ”€โ”€ treydock-keycloak (v7.19.0)
โ””โ”€โ”€ abcdef (???)

I am getting this error on my node:

Error:
Could not retrieve catalog from remote server:
Error 500 on SERVER:
Server Error:
Evaluation Error:
Error while evaluating a Resource Statement, Class[Keycloak]: parameter 'syslog_hostname' expects a Stdlib::Host = Variant[Stdlib::Fqdn = Pattern[/\A(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])\z/], Stdlib::Compat::Ip_address = Variant[Stdlib::Compat::Ipv4 = Pattern[/^((([0-9](?!\d)|[1-9][0-9](?!\d)|1[0-9]{2}(?!\d)|2[0-4][0-9](?!\d)|25[0-5](?!\d))[.]){3}([0-9](?!\d)|[1-9][0-9](?!\d)|1[0-9]{2}(?!\d)|2[0-4][0-9](?!\d)|25[0-5](?!\d)))(\/((([0-9](?!\d)|[1-9][0-9](?!\d)|1[0-9]{2}(?!\d)|2[0-4][0-9](?!\d)|25[0-5](?!\d))[.]){3}([0-9](?!\d)|[1-9][0-9](?!\d)|1[0-9]{2}(?!\d)|2[0-4][0-9](?!\d)|25[0-5](?!\d))|[0-9]+))?$/], Stdlib::Compat::Ipv6 = Pattern[/\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/]]] value, got String (file: /etc/puppetlabs/code/environments/production/site/profile/manifests/keycloak/etw.pp, line: 11, column: 3) on node abcd

The contents of /etc/puppetlabs/code/environments/production/site/profile/manifests/keycloak/etw.pp:

class profile::keycloak::etw {
  $redirect_uris = lookup('profile::keycloak::etw::redirect_uris', Array[String], 'unique', [])

  include mysql::server
  include apache

  class { 'apache::mod::proxy': }
  class { 'apache::mod::proxy_http': }
  class { 'apache::mod::headers': }

  class { 'keycloak':
    datasource_driver    => 'mysql',
    # we are using the url instead of host, port, dbname combo because we need to
    # append the useSSL=false parameter.
    # Without this parameter, keycloak tries establishing a ssl connection to the
    # database, which we do not have set up and then fails to start.
    datasource_url       => 'jdbc:mysql://localhost:3306/keycloak?useSSL=false',
    #datasource_host      => 'localhost',
    #datasource_port      => 3306,
    #datasource_dbname    => 'keycloak',
    datasource_username  => 'abcdefg',
    datasource_password  => 'abcdefg',

    service_bind_address => '127.0.0.1',
    http_port            => 18080,
    proxy_https          => true,

    admin_user_password  => 'abcdefg',
  }

  keycloak_realm { 'abcdefg':
    ensure                        => 'present',
    display_name                  => 'abcdefg',

    enabled                       => true,
    remember_me                   => true,
    verify_email                  => true,
    reset_password_allowed        => true,
    registration_allowed          => false,

    roles                         => [
      'manager_bs',
      'admin_bs',
      'user_bs',
      'uma_authorization',
      'offline_access',
    ],

    smtp_server_auth              => true,
    smtp_server_from              => 'abcdefg',
    smtp_server_host              => 'abcdefg',
    smtp_server_port              => 587,
    smtp_server_reply_to          => 'abcdefg',
    smtp_server_from_display_name => 'abcdefg',
    smtp_server_starttls          => true,
    smtp_server_user              => 'abcdefg',
    smtp_server_password          => 'abcdefg',
  }

  keycloak_client { 'abcdefg':
    ensure                 => 'present',
    realm                  => 'abcdefg',
    redirect_uris          => $redirect_uris,
    default_client_scopes  => [
      'email',
      'profile',
      'roles',
      'web-origins',
    ],
    optional_client_scopes => [
      'address',
      'microprofile-jwt',
      'offline_access',
      'phone',
    ],
    secret                 => '',
    public_client          => true,
  }
}

v9.3.3 relative_path parameter fix for keycloak_validator.rb does not work

Hello,

I'm following issue #277 (I cannot reopen it because I'm not the one who closed it, sorry) because I just tested the v9.3.3 but it doesn't seem to work properly.

Here's my Puppet code for Keycloak:

  class { 'keycloak':
    hostname           => $hostname,
    version            => $keycloak_version,
    proxy              => 'edge',
    http_relative_path => '/auth',
    db                 => 'mariadb',
    db_url_host        => $ip,
    db_url_port        => $dbport,
    db_url_database    => $db,
    db_username        => $user,
    db_password        => $password,
    manage_db_server   => false,
    manage_db          => false,
  }

And here is what happen on a perfectly fine Keycloak with this update:

# puppet agent -t
Info: Using environment 'dev'
Info: Retrieving pluginfacts
Notice: /File[/opt/puppetlabs/puppet/cache/facts.d]/mode: mode changed '0755' to '0775'
Info: Retrieving plugin
Notice: /File[/opt/puppetlabs/puppet/cache/lib/puppet/provider/keycloak_conn_validator/puppet_https.rb]/content: 
--- /opt/puppetlabs/puppet/cache/lib/puppet/provider/keycloak_conn_validator/puppet_https.rb	2023-03-01 16:12:10.467228387 +0000
+++ /tmp/puppet-file20230314-647290-idp47d	2023-03-14 10:22:59.520825710 +0000
@@ -67,6 +67,6 @@
   #
   # @api private
   def validator
-    @validator ||= Puppet::Util::KeycloakValidator.new(resource[:keycloak_server], resource[:keycloak_port], resource[:use_ssl], resource[:test_url])
+    @validator ||= Puppet::Util::KeycloakValidator.new(resource[:keycloak_server], resource[:keycloak_port], resource[:use_ssl], resource[:test_url], resource[:relative_path])
   end
 end

Notice: /File[/opt/puppetlabs/puppet/cache/lib/puppet/provider/keycloak_conn_validator/puppet_https.rb]/content: content changed '{sha256}5ebe05ce820c83e6b6eb7c086f7406c06895a800a04a5498f8844e5555036a0c' to '{sha256}52454705e50f8b664390111730797bf63d5f6c4ce5cb758e4715ff10a705e5d7'
Notice: /File[/opt/puppetlabs/puppet/cache/lib/puppet/type/keycloak_conn_validator.rb]/content: 
--- /opt/puppetlabs/puppet/cache/lib/puppet/type/keycloak_conn_validator.rb	2023-03-01 16:12:11.495317195 +0000
+++ /tmp/puppet-file20230314-647290-p6dro6	2023-03-14 10:22:59.640836101 +0000
@@ -32,7 +32,12 @@
 
   newparam(:test_url) do
     desc 'URL to use for testing if the Keycloak database is up'
-    defaultto '/auth/admin/serverinfo'
+    defaultto '/realms/master/.well-known/openid-configuration'
+  end
+
+  newparam(:relative_path) do
+    desc 'URL relative path that is used by Keycloak'
+    defaultto '/'
   end
 
   newparam(:timeout) do

Notice: /File[/opt/puppetlabs/puppet/cache/lib/puppet/type/keycloak_conn_validator.rb]/content: content changed '{sha256}db88c03dbb101abba3dd929f58f321f38f0e8017901211388f6e8b4a8b27be60' to '{sha256}e6f2000b23fc870289858d01852597f307c6643690ab2d3a51b4250e6ab929c0'
Notice: /File[/opt/puppetlabs/puppet/cache/lib/puppet/util/keycloak_validator.rb]/content: 
--- /opt/puppetlabs/puppet/cache/lib/puppet/util/keycloak_validator.rb	2023-03-01 16:12:12.239381469 +0000
+++ /tmp/puppet-file20230314-647290-ue43hy	2023-03-14 10:22:59.700841298 +0000
@@ -6,11 +6,12 @@
 class Puppet::Util::KeycloakValidator
   attr_reader :keycloak_server, :keycloak_port, :use_ssl, :test_path
 
-  def initialize(keycloak_server, keycloak_port, use_ssl = false, test_path = '/auth/admin/serverinfo')
+  def initialize(keycloak_server, keycloak_port, use_ssl = false, test_path = '/realms/master/.well-known/openid-configuration', relative_path = '/')
     @keycloak_server = keycloak_server
     @keycloak_port   = keycloak_port
     @use_ssl         = use_ssl
     @test_path       = test_path
+    @relative_path   = relative_path
   end
 
   # Utility method; attempts to make an http/https connection to the keycloak server.
@@ -22,10 +23,11 @@
     # All that we care about is that we are able to connect successfully via
     # http(s), so here we're simpling hitting a somewhat arbitrary low-impact URL
     # on the keycloak server.
+    path = "#{@relative_path}#{@test_path.sub(%r{^/}, '')}"
     http = Net::HTTP.new(@keycloak_server, @keycloak_port)
     http.use_ssl = @use_ssl
     http.verify_mode = OpenSSL::SSL::VERIFY_NONE
-    request = Net::HTTP::Get.new(@test_path)
+    request = Net::HTTP::Get.new(path)
     request.add_field('Accept', 'application/json')
     response = http.request(request)
 

Notice: /File[/opt/puppetlabs/puppet/cache/lib/puppet/util/keycloak_validator.rb]/content: content changed '{sha256}1f3d7b41bf59b48fb3e91adc15d687a3daa74562e5852b09cc13010e2605e941' to '{sha256}0c83932525ea28f1779c3872af6cf96feb4dc70ce415c60986b51c755fe2f077'
Info: Loading facts
Info: Caching catalog for <redacted>
Info: Applying configuration version '1678789388'
Notice: Unable to connect to keycloak server (http://localhost:8080): [404] Not Found
Notice: Failed to connect to keycloak; sleeping 5 seconds before retry
Notice: Unable to connect to keycloak server (http://localhost:8080): [404] Not Found
Notice: Failed to connect to keycloak; sleeping 5 seconds before retry
Notice: Unable to connect to keycloak server (http://localhost:8080): [404] Not Found
Notice: Failed to connect to keycloak; sleeping 5 seconds before retry
Notice: Unable to connect to keycloak server (http://localhost:8080): [404] Not Found
Notice: Failed to connect to keycloak; sleeping 5 seconds before retry
Notice: Unable to connect to keycloak server (http://localhost:8080): [404] Not Found
Notice: Failed to connect to keycloak; sleeping 5 seconds before retry
Notice: Unable to connect to keycloak server (http://localhost:8080): [404] Not Found
Notice: Failed to connect to keycloak; sleeping 5 seconds before retry
Notice: Unable to connect to keycloak server (http://localhost:8080): [404] Not Found
Notice: Failed to connect to keycloak; sleeping 5 seconds before retry
Notice: Unable to connect to keycloak server (http://localhost:8080): [404] Not Found
Notice: Failed to connect to keycloak; sleeping 5 seconds before retry
Notice: Unable to connect to keycloak server (http://localhost:8080): [404] Not Found
Notice: Failed to connect to keycloak; sleeping 5 seconds before retry
Notice: Unable to connect to keycloak server (http://localhost:8080): [404] Not Found
Notice: Failed to connect to keycloak; sleeping 5 seconds before retry
Notice: Unable to connect to keycloak server (http://localhost:8080): [404] Not Found
Notice: Failed to connect to keycloak; sleeping 5 seconds before retry
Notice: Unable to connect to keycloak server (http://localhost:8080): [404] Not Found
Notice: Failed to connect to keycloak; sleeping 5 seconds before retry
Notice: Unable to connect to keycloak server (http://localhost:8080): [404] Not Found
Notice: Failed to connect to keycloak within timeout window of 60 seconds; giving up.
Notice: Applied catalog in 64.72 seconds
Info: Loading facts
Info: Uploading facts for <redacted> to <redacted>

Do you have any clues?
Thanks,

Support for Debian 11

I've tested this module on Debian 11 with Keycloak 16.1.0 and it works with no issues. It would be great if we can list Debian 11 as supported by the module.

keycloak_ldap_mapper with user-attribute-ldap-mapper

I'm trying to remap first name attribute from 'cn' to 'firstName', but with no luck, puppet code looks like this:

    keycloak_ldap_mapper { "first name for LDAP-${realm_name} on ${realm_name}":
      ensure               => 'present',                     
      type                 => 'user-attribute-ldap-mapper',  
      resource_name        => 'first name',                  
      user_model_attribute => 'firstName',                   
      ldap_attribute       => 'givenName',                   
    }   

and json request like this:

{
  "providerId": "user-attribute-ldap-mapper",
  "providerType": "org.keycloak.storage.ldap.mappers.LDAPStorageMapper",
  "config": {
    "ldap.attribute": [
      "givenName"
    ],
    "is.mandatory.in.ldap": [
      "false"
    ],
    "write.only": [
      "false"
    ]
  }
}

As I looked into json request made by this function but with full-name-ldap-mapper type (as you've described in doc - and this is working), it seems like json is missing some variables.
Is it bug or I'm doing somethin wrong?

Hiding /auth part of URL behind reverse proxy fails Puppet run due to connectivity check

Hi,

thanks for this awesome module.
After switching to a reverse proxy to customize the Test URL we ran into an issue with the connectivity validator in init.pp and the kcadm-wrapper.sh.erb. I had to remove the auth part of the test_url to work for this case.
Is it possible for you to default the test_url thats being checked for connectivity to current value and make it a variable to be customizable?

Thanks alot!

Mathias Bachhuber

keycloak_ldap_mapper requires multiple runs for multiple realms

Puppet module version: 7.11.0
Keycloak version: 15.0.2

Requirements:

  • Create two realms (via keycloak_realm)
  • On each realm: configure LDAP as user provider (via keycloak_ldap_user_provider)
  • On each LDAP user provider: remove an automatically generated ldap mapper attribute: first name (via keycloak_ldap_mapper)

I noticed that two Puppet runs are required to get to the desired state (starting afresh).

In the first run:

  • Both realms are created
  • Both user provider are configured
  • The first ldap mapper attribute first name is removed

In the second run:

  • The second ldap mapper attribute first name is removed

This is the code to remove the first name LDAP attribute mapper for both realms:

  keycloak_ldap_mapper { 'remove first name from realm one':
    ensure        => 'absent',
    name          => 'first name one',
    resource_name => 'first name',
    realm         => 'one',
    ldap          => 'ldap-one',
    require       => Keycloak_Ldap_User_Provider['LDAP one ...'],
  }

  keycloak_ldap_mapper { 'remove first name from realm two':
    ensure        => 'absent',
    name          => 'first name two',
    resource_name => 'first name',
    realm         => 'two',
    ldap          => 'ldap-two',
    require       => Keycloak_Ldap_User_Provider['LDAP two ...'],
  }

Do I miss something obvious here?

quoting for datasource_password

in config.cli, datasource_password is not quoted (like datasource url connection-url, i.e.)

please properly quote passwords, otherwise no special characters are able to be used.
(workaround: manually quote passwords in puppet. i.e.:

...
# TODO: fix manual quoting: "" required inside of ''
datasource_password   => '"some;)special$characters|"'
...

KC 19: WARNING: The '--auto-build' option for 'start' command is DEPRECATED

This warning is printed on start when the image is built afresh on Keycloak 19:

WARNING: The '--auto-build' option for 'start' command is DEPRECATED and no longer needed. When executing the 'start' command, a new server image is automatically built based on the configuration. If you want to disable this behavior and achieve an optimal startup time, use the '--optimized' option instead.

The release notes explain the reason behind this change: https://www.keycloak.org/2022/07/keycloak-1900-released

Question about support for MySQL8

Hi,

I'm playing around with Keycloak on MySQL8. I followed this blogpost https://pedrohosilva.wordpress.com/2019/08/11/04-configurando-banco-de-dados-mysql/ and I can confirm that it works.

Now, I'm trying to puppetize it but it did not work straight away.

I provided the module with a custom datasource_jar_source pointing it to the new mysql-connector-java-8.0.XX.jar, but the service won't start.

After some investigation, I realized that this is the line that breaks it https://github.com/treydock/puppet-module-keycloak/blob/master/templates/config.cli.erb#L28

If I manually delete it from the standalone file, and restart the service, keycloak service starts OK

I don't understand very well the logic behind it.

if (outcome != success) ....

Does the outcome always != success in my case?
Is there a simple way I can avoid that line being added to the standalone file?

Thanks a lot,
Daniel.

Dependency issue in Gemfile

While working on #127 I noticed that there is a dependency conflict:

$ bundle install --path vendor/bundle
Ignoring unf_ext-0.0.7.6 because its extensions are not built. Try: gem pristine unf_ext --version 0.0.7.6
The dependency rb-readline (= 0.5.5) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mswin32, x86-mingw32, x64-mingw32. To add those platforms to the bundle, run `bundle lock --add-platform x86-mswin32 x86-mingw32 x64-mingw32`.
The dependency puppet-module-win-default-r2.6 (~> 0.3) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mswin32, x86-mingw32, x64-mingw32. To add those platforms to the bundle, run `bundle lock --add-platform x86-mswin32 x86-mingw32 x64-mingw32`.
The dependency puppet-module-win-dev-r2.6 (~> 0.3) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mswin32, x86-mingw32, x64-mingw32. To add those platforms to the bundle, run `bundle lock --add-platform x86-mswin32 x86-mingw32 x64-mingw32`.
The dependency puppet-module-win-system-r2.6 (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mswin32, x86-mingw32, x64-mingw32. To add those platforms to the bundle, run `bundle lock --add-platform x86-mswin32 x86-mingw32 x64-mingw32`.
NOTE: Gem::Specification#default_executable= is deprecated with no replacement. It will be removed on or after 2018-12-01.
Gem::Specification#default_executable= called from /home/samuli/opt/puppet/puppet-module-keycloak/vendor/bundle/ruby/2.6.0/bundler/gems/github-changelog-generator-20ee04ba1234/github_changelog_generator.gemspec:10.
Fetching gem metadata from https://rubygems.org/.......
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies...
Bundler could not find compatible versions for gem "fast_gettext":
  In snapshot (Gemfile.lock):
    fast_gettext (= 1.8.0)

  In Gemfile:
    fast_gettext

    gettext-setup (~> 0.26) was resolved to 0.34, which depends on
      fast_gettext (~> 1.1.0)

Running `bundle update` will rebuild your snapshot from scratch, using only
the gems in your Gemfile, which may resolve the conflict.

Any clue how to resolve this without breaking something else?

Realms with spaces in the name fail to be fully created

When creating realms that have a space in the name such as "My Realm", errors happen on puppet runs.

First run you may see this:

Error: Could not prefetch keycloak_realm provider 'kcadm': Execution of '/opt/keycloak/bin/kcadm-wrapper.sh get events/config -r My Realm' returned 1:

Next run may show this:

Error: Execution of '/opt/keycloak/bin/kcadm-wrapper.sh get roles -r My Realm' returned 1:
Error: /Stage[main]/Profile::Keycloak::Master/Keycloak_realm[My Realm]/ensure: change from 'absent' to 'present' failed: Execution of '/opt/keycloak/bin/kcadm-wrapper.sh get roles -r My Realm' returned 1:  (corrective)

Support for more/custom keycloak_ldap_mapper types?

Currently, the list of supported types for the keycloak_ldap_mapper is hardcoded to:

  • user-attribute-ldap-mapper
  • full-name-ldap-mapper
  • group-ldap-mapper
  • role-ldap-mapper

In Keycloak 15.0.2 the following LDAP mappers (for AD) are available:

  • msad-user-account-control-mapper
  • group-ldap-mapper
  • role-ldap-mapper
  • hardcoded-attribute-mapper
  • hardcoded-ldap-role-mapper
  • msad-lds-user-account-control-mapper
  • user-attribute-ldap-mapper
  • certificate-ldap-mapper
  • full-name-ldap-mapper
  • hardcoded-ldap-group-mapper
  • hardcoded-ldap-attribute-mapper

In addition to the built-in LDAP mappers one can add custom ones with their own ID. Do you see a way to support custom ldap mappers in the module?

Puppet module version: 7.12.0
Keycloak version: 15.0.2

Missing usermodel_clientRoleMapping_clientId property from keycloak_client_protocol_mapper resource type

Missing usermodel_clientRoleMapping_clientId property from keycloak_client_protocol_mapper resource type

First off, thanks for this module, it has helped a lot ๐Ÿ™
I found myself in need for a client role mapper and using oidc-usermodel-client-role-mapper works fine except I can't seem to find a way to specify what client my roles should come from in this module. Hence, I think I need a usermodel_clientRoleMapping_clientId on the keycloak_client_protocol_mapper resource type. Without it I seem to map the realm roles. But I want to only map a specific clients roles in my mapper.

On the web there is a way to set this client's Id here:
image

And when I do so, on the payload that gets sent to the REST API I see usermodel.clientRoleMapping.clientId: "client-id-name-here"

The reason I suggest usermodel_clientRoleMapping_clientId is that on the payload I can see properties like userinfo.token.claim being translated to userinfo_token_claim and the like.

What do you think? Is this something that should be added to the resource type or have I overlooked some other way of achieving this?

Prettify resulting xml files

When working with the module, something like 'xmllint --format' would make it easier to follow the changes in xml files. This is especially so with augeas edits, where formatting is frequently ugly.

A change for user_object_classes is detected on each run

Puppet module version: 7.11.0
Keycloak version: 15.0.2

It seems that the change detection for user_object_classes on keycloak_ldap_user_provider is not working. For the following snippet, a change is detected on each Puppet run:

  keycloak_ldap_user_provider { 'LDAP name on development':
    ensure              => 'present',
    resource_name       => 'name',
    user_object_classes => ['person, organizationalPerson, user'],
    ....

The realm settings in the GUI shows: User Object Classes: person, organizationalPerson, user

Logs:

โ€ฆ
Warning: Parameter 'bind_credential' is set and Puppet has no way to check current value
Notice: /Stage[main]/Role::Keycloakapp/Keycloak_ldap_user_provider[LDAP name on development]/user_object_classes: user_object_classes changed person, organizationalPerson, user to person, organizationalPerson, user (corrective)             
โ€ฆ
``

Adding extra service_java_opts without having $JAVA_OPTS impossible

I was trying to pass some extra service_java_opts to the systemd service file.
The values are placed correctly, but keycloak fails to start.

class { '::keycloak':
   ...
   service_java_opts     => "-Xmx${heapsize}m -Xms${heapsize}m -XX:+UseG1GC",
   ...
}

This results in Environment="JAVA_OPTS=$JAVA_OPTS -Xmx595m -Xms595m -XX:+UseG1GC".
I nowhere have the $JAVA_OPTS defined as environment variable, so the startup of keycloak fails with

Dec 17 11:19:38 keycloak2.vito standalone.sh[12569]: ==========================================================...====
Dec 17 11:19:38 keycloak2.vito standalone.sh[12569]: JBoss Bootstrap Environment
Dec 17 11:19:38 keycloak2.vito standalone.sh[12569]: JBOSS_HOME: /opt/keycloak-7.0.1
Dec 17 11:19:38 keycloak2.vito standalone.sh[12569]: JAVA: java
Dec 17 11:19:38 keycloak2.vito standalone.sh[12569]: JAVA_OPTS:  -server $JAVA_OPTS -Xmx595m -Xms595m -XX:+UseG1GC
Dec 17 11:19:38 keycloak2.vito standalone.sh[12569]: ==========================================================...====
Dec 17 11:19:38 keycloak2.vito standalone.sh[12569]: Error: Could not find or load main class $JAVA_OPTS

I don't think the concat (mentioned in #51) is a good idea. The $JAVA_OPTS can never be set by the EnvironmentFile as these values are only used in the ExecStart.

Adding Vagrant VMs for clustered domain mode?

We're working on a Vagrant development environment for Keycloak's clustered domain mode. Right now our code is in a private repository. It consists of

  • Two Keycloak instances where one is configured as the domain controller
  • Shared database instance
  • Load balancer (haproxy) instance

Would you be interested in merging our clustered domain mode Vagrant environment to this project as well?

Support for "genreic" properties in types

Hi,

first of all thank you for this great module. We are already using it to do a general setup of keycloak. We are now planning to use this module to fully configure realms and clients, which we did through the UI so far. Unfortunately we are missing several properties while configuring realms and haven't looked into clients yet.

As an example, following properties are not available within the realm type (but many more available within keycloak that are missing in the module)

  • sslRequired
  • editUsernameAllowed
  • registrationAllowed

Would it be a feasible solution to allow "custom" properties where you can just add whatever you want kcadm to use as the key part while doing the set? Or would your prefer to define all valid properties within the corresponding type? Or are we missing some option that already allows this?

Thanks in advance

Turn warnings about smtp_server_password into notices

When setting smtp_server_password for a realm, there is a warning being printed to stderr:
Warning: Property 'smtp_server_password' is set and Puppet has no way to check current value
As I understand the code and the discussions in #131 this was done since the keycloak only returns a redacted string of ***'s when checking the current value. So I would assume that the new password value is always being set on each apply.

The issue is that this is being displayed as a warning via stderr rather than a notice. My intended workflow is that I run puppet apply standalone as a cron job once per hour and send an email if anything gets printed to stderr, so this creates quite a lot of noise for something that I can't seem to do anything about.

I would regard this belongs more as a notice than a warning since it's merely informing us that the password value was set, similar to the notices when other resources have been updated with new values.

It looks like the same pattern is used for keycloak_ldap_user_provider and keycloak_identity_provider also, I would imagine the same reasoning could be used there.

Also, thanks for the great work on this module!

Support for partialImport?

First of all, thanks for your module and the effort you put into it!

I was looking for a way to manage groups in Keycloak via Puppet, in particular the creation of groups and the role mappings for a group. This is currently not implemented in the module. Looking further, I discovered the JSON import feature of Keycloak that allows to import various settings from a JSON file. This is also support by kcadm.sh (docs):

./bin/kcadm.sh create partialImport -r myrealm -s ifResourceExists=SKIP -o -f ~/mysettings.json 

where mysettings.json might look something like this:

{
  "id": "myrealm",
  "groups": [
    {
      "name": "group1",
      "path": "/group1",
      "attributes": {},
      "realmRoles": [
        "role1"
      ],
      "clientRoles": {},
      "subGroups": []
    },
    {
      "name": "group2",
      "path": "/group2",
      "attributes": {},
      "realmRoles": [],
      "clientRoles": {},
      "subGroups": []
    }
  ]
}

Do you consider the support for partialImport as valuable addition to the module? It would allow to bridge the gap between native support for various features in the module and Keycloak's full featureset.

Puppet module version: 7.12.0
Keycloak version: 15.0.2

ID for Providers cannot exceed 36 characters

Hey,

I stumbled across this whilst deploying out Keycloak . When defining your keycloak_ldap_user_provider, or keycloak::freeipa_user_provider, if your {provider-name}-{realm} ends up being longer than 36 characters (standard UUIDv4 length), then in Keycloak version 15.0.2, it gives an error similar to the one below.

value too long for type character varying(36)

I totally get why this can occur, as the ID can be manually POST'ed to Keycloak for the purposes of tracking it later on. Possibly might need to re-think or adjust the ID to be less or equal to those number of characters, or move to a different way of tracking providers and letting the UUID self-populate.

Ideally a good solution might be to have a UUIDv4 value be deterministically generated so it can still be tracked?

Upgrading Keycloak does not execute migration scripts

Hi,

I just upgraded keycloak via changing the version number parameter in the module. Everything went fine but after some time running the new version, I started seeing some errors in the keycloak logs.

I'm afraid the migration scripts[1] are not run when the new version is installed.

To solve these issues, I manually ran:

/opt/keycloak-$KEYCLOAK_NEW_VERSION.Final/bin/jboss-cli.sh --file=/opt/keycloak-$KEYCLOAK_NEW_VERSION.Final/bin/migrate-standalone.cli

and:

[root@keycloak-dev-b11941f37c ~]# /opt/keycloak-$KEYCLOAK_NEW_VERSION/bin/jboss-cli.sh
You are disconnected at the moment. Type 'connect' to connect to the server or 'help' for the list of supported commands.
[disconnected /] connect
[standalone@localhost:9990 /] /subsystem=keycloak-server/spi=connectionsJpa/provider=default/:map-put(name=properties,key=migrationStrategy,value=update)
{
    "outcome" => "success",
    "response-headers" => {
        "operation-requires-reload" => true,
        "process-state" => "reload-required"
    }
}

[standalone@localhost:9990 /] q

Do you think there is a way we can integrate this in the module?
Maybe executing them for every installation (even when we install from scratch)?

Let's discuss about it. I can help you out with the MR.
Thanks,
Daniel.

[1] https://www.keycloak.org/docs/latest/upgrading/index.html

Allow keycloak.v2 theme on defined realms

Currently on defined realms it is not possible to use the keycloak.v2 theme.
Puppet automatically sets the themes to keycloak when no theme is set in the puppet realm definition. When trying to use a builtin theme the following error occurs:

Notice: /Stage[main]/Profile::Sso/Keycloak_realm[MyRealm]/account_theme: account_theme changed 'keycloak' to 'keycloak.v2'
Notice: /Stage[main]/Profile::Sso/Keycloak_realm[MyRealm]/admin_theme: admin_theme changed 'keycloak' to 'keycloak.v2'
Warning: Keycloak_realm[MyRealm]: Theme keycloak.v2 not found at path /srv/keycloak/keycloak-19.0.3/themes/keycloak.v2.
Warning: Keycloak_realm[MyRealm]: Theme keycloak.v2 not found at path /srv/keycloak/keycloak-19.0.3/themes/keycloak.v2.

Custom `java_home` not actually used on RHEL-based distros

Hey everyone, thanks for the cool project! It's working great so far, however I have an issue with the Java support in it.
When using the java class from puppet and passing the java_home property, all it does is write it to /etc/environment, which isn't read by systemd services. Using the java_alternative property makes it work, but that change is globally and could affect other services as well.

I would propose adding the JAVA_HOME env var to the systemd service similarly to the JAVA_OPTS, so the service is picking it up correctly.

Also maybe it would make sense to add a manage_jdk flag to let the user configure the Java setup somewhere else?
WDYT?

http_relative_path parameter is not taken into account in keycloak_validator.rb

Hi,

Since Keycloak Quarkus releases, they removed the context-path /auth accordingly to their Release Announcement, causing a change into URL users and apps are using.

We have a lot of Kubernetes clusters using OIDC with Keycloak that have the /auth URL into their configurations, in the client side (~/.kube/config), server side (/etc/kubernetes/manifests/kube-apiserver), and SSO Side (Google Cloud Console) and do not want to move from that path to avoid any changes (at least, in the client side to not disrupt users).

So I used the http_relative_path of this Puppet module, accordingly to what Keycloak Documentation said about this parameter. The parameter itself works as intended, but lib/puppet/util/keycloak_validator.rb is not taking into account this parameter with its check, leading to this at every Puppet Agent run, even if all is working great actually:

Notice: Unable to connect to keycloak server (http://localhost:8080): [404] Not Found
Notice: Failed to connect to keycloak; sleeping 5 seconds before retry
Notice: Unable to connect to keycloak server (http://localhost:8080): [404] Not Found
Notice: Failed to connect to keycloak; sleeping 5 seconds before retry
Notice: Unable to connect to keycloak server (http://localhost:8080): [404] Not Found
Notice: Failed to connect to keycloak; sleeping 5 seconds before retry
Notice: Unable to connect to keycloak server (http://localhost:8080): [404] Not Found
Notice: Failed to connect to keycloak; sleeping 5 seconds before retry
Notice: Unable to connect to keycloak server (http://localhost:8080): [404] Not Found
Notice: Failed to connect to keycloak; sleeping 5 seconds before retry
Notice: Unable to connect to keycloak server (http://localhost:8080): [404] Not Found
Notice: Failed to connect to keycloak; sleeping 5 seconds before retry
Notice: Unable to connect to keycloak server (http://localhost:8080): [404] Not Found
Notice: Failed to connect to keycloak; sleeping 5 seconds before retry
Notice: Unable to connect to keycloak server (http://localhost:8080): [404] Not Found
Notice: Failed to connect to keycloak; sleeping 5 seconds before retry
Notice: Unable to connect to keycloak server (http://localhost:8080): [404] Not Found
Notice: Failed to connect to keycloak; sleeping 5 seconds before retry
Notice: Unable to connect to keycloak server (http://localhost:8080): [404] Not Found
Notice: Failed to connect to keycloak; sleeping 5 seconds before retry
Notice: Unable to connect to keycloak server (http://localhost:8080): [404] Not Found
Notice: Failed to connect to keycloak; sleeping 5 seconds before retry
Notice: Unable to connect to keycloak server (http://localhost:8080): [404] Not Found
Notice: Failed to connect to keycloak; sleeping 5 seconds before retry
Notice: Unable to connect to keycloak server (http://localhost:8080): [404] Not Found
Notice: Failed to connect to keycloak within timeout window of 60 seconds; giving up.
Notice: Applied catalog in 64.87 seconds

In my case, as I configured http_relative_path => '/auth', it should check http://localhost:8080/auth/.

Regards, and thanks for this module!

Support customUserSearchFilter

@matsadolfsson is customUserSearchFilter part of the LDAP user provider and if so do you have any examples of what that looks like? Everything in the config hash for API objects is pretty much undocumented.

DB Encoding Issue on Ubunutu 20.04

When Installing Keycloak using the the 9.4.0 module version (and the 9.3x versions):

Error: Error executing SQL; psql returned pid 3864291 exit 1: 'ERROR:  encoding "UTF8" does not match locale "en_US"
DETAIL:  The chosen LC_CTYPE setting requires encoding "LATIN1".
'
Error: /Stage[main]/Keycloak::Db::Postgres/Postgresql::Server::Db[keycloak]/Postgresql::Server::Database[keycloak]/Postgresql_psql[CREATE DATABASE "keycloak"]/command: change from 'notrun' to 'CREATE DATABASE "keycloak" WITH TEMPLATE = "template0" ENCODING = \'UTF8\'  ' failed: Error executing SQL; psql returned pid 3864291 exit 1: 'ERROR:  encoding "UTF8" does not match locale "en_US"
DETAIL:  The chosen LC_CTYPE setting requires encoding "LATIN1".
'

Either Keycloak or Postgres wants to use the incorrect encoding.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.