+
+
+

Welcome to Keycloak Collection documentation

+
+

Pick collection version:

+
    diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..31502f3 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,170 @@ +# -*- coding: utf-8 -*- +# +# Configuration file for the Sphinx documentation builder. +# +# This file does only contain a selection of the most common options. For a +# full list see the documentation: +# http://www.sphinx-doc.org/en/master/config + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import datetime +import os +import sys +sys.path.insert(0, os.path.abspath('../plugins/module_utils/')) +# sys.path.insert(0, os.path.abspath('.')) + +# -- Project information ----------------------------------------------------- + +project = 'Keycloak Ansible Collection' +copyright = '{y}, Red Hat, Inc.'.format(y=datetime.date.today().year) +author = 'Red Hat, Inc.' + +# The short X.Y version +version = '' +# The full version, including alpha/beta/rc tags +release = '' + + +# -- General configuration --------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'myst_parser', + 'sphinx.ext.autodoc', + 'sphinx.ext.intersphinx', + 'ansible_basic_sphinx_ext', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = ['.rst', '.md'] + +# The master toctree document. +master_doc = 'index' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path . +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', '.tmp'] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +highlight_language = 'YAML+Jinja' + +# -- Options for HTML output ------------------------------------------------- +html_theme_path = ['_themes'] +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +# html_theme = 'alabaster' +html_theme = 'sphinx_rtd_theme' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = [] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# The default sidebars (for documents that don't match any pattern) are +# defined by theme itself. Builtin themes are using these templates by +# default: ``['localtoc.html', 'relations.html', 'sourcelink.html', +# 'searchbox.html']``. +# +# html_sidebars = {} + + +# -- Options for HTMLHelp output --------------------------------------------- + +# Output file base name for HTML help builder. +htmlhelp_basename = 'KeycloakCollectionDoc' + + +# -- Options for LaTeX output ------------------------------------------------ + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'KeycloakCollection.tex', 'Red Hat Single Sign-On Ansible Collection Documentation', + 'Red Hat, Inc.', 'manual'), +] + + +# -- Options for manual page output ------------------------------------------ + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'keycloakcollection', 'Red Hat Single Sign-On Ansible Collection Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ---------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'KeycloakCollection', 'Red Hat Single Sign-On Ansible Collection Documentation', + author, 'KeycloakCollection', 'One line description of project.', + 'Miscellaneous'), +] + + +# -- Extension configuration ------------------------------------------------- + +# -- Options for intersphinx extension --------------------------------------- + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = {'python': ('https://docs.python.org/2', None), 'ansible': ('https://docs.ansible.com/ansible/latest/', None)} diff --git a/docs/developing.md b/docs/developing.md new file mode 120000 index 0000000..44fcc63 --- /dev/null +++ b/docs/developing.md @@ -0,0 +1 @@ +../CONTRIBUTING.md \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..dc5034f --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,32 @@ +.. Red Hat middleware_automation Keycloak Ansible Collection documentation main file + +Welcome to Keycloak Collection documentation +============================================ + +.. toctree:: + :maxdepth: 2 + :caption: User documentation + + README + plugins/index + roles/index + +.. toctree:: + :maxdepth: 2 + :caption: Developer documentation + + developing + testing + releasing + +.. toctree:: + :maxdepth: 2 + :caption: General + + Changelog + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`search` diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..72a7d48 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,5 @@ +antsibull>=0.17.0 +ansible-base>=2.10.12 +sphinx-rtd-theme +git+https://github.com/felixfontein/ansible-basic-sphinx-ext +myst-parser diff --git a/docs/roles.rst.template b/docs/roles.rst.template new file mode 100644 index 0000000..b025af6 --- /dev/null +++ b/docs/roles.rst.template @@ -0,0 +1,3 @@ +Role Index +========== + diff --git a/galaxy.yml b/galaxy.yml index bc17757..0fe0c42 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -22,6 +22,6 @@ dependencies: "middleware_automation.redhat_csp_download": ">=1.2.1" "middleware_automation.wildfly": ">=0.0.6" repository: https://github.com/ansible-middleware/keycloak -documentation: https://github.com/ansible-middleware/keycloak +documentation: https://ansible-middleware.github.io/keycloak homepage: https://github.com/ansible-middleware/keycloak issues: https://github.com/ansible-middleware/keycloak/issues diff --git a/roles/keycloak/meta/main.yml b/roles/keycloak/meta/main.yml index 8729169..ed05acb 100644 --- a/roles/keycloak/meta/main.yml +++ b/roles/keycloak/meta/main.yml @@ -6,7 +6,7 @@ collections: galaxy_info: role_name: keycloak namespace: middleware_automation - author: Romain Pelisse, Guido Grazioli + author: Romain Pelisse, Guido Grazioli, Pavan Kumar Motaparthi description: Install keycloak or Red Hat Single Sing-On server configurations company: Red Hat, Inc. @@ -17,7 +17,6 @@ galaxy_info: platforms: - name: EL versions: - - 7 - 8 galaxy_tags: diff --git a/roles/keycloak_realm/meta/main.yml b/roles/keycloak_realm/meta/main.yml index 441ccd8..04dff8a 100644 --- a/roles/keycloak_realm/meta/main.yml +++ b/roles/keycloak_realm/meta/main.yml @@ -13,7 +13,6 @@ galaxy_info: platforms: - name: EL versions: - - 7 - 8 galaxy_tags: From 78f225b10c54dcdc9d363d74324edfa5eabc7eab Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 1 Mar 2022 10:46:06 +0100 Subject: [PATCH 012/554] chore: reword collection tags not accepted by galaxy --- galaxy.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/galaxy.yml b/galaxy.yml index 0fe0c42..d3589a3 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,6 +1,6 @@ namespace: middleware_automation name: keycloak -version: "0.2.5" +version: "0.2.6" readme: README.md authors: - Romain Pelisse @@ -12,9 +12,10 @@ tags: - keycloak - redhat - rhel - - rhn - sso - - single sign-on + - openid + - application + - identity - security - infrastructure - authentication From 2073c90e1db94186711f036a189761c3d2ee3bd2 Mon Sep 17 00:00:00 2001 From: Harsha Cherukuri Date: Tue, 1 Mar 2022 12:02:15 -0500 Subject: [PATCH 013/554] Bump version to 1.0.0 to statisfy Automation hub --- README.md | 3 +++ galaxy.yml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 93d7a98..9006532 100644 --- a/README.md +++ b/README.md @@ -156,6 +156,9 @@ ansible-playbook -i playbooks/keycloak_realm.yml -e keycloak_adm For full configuration details, refer to the [keycloak_realm role README](roles/keycloak_realm/README.md). +## Support + +Keycloak collection v1.0.0 is a Beta release and for [Technical Preview](https://access.redhat.com/support/offerings/techpreview). If you have any issues or questions related to collection, please don't hesitate to contact us on Ansible-middleware-core@redhat.com or open an issue on https://github.com/ansible-middleware/keycloak/issues ## License diff --git a/galaxy.yml b/galaxy.yml index d3589a3..f026867 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,6 +1,6 @@ namespace: middleware_automation name: keycloak -version: "0.2.6" +version: "1.0.0" readme: README.md authors: - Romain Pelisse From 0bc81cc78140110b966dc17ca598d7497173135b Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 1 Mar 2022 19:05:28 +0100 Subject: [PATCH 014/554] chore: add build ignores / fix release tag names --- .github/workflows/docs.yml | 2 +- .github/workflows/release.yml | 6 +++--- galaxy.yml | 5 +++++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 2e303d6..c55a637 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -5,7 +5,7 @@ on: branches: - main tags: - - "*.*.*" + - "[0-9]+.[0-9]+.[0-9]+" env: COLORTERM: 'yes' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cafc1eb..820289d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,9 +1,9 @@ +--- name: Release collection - on: push: tags: - - "*.*.*" + - "[0-9]+.[0-9]+.[0-9]+" jobs: release: @@ -31,7 +31,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: files: "*.tar.gz" - body: "Release ${{ steps.get_version.outputs.TAG_VERSION }}" + body: "Release v${{ steps.get_version.outputs.TAG_VERSION }}" - name: Publish collection env: ANSIBLE_GALAXY_API_KEY: ${{ secrets.ANSIBLE_GALAXY_API_KEY }} diff --git a/galaxy.yml b/galaxy.yml index f026867..3d7900e 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,3 +1,4 @@ +--- namespace: middleware_automation name: keycloak version: "1.0.0" @@ -26,3 +27,7 @@ repository: https://github.com/ansible-middleware/keycloak documentation: https://ansible-middleware.github.io/keycloak homepage: https://github.com/ansible-middleware/keycloak issues: https://github.com/ansible-middleware/keycloak/issues +build_ignore: + - molecule + - docs + - .github From b88c43933c16ea515ce2087f2730dc56151589a8 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 8 Mar 2022 12:08:40 +0100 Subject: [PATCH 015/554] Replace use of serial with run_once run_once on first node when database config enabled (so the first node creates the tables), then wakeup all other nodes --- roles/keycloak/tasks/main.yml | 4 +-- roles/keycloak/tasks/start_keycloak.yml | 15 ++++++++++ roles/keycloak/tasks/systemd.yml | 29 +++++++------------ .../templates/standalone-infinispan.xml.j2 | 3 +- roles/keycloak/templates/standalone.xml.j2 | 3 +- 5 files changed, 30 insertions(+), 24 deletions(-) create mode 100644 roles/keycloak/tasks/start_keycloak.yml diff --git a/roles/keycloak/tasks/main.yml b/roles/keycloak/tasks/main.yml index ba8185f..7ed5efe 100644 --- a/roles/keycloak/tasks/main.yml +++ b/roles/keycloak/tasks/main.yml @@ -7,10 +7,10 @@ - prereqs - name: Include install tasks - ansible.builtin.include_tasks: tasks/install.yml + ansible.builtin.include_tasks: install.yml - name: Include systemd tasks - ansible.builtin.include_tasks: tasks/systemd.yml + ansible.builtin.include_tasks: systemd.yml - name: Link default logs directory ansible.builtin.file: diff --git a/roles/keycloak/tasks/start_keycloak.yml b/roles/keycloak/tasks/start_keycloak.yml new file mode 100644 index 0000000..b3c34f9 --- /dev/null +++ b/roles/keycloak/tasks/start_keycloak.yml @@ -0,0 +1,15 @@ +--- +- name: start keycloak + ansible.builtin.systemd: + name: keycloak + enabled: yes + state: started + become: yes + +- name: "Wait until Keycloak becomes active {{ keycloak.health_url }}" + ansible.builtin.uri: + url: "{{ keycloak.health_url }}" + register: keycloak_status + until: keycloak_status.status == 200 + retries: 25 + delay: 10 \ No newline at end of file diff --git a/roles/keycloak/tasks/systemd.yml b/roles/keycloak/tasks/systemd.yml index eff55cc..de643af 100644 --- a/roles/keycloak/tasks/systemd.yml +++ b/roles/keycloak/tasks/systemd.yml @@ -1,4 +1,4 @@ -- name: configure keycloak service script wrapper +- name: Configure keycloak service script wrapper become: yes ansible.builtin.template: src: keycloak-service.sh.j2 @@ -9,7 +9,7 @@ notify: - restart keycloak -- name: configure sysconfig file for keycloak service +- name: Configure sysconfig file for keycloak service become: yes ansible.builtin.template: src: keycloak-sysconfig.j2 @@ -20,7 +20,7 @@ notify: - restart keycloak -- name: configure systemd unit file for keycloak service +- name: Configure systemd unit file for keycloak service ansible.builtin.template: src: keycloak.service.j2 dest: /etc/systemd/system/keycloak.service @@ -32,18 +32,19 @@ notify: - restart keycloak -- name: reload systemd +- name: Reload systemd become: yes ansible.builtin.systemd: daemon_reload: yes when: systemdunit.changed -- name: start keycloak - ansible.builtin.systemd: - name: keycloak - enabled: yes - state: started - become: yes +- name: Start and wait for keycloak service (first node db) + ansible.builtin.include_tasks: start_keycloak.yml + run_once: yes + when: keycloak_db_enabled + +- name: Start and wait for keycloak service (remaining nodes) + ansible.builtin.include_tasks: start_keycloak.yml - name: Check service status ansible.builtin.command: "systemctl status keycloak" @@ -58,11 +59,3 @@ - name: Flush handlers ansible.builtin.meta: flush_handlers - -- name: "Wait until Keycloak becomes active {{ keycloak.health_url }}" - ansible.builtin.uri: - url: "{{ keycloak.health_url }}" - register: keycloak_status - until: keycloak_status.status == 200 - retries: 25 - delay: 10 diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index 1097047..544638e 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -633,7 +633,7 @@ {% if keycloak_modcluster.enabled %} - + @@ -744,7 +744,6 @@ - diff --git a/roles/keycloak/templates/standalone.xml.j2 b/roles/keycloak/templates/standalone.xml.j2 index 5b57e09..3207ef9 100644 --- a/roles/keycloak/templates/standalone.xml.j2 +++ b/roles/keycloak/templates/standalone.xml.j2 @@ -546,7 +546,7 @@ {% if keycloak_modcluster.enabled %} - + @@ -644,7 +644,6 @@ - From 707d8cfb11fff4fb63ffd7d95412dd80a022b4eb Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 8 Mar 2022 13:57:06 +0100 Subject: [PATCH 016/554] add rhsso_cli tasks, change shape of rhsso_rhn_ids --- roles/keycloak/README.md | 3 ++- roles/keycloak/defaults/main.yml | 3 ++- roles/keycloak/meta/argument_specs.yml | 7 ++++++- roles/keycloak/tasks/rhsso_cli.yml | 20 ++++++++++++++++++++ roles/keycloak/vars/main.yml | 7 +++++-- 5 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 roles/keycloak/tasks/rhsso_cli.yml diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index 60c183a..1ab0aba 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -68,6 +68,7 @@ Role Defaults |`keycloak_rhsso_download_url`| Download URL for RHSSO | `https://access.redhat.com/jbossnetwork/restricted/softwareDownload.html?softwareId=`| |`keycloak_version`| keycloak.org package version | `15.0.2` | |`keycloak_rhsso_version`| RHSSO version | `7.5.0` | +|`keycloak_rhsso_apply_patches`| Install RHSSO more recent cumulative patch | `True` | |`keycloak_dest`| Installation root path | `/opt/keycloak` | |`keycloak_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_version }}/{{ keycloak_archive }}` | |`keycloak_rhn_url` | Base download URI for customer portal | `https://access.redhat.com/jbossnetwork/restricted/softwareDownload.html?softwareId=` | @@ -91,7 +92,7 @@ Role Defaults |`keycloak_force_install` | Remove pre-existing versions of service | `False` | |`keycloak_url` | URL for configuration rest calls | `http://{{ keycloak_host }}:{{ keycloak_http_port }}` | |`keycloak_management_url` | URL for management console rest calls | `http://{{ keycloak_host }}:{{ keycloak_management_http_port }}` | -|`rhsso_rhn_id` | Customer Portal product ID for Red Hat SSO | `{{ rhsso_rhn_ids[keycloak_rhsso_version] }}` | +|`rhsso_rhn_id` | Customer Portal product ID for Red Hat SSO | `{{ rhsso_rhn_ids[keycloak_rhsso_version].id }}` | Role Variables diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index a4af3fe..6515664 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -8,11 +8,12 @@ keycloak_installdir: "{{ keycloak_dest }}/keycloak-{{ keycloak_version }}" ### Configuration specific to Red Hat Single Sing-On keycloak_rhsso_version: 7.5.0 -rhsso_rhn_id: "{{ rhsso_rhn_ids[keycloak_rhsso_version] }}" +rhsso_rhn_id: "{{ rhsso_rhn_ids[keycloak_rhsso_version].id }}" keycloak_rhsso_archive: "rh-sso-{{ keycloak_rhsso_version }}-server-dist.zip" keycloak_rhsso_installdir: "{{ keycloak_dest }}/rh-sso-{{ keycloak_rhsso_version | regex_replace('^([0-9])\\.([0-9]*).*', '\\1.\\2') }}" keycloak_rhn_url: 'https://access.redhat.com/jbossnetwork/restricted/softwareDownload.html?softwareId=' keycloak_rhsso_download_url: "{{ keycloak_rhn_url }}{{ rhsso_rhn_id }}" +keycloak_rhsso_apply_patches: True ### keycloak/rhsso choice: by default install rhsso if rhn credentials are defined keycloak_rhsso_enable: "{{ True if rhsso_rhn_id is defined and rhn_username is defined and rhn_password is defined else False }}" diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 8331945..311f57a 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -33,7 +33,7 @@ argument_specs: type: "str" rhsso_rhn_id: # line 11 of keycloak/defaults/main.yml - default: "{{ rhsso_rhn_ids[keycloak_rhsso_version] }}" + default: "{{ rhsso_rhn_ids[keycloak_rhsso_version].id }}" description: "Customer Portal product ID for Red Hat SSO" type: "str" keycloak_rhsso_archive: @@ -41,6 +41,11 @@ argument_specs: default: "rh-sso-{{ keycloak_rhsso_version }}-server-dist.zip" description: "ed Hat SSO install archive filename" type: "str" + keycloak_rhsso_apply_patches: + # line 16 of keycloak/defaults/main.yml + default: true + description: "Install RHSSO more recent cumulative patch" + type: "bool" keycloak_rhsso_installdir: # line 13 of keycloak/defaults/main.yml default: "{{ keycloak_dest }}/rh-sso-{{ keycloak_rhsso_version | regex_replace('^([0-9])\\.([0-9]*).*', '\\1.\\2') }}" diff --git a/roles/keycloak/tasks/rhsso_cli.yml b/roles/keycloak/tasks/rhsso_cli.yml new file mode 100644 index 0000000..9e9d7f5 --- /dev/null +++ b/roles/keycloak/tasks/rhsso_cli.yml @@ -0,0 +1,20 @@ +--- +- name: Ensure required params for CLI have been provided + ansible.builtin.assert: + that: + - query is defined + fail_msg: "Missing required parameters to execute CLI." + quiet: true + +- name: Verify server management interface is functional + ansible.builtin.uri: + url: "{{ keycloak_management_url }}" + register: result + until: result.status == 200 + retries: 5 + delay: 5 + +- name: "Execute CLI query: {{ query }}" + ansible.builtin.command: > + {{ path_to_cli }} -c --output-json --command='{{ query }}' --controller={{ keycloak_host }}:{{ keycloak_management_http_port }} + changed_when: false \ No newline at end of file diff --git a/roles/keycloak/vars/main.yml b/roles/keycloak/vars/main.yml index 43ece24..f639a3c 100644 --- a/roles/keycloak/vars/main.yml +++ b/roles/keycloak/vars/main.yml @@ -5,8 +5,11 @@ keycloak_admin_password: # internal variables below rhsso_rhn_ids: - '7.5.0': '101971' - '7.5.1': '103836' + '7.5.0': + id: '101971' + latest_cp: + id: '103836' + v: '7.5.1' # locations keycloak_url: "http://{{ keycloak_host }}:{{ keycloak_http_port }}" From cfdc04377044e0031cd3d67983129e1abe87ca30 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 11 Mar 2022 14:44:19 +0100 Subject: [PATCH 017/554] Update docs, fix patch apply steps and cli vars --- roles/keycloak/README.md | 14 ++- roles/keycloak/defaults/main.yml | 1 + roles/keycloak/meta/argument_specs.yml | 5 ++ roles/keycloak/tasks/main.yml | 17 ++++ roles/keycloak/tasks/rhsso_cli.yml | 13 +-- roles/keycloak/tasks/rhsso_patch.yml | 87 +++++++++++++++++++ roles/keycloak/tasks/stop_keycloak.yml | 2 +- .../templates/standalone-infinispan.xml.j2 | 2 +- roles/keycloak/vars/main.yml | 2 + 9 files changed, 130 insertions(+), 13 deletions(-) create mode 100644 roles/keycloak/tasks/rhsso_patch.yml diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index 1ab0aba..1b7ee9f 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -31,6 +31,17 @@ Versions |`7.5.0 GA` |September 20, 2021 |`15.0.2` | `7.4.0` |[Release Notes](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.5/html/release_notes/index)| +Patching +-------- + +When variable `keycloak_rhsso_apply_patches` is `True` (default: `True`), the role will automatically apply the latest cumulative patch for the selected base version. + +| RH-SSO VERSION | Release Date | RH-SSO LATEST CP | Notes | +|:---------------|:------------------|:-----------------|:----------------| +|`7.5.0 GA` |January 20, 2022 |`7.5.1 GA` |[Release Notes](https://access.redhat.com/articles/6646321)| + + + Role Defaults ------------- @@ -62,7 +73,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:---------| -|`keycloak_rhsso_enable`| Enable Red Hat Single Sign-on installation | `False` | +|`keycloak_rhsso_enable`| Enable Red Hat Single Sign-on installation | `False` | |`keycloak_offline_install` | perform an offline install | `False`| |`keycloak_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| |`keycloak_rhsso_download_url`| Download URL for RHSSO | `https://access.redhat.com/jbossnetwork/restricted/softwareDownload.html?softwareId=`| @@ -72,6 +83,7 @@ Role Defaults |`keycloak_dest`| Installation root path | `/opt/keycloak` | |`keycloak_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_version }}/{{ keycloak_archive }}` | |`keycloak_rhn_url` | Base download URI for customer portal | `https://access.redhat.com/jbossnetwork/restricted/softwareDownload.html?softwareId=` | +|`keycloak_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` | * Miscellaneous configuration diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 6515664..7f5e786 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -30,6 +30,7 @@ keycloak_config_path_to_standalone_xml: "{{ keycloak_jboss_home }}/standalone/co keycloak_service_user: keycloak keycloak_service_group: keycloak keycloak_service_pidfile: "/run/keycloak.pid" +keycloak_configure_firewalld: False ### Common configuration settings keycloak_bind_address: 0.0.0.0 diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 311f57a..bd3313a 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -11,6 +11,11 @@ argument_specs: default: "keycloak-{{ keycloak_version }}.zip" description: "keycloak install archive filename" type: "str" + keycloak_configure_firewalld: + # line 33 of keycloak/defaults/main.yml + default: false + description: "Ensure firewalld is running and configure keycloak ports" + type: "bool" keycloak_download_url: # line 5 of keycloak/defaults/main.yml default: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_version }}/{{ keycloak_archive }}" diff --git a/roles/keycloak/tasks/main.yml b/roles/keycloak/tasks/main.yml index 7ed5efe..ef00cd0 100644 --- a/roles/keycloak/tasks/main.yml +++ b/roles/keycloak/tasks/main.yml @@ -6,11 +6,28 @@ tags: - prereqs +- name: Include firewall config tasks + ansible.builtin.include_tasks: firewalld.yml + when: keycloak_configure_firewalld + tags: + - firewall + - name: Include install tasks ansible.builtin.include_tasks: install.yml + tags: + - install - name: Include systemd tasks ansible.builtin.include_tasks: systemd.yml + tags: + - systemd + +- name: Include patch install tasks + ansible.builtin.include_tasks: rhsso_patch.yml + when: keycloak_rhsso_apply_patches and keycloak_rhsso_enable + tags: + - install + - patch - name: Link default logs directory ansible.builtin.file: diff --git a/roles/keycloak/tasks/rhsso_cli.yml b/roles/keycloak/tasks/rhsso_cli.yml index 9e9d7f5..c51cdc7 100644 --- a/roles/keycloak/tasks/rhsso_cli.yml +++ b/roles/keycloak/tasks/rhsso_cli.yml @@ -6,15 +6,8 @@ fail_msg: "Missing required parameters to execute CLI." quiet: true -- name: Verify server management interface is functional - ansible.builtin.uri: - url: "{{ keycloak_management_url }}" - register: result - until: result.status == 200 - retries: 5 - delay: 5 - - name: "Execute CLI query: {{ query }}" ansible.builtin.command: > - {{ path_to_cli }} -c --output-json --command='{{ query }}' --controller={{ keycloak_host }}:{{ keycloak_management_http_port }} - changed_when: false \ No newline at end of file + {{ keycloak.cli_path }} --connect --command='{{ query }}' --controller={{ keycloak_host }}:{{ keycloak_management_http_port }} + changed_when: false + register: cli_result \ No newline at end of file diff --git a/roles/keycloak/tasks/rhsso_patch.yml b/roles/keycloak/tasks/rhsso_patch.yml new file mode 100644 index 0000000..d0ba46d --- /dev/null +++ b/roles/keycloak/tasks/rhsso_patch.yml @@ -0,0 +1,87 @@ +--- +## check remote patch archive +- name: Set download patch archive path + ansible.builtin.set_fact: + patch_archive: "{{ keycloak_dest }}/{{ keycloak.patch_bundle }}" + +- name: Check download patch archive path + ansible.builtin.stat: + path: "{{ patch_archive }}" + register: patch_archive_path + +- name: Perform download from RHN + middleware_automation.redhat_csp_download.redhat_csp_download: + url: "{{ keycloak_rhn_url }}{{ rhsso_rhn_ids[keycloak_rhsso_version].latest_cp.id }}" + dest: "{{ local_path.stat.path }}/{{ keycloak.patch_bundle }}" + username: "{{ rhn_username }}" + password: "{{ rhn_password }}" + no_log: "{{ omit_rhn_output | default(true) }}" + delegate_to: localhost + when: + - patch_archive_path is defined + - patch_archive_path.stat is defined + - not patch_archive_path.stat.exists + - keycloak_rhsso_enable + - not keycloak_offline_install + +## copy and unpack +- name: Copy patch archive to target nodes + ansible.builtin.copy: + src: "{{ local_path.stat.path }}/{{ keycloak.patch_bundle }}" + dest: "{{ patch_archive }}" + owner: "{{ keycloak_service_user }}" + group: "{{ keycloak_service_group }}" + mode: 0750 + register: new_version_downloaded + when: + - not patch_archive_path.stat.exists + - local_archive_path.stat is defined + - local_archive_path.stat.exists + become: yes + +- name: "Check installed patches" + ansible.builtin.include_tasks: rhsso_cli.yml + vars: + query: "patch info" + +- name: "Perform patching" + when: + - cli_result is defined + - cli_result.stdout is defined + - rhsso_rhn_ids[keycloak_rhsso_version].latest_cp.v not in cli_result.stdout + block: + - name: "Apply patch {{ rhsso_rhn_ids[keycloak_rhsso_version].latest_cp.v }} to server" + ansible.builtin.include_tasks: rhsso_cli.yml + vars: + query: "patch apply {{ patch_archive }}" + + - name: "Restart server to ensure patch content is running" + ansible.builtin.include_tasks: rhsso_cli.yml + vars: + query: "shutdown --restart" + when: + - cli_result.rc == 0 + + - name: "Wait until Keycloak becomes active {{ keycloak.health_url }}" + ansible.builtin.uri: + url: "{{ keycloak.health_url }}" + register: keycloak_status + until: keycloak_status.status == 200 + retries: 25 + delay: 10 + + - name: "Query installed patch after restart" + ansible.builtin.include_tasks: rhsso_cli.yml + vars: + query: "patch info" + + - name: "Verify installed patch version" + ansible.builtin.assert: + that: + - rhsso_rhn_ids[keycloak_rhsso_version].latest_cp.v not in cli_result.stdout + fail_msg: "Patch installation failed" + success_msg: "Patch installation successful" + +- name: "Skipping patch" + debug: + msg: "Latest cumulative patch {{ rhsso_rhn_ids[keycloak_rhsso_version].latest_cp.v }} already installed, skipping patch installation." diff --git a/roles/keycloak/tasks/stop_keycloak.yml b/roles/keycloak/tasks/stop_keycloak.yml index 2f76c9d..ecf4411 100644 --- a/roles/keycloak/tasks/stop_keycloak.yml +++ b/roles/keycloak/tasks/stop_keycloak.yml @@ -1,5 +1,5 @@ --- -- name: "Stop SSO service" +- name: Stop keycloak ansible.builtin.systemd: name: keycloak enabled: yes diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index 544638e..8e58b53 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -726,7 +726,7 @@ - + {% if ansible_default_ipv4 is defined %} {% else %} diff --git a/roles/keycloak/vars/main.yml b/roles/keycloak/vars/main.yml index f639a3c..ff7456a 100644 --- a/roles/keycloak/vars/main.yml +++ b/roles/keycloak/vars/main.yml @@ -20,8 +20,10 @@ keycloak: home: "{{ keycloak_jboss_home }}" config_dir: "{{ keycloak_config_dir }}" bundle: "{{ keycloak_rhsso_archive if keycloak_rhsso_enable else keycloak_archive }}" + patch_bundle: "rh-sso-{{ rhsso_rhn_ids[keycloak_rhsso_version].latest_cp.v }}-patch.zip" service_name: "{{ 'rhsso' if keycloak_rhsso_enable else 'keycloak' }}" health_url: "{{ keycloak_management_url }}/health" + cli_path: "{{ keycloak_jboss_home }}/bin/jboss-cli.sh" # database keycloak_jdbc: From 266f2bc00b434eb6af6a7b32eff53af3f04d05e3 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 11 Mar 2022 15:11:21 +0100 Subject: [PATCH 018/554] Bump to v1.0.1 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 3d7900e..32007fb 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.0.0" +version: "1.0.1" readme: README.md authors: - Romain Pelisse From c5b38e8bac8dfc2b27b0ec4574cd06b98c1799e5 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 11 Mar 2022 15:15:18 +0100 Subject: [PATCH 019/554] docs: add testing and releasing contributor pages --- CONTRIBUTING.md | 4 ++-- docs/releasing.md | 61 +++++++++++++++++++++++++++++++++++++++++++++++ docs/testing.md | 49 +++++++++++++++++++++++++++++++++++++ 3 files changed, 112 insertions(+), 2 deletions(-) create mode 100644 docs/releasing.md create mode 100644 docs/testing.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 613657d..aee36a6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,7 +1,7 @@ ## Contributor's Guidelines -- All YAML files named with '.yml' extension +- All YAML files named with `.yml` extension - Use spaces around jinja variables. `{{ var }}` over `{{var}}` - Variables that are internal to the role should be lowercase and start with the role name - Keep roles self contained - Roles should avoid including tasks from other roles when possible @@ -11,4 +11,4 @@ - Indentation - Use 2 spaces for each indent - `vars/` vs `defaults/` - internal or interpolated variables that don't need to change or be overridden by user go in `vars/`, those that a user would likely override, go under `defaults/` directory - All role arguments have a specification in `meta/argument_specs.yml` -- All playbooks/roles should be focused on compatibility with Ansible Tower +- All playbooks/roles should be focused on compatibility with Ansible Automation Platform diff --git a/docs/releasing.md b/docs/releasing.md new file mode 100644 index 0000000..537ba1e --- /dev/null +++ b/docs/releasing.md @@ -0,0 +1,61 @@ +# Collection Versioning Strategy + +Each supported collection maintained by Ansible follows Semantic Versioning 2.0.0 (https://semver.org/), for example: +Given a version number MAJOR.MINOR.PATCH, the following is incremented: + +MAJOR version: when making incompatible API changes (see Feature Release scenarios below for examples) + +MINOR version: when adding features or functionality in a backwards compatible manner, or updating testing matrix and/or metadata (deprecation) + +PATCH version: when adding backwards compatible bug fixes or security fixes (strict). + +Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format. + +The first version of a generally available supported collection on Ansible Automation Hub shall be version 1.0.0. NOTE: By default, all newly created collections may begin with a smaller default version of 0.1.0, and therefore a version of 1.0.0 should be explicitly stated by the collection maintainer. + +## New content is added to an existing collection + +Assuming the current release is 1.0.0, and a new module is ready to be added to the collection, the minor version would be incremented to 1.1.0. The change in the MINOR version indicates an additive change was made while maintaining backward compatibility for existing content within the collection. + + +## New feature to existing plugin or role within a collection (backwards compatible) + +Assuming the current release is 1.0.0, and new features for an existing module are ready for release . We would increment the MINOR version to 1.1.0. The change in the MINOR version indicates an additive change was made while maintaining backward compatibility for existing content within the collection. + + +## Bug fix or security fix to existing content within a collection + +Assuming the current release is 1.0.0 and a bug is fixed prior to the next minor release, the PATCH version would be incremented to 1.0.1. The patch indicates only a bug was fixed within a current version. The PATCH release does not contain new content, nor was functionality removed. Bug fixes may be included in a MINOR or MAJOR feature release if the timing allows, eliminating the need for a PATCH dedicated to the fix. + + +## Breaking change to any content within a collection + +Assuming the current release is 1.0.0, and a breaking change (API or module) is introduced for a user or developer. The MAJOR version would be incremented to 2.0.0. + +Examples of breaking changes within a collection may include but are not limited to: + + - Argspec changes for a module that require either inventory structure or playbook changes. + - A change in the shape of either the inbound or returned payload of a filter plugin. + - Changes to a connection plugin that require additional inventory parameters or ansible.cfg entries. + - New functionality added to a module that changes the outcome of that module as released in previous versions. + - The removal of plugins from a collection. + + +## Content removed from a collection + +Deleting a module or API is a breaking change. Please see the 'Breaking change' section for how to version this. + + +## A typographical error was fixed in the documentation for a collection + +A correction to the README would be considered a bug fix and the PATCH incremented. See 'Bug fix' above. + + +## Documentation added/removed/modified within a collection + +Only the PATCH version should be increased for a release that contains changes limited to revised documentation. + + +## Release automation + +New releases are triggered by annotated git tags named after semantic versioning. The automation publishes the built artifacts to ansible-galaxy and github releases page. diff --git a/docs/testing.md b/docs/testing.md new file mode 100644 index 0000000..7a700c0 --- /dev/null +++ b/docs/testing.md @@ -0,0 +1,49 @@ +# Testing + +## Continuous integration + +The collection is tested with a [molecule](https://github.com/ansible-community/molecule) setup covering the included roles and verifying correct installation and idempotency. +In order to run the molecule tests locally with python 3.9 available, after cloning the repository: + +``` +pip install yamllint 'molecule[docker]~=3.5.2' ansible-core flake8 ansible-lint voluptuous +molecule test --all +``` + + +## Integration testing + +Demo repositories which depend on the collection, and aggregate functionality with other middleware_automation collections, are automatically rebuilt +at every collection release to ensure non-breaking changes and consistent behaviour. + +The repository are: + + - [Flange demo](https://github.com/ansible-middleware/flange-demo) + A deployment of Wildfly cluster integrated with keycloak and infinispan. + - [CrossDC keycloak demo](https://github.com/ansible-middleware/cross-dc-rhsso-demo) + A clustered multi-regional installation of keycloak with infinispan remote caches. + + +## Test playbooks + +Sample playbooks are provided in the `playbooks/` directory; to run the playbooks locally (requires a rhel system with python 3.9+, ansible, and systemd) the steps are as follows: + +``` +# setup environment +pip install ansible-core +# clone the repository +git clone https://github.com/ansible-middleware/keycloak +cd keycloak +# install collection dependencies +ansible-galaxy collection install -r requirements.yml +# install collection python deps +pip install -r requirements.txt +# create inventory for localhost +cat << EOF > inventory +[keycloak] +localhost ansible_connection=local +EOF +# run the playbook +ansible-playbook -i inventory playbooks/keycloak.yml +``` + From d5bf0a195a8c5fcfd31545cdc910be078094fdd4 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 11 Mar 2022 15:31:48 +0100 Subject: [PATCH 020/554] docs: fix typo --- docs/_gh_include/footer.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_gh_include/footer.inc b/docs/_gh_include/footer.inc index 896a880..73bac34 100644 --- a/docs/_gh_include/footer.inc +++ b/docs/_gh_include/footer.inc @@ -7,7 +7,7 @@

-

© Copyright 2022, Red Hat, Inc..

+

© Copyright 2022, Red Hat, Inc.

Built with Sphinx using a theme From bf26c727a84812ca0557e3488f7762b6008a525b Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 11 Mar 2022 15:08:53 +0100 Subject: [PATCH 021/554] misc: simply fastpackages logic and reduce play time --- roles/keycloak/tasks/fastpackages/check.yml | 14 ----------- roles/keycloak/tasks/fastpackages/install.yml | 23 +++++++++++-------- roles/keycloak/tasks/install.yml | 6 ++--- roles/keycloak/tasks/start_keycloak.yml | 2 +- 4 files changed, 17 insertions(+), 28 deletions(-) delete mode 100644 roles/keycloak/tasks/fastpackages/check.yml diff --git a/roles/keycloak/tasks/fastpackages/check.yml b/roles/keycloak/tasks/fastpackages/check.yml deleted file mode 100644 index c0679dc..0000000 --- a/roles/keycloak/tasks/fastpackages/check.yml +++ /dev/null @@ -1,14 +0,0 @@ ---- -- block: - - name: "Check if package {{ package_name }} is already installed" - ansible.builtin.command: rpm -q {{ package_name }} - args: - warn: no - register: rpm_info - changed_when: rpm_info.failed - - rescue: - - name: "Add {{ package_name }} to the yum install list if missing" - ansible.builtin.set_fact: - packages_to_install: "{{ packages_to_install + [ package_name ] }}" - when: rpm_info.failed \ No newline at end of file diff --git a/roles/keycloak/tasks/fastpackages/install.yml b/roles/keycloak/tasks/fastpackages/install.yml index 41133f4..29155f9 100644 --- a/roles/keycloak/tasks/fastpackages/install.yml +++ b/roles/keycloak/tasks/fastpackages/install.yml @@ -1,18 +1,21 @@ --- -- name: Set facts - ansible.builtin.set_fact: - update_cache: true - packages_to_install: [] +- block: + - name: "Check if packages are already installed" + ansible.builtin.command: "rpm -q {{ packages_list | join(' ') }}" + args: + warn: no + register: rpm_info + changed_when: rpm_info.failed -- name: "Check packages to be installed" - ansible.builtin.include_tasks: check.yml - loop: "{{ packages_list | flatten }}" - loop_control: - loop_var: package_name + rescue: + - name: "Add missing packages to the yum install list" + ansible.builtin.set_fact: + packages_to_install: "{{ packages_to_install | default([]) + rpm_info.stdout_lines | map('regex_findall', 'package (.+) is not installed$') | flatten }}" + when: rpm_info.failed - name: "Install packages: {{ packages_to_install }}" become: yes ansible.builtin.yum: name: "{{ packages_to_install }}" state: present - when: packages_to_install | length > 0 \ No newline at end of file + when: packages_to_install | default([]) | length > 0 \ No newline at end of file diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index 7698719..e8ee292 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -30,12 +30,12 @@ state: absent when: existing_deploy.stat.exists and keycloak_force_install|bool -- name: check for an existing deployment after possible forced removal +- name: Check for an existing deployment after possible forced removal become: yes ansible.builtin.stat: path: "{{ keycloak_jboss_home }}" -- name: create Keycloak service user/group +- name: Create Keycloak service user/group become: yes ansible.builtin.user: name: "{{ keycloak_service_user }}" @@ -43,7 +43,7 @@ system: yes create_home: no -- name: create Keycloak install location +- name: Create Keycloak install location become: yes ansible.builtin.file: dest: "{{ keycloak_dest }}" diff --git a/roles/keycloak/tasks/start_keycloak.yml b/roles/keycloak/tasks/start_keycloak.yml index b3c34f9..62d4f99 100644 --- a/roles/keycloak/tasks/start_keycloak.yml +++ b/roles/keycloak/tasks/start_keycloak.yml @@ -1,5 +1,5 @@ --- -- name: start keycloak +- name: Start keycloak ansible.builtin.systemd: name: keycloak enabled: yes From 33e80a0cd455372127028dcd46b4f90a06f6db53 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 11 Mar 2022 15:57:10 +0100 Subject: [PATCH 022/554] remove unused set_fact --- .../install.yml => fastpackages.yml} | 0 roles/keycloak/tasks/firewalld.yml | 2 +- roles/keycloak/tasks/prereqs.yml | 16 ++++++---------- 3 files changed, 7 insertions(+), 11 deletions(-) rename roles/keycloak/tasks/{fastpackages/install.yml => fastpackages.yml} (100%) diff --git a/roles/keycloak/tasks/fastpackages/install.yml b/roles/keycloak/tasks/fastpackages.yml similarity index 100% rename from roles/keycloak/tasks/fastpackages/install.yml rename to roles/keycloak/tasks/fastpackages.yml diff --git a/roles/keycloak/tasks/firewalld.yml b/roles/keycloak/tasks/firewalld.yml index 1703ae9..e17b55c 100644 --- a/roles/keycloak/tasks/firewalld.yml +++ b/roles/keycloak/tasks/firewalld.yml @@ -1,6 +1,6 @@ --- - name: Ensures required package firewalld are installed - ansible.builtin.include_tasks: fastpackages/install.yml + ansible.builtin.include_tasks: fastpackages.yml vars: packages_list: - firewalld diff --git a/roles/keycloak/tasks/prereqs.yml b/roles/keycloak/tasks/prereqs.yml index 0fbe6c1..77e8364 100644 --- a/roles/keycloak/tasks/prereqs.yml +++ b/roles/keycloak/tasks/prereqs.yml @@ -16,15 +16,11 @@ fail_msg: "Cannot install Red Hat SSO without RHN credentials. Check rhn_username and rhn_password are defined" success_msg: "{{ 'Installing Red Hat Single Sign-On' if keycloak_rhsso_enable else 'Installing keycloak.org' }}" -- name: Set required packages facts - ansible.builtin.set_fact: - required_packages: - - "{{ jvm_package }}" - - unzip - - procps-ng - - initscripts - - name: Ensures required packages are installed - ansible.builtin.include_tasks: fastpackages/install.yml + ansible.builtin.include_tasks: fastpackages.yml vars: - packages_list: "{{ required_packages }}" \ No newline at end of file + packages_list: + - "{{ jvm_package }}" + - unzip + - procps-ng + - initscripts \ No newline at end of file From e773e12e246fc97b3bab61fb15f713e1350b847d Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 17 Mar 2022 10:45:55 +0100 Subject: [PATCH 023/554] use proper service name in task names --- playbooks/keycloak.yml | 10 ++++------ playbooks/rhsso.yml | 12 +++++------- roles/keycloak/tasks/firewalld.yml | 2 +- roles/keycloak/tasks/install.yml | 9 +++++---- roles/keycloak/tasks/main.yml | 2 +- roles/keycloak/tasks/restart_keycloak.yml | 2 +- roles/keycloak/tasks/rhsso_patch.yml | 2 +- roles/keycloak/tasks/start_keycloak.yml | 4 ++-- roles/keycloak/tasks/stop_keycloak.yml | 2 +- roles/keycloak/tasks/systemd.yml | 10 +++++----- 10 files changed, 26 insertions(+), 29 deletions(-) diff --git a/playbooks/keycloak.yml b/playbooks/keycloak.yml index 4a2706c..020c1f7 100644 --- a/playbooks/keycloak.yml +++ b/playbooks/keycloak.yml @@ -1,11 +1,9 @@ --- - name: Playbook for Keycloak Hosts hosts: keycloak + vars: + keycloak_admin_password: "changeme" collections: - middleware_automation.keycloak - tasks: - - name: Include keycloak role - ansible.builtin.include_role: - name: middleware_automation.keycloak.keycloak - vars: - keycloak_admin_password: "changeme" \ No newline at end of file + roles: + - middleware_automation.keycloak.keycloak diff --git a/playbooks/rhsso.yml b/playbooks/rhsso.yml index 8aa73e9..13f4ce6 100644 --- a/playbooks/rhsso.yml +++ b/playbooks/rhsso.yml @@ -1,14 +1,12 @@ --- - name: Playbook for Keycloak Hosts hosts: keycloak + vars: + keycloak_admin_password: "changeme" + keycloak_rhsso_enable: True collections: - middleware_automation.redhat_csp_download + - middleware_automation.keycloak roles: - middleware_automation.redhat_csp_download.redhat_csp_download - tasks: - - name: Keycloak Role - ansible.builtin.include_role: - name: middleware_automation.keycloak.keycloak - vars: - keycloak_admin_password: "changeme" - keycloak_rhsso_enable: True \ No newline at end of file + - middleware_automation.keycloak.keycloak diff --git a/roles/keycloak/tasks/firewalld.yml b/roles/keycloak/tasks/firewalld.yml index e17b55c..15f91cb 100644 --- a/roles/keycloak/tasks/firewalld.yml +++ b/roles/keycloak/tasks/firewalld.yml @@ -12,7 +12,7 @@ enabled: yes state: started -- name: Configure firewall for keycloak ports +- name: "Configure firewall for {{ keycloak.service_name }} ports" become: yes firewalld: port: "{{ item }}" diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index e8ee292..c45a842 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -17,13 +17,13 @@ register: existing_deploy - block: - - name: Stop the old keycloak service + - name: "Stop the old {{ keycloak.service_name }} service" become: yes ignore_errors: yes ansible.builtin.systemd: name: keycloak state: stopped - - name: Remove the old Keycloak deployment + - name: "Remove the old {{ keycloak.service_name }} deployment" become: yes ansible.builtin.file: path: "{{ keycloak_jboss_home }}" @@ -35,7 +35,7 @@ ansible.builtin.stat: path: "{{ keycloak_jboss_home }}" -- name: Create Keycloak service user/group +- name: "Create {{ keycloak.service_name }} service user/group" become: yes ansible.builtin.user: name: "{{ keycloak_service_user }}" @@ -43,7 +43,7 @@ system: yes create_home: no -- name: Create Keycloak install location +- name: "Create {{ keycloak.service_name }} install location" become: yes ansible.builtin.file: dest: "{{ keycloak_dest }}" @@ -58,6 +58,7 @@ archive: "{{ keycloak_dest }}/{{ keycloak.bundle }}" - name: Check download archive path + become: yes ansible.builtin.stat: path: "{{ archive }}" register: archive_path diff --git a/roles/keycloak/tasks/main.yml b/roles/keycloak/tasks/main.yml index ef00cd0..c16f6cb 100644 --- a/roles/keycloak/tasks/main.yml +++ b/roles/keycloak/tasks/main.yml @@ -36,7 +36,7 @@ dest: /var/log/keycloak - block: - - name: Check admin credentials by generating a token + - name: Check admin credentials by generating a token (supposed to fail on first installation) ansible.builtin.uri: url: "{{ keycloak_url }}/auth/realms/master/protocol/openid-connect/token" method: POST diff --git a/roles/keycloak/tasks/restart_keycloak.yml b/roles/keycloak/tasks/restart_keycloak.yml index 255cb22..eff9ddf 100644 --- a/roles/keycloak/tasks/restart_keycloak.yml +++ b/roles/keycloak/tasks/restart_keycloak.yml @@ -1,5 +1,5 @@ --- -- name: "Restart and enable keycloack service" +- name: "Restart and enable {{ keycloak.service_name }} service" ansible.builtin.systemd: name: keycloak enabled: yes diff --git a/roles/keycloak/tasks/rhsso_patch.yml b/roles/keycloak/tasks/rhsso_patch.yml index d0ba46d..d4a4273 100644 --- a/roles/keycloak/tasks/rhsso_patch.yml +++ b/roles/keycloak/tasks/rhsso_patch.yml @@ -62,7 +62,7 @@ when: - cli_result.rc == 0 - - name: "Wait until Keycloak becomes active {{ keycloak.health_url }}" + - name: "Wait until {{ keycloak.service_name }} becomes active {{ keycloak.health_url }}" ansible.builtin.uri: url: "{{ keycloak.health_url }}" register: keycloak_status diff --git a/roles/keycloak/tasks/start_keycloak.yml b/roles/keycloak/tasks/start_keycloak.yml index 62d4f99..bdf42f9 100644 --- a/roles/keycloak/tasks/start_keycloak.yml +++ b/roles/keycloak/tasks/start_keycloak.yml @@ -1,12 +1,12 @@ --- -- name: Start keycloak +- name: "Start {{ keycloak.service_name }} service" ansible.builtin.systemd: name: keycloak enabled: yes state: started become: yes -- name: "Wait until Keycloak becomes active {{ keycloak.health_url }}" +- name: "Wait until {{ keycloak.service_name }} becomes active {{ keycloak.health_url }}" ansible.builtin.uri: url: "{{ keycloak.health_url }}" register: keycloak_status diff --git a/roles/keycloak/tasks/stop_keycloak.yml b/roles/keycloak/tasks/stop_keycloak.yml index ecf4411..fd87802 100644 --- a/roles/keycloak/tasks/stop_keycloak.yml +++ b/roles/keycloak/tasks/stop_keycloak.yml @@ -1,5 +1,5 @@ --- -- name: Stop keycloak +- name: "Stop {{ keycloak.service_name }}" ansible.builtin.systemd: name: keycloak enabled: yes diff --git a/roles/keycloak/tasks/systemd.yml b/roles/keycloak/tasks/systemd.yml index de643af..cfc3762 100644 --- a/roles/keycloak/tasks/systemd.yml +++ b/roles/keycloak/tasks/systemd.yml @@ -1,4 +1,4 @@ -- name: Configure keycloak service script wrapper +- name: "Configure {{ keycloak.service_name }} service script wrapper" become: yes ansible.builtin.template: src: keycloak-service.sh.j2 @@ -9,7 +9,7 @@ notify: - restart keycloak -- name: Configure sysconfig file for keycloak service +- name: "Configure sysconfig file for {{ keycloak.service_name }} service" become: yes ansible.builtin.template: src: keycloak-sysconfig.j2 @@ -20,7 +20,7 @@ notify: - restart keycloak -- name: Configure systemd unit file for keycloak service +- name: "Configure systemd unit file for {{ keycloak.service_name }} service" ansible.builtin.template: src: keycloak.service.j2 dest: /etc/systemd/system/keycloak.service @@ -38,12 +38,12 @@ daemon_reload: yes when: systemdunit.changed -- name: Start and wait for keycloak service (first node db) +- name: "Start and wait for {{ keycloak.service_name }} service (first node db)" ansible.builtin.include_tasks: start_keycloak.yml run_once: yes when: keycloak_db_enabled -- name: Start and wait for keycloak service (remaining nodes) +- name: "Start and wait for {{ keycloak.service_name }} service (remaining nodes)" ansible.builtin.include_tasks: start_keycloak.yml - name: Check service status From 5828c0a7bbbbfc73006fcf68af572f16f1564b63 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 23 Mar 2022 12:30:32 +0100 Subject: [PATCH 024/554] fix: spelling --- roles/keycloak/README.md | 2 +- roles/keycloak/defaults/main.yml | 2 +- roles/keycloak/meta/main.yml | 2 +- roles/keycloak_realm/README.md | 2 +- roles/keycloak_realm/meta/main.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index 1b7ee9f..a1295f1 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -1,7 +1,7 @@ keycloak ======== -Install [keycloak](https://keycloak.org/) or [Red Hat Single Sing-On](https://access.redhat.com/products/red-hat-single-sign-on) server configurations. +Install [keycloak](https://keycloak.org/) or [Red Hat Single Sign-On](https://access.redhat.com/products/red-hat-single-sign-on) server configurations. Requirements diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 7f5e786..ebbaa05 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -6,7 +6,7 @@ keycloak_download_url: "https://github.com/keycloak/keycloak/releases/download/{ keycloak_download_url_9x: "https://downloads.jboss.org/keycloak/{{ keycloak_version }}/{{ keycloak_archive }}" keycloak_installdir: "{{ keycloak_dest }}/keycloak-{{ keycloak_version }}" -### Configuration specific to Red Hat Single Sing-On +### Configuration specific to Red Hat Single Sign-On keycloak_rhsso_version: 7.5.0 rhsso_rhn_id: "{{ rhsso_rhn_ids[keycloak_rhsso_version].id }}" keycloak_rhsso_archive: "rh-sso-{{ keycloak_rhsso_version }}-server-dist.zip" diff --git a/roles/keycloak/meta/main.yml b/roles/keycloak/meta/main.yml index ed05acb..8f5bc1e 100644 --- a/roles/keycloak/meta/main.yml +++ b/roles/keycloak/meta/main.yml @@ -7,7 +7,7 @@ galaxy_info: role_name: keycloak namespace: middleware_automation author: Romain Pelisse, Guido Grazioli, Pavan Kumar Motaparthi - description: Install keycloak or Red Hat Single Sing-On server configurations + description: Install keycloak or Red Hat Single Sign-On server configurations company: Red Hat, Inc. license: Apache License 2.0 diff --git a/roles/keycloak_realm/README.md b/roles/keycloak_realm/README.md index cf147b5..4a01e64 100644 --- a/roles/keycloak_realm/README.md +++ b/roles/keycloak_realm/README.md @@ -1,7 +1,7 @@ keycloak_realm ============== -Create realms and clients in [keycloak](https://keycloak.org/) or [Red Hat Single Sing-On](https://access.redhat.com/products/red-hat-single-sign-on) services. +Create realms and clients in [keycloak](https://keycloak.org/) or [Red Hat Single Sign-On](https://access.redhat.com/products/red-hat-single-sign-on) services. Role Defaults diff --git a/roles/keycloak_realm/meta/main.yml b/roles/keycloak_realm/meta/main.yml index 04dff8a..4ce1b73 100644 --- a/roles/keycloak_realm/meta/main.yml +++ b/roles/keycloak_realm/meta/main.yml @@ -3,7 +3,7 @@ galaxy_info: role_name: keycloak_realm namespace: middleware_automation author: Romain Pelisse, Guido Grazioli - description: Create realms and clients in keycloak or Red Hat Single Sing-On + description: Create realms and clients in keycloak or Red Hat Single Sign-On company: Red Hat, Inc. license: Apache License 2.0 From 6270762a3ad032f05259a1e6ac859b94535bea30 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 23 Mar 2022 15:42:41 +0100 Subject: [PATCH 025/554] trigger EE rebuild when released --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 820289d..aafcfb1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -41,7 +41,7 @@ jobs: needs: release strategy: matrix: - repo: ['ansible-middleware/cross-dc-rhsso-demo', 'ansible-middleware/flange-demo'] + repo: ['ansible-middleware/cross-dc-rhsso-demo', 'ansible-middleware/flange-demo', 'ansible-middleware/ansible-middleware-ee'] runs-on: ubuntu-latest steps: - name: Repository Dispatch From 8173be4b58b548ba71dcda1ee87f1b2496865b7d Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 24 Mar 2022 17:00:30 +0100 Subject: [PATCH 026/554] Set the frontend URL to play well with other defaults --- roles/keycloak/README.md | 6 +++--- roles/keycloak/defaults/main.yml | 6 ++++-- roles/keycloak/handlers/main.yml | 3 ++- roles/keycloak/meta/argument_specs.yml | 2 +- roles/keycloak/tasks/prereqs.yml | 2 +- roles/keycloak/templates/keycloak.service.j2 | 2 +- 6 files changed, 12 insertions(+), 9 deletions(-) diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index a1295f1..73d6b26 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -66,7 +66,7 @@ Role Defaults |`keycloak_service_user`| posix account username | `keycloak` | |`keycloak_service_group`| posix account group | `keycloak` | |`keycloak_service_pidfile`| pid file path for service | `/run/keycloak.pid` | -|`jvm_package`| RHEL java package runtime | `java-1.8.0-openjdk-devel` | +|`keycloak_jvm_package`| RHEL java package runtime | `java-1.8.0-openjdk-devel` | * Install options @@ -115,6 +115,7 @@ The following are a set of _required_ variables for the role: | Variable | Description | |:---------|:------------| |`keycloak_admin_password`| Password for the administration console user account | +|`keycloak_frontend_url` | frontend URL for keycloak endpoint | `http://localhost:8080/auth` | The following variables are _required_ only when `keycloak_ha_enabled` is True: @@ -122,8 +123,7 @@ The following variables are _required_ only when `keycloak_ha_enabled` is True: | Variable | Description | Default | |:---------|:------------|:---------| |`keycloak_modcluster_url` | URL for the modcluster reverse proxy | `localhost` | -|`keycloak_frontend_url` | frontend URL for keycloak endpoints when a reverse proxy is used | `http://localhost` | -|`keycloak_jdbc_engine` | backend database flavour when db is enabled: [ postgres, mariadb ] | `postgres` | +|`keycloak_jdbc_engine` | backend database engine when db is enabled: [ postgres, mariadb ] | `postgres` | |`infinispan_url` | URL for the infinispan remote-cache server | `localhost:11122` | |`infinispan_user` | username for connecting to infinispan | `supervisor` | |`infinispan_pass` | password for connecting to infinispan | `supervisor` | diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index ebbaa05..aa62b06 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -21,7 +21,7 @@ keycloak_rhsso_enable: "{{ True if rhsso_rhn_id is defined and rhn_username is d keycloak_offline_install: False ### Install location and service settings -jvm_package: java-1.8.0-openjdk-devel +keycloak_jvm_package: java-1.8.0-openjdk-devel keycloak_dest: /opt/keycloak keycloak_jboss_home: "{{ keycloak_rhsso_installdir if keycloak_rhsso_enable else keycloak_installdir }}" keycloak_config_dir: "{{ keycloak_jboss_home }}/standalone/configuration" @@ -58,7 +58,9 @@ keycloak_force_install: False ### mod_cluster reverse proxy keycloak_modcluster_url: localhost -keycloak_frontend_url: http://localhost + +### keycloak frontend url +keycloak_frontend_url: http://localhost:8080/auth ### infinispan remote caches access (hotrod) infinispan_user: supervisor diff --git a/roles/keycloak/handlers/main.yml b/roles/keycloak/handlers/main.yml index 1727b6d..dda3682 100644 --- a/roles/keycloak/handlers/main.yml +++ b/roles/keycloak/handlers/main.yml @@ -1,3 +1,4 @@ --- -- name: restart keycloak +- name: "Restart {{ keycloak.service_name }}" ansible.builtin.include_tasks: restart_keycloak.yml + listen: "restart keycloak" diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index bd3313a..ba2ecdd 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -76,7 +76,7 @@ argument_specs: default: false description: "Perform an offline install" type: "bool" - jvm_package: + keycloak_jvm_package: # line 23 of keycloak/defaults/main.yml default: "java-1.8.0-openjdk-devel" description: "RHEL java package runtime rpm" diff --git a/roles/keycloak/tasks/prereqs.yml b/roles/keycloak/tasks/prereqs.yml index 77e8364..6d3fc33 100644 --- a/roles/keycloak/tasks/prereqs.yml +++ b/roles/keycloak/tasks/prereqs.yml @@ -20,7 +20,7 @@ ansible.builtin.include_tasks: fastpackages.yml vars: packages_list: - - "{{ jvm_package }}" + - "{{ keycloak_jvm_package }}" - unzip - procps-ng - initscripts \ No newline at end of file diff --git a/roles/keycloak/templates/keycloak.service.j2 b/roles/keycloak/templates/keycloak.service.j2 index e7233f2..0fcecbf 100644 --- a/roles/keycloak/templates/keycloak.service.j2 +++ b/roles/keycloak/templates/keycloak.service.j2 @@ -1,6 +1,6 @@ # {{ ansible_managed }} [Unit] -Description=Keycloak Server +Description={{ keycloak.service_name }} Server After=network.target [Service] From a67081a68d413c4bd7d7762534633468a0b07976 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 24 Mar 2022 17:44:13 +0100 Subject: [PATCH 027/554] move admin pwd param from vars to defaults, add assert --- roles/keycloak/defaults/main.yml | 3 +++ roles/keycloak/meta/main.yml | 6 ++++-- roles/keycloak/tasks/firewalld.yml | 2 +- roles/keycloak/tasks/prereqs.yml | 10 +++++++++- roles/keycloak/vars/main.yml | 4 ---- 5 files changed, 17 insertions(+), 8 deletions(-) diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index ebbaa05..ad1b2c6 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -32,6 +32,9 @@ keycloak_service_group: keycloak keycloak_service_pidfile: "/run/keycloak.pid" keycloak_configure_firewalld: False +### administrator console password +keycloak_admin_password: '' + ### Common configuration settings keycloak_bind_address: 0.0.0.0 keycloak_host: localhost diff --git a/roles/keycloak/meta/main.yml b/roles/keycloak/meta/main.yml index 8f5bc1e..4760762 100644 --- a/roles/keycloak/meta/main.yml +++ b/roles/keycloak/meta/main.yml @@ -23,5 +23,7 @@ galaxy_info: - keycloak - redhat - rhel - - rhn - - sso \ No newline at end of file + - sso + - authentication + - identity + - security diff --git a/roles/keycloak/tasks/firewalld.yml b/roles/keycloak/tasks/firewalld.yml index 15f91cb..58a6cac 100644 --- a/roles/keycloak/tasks/firewalld.yml +++ b/roles/keycloak/tasks/firewalld.yml @@ -1,5 +1,5 @@ --- -- name: Ensures required package firewalld are installed +- name: Ensure required package firewalld are installed ansible.builtin.include_tasks: fastpackages.yml vars: packages_list: diff --git a/roles/keycloak/tasks/prereqs.yml b/roles/keycloak/tasks/prereqs.yml index 77e8364..5d685be 100644 --- a/roles/keycloak/tasks/prereqs.yml +++ b/roles/keycloak/tasks/prereqs.yml @@ -1,4 +1,12 @@ --- +- name: Validate admin console password + ansible.builtin.assert: + that: + - keycloak_admin_password | length > 12 + quiet: True + fail_msg: "The console administrator password is empty or invalid. Please set the keycloak_admin_password variable to a 16+ char long string" + success_msg: "{{ 'Console administrator password OK' }}" + - name: Validate configuration ansible.builtin.assert: that: @@ -16,7 +24,7 @@ fail_msg: "Cannot install Red Hat SSO without RHN credentials. Check rhn_username and rhn_password are defined" success_msg: "{{ 'Installing Red Hat Single Sign-On' if keycloak_rhsso_enable else 'Installing keycloak.org' }}" -- name: Ensures required packages are installed +- name: Ensure required packages are installed ansible.builtin.include_tasks: fastpackages.yml vars: packages_list: diff --git a/roles/keycloak/vars/main.yml b/roles/keycloak/vars/main.yml index ff7456a..437eac0 100644 --- a/roles/keycloak/vars/main.yml +++ b/roles/keycloak/vars/main.yml @@ -1,8 +1,4 @@ --- -# required variables for keycloak -# administrator console password -keycloak_admin_password: - # internal variables below rhsso_rhn_ids: '7.5.0': From d854791183b3af5a9db1a6a503e297440eb2baa0 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 24 Mar 2022 18:07:33 +0100 Subject: [PATCH 028/554] set admin pass to valid length --- playbooks/keycloak_realm.yml | 2 +- playbooks/rhsso.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/playbooks/keycloak_realm.yml b/playbooks/keycloak_realm.yml index e7d0259..8bc1962 100644 --- a/playbooks/keycloak_realm.yml +++ b/playbooks/keycloak_realm.yml @@ -6,7 +6,7 @@ ansible.builtin.include_role: name: middleware_automation.keycloak.keycloak_realm vars: - keycloak_admin_password: "changeme" + keycloak_admin_password: "remembertochangeme" keycloak_realm: TestRealm keycloak_user_federation: - realm: TestRealm diff --git a/playbooks/rhsso.yml b/playbooks/rhsso.yml index 13f4ce6..ba30a74 100644 --- a/playbooks/rhsso.yml +++ b/playbooks/rhsso.yml @@ -2,7 +2,7 @@ - name: Playbook for Keycloak Hosts hosts: keycloak vars: - keycloak_admin_password: "changeme" + keycloak_admin_password: "remembertochangeme" keycloak_rhsso_enable: True collections: - middleware_automation.redhat_csp_download From 85b0a2549af5d1ef925ab113e25c6fb3bb6092a8 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 24 Mar 2022 19:00:30 +0100 Subject: [PATCH 029/554] update tests with pwd, apply change to keycloak_realm --- molecule/default/converge.yml | 4 +--- molecule/default/verify.yml | 1 + roles/keycloak_realm/README.md | 2 +- roles/keycloak_realm/defaults/main.yml | 2 ++ roles/keycloak_realm/vars/main.yml | 3 --- 5 files changed, 5 insertions(+), 7 deletions(-) diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index 55f17ef..2ab6ad5 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -2,17 +2,15 @@ - name: Converge hosts: all vars: + keycloak_admin_password: "remembertochangeme" tasks: - name: Include keycloak role include_role: name: ../../roles/keycloak - vars: - keycloak_admin_password: "changeme" - name: Keycloak Realm Role include_role: name: ../../roles/keycloak_realm vars: - keycloak_admin_password: "changeme" keycloak_client_default_roles: - TestRoleAdmin - TestRoleUser diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml index 0952ba5..ef973cd 100644 --- a/molecule/default/verify.yml +++ b/molecule/default/verify.yml @@ -8,3 +8,4 @@ ansible.builtin.assert: that: - ansible_facts.services["keycloak.service"]["state"] == "running" + - ansible_facts.services["keycloak.service"]["status"] == "enabled" diff --git a/roles/keycloak_realm/README.md b/roles/keycloak_realm/README.md index 4a01e64..cf098a7 100644 --- a/roles/keycloak_realm/README.md +++ b/roles/keycloak_realm/README.md @@ -30,8 +30,8 @@ The following are a set of _required_ variables for the role: | Variable | Description | |:---------|:------------| -|`keycloak_admin_password`| Password for the administration console user account | |`keycloak_realm` | Name of the realm to be created | +|`keycloak_admin_password`| Password for the administration console user account | The following variables are available for creating clients: diff --git a/roles/keycloak_realm/defaults/main.yml b/roles/keycloak_realm/defaults/main.yml index c47aea3..2f33e57 100644 --- a/roles/keycloak_realm/defaults/main.yml +++ b/roles/keycloak_realm/defaults/main.yml @@ -11,6 +11,8 @@ keycloak_admin_user: admin keycloak_auth_realm: master keycloak_auth_client: admin-cli +# administrator console password, this is a required variable +keycloak_admin_password: '' ### Keycloak realms, clients, roles, federation # list of clients to create in the realm diff --git a/roles/keycloak_realm/vars/main.yml b/roles/keycloak_realm/vars/main.yml index f87e7f5..076a8a9 100644 --- a/roles/keycloak_realm/vars/main.yml +++ b/roles/keycloak_realm/vars/main.yml @@ -1,9 +1,6 @@ --- # vars file for keycloak_realm -# administrator console password, this is a required variable -keycloak_admin_password: - # name of the realm to create, this is a required variable keycloak_realm: From f736ad5632c2714cea2b8cdc5c2d131f0e2214a3 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 25 Mar 2022 10:11:22 +0100 Subject: [PATCH 030/554] misc: switch default keycloak_rhsso_apply_patches to false --- roles/keycloak/README.md | 27 +++++++++++++------------- roles/keycloak/defaults/main.yml | 2 +- roles/keycloak/meta/argument_specs.yml | 2 +- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index 73d6b26..3588b86 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -34,7 +34,7 @@ Versions Patching -------- -When variable `keycloak_rhsso_apply_patches` is `True` (default: `True`), the role will automatically apply the latest cumulative patch for the selected base version. +When variable `keycloak_rhsso_apply_patches` is `True` (default: `False`), the role will automatically apply the latest cumulative patch for the selected base version. | RH-SSO VERSION | Release Date | RH-SSO LATEST CP | Notes | |:---------------|:------------------|:-----------------|:----------------| @@ -79,7 +79,7 @@ Role Defaults |`keycloak_rhsso_download_url`| Download URL for RHSSO | `https://access.redhat.com/jbossnetwork/restricted/softwareDownload.html?softwareId=`| |`keycloak_version`| keycloak.org package version | `15.0.2` | |`keycloak_rhsso_version`| RHSSO version | `7.5.0` | -|`keycloak_rhsso_apply_patches`| Install RHSSO more recent cumulative patch | `True` | +|`keycloak_rhsso_apply_patches`| Install RHSSO more recent cumulative patch | `False` | |`keycloak_dest`| Installation root path | `/opt/keycloak` | |`keycloak_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_version }}/{{ keycloak_archive }}` | |`keycloak_rhn_url` | Base download URI for customer portal | `https://access.redhat.com/jbossnetwork/restricted/softwareDownload.html?softwareId=` | @@ -114,7 +114,7 @@ The following are a set of _required_ variables for the role: | Variable | Description | |:---------|:------------| -|`keycloak_admin_password`| Password for the administration console user account | +|`keycloak_admin_password`| Password for the administration console user account (minimum 12 characters) | |`keycloak_frontend_url` | frontend URL for keycloak endpoint | `http://localhost:8080/auth` | @@ -154,14 +154,12 @@ _NOTE_: use ansible vaults or other security systems for storing credentials. ```yaml --- - hosts: ... + vars: + keycloak_admin_password: "remembertochangeme" collections: - middleware_automation.keycloak - tasks: - - name: Include keycloak role - include_role: - name: keycloak - vars: - keycloak_admin_password: "changeme" + roles: + - middleware_automation.keycloak.keycloak ``` * The following is an example playbook that makes use of the role to install Red Hat Single Sign-On from RHN: @@ -179,7 +177,7 @@ _NOTE_: use ansible vaults or other security systems for storing credentials. include_role: name: keycloak vars: - keycloak_admin_password: "changeme" + keycloak_admin_password: "remembertochangeme" keycloak_rhsso_enable: True rhn_username: '' rhn_password: '' @@ -198,7 +196,7 @@ _NOTE_: use ansible vaults or other security systems for storing credentials. include_role: name: keycloak vars: - keycloak_admin_password: "changeme" + keycloak_admin_password: "remembertochangeme" keycloak_offline_install: True # This should be the filename of keycloak archive on Ansible node: keycloak-16.1.0.zip ``` @@ -216,14 +214,14 @@ _NOTE_: use ansible vaults or other security systems for storing credentials. include_role: name: keycloak vars: - keycloak_admin_password: "changeme" + keycloak_admin_password: "remembertochangeme" keycloak_rhsso_enable: True keycloak_rhsso_download_url: "" # This should be the full of remote source rhsso zip file and can contain basic authentication credentials ``` -* The following is an example playbook that makes use of the role to install Red Hat Single Sign-On from the controller node: +* The following is an example playbook that makes use of the role to install Red Hat Single Sign-On offline from the controller node, and apply latest cumulative patch: ```yaml --- @@ -235,9 +233,10 @@ _NOTE_: use ansible vaults or other security systems for storing credentials. include_role: name: keycloak vars: - keycloak_admin_password: "changeme" + keycloak_admin_password: "remembertochangeme" keycloak_rhsso_enable: True keycloak_offline_install: True + keycloak_rhsso_apply_patches: True # This should be the filename of rhsso zip file on Ansible node: rh-sso-7.5-server-dist.zip ``` diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index cfa80fd..c9d8d29 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -13,7 +13,7 @@ keycloak_rhsso_archive: "rh-sso-{{ keycloak_rhsso_version }}-server-dist.zip" keycloak_rhsso_installdir: "{{ keycloak_dest }}/rh-sso-{{ keycloak_rhsso_version | regex_replace('^([0-9])\\.([0-9]*).*', '\\1.\\2') }}" keycloak_rhn_url: 'https://access.redhat.com/jbossnetwork/restricted/softwareDownload.html?softwareId=' keycloak_rhsso_download_url: "{{ keycloak_rhn_url }}{{ rhsso_rhn_id }}" -keycloak_rhsso_apply_patches: True +keycloak_rhsso_apply_patches: False ### keycloak/rhsso choice: by default install rhsso if rhn credentials are defined keycloak_rhsso_enable: "{{ True if rhsso_rhn_id is defined and rhn_username is defined and rhn_password is defined else False }}" diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index ba2ecdd..3c428c9 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -48,7 +48,7 @@ argument_specs: type: "str" keycloak_rhsso_apply_patches: # line 16 of keycloak/defaults/main.yml - default: true + default: false description: "Install RHSSO more recent cumulative patch" type: "bool" keycloak_rhsso_installdir: From 494a1c518ba577117634fbd5529b0b78e7bddc39 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 25 Mar 2022 11:07:51 +0100 Subject: [PATCH 031/554] docs: add changelogs --- CHANGELOG.rst | 24 ++++++++++++++++++++++++ changelogs/changelog.yaml | 16 ++++++++++++++++ changelogs/config.yaml | 32 ++++++++++++++++++++++++++++++++ changelogs/fragments/.git-keep | 0 docs/CHANGELOG.rst | 1 + galaxy.yml | 7 ++++--- 6 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 CHANGELOG.rst create mode 100644 changelogs/changelog.yaml create mode 100644 changelogs/config.yaml create mode 100644 changelogs/fragments/.git-keep create mode 120000 docs/CHANGELOG.rst diff --git a/CHANGELOG.rst b/CHANGELOG.rst new file mode 100644 index 0000000..ada0d32 --- /dev/null +++ b/CHANGELOG.rst @@ -0,0 +1,24 @@ +============================================ +middleware_automation.keycloak Release Notes +============================================ + +.. contents:: Topics + +This changelog describes changes after version 0.2.6 + +v1.0.1 +====== + +Release Summary +--------------- + +Documentation fixes to reflect the correct module names. + + +v1.0.0 +====== + +Release Summary +--------------- + +This is the first stable release of the ``middleware_automation.keycloak`` collection. diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml new file mode 100644 index 0000000..fac497d --- /dev/null +++ b/changelogs/changelog.yaml @@ -0,0 +1,16 @@ +ancestor: 0.2.6 +releases: + 1.0.0: + changes: + release_summary: | + This is the first stable release of the ``middleware_automation.keycloak`` collection. + release_date: '2022-03-04' + 1.0.1: + changes: + minor_changes: + - apply latest cumulative patch of RH-SSO automatically when new parameter ``keycloak_rhsso_apply_patches`` is ``true`` + bugfixes: + - clustered installs now perform database initialization on first node to avoid locking issues + release_summary: | + Minor enhancements, bug and documentation fixes. + release_date: '2022-03-11' \ No newline at end of file diff --git a/changelogs/config.yaml b/changelogs/config.yaml new file mode 100644 index 0000000..374ae65 --- /dev/null +++ b/changelogs/config.yaml @@ -0,0 +1,32 @@ +--- +changelog_filename_template: ../CHANGELOG.rst +changelog_filename_version_depth: 0 +changes_file: changelog.yaml +changes_format: combined +ignore_other_fragment_extensions: true +keep_fragments: false +mention_ancestor: true +new_plugins_after_name: removed_features +notesdir: fragments +prelude_section_name: release_summary +prelude_section_title: Release Summary +sections: +- - major_changes + - Major Changes +- - minor_changes + - Minor Changes +- - breaking_changes + - Breaking Changes / Porting Guide +- - deprecated_features + - Deprecated Features +- - removed_features + - Removed Features +- - security_fixes + - Security Fixes +- - bugfixes + - Bugfixes +- - known_issues + - Known Issues +title: middleware_automation.keycloak +trivial_section_name: trivial +use_fqcn: true diff --git a/changelogs/fragments/.git-keep b/changelogs/fragments/.git-keep new file mode 100644 index 0000000..e69de29 diff --git a/docs/CHANGELOG.rst b/docs/CHANGELOG.rst new file mode 120000 index 0000000..e22698b --- /dev/null +++ b/docs/CHANGELOG.rst @@ -0,0 +1 @@ +../CHANGELOG.rst \ No newline at end of file diff --git a/galaxy.yml b/galaxy.yml index 32007fb..195f396 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.0.1" +version: "1.0.2" readme: README.md authors: - Romain Pelisse @@ -22,12 +22,13 @@ tags: - authentication dependencies: "middleware_automation.redhat_csp_download": ">=1.2.1" - "middleware_automation.wildfly": ">=0.0.6" + "middleware_automation.wildfly": ">=1.0.0" repository: https://github.com/ansible-middleware/keycloak documentation: https://ansible-middleware.github.io/keycloak homepage: https://github.com/ansible-middleware/keycloak issues: https://github.com/ansible-middleware/keycloak/issues build_ignore: - molecule - - docs - .github + - '*.tar.gz' + - '*.zip' \ No newline at end of file From fc780599b0c644e2fcd192a4bc1017dd0f40083c Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 25 Mar 2022 11:21:55 +0100 Subject: [PATCH 032/554] add antsibull generated changelog --- .gitignore | 1 + CHANGELOG.rst | 15 +++++++++++++-- changelogs/fragments/.git-keep | 0 changelogs/fragments/.gitignore | 2 ++ 4 files changed, 16 insertions(+), 2 deletions(-) delete mode 100644 changelogs/fragments/.git-keep create mode 100644 changelogs/fragments/.gitignore diff --git a/.gitignore b/.gitignore index f10cc78..ef79fe9 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ docs/_build/ .pytest_cache/ .mypy_cache/ *.retry +changelogs/.plugin-cache.yaml diff --git a/CHANGELOG.rst b/CHANGELOG.rst index ada0d32..24f1090 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,7 +4,7 @@ middleware_automation.keycloak Release Notes .. contents:: Topics -This changelog describes changes after version 0.2.6 +This changelog describes changes after version 0.2.6. v1.0.1 ====== @@ -12,9 +12,19 @@ v1.0.1 Release Summary --------------- -Documentation fixes to reflect the correct module names. +Minor enhancements, bug and documentation fixes. +Minor Changes +------------- + +- apply latest cumulative patch of RH-SSO automatically when new parameter ``keycloak_rhsso_apply_patches`` is ``true`` + +Bugfixes +-------- + +- clustered installs now perform database initialization on first node to avoid locking issues + v1.0.0 ====== @@ -22,3 +32,4 @@ Release Summary --------------- This is the first stable release of the ``middleware_automation.keycloak`` collection. + diff --git a/changelogs/fragments/.git-keep b/changelogs/fragments/.git-keep deleted file mode 100644 index e69de29..0000000 diff --git a/changelogs/fragments/.gitignore b/changelogs/fragments/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/changelogs/fragments/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore From 63f31fe258b1fec48a086079cf8a2915e4f1d9af Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 25 Mar 2022 18:22:55 +0100 Subject: [PATCH 033/554] Add gitignore to ansible-test sanity excludes --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9a72e5c..7c96b1d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,7 +40,7 @@ jobs: mkdir -p /home/runner/.ansible/collections/ansible_collections - name: Run sanity tests - run: ansible-test sanity --docker -v --color --python ${{ matrix.python_version }} + run: ansible-test sanity --docker -v --color --python ${{ matrix.python_version }} --exclude changelogs/fragments/.gitignore working-directory: ./ansible_collections/middleware_automation/keycloak - name: Run molecule test From 609147729447acef7e33e5c55d2b2d8bf38793ba Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 30 Mar 2022 17:31:15 +0200 Subject: [PATCH 034/554] ci: generate changelog fragments from PR messages --- .github/workflows/docs.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index c55a637..cb37a49 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -6,6 +6,7 @@ on: - main tags: - "[0-9]+.[0-9]+.[0-9]+" + pull_request: env: COLORTERM: 'yes' @@ -40,6 +41,7 @@ jobs: python -m pip install --upgrade pip pip install -r ansible_collections/middleware_automation/keycloak/docs/requirements.txt pip install -r ansible_collections/middleware_automation/keycloak/requirements.txt + sudo apt install -y sed hub - name: Create default collection path run: | @@ -53,6 +55,27 @@ jobs: for role_readme in roles/*/README.md; do ln -f -s ../../$role_readme ./docs/roles/$(basename $(dirname $role_readme)).md; echo " * :doc:\`$(basename $(dirname $role_readme))\`" >> ./docs/roles/index.rst; done working-directory: ansible_collections/middleware_automation/keycloak + - name: Scan PR merges from latest tag + run: | + TYPES=("minor_changes" "major_changes" "bugfixes" "deprecated_features" "removed_features") + TAG=$(git describe --abbrev=0 --tags) + PRS=($(comm -12 <(git log --oneline ${TAG}.. --format="tformat:%H" | sort ) <(hub pr list -s all -f '%sm%n' --color=never | sort ))) + IFS=$'\n' FRAGMENTS=($(hub pr list -s all -f '%sm~%I~%L~%t~%n' --color=never| grep -P "$(echo "^(${PRS[@]})" | tr ' ' '|')")) + for frag in "${FRAGMENTS[@]}"; do + PR=$(echo $frag|cut -d~ -f2) + type="$(echo $frag|cut -d~ -f3)" + msg="$(echo $frag|cut -d~ -f4|sed 's/`/``/g')" + if [[ "${TYPES[*]}" =~ "${type}" ]]; then + echo -e "$type:\n - >\n $msg \`#${PR}\`" \ + > changelogs/fragments/${PR}.yaml + fi + done + antsibull-changelog lint -vvv + antsibull-changelog generate + working-directory: ansible_collections/middleware_automation/keycloak + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Run sphinx run: | sphinx-build -M html . _build -v From 5a45d1f4f888a392e339827e9fee4926dba8701e Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 31 Mar 2022 14:56:41 +0200 Subject: [PATCH 035/554] add prerelease to docs wf, generate on release wf --- .github/workflows/docs.yml | 5 ++- .github/workflows/release.yml | 73 +++++++++++++++++++++++++++++------ 2 files changed, 65 insertions(+), 13 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index cb37a49..55eaada 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -6,7 +6,6 @@ on: - main tags: - "[0-9]+.[0-9]+.[0-9]+" - pull_request: env: COLORTERM: 'yes' @@ -71,7 +70,9 @@ jobs: fi done antsibull-changelog lint -vvv - antsibull-changelog generate + if [[ "${{github.ref}}" == "refs/heads/main" ]]; then + antsibull-changelog release --version "prerelease-$(grep version galaxy.yml | awk -F'"' '{ print $2 }')" + fi working-directory: ansible_collections/middleware_automation/keycloak env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index aafcfb1..30e480f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,30 +1,86 @@ --- name: Release collection on: - push: - tags: - - "[0-9]+.[0-9]+.[0-9]+" + workflow_dispatch: jobs: release: runs-on: ubuntu-latest + if: github.repository == 'ansible-middleware/keycloak' + permissions: + actions: write + checks: write + contents: write + deployments: write + packages: write + pages: write steps: - name: Checkout code uses: actions/checkout@v2 + - name: Fetch tags + run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* - name: Set up Python uses: actions/setup-python@v1 with: python-version: "3.x" - - name: Get Tag Version + - name: Get current version id: get_version - run: echo ::set-output name=TAG_VERSION::${GITHUB_REF#refs/tags/} + run: echo "::set-output name=TAG_VERSION::$(grep version galaxy.yml | awk -F'"' '{ print $2 }')" + - name: Check if tag exists + id: check_tag + run: echo "::set-output name=TAG_EXISTS::$(git tag | grep ${{ steps.get_version.outputs.TAG_VERSION }})" + - name: Fail if tag exists + if: ${{ steps.get_version.outputs.TAG_VERSION == steps.check_tag.outputs.TAG_EXISTS }} + uses: actions/github-script@v3 + with: + script: | + core.setFailed('Release tag already exists') - name: Install dependencies run: | python -m pip install --upgrade pip pip install ansible-core + sudo apt install -y sed hub - name: Build collection run: | ansible-galaxy collection build . + - name: Scan PR merges from latest tag + run: | + TYPES=("minor_changes" "major_changes" "bugfixes" "deprecated_features" "removed_features") + TAG=$(git describe --abbrev=0 --tags) + PRS=($(comm -12 <(git log --oneline ${TAG}.. --format="tformat:%H" | sort ) <(hub pr list -s all -f '%sm%n' --color=never | sort ))) + IFS=$'\n' FRAGMENTS=($(hub pr list -s all -f '%sm~%I~%L~%t~%n' --color=never| grep -P "$(echo "^(${PRS[@]})" | tr ' ' '|')")) + for frag in "${FRAGMENTS[@]}"; do + PR=$(echo $frag|cut -d~ -f2) + type="$(echo $frag|cut -d~ -f3)" + msg="$(echo $frag|cut -d~ -f4|sed 's/`/``/g')" + if [[ "${TYPES[*]}" =~ "${type}" ]]; then + echo -e "$type:\n - >\n $msg \`#${PR}\`" \ + > changelogs/fragments/${PR}.yaml + fi + done + antsibull-changelog lint -vvv + antsibull-changelog generate + antsibull-changelog release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Commit changelogs + run: | + git config user.name github-actions + git config user.email github-actions@github.com + git add CHANGELOG.rst changelogs/changelog.yaml + git commit -m "Update changelog for release ${{ steps.get_version.outputs.TAG_VERSION }}" || true + git push origin + - name: Publish collection + env: + ANSIBLE_GALAXY_API_KEY: ${{ secrets.ANSIBLE_GALAXY_API_KEY }} + run: | + ansible-galaxy collection publish *.tar.gz --api-key $ANSIBLE_GALAXY_API_KEY + - name: Create release tag + run: | + git config user.name github-actions + git config user.email github-actions@github.com + git tag -a ${{ steps.get_version.outputs.TAG_VERSION }}" -m "Release v${{ steps.get_version.outputs.TAG_VERSION }}" || true + git push origin --tags - name: Publish Release uses: softprops/action-gh-release@v1 env: @@ -32,11 +88,6 @@ jobs: with: files: "*.tar.gz" body: "Release v${{ steps.get_version.outputs.TAG_VERSION }}" - - name: Publish collection - env: - ANSIBLE_GALAXY_API_KEY: ${{ secrets.ANSIBLE_GALAXY_API_KEY }} - run: | - ansible-galaxy collection publish *.tar.gz --api-key $ANSIBLE_GALAXY_API_KEY dispatch: needs: release strategy: @@ -49,5 +100,5 @@ jobs: with: token: ${{ secrets.TRIGGERING_PAT }} repository: ${{ matrix.repo }} - event-type: "Dependency released - Keycloak" + event-type: "Dependency released - Keycloak v${{ steps.get_version.outputs.TAG_VERSION }}" client-payload: '{ "github": ${{toJson(github)}} }' From c166c643fc157c281f81d7ae8e1bbc5738265e38 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 31 Mar 2022 15:04:55 +0200 Subject: [PATCH 036/554] docs: set -devel version for main branch --- .github/workflows/docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 55eaada..950a4df 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -71,7 +71,7 @@ jobs: done antsibull-changelog lint -vvv if [[ "${{github.ref}}" == "refs/heads/main" ]]; then - antsibull-changelog release --version "prerelease-$(grep version galaxy.yml | awk -F'"' '{ print $2 }')" + antsibull-changelog release --version "$(grep version galaxy.yml | awk -F'"' '{ print $2 }')-devel" -v fi working-directory: ansible_collections/middleware_automation/keycloak env: From 9ee6788f98844a321edeb82d26ce9fed87bd99ee Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 31 Mar 2022 15:13:30 +0200 Subject: [PATCH 037/554] docs: workaround unstaged file when checking out gh-pages --- .github/workflows/docs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 950a4df..0fbd0a8 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -86,6 +86,7 @@ jobs: run: | git config user.name github-actions git config user.email github-actions@github.com + git stash git checkout gh-pages rm -rf $(basename ${GITHUB_REF}) mv docs/_build/html $(basename ${GITHUB_REF}) From b974bf1967afff9128993de2807b873c2ede6700 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 31 Mar 2022 15:30:23 +0200 Subject: [PATCH 038/554] docs: absolute links in READMEs --- .github/workflows/docs.yml | 2 +- README.md | 10 +++++----- docs/index.rst | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 0fbd0a8..b867bca 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -65,7 +65,7 @@ jobs: type="$(echo $frag|cut -d~ -f3)" msg="$(echo $frag|cut -d~ -f4|sed 's/`/``/g')" if [[ "${TYPES[*]}" =~ "${type}" ]]; then - echo -e "$type:\n - >\n $msg \`#${PR}\`" \ + echo -e "$type:\n - >\n $msg \`#${PR}\`_" \ > changelogs/fragments/${PR}.yaml fi done diff --git a/README.md b/README.md index 9006532..581e882 100644 --- a/README.md +++ b/README.md @@ -50,12 +50,12 @@ A requirement file is provided to install: ### Install Playbook -* [`playbooks/keycloak.yml`](playbooks/keycloak.yml) installs the upstream(Keycloak) based on the defined variables. -* [`playbooks/rhsso.yml`](playbooks/rhsso.yml) installs Red Hat Single Sign-On(RHSSO) based on defined variables. +* [`playbooks/keycloak.yml`](https://github.com/ansible-middleware/keycloak/blob/main/playbooks/keycloak.yml) installs the upstream(Keycloak) based on the defined variables. +* [`playbooks/rhsso.yml`](https://github.com/ansible-middleware/keycloak/blob/main/playbooks/rhsso.yml) installs Red Hat Single Sign-On(RHSSO) based on defined variables. Both playbooks include the `keycloak` role, with different settings, as described in the following sections. -For full service configuration details, refer to the [keycloak role README](roles/keycloak/README.md). +For full service configuration details, refer to the [keycloak role README](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak/README.md). ### Choosing between upstream project (Keycloak) and Red Hat Single Sign-On (RHSSO) @@ -134,7 +134,7 @@ ansible-playbook -i -e @rhn-creds.yml playbooks/keycloak.yml -e ### Config Playbook -[`playbooks/keycloak_realm.yml`](playbooks/keycloak_realm.yml) creates or updates provided realm, user federation(s), client(s), client role(s) and client user(s). +[`playbooks/keycloak_realm.yml`](https://github.com/ansible-middleware/keycloak/blob/main/playbooks/keycloak_realm.yml) creates or updates provided realm, user federation(s), client(s), client role(s) and client user(s). ### Example configuration command @@ -154,7 +154,7 @@ ansible-playbook -i playbooks/keycloak_realm.yml -e keycloak_adm localhost ansible_connection=local ``` -For full configuration details, refer to the [keycloak_realm role README](roles/keycloak_realm/README.md). +For full configuration details, refer to the [keycloak_realm role README](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak_realm/README.md). ## Support diff --git a/docs/index.rst b/docs/index.rst index dc5034f..d9bfa5f 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -15,8 +15,8 @@ Welcome to Keycloak Collection documentation :maxdepth: 2 :caption: Developer documentation - developing testing + developing releasing .. toctree:: From b91c9e17fc17cf552a7d4c54981721b377617e3d Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 31 Mar 2022 15:40:16 +0200 Subject: [PATCH 039/554] docs: fix typo in href target generation --- .github/workflows/docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index b867bca..493b818 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -65,7 +65,7 @@ jobs: type="$(echo $frag|cut -d~ -f3)" msg="$(echo $frag|cut -d~ -f4|sed 's/`/``/g')" if [[ "${TYPES[*]}" =~ "${type}" ]]; then - echo -e "$type:\n - >\n $msg \`#${PR}\`_" \ + echo -e "$type:\n - >\n $msg \`#${PR} \`_" \ > changelogs/fragments/${PR}.yaml fi done From bada6f40733ec8eea24d686e5ef18be4fc9a6798 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 31 Mar 2022 15:54:30 +0200 Subject: [PATCH 040/554] docs: add changelog breaking_change type --- .github/workflows/docs.yml | 2 +- .github/workflows/release.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 493b818..3901e7c 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -56,7 +56,7 @@ jobs: - name: Scan PR merges from latest tag run: | - TYPES=("minor_changes" "major_changes" "bugfixes" "deprecated_features" "removed_features") + TYPES=("minor_changes" "major_changes" "bugfixes" "deprecated_features" "removed_features" "breaking_changes") TAG=$(git describe --abbrev=0 --tags) PRS=($(comm -12 <(git log --oneline ${TAG}.. --format="tformat:%H" | sort ) <(hub pr list -s all -f '%sm%n' --color=never | sort ))) IFS=$'\n' FRAGMENTS=($(hub pr list -s all -f '%sm~%I~%L~%t~%n' --color=never| grep -P "$(echo "^(${PRS[@]})" | tr ' ' '|')")) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 30e480f..2471420 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -38,14 +38,14 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install ansible-core + pip install ansible-core antsibull sudo apt install -y sed hub - name: Build collection run: | ansible-galaxy collection build . - name: Scan PR merges from latest tag run: | - TYPES=("minor_changes" "major_changes" "bugfixes" "deprecated_features" "removed_features") + TYPES=("minor_changes" "major_changes" "bugfixes" "deprecated_features" "removed_features" "breaking_changes") TAG=$(git describe --abbrev=0 --tags) PRS=($(comm -12 <(git log --oneline ${TAG}.. --format="tformat:%H" | sort ) <(hub pr list -s all -f '%sm%n' --color=never | sort ))) IFS=$'\n' FRAGMENTS=($(hub pr list -s all -f '%sm~%I~%L~%t~%n' --color=never| grep -P "$(echo "^(${PRS[@]})" | tr ' ' '|')")) @@ -54,7 +54,7 @@ jobs: type="$(echo $frag|cut -d~ -f3)" msg="$(echo $frag|cut -d~ -f4|sed 's/`/``/g')" if [[ "${TYPES[*]}" =~ "${type}" ]]; then - echo -e "$type:\n - >\n $msg \`#${PR}\`" \ + echo -e "$type:\n - >\n $msg \`#${PR}\`_" \ > changelogs/fragments/${PR}.yaml fi done From d3f9b0ca869fd5cc33c2ae64ecb450d8743e620d Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 31 Mar 2022 16:12:04 +0200 Subject: [PATCH 041/554] docs: add PR link to previous releases --- CHANGELOG.rst | 12 ++++++------ changelogs/changelog.yaml | 8 ++++---- playbooks/keycloak.yml | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 24f1090..6ed132d 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -15,15 +15,15 @@ Release Summary Minor enhancements, bug and documentation fixes. +Major Changes +------------- + +- Apply latest cumulative patch of RH-SSO automatically when new parameter ``keycloak_rhsso_apply_patches`` is ``true`` `#18 `_ + Minor Changes ------------- -- apply latest cumulative patch of RH-SSO automatically when new parameter ``keycloak_rhsso_apply_patches`` is ``true`` - -Bugfixes --------- - -- clustered installs now perform database initialization on first node to avoid locking issues +- Clustered installs now perform database initialization on first node to avoid locking issues `#17 `_ v1.0.0 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index fac497d..ae3cf9d 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -7,10 +7,10 @@ releases: release_date: '2022-03-04' 1.0.1: changes: + major_changes: + - Apply latest cumulative patch of RH-SSO automatically when new parameter ``keycloak_rhsso_apply_patches`` is ``true`` `#18 `_ minor_changes: - - apply latest cumulative patch of RH-SSO automatically when new parameter ``keycloak_rhsso_apply_patches`` is ``true`` - bugfixes: - - clustered installs now perform database initialization on first node to avoid locking issues + - Clustered installs now perform database initialization on first node to avoid locking issues `#17 `_ release_summary: | Minor enhancements, bug and documentation fixes. - release_date: '2022-03-11' \ No newline at end of file + release_date: '2022-03-11' diff --git a/playbooks/keycloak.yml b/playbooks/keycloak.yml index 020c1f7..39697bc 100644 --- a/playbooks/keycloak.yml +++ b/playbooks/keycloak.yml @@ -2,7 +2,7 @@ - name: Playbook for Keycloak Hosts hosts: keycloak vars: - keycloak_admin_password: "changeme" + keycloak_admin_password: "remembertochangeme" collections: - middleware_automation.keycloak roles: From 9365d38162047e142adbfb8ee0085bdd836717f6 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 31 Mar 2022 16:51:25 +0200 Subject: [PATCH 042/554] docs: add role index to toctree --- .github/workflows/docs.yml | 5 ++++- .github/workflows/release.yml | 13 +++++++++++++ docs/roles.rst.template | 1 + 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 3901e7c..28ae026 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -51,7 +51,10 @@ jobs: mkdir -p ./docs/plugins ./docs/roles cat ./docs/roles.rst.template > ./docs/roles/index.rst antsibull-docs collection --use-current --squash-hierarchy --dest-dir docs/plugins middleware_automation.keycloak - for role_readme in roles/*/README.md; do ln -f -s ../../$role_readme ./docs/roles/$(basename $(dirname $role_readme)).md; echo " * :doc:\`$(basename $(dirname $role_readme))\`" >> ./docs/roles/index.rst; done + for role_readme in roles/*/README.md; do + ln -f -s ../../$role_readme ./docs/roles/$(basename $(dirname $role_readme)).md + echo " $(basename $(dirname $role_readme))" >> ./docs/roles/index.rst + done working-directory: ansible_collections/middleware_automation/keycloak - name: Scan PR merges from latest tag diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2471420..a99d01d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,32 +17,40 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v2 + - name: Fetch tags run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* + - name: Set up Python uses: actions/setup-python@v1 with: python-version: "3.x" + - name: Get current version id: get_version run: echo "::set-output name=TAG_VERSION::$(grep version galaxy.yml | awk -F'"' '{ print $2 }')" + - name: Check if tag exists id: check_tag run: echo "::set-output name=TAG_EXISTS::$(git tag | grep ${{ steps.get_version.outputs.TAG_VERSION }})" + - name: Fail if tag exists if: ${{ steps.get_version.outputs.TAG_VERSION == steps.check_tag.outputs.TAG_EXISTS }} uses: actions/github-script@v3 with: script: | core.setFailed('Release tag already exists') + - name: Install dependencies run: | python -m pip install --upgrade pip pip install ansible-core antsibull sudo apt install -y sed hub + - name: Build collection run: | ansible-galaxy collection build . + - name: Scan PR merges from latest tag run: | TYPES=("minor_changes" "major_changes" "bugfixes" "deprecated_features" "removed_features" "breaking_changes") @@ -63,6 +71,7 @@ jobs: antsibull-changelog release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Commit changelogs run: | git config user.name github-actions @@ -70,17 +79,20 @@ jobs: git add CHANGELOG.rst changelogs/changelog.yaml git commit -m "Update changelog for release ${{ steps.get_version.outputs.TAG_VERSION }}" || true git push origin + - name: Publish collection env: ANSIBLE_GALAXY_API_KEY: ${{ secrets.ANSIBLE_GALAXY_API_KEY }} run: | ansible-galaxy collection publish *.tar.gz --api-key $ANSIBLE_GALAXY_API_KEY + - name: Create release tag run: | git config user.name github-actions git config user.email github-actions@github.com git tag -a ${{ steps.get_version.outputs.TAG_VERSION }}" -m "Release v${{ steps.get_version.outputs.TAG_VERSION }}" || true git push origin --tags + - name: Publish Release uses: softprops/action-gh-release@v1 env: @@ -88,6 +100,7 @@ jobs: with: files: "*.tar.gz" body: "Release v${{ steps.get_version.outputs.TAG_VERSION }}" + dispatch: needs: release strategy: diff --git a/docs/roles.rst.template b/docs/roles.rst.template index b025af6..52dfdcd 100644 --- a/docs/roles.rst.template +++ b/docs/roles.rst.template @@ -1,3 +1,4 @@ Role Index ========== +.. toctree:: From 28ff78d809933cde6c8af6f63831e92557a2ddbf Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 1 Apr 2022 10:57:42 +0200 Subject: [PATCH 043/554] docs: changelog pasted into github release page --- .github/workflows/release.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a99d01d..5e03fb1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -76,6 +76,7 @@ jobs: run: | git config user.name github-actions git config user.email github-actions@github.com + git diff --minimal --output-indicator-new=' ' -U0 --no-indent-heuristic CHANGELOG.rst | grep "^ "| sed -e 's/`\(#[0-9]\+\) <.*_/\1/g' > gh-release.md git add CHANGELOG.rst changelogs/changelog.yaml git commit -m "Update changelog for release ${{ steps.get_version.outputs.TAG_VERSION }}" || true git push origin @@ -98,8 +99,9 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: + tag_name: ${{ steps.get_version.outputs.TAG_VERSION }} files: "*.tar.gz" - body: "Release v${{ steps.get_version.outputs.TAG_VERSION }}" + body_path: gh-release.md dispatch: needs: release From 4e6ea2f1cab334ae2f19aaa2b3785643247ebd9f Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 1 Apr 2022 12:14:09 +0200 Subject: [PATCH 044/554] ci: release wf uses deep clone --- .github/workflows/release.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5e03fb1..d3ceb1d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,10 +16,9 @@ jobs: pages: write steps: - name: Checkout code - uses: actions/checkout@v2 - - - name: Fetch tags - run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* + uses: actions/checkout@v3 + with: + fetch-depth: 0 - name: Set up Python uses: actions/setup-python@v1 From 5cbe905dda74f7f75ef965ad11111997c1828207 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 1 Apr 2022 12:53:56 +0200 Subject: [PATCH 045/554] docs: restructuredtext link needs separator --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d3ceb1d..48c29ac 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -61,7 +61,7 @@ jobs: type="$(echo $frag|cut -d~ -f3)" msg="$(echo $frag|cut -d~ -f4|sed 's/`/``/g')" if [[ "${TYPES[*]}" =~ "${type}" ]]; then - echo -e "$type:\n - >\n $msg \`#${PR}\`_" \ + echo -e "$type:\n - >\n $msg \`#${PR} \`_" \ > changelogs/fragments/${PR}.yaml fi done From fddfa9a49300d40e555bba4be5e1723ace1d46dc Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 1 Apr 2022 10:57:28 +0000 Subject: [PATCH 046/554] Update changelog for release 1.0.2 --- CHANGELOG.rst | 14 ++++++++++++++ changelogs/changelog.yaml | 36 ++++++++++++++++++++++++++++++------ 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 6ed132d..4644d47 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,20 @@ middleware_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v1.0.2 +====== + +Minor Changes +------------- + +- Make ``keycloak_admin_password`` a default with assert (was: role variable) `#26 `_ +- Simplify dependency install logic and reduce play execution time `#19 `_ + +Bugfixes +-------- + +- Set ``keycloak_frontend_url`` default according to other defaults `#25 `_ + v1.0.1 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index ae3cf9d..6200619 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -2,15 +2,39 @@ ancestor: 0.2.6 releases: 1.0.0: changes: - release_summary: | - This is the first stable release of the ``middleware_automation.keycloak`` collection. + release_summary: 'This is the first stable release of the ``middleware_automation.keycloak`` + collection. + + ' release_date: '2022-03-04' 1.0.1: changes: major_changes: - - Apply latest cumulative patch of RH-SSO automatically when new parameter ``keycloak_rhsso_apply_patches`` is ``true`` `#18 `_ + - Apply latest cumulative patch of RH-SSO automatically when new parameter ``keycloak_rhsso_apply_patches`` + is ``true`` `#18 `_ minor_changes: - - Clustered installs now perform database initialization on first node to avoid locking issues `#17 `_ - release_summary: | - Minor enhancements, bug and documentation fixes. + - Clustered installs now perform database initialization on first node to avoid + locking issues `#17 `_ + release_summary: 'Minor enhancements, bug and documentation fixes. + + ' release_date: '2022-03-11' + 1.0.2: + changes: + bugfixes: + - 'Set ``keycloak_frontend_url`` default according to other defaults `#25 `_ + + ' + minor_changes: + - 'Make ``keycloak_admin_password`` a default with assert (was: role variable) + `#26 `_ + + ' + - 'Simplify dependency install logic and reduce play execution time `#19 `_ + + ' + fragments: + - 19.yaml + - 25.yaml + - 26.yaml + release_date: '2022-04-01' From 9d5705727290293d6384d64dbd8555362f22d497 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 1 Apr 2022 13:06:34 +0200 Subject: [PATCH 047/554] docs: fix unbalanced quotes in release workflow --- .github/workflows/docs.yml | 33 ++++++++++++++++++++------------- .github/workflows/release.yml | 2 +- galaxy.yml | 2 +- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 28ae026..4f42680 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -61,20 +61,27 @@ jobs: run: | TYPES=("minor_changes" "major_changes" "bugfixes" "deprecated_features" "removed_features" "breaking_changes") TAG=$(git describe --abbrev=0 --tags) - PRS=($(comm -12 <(git log --oneline ${TAG}.. --format="tformat:%H" | sort ) <(hub pr list -s all -f '%sm%n' --color=never | sort ))) - IFS=$'\n' FRAGMENTS=($(hub pr list -s all -f '%sm~%I~%L~%t~%n' --color=never| grep -P "$(echo "^(${PRS[@]})" | tr ' ' '|')")) - for frag in "${FRAGMENTS[@]}"; do - PR=$(echo $frag|cut -d~ -f2) - type="$(echo $frag|cut -d~ -f3)" - msg="$(echo $frag|cut -d~ -f4|sed 's/`/``/g')" - if [[ "${TYPES[*]}" =~ "${type}" ]]; then - echo -e "$type:\n - >\n $msg \`#${PR} \`_" \ - > changelogs/fragments/${PR}.yaml - fi - done - antsibull-changelog lint -vvv if [[ "${{github.ref}}" == "refs/heads/main" ]]; then - antsibull-changelog release --version "$(grep version galaxy.yml | awk -F'"' '{ print $2 }')-devel" -v + PRS=($(comm -12 <(git log --oneline ${TAG}.. --format="tformat:%H" | sort ) <(hub pr list -s all -f '%sm%n' --color=never | sort ))) + else + PREV_TAG=$(git tag | grep -P "^[0-9]+[.][0-9]+[.][0-9]+$" | sort --version-sort -r | head -n2 | grep -v "${TAG}") + PRS=($(comm -12 <(git log --oneline ${PREV_TAG}..${TAG} --format="tformat:%H" | sort ) <(hub pr list -s all -f '%sm%n' --color=never | sort ))) + fi + if [[ ${#PRS[@]} > 0 ]]; then + IFS=$'\n' FRAGMENTS=($(hub pr list -s all -f '%sm~%I~%L~%t~%n' --color=never | grep -P "$(echo "^(${PRS[@]})" | tr ' ' '|')")) + for frag in "${FRAGMENTS[@]}"; do + PR=$(echo $frag|cut -d~ -f2) + type="$(echo $frag|cut -d~ -f3)" + msg="$(echo $frag|cut -d~ -f4|sed 's/`/``/g')" + if [[ "${TYPES[*]}" =~ "${type}" ]]; then + echo -e "$type:\n - >\n $msg \`#${PR} \`_" \ + > changelogs/fragments/${PR}.yaml + fi + done + antsibull-changelog lint -vvv + if [[ "${{github.ref}}" == "refs/heads/main" ]]; then + antsibull-changelog release --version "$(grep version galaxy.yml | awk -F'"' '{ print $2 }')-devel" -v + fi fi working-directory: ansible_collections/middleware_automation/keycloak env: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 48c29ac..a95c5ad 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -90,7 +90,7 @@ jobs: run: | git config user.name github-actions git config user.email github-actions@github.com - git tag -a ${{ steps.get_version.outputs.TAG_VERSION }}" -m "Release v${{ steps.get_version.outputs.TAG_VERSION }}" || true + git tag -a ${{ steps.get_version.outputs.TAG_VERSION }} -m "Release v${{ steps.get_version.outputs.TAG_VERSION }}" || true git push origin --tags - name: Publish Release diff --git a/galaxy.yml b/galaxy.yml index 195f396..0e6d34d 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -31,4 +31,4 @@ build_ignore: - molecule - .github - '*.tar.gz' - - '*.zip' \ No newline at end of file + - '*.zip' From 29aaafb9e4920540a801a16b9caa0b6d6a8d50e3 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 1 Apr 2022 21:41:52 +0200 Subject: [PATCH 048/554] ci: changelogs skip unlabeled PRs --- .github/workflows/docs.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 4f42680..80f3128 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -73,7 +73,7 @@ jobs: PR=$(echo $frag|cut -d~ -f2) type="$(echo $frag|cut -d~ -f3)" msg="$(echo $frag|cut -d~ -f4|sed 's/`/``/g')" - if [[ "${TYPES[*]}" =~ "${type}" ]]; then + if [[ "$type" != "" && "${TYPES[*]}" =~ "${type}" ]]; then echo -e "$type:\n - >\n $msg \`#${PR} \`_" \ > changelogs/fragments/${PR}.yaml fi diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a95c5ad..9a497a9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -60,7 +60,7 @@ jobs: PR=$(echo $frag|cut -d~ -f2) type="$(echo $frag|cut -d~ -f3)" msg="$(echo $frag|cut -d~ -f4|sed 's/`/``/g')" - if [[ "${TYPES[*]}" =~ "${type}" ]]; then + if [[ "$type" != "" && "${TYPES[*]}" =~ "${type}" ]]; then echo -e "$type:\n - >\n $msg \`#${PR} \`_" \ > changelogs/fragments/${PR}.yaml fi From a62f26648f180dee8fe066952d93005d0f7796bc Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 4 Apr 2022 17:35:22 +0200 Subject: [PATCH 049/554] bump version, use git describe for -devel changelogs --- .github/workflows/docs.yml | 2 +- galaxy.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 80f3128..0162c82 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -80,7 +80,7 @@ jobs: done antsibull-changelog lint -vvv if [[ "${{github.ref}}" == "refs/heads/main" ]]; then - antsibull-changelog release --version "$(grep version galaxy.yml | awk -F'"' '{ print $2 }')-devel" -v + antsibull-changelog release --version "$(git describe --tags)" -v fi fi working-directory: ansible_collections/middleware_automation/keycloak diff --git a/galaxy.yml b/galaxy.yml index 0e6d34d..a697240 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.0.2" +version: "1.0.3" readme: README.md authors: - Romain Pelisse From c7b6bc1d6192a3033f9f5ce9f329be08b7f57048 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 7 Apr 2022 08:53:43 +0200 Subject: [PATCH 050/554] ci: docs wf uses custom action --- .github/workflows/docs.yml | 74 +++++++------------------------------- 1 file changed, 12 insertions(+), 62 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 0162c82..d81f4ff 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -46,65 +46,15 @@ jobs: run: | mkdir -p /home/runner/.ansible/collections/ansible_collections - - name: Create doc directories and resources - run: | - mkdir -p ./docs/plugins ./docs/roles - cat ./docs/roles.rst.template > ./docs/roles/index.rst - antsibull-docs collection --use-current --squash-hierarchy --dest-dir docs/plugins middleware_automation.keycloak - for role_readme in roles/*/README.md; do - ln -f -s ../../$role_readme ./docs/roles/$(basename $(dirname $role_readme)).md - echo " $(basename $(dirname $role_readme))" >> ./docs/roles/index.rst - done - working-directory: ansible_collections/middleware_automation/keycloak - - - name: Scan PR merges from latest tag - run: | - TYPES=("minor_changes" "major_changes" "bugfixes" "deprecated_features" "removed_features" "breaking_changes") - TAG=$(git describe --abbrev=0 --tags) - if [[ "${{github.ref}}" == "refs/heads/main" ]]; then - PRS=($(comm -12 <(git log --oneline ${TAG}.. --format="tformat:%H" | sort ) <(hub pr list -s all -f '%sm%n' --color=never | sort ))) - else - PREV_TAG=$(git tag | grep -P "^[0-9]+[.][0-9]+[.][0-9]+$" | sort --version-sort -r | head -n2 | grep -v "${TAG}") - PRS=($(comm -12 <(git log --oneline ${PREV_TAG}..${TAG} --format="tformat:%H" | sort ) <(hub pr list -s all -f '%sm%n' --color=never | sort ))) - fi - if [[ ${#PRS[@]} > 0 ]]; then - IFS=$'\n' FRAGMENTS=($(hub pr list -s all -f '%sm~%I~%L~%t~%n' --color=never | grep -P "$(echo "^(${PRS[@]})" | tr ' ' '|')")) - for frag in "${FRAGMENTS[@]}"; do - PR=$(echo $frag|cut -d~ -f2) - type="$(echo $frag|cut -d~ -f3)" - msg="$(echo $frag|cut -d~ -f4|sed 's/`/``/g')" - if [[ "$type" != "" && "${TYPES[*]}" =~ "${type}" ]]; then - echo -e "$type:\n - >\n $msg \`#${PR} \`_" \ - > changelogs/fragments/${PR}.yaml - fi - done - antsibull-changelog lint -vvv - if [[ "${{github.ref}}" == "refs/heads/main" ]]; then - antsibull-changelog release --version "$(git describe --tags)" -v - fi - fi - working-directory: ansible_collections/middleware_automation/keycloak - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Run sphinx - run: | - sphinx-build -M html . _build -v - working-directory: ansible_collections/middleware_automation/keycloak/docs/ - - - name: Commit docs - run: | - git config user.name github-actions - git config user.email github-actions@github.com - git stash - git checkout gh-pages - rm -rf $(basename ${GITHUB_REF}) - mv docs/_build/html $(basename ${GITHUB_REF}) - ln --force --no-dereference --symbolic main latest - git show origin/main:docs/_gh_include/header.inc > index.html - (echo main; echo latest; dirname *.*.*/index.html | sort --version-sort --reverse) | xargs -I@@ -n1 echo '
  • @@
  • ' >> index.html - git show origin/main:docs/_gh_include/footer.inc >> index.html - git add $(basename ${GITHUB_REF}) latest index.html - git commit -m "Update docs for $(basename ${GITHUB_REF})" || true - git push origin gh-pages - working-directory: ansible_collections/middleware_automation/keycloak/ + - name: Create changelog and documentation + uses: ansible-middleware/collection-docs-action@main + with: + collection_fqcn: middleware_automation.keycloak + collection_repo: ansible-middleware/keycloak + dependencies: false + commit_changelog: false + commit_ghpages: true + changelog_release: false + generate_docs: true + path: ansible_collections/middleware_automation/keycloak + token: ${{ secrets.GITHUB_TOKEN }} From 419c862341b35c621e5d55c154c9f7145a2b0c2c Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 7 Apr 2022 14:07:08 +0200 Subject: [PATCH 051/554] add role keycloak_quarkus --- roles/keycloak_quarkus/defaults/main.yml | 70 ++++++ roles/keycloak_quarkus/handlers/main.yml | 4 + .../keycloak_quarkus/meta/argument_specs.yml | 203 ++++++++++++++++++ roles/keycloak_quarkus/meta/main.yml | 28 +++ roles/keycloak_quarkus/tasks/fastpackages.yml | 21 ++ roles/keycloak_quarkus/tasks/firewalld.yml | 25 +++ roles/keycloak_quarkus/tasks/install.yml | 110 ++++++++++ roles/keycloak_quarkus/tasks/main.yml | 41 ++++ roles/keycloak_quarkus/tasks/prereqs.yml | 34 +++ roles/keycloak_quarkus/tasks/restart.yml | 7 + roles/keycloak_quarkus/tasks/start.yml | 15 ++ roles/keycloak_quarkus/tasks/systemd.yml | 29 +++ .../templates/keycloak-sysconfig.j2 | 3 + .../templates/keycloak.conf.j2 | 51 +++++ .../templates/keycloak.service.j2 | 14 ++ roles/keycloak_quarkus/vars/main.yml | 11 + 16 files changed, 666 insertions(+) create mode 100644 roles/keycloak_quarkus/defaults/main.yml create mode 100644 roles/keycloak_quarkus/handlers/main.yml create mode 100644 roles/keycloak_quarkus/meta/argument_specs.yml create mode 100644 roles/keycloak_quarkus/meta/main.yml create mode 100644 roles/keycloak_quarkus/tasks/fastpackages.yml create mode 100644 roles/keycloak_quarkus/tasks/firewalld.yml create mode 100644 roles/keycloak_quarkus/tasks/install.yml create mode 100644 roles/keycloak_quarkus/tasks/main.yml create mode 100644 roles/keycloak_quarkus/tasks/prereqs.yml create mode 100644 roles/keycloak_quarkus/tasks/restart.yml create mode 100644 roles/keycloak_quarkus/tasks/start.yml create mode 100644 roles/keycloak_quarkus/tasks/systemd.yml create mode 100644 roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 create mode 100644 roles/keycloak_quarkus/templates/keycloak.conf.j2 create mode 100644 roles/keycloak_quarkus/templates/keycloak.service.j2 create mode 100644 roles/keycloak_quarkus/vars/main.yml diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml new file mode 100644 index 0000000..6778308 --- /dev/null +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -0,0 +1,70 @@ +--- +### Configuration specific to keycloak +keycloak_quarkus_version: 17.0.1 +keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip" +keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" +keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" + +# whether to install from local archive +keycloak_quarkus_offline_install: False + +### Install location and service settings +keycloak_quarkus_jvm_package: java-11-openjdk-headless +keycloak_quarkus_dest: /opt/keycloak +keycloak_quarkus_home: "{{ keycloak_quarkus_installdir }}" +keycloak_quarkus_config_dir: "{{ keycloak_quarkus_home }}/conf" +keycloak_quarkus_service_user: keycloak +keycloak_quarkus_service_group: keycloak +keycloak_quarkus_service_pidfile: "/run/keycloak.pid" +keycloak_quarkus_configure_firewalld: False + +### administrator console password +keycloak_quarkus_admin_user: admin +keycloak_quarkus_admin_pass: '' +keycloak_quarkus_master_realm: master + +### Configuration settings +keycloak_quarkus_bind_address: 0.0.0.0 +keycloak_quarkus_host: localhost +keycloak_quarkus_http_port: 8080 +keycloak_quarkus_https_port: 8443 +keycloak_quarkus_ajp_port: 8009 +keycloak_quarkus_jgroups_port: 7600 +keycloak_quarkus_java_opts: "-Xms1024m -Xmx2048m" + +### Enable configuration for database backend, clustering and remote caches on infinispan +keycloak_quarkus_ha_enabled: False +### Enable database configuration, must be enabled when HA is configured +keycloak_quarkus_db_enabled: "{{ True if keycloak_quarkus_ha_enabled else False }}" + +### keycloak frontend url +keycloak_quarkus_http_relative_path: auth +keycloak_quarkus_frontend_url: http://localhost:8080/auth + +keycloak_quarkus_metrics_enabled: False + +### infinispan remote caches access (hotrod) +keycloak_quarkus_ispn_user: supervisor +keycloak_quarkus_ispn_pass: supervisor +keycloak_quarkus_ispn_url: localhost +keycloak_quarkus_ispn_sasl_mechanism: SCRAM-SHA-512 +keycloak_quarkus_ispn_use_ssl: False +# if ssl is enabled, import ispn server certificate here +keycloak_quarkus_ispn_trust_store_path: /etc/pki/java/cacerts +keycloak_quarkus_ispn_trust_store_password: changeit + +### database backend engine: values [ 'postgres', 'mariadb' ] +keycloak_quarkus_jdbc_engine: postgres +### database backend credentials +keycloak_quarkus_db_user: keycloak-user +keycloak_quarkus_db_pass: keycloak-pass +keycloak_quarkus_jdbc_url: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].url }}" +keycloak_quarkus_jdbc_driver_version: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].version }}" +# override the variables above, following defaults show minimum supported versions +keycloak_quarkus_default_jdbc: + postgres: + url: 'jdbc:postgresql://localhost:5432/keycloak' + version: 9.4.1212 + mariadb: + url: 'jdbc:mariadb://localhost:3306/keycloak' + version: 2.7.4 \ No newline at end of file diff --git a/roles/keycloak_quarkus/handlers/main.yml b/roles/keycloak_quarkus/handlers/main.yml new file mode 100644 index 0000000..00cab00 --- /dev/null +++ b/roles/keycloak_quarkus/handlers/main.yml @@ -0,0 +1,4 @@ +--- +- name: "Restart {{ keycloak.service_name }}" + ansible.builtin.include_tasks: restart.yml + listen: "restart keycloak" \ No newline at end of file diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml new file mode 100644 index 0000000..cc94017 --- /dev/null +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -0,0 +1,203 @@ +argument_specs: + main: + options: + keycloak_quarkus_version: + # line 3 of defaults/main.yml + default: "17.0.1" + description: "TODO document argument" + type: "str" + keycloak_quarkus_archive: + # line 4 of defaults/main.yml + default: "keycloak-{{ keycloak_quarkus_version }}.zip" + description: "TODO document argument" + type: "str" + keycloak_quarkus_download_url: + # line 5 of defaults/main.yml + default: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" + description: "TODO document argument" + type: "str" + keycloak_quarkus_installdir: + # line 6 of defaults/main.yml + default: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" + description: "TODO document argument" + type: "str" + keycloak_quarkus_offline_install: + # line 9 of defaults/main.yml + default: false + description: "TODO document argument" + type: "bool" + keycloak_quarkus_jvm_package: + # line 12 of defaults/main.yml + default: "java-11-openjdk-headless" + description: "TODO document argument" + type: "str" + keycloak_quarkus_dest: + # line 13 of defaults/main.yml + default: "/opt/keycloak" + description: "TODO document argument" + type: "str" + keycloak_quarkus_home: + # line 14 of defaults/main.yml + default: "{{ keycloak_quarkus_installdir }}" + description: "TODO document argument" + type: "str" + keycloak_quarkus_config_dir: + # line 15 of defaults/main.yml + default: "{{ keycloak_quarkus_home }}/conf" + description: "TODO document argument" + type: "str" + keycloak_quarkus_service_user: + # line 16 of defaults/main.yml + default: "keycloak" + description: "TODO document argument" + type: "str" + keycloak_quarkus_service_group: + # line 17 of defaults/main.yml + default: "keycloak" + description: "TODO document argument" + type: "str" + keycloak_quarkus_service_pidfile: + # line 18 of defaults/main.yml + default: "/run/keycloak.pid" + description: "TODO document argument" + type: "str" + keycloak_quarkus_configure_firewalld: + # line 19 of defaults/main.yml + default: false + description: "TODO document argument" + type: "bool" + keycloak_quarkus_admin_user: + # line 22 of defaults/main.yml + default: "admin" + description: "TODO document argument" + type: "str" + keycloak_quarkus_admin_pass: + # line 23 of defaults/main.yml + default: "" + description: "TODO document argument" + type: "str" + keycloak_quarkus_master_realm: + # line 24 of defaults/main.yml + default: "master" + description: "TODO document argument" + type: "str" + keycloak_quarkus_bind_address: + # line 27 of defaults/main.yml + default: "0.0.0.0" + description: "TODO document argument" + type: "str" + keycloak_quarkus_host: + # line 28 of defaults/main.yml + default: "localhost" + description: "TODO document argument" + type: "str" + keycloak_quarkus_http_port: + # line 29 of defaults/main.yml + default: 8080 + description: "TODO document argument" + type: "int" + keycloak_quarkus_https_port: + # line 30 of defaults/main.yml + default: 8443 + description: "TODO document argument" + type: "int" + keycloak_quarkus_ajp_port: + # line 31 of defaults/main.yml + default: 8009 + description: "TODO document argument" + type: "int" + keycloak_quarkus_jgroups_port: + # line 32 of defaults/main.yml + default: 7600 + description: "TODO document argument" + type: "int" + keycloak_quarkus_java_opts: + # line 33 of defaults/main.yml + default: "-Xms1024m -Xmx2048m" + description: "TODO document argument" + type: "str" + keycloak_quarkus_ha_enabled: + # line 36 of defaults/main.yml + default: false + description: "TODO document argument" + type: "bool" + keycloak_quarkus_db_enabled: + # line 38 of defaults/main.yml + default: "{{ True if keycloak_quarkus_ha_enabled else False }}" + description: "TODO document argument" + type: "str" + keycloak_quarkus_http_relative_path: + # line 41 of defaults/main.yml + default: "auth" + description: "TODO document argument" + type: "str" + keycloak_quarkus_frontend_url: + # line 41 of defaults/main.yml + default: "http://localhost:8080/auth" + description: "TODO document argument" + type: "str" + keycloak_quarkus_metrics_enabled: + # line 43 of defaults/main.yml + default: false + description: "TODO document argument" + type: "bool" + keycloak_quarkus_ispn_user: + # line 46 of defaults/main.yml + default: "supervisor" + description: "TODO document argument" + type: "str" + keycloak_quarkus_ispn_pass: + # line 47 of defaults/main.yml + default: "supervisor" + description: "TODO document argument" + type: "str" + keycloak_quarkus_ispn_url: + # line 48 of defaults/main.yml + default: "localhost" + description: "TODO document argument" + type: "str" + keycloak_quarkus_ispn_sasl_mechanism: + # line 49 of defaults/main.yml + default: "SCRAM-SHA-512" + description: "TODO document argument" + type: "str" + keycloak_quarkus_ispn_use_ssl: + # line 50 of defaults/main.yml + default: false + description: "TODO document argument" + type: "bool" + keycloak_quarkus_ispn_trust_store_path: + # line 52 of defaults/main.yml + default: "/etc/pki/java/cacerts" + description: "TODO document argument" + type: "str" + keycloak_quarkus_ispn_trust_store_password: + # line 53 of defaults/main.yml + default: "changeit" + description: "TODO document argument" + type: "str" + keycloak_quarkus_jdbc_engine: + # line 56 of defaults/main.yml + default: "postgres" + description: "TODO document argument" + type: "str" + keycloak_quarkus_db_user: + # line 58 of defaults/main.yml + default: "keycloak-user" + description: "TODO document argument" + type: "str" + keycloak_quarkus_db_pass: + # line 59 of defaults/main.yml + default: "keycloak-pass" + description: "TODO document argument" + type: "str" + keycloak_quarkus_jdbc_url: + # line 60 of defaults/main.yml + default: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].url }}" + description: "TODO document argument" + type: "str" + keycloak_quarkus_jdbc_driver_version: + # line 61 of defaults/main.yml + default: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].version }}" + description: "TODO document argument" + type: "str" diff --git a/roles/keycloak_quarkus/meta/main.yml b/roles/keycloak_quarkus/meta/main.yml new file mode 100644 index 0000000..fd6a110 --- /dev/null +++ b/roles/keycloak_quarkus/meta/main.yml @@ -0,0 +1,28 @@ +--- +collections: + +galaxy_info: + role_name: keycloak_quarkus + namespace: middleware_automation + author: Guido Grazioli + description: Install keycloak on quarkus server configurations + company: Red Hat, Inc. + + license: Apache License 2.0 + + min_ansible_version: "2.9" + + platforms: + - name: EL + versions: + - 8 + + galaxy_tags: + - keycloak + - quarkus + - redhat + - rhel + - sso + - authentication + - identity + - security diff --git a/roles/keycloak_quarkus/tasks/fastpackages.yml b/roles/keycloak_quarkus/tasks/fastpackages.yml new file mode 100644 index 0000000..29155f9 --- /dev/null +++ b/roles/keycloak_quarkus/tasks/fastpackages.yml @@ -0,0 +1,21 @@ +--- +- block: + - name: "Check if packages are already installed" + ansible.builtin.command: "rpm -q {{ packages_list | join(' ') }}" + args: + warn: no + register: rpm_info + changed_when: rpm_info.failed + + rescue: + - name: "Add missing packages to the yum install list" + ansible.builtin.set_fact: + packages_to_install: "{{ packages_to_install | default([]) + rpm_info.stdout_lines | map('regex_findall', 'package (.+) is not installed$') | flatten }}" + when: rpm_info.failed + +- name: "Install packages: {{ packages_to_install }}" + become: yes + ansible.builtin.yum: + name: "{{ packages_to_install }}" + state: present + when: packages_to_install | default([]) | length > 0 \ No newline at end of file diff --git a/roles/keycloak_quarkus/tasks/firewalld.yml b/roles/keycloak_quarkus/tasks/firewalld.yml new file mode 100644 index 0000000..772ba3c --- /dev/null +++ b/roles/keycloak_quarkus/tasks/firewalld.yml @@ -0,0 +1,25 @@ +--- +- name: Ensure required package firewalld are installed + ansible.builtin.include_tasks: fastpackages.yml + vars: + packages_list: + - firewalld + +- name: Enable and start the firewalld service + become: yes + ansible.builtin.systemd: + name: firewalld + enabled: yes + state: started + +- name: "Configure firewall for {{ keycloak.service_name }} ports" + become: yes + firewalld: + port: "{{ item }}" + permanent: true + state: enabled + immediate: yes + loop: + - "{{ keycloak_quarkus_http_port }}/tcp" + - "{{ keycloak_quarkus_https_port }}/tcp" + - "{{ keycloak_quarkus_jgroups_port }}/tcp" diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml new file mode 100644 index 0000000..c8e5b73 --- /dev/null +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -0,0 +1,110 @@ +--- +- name: Validate parameters + ansible.builtin.assert: + that: + - keycloak.home is defined + - keycloak_quarkus_service_user is defined + - keycloak_quarkus_dest is defined + - keycloak_quarkus_archive is defined + - keycloak_quarkus_download_url is defined + - keycloak_quarkus_version is defined + quiet: true + +- name: Check for an existing deployment + become: yes + ansible.builtin.stat: + path: "{{ keycloak.home }}" + register: existing_deploy + +- name: "Create {{ keycloak.service_name }} service user/group" + become: yes + ansible.builtin.user: + name: "{{ keycloak.service_user }}" + home: /opt/keycloak + system: yes + create_home: no + +- name: "Create {{ keycloak.service_name }} install location" + become: yes + ansible.builtin.file: + dest: "{{ keycloak_quarkus_dest }}" + state: directory + owner: "{{ keycloak.service_user }}" + group: "{{ keycloak.service_group }}" + mode: 0750 + +## check remote archive +- name: Set download archive path + ansible.builtin.set_fact: + archive: "{{ keycloak_quarkus_dest }}/{{ keycloak.bundle }}" + +- name: Check download archive path + become: yes + ansible.builtin.stat: + path: "{{ archive }}" + register: archive_path + +## download to controller +- name: Check local download archive path + ansible.builtin.stat: + path: "{{ lookup('env', 'PWD') }}" + register: local_path + delegate_to: localhost + +- name: Download keycloak archive + ansible.builtin.get_url: + url: "{{ keycloak_quarkus_download_url }}" + dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" + delegate_to: localhost + when: + - archive_path is defined + - archive_path.stat is defined + - not archive_path.stat.exists + - not keycloak.offline_install + +- name: Check downloaded archive + ansible.builtin.stat: + path: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" + register: local_archive_path + delegate_to: localhost + +## copy and unpack +- name: Copy archive to target nodes + ansible.builtin.copy: + src: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" + dest: "{{ archive }}" + owner: "{{ keycloak.service_user }}" + group: "{{ keycloak.service_group }}" + mode: 0750 + register: new_version_downloaded + when: + - not archive_path.stat.exists + - local_archive_path.stat is defined + - local_archive_path.stat.exists + become: yes + +- name: "Check target directory: {{ keycloak.home }}" + ansible.builtin.stat: + path: "{{ keycloak.home }}" + register: path_to_workdir + become: yes + +- name: "Extract Keycloak archive on target" + ansible.builtin.unarchive: + remote_src: yes + src: "{{ archive }}" + dest: "{{ keycloak_quarkus_dest }}" + creates: "{{ keycloak.home }}" + owner: "{{ keycloak.service_user }}" + group: "{{ keycloak.service_group }}" + become: yes + when: + - new_version_downloaded.changed or not path_to_workdir.stat.exists + notify: + - restart keycloak + +- name: Inform decompression was not executed + ansible.builtin.debug: + msg: "{{ keycloak.home }} already exists and version unchanged, skipping decompression" + when: + - not new_version_downloaded.changed and path_to_workdir.stat.exists diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml new file mode 100644 index 0000000..d350f6f --- /dev/null +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -0,0 +1,41 @@ +--- +# tasks file for keycloak + +- name: Check prerequisites + ansible.builtin.include_tasks: prereqs.yml + tags: + - prereqs + +- name: Include firewall config tasks + ansible.builtin.include_tasks: firewalld.yml + when: keycloak_quarkus_configure_firewalld + tags: + - firewall + +- name: Include install tasks + ansible.builtin.include_tasks: install.yml + tags: + - install + +- name: Include systemd tasks + ansible.builtin.include_tasks: systemd.yml + tags: + - systemd + +- name: "Configure config for keycloak service" + ansible.builtin.template: + src: keycloak.conf.j2 + dest: "{{ keycloak.home }}/conf/keycloak.conf" + owner: "{{ keycloak.service_user }}" + group: "{{ keycloak.service_group }}" + mode: 0644 + notify: + - restart keycloak + +- name: "Start and wait for keycloak service" + ansible.builtin.include_tasks: start.yml + +- name: Check service status + ansible.builtin.command: "systemctl status keycloak" + register: keycloak_service_status + changed_when: False \ No newline at end of file diff --git a/roles/keycloak_quarkus/tasks/prereqs.yml b/roles/keycloak_quarkus/tasks/prereqs.yml new file mode 100644 index 0000000..ea2b8f4 --- /dev/null +++ b/roles/keycloak_quarkus/tasks/prereqs.yml @@ -0,0 +1,34 @@ +--- +- name: Validate admin console password + ansible.builtin.assert: + that: + - keycloak_quarkus_admin_pass | length > 12 + quiet: True + fail_msg: "The console administrator password is empty or invalid. Please set the keycloak_quarkus_admin_pass variable to a 12+ char long string" + success_msg: "{{ 'Console administrator password OK' }}" + +- name: Validate configuration + ansible.builtin.assert: + that: + - (keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled) or (not keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled) or (not keycloak_quarkus_ha_enabled and not keycloak_quarkus_db_enabled) + quiet: True + fail_msg: "Cannot install HA setup without a backend database service. Check keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled" + success_msg: "{{ 'Configuring HA' if keycloak_quarkus_ha_enabled else 'Configuring standalone' }}" + +# - name: Validate credentials +# ansible.builtin.assert: +# that: +# - (rhn_username is defined and keycloak_rhsso_enable) or not keycloak_rhsso_enable or keycloak_offline_install +# - (rhn_password is defined and keycloak_rhsso_enable) or not keycloak_rhsso_enable or keycloak_offline_install +# quiet: True +# fail_msg: "Cannot install Red Hat SSO without RHN credentials. Check rhn_username and rhn_password are defined" +# success_msg: "{{ 'Installing Red Hat Single Sign-On' if keycloak_rhsso_enable else 'Installing keycloak.org' }}" + +- name: Ensure required packages are installed + ansible.builtin.include_tasks: fastpackages.yml + vars: + packages_list: + - "{{ keycloak_quarkus_jvm_package }}" + - unzip + - procps-ng + - initscripts \ No newline at end of file diff --git a/roles/keycloak_quarkus/tasks/restart.yml b/roles/keycloak_quarkus/tasks/restart.yml new file mode 100644 index 0000000..eff9ddf --- /dev/null +++ b/roles/keycloak_quarkus/tasks/restart.yml @@ -0,0 +1,7 @@ +--- +- name: "Restart and enable {{ keycloak.service_name }} service" + ansible.builtin.systemd: + name: keycloak + enabled: yes + state: restarted + become: yes diff --git a/roles/keycloak_quarkus/tasks/start.yml b/roles/keycloak_quarkus/tasks/start.yml new file mode 100644 index 0000000..bdf42f9 --- /dev/null +++ b/roles/keycloak_quarkus/tasks/start.yml @@ -0,0 +1,15 @@ +--- +- name: "Start {{ keycloak.service_name }} service" + ansible.builtin.systemd: + name: keycloak + enabled: yes + state: started + become: yes + +- name: "Wait until {{ keycloak.service_name }} becomes active {{ keycloak.health_url }}" + ansible.builtin.uri: + url: "{{ keycloak.health_url }}" + register: keycloak_status + until: keycloak_status.status == 200 + retries: 25 + delay: 10 \ No newline at end of file diff --git a/roles/keycloak_quarkus/tasks/systemd.yml b/roles/keycloak_quarkus/tasks/systemd.yml new file mode 100644 index 0000000..578802c --- /dev/null +++ b/roles/keycloak_quarkus/tasks/systemd.yml @@ -0,0 +1,29 @@ +--- +- name: "Configure sysconfig file for keycloak service" + become: yes + ansible.builtin.template: + src: keycloak-sysconfig.j2 + dest: /etc/sysconfig/keycloak + owner: root + group: root + mode: 0644 + notify: + - restart keycloak + +- name: "Configure systemd unit file for keycloak service" + ansible.builtin.template: + src: keycloak.service.j2 + dest: /etc/systemd/system/keycloak.service + owner: root + group: root + mode: 0644 + become: yes + register: systemdunit + notify: + - restart keycloak + +- name: Reload systemd + become: yes + ansible.builtin.systemd: + daemon_reload: yes + when: systemdunit.changed diff --git a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 new file mode 100644 index 0000000..13a589e --- /dev/null +++ b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 @@ -0,0 +1,3 @@ +# {{ ansible_managed }} +KEYCLOAK_ADMIN={{ keycloak_quarkus_admin_user }} +KEYCLOAK_ADMIN_PASSWORD='{{ keycloak_quarkus_admin_pass }}' \ No newline at end of file diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 new file mode 100644 index 0000000..59d82a2 --- /dev/null +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -0,0 +1,51 @@ +# {{ ansible_managed }} + +# Database +# Database vendor [dev-file, dev-mem, mariadb, mssql, mysql, oracle, postgres] +#db=postgres +# The username of the database user. +#db-username=keycloak +# The password of the database user. +#db-password=password +# The full database JDBC URL. If not provided, a default URL is set based on the selected database vendor. +#db-url=jdbc:postgresql://localhost/keycloak + +# Observability +# If the server should expose metrics and healthcheck endpoints. +#metrics-enabled=true + +# HTTP +http-enabled=true +http-port=8080 +https-port=8443 +# The file path to a server certificate or certificate chain in PEM format. +#https-certificate-file=${kc.home.dir}conf/server.crt.pem +# The file path to a private key in PEM format. +#https-certificate-key-file=${kc.home.dir}conf/server.key.pem +# The proxy address forwarding mode if the server is behind a reverse proxy. +#proxy=reencrypt +# Do not attach route to cookies and rely on the session affinity capabilities from reverse proxy +#spi-sticky-session-encoder-infinispan-should-attach-route=false + +# Hostname for the Keycloak server. +hostname={{ keycloak_quarkus_host }} +hostname-path={{ keycloak_quarkus_http_relative_path }} + +# Cluster +#cache=ispn +#Defines the cache mechanism for high-availability. [local, ispn] +#cache-config-file=conf/cache-ispn.xml +#Defines the file from which cache configuration should be loaded from. +#cache-stack=tcp +#Define the default stack to use for cluster communication and node discovery. [tcp, udp, kubernetes, ec2, azure, google] + +# Proxy +# The proxy address forwarding mode if the server is behind a reverse proxy. [edge, reencrypt, passthrough] +#proxy= + +# Logging +# The format of log entries. +#log-format=%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n +# The log level of the root category or a comma-separated list of individual categories and their levels. +#log-level=info + diff --git a/roles/keycloak_quarkus/templates/keycloak.service.j2 b/roles/keycloak_quarkus/templates/keycloak.service.j2 new file mode 100644 index 0000000..a710ee2 --- /dev/null +++ b/roles/keycloak_quarkus/templates/keycloak.service.j2 @@ -0,0 +1,14 @@ +# {{ ansible_managed }} +[Unit] +Description=Keycloak Server +After=network.target + +[Service] +Type=simple +EnvironmentFile=-/etc/sysconfig/keycloak +PIDFile={{ keycloak_quarkus_service_pidfile }} +ExecStart={{ keycloak.home }}/bin/kc.sh start +#--http-relative-path={{ keycloak_quarkus_http_relative_path }} + +[Install] +WantedBy=multi-user.target diff --git a/roles/keycloak_quarkus/vars/main.yml b/roles/keycloak_quarkus/vars/main.yml new file mode 100644 index 0000000..bca7d88 --- /dev/null +++ b/roles/keycloak_quarkus/vars/main.yml @@ -0,0 +1,11 @@ +--- +keycloak: + home: "{{ keycloak_quarkus_home }}" + config_dir: "{{ keycloak_quarkus_config_dir }}" + bundle: "{{ keycloak_quarkus_archive }}" + service_name: "keycloak" + health_url: "http://localhost:8080/realms/master/.well-known/openid-configuration" + cli_path: "{{ keycloak_quarkus_home }}/bin/kcadm.sh" + service_user: "{{ keycloak_quarkus_service_user }}" + service_group: "{{ keycloak_quarkus_service_group }}" + offline_install: "{{ keycloak_quarkus_offline_install }}" \ No newline at end of file From cf92da9e940568ccdfc67ce8dc1f58558ff39070 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 7 Apr 2022 14:07:28 +0200 Subject: [PATCH 052/554] update keycloak_realm to test nicely with keycloak_quarkus --- roles/keycloak_realm/defaults/main.yml | 1 + roles/keycloak_realm/meta/argument_specs.yml | 7 ++++++- roles/keycloak_realm/tasks/main.yml | 10 +++++----- roles/keycloak_realm/tasks/manage_client_roles.yml | 2 +- roles/keycloak_realm/tasks/manage_user.yml | 8 ++++---- .../keycloak_realm/tasks/manage_user_client_roles.yml | 6 +++--- roles/keycloak_realm/tasks/manage_user_roles.yml | 4 ++-- 7 files changed, 22 insertions(+), 16 deletions(-) diff --git a/roles/keycloak_realm/defaults/main.yml b/roles/keycloak_realm/defaults/main.yml index 2f33e57..4975380 100644 --- a/roles/keycloak_realm/defaults/main.yml +++ b/roles/keycloak_realm/defaults/main.yml @@ -10,6 +10,7 @@ keycloak_rhsso_enable: False keycloak_admin_user: admin keycloak_auth_realm: master keycloak_auth_client: admin-cli +keycloak_context: /auth # administrator console password, this is a required variable keycloak_admin_password: '' diff --git a/roles/keycloak_realm/meta/argument_specs.yml b/roles/keycloak_realm/meta/argument_specs.yml index 8f951b4..45b5998 100644 --- a/roles/keycloak_realm/meta/argument_specs.yml +++ b/roles/keycloak_realm/meta/argument_specs.yml @@ -4,8 +4,13 @@ argument_specs: keycloak_host: # line 3 of keycloak_realm/defaults/main.yml default: "localhost" - description: "hostname for rest calls" + description: "Hostname for rest calls" type: "str" + keycloak_context: + # line 5 of keycloak_realm/defaults/main.yml + default: "/auth" + description: "Context path for rest calls" + type: "str" keycloak_http_port: # line 4 of keycloak_realm/defaults/main.yml default: 8080 diff --git a/roles/keycloak_realm/tasks/main.yml b/roles/keycloak_realm/tasks/main.yml index 8659fd3..2554958 100644 --- a/roles/keycloak_realm/tasks/main.yml +++ b/roles/keycloak_realm/tasks/main.yml @@ -1,7 +1,7 @@ --- - name: Generate keycloak auth token ansible.builtin.uri: - url: "{{ keycloak_url }}/auth/realms/master/protocol/openid-connect/token" + url: "{{ keycloak_url }}{{ keycloak_context }}/realms/master/protocol/openid-connect/token" method: POST body: "client_id={{ keycloak_auth_client }}&username={{ keycloak_admin_user }}&password={{ keycloak_admin_password }}&grant_type=password" validate_certs: no @@ -13,7 +13,7 @@ - name: "Determine if realm exists" ansible.builtin.uri: - url: "{{ keycloak_url }}/auth/admin/realms/{{ keycloak_realm }}" + url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ keycloak_realm }}" method: GET status_code: - 200 @@ -25,7 +25,7 @@ - name: Create Realm ansible.builtin.uri: - url: "{{ keycloak_url }}/auth/admin/realms" + url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms" method: POST body: "{{ lookup('template','realm.json.j2') }}" validate_certs: no @@ -37,7 +37,7 @@ - name: Create user federation community.general.keycloak_user_federation: - auth_keycloak_url: "{{ keycloak_url }}/auth" + auth_keycloak_url: "{{ keycloak_url }}{{ keycloak_context }}" auth_realm: "{{ keycloak_auth_realm }}" auth_username: "{{ keycloak_admin_user }}" auth_password: "{{ keycloak_admin_password }}" @@ -56,7 +56,7 @@ - name: Create or update a Keycloak client community.general.keycloak_client: auth_client_id: "{{ keycloak_auth_client }}" - auth_keycloak_url: "{{ keycloak_url }}/auth" + auth_keycloak_url: "{{ keycloak_url }}{{ keycloak_context }}" auth_realm: "{{ keycloak_auth_realm }}" auth_username: "{{ keycloak_admin_user }}" auth_password: "{{ keycloak_admin_password }}" diff --git a/roles/keycloak_realm/tasks/manage_client_roles.yml b/roles/keycloak_realm/tasks/manage_client_roles.yml index dd47eb3..04cf2fa 100644 --- a/roles/keycloak_realm/tasks/manage_client_roles.yml +++ b/roles/keycloak_realm/tasks/manage_client_roles.yml @@ -4,7 +4,7 @@ realm: "{{ client.realm }}" client_id: "{{ client.name }}" auth_client_id: "{{ keycloak_auth_client }}" - auth_keycloak_url: "{{ keycloak_url }}/auth" + auth_keycloak_url: "{{ keycloak_url }}{{ keycloak_context }}" auth_realm: "{{ keycloak_auth_realm }}" auth_username: "{{ keycloak_admin_user }}" auth_password: "{{ keycloak_admin_password }}" diff --git a/roles/keycloak_realm/tasks/manage_user.yml b/roles/keycloak_realm/tasks/manage_user.yml index d304e13..840c738 100644 --- a/roles/keycloak_realm/tasks/manage_user.yml +++ b/roles/keycloak_realm/tasks/manage_user.yml @@ -1,7 +1,7 @@ --- - name: "Check if User Already Exists" ansible.builtin.uri: - url: "{{ keycloak_url }}/auth/admin/realms/{{ keycloak_realm }}/users?username={{ user.username }}" + url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ keycloak_realm }}/users?username={{ user.username }}" validate_certs: no headers: Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" @@ -9,7 +9,7 @@ - name: "Create User" ansible.builtin.uri: - url: "{{ keycloak_url }}/auth/admin/realms/{{ keycloak_realm }}/users" + url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ keycloak_realm }}/users" method: POST body: enabled: true @@ -27,7 +27,7 @@ - name: "Get User" ansible.builtin.uri: - url: "{{ keycloak_url }}/auth/admin/realms/{{ keycloak_realm }}/users?username={{ user.username }}" + url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ keycloak_realm }}/users?username={{ user.username }}" validate_certs: no headers: Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" @@ -35,7 +35,7 @@ - name: "Update User Password" ansible.builtin.uri: - url: "{{ keycloak_url }}/auth/admin/realms/{{ keycloak_realm }}/users/{{ (keycloak_user.json | first).id }}/reset-password" + url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ keycloak_realm }}/users/{{ (keycloak_user.json | first).id }}/reset-password" method: PUT body: type: password diff --git a/roles/keycloak_realm/tasks/manage_user_client_roles.yml b/roles/keycloak_realm/tasks/manage_user_client_roles.yml index f29bbc6..5369094 100644 --- a/roles/keycloak_realm/tasks/manage_user_client_roles.yml +++ b/roles/keycloak_realm/tasks/manage_user_client_roles.yml @@ -1,7 +1,7 @@ --- - name: "Get Realm for role" ansible.builtin.uri: - url: "{{ keycloak_url }}/auth/admin/realms/{{ client_role.realm }}" + url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ client_role.realm }}" method: GET status_code: - 200 @@ -12,7 +12,7 @@ - name: Check if Mapping is available ansible.builtin.uri: - url: "{{ keycloak_url }}/auth/admin/realms/{{ client_role.realm }}/users/{{ (keycloak_user.json | first).id }}/role-mappings/clients/{{ (create_client_result.results | selectattr('end_state.clientId', 'equalto', client_role.client) | list | first).end_state.id }}/available" + url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ client_role.realm }}/users/{{ (keycloak_user.json | first).id }}/role-mappings/clients/{{ (create_client_result.results | selectattr('end_state.clientId', 'equalto', client_role.client) | list | first).end_state.id }}/available" method: GET status_code: - 200 @@ -23,7 +23,7 @@ - name: "Create Role Mapping" ansible.builtin.uri: - url: "{{ keycloak_url }}/auth/admin/realms/{{ client_role.realm }}/users/{{ (keycloak_user.json | first).id }}/role-mappings/clients/{{ (create_client_result.results | selectattr('end_state.clientId', 'equalto', client_role.client) | list | first).end_state.id }}" + url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ client_role.realm }}/users/{{ (keycloak_user.json | first).id }}/role-mappings/clients/{{ (create_client_result.results | selectattr('end_state.clientId', 'equalto', client_role.client) | list | first).end_state.id }}" method: POST body: - id: "{{ item.id }}" diff --git a/roles/keycloak_realm/tasks/manage_user_roles.yml b/roles/keycloak_realm/tasks/manage_user_roles.yml index 2d50f8b..e9d18b7 100644 --- a/roles/keycloak_realm/tasks/manage_user_roles.yml +++ b/roles/keycloak_realm/tasks/manage_user_roles.yml @@ -1,7 +1,7 @@ --- - name: "Get User {{ user.username }}" ansible.builtin.uri: - url: "{{ keycloak_url }}/auth/admin/realms/{{ keycloak_realm }}/users?username={{ user.username }}" + url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ keycloak_realm }}/users?username={{ user.username }}" headers: validate_certs: no Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" @@ -9,7 +9,7 @@ - name: Refresh keycloak auth token ansible.builtin.uri: - url: "{{ keycloak_url }}/auth/realms/master/protocol/openid-connect/token" + url: "{{ keycloak_url }}{{ keycloak_context }}/realms/master/protocol/openid-connect/token" method: POST body: "client_id={{ keycloak_auth_client }}&username={{ keycloak_admin_user }}&password={{ keycloak_admin_password }}&grant_type=password" validate_certs: no From 33c8f741228f72cbf877917e8d4eccc0d1281120 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 7 Apr 2022 14:07:45 +0200 Subject: [PATCH 053/554] add molecule test for keycloak_quarkus --- molecule/quarkus/converge.yml | 39 +++++++++++++++++++++++ molecule/quarkus/molecule.yml | 53 +++++++++++++++++++++++++++++++ molecule/quarkus/prepare.yml | 12 +++++++ molecule/quarkus/requirements.yml | 10 ++++++ molecule/quarkus/roles | 1 + molecule/quarkus/verify.yml | 11 +++++++ 6 files changed, 126 insertions(+) create mode 100644 molecule/quarkus/converge.yml create mode 100644 molecule/quarkus/molecule.yml create mode 100644 molecule/quarkus/prepare.yml create mode 100644 molecule/quarkus/requirements.yml create mode 120000 molecule/quarkus/roles create mode 100644 molecule/quarkus/verify.yml diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml new file mode 100644 index 0000000..452212b --- /dev/null +++ b/molecule/quarkus/converge.yml @@ -0,0 +1,39 @@ +--- +- name: Converge + hosts: all + vars: + keycloak_quarkus_admin_pass: "remembertochangeme" + keycloak_realm: TestRealm + roles: + - role: keycloak_quarkus + - role: keycloak_realm + keycloak_context: '' + keycloak_admin_password: "remembertochangeme" + keycloak_client_default_roles: + - TestRoleAdmin + - TestRoleUser + keycloak_client_users: + - username: TestUser + password: password + client_roles: + - client: TestClient + role: TestRoleUser + realm: "{{ keycloak_realm }}" + - username: TestAdmin + password: password + client_roles: + - client: TestClient + role: TestRoleUser + realm: "{{ keycloak_realm }}" + - client: TestClient + role: TestRoleAdmin + realm: "{{ keycloak_realm }}" + keycloak_realm: TestRealm + keycloak_clients: + - name: TestClient + roles: "{{ keycloak_client_default_roles }}" + realm: "{{ keycloak_realm }}" + public_client: "{{ keycloak_client_public }}" + web_origins: "{{ keycloak_client_web_origins }}" + users: "{{ keycloak_client_users }}" + client_id: TestClient diff --git a/molecule/quarkus/molecule.yml b/molecule/quarkus/molecule.yml new file mode 100644 index 0000000..ea8ad61 --- /dev/null +++ b/molecule/quarkus/molecule.yml @@ -0,0 +1,53 @@ +--- +dependency: + name: shell + command: ansible-galaxy collection install -r molecule/default/requirements.yml -p $HOME/.ansible/collections --force-with-deps +driver: + name: docker +lint: | + ansible-lint --version + ansible-lint -v +platforms: + - name: instance + image: registry.access.redhat.com/ubi8/ubi-init:latest + pre_build_image: true + privileged: true + command: "/usr/sbin/init" + port_bindings: + - "8080/tcp" + - "8443/tcp" + - "8009/tcp" +provisioner: + name: ansible + config_options: + defaults: + interpreter_python: auto_silent + ssh_connection: + pipelining: false + playbooks: + prepare: prepare.yml + converge: converge.yml + verify: verify.yml + inventory: + host_vars: + localhost: + ansible_python_interpreter: "{{ ansible_playbook_python }}" + env: + ANSIBLE_FORCE_COLOR: "true" +verifier: + name: ansible +scenario: + test_sequence: + - dependency + - lint + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - side_effect + - verify + - cleanup + - destroy diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml new file mode 100644 index 0000000..03433c0 --- /dev/null +++ b/molecule/quarkus/prepare.yml @@ -0,0 +1,12 @@ +--- +- name: Prepare + hosts: all + tasks: + - name: Disable beta repos + ansible.builtin.command: yum config-manager --disable '*beta*' + ignore_errors: yes + + - name: Install sudo + ansible.builtin.yum: + name: sudo + state: present diff --git a/molecule/quarkus/requirements.yml b/molecule/quarkus/requirements.yml new file mode 100644 index 0000000..9aa3437 --- /dev/null +++ b/molecule/quarkus/requirements.yml @@ -0,0 +1,10 @@ +--- +collections: + - name: middleware_automation.redhat_csp_download + version: ">=1.2.1" + - name: middleware_automation.wildfly + version: ">=0.0.5" + - name: community.general + - name: community.docker + version: ">=1.9.1" + diff --git a/molecule/quarkus/roles b/molecule/quarkus/roles new file mode 120000 index 0000000..b741aa3 --- /dev/null +++ b/molecule/quarkus/roles @@ -0,0 +1 @@ +../../roles \ No newline at end of file diff --git a/molecule/quarkus/verify.yml b/molecule/quarkus/verify.yml new file mode 100644 index 0000000..ef973cd --- /dev/null +++ b/molecule/quarkus/verify.yml @@ -0,0 +1,11 @@ +--- +- name: Verify + hosts: all + tasks: + - name: Populate service facts + ansible.builtin.service_facts: + - name: Check if keycloak service started + ansible.builtin.assert: + that: + - ansible_facts.services["keycloak.service"]["state"] == "running" + - ansible_facts.services["keycloak.service"]["status"] == "enabled" From 9bb9816a01e876c7aff649d68c25f2cd4a9a4f2c Mon Sep 17 00:00:00 2001 From: Romain Pelisse Date: Tue, 5 Apr 2022 10:11:28 +0200 Subject: [PATCH 054/554] Switch playbooks hosts to all --- playbooks/keycloak.yml | 2 +- playbooks/keycloak_realm.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/playbooks/keycloak.yml b/playbooks/keycloak.yml index 39697bc..e4ac27c 100644 --- a/playbooks/keycloak.yml +++ b/playbooks/keycloak.yml @@ -1,6 +1,6 @@ --- - name: Playbook for Keycloak Hosts - hosts: keycloak + hosts: all vars: keycloak_admin_password: "remembertochangeme" collections: diff --git a/playbooks/keycloak_realm.yml b/playbooks/keycloak_realm.yml index 8bc1962..baeb2f2 100644 --- a/playbooks/keycloak_realm.yml +++ b/playbooks/keycloak_realm.yml @@ -1,6 +1,6 @@ --- - name: Playbook for Keycloak Hosts - hosts: keycloak + hosts: all tasks: - name: Keycloak Realm Role ansible.builtin.include_role: From dc33cbc358da59d412483b14c86985bb085fbe81 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 11 Apr 2022 13:48:59 +0200 Subject: [PATCH 055/554] quarkus: add README, update parameters doc --- README.md | 1 + roles/keycloak_quarkus/README.md | 101 ++++++++++++++++++ .../keycloak_quarkus/meta/argument_specs.yml | 80 +++++++------- 3 files changed, 142 insertions(+), 40 deletions(-) create mode 100644 roles/keycloak_quarkus/README.md diff --git a/README.md b/README.md index 581e882..d341f58 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ A requirement file is provided to install: * [`keycloak`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak/README.md): role for installing the service. * [`keycloak_realm`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak_realm/README.md): role for configuring a realm, user federation(s), clients and users, in an installed service. +* [`keycloak_quarkus`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak_quarkus/README.md): role for installing the quarkus variant of keycloak (>= 17.0.0). ## Usage diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md new file mode 100644 index 0000000..19237d5 --- /dev/null +++ b/roles/keycloak_quarkus/README.md @@ -0,0 +1,101 @@ +keycloak_quarkus +================ + +Install [keycloak](https://keycloak.org/) >= 17.0.0 (quarkus) server configurations. + + +Role Defaults +------------- + +* Service configuration + +| Variable | Description | Default | +|:---------|:------------|:--------| +|`keycloak_quarkus_ha_enabled`| Enable auto configuration for database backend, clustering and remote caches on infinispan | `False` | +|`keycloak_quarkus_db_enabled`| Enable auto configuration for database backend | `True` if `keycloak_quarkus_ha_enabled` is True, else `False` | +|`keycloak_quarkus_admin_user`| Administration console user account | `admin` | +|`keycloak_quarkus_bind_address`| Address for binding service ports | `0.0.0.0` | +|`keycloak_quarkus_host`| hostname | `localhost` | +|`keycloak_quarkus_http_port`| HTTP port | `8080` | +|`keycloak_quarkus_https_port`| TLS HTTP port | `8443` | +|`keycloak_quarkus_ajp_port`| AJP port | `8009` | +|`keycloak_quarkus_jgroups_port`| jgroups cluster tcp port | `7600` | +|`keycloak_quarkus_java_opts`| Additional JVM options | `-Xms1024m -Xmx2048m` | +|`keycloak_quarkus_service_user`| Posix account username | `keycloak` | +|`keycloak_quarkus_service_group`| Posix account group | `keycloak` | +|`keycloak_quarkus_service_pidfile`| Pid file path for service | `/run/keycloak.pid` | +|`keycloak_quarkus_jvm_package`| RHEL java package runtime | `java-11-openjdk-headless` | +|`keycloak_quarkus_frontend_url`| Service public URL | `http://localhost:8080/auth` | +|`keycloak_quarkus_http_relative_path` | Service context path | `auth` | + + +* Database configuration + +| Variable | Description | Default | +|:---------|:------------|:--------| +|`keycloak_quarkus_jdbc_engine` | Database engine [mariadb,postres] | `postgres` | +|`keycloak_quarkus_db_user` | User for database connection | `keycloak-user` | +|`keycloak_quarkus_db_pass` | Password for database connection | `keycloak-pass` | +|`keycloak_quarkus_jdbc_url` | JDBC URL for connecting to database | `jdbc:postgresql://localhost:5432/keycloak` | +|`keycloak_quarkus_jdbc_driver_version` | Version for JDBC driver | `9.4.1212` | + + +* Remote caches configuration + +| Variable | Description | Default | +|:---------|:------------|:--------| +|`keycloak_quarkus_ispn_user` | Username for connecting to infinispan | `supervisor` | +|`keycloak_quarkus_ispn_pass` | Password for connecting to infinispan | `supervisor` | +|`keycloak_quarkus_ispn_url` | URL for connecting to infinispan | `localhost` | +|`keycloak_quarkus_ispn_sasl_mechanism` | Infinispan auth mechanism | `SCRAM-SHA-512` | +|`keycloak_quarkus_ispn_use_ssl` | Whether infinispan uses TLS connection | `false` | +|`keycloak_quarkus_ispn_trust_store_path` | Path to infinispan server trust certificate | `/etc/pki/java/cacerts` | +|`keycloak_quarkus_ispn_trust_store_password` | Password for infinispan certificate keystore | `changeit` | + + +* Install options + +| Variable | Description | Default | +|:---------|:------------|:---------| +|`keycloak_quarkus_offline_install` | Perform an offline install | `False`| +|`keycloak_quarkus_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| +|`keycloak_quarkus_version`| keycloak.org package version | `17.0.1` | +|`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` | +|`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` | +|`keycloak_quarkus_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` | + + +* Miscellaneous configuration + +| Variable | Description | Default | +|:---------|:------------|:--------| +|`keycloak_quarkus_metrics_enabled`| Whether to enable metrics | `False` | +|`keycloak_quarkus_archive` | keycloak install archive filename | `keycloak-{{ keycloak_quarkus_version }}.zip` | +|`keycloak_quarkus_installdir` | Installation path | `{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}` | +|`keycloak_quarkus_home` | Installation work directory | `{{ keycloak_quarkus_installdir }}` | +|`keycloak_quarkus_config_dir` | Path for configuration | `{{ keycloak_quarkus_home }}/conf` | +|`keycloak_quarkus_master_realm` | Name for rest authentication realm | `master` | +|`keycloak_auth_client` | Authentication client for configuration REST calls | `admin-cli` | +|`keycloak_force_install` | Remove pre-existing versions of service | `False` | +|`keycloak_url` | URL for configuration rest calls | `http://{{ keycloak_quarkus_host }}:{{ keycloak_http_port }}` | +|`keycloak_management_url` | URL for management console rest calls | `http://{{ keycloak_quarkus_host }}:{{ keycloak_management_http_port }}` | + + +Role Variables +-------------- + +| Variable | Description | +|:---------|:------------| +|`keycloak_quarkus_admin_pass`| Password of console admin account | + + +License +------- + +Apache License 2.0 + + +Author Information +------------------ + +* [Guido Grazioli](https://github.com/guidograzioli) diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index cc94017..78382f9 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -4,200 +4,200 @@ argument_specs: keycloak_quarkus_version: # line 3 of defaults/main.yml default: "17.0.1" - description: "TODO document argument" + description: "keycloak.org package version" type: "str" keycloak_quarkus_archive: # line 4 of defaults/main.yml default: "keycloak-{{ keycloak_quarkus_version }}.zip" - description: "TODO document argument" + description: "keycloak install archive filename" type: "str" keycloak_quarkus_download_url: # line 5 of defaults/main.yml default: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" - description: "TODO document argument" + description: "Download URL for keycloak" type: "str" keycloak_quarkus_installdir: # line 6 of defaults/main.yml default: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" - description: "TODO document argument" + description: "Installation path" type: "str" keycloak_quarkus_offline_install: # line 9 of defaults/main.yml default: false - description: "TODO document argument" + description: "Perform an offline install" type: "bool" keycloak_quarkus_jvm_package: # line 12 of defaults/main.yml default: "java-11-openjdk-headless" - description: "TODO document argument" + description: "RHEL java package runtime" type: "str" keycloak_quarkus_dest: # line 13 of defaults/main.yml default: "/opt/keycloak" - description: "TODO document argument" + description: "Installation root path" type: "str" keycloak_quarkus_home: # line 14 of defaults/main.yml default: "{{ keycloak_quarkus_installdir }}" - description: "TODO document argument" + description: "Installation work directory" type: "str" keycloak_quarkus_config_dir: # line 15 of defaults/main.yml default: "{{ keycloak_quarkus_home }}/conf" - description: "TODO document argument" + description: "Path for configuration" type: "str" keycloak_quarkus_service_user: # line 16 of defaults/main.yml default: "keycloak" - description: "TODO document argument" + description: "Posix account username" type: "str" keycloak_quarkus_service_group: # line 17 of defaults/main.yml default: "keycloak" - description: "TODO document argument" + description: "Posix account group" type: "str" keycloak_quarkus_service_pidfile: # line 18 of defaults/main.yml default: "/run/keycloak.pid" - description: "TODO document argument" + description: "Pid file path for service" type: "str" keycloak_quarkus_configure_firewalld: # line 19 of defaults/main.yml default: false - description: "TODO document argument" + description: "Ensure firewalld is running and configure keycloak ports" type: "bool" keycloak_quarkus_admin_user: # line 22 of defaults/main.yml default: "admin" - description: "TODO document argument" + description: "Administration console user account" type: "str" keycloak_quarkus_admin_pass: # line 23 of defaults/main.yml default: "" - description: "TODO document argument" + description: "Password of console admin account" type: "str" keycloak_quarkus_master_realm: # line 24 of defaults/main.yml default: "master" - description: "TODO document argument" + description: "Name for rest authentication realm" type: "str" keycloak_quarkus_bind_address: # line 27 of defaults/main.yml default: "0.0.0.0" - description: "TODO document argument" + description: "Address for binding service ports" type: "str" keycloak_quarkus_host: # line 28 of defaults/main.yml default: "localhost" - description: "TODO document argument" + description: "hostname" type: "str" keycloak_quarkus_http_port: # line 29 of defaults/main.yml default: 8080 - description: "TODO document argument" + description: "HTTP port" type: "int" keycloak_quarkus_https_port: # line 30 of defaults/main.yml default: 8443 - description: "TODO document argument" + description: "HTTPS port" type: "int" keycloak_quarkus_ajp_port: # line 31 of defaults/main.yml default: 8009 - description: "TODO document argument" + description: "AJP port" type: "int" keycloak_quarkus_jgroups_port: # line 32 of defaults/main.yml default: 7600 - description: "TODO document argument" + description: "jgroups cluster tcp port" type: "int" keycloak_quarkus_java_opts: # line 33 of defaults/main.yml default: "-Xms1024m -Xmx2048m" - description: "TODO document argument" + description: "Additional JVM options" type: "str" keycloak_quarkus_ha_enabled: # line 36 of defaults/main.yml default: false - description: "TODO document argument" + description: "Enable auto configuration for database backend, clustering and remote caches on infinispan" type: "bool" keycloak_quarkus_db_enabled: # line 38 of defaults/main.yml default: "{{ True if keycloak_quarkus_ha_enabled else False }}" - description: "TODO document argument" + description: "Enable auto configuration for database backend" type: "str" keycloak_quarkus_http_relative_path: # line 41 of defaults/main.yml default: "auth" - description: "TODO document argument" + description: "Service context path" type: "str" keycloak_quarkus_frontend_url: # line 41 of defaults/main.yml default: "http://localhost:8080/auth" - description: "TODO document argument" + description: "Service public URL" type: "str" keycloak_quarkus_metrics_enabled: # line 43 of defaults/main.yml default: false - description: "TODO document argument" + description: "Whether to enable metrics" type: "bool" keycloak_quarkus_ispn_user: # line 46 of defaults/main.yml default: "supervisor" - description: "TODO document argument" + description: "Username for connecting to infinispan" type: "str" keycloak_quarkus_ispn_pass: # line 47 of defaults/main.yml default: "supervisor" - description: "TODO document argument" + description: "Password for connecting to infinispan" type: "str" keycloak_quarkus_ispn_url: # line 48 of defaults/main.yml default: "localhost" - description: "TODO document argument" + description: "URL for connecting to infinispan" type: "str" keycloak_quarkus_ispn_sasl_mechanism: # line 49 of defaults/main.yml default: "SCRAM-SHA-512" - description: "TODO document argument" + description: "Infinispan auth mechanism" type: "str" keycloak_quarkus_ispn_use_ssl: # line 50 of defaults/main.yml default: false - description: "TODO document argument" + description: "Whether infinispan uses TLS connection" type: "bool" keycloak_quarkus_ispn_trust_store_path: # line 52 of defaults/main.yml default: "/etc/pki/java/cacerts" - description: "TODO document argument" + description: "Path to infinispan server trust certificate" type: "str" keycloak_quarkus_ispn_trust_store_password: # line 53 of defaults/main.yml default: "changeit" - description: "TODO document argument" + description: "Password for infinispan certificate keystore" type: "str" keycloak_quarkus_jdbc_engine: # line 56 of defaults/main.yml default: "postgres" - description: "TODO document argument" + description: "Database engine [mariadb,postres]" type: "str" keycloak_quarkus_db_user: # line 58 of defaults/main.yml default: "keycloak-user" - description: "TODO document argument" + description: "User for database connection" type: "str" keycloak_quarkus_db_pass: # line 59 of defaults/main.yml default: "keycloak-pass" - description: "TODO document argument" + description: "Password for database connection" type: "str" keycloak_quarkus_jdbc_url: # line 60 of defaults/main.yml default: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].url }}" - description: "TODO document argument" + description: "JDBC URL for connecting to database" type: "str" keycloak_quarkus_jdbc_driver_version: # line 61 of defaults/main.yml default: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].version }}" - description: "TODO document argument" + description: "Version for JDBC driver" type: "str" From 0751b97b87b87a4f1f19c95054acbdb0c4e8a43f Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 12 Apr 2022 12:07:06 +0200 Subject: [PATCH 056/554] Add custom xml parameter and test scenario --- molecule/default/converge.yml | 9 +- molecule/default/roles | 1 + molecule/overridexml/converge.yml | 43 ++ molecule/overridexml/molecule.yml | 53 ++ molecule/overridexml/prepare.yml | 12 + molecule/overridexml/requirements.yml | 10 + molecule/overridexml/roles | 1 + molecule/overridexml/templates/custom.xml.j2 | 604 +++++++++++++++++++ molecule/overridexml/verify.yml | 11 + molecule/quarkus/converge.yml | 2 +- roles/keycloak/README.md | 1 + roles/keycloak/defaults/main.yml | 1 + roles/keycloak/meta/argument_specs.yml | 5 + roles/keycloak/tasks/install.yml | 6 +- roles/keycloak/vars/main.yml | 1 + 15 files changed, 751 insertions(+), 9 deletions(-) create mode 120000 molecule/default/roles create mode 100644 molecule/overridexml/converge.yml create mode 100644 molecule/overridexml/molecule.yml create mode 100644 molecule/overridexml/prepare.yml create mode 100644 molecule/overridexml/requirements.yml create mode 120000 molecule/overridexml/roles create mode 100644 molecule/overridexml/templates/custom.xml.j2 create mode 100644 molecule/overridexml/verify.yml diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index 2ab6ad5..938aaa0 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -3,13 +3,12 @@ hosts: all vars: keycloak_admin_password: "remembertochangeme" + roles: + - role: keycloak tasks: - - name: Include keycloak role - include_role: - name: ../../roles/keycloak - name: Keycloak Realm Role - include_role: - name: ../../roles/keycloak_realm + ansible.builtin.include_role: + name: keycloak_realm vars: keycloak_client_default_roles: - TestRoleAdmin diff --git a/molecule/default/roles b/molecule/default/roles new file mode 120000 index 0000000..b741aa3 --- /dev/null +++ b/molecule/default/roles @@ -0,0 +1 @@ +../../roles \ No newline at end of file diff --git a/molecule/overridexml/converge.yml b/molecule/overridexml/converge.yml new file mode 100644 index 0000000..9304eba --- /dev/null +++ b/molecule/overridexml/converge.yml @@ -0,0 +1,43 @@ +--- +- name: Converge + hosts: all + vars: + keycloak_admin_password: "remembertochangeme" + keycloak_config_override_template: custom.xml.j2 + keycloak_http_port: 8081 + keycloak_management_http_port: 19990 + roles: + - role: keycloak + tasks: + - name: Keycloak Realm Role + ansible.builtin.include_role: + name: keycloak_realm + vars: + keycloak_client_default_roles: + - TestRoleAdmin + - TestRoleUser + keycloak_client_users: + - username: TestUser + password: password + client_roles: + - client: TestClient + role: TestRoleUser + realm: "{{ keycloak_realm }}" + - username: TestAdmin + password: password + client_roles: + - client: TestClient + role: TestRoleUser + realm: "{{ keycloak_realm }}" + - client: TestClient + role: TestRoleAdmin + realm: "{{ keycloak_realm }}" + keycloak_realm: TestRealm + keycloak_clients: + - name: TestClient + roles: "{{ keycloak_client_default_roles }}" + realm: "{{ keycloak_realm }}" + public_client: "{{ keycloak_client_public }}" + web_origins: "{{ keycloak_client_web_origins }}" + users: "{{ keycloak_client_users }}" + client_id: TestClient diff --git a/molecule/overridexml/molecule.yml b/molecule/overridexml/molecule.yml new file mode 100644 index 0000000..ea8ad61 --- /dev/null +++ b/molecule/overridexml/molecule.yml @@ -0,0 +1,53 @@ +--- +dependency: + name: shell + command: ansible-galaxy collection install -r molecule/default/requirements.yml -p $HOME/.ansible/collections --force-with-deps +driver: + name: docker +lint: | + ansible-lint --version + ansible-lint -v +platforms: + - name: instance + image: registry.access.redhat.com/ubi8/ubi-init:latest + pre_build_image: true + privileged: true + command: "/usr/sbin/init" + port_bindings: + - "8080/tcp" + - "8443/tcp" + - "8009/tcp" +provisioner: + name: ansible + config_options: + defaults: + interpreter_python: auto_silent + ssh_connection: + pipelining: false + playbooks: + prepare: prepare.yml + converge: converge.yml + verify: verify.yml + inventory: + host_vars: + localhost: + ansible_python_interpreter: "{{ ansible_playbook_python }}" + env: + ANSIBLE_FORCE_COLOR: "true" +verifier: + name: ansible +scenario: + test_sequence: + - dependency + - lint + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - side_effect + - verify + - cleanup + - destroy diff --git a/molecule/overridexml/prepare.yml b/molecule/overridexml/prepare.yml new file mode 100644 index 0000000..03433c0 --- /dev/null +++ b/molecule/overridexml/prepare.yml @@ -0,0 +1,12 @@ +--- +- name: Prepare + hosts: all + tasks: + - name: Disable beta repos + ansible.builtin.command: yum config-manager --disable '*beta*' + ignore_errors: yes + + - name: Install sudo + ansible.builtin.yum: + name: sudo + state: present diff --git a/molecule/overridexml/requirements.yml b/molecule/overridexml/requirements.yml new file mode 100644 index 0000000..9aa3437 --- /dev/null +++ b/molecule/overridexml/requirements.yml @@ -0,0 +1,10 @@ +--- +collections: + - name: middleware_automation.redhat_csp_download + version: ">=1.2.1" + - name: middleware_automation.wildfly + version: ">=0.0.5" + - name: community.general + - name: community.docker + version: ">=1.9.1" + diff --git a/molecule/overridexml/roles b/molecule/overridexml/roles new file mode 120000 index 0000000..b741aa3 --- /dev/null +++ b/molecule/overridexml/roles @@ -0,0 +1 @@ +../../roles \ No newline at end of file diff --git a/molecule/overridexml/templates/custom.xml.j2 b/molecule/overridexml/templates/custom.xml.j2 new file mode 100644 index 0000000..a59561a --- /dev/null +++ b/molecule/overridexml/templates/custom.xml.j2 @@ -0,0 +1,604 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE + h2 + + sa + sa + + + + + org.h2.jdbcx.JdbcDataSource + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + auth + + + classpath:${jboss.home.dir}/providers/* + + + master + 900 + + 2592000 + true + true + ${jboss.home.dir}/themes + + + + + + + + + + + + + jpa + + + basic + + + + + + + + + + + + + + + + + + + default + + + + + + + + ${keycloak.jta.lookup.provider:jboss} + + + + + + + + + + + ${keycloak.x509cert.lookup.provider:default} + + + + default + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/molecule/overridexml/verify.yml b/molecule/overridexml/verify.yml new file mode 100644 index 0000000..ef973cd --- /dev/null +++ b/molecule/overridexml/verify.yml @@ -0,0 +1,11 @@ +--- +- name: Verify + hosts: all + tasks: + - name: Populate service facts + ansible.builtin.service_facts: + - name: Check if keycloak service started + ansible.builtin.assert: + that: + - ansible_facts.services["keycloak.service"]["state"] == "running" + - ansible_facts.services["keycloak.service"]["status"] == "enabled" diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index 452212b..1f77fe5 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -3,12 +3,12 @@ hosts: all vars: keycloak_quarkus_admin_pass: "remembertochangeme" + keycloak_admin_password: "remembertochangeme" keycloak_realm: TestRealm roles: - role: keycloak_quarkus - role: keycloak_realm keycloak_context: '' - keycloak_admin_password: "remembertochangeme" keycloak_client_default_roles: - TestRoleAdmin - TestRoleUser diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index 3588b86..7ef3cb5 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -99,6 +99,7 @@ Role Defaults |`keycloak_jboss_home` | Installation work directory | `{{ keycloak_rhsso_installdir if keycloak_rhsso_enable else keycloak_installdir }}` | |`keycloak_config_dir` | Path for configuration | `{{ keycloak_jboss_home }}/standalone/configuration` | |`keycloak_config_path_to_standalone_xml` | Custom path for configuration | `{{ keycloak_jboss_home }}/standalone/configuration/{{ keycloak_config_standalone_xml }}` | +|`keycloak_config_override_template` | Path to custom template for standalone.xml configuration | `''` | |`keycloak_auth_realm` | Name for rest authentication realm | `master` | |`keycloak_auth_client` | Authentication client for configuration REST calls | `admin-cli` | |`keycloak_force_install` | Remove pre-existing versions of service | `False` | diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index c9d8d29..f33d332 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -27,6 +27,7 @@ keycloak_jboss_home: "{{ keycloak_rhsso_installdir if keycloak_rhsso_enable else keycloak_config_dir: "{{ keycloak_jboss_home }}/standalone/configuration" keycloak_config_standalone_xml: "keycloak.xml" keycloak_config_path_to_standalone_xml: "{{ keycloak_jboss_home }}/standalone/configuration/{{ keycloak_config_standalone_xml }}" +keycloak_config_override_template: '' keycloak_service_user: keycloak keycloak_service_group: keycloak keycloak_service_pidfile: "/run/keycloak.pid" diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 3c428c9..67121c2 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -106,6 +106,11 @@ argument_specs: default: "{{ keycloak_jboss_home }}/standalone/configuration/{{ keycloak_config_standalone_xml }}" description: "Custom path for configuration" type: "str" + keycloak_config_override_template: + # line 30 of keycloak/defaults/main.yml + default: "" + description: "Path to custom template for standalone.xml configuration" + type: "str" keycloak_service_user: # line 29 of keycloak/defaults/main.yml default: "keycloak" diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index c45a842..9e0dbd3 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -181,17 +181,17 @@ jdbc_driver_module_name: "{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_name }}" when: keycloak_jdbc[keycloak_jdbc_engine].enabled -- name: "Deploy {{ keycloak.service_name }} config to {{ keycloak_config_path_to_standalone_xml }}" +- name: "Deploy {{ keycloak.service_name }} config to {{ keycloak_config_path_to_standalone_xml }} from {{ keycloak.config_template_source }}" become: yes ansible.builtin.template: - src: templates/standalone.xml.j2 + src: "templates/{{ keycloak.config_template_source }}" dest: "{{ keycloak_config_path_to_standalone_xml }}" owner: "{{ keycloak_service_user }}" group: "{{ keycloak_service_group }}" mode: 0640 notify: - restart keycloak - when: not keycloak_remotecache.enabled + when: not keycloak_remotecache.enabled or keycloak_config_override_template|length > 0 - name: "Deploy {{ keycloak.service_name }} config with remote cache store to {{ keycloak_config_path_to_standalone_xml }}" become: yes diff --git a/roles/keycloak/vars/main.yml b/roles/keycloak/vars/main.yml index 437eac0..f639970 100644 --- a/roles/keycloak/vars/main.yml +++ b/roles/keycloak/vars/main.yml @@ -20,6 +20,7 @@ keycloak: service_name: "{{ 'rhsso' if keycloak_rhsso_enable else 'keycloak' }}" health_url: "{{ keycloak_management_url }}/health" cli_path: "{{ keycloak_jboss_home }}/bin/jboss-cli.sh" + config_template_source: "{{ keycloak_config_override_template if keycloak_config_override_template | length > 0 else 'standalone.xml.j2' }}" # database keycloak_jdbc: From e3bb10d9011492e0cdd050b8b4876c1ccb8b2212 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 28 Apr 2022 11:33:23 +0200 Subject: [PATCH 057/554] fix: ensure correct jvm java_home is set --- playbooks/keycloak.yml | 2 +- roles/keycloak/README.md | 3 ++- roles/keycloak/defaults/main.yml | 3 ++- roles/keycloak/handlers/main.yml | 2 +- roles/keycloak/meta/argument_specs.yml | 3 +++ roles/keycloak/tasks/rhsso_patch.yml | 2 +- roles/keycloak/tasks/systemd.yml | 10 ++++++++++ roles/keycloak/templates/keycloak-service.sh.j2 | 4 ++-- roles/keycloak/templates/keycloak-sysconfig.j2 | 3 ++- 9 files changed, 24 insertions(+), 8 deletions(-) diff --git a/playbooks/keycloak.yml b/playbooks/keycloak.yml index e4ac27c..2b222a5 100644 --- a/playbooks/keycloak.yml +++ b/playbooks/keycloak.yml @@ -6,4 +6,4 @@ collections: - middleware_automation.keycloak roles: - - middleware_automation.keycloak.keycloak + - keycloak diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index 7ef3cb5..c63085b 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -60,13 +60,14 @@ Role Defaults |`keycloak_jgroups_port`| jgroups cluster tcp port | `7600` | |`keycloak_management_http_port`| Management port | `9990` | |`keycloak_management_https_port`| TLS management port | `9993` | -|`keycloak_java_opts`| Additional JVM options | `-Xms1024m -Xmx2048m` | |`keycloak_prefer_ipv4`| Prefer IPv4 stack and addresses for port binding | `True` | |`keycloak_config_standalone_xml`| filename for configuration | `keycloak.xml` | |`keycloak_service_user`| posix account username | `keycloak` | |`keycloak_service_group`| posix account group | `keycloak` | |`keycloak_service_pidfile`| pid file path for service | `/run/keycloak.pid` | |`keycloak_jvm_package`| RHEL java package runtime | `java-1.8.0-openjdk-devel` | +|`keycloak_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_jvm_package RPM path | `None` | +|`keycloak_java_opts`| Additional JVM options | `-Xms1024m -Xmx2048m` | * Install options diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index f33d332..7ef632a 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -21,7 +21,8 @@ keycloak_rhsso_enable: "{{ True if rhsso_rhn_id is defined and rhn_username is d keycloak_offline_install: False ### Install location and service settings -keycloak_jvm_package: java-1.8.0-openjdk-devel +keycloak_jvm_package: java-1.8.0-openjdk-headless +keycloak_java_home: keycloak_dest: /opt/keycloak keycloak_jboss_home: "{{ keycloak_rhsso_installdir if keycloak_rhsso_enable else keycloak_installdir }}" keycloak_config_dir: "{{ keycloak_jboss_home }}/standalone/configuration" diff --git a/roles/keycloak/handlers/main.yml b/roles/keycloak/handlers/main.yml index dda3682..4dd6ba2 100644 --- a/roles/keycloak/handlers/main.yml +++ b/roles/keycloak/handlers/main.yml @@ -1,4 +1,4 @@ --- -- name: "Restart {{ keycloak.service_name }}" +- name: "Restart handler" ansible.builtin.include_tasks: restart_keycloak.yml listen: "restart keycloak" diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 67121c2..24b644c 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -81,6 +81,9 @@ argument_specs: default: "java-1.8.0-openjdk-devel" description: "RHEL java package runtime rpm" type: "str" + keycloak_java_home: + description: "JAVA_HOME of installed JRE, leave empty for using specified keycloak_jvm_package RPM path" + type: "str" keycloak_dest: # line 24 of keycloak/defaults/main.yml default: "/opt/keycloak" diff --git a/roles/keycloak/tasks/rhsso_patch.yml b/roles/keycloak/tasks/rhsso_patch.yml index d4a4273..b290877 100644 --- a/roles/keycloak/tasks/rhsso_patch.yml +++ b/roles/keycloak/tasks/rhsso_patch.yml @@ -31,7 +31,7 @@ dest: "{{ patch_archive }}" owner: "{{ keycloak_service_user }}" group: "{{ keycloak_service_group }}" - mode: 0750 + mode: 0640 register: new_version_downloaded when: - not patch_archive_path.stat.exists diff --git a/roles/keycloak/tasks/systemd.yml b/roles/keycloak/tasks/systemd.yml index cfc3762..8145189 100644 --- a/roles/keycloak/tasks/systemd.yml +++ b/roles/keycloak/tasks/systemd.yml @@ -9,6 +9,14 @@ notify: - restart keycloak +- name: Determine JAVA_HOME for selected JVM RPM + shell: | + set -o pipefail + rpm -ql {{ keycloak_jvm_package }} | grep -Po '/usr/lib/jvm/.*(?=/bin/java$)' + args: + executable: /bin/bash + register: rpm_java_home + - name: "Configure sysconfig file for {{ keycloak.service_name }} service" become: yes ansible.builtin.template: @@ -17,6 +25,8 @@ owner: root group: root mode: 0644 + vars: + keycloak_rpm_java_home: "{{ rpm_java_home.stdout }}" notify: - restart keycloak diff --git a/roles/keycloak/templates/keycloak-service.sh.j2 b/roles/keycloak/templates/keycloak-service.sh.j2 index 2281b17..577959e 100755 --- a/roles/keycloak/templates/keycloak-service.sh.j2 +++ b/roles/keycloak/templates/keycloak-service.sh.j2 @@ -17,7 +17,7 @@ checkEnvVar() { # for testing outside systemd . /etc/sysconfig/keycloak -readonly KEYCLOAK_HOME={{ keycloak_jboss_home }} +readonly KEYCLOAK_HOME={{ keycloak.home }} readonly KEYCLOAK_BIND_ADDRESS=${KEYCLOAK_BIND_ADDRESS} readonly KEYCLOAK_HTTP_PORT=${KEYCLOAK_HTTP_PORT} readonly KEYCLOAK_HTTPS_PORT=${KEYCLOAK_HTTPS_PORT} @@ -27,7 +27,7 @@ readonly KEYCLOAK_PIDFILE={{ keycloak_service_pidfile }} set -u if [ ! -d "${KEYCLOAK_HOME}" ]; then - echo "KEYCLOAK_HOME (${KEYCLOAK_HOME}) is not a director or does not exists." + echo "KEYCLOAK_HOME (${KEYCLOAK_HOME}) is not a directory or does not exists." exit 1 fi diff --git a/roles/keycloak/templates/keycloak-sysconfig.j2 b/roles/keycloak/templates/keycloak-sysconfig.j2 index 15b777c..68474c3 100644 --- a/roles/keycloak/templates/keycloak-sysconfig.j2 +++ b/roles/keycloak/templates/keycloak-sysconfig.j2 @@ -1,6 +1,7 @@ # {{ ansible_managed }} JAVA_OPTS='{{ keycloak_java_opts }}' -JBOSS_HOME={{ keycloak_jboss_home }} +JAVA_HOME={{ keycloak_java_home | default(keycloak_rpm_java_home, true) }} +JBOSS_HOME={{ keycloak.home }} KEYCLOAK_BIND_ADDRESS={{ keycloak_bind_address }} KEYCLOAK_HTTP_PORT={{ keycloak_http_port }} KEYCLOAK_HTTPS_PORT={{ keycloak_https_port }} From 9987f6a0444478f7d4b1bef3fe95fa6e4529f915 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 28 Apr 2022 11:33:40 +0200 Subject: [PATCH 058/554] update molecule test and verify for jvm --- molecule/default/converge.yml | 1 + molecule/default/prepare.yml | 4 +++- molecule/default/verify.yml | 17 +++++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index 938aaa0..7e73d70 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -3,6 +3,7 @@ hosts: all vars: keycloak_admin_password: "remembertochangeme" + keycloak_jvm_package: java-11-openjdk-headless roles: - role: keycloak tasks: diff --git a/molecule/default/prepare.yml b/molecule/default/prepare.yml index 03433c0..8137cfd 100644 --- a/molecule/default/prepare.yml +++ b/molecule/default/prepare.yml @@ -8,5 +8,7 @@ - name: Install sudo ansible.builtin.yum: - name: sudo + name: + - sudo + - java-1.8.0-openjdk state: present diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml index ef973cd..8bd5b6f 100644 --- a/molecule/default/verify.yml +++ b/molecule/default/verify.yml @@ -1,6 +1,11 @@ --- - name: Verify hosts: all + vars: + keycloak_admin_password: "remembertochangeme" + keycloak_jvm_package: java-11-openjdk-headless + keycloak_port: http://localhost:8080 + keycloak_management_port: http://localhost:9990 tasks: - name: Populate service facts ansible.builtin.service_facts: @@ -9,3 +14,15 @@ that: - ansible_facts.services["keycloak.service"]["state"] == "running" - ansible_facts.services["keycloak.service"]["status"] == "enabled" + - name: Verify we are running on requested jvm + shell: | + ps -ef | grep /usr/lib/jvm/java-11 | grep -v grep + - name: Verify token api call + ansible.builtin.uri: + url: "{{ keycloak_port }}/auth/realms/master/protocol/openid-connect/token" + method: POST + body: "client_id=admin-cli&username=admin&password={{ keycloak_admin_password }}&grant_type=password" + validate_certs: no + until: keycloak_auth_response.status == 200 + retries: 2 + delay: 2 \ No newline at end of file From 78d5499abf5f2401150f4bbb5186c9e3d30ce412 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 28 Apr 2022 11:58:29 +0200 Subject: [PATCH 059/554] fix: linter --- molecule/default/verify.yml | 1 + roles/keycloak/tasks/install.yml | 6 ++++-- roles/keycloak/tasks/rhsso_patch.yml | 2 +- roles/keycloak/tasks/systemd.yml | 5 +++-- roles/keycloak_quarkus/tasks/install.yml | 3 ++- 5 files changed, 11 insertions(+), 6 deletions(-) diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml index 8bd5b6f..07acf4d 100644 --- a/molecule/default/verify.yml +++ b/molecule/default/verify.yml @@ -23,6 +23,7 @@ method: POST body: "client_id=admin-cli&username=admin&password={{ keycloak_admin_password }}&grant_type=password" validate_certs: no + register: keycloak_auth_response until: keycloak_auth_response.status == 200 retries: 2 delay: 2 \ No newline at end of file diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index 9e0dbd3..7fee03d 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -71,9 +71,10 @@ delegate_to: localhost - name: Download keycloak archive - ansible.builtin.get_url: + ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user url: "{{ keycloak_download_url }}" dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" + mode: 0640 delegate_to: localhost when: - archive_path is defined @@ -99,9 +100,10 @@ - keycloak_rhn_url in keycloak_rhsso_download_url - name: Download rhsso archive from alternate location - ansible.builtin.get_url: + ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user url: "{{ keycloak_rhsso_download_url }}" dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" + mode: 0640 delegate_to: localhost when: - archive_path is defined diff --git a/roles/keycloak/tasks/rhsso_patch.yml b/roles/keycloak/tasks/rhsso_patch.yml index b290877..f517e7a 100644 --- a/roles/keycloak/tasks/rhsso_patch.yml +++ b/roles/keycloak/tasks/rhsso_patch.yml @@ -83,5 +83,5 @@ success_msg: "Patch installation successful" - name: "Skipping patch" - debug: + ansible.builtin.debug: msg: "Latest cumulative patch {{ rhsso_rhn_ids[keycloak_rhsso_version].latest_cp.v }} already installed, skipping patch installation." diff --git a/roles/keycloak/tasks/systemd.yml b/roles/keycloak/tasks/systemd.yml index 8145189..77f7d7c 100644 --- a/roles/keycloak/tasks/systemd.yml +++ b/roles/keycloak/tasks/systemd.yml @@ -9,12 +9,13 @@ notify: - restart keycloak -- name: Determine JAVA_HOME for selected JVM RPM - shell: | +- name: Determine JAVA_HOME for selected JVM RPM # noqa blocked_modules + ansible.builtin.shell: | set -o pipefail rpm -ql {{ keycloak_jvm_package }} | grep -Po '/usr/lib/jvm/.*(?=/bin/java$)' args: executable: /bin/bash + changed_when: False register: rpm_java_home - name: "Configure sysconfig file for {{ keycloak.service_name }} service" diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index c8e5b73..ba6ec40 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -52,9 +52,10 @@ delegate_to: localhost - name: Download keycloak archive - ansible.builtin.get_url: + ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user url: "{{ keycloak_quarkus_download_url }}" dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" + mode: 0640 delegate_to: localhost when: - archive_path is defined From 8341416ee0da322648f65a574fdc0c726ef5b086 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 9 May 2022 15:57:12 +0200 Subject: [PATCH 060/554] keycloak: default jvm to headless variant, add jdbc validation --- roles/keycloak/README.md | 2 +- roles/keycloak/meta/argument_specs.yml | 2 +- roles/keycloak/tasks/prereqs.yml | 14 +++++++++++++- roles/keycloak/tasks/systemd.yml | 1 + 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index c63085b..71787b1 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -65,7 +65,7 @@ Role Defaults |`keycloak_service_user`| posix account username | `keycloak` | |`keycloak_service_group`| posix account group | `keycloak` | |`keycloak_service_pidfile`| pid file path for service | `/run/keycloak.pid` | -|`keycloak_jvm_package`| RHEL java package runtime | `java-1.8.0-openjdk-devel` | +|`keycloak_jvm_package`| RHEL java package runtime | `java-1.8.0-openjdk-headless` | |`keycloak_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_jvm_package RPM path | `None` | |`keycloak_java_opts`| Additional JVM options | `-Xms1024m -Xmx2048m` | diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 24b644c..983d59d 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -78,7 +78,7 @@ argument_specs: type: "bool" keycloak_jvm_package: # line 23 of keycloak/defaults/main.yml - default: "java-1.8.0-openjdk-devel" + default: "java-1.8.0-openjdk-headless" description: "RHEL java package runtime rpm" type: "str" keycloak_java_home: diff --git a/roles/keycloak/tasks/prereqs.yml b/roles/keycloak/tasks/prereqs.yml index c84dccb..4df0d96 100644 --- a/roles/keycloak/tasks/prereqs.yml +++ b/roles/keycloak/tasks/prereqs.yml @@ -4,7 +4,7 @@ that: - keycloak_admin_password | length > 12 quiet: True - fail_msg: "The console administrator password is empty or invalid. Please set the keycloak_admin_password variable to a 16+ char long string" + fail_msg: "The console administrator password is empty or invalid. Please set the keycloak_admin_password variable to a 12+ char long string" success_msg: "{{ 'Console administrator password OK' }}" - name: Validate configuration @@ -24,6 +24,18 @@ fail_msg: "Cannot install Red Hat SSO without RHN credentials. Check rhn_username and rhn_password are defined" success_msg: "{{ 'Installing Red Hat Single Sign-On' if keycloak_rhsso_enable else 'Installing keycloak.org' }}" +- name: Validate persistence configuration + ansible.builtin.assert: + that: + - keycloak_jdbc_engine is defined and keycloak_jdbc_engine in [ 'postgres', 'mariadb' ] + - keycloak_jdbc_url | length > 0 + - keycloak_db_user | length > 0 + - keycloak_db_pass | length > 0 + quiet: True + when: keycloak_db_enabled + fail_msg: "Configuration for the JDBC persistence is invalid or incomplete" + success_msg: "Configuring JDBC persistence using {{ keycloak_jdbc_engine }} database" + - name: Ensure required packages are installed ansible.builtin.include_tasks: fastpackages.yml vars: diff --git a/roles/keycloak/tasks/systemd.yml b/roles/keycloak/tasks/systemd.yml index 77f7d7c..871180f 100644 --- a/roles/keycloak/tasks/systemd.yml +++ b/roles/keycloak/tasks/systemd.yml @@ -1,3 +1,4 @@ +--- - name: "Configure {{ keycloak.service_name }} service script wrapper" become: yes ansible.builtin.template: From 7d57857a1fb867194a1af6a64ed3569eb1e24a01 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 9 May 2022 16:00:00 +0200 Subject: [PATCH 061/554] ci: use github custom action --- .github/workflows/release.yml | 40 ++++++++++------------------------- 1 file changed, 11 insertions(+), 29 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9a497a9..6704e48 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -50,35 +50,17 @@ jobs: run: | ansible-galaxy collection build . - - name: Scan PR merges from latest tag - run: | - TYPES=("minor_changes" "major_changes" "bugfixes" "deprecated_features" "removed_features" "breaking_changes") - TAG=$(git describe --abbrev=0 --tags) - PRS=($(comm -12 <(git log --oneline ${TAG}.. --format="tformat:%H" | sort ) <(hub pr list -s all -f '%sm%n' --color=never | sort ))) - IFS=$'\n' FRAGMENTS=($(hub pr list -s all -f '%sm~%I~%L~%t~%n' --color=never| grep -P "$(echo "^(${PRS[@]})" | tr ' ' '|')")) - for frag in "${FRAGMENTS[@]}"; do - PR=$(echo $frag|cut -d~ -f2) - type="$(echo $frag|cut -d~ -f3)" - msg="$(echo $frag|cut -d~ -f4|sed 's/`/``/g')" - if [[ "$type" != "" && "${TYPES[*]}" =~ "${type}" ]]; then - echo -e "$type:\n - >\n $msg \`#${PR} \`_" \ - > changelogs/fragments/${PR}.yaml - fi - done - antsibull-changelog lint -vvv - antsibull-changelog generate - antsibull-changelog release - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Commit changelogs - run: | - git config user.name github-actions - git config user.email github-actions@github.com - git diff --minimal --output-indicator-new=' ' -U0 --no-indent-heuristic CHANGELOG.rst | grep "^ "| sed -e 's/`\(#[0-9]\+\) <.*_/\1/g' > gh-release.md - git add CHANGELOG.rst changelogs/changelog.yaml - git commit -m "Update changelog for release ${{ steps.get_version.outputs.TAG_VERSION }}" || true - git push origin + - name: Create changelog and documentation + uses: ansible-middleware/collection-docs-action@main + with: + collection_fqcn: middleware_automation.keycloak + collection_repo: ansible-middleware/keycloak + dependencies: false + commit_changelog: true + commit_ghpages: false + changelog_release: true + generate_docs: false + token: ${{ secrets.GITHUB_TOKEN }} - name: Publish collection env: From 4167edda63b8497da65622b1bd0fd37c3e9125f4 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 9 May 2022 17:22:52 +0200 Subject: [PATCH 062/554] ci: use tar creating token, allow dispatch of docs --- .github/workflows/docs.yml | 1 + .github/workflows/release.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index d81f4ff..7345971 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -6,6 +6,7 @@ on: - main tags: - "[0-9]+.[0-9]+.[0-9]+" + workflow_dispatch: env: COLORTERM: 'yes' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6704e48..3a48b3b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -19,6 +19,7 @@ jobs: uses: actions/checkout@v3 with: fetch-depth: 0 + token: ${{ secrets.TRIGGERING_PAT }} - name: Set up Python uses: actions/setup-python@v1 From 37141455267fa33c7f4a32bc09a1eb06afb65468 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 9 May 2022 17:26:20 +0200 Subject: [PATCH 063/554] keycloak: fix jdbc assert --- roles/keycloak/tasks/prereqs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak/tasks/prereqs.yml b/roles/keycloak/tasks/prereqs.yml index 4df0d96..31735d5 100644 --- a/roles/keycloak/tasks/prereqs.yml +++ b/roles/keycloak/tasks/prereqs.yml @@ -32,9 +32,9 @@ - keycloak_db_user | length > 0 - keycloak_db_pass | length > 0 quiet: True - when: keycloak_db_enabled fail_msg: "Configuration for the JDBC persistence is invalid or incomplete" success_msg: "Configuring JDBC persistence using {{ keycloak_jdbc_engine }} database" + when: keycloak_db_enabled - name: Ensure required packages are installed ansible.builtin.include_tasks: fastpackages.yml From f4674a876257050910cf1aa1a20c743ce45d53a6 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 9 May 2022 17:34:19 +0200 Subject: [PATCH 064/554] ci: release triggers with correct tag version --- .github/workflows/release.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3a48b3b..f8cdffe 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,6 +14,8 @@ jobs: deployments: write packages: write pages: write + outputs: + tag_version: ${{ steps.get_version.outputs.TAG_VERSION }} steps: - name: Checkout code uses: actions/checkout@v3 @@ -97,5 +99,5 @@ jobs: with: token: ${{ secrets.TRIGGERING_PAT }} repository: ${{ matrix.repo }} - event-type: "Dependency released - Keycloak v${{ steps.get_version.outputs.TAG_VERSION }}" + event-type: "Dependency released - Keycloak v${{ needs.release.outputs.tag_version }}" client-payload: '{ "github": ${{toJson(github)}} }' From 95c346d4b3783f913815d85bbc4c2b6087cd471e Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 9 May 2022 15:51:47 +0000 Subject: [PATCH 065/554] Update changelog for release 1.0.3 --- CHANGELOG.rst | 18 ++++++++++++++++++ changelogs/changelog.yaml | 20 ++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 4644d47..4e8f136 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,24 @@ middleware_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v1.0.3 +====== + +Major Changes +------------- + +- New role for installing keycloak >= 17.0.0 (quarkus) `#29 `_ + +Minor Changes +------------- + +- Add ``keycloak_config_override_template`` parameter for passing a custom xml config template `#30 `_ + +Bugfixes +-------- + +- Make sure systemd unit starts with selected java JVM `#31 `_ + v1.0.2 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 6200619..db7e712 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -38,3 +38,23 @@ releases: - 25.yaml - 26.yaml release_date: '2022-04-01' + 1.0.3: + changes: + bugfixes: + - 'Make sure systemd unit starts with selected java JVM `#31 `_ + + ' + major_changes: + - 'New role for installing keycloak >= 17.0.0 (quarkus) `#29 `_ + + ' + minor_changes: + - 'Add ``keycloak_config_override_template`` parameter for passing a custom + xml config template `#30 `_ + + ' + fragments: + - 29.yaml + - 30.yaml + - 31.yaml + release_date: '2022-05-09' From 3b45c133b83a55b659f6eb0045362149601f8078 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 11 May 2022 10:38:52 +0200 Subject: [PATCH 066/554] fix incorrect downloaded archive filemode --- roles/keycloak/tasks/install.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index 7fee03d..861bca0 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -74,7 +74,7 @@ ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user url: "{{ keycloak_download_url }}" dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" - mode: 0640 + mode: 0644 delegate_to: localhost when: - archive_path is defined @@ -103,7 +103,7 @@ ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user url: "{{ keycloak_rhsso_download_url }}" dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" - mode: 0640 + mode: 0644 delegate_to: localhost when: - archive_path is defined @@ -126,7 +126,7 @@ dest: "{{ archive }}" owner: "{{ keycloak_service_user }}" group: "{{ keycloak_service_group }}" - mode: 0750 + mode: 0640 register: new_version_downloaded when: - not archive_path.stat.exists From 9278d3440e1aaf15768a2eb7c70e2efec27c2c84 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 11 May 2022 11:33:52 +0200 Subject: [PATCH 067/554] ci: linter version update fixes --- .ansible-lint | 4 +++- roles/keycloak/tasks/fastpackages.yml | 3 ++- roles/keycloak/tasks/install.yml | 3 ++- roles/keycloak/tasks/main.yml | 3 ++- roles/keycloak/vars/main.yml | 2 +- roles/keycloak_quarkus/tasks/fastpackages.yml | 3 ++- 6 files changed, 12 insertions(+), 6 deletions(-) diff --git a/.ansible-lint b/.ansible-lint index eef1f63..5472a97 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -16,12 +16,14 @@ enable_list: warn_list: - role_vars_start_with_role_name - vars_in_vars_files_have_valid_names - - vars_should_not_be_used - experimental - ignore-errors - no-handler - fqcn-builtins - no-log-password +skip_list: + - vars_should_not_be_used + use_default_rules: true parseable: true diff --git a/roles/keycloak/tasks/fastpackages.yml b/roles/keycloak/tasks/fastpackages.yml index 29155f9..78bc556 100644 --- a/roles/keycloak/tasks/fastpackages.yml +++ b/roles/keycloak/tasks/fastpackages.yml @@ -1,5 +1,6 @@ --- -- block: +- name: Check packages to be installed + block: - name: "Check if packages are already installed" ansible.builtin.command: "rpm -q {{ packages_list | join(' ') }}" args: diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index 861bca0..26c5466 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -16,7 +16,8 @@ path: "{{ keycloak_jboss_home }}" register: existing_deploy -- block: +- name: Stop and restart if existing deployment exists and install forced + block: - name: "Stop the old {{ keycloak.service_name }} service" become: yes ignore_errors: yes diff --git a/roles/keycloak/tasks/main.yml b/roles/keycloak/tasks/main.yml index c16f6cb..ba5ec87 100644 --- a/roles/keycloak/tasks/main.yml +++ b/roles/keycloak/tasks/main.yml @@ -35,7 +35,8 @@ src: "{{ keycloak_jboss_home }}/standalone/log" dest: /var/log/keycloak -- block: +- name: Set admin credentials and restart if not already created + block: - name: Check admin credentials by generating a token (supposed to fail on first installation) ansible.builtin.uri: url: "{{ keycloak_url }}/auth/realms/master/protocol/openid-connect/token" diff --git a/roles/keycloak/vars/main.yml b/roles/keycloak/vars/main.yml index f639970..5a6b059 100644 --- a/roles/keycloak/vars/main.yml +++ b/roles/keycloak/vars/main.yml @@ -1,7 +1,7 @@ --- # internal variables below rhsso_rhn_ids: - '7.5.0': + '7.5.0': # noqa vars_in_vars_files_have_valid_names id: '101971' latest_cp: id: '103836' diff --git a/roles/keycloak_quarkus/tasks/fastpackages.yml b/roles/keycloak_quarkus/tasks/fastpackages.yml index 29155f9..78bc556 100644 --- a/roles/keycloak_quarkus/tasks/fastpackages.yml +++ b/roles/keycloak_quarkus/tasks/fastpackages.yml @@ -1,5 +1,6 @@ --- -- block: +- name: Check packages to be installed + block: - name: "Check if packages are already installed" ansible.builtin.command: "rpm -q {{ packages_list | join(' ') }}" args: From 9e3cd224847e28adc671dac7fb21ba93d2cd5f4e Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 11 May 2022 14:05:43 +0200 Subject: [PATCH 068/554] Bump to 1.0.4 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index a697240..40279e4 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.0.3" +version: "1.0.4" readme: README.md authors: - Romain Pelisse From 2cc835219cf7b250866e552fc990ee3dbebccf89 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 11 May 2022 12:23:41 +0000 Subject: [PATCH 069/554] Update changelog for release 1.0.4 --- CHANGELOG.rst | 3 +++ changelogs/changelog.yaml | 2 ++ 2 files changed, 5 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 4e8f136..c0aca3c 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,9 @@ middleware_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v1.0.4 +====== + v1.0.3 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index db7e712..f43e0d7 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -58,3 +58,5 @@ releases: - 30.yaml - 31.yaml release_date: '2022-05-09' + 1.0.4: + release_date: '2022-05-11' From 31420fc24ce21163d8172c1ae67daacb37945ba8 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 17 May 2022 18:59:10 +0200 Subject: [PATCH 070/554] update config options: keycloak and quarkus --- roles/keycloak_quarkus/defaults/main.yml | 15 +++++- .../keycloak_quarkus/meta/argument_specs.yml | 36 +++++++++++++ roles/keycloak_quarkus/tasks/fastpackages.yml | 2 +- roles/keycloak_quarkus/tasks/main.yml | 18 ++++++- .../templates/keycloak-sysconfig.j2 | 2 +- .../templates/keycloak.conf.j2 | 54 +++++++++---------- .../templates/keycloak.service.j2 | 2 +- .../templates/quarkus.properties.j2 | 19 +++++++ roles/keycloak_quarkus/vars/main.yml | 6 ++- 9 files changed, 120 insertions(+), 34 deletions(-) create mode 100644 roles/keycloak_quarkus/templates/quarkus.properties.j2 diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 6778308..f8cefdd 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -26,12 +26,18 @@ keycloak_quarkus_master_realm: master ### Configuration settings keycloak_quarkus_bind_address: 0.0.0.0 keycloak_quarkus_host: localhost +keycloak_quarkus_http_enabled: True keycloak_quarkus_http_port: 8080 keycloak_quarkus_https_port: 8443 keycloak_quarkus_ajp_port: 8009 keycloak_quarkus_jgroups_port: 7600 keycloak_quarkus_java_opts: "-Xms1024m -Xmx2048m" +### TLS/HTTPS configuration +keycloak_quarkus_https_enabled: False +keycloak_quarkus_key_file: conf/server.key.pem +keycloak_quarkus_cert_file: conf/server.crt.pem + ### Enable configuration for database backend, clustering and remote caches on infinispan keycloak_quarkus_ha_enabled: False ### Enable database configuration, must be enabled when HA is configured @@ -42,6 +48,7 @@ keycloak_quarkus_http_relative_path: auth keycloak_quarkus_frontend_url: http://localhost:8080/auth keycloak_quarkus_metrics_enabled: False +keycloak_quarkus_health_enabled: True ### infinispan remote caches access (hotrod) keycloak_quarkus_ispn_user: supervisor @@ -67,4 +74,10 @@ keycloak_quarkus_default_jdbc: version: 9.4.1212 mariadb: url: 'jdbc:mariadb://localhost:3306/keycloak' - version: 2.7.4 \ No newline at end of file + version: 2.7.4 + +### logging configuration +keycloak_quarkus_log: file +keycloak_quarkus_log_level: info +keycloak_quarkus_log_file: data/log/keycloak.log +keycloak_quarkus_log_format: '%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n' diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 78382f9..b10f83a 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -91,11 +91,27 @@ argument_specs: default: "localhost" description: "hostname" type: "str" + keycloak_quarkus_http_enabled: + default: true + description: "Enable listener on HTTP port" + type: "bool" keycloak_quarkus_http_port: # line 29 of defaults/main.yml default: 8080 description: "HTTP port" type: "int" + keycloak_quarkus_https_enabled: + default: false + description: "Enable listener on HTTPS port" + type: "bool" + keycloak_quarkus_key_file: + default: "conf/server.key.pem" + description: "The file path to a private key in PEM format" + type: "str" + keycloak_quarkus_cert_file: + default: "conf/server.crt.pem" + description: "The file path to a server certificate or certificate chain in PEM format" + type: "str" keycloak_quarkus_https_port: # line 30 of defaults/main.yml default: 8443 @@ -141,6 +157,10 @@ argument_specs: default: false description: "Whether to enable metrics" type: "bool" + keycloak_quarkus_health_enabled: + default: true + description: "If the server should expose health check endpoints" + type: "bool" keycloak_quarkus_ispn_user: # line 46 of defaults/main.yml default: "supervisor" @@ -201,3 +221,19 @@ argument_specs: default: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].version }}" description: "Version for JDBC driver" type: "str" + keycloak_quarkus_log: + default: "file" + type: "str" + description: "Enable one or more log handlers in a comma-separated list" + keycloak_quarkus_log_level: + default: "info" + type: "str" + description: "The log level of the root category or a comma-separated list of individual categories and their levels" + keycloak_quarkus_log_file: + default: "data/log/keycloak.log" + type: "str" + description: "Set the log file path and filename relative to keycloak home" + keycloak_quarkus_log_format: + default: '%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n' + type: "str" + description: "Set a format specific to file log entries" diff --git a/roles/keycloak_quarkus/tasks/fastpackages.yml b/roles/keycloak_quarkus/tasks/fastpackages.yml index 78bc556..3dd28e1 100644 --- a/roles/keycloak_quarkus/tasks/fastpackages.yml +++ b/roles/keycloak_quarkus/tasks/fastpackages.yml @@ -14,7 +14,7 @@ packages_to_install: "{{ packages_to_install | default([]) + rpm_info.stdout_lines | map('regex_findall', 'package (.+) is not installed$') | flatten }}" when: rpm_info.failed -- name: "Install packages: {{ packages_to_install }}" +- name: "Install packages: {{ packages_to_install | join(',') }}" become: yes ansible.builtin.yum: name: "{{ packages_to_install }}" diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index d350f6f..1d16c27 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -32,10 +32,26 @@ notify: - restart keycloak +- name: "Configure quarkus config for keycloak service" + ansible.builtin.template: + src: quarkus.properties.j2 + dest: "{{ keycloak.home }}/conf/quarkus.properties" + owner: "{{ keycloak.service_user }}" + group: "{{ keycloak.service_group }}" + mode: 0644 + notify: + - restart keycloak + - name: "Start and wait for keycloak service" ansible.builtin.include_tasks: start.yml - name: Check service status ansible.builtin.command: "systemctl status keycloak" register: keycloak_service_status - changed_when: False \ No newline at end of file + changed_when: False + +- name: Link default logs directory + ansible.builtin.file: + state: link + src: "{{ keycloak.home }}/{{ keycloak.log_file }}" + dest: /var/log/keycloak diff --git a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 index 13a589e..b02de03 100644 --- a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 +++ b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 @@ -1,3 +1,3 @@ # {{ ansible_managed }} KEYCLOAK_ADMIN={{ keycloak_quarkus_admin_user }} -KEYCLOAK_ADMIN_PASSWORD='{{ keycloak_quarkus_admin_pass }}' \ No newline at end of file +KEYCLOAK_ADMIN_PASSWORD='{{ keycloak_quarkus_admin_pass }}' diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index 59d82a2..4d19073 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -1,29 +1,27 @@ # {{ ansible_managed }} +{% if keycloak_quarkus_db_enabled %} # Database -# Database vendor [dev-file, dev-mem, mariadb, mssql, mysql, oracle, postgres] -#db=postgres -# The username of the database user. -#db-username=keycloak -# The password of the database user. -#db-password=password -# The full database JDBC URL. If not provided, a default URL is set based on the selected database vendor. -#db-url=jdbc:postgresql://localhost/keycloak +db={{ keycloak_quarkus_jdbc_engine }} +db-url={{ keycloak_quarkus_jdbc_url }} +db-username={{ keycloak_quarkus_db_user }} +db-password={{ keycloak_quarkus_db_pass }} +{% endif %} # Observability -# If the server should expose metrics and healthcheck endpoints. -#metrics-enabled=true +metrics-enabled={{ keycloak_quarkus_metrics_enabled }} +health-enabled={{ keycloak_quarkus_health_enabled }} # HTTP -http-enabled=true -http-port=8080 -https-port=8443 -# The file path to a server certificate or certificate chain in PEM format. -#https-certificate-file=${kc.home.dir}conf/server.crt.pem -# The file path to a private key in PEM format. -#https-certificate-key-file=${kc.home.dir}conf/server.key.pem -# The proxy address forwarding mode if the server is behind a reverse proxy. -#proxy=reencrypt +http-enabled={{ keycloak_quarkus_http_enabled }} +http-port={{ keycloak_quarkus_http_port }} + +# HTTPS +https-port={{ keycloak_quarkus_https_port }} +{% if keycloak_quarkus_https_enabled %} +https-certificate-file={{ keycloak.home }}/{{ keycloak_quarkus_cert_file}} +https-certificate-key-file={{ keycloak.home }}/{{ keycloak_quarkus_key_file }} +{% endif %} # Do not attach route to cookies and rely on the session affinity capabilities from reverse proxy #spi-sticky-session-encoder-infinispan-should-attach-route=false @@ -32,12 +30,11 @@ hostname={{ keycloak_quarkus_host }} hostname-path={{ keycloak_quarkus_http_relative_path }} # Cluster -#cache=ispn -#Defines the cache mechanism for high-availability. [local, ispn] -#cache-config-file=conf/cache-ispn.xml -#Defines the file from which cache configuration should be loaded from. -#cache-stack=tcp -#Define the default stack to use for cluster communication and node discovery. [tcp, udp, kubernetes, ec2, azure, google] +{% if keycloak_quarkus_ha_enabled %} +cache=ispn +cache-config-file=conf/cache-ispn.xml +cache-stack=tcp +{% endif %} # Proxy # The proxy address forwarding mode if the server is behind a reverse proxy. [edge, reencrypt, passthrough] @@ -46,6 +43,7 @@ hostname-path={{ keycloak_quarkus_http_relative_path }} # Logging # The format of log entries. #log-format=%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n -# The log level of the root category or a comma-separated list of individual categories and their levels. -#log-level=info - +log=file +log-level={{ keycloak.log.level }} +log-file={{ keycloak.log.file }} +log-file-format={{ keycloak.log.format }} diff --git a/roles/keycloak_quarkus/templates/keycloak.service.j2 b/roles/keycloak_quarkus/templates/keycloak.service.j2 index a710ee2..fcfb633 100644 --- a/roles/keycloak_quarkus/templates/keycloak.service.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.service.j2 @@ -7,7 +7,7 @@ After=network.target Type=simple EnvironmentFile=-/etc/sysconfig/keycloak PIDFile={{ keycloak_quarkus_service_pidfile }} -ExecStart={{ keycloak.home }}/bin/kc.sh start +ExecStart={{ keycloak.home }}/bin/kc.sh --auto-build start #--http-relative-path={{ keycloak_quarkus_http_relative_path }} [Install] diff --git a/roles/keycloak_quarkus/templates/quarkus.properties.j2 b/roles/keycloak_quarkus/templates/quarkus.properties.j2 new file mode 100644 index 0000000..cf133a3 --- /dev/null +++ b/roles/keycloak_quarkus/templates/quarkus.properties.j2 @@ -0,0 +1,19 @@ +# {{ ansible_managed }} +{% if keycloak_quarkus_ha_enabled %} +quarkus.infinispan-client.server-list={{ keycloak_quarkus_ispn_url }} +quarkus.infinispan-client.client-intelligence=HASH_DISTRIBUTION_AWARE +quarkus.infinispan-client.use-auth=true +quarkus.infinispan-client.auth-username={{ keycloak_quarkus_ispn_user }} +quarkus.infinispan-client.auth-password={{ keycloak_quarkus_ispn_pass }} +quarkus.infinispan-client.auth-realm=default +quarkus.infinispan-client.auth-server-name=infinispan +quarkus.infinispan-client.sasl-mechanism={{ keycloak_quarkus_ispn_sasl_mechanism }} +{% if keycloak_quarkus_ispn_use_ssl %} +quarkus.infinispan-client.trust-store={{ keycloak_quarkus_ispn_trust_store_path }} +quarkus.infinispan-client.trust-store-password={{ keycloak_quarkus_ispn_trust_store_password }} +quarkus.infinispan-client.trust-store-type=jks +{% endif %} +#quarkus.infinispan-client.use-schema-registration=true +#quarkus.infinispan-client.auth-client-subject +#quarkus.infinispan-client.auth-callback-handler +{% endif %} \ No newline at end of file diff --git a/roles/keycloak_quarkus/vars/main.yml b/roles/keycloak_quarkus/vars/main.yml index bca7d88..e5302f4 100644 --- a/roles/keycloak_quarkus/vars/main.yml +++ b/roles/keycloak_quarkus/vars/main.yml @@ -8,4 +8,8 @@ keycloak: cli_path: "{{ keycloak_quarkus_home }}/bin/kcadm.sh" service_user: "{{ keycloak_quarkus_service_user }}" service_group: "{{ keycloak_quarkus_service_group }}" - offline_install: "{{ keycloak_quarkus_offline_install }}" \ No newline at end of file + offline_install: "{{ keycloak_quarkus_offline_install }}" + log: + file: "{{ keycloak_quarkus_log_file }}" + level: "{{ keycloak_quarkus_log_level }}" + format: "{{ keycloak_quarkus_log_format }}" \ No newline at end of file From 0ddbc66448808a6aeb586b4fc0baad3e2cc21eba Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 17 May 2022 19:07:53 +0200 Subject: [PATCH 071/554] Add keycloak X playbook, update roles README --- playbooks/keyclock_quarkus.yml | 9 ++++++++ roles/keycloak_quarkus/README.md | 22 ++++++++++++++++--- .../templates/keycloak.service.j2 | 3 +-- roles/keycloak_realm/README.md | 3 ++- 4 files changed, 31 insertions(+), 6 deletions(-) create mode 100644 playbooks/keyclock_quarkus.yml diff --git a/playbooks/keyclock_quarkus.yml b/playbooks/keyclock_quarkus.yml new file mode 100644 index 0000000..ebed89b --- /dev/null +++ b/playbooks/keyclock_quarkus.yml @@ -0,0 +1,9 @@ +--- +- name: Playbook for Keycloak X Hosts + hosts: all + vars: + keycloak_admin_password: "remembertochangeme" + collections: + - middleware_automation.keycloak + roles: + - keycloak_quarkus \ No newline at end of file diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 19237d5..0bf4560 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -7,6 +7,13 @@ Install [keycloak](https://keycloak.org/) >= 17.0.0 (quarkus) server configurati Role Defaults ------------- +* Installation options + +| Variable | Description | Default | +|:---------|:------------|:--------| +|`keycloak_quarkus_version`| keycloak.org package version | `17.0.1` | + + * Service configuration | Variable | Description | Default | @@ -27,6 +34,10 @@ Role Defaults |`keycloak_quarkus_jvm_package`| RHEL java package runtime | `java-11-openjdk-headless` | |`keycloak_quarkus_frontend_url`| Service public URL | `http://localhost:8080/auth` | |`keycloak_quarkus_http_relative_path` | Service context path | `auth` | +|`keycloak_quarkus_http_enabled`| Enable listener on HTTP port | `True` | +|`keycloak_quarkus_https_enabled`| Enable listener on HTTPS port | `False` | +|`keycloak_quarkus_key_file`| The file path to a private key in PEM format | `conf/server.key.pem` | +|`keycloak_quarkus_cert_file`| The file path to a server certificate or certificate chain in PEM format | `conf/server.crt.pem` | * Database configuration @@ -70,6 +81,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| |`keycloak_quarkus_metrics_enabled`| Whether to enable metrics | `False` | +|`keycloak_quarkus_health_enabled`| If the server should expose health check endpoints | `True` | |`keycloak_quarkus_archive` | keycloak install archive filename | `keycloak-{{ keycloak_quarkus_version }}.zip` | |`keycloak_quarkus_installdir` | Installation path | `{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}` | |`keycloak_quarkus_home` | Installation work directory | `{{ keycloak_quarkus_installdir }}` | @@ -79,14 +91,18 @@ Role Defaults |`keycloak_force_install` | Remove pre-existing versions of service | `False` | |`keycloak_url` | URL for configuration rest calls | `http://{{ keycloak_quarkus_host }}:{{ keycloak_http_port }}` | |`keycloak_management_url` | URL for management console rest calls | `http://{{ keycloak_quarkus_host }}:{{ keycloak_management_http_port }}` | +|`keycloak_quarkus_log`| Enable one or more log handlers in a comma-separated list | `file` | +|`keycloak_quarkus_log_level`| The log level of the root category or a comma-separated list of individual categories and their levels | `info` | +|`keycloak_quarkus_log_file`| Set the log file path and filename relative to keycloak home | `data/log/keycloak.log` | +|`keycloak_quarkus_log_format`| Set a format specific to file log entries | `%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n` | Role Variables -------------- -| Variable | Description | -|:---------|:------------| -|`keycloak_quarkus_admin_pass`| Password of console admin account | +| Variable | Description | Required | +|:---------|:------------|----------| +|`keycloak_quarkus_admin_pass`| Password of console admin account | `yes` | License diff --git a/roles/keycloak_quarkus/templates/keycloak.service.j2 b/roles/keycloak_quarkus/templates/keycloak.service.j2 index fcfb633..6b0bb1d 100644 --- a/roles/keycloak_quarkus/templates/keycloak.service.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.service.j2 @@ -7,8 +7,7 @@ After=network.target Type=simple EnvironmentFile=-/etc/sysconfig/keycloak PIDFile={{ keycloak_quarkus_service_pidfile }} -ExecStart={{ keycloak.home }}/bin/kc.sh --auto-build start -#--http-relative-path={{ keycloak_quarkus_http_relative_path }} +ExecStart={{ keycloak.home }}/bin/kc.sh start --auto-build [Install] WantedBy=multi-user.target diff --git a/roles/keycloak_realm/README.md b/roles/keycloak_realm/README.md index cf098a7..91e6b8f 100644 --- a/roles/keycloak_realm/README.md +++ b/roles/keycloak_realm/README.md @@ -8,9 +8,10 @@ Role Defaults ------------- | Variable | Description | Default | -|:---------|:------------|:---------| +|:---------|:------------|:--------| |`keycloak_admin_user`| Administration console user account | `admin` | |`keycloak_host`| hostname | `localhost` | +|`keycloak_context`| Context path for rest calls | `/auth` | |`keycloak_http_port`| HTTP port | `8080` | |`keycloak_https_port`| TLS HTTP port | `8443` | |`keycloak_auth_realm`| Name of the main authentication realm | `master` | From 8bede6791e61da0ee828b8b2deadc062129ab1ab Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 18 May 2022 09:29:28 +0200 Subject: [PATCH 072/554] update 18.0.0, add JAVA_HOME check, runas systemd unit --- roles/keycloak_quarkus/README.md | 3 ++- roles/keycloak_quarkus/defaults/main.yml | 6 +++++- roles/keycloak_quarkus/meta/argument_specs.yml | 3 +++ roles/keycloak_quarkus/tasks/main.yml | 4 ++-- roles/keycloak_quarkus/tasks/systemd.yml | 11 +++++++++++ .../keycloak_quarkus/templates/keycloak-sysconfig.j2 | 1 + roles/keycloak_quarkus/templates/keycloak.conf.j2 | 10 ++++------ roles/keycloak_quarkus/templates/keycloak.service.j2 | 3 ++- 8 files changed, 30 insertions(+), 11 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 0bf4560..b977dcd 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -27,11 +27,12 @@ Role Defaults |`keycloak_quarkus_https_port`| TLS HTTP port | `8443` | |`keycloak_quarkus_ajp_port`| AJP port | `8009` | |`keycloak_quarkus_jgroups_port`| jgroups cluster tcp port | `7600` | -|`keycloak_quarkus_java_opts`| Additional JVM options | `-Xms1024m -Xmx2048m` | |`keycloak_quarkus_service_user`| Posix account username | `keycloak` | |`keycloak_quarkus_service_group`| Posix account group | `keycloak` | |`keycloak_quarkus_service_pidfile`| Pid file path for service | `/run/keycloak.pid` | |`keycloak_quarkus_jvm_package`| RHEL java package runtime | `java-11-openjdk-headless` | +|`keycloak_quarkus_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_quarkus_jvm_package RPM path | `None` | +|`keycloak_quarkus_java_opts`| Additional JVM options | `-Xms1024m -Xmx2048m` | |`keycloak_quarkus_frontend_url`| Service public URL | `http://localhost:8080/auth` | |`keycloak_quarkus_http_relative_path` | Service context path | `auth` | |`keycloak_quarkus_http_enabled`| Enable listener on HTTP port | `True` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index f8cefdd..7d58fe3 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -1,6 +1,6 @@ --- ### Configuration specific to keycloak -keycloak_quarkus_version: 17.0.1 +keycloak_quarkus_version: 18.0.0 keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip" keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" @@ -10,6 +10,7 @@ keycloak_quarkus_offline_install: False ### Install location and service settings keycloak_quarkus_jvm_package: java-11-openjdk-headless +keycloak_quarkus_java_home: keycloak_quarkus_dest: /opt/keycloak keycloak_quarkus_home: "{{ keycloak_quarkus_installdir }}" keycloak_quarkus_config_dir: "{{ keycloak_quarkus_home }}/conf" @@ -47,6 +48,9 @@ keycloak_quarkus_db_enabled: "{{ True if keycloak_quarkus_ha_enabled else False keycloak_quarkus_http_relative_path: auth keycloak_quarkus_frontend_url: http://localhost:8080/auth +# proxy address forwarding mode if the server is behind a reverse proxy. [edge, reencrypt, passthrough] +keycloak_quarkus_proxy_mode: edge + keycloak_quarkus_metrics_enabled: False keycloak_quarkus_health_enabled: True diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index b10f83a..0b2d5bf 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -31,6 +31,9 @@ argument_specs: default: "java-11-openjdk-headless" description: "RHEL java package runtime" type: "str" + keycloak_quarkus_java_home: + description: "JAVA_HOME of installed JRE, leave empty for using specified keycloak_jvm_package RPM path" + type: "str" keycloak_quarkus_dest: # line 13 of defaults/main.yml default: "/opt/keycloak" diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index 1d16c27..0ed3ece 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -1,6 +1,5 @@ --- # tasks file for keycloak - - name: Check prerequisites ansible.builtin.include_tasks: prereqs.yml tags: @@ -53,5 +52,6 @@ - name: Link default logs directory ansible.builtin.file: state: link - src: "{{ keycloak.home }}/{{ keycloak.log_file }}" + src: "{{ keycloak.home }}/{{ keycloak.log.file }}" dest: /var/log/keycloak + force: yes diff --git a/roles/keycloak_quarkus/tasks/systemd.yml b/roles/keycloak_quarkus/tasks/systemd.yml index 578802c..ee8a1cc 100644 --- a/roles/keycloak_quarkus/tasks/systemd.yml +++ b/roles/keycloak_quarkus/tasks/systemd.yml @@ -1,4 +1,13 @@ --- +- name: Determine JAVA_HOME for selected JVM RPM # noqa blocked_modules + ansible.builtin.shell: | + set -o pipefail + rpm -ql {{ keycloak_quarkus_jvm_package }} | grep -Po '/usr/lib/jvm/.*(?=/bin/java$)' + args: + executable: /bin/bash + changed_when: False + register: rpm_java_home + - name: "Configure sysconfig file for keycloak service" become: yes ansible.builtin.template: @@ -7,6 +16,8 @@ owner: root group: root mode: 0644 + vars: + keycloak_rpm_java_home: "{{ rpm_java_home.stdout }}" notify: - restart keycloak diff --git a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 index b02de03..5315708 100644 --- a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 +++ b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 @@ -1,3 +1,4 @@ # {{ ansible_managed }} KEYCLOAK_ADMIN={{ keycloak_quarkus_admin_user }} KEYCLOAK_ADMIN_PASSWORD='{{ keycloak_quarkus_admin_pass }}' +JAVA_HOME={{ keycloak_java_home | default(keycloak_rpm_java_home, true) }} diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index 4d19073..63fcae1 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -22,8 +22,6 @@ https-port={{ keycloak_quarkus_https_port }} https-certificate-file={{ keycloak.home }}/{{ keycloak_quarkus_cert_file}} https-certificate-key-file={{ keycloak.home }}/{{ keycloak_quarkus_key_file }} {% endif %} -# Do not attach route to cookies and rely on the session affinity capabilities from reverse proxy -#spi-sticky-session-encoder-infinispan-should-attach-route=false # Hostname for the Keycloak server. hostname={{ keycloak_quarkus_host }} @@ -37,13 +35,13 @@ cache-stack=tcp {% endif %} # Proxy -# The proxy address forwarding mode if the server is behind a reverse proxy. [edge, reencrypt, passthrough] -#proxy= +proxy={{ keycloak_quarkus_proxy_mode }} +# Do not attach route to cookies and rely on the session affinity capabilities from reverse proxy +#spi-sticky-session-encoder-infinispan-should-attach-route=false # Logging -# The format of log entries. #log-format=%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n -log=file +log={{ keycloak_quarkus_log }} log-level={{ keycloak.log.level }} log-file={{ keycloak.log.file }} log-file-format={{ keycloak.log.format }} diff --git a/roles/keycloak_quarkus/templates/keycloak.service.j2 b/roles/keycloak_quarkus/templates/keycloak.service.j2 index 6b0bb1d..90242cf 100644 --- a/roles/keycloak_quarkus/templates/keycloak.service.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.service.j2 @@ -7,7 +7,8 @@ After=network.target Type=simple EnvironmentFile=-/etc/sysconfig/keycloak PIDFile={{ keycloak_quarkus_service_pidfile }} -ExecStart={{ keycloak.home }}/bin/kc.sh start --auto-build +ExecStart={{ keycloak.home }}/bin/kc.sh start --auto-build --log={{ keycloak_quarkus_log }} +User={{ keycloak.service_user }} [Install] WantedBy=multi-user.target From 281767f505bcb6875cb2daa179e62892529b0003 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 18 May 2022 10:05:34 +0200 Subject: [PATCH 073/554] add missing variable spec --- roles/keycloak_quarkus/README.md | 1 + roles/keycloak_quarkus/meta/argument_specs.yml | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index b977dcd..ed4fae3 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -96,6 +96,7 @@ Role Defaults |`keycloak_quarkus_log_level`| The log level of the root category or a comma-separated list of individual categories and their levels | `info` | |`keycloak_quarkus_log_file`| Set the log file path and filename relative to keycloak home | `data/log/keycloak.log` | |`keycloak_quarkus_log_format`| Set a format specific to file log entries | `%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n` | +|`keycloak_quarkus_proxy_mode`| The proxy address forwarding mode if the server is behind a reverse proxy | `edge` | Role Variables diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 0b2d5bf..19fb8df 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -240,3 +240,7 @@ argument_specs: default: '%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n' type: "str" description: "Set a format specific to file log entries" + keycloak_quarkus_proxy_mode: + default: 'edge' + type: "str" + description: "The proxy address forwarding mode if the server is behind a reverse proxy" From 09a34567a726491e97399d6d86bdb1f9cbf82302 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 19 May 2022 09:38:47 +0200 Subject: [PATCH 074/554] Bump to 1.0.5, add EE setup ref --- bindep.txt | 7 +++++++ galaxy.yml | 2 +- meta/execution-environment.yml | 11 +++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 bindep.txt create mode 100644 meta/execution-environment.yml diff --git a/bindep.txt b/bindep.txt new file mode 100644 index 0000000..641ec85 --- /dev/null +++ b/bindep.txt @@ -0,0 +1,7 @@ +python39-devel [platform:rpm compile] +git-lfs [platform:rpm] +python3-netaddr [platform:rpm] +python3-lxml [platform:rpm] +python3-jmespath [platform:rpm] +python3-requests [platform:rpm] + diff --git a/galaxy.yml b/galaxy.yml index 40279e4..86b2775 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.0.4" +version: "1.0.5" readme: README.md authors: - Romain Pelisse diff --git a/meta/execution-environment.yml b/meta/execution-environment.yml new file mode 100644 index 0000000..dba85a8 --- /dev/null +++ b/meta/execution-environment.yml @@ -0,0 +1,11 @@ +--- +version: 1 +build_arg_defaults: + EE_BASE_IMAGE: 'quay.io/ansible/ansible-runner:stable-2.12-devel' +dependencies: + galaxy: requirements.yml + python: requirements.txt + system: bindep.txt +additional_build_steps: + append: + - RUN alternatives --set python /usr/bin/python3 From d5a63f55f9d8251867a43843ac8f3a7d406da614 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 25 May 2022 15:37:36 +0000 Subject: [PATCH 075/554] Update changelog for release 1.0.5 --- CHANGELOG.rst | 8 ++++++++ changelogs/changelog.yaml | 9 +++++++++ 2 files changed, 17 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index c0aca3c..5a2c59c 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,14 @@ middleware_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v1.0.5 +====== + +Minor Changes +------------- + +- Update config options: keycloak and quarkus `#32 `_ + v1.0.4 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index f43e0d7..2388c2f 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -60,3 +60,12 @@ releases: release_date: '2022-05-09' 1.0.4: release_date: '2022-05-11' + 1.0.5: + changes: + minor_changes: + - 'Update config options: keycloak and quarkus `#32 `_ + + ' + fragments: + - 32.yaml + release_date: '2022-05-25' From 8454f5c341785395baf6f7bb37b9e55ebde1ba1f Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 31 May 2022 10:43:55 +0200 Subject: [PATCH 076/554] keycloak_quarkus: add selected java to PATH in systemd unit (#34) --- .ansible-lint | 1 + docs/testing.md | 1 - molecule/quarkus/prepare.yml | 4 ---- playbooks/{keyclock_quarkus.yml => keycloak_quarkus.yml} | 0 roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 | 1 + 5 files changed, 2 insertions(+), 5 deletions(-) rename playbooks/{keyclock_quarkus.yml => keycloak_quarkus.yml} (100%) diff --git a/.ansible-lint b/.ansible-lint index 5472a97..ea3a6db 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -5,6 +5,7 @@ exclude_paths: - molecule/ - .ansible-lint - .yamllint + - meta/ rulesdir: - ../../ansible-lint-custom-rules/rules/ diff --git a/docs/testing.md b/docs/testing.md index 7a700c0..1d06d7f 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -46,4 +46,3 @@ EOF # run the playbook ansible-playbook -i inventory playbooks/keycloak.yml ``` - diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index 03433c0..bda79cf 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -2,10 +2,6 @@ - name: Prepare hosts: all tasks: - - name: Disable beta repos - ansible.builtin.command: yum config-manager --disable '*beta*' - ignore_errors: yes - - name: Install sudo ansible.builtin.yum: name: sudo diff --git a/playbooks/keyclock_quarkus.yml b/playbooks/keycloak_quarkus.yml similarity index 100% rename from playbooks/keyclock_quarkus.yml rename to playbooks/keycloak_quarkus.yml diff --git a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 index 5315708..a3fdf57 100644 --- a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 +++ b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 @@ -1,4 +1,5 @@ # {{ ansible_managed }} KEYCLOAK_ADMIN={{ keycloak_quarkus_admin_user }} KEYCLOAK_ADMIN_PASSWORD='{{ keycloak_quarkus_admin_pass }}' +PATH={{ keycloak_java_home | default(keycloak_rpm_java_home, true) }}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin JAVA_HOME={{ keycloak_java_home | default(keycloak_rpm_java_home, true) }} From 469036e9e71d2cb50f7d87512eb699cdc4054240 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 31 May 2022 10:47:29 +0200 Subject: [PATCH 077/554] keycloak_quarkus: set logfile path correctly under keycloak home (#35) --- roles/keycloak_quarkus/vars/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/vars/main.yml b/roles/keycloak_quarkus/vars/main.yml index e5302f4..abd6413 100644 --- a/roles/keycloak_quarkus/vars/main.yml +++ b/roles/keycloak_quarkus/vars/main.yml @@ -10,6 +10,6 @@ keycloak: service_group: "{{ keycloak_quarkus_service_group }}" offline_install: "{{ keycloak_quarkus_offline_install }}" log: - file: "{{ keycloak_quarkus_log_file }}" + file: "{{ keycloak_quarkus_home }}/{{ keycloak_quarkus_log_file }}" level: "{{ keycloak_quarkus_log_level }}" format: "{{ keycloak_quarkus_log_format }}" \ No newline at end of file From 76cbb4c676c037abe3a59a307afc39221510024f Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 31 May 2022 19:07:18 +0200 Subject: [PATCH 078/554] keycloak_quarkus: add https to molecule test setup (#36) * keycloak_quarkus: add https to molecule test setup * move converge pre_tasks to prepare phase * Update zipfile unarchive to cater for existing certs --- .gitignore | 1 + molecule/default/prepare.yml | 4 ---- molecule/quarkus/converge.yml | 6 ++++++ molecule/quarkus/molecule.yml | 4 +++- molecule/quarkus/prepare.yml | 18 ++++++++++++++++++ molecule/quarkus/verify.yml | 16 ++++++++++++++++ playbooks/keycloak_quarkus.yml | 8 +++++++- roles/keycloak_quarkus/tasks/install.yml | 10 +++++----- roles/keycloak_quarkus/tasks/main.yml | 10 +++++++++- 9 files changed, 65 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index ef79fe9..9cc2eb2 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ docs/_build/ .mypy_cache/ *.retry changelogs/.plugin-cache.yaml +*.pem diff --git a/molecule/default/prepare.yml b/molecule/default/prepare.yml index 8137cfd..40923c9 100644 --- a/molecule/default/prepare.yml +++ b/molecule/default/prepare.yml @@ -2,10 +2,6 @@ - name: Prepare hosts: all tasks: - - name: Disable beta repos - ansible.builtin.command: yum config-manager --disable '*beta*' - ignore_errors: yes - - name: Install sudo ansible.builtin.yum: name: diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index 1f77fe5..fd40a44 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -5,6 +5,12 @@ keycloak_quarkus_admin_pass: "remembertochangeme" keycloak_admin_password: "remembertochangeme" keycloak_realm: TestRealm + keycloak_quarkus_host: instance:8443 + keycloak_quarkus_http_relative_path: '' + keycloak_quarkus_log: file + keycloak_quarkus_https_enabled: True + keycloak_quarkus_key_file: conf/key.pem + keycloak_quarkus_cert_file: conf/cert.pem roles: - role: keycloak_quarkus - role: keycloak_realm diff --git a/molecule/quarkus/molecule.yml b/molecule/quarkus/molecule.yml index ea8ad61..785de19 100644 --- a/molecule/quarkus/molecule.yml +++ b/molecule/quarkus/molecule.yml @@ -16,7 +16,9 @@ platforms: port_bindings: - "8080/tcp" - "8443/tcp" - - "8009/tcp" + - "8009/tcp" + published_ports: + - 0.0.0.0:8443:8443/tcp provisioner: name: ansible config_options: diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index bda79cf..7d95f2f 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -6,3 +6,21 @@ ansible.builtin.yum: name: sudo state: present + - command: openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes -subj '/CN=instance' + delegate_to: localhost + - lineinfile: + dest: /etc/hosts + line: "127.0.0.1 instance" + state: present + delegate_to: localhost + become: yes + - file: + state: directory + path: /opt/keycloak/keycloak-18.0.0/conf/ + - copy: + src: "{{ item }}" + dest: "/opt/keycloak/keycloak-18.0.0/conf/{{ item }}" + mode: 0444 + loop: + - cert.pem + - key.pem diff --git a/molecule/quarkus/verify.yml b/molecule/quarkus/verify.yml index ef973cd..9b469a4 100644 --- a/molecule/quarkus/verify.yml +++ b/molecule/quarkus/verify.yml @@ -9,3 +9,19 @@ that: - ansible_facts.services["keycloak.service"]["state"] == "running" - ansible_facts.services["keycloak.service"]["status"] == "enabled" + - name: Fetch openID config + shell: | + curl https://instance:8443/realms/master/.well-known/openid-configuration -k | jq . + delegate_to: localhost + register: openid_config + - debug: + msg: " {{ openid_config.stdout | from_json }}" + delegate_to: localhost + - name: Verify endpoint URLs + assert: + that: + - (openid_config.stdout | from_json)["backchannel_authentication_endpoint"] == 'https://instance:8443/realms/master/protocol/openid-connect/ext/ciba/auth' + - (openid_config.stdout | from_json)['issuer'] == 'https://instance:8443/realms/master' + - (openid_config.stdout | from_json)['authorization_endpoint'] == 'https://instance:8443/realms/master/protocol/openid-connect/auth' + - (openid_config.stdout | from_json)['token_endpoint'] == 'https://instance:8443/realms/master/protocol/openid-connect/token' + delegate_to: localhost diff --git a/playbooks/keycloak_quarkus.yml b/playbooks/keycloak_quarkus.yml index ebed89b..b9bbbba 100644 --- a/playbooks/keycloak_quarkus.yml +++ b/playbooks/keycloak_quarkus.yml @@ -3,7 +3,13 @@ hosts: all vars: keycloak_admin_password: "remembertochangeme" + keycloak_quarkus_host: localhost:8443 + keycloak_quarkus_http_relative_path: '' + keycloak_quarkus_log: file + keycloak_quarkus_https_enabled: True + keycloak_quarkus_key_file: conf/key.pem + keycloak_quarkus_cert_file: conf/cert.pem collections: - middleware_automation.keycloak roles: - - keycloak_quarkus \ No newline at end of file + - keycloak_quarkus diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index ba6ec40..b1ea1ee 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -84,9 +84,9 @@ - local_archive_path.stat.exists become: yes -- name: "Check target directory: {{ keycloak.home }}" +- name: "Check target directory: {{ keycloak.home }}/bin/" ansible.builtin.stat: - path: "{{ keycloak.home }}" + path: "{{ keycloak.home }}/bin/" register: path_to_workdir become: yes @@ -95,12 +95,12 @@ remote_src: yes src: "{{ archive }}" dest: "{{ keycloak_quarkus_dest }}" - creates: "{{ keycloak.home }}" + creates: "{{ keycloak.home }}/bin/" owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" become: yes when: - - new_version_downloaded.changed or not path_to_workdir.stat.exists + - (not path_to_workdir.stat.exists) or new_version_downloaded.changed notify: - restart keycloak @@ -108,4 +108,4 @@ ansible.builtin.debug: msg: "{{ keycloak.home }} already exists and version unchanged, skipping decompression" when: - - not new_version_downloaded.changed and path_to_workdir.stat.exists + - (not new_version_downloaded.changed) and path_to_workdir.stat.exists diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index 0ed3ece..cf855a2 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -41,6 +41,14 @@ notify: - restart keycloak +- name: Ensure logdirectory exists + ansible.builtin.file: + state: directory + path: "{{ keycloak.home }}/{{ keycloak.log.file | dirname }}" + owner: "{{ keycloak.service_user }}" + group: "{{ keycloak.service_group }}" + mode: 0775 + - name: "Start and wait for keycloak service" ansible.builtin.include_tasks: start.yml @@ -52,6 +60,6 @@ - name: Link default logs directory ansible.builtin.file: state: link - src: "{{ keycloak.home }}/{{ keycloak.log.file }}" + src: "{{ keycloak.home }}/{{ keycloak.log.file | dirname }}" dest: /var/log/keycloak force: yes From 46f445560bf06957cf077edec2bd346f97ced0b5 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 31 May 2022 19:10:20 +0200 Subject: [PATCH 079/554] Bump to 1.0.6 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 86b2775..b56c1a6 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.0.5" +version: "1.0.6" readme: README.md authors: - Romain Pelisse From 713437343dc78f389c695f721816c9baf7df10b1 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 1 Jun 2022 13:12:11 +0000 Subject: [PATCH 080/554] Update changelog for release 1.0.6 --- CHANGELOG.rst | 9 +++++++++ changelogs/changelog.yaml | 13 +++++++++++++ 2 files changed, 22 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 5a2c59c..53b39b9 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,15 @@ middleware_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v1.0.6 +====== + +Bugfixes +-------- + +- keycloak_quarkus: add selected java to PATH in systemd unit `#34 `_ +- keycloak_quarkus: set logfile path correctly under keycloak home `#35 `_ + v1.0.5 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 2388c2f..aeb76f5 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -69,3 +69,16 @@ releases: fragments: - 32.yaml release_date: '2022-05-25' + 1.0.6: + changes: + bugfixes: + - 'keycloak_quarkus: add selected java to PATH in systemd unit `#34 `_ + + ' + - 'keycloak_quarkus: set logfile path correctly under keycloak home `#35 `_ + + ' + fragments: + - 34.yaml + - 35.yaml + release_date: '2022-06-01' From 065fb53eb281cf2305d2cc015882bee96a314e7b Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 1 Jun 2022 17:33:19 +0200 Subject: [PATCH 081/554] Bump to 1.0.7 --- .ansible-lint | 1 + galaxy.yml | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.ansible-lint b/.ansible-lint index ea3a6db..f777db8 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -6,6 +6,7 @@ exclude_paths: - .ansible-lint - .yamllint - meta/ + - playbooks/roles/ rulesdir: - ../../ansible-lint-custom-rules/rules/ diff --git a/galaxy.yml b/galaxy.yml index b56c1a6..6a9e648 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.0.6" +version: "1.0.7" readme: README.md authors: - Romain Pelisse @@ -32,3 +32,4 @@ build_ignore: - .github - '*.tar.gz' - '*.zip' + - changelogs/fragments/.gitignore From 4baa61e0cfe678d6c285d6ae9f6c2025274a816a Mon Sep 17 00:00:00 2001 From: Xabier Davila Date: Thu, 30 Jun 2022 16:15:48 +0200 Subject: [PATCH 082/554] Use sudo for tasks that will otherwise fail --- roles/keycloak_quarkus/tasks/main.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index cf855a2..738b55e 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -28,6 +28,7 @@ owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" mode: 0644 + become: yes notify: - restart keycloak @@ -38,6 +39,7 @@ owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" mode: 0644 + become: yes notify: - restart keycloak @@ -48,6 +50,7 @@ owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" mode: 0775 + become: yes - name: "Start and wait for keycloak service" ansible.builtin.include_tasks: start.yml @@ -63,3 +66,4 @@ src: "{{ keycloak.home }}/{{ keycloak.log.file | dirname }}" dest: /var/log/keycloak force: yes + become: yes From 41caa49cfcb1114be8ae36ab004b273cd8ecc006 Mon Sep 17 00:00:00 2001 From: Xabier Davila Date: Thu, 30 Jun 2022 16:22:58 +0200 Subject: [PATCH 083/554] Use absolute path for certificate files --- roles/keycloak_quarkus/README.md | 4 ++-- roles/keycloak_quarkus/defaults/main.yml | 4 ++-- roles/keycloak_quarkus/meta/argument_specs.yml | 4 ++-- roles/keycloak_quarkus/templates/keycloak.conf.j2 | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index ed4fae3..769e2f7 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -37,8 +37,8 @@ Role Defaults |`keycloak_quarkus_http_relative_path` | Service context path | `auth` | |`keycloak_quarkus_http_enabled`| Enable listener on HTTP port | `True` | |`keycloak_quarkus_https_enabled`| Enable listener on HTTPS port | `False` | -|`keycloak_quarkus_key_file`| The file path to a private key in PEM format | `conf/server.key.pem` | -|`keycloak_quarkus_cert_file`| The file path to a server certificate or certificate chain in PEM format | `conf/server.crt.pem` | +|`keycloak_quarkus_key_file`| The file path to a private key in PEM format | `{{ keycloak.home }}/conf/server.key.pem` | +|`keycloak_quarkus_cert_file`| The file path to a server certificate or certificate chain in PEM format | `{{ keycloak.home }}/conf/server.crt.pem` | * Database configuration diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 7d58fe3..a54a8ec 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -36,8 +36,8 @@ keycloak_quarkus_java_opts: "-Xms1024m -Xmx2048m" ### TLS/HTTPS configuration keycloak_quarkus_https_enabled: False -keycloak_quarkus_key_file: conf/server.key.pem -keycloak_quarkus_cert_file: conf/server.crt.pem +keycloak_quarkus_key_file: "{{ keycloak.home }}/conf/server.key.pem" +keycloak_quarkus_cert_file: "{{ keycloak.home }}/conf/server.crt.pem" ### Enable configuration for database backend, clustering and remote caches on infinispan keycloak_quarkus_ha_enabled: False diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 19fb8df..a0214a5 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -108,11 +108,11 @@ argument_specs: description: "Enable listener on HTTPS port" type: "bool" keycloak_quarkus_key_file: - default: "conf/server.key.pem" + default: "{{ keycloak.home }}/conf/server.key.pem" description: "The file path to a private key in PEM format" type: "str" keycloak_quarkus_cert_file: - default: "conf/server.crt.pem" + default: "{{ keycloak.home }}/conf/server.crt.pem" description: "The file path to a server certificate or certificate chain in PEM format" type: "str" keycloak_quarkus_https_port: diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index 63fcae1..c02dbae 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -19,8 +19,8 @@ http-port={{ keycloak_quarkus_http_port }} # HTTPS https-port={{ keycloak_quarkus_https_port }} {% if keycloak_quarkus_https_enabled %} -https-certificate-file={{ keycloak.home }}/{{ keycloak_quarkus_cert_file}} -https-certificate-key-file={{ keycloak.home }}/{{ keycloak_quarkus_key_file }} +https-certificate-file={{ keycloak_quarkus_cert_file}} +https-certificate-key-file={{ keycloak_quarkus_key_file }} {% endif %} # Hostname for the Keycloak server. From adb0a4da45643b39cd52d33af6f810553e844e9e Mon Sep 17 00:00:00 2001 From: Xabier Davila Date: Mon, 4 Jul 2022 08:31:10 +0200 Subject: [PATCH 084/554] Fix molecule tests --- molecule/quarkus/converge.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index fd40a44..cb84edb 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -9,8 +9,8 @@ keycloak_quarkus_http_relative_path: '' keycloak_quarkus_log: file keycloak_quarkus_https_enabled: True - keycloak_quarkus_key_file: conf/key.pem - keycloak_quarkus_cert_file: conf/cert.pem + keycloak_quarkus_key_file: "{{ keycloak.home }}/conf/key.pem" + keycloak_quarkus_cert_file: "{{ keycloak.home }}/conf/cert.pem" roles: - role: keycloak_quarkus - role: keycloak_realm From 1b1127ed9188d03e2b620eaf65739e393592e422 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 6 Jul 2022 12:10:08 +0000 Subject: [PATCH 085/554] Update changelog for release 1.0.7 --- CHANGELOG.rst | 13 +++++++++++++ changelogs/changelog.yaml | 14 ++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 53b39b9..f67ba17 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,19 @@ middleware_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v1.0.7 +====== + +Breaking Changes / Porting Guide +-------------------------------- + +- keycloak_quarkus: use absolute path for certificate files `#39 `_ + +Bugfixes +-------- + +- keycloak_quarkus: use become for tasks that will otherwise fail `#38 `_ + v1.0.6 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index aeb76f5..bde3179 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -82,3 +82,17 @@ releases: - 34.yaml - 35.yaml release_date: '2022-06-01' + 1.0.7: + changes: + breaking_changes: + - 'keycloak_quarkus: use absolute path for certificate files `#39 `_ + + ' + bugfixes: + - 'keycloak_quarkus: use become for tasks that will otherwise fail `#38 `_ + + ' + fragments: + - 38.yaml + - 39.yaml + release_date: '2022-07-06' From ded44b084d30f712a46704d8368dc09d08a090c0 Mon Sep 17 00:00:00 2001 From: Romain Pelisse Date: Tue, 2 Aug 2022 20:22:35 +0200 Subject: [PATCH 086/554] quarkus scenario skip part if hera is used --- molecule/quarkus/prepare.yml | 30 +++++++++++++++++++-------- molecule/quarkus/verify.yml | 40 +++++++++++++++++++++--------------- 2 files changed, 45 insertions(+), 25 deletions(-) diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index 7d95f2f..f54dbb8 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -6,18 +6,30 @@ ansible.builtin.yum: name: sudo state: present - - command: openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes -subj '/CN=instance' + + - name: "Display hera_home if defined." + ansible.builtin.set_fact: + hera_home: "{{ lookup('env', 'HERA_HOME') }}" + + - ansible.builtin.command: openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes -subj '/CN=instance' delegate_to: localhost - - lineinfile: - dest: /etc/hosts - line: "127.0.0.1 instance" - state: present - delegate_to: localhost - become: yes - - file: + + - block: + - ansible.builtin.lineinfile: + dest: /etc/hosts + line: "127.0.0.1 instance" + state: present + delegate_to: localhost + become: yes + when: + - hera_home is defined + - hera_home | length == 0 + + - ansible.builtin.file: state: directory path: /opt/keycloak/keycloak-18.0.0/conf/ - - copy: + + - ansible.builtin.copy: src: "{{ item }}" dest: "/opt/keycloak/keycloak-18.0.0/conf/{{ item }}" mode: 0444 diff --git a/molecule/quarkus/verify.yml b/molecule/quarkus/verify.yml index 9b469a4..8d86585 100644 --- a/molecule/quarkus/verify.yml +++ b/molecule/quarkus/verify.yml @@ -9,19 +9,27 @@ that: - ansible_facts.services["keycloak.service"]["state"] == "running" - ansible_facts.services["keycloak.service"]["status"] == "enabled" - - name: Fetch openID config - shell: | - curl https://instance:8443/realms/master/.well-known/openid-configuration -k | jq . - delegate_to: localhost - register: openid_config - - debug: - msg: " {{ openid_config.stdout | from_json }}" - delegate_to: localhost - - name: Verify endpoint URLs - assert: - that: - - (openid_config.stdout | from_json)["backchannel_authentication_endpoint"] == 'https://instance:8443/realms/master/protocol/openid-connect/ext/ciba/auth' - - (openid_config.stdout | from_json)['issuer'] == 'https://instance:8443/realms/master' - - (openid_config.stdout | from_json)['authorization_endpoint'] == 'https://instance:8443/realms/master/protocol/openid-connect/auth' - - (openid_config.stdout | from_json)['token_endpoint'] == 'https://instance:8443/realms/master/protocol/openid-connect/token' - delegate_to: localhost + + - set_fact: + hera_home: "{{ lookup('env', 'HERA_HOME') }}" + + - block: + - name: Fetch openID config + shell: | + curl https://instance:8443/realms/master/.well-known/openid-configuration -k | jq . + delegate_to: localhost + register: openid_config + - debug: + msg: " {{ openid_config.stdout | from_json }}" + delegate_to: localhost + - name: Verify endpoint URLs + assert: + that: + - (openid_config.stdout | from_json)["backchannel_authentication_endpoint"] == 'https://instance:8443/realms/master/protocol/openid-connect/ext/ciba/auth' + - (openid_config.stdout | from_json)['issuer'] == 'https://instance:8443/realms/master' + - (openid_config.stdout | from_json)['authorization_endpoint'] == 'https://instance:8443/realms/master/protocol/openid-connect/auth' + - (openid_config.stdout | from_json)['token_endpoint'] == 'https://instance:8443/realms/master/protocol/openid-connect/token' + delegate_to: localhost + when: + - hera_home is defined + - hera_home | length == 0 From 9b2ea35184f8f39e95bd5db38f36a578d622ce54 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 19 Sep 2022 15:41:12 +0200 Subject: [PATCH 087/554] ci: linter, workflows, galaxy, molecule --- .ansible-lint | 4 ++++ .github/workflows/ci.yml | 16 +++++++++++----- .github/workflows/docs.yml | 3 ++- galaxy.yml | 11 +++++++++-- molecule/default/prepare.yml | 10 ++++++++++ molecule/overridexml/prepare.yml | 13 +++++-------- molecule/prepare.yml | 28 ++++++++++++++++++++++++++++ 7 files changed, 69 insertions(+), 16 deletions(-) create mode 100644 molecule/prepare.yml diff --git a/.ansible-lint b/.ansible-lint index f777db8..f9251eb 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -23,9 +23,13 @@ warn_list: - no-handler - fqcn-builtins - no-log-password + - jinja[spacing] + - jinja[invalid] + - meta-no-tags skip_list: - vars_should_not_be_used + - file_is_small_enough use_default_rules: true parseable: true diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7c96b1d..85da941 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,11 +1,16 @@ --- name: CI -"on": +on: push: branches: - main pull_request: +env: + COLORTERM: 'yes' + TERM: 'xterm-256color' + PYTEST_ADDOPTS: '--color=yes' + jobs: ci: runs-on: ubuntu-latest @@ -29,16 +34,17 @@ jobs: pip install yamllint 'molecule[docker]~=3.5.2' ansible-core flake8 ansible-lint voluptuous pip install -r ansible_collections/middleware_automation/keycloak/requirements.txt + - name: Create default collection path + run: | + mkdir -p /home/runner/.ansible/ + ln -s /home/runner/work/keycloak/keycloak /home/runner/.ansible/collections + - name: Install ansible-lint custom rules uses: actions/checkout@v2 with: repository: ansible-middleware/ansible-lint-custom-rules path: ansible_collections/ansible-lint-custom-rules/ - - name: Create default collection path - run: | - mkdir -p /home/runner/.ansible/collections/ansible_collections - - name: Run sanity tests run: ansible-test sanity --docker -v --color --python ${{ matrix.python_version }} --exclude changelogs/fragments/.gitignore working-directory: ./ansible_collections/middleware_automation/keycloak diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 7345971..7163a00 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -45,7 +45,8 @@ jobs: - name: Create default collection path run: | - mkdir -p /home/runner/.ansible/collections/ansible_collections + mkdir -p /home/runner/.ansible/ + ln -s /home/runner/work/keycloak/keycloak /home/runner/.ansible/collections - name: Create changelog and documentation uses: ansible-middleware/collection-docs-action@main diff --git a/galaxy.yml b/galaxy.yml index 6a9e648..e3c6bfb 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -28,8 +28,15 @@ documentation: https://ansible-middleware.github.io/keycloak homepage: https://github.com/ansible-middleware/keycloak issues: https://github.com/ansible-middleware/keycloak/issues build_ignore: - - molecule + - .gitignore - .github + - .ansible-lint + - .yamllint - '*.tar.gz' - '*.zip' - - changelogs/fragments/.gitignore + - molecule + - changelogs + - docs/_gh_include + - docs/conf.py + - docs/roles.rst.template + - docs/requirements.yml diff --git a/molecule/default/prepare.yml b/molecule/default/prepare.yml index 40923c9..1d78e2d 100644 --- a/molecule/default/prepare.yml +++ b/molecule/default/prepare.yml @@ -8,3 +8,13 @@ - sudo - java-1.8.0-openjdk state: present + +- name: Prepare + hosts: all + tasks: + - name: "Run preparation common to all scenario" + ansible.builtin.include_tasks: ../prepare.yml + vars: + assets: + - "{{ assets_server }}/sso/7.5.0/rh-sso-7.5.0-server-dist.zip" + - "{{ assets_server }}/sso/7.5.1/rh-sso-7.5.1-patch.zip" diff --git a/molecule/overridexml/prepare.yml b/molecule/overridexml/prepare.yml index 03433c0..3fc1104 100644 --- a/molecule/overridexml/prepare.yml +++ b/molecule/overridexml/prepare.yml @@ -2,11 +2,8 @@ - name: Prepare hosts: all tasks: - - name: Disable beta repos - ansible.builtin.command: yum config-manager --disable '*beta*' - ignore_errors: yes - - - name: Install sudo - ansible.builtin.yum: - name: sudo - state: present + - name: "Run preparation common to all scenario" + ansible.builtin.include_tasks: ../prepare.yml + vars: + assets: + - "{{ assets_server }}/sso/7.5.0/rh-sso-7.5.0-server-dist.zip" diff --git a/molecule/prepare.yml b/molecule/prepare.yml new file mode 100644 index 0000000..c457571 --- /dev/null +++ b/molecule/prepare.yml @@ -0,0 +1,28 @@ +--- +- name: Display Ansible version + ansible.builtin.debug: + msg: "Ansible version is {{ ansible_version.full }}" + +- name: Install sudo + ansible.builtin.yum: + name: + - sudo + - iproute + state: present + +- name: "Retrieve assets server from env" + ansible.builtin.set_fact: + assets_server: "{{ lookup('env','MIDDLEWARE_DOWNLOAD_RELEASE_SERVER_URL') }}" + +- name: "Download and deploy jws zips from {{ assets_server }}" + ansible.builtin.get_url: + url: "{{ asset }}" + dest: "{{ lookup('env', 'PWD') }}" + validate_certs: no + delegate_to: localhost + loop: "{{ assets }}" + loop_control: + loop_var: asset + when: + - assets_server is defined + - assets_server | length > 0 From 38b5a02e9575de66d7309f3bdb51a8647560d901 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 19 Sep 2022 15:42:01 +0200 Subject: [PATCH 088/554] Rename infinispan_ vars to keycloak_infinispan_, prepare downstrea --- roles/keycloak/README.md | 14 ++-- roles/keycloak/defaults/main.yml | 28 ++------ roles/keycloak/meta/argument_specs.yml | 96 +++++++++++++------------- roles/keycloak/vars/main.yml | 20 +++--- 4 files changed, 73 insertions(+), 85 deletions(-) diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index 71787b1..1693a66 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -126,13 +126,13 @@ The following variables are _required_ only when `keycloak_ha_enabled` is True: |:---------|:------------|:---------| |`keycloak_modcluster_url` | URL for the modcluster reverse proxy | `localhost` | |`keycloak_jdbc_engine` | backend database engine when db is enabled: [ postgres, mariadb ] | `postgres` | -|`infinispan_url` | URL for the infinispan remote-cache server | `localhost:11122` | -|`infinispan_user` | username for connecting to infinispan | `supervisor` | -|`infinispan_pass` | password for connecting to infinispan | `supervisor` | -|`infinispan_sasl_mechanism`| Authentication type | `SCRAM-SHA-512` | -|`infinispan_use_ssl`| Enable hotrod TLS communication | `False` | -|`infinispan_trust_store_path`| Path to truststore with infinispan server certificate | `/etc/pki/java/cacerts` | -|`infinispan_trust_store_password`| Password for opening truststore | `changeit` | +|`keycloak_infinispan_url` | URL for the infinispan remote-cache server | `localhost:11122` | +|`keycloak_infinispan_user` | username for connecting to infinispan | `supervisor` | +|`keycloak_infinispan_pass` | password for connecting to infinispan | `supervisor` | +|`keycloak_infinispan_sasl_mechanism`| Authentication type | `SCRAM-SHA-512` | +|`keycloak_infinispan_use_ssl`| Enable hotrod TLS communication | `False` | +|`keycloak_infinispan_trust_store_path`| Path to truststore with infinispan server certificate | `/etc/pki/java/cacerts` | +|`keycloak_infinispan_trust_store_password`| Password for opening truststore | `changeit` | The following variables are _required_ only when `keycloak_db_enabled` is True: diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 7ef632a..ba3413c 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -6,20 +6,6 @@ keycloak_download_url: "https://github.com/keycloak/keycloak/releases/download/{ keycloak_download_url_9x: "https://downloads.jboss.org/keycloak/{{ keycloak_version }}/{{ keycloak_archive }}" keycloak_installdir: "{{ keycloak_dest }}/keycloak-{{ keycloak_version }}" -### Configuration specific to Red Hat Single Sign-On -keycloak_rhsso_version: 7.5.0 -rhsso_rhn_id: "{{ rhsso_rhn_ids[keycloak_rhsso_version].id }}" -keycloak_rhsso_archive: "rh-sso-{{ keycloak_rhsso_version }}-server-dist.zip" -keycloak_rhsso_installdir: "{{ keycloak_dest }}/rh-sso-{{ keycloak_rhsso_version | regex_replace('^([0-9])\\.([0-9]*).*', '\\1.\\2') }}" -keycloak_rhn_url: 'https://access.redhat.com/jbossnetwork/restricted/softwareDownload.html?softwareId=' -keycloak_rhsso_download_url: "{{ keycloak_rhn_url }}{{ rhsso_rhn_id }}" -keycloak_rhsso_apply_patches: False - -### keycloak/rhsso choice: by default install rhsso if rhn credentials are defined -keycloak_rhsso_enable: "{{ True if rhsso_rhn_id is defined and rhn_username is defined and rhn_password is defined else False }}" -# whether to install from local archive; filename must be keycloak_archive or keycloak_rhsso_archive depending on keycloak_rhsso_enable -keycloak_offline_install: False - ### Install location and service settings keycloak_jvm_package: java-1.8.0-openjdk-headless keycloak_java_home: @@ -68,14 +54,14 @@ keycloak_modcluster_url: localhost keycloak_frontend_url: http://localhost:8080/auth ### infinispan remote caches access (hotrod) -infinispan_user: supervisor -infinispan_pass: supervisor -infinispan_url: localhost -infinispan_sasl_mechanism: SCRAM-SHA-512 -infinispan_use_ssl: False +keycloak_infinispan_user: supervisor +keycloak_infinispan_pass: supervisor +keycloak_infinispan_url: localhost +keycloak_infinispan_sasl_mechanism: SCRAM-SHA-512 +keycloak_infinispan_use_ssl: False # if ssl is enabled, import ispn server certificate here -infinispan_trust_store_path: /etc/pki/java/cacerts -infinispan_trust_store_password: changeit +keycloak_infinispan_trust_store_path: /etc/pki/java/cacerts +keycloak_infinispan_trust_store_password: changeit ### database backend engine: values [ 'postgres', 'mariadb' ] keycloak_jdbc_engine: postgres diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 983d59d..39c047a 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -31,46 +31,6 @@ argument_specs: default: "{{ keycloak_dest }}/keycloak-{{ keycloak_version }}" description: "Installation path" type: "str" - keycloak_rhsso_version: - # line 10 of keycloak/defaults/main.yml - default: "7.5.0" - description: "Red Hat Single Sign-On version" - type: "str" - rhsso_rhn_id: - # line 11 of keycloak/defaults/main.yml - default: "{{ rhsso_rhn_ids[keycloak_rhsso_version].id }}" - description: "Customer Portal product ID for Red Hat SSO" - type: "str" - keycloak_rhsso_archive: - # line 12 of keycloak/defaults/main.yml - default: "rh-sso-{{ keycloak_rhsso_version }}-server-dist.zip" - description: "ed Hat SSO install archive filename" - type: "str" - keycloak_rhsso_apply_patches: - # line 16 of keycloak/defaults/main.yml - default: false - description: "Install RHSSO more recent cumulative patch" - type: "bool" - keycloak_rhsso_installdir: - # line 13 of keycloak/defaults/main.yml - default: "{{ keycloak_dest }}/rh-sso-{{ keycloak_rhsso_version | regex_replace('^([0-9])\\.([0-9]*).*', '\\1.\\2') }}" - description: "Installation path for Red Hat SSO" - type: "str" - keycloak_rhn_url: - # line 14 of keycloak/defaults/main.yml - default: "https://access.redhat.com/jbossnetwork/restricted/softwareDownload.html?softwareId=" - description: "Base download URI for customer portal" - type: "str" - keycloak_rhsso_download_url: - # line 15 of keycloak/defaults/main.yml - default: "{{ keycloak_rhn_url }}{{ rhsso_rhn_id }}" - description: "Full download URI for Red Hat SSO" - type: "str" - keycloak_rhsso_enable: - # line 18 of keycloak/defaults/main.yml - default: "{{ True if rhsso_rhn_id is defined and rhn_username is defined and rhn_password is defined else False }}" - description: "Enable Red Hat Single Sign-on installation" - type: "str" keycloak_offline_install: # line 20 of keycloak/defaults/main.yml default: false @@ -219,37 +179,37 @@ argument_specs: default: "http://localhost" description: "Frontend URL for keycloak endpoints when a reverse proxy is used" type: "str" - infinispan_user: + keycloak_infinispan_user: # line 62 of keycloak/defaults/main.yml default: "supervisor" description: "Username for connecting to infinispan" type: "str" - infinispan_pass: + keycloak_infinispan_pass: # line 63 of keycloak/defaults/main.yml default: "supervisor" description: "Password for connecting to infinispan" type: "str" - infinispan_url: + keycloak_infinispan_url: # line 64 of keycloak/defaults/main.yml default: "localhost" description: "URL for the infinispan remote-cache server" type: "str" - infinispan_sasl_mechanism: + keycloak_infinispan_sasl_mechanism: # line 65 of keycloak/defaults/main.yml default: "SCRAM-SHA-512" description: "Authentication type to infinispan server" type: "str" - infinispan_use_ssl: + keycloak_infinispan_use_ssl: # line 66 of keycloak/defaults/main.yml default: false description: "Enable hotrod client TLS communication" type: "bool" - infinispan_trust_store_path: + keycloak_infinispan_trust_store_path: # line 68 of keycloak/defaults/main.yml default: "/etc/pki/java/cacerts" description: "TODO document argument" type: "str" - infinispan_trust_store_password: + keycloak_infinispan_trust_store_password: # line 69 of keycloak/defaults/main.yml default: "changeit" description: "Path to truststore containing infinispan server certificate" @@ -294,3 +254,45 @@ argument_specs: default: "http://{{ keycloak_host }}:{{ keycloak_management_http_port }}" description: "URL for management console rest calls" type: "str" + downstream: + options: + sso_version: + default: "7.5.0" + description: "Red Hat Single Sign-On version" + type: "str" + sso_rhn_id: + default: "{{ sso_rhn_ids[keycloak_version].id }}" + description: "Customer Portal product ID for Red Hat SSO" + type: "str" + sso_archive: + default: "rh-sso-{{ keycloak_version }}-server-dist.zip" + description: "Red Hat SSO install archive filename" + type: "str" + sso_dest: + default: "/opt/sso" + description: "Root installation directory" + type: "str" + sso_installdir: + default: "{{ keycloak_dest }}/rh-sso-{{ keycloak_version | regex_replace('^([0-9])\\.([0-9]*).*', '\\1.\\2') }}" + description: "Installation path for Red Hat SSO" + type: "str" + sso_rhn_url: + default: 'https://access.redhat.com/jbossnetwork/restricted/softwareDownload.html?softwareId=' + description: "Base download URI for customer portal" + type: "str" + sso_download_url: + default: "{{ sso_rhn_url }}{{ sso_rhn_id }}" + description: "Full download URI for Red Hat SSO" + type: "str" + sso_apply_patches: + default: False + description: "Install Red Hat SSO most recent cumulative patch" + type: "bool" + sso_enable: + default: True + description: "Enable Red Hat Single Sign-on installation" + type: "str" + sso_offline_install: + default: True + description: "Perform an offline install" + type: "bool" diff --git a/roles/keycloak/vars/main.yml b/roles/keycloak/vars/main.yml index 5a6b059..76d2b58 100644 --- a/roles/keycloak/vars/main.yml +++ b/roles/keycloak/vars/main.yml @@ -1,6 +1,6 @@ --- # internal variables below -rhsso_rhn_ids: +sso_rhn_ids: '7.5.0': # noqa vars_in_vars_files_have_valid_names id: '101971' latest_cp: @@ -15,8 +15,8 @@ keycloak_management_url: "http://{{ keycloak_host }}:{{ keycloak_management_http keycloak: home: "{{ keycloak_jboss_home }}" config_dir: "{{ keycloak_config_dir }}" - bundle: "{{ keycloak_rhsso_archive if keycloak_rhsso_enable else keycloak_archive }}" - patch_bundle: "rh-sso-{{ rhsso_rhn_ids[keycloak_rhsso_version].latest_cp.v }}-patch.zip" + bundle: "{{ keycloak_archive }}" + patch_bundle: "rh-sso-{{ sso_rhn_ids[keycloak_version].latest_cp.v }}-patch.zip" service_name: "{{ 'rhsso' if keycloak_rhsso_enable else 'keycloak' }}" health_url: "{{ keycloak_management_url }}/health" cli_path: "{{ keycloak_jboss_home }}/bin/jboss-cli.sh" @@ -73,11 +73,11 @@ keycloak_modcluster: # infinispan keycloak_remotecache: enabled: "{{ keycloak_ha_enabled }}" - username: "{{ infinispan_user }}" - password: "{{ infinispan_pass }}" + username: "{{ keycloak_infinispan_user }}" + password: "{{ keycloak_infinispan_pass }}" realm: default - sasl_mechanism: "{{ infinispan_sasl_mechanism }}" - server_name: "{{ infinispan_url }}" - use_ssl: "{{ infinispan_use_ssl }}" - trust_store_path: "{{ infinispan_trust_store_path }}" - trust_store_password: "{{ infinispan_trust_store_password }}" \ No newline at end of file + sasl_mechanism: "{{ keycloak_infinispan_sasl_mechanism }}" + server_name: "{{ keycloak_infinispan_url }}" + use_ssl: "{{ keycloak_infinispan_use_ssl }}" + trust_store_path: "{{ keycloak_infinispan_trust_store_path }}" + trust_store_password: "{{ keycloak_infinispan_trust_store_password }}" \ No newline at end of file From 5e891398705eb53550423aa4cce46515c0db8cd5 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 19 Sep 2022 16:02:55 +0200 Subject: [PATCH 089/554] Downstream variables --- README.md | 26 +------ playbooks/rhsso.yml | 2 +- roles/keycloak/README.md | 74 +------------------- roles/keycloak/defaults/main.yml | 6 +- roles/keycloak/meta/argument_specs.yml | 22 +++++- roles/keycloak/tasks/install.yml | 12 ++-- roles/keycloak/tasks/main.yml | 4 +- roles/keycloak/tasks/prereqs.yml | 6 +- roles/keycloak/tasks/rhsso_patch.yml | 18 ++--- roles/keycloak/vars/main.yml | 3 +- roles/keycloak_quarkus/tasks/prereqs.yml | 9 --- roles/keycloak_realm/README.md | 1 - roles/keycloak_realm/defaults/main.yml | 1 - roles/keycloak_realm/meta/argument_specs.yml | 27 +++++-- 14 files changed, 73 insertions(+), 138 deletions(-) diff --git a/README.md b/README.md index d341f58..75775d7 100644 --- a/README.md +++ b/README.md @@ -59,28 +59,6 @@ Both playbooks include the `keycloak` role, with different settings, as describe For full service configuration details, refer to the [keycloak role README](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak/README.md). -### Choosing between upstream project (Keycloak) and Red Hat Single Sign-On (RHSSO) - -The general flag `keycloak_rhsso_enable` controls what to install between upstream (Keycloak, when `False`) or Red Hat Single Sign-On (when `True`). -The default value for the flag if `True` when Red Hat Network credentials are defined, `False` otherwise. - - -#### Install upstream (Keycloak) from keycloak releases - -This is the default approach when RHN credentials are not defined. Keycloak is downloaded from keycloak builds (hosted on github.com) locally, and distributed to target nodes. - - -#### Install RHSSO from the Red Hat Customer Support Portal - -Define the credentials as follows, and the default behaviour is to download a fresh archive of RHSSO on the controller node, then distribute to target nodes. - -```yaml -rhn_username: '' -rhn_password: '' -# (keycloak_rhsso_enable defaults to True) -``` - - #### Install from controller node (local source) Making the keycloak zip archive (or the RHSSO zip archive), available to the playbook repository root directory, and setting `keycloak_offline_install` to `True`, allows to skip @@ -101,14 +79,12 @@ And depending on `keycloak_rhsso_enable`: For RHSSO: ```yaml -keycloak_rhsso_enable: True -keycloak_rhsso_download_url: "https://///rh-sso-x.y.z-server-dist.zip" +sso_download_url: "https://///rh-sso-x.y.z-server-dist.zip" ``` For keycloak: ```yaml -keycloak_rhsso_enable: False keycloak_download_url: "https://///keycloak-x.y.zip" ``` diff --git a/playbooks/rhsso.yml b/playbooks/rhsso.yml index ba30a74..e34334f 100644 --- a/playbooks/rhsso.yml +++ b/playbooks/rhsso.yml @@ -3,7 +3,7 @@ hosts: keycloak vars: keycloak_admin_password: "remembertochangeme" - keycloak_rhsso_enable: True + sso_enable: True collections: - middleware_automation.redhat_csp_download - middleware_automation.keycloak diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index 1693a66..0f3d198 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -74,16 +74,11 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:---------| -|`keycloak_rhsso_enable`| Enable Red Hat Single Sign-on installation | `False` | |`keycloak_offline_install` | perform an offline install | `False`| |`keycloak_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| -|`keycloak_rhsso_download_url`| Download URL for RHSSO | `https://access.redhat.com/jbossnetwork/restricted/softwareDownload.html?softwareId=`| |`keycloak_version`| keycloak.org package version | `15.0.2` | -|`keycloak_rhsso_version`| RHSSO version | `7.5.0` | -|`keycloak_rhsso_apply_patches`| Install RHSSO more recent cumulative patch | `False` | |`keycloak_dest`| Installation root path | `/opt/keycloak` | |`keycloak_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_version }}/{{ keycloak_archive }}` | -|`keycloak_rhn_url` | Base download URI for customer portal | `https://access.redhat.com/jbossnetwork/restricted/softwareDownload.html?softwareId=` | |`keycloak_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` | @@ -94,9 +89,6 @@ Role Defaults |`keycloak_archive` | keycloak install archive filename | `keycloak-{{ keycloak_version }}.zip` | |`keycloak_download_url_9x` | Download URL for keycloak (deprecated) | `https://downloads.jboss.org/keycloak/{{ keycloak_version }}/{{ keycloak_archive }}` | |`keycloak_installdir` | Installation path | `{{ keycloak_dest }}/keycloak-{{ keycloak_version }}` | -|`keycloak_rhsso_archive` | Red Hat SSO install archive filename | `rh-sso-{{ keycloak_rhsso_version }}-server-dist.zip` | -|`keycloak_rhsso_installdir`| Installation path for Red Hat SSO | `{{ keycloak_dest }}/rh-sso-{{ keycloak_rhsso_version | regex_replace('^([0-9])\.([0-9]*).*', '\1.\2') }}` | -|`keycloak_rhsso_download_url`| Full download URI for Red Hat SSO | `{{ keycloak_rhn_url }}{{ rhsso_rhn_id }}` | |`keycloak_jboss_home` | Installation work directory | `{{ keycloak_rhsso_installdir if keycloak_rhsso_enable else keycloak_installdir }}` | |`keycloak_config_dir` | Path for configuration | `{{ keycloak_jboss_home }}/standalone/configuration` | |`keycloak_config_path_to_standalone_xml` | Custom path for configuration | `{{ keycloak_jboss_home }}/standalone/configuration/{{ keycloak_config_standalone_xml }}` | @@ -106,7 +98,6 @@ Role Defaults |`keycloak_force_install` | Remove pre-existing versions of service | `False` | |`keycloak_url` | URL for configuration rest calls | `http://{{ keycloak_host }}:{{ keycloak_http_port }}` | |`keycloak_management_url` | URL for management console rest calls | `http://{{ keycloak_host }}:{{ keycloak_management_http_port }}` | -|`rhsso_rhn_id` | Customer Portal product ID for Red Hat SSO | `{{ rhsso_rhn_ids[keycloak_rhsso_version].id }}` | Role Variables @@ -145,12 +136,9 @@ The following variables are _required_ only when `keycloak_db_enabled` is True: |`keycloak_db_pass` | password for connecting to postgres | `keycloak-pass` | -Example Playbooks +Example Playbook ----------------- -_NOTE_: use ansible vaults or other security systems for storing credentials. - - * The following is an example playbook that makes use of the role to install keycloak from remote: ```yaml @@ -164,27 +152,6 @@ _NOTE_: use ansible vaults or other security systems for storing credentials. - middleware_automation.keycloak.keycloak ``` -* The following is an example playbook that makes use of the role to install Red Hat Single Sign-On from RHN: - -```yaml ---- -- name: Playbook for RHSSO - hosts: keycloak - collections: - - middleware_automation.redhat_csp_download - roles: - - redhat_csp_download - tasks: - - name: Keycloak Role - include_role: - name: keycloak - vars: - keycloak_admin_password: "remembertochangeme" - keycloak_rhsso_enable: True - rhn_username: '' - rhn_password: '' -``` - * The following example playbook makes use of the role to install keycloak from the controller node: @@ -203,45 +170,6 @@ _NOTE_: use ansible vaults or other security systems for storing credentials. # This should be the filename of keycloak archive on Ansible node: keycloak-16.1.0.zip ``` - -* This playbook installs Red Hat Single Sign-On from an alternate url: - -```yaml ---- -- hosts: keycloak - collections: - - middleware_automation.keycloak - tasks: - - name: Keycloak Role - include_role: - name: keycloak - vars: - keycloak_admin_password: "remembertochangeme" - keycloak_rhsso_enable: True - keycloak_rhsso_download_url: "" - # This should be the full of remote source rhsso zip file and can contain basic authentication credentials -``` - - -* The following is an example playbook that makes use of the role to install Red Hat Single Sign-On offline from the controller node, and apply latest cumulative patch: - -```yaml ---- -- hosts: keycloak - collections: - - middleware_automation.keycloak - tasks: - - name: Keycloak Role - include_role: - name: keycloak - vars: - keycloak_admin_password: "remembertochangeme" - keycloak_rhsso_enable: True - keycloak_offline_install: True - keycloak_rhsso_apply_patches: True - # This should be the filename of rhsso zip file on Ansible node: rh-sso-7.5-server-dist.zip -``` - License ------- diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index ba3413c..291ff37 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -5,12 +5,13 @@ keycloak_archive: "keycloak-{{ keycloak_version }}.zip" keycloak_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_version }}/{{ keycloak_archive }}" keycloak_download_url_9x: "https://downloads.jboss.org/keycloak/{{ keycloak_version }}/{{ keycloak_archive }}" keycloak_installdir: "{{ keycloak_dest }}/keycloak-{{ keycloak_version }}" +keycloak_offline_install: False ### Install location and service settings keycloak_jvm_package: java-1.8.0-openjdk-headless keycloak_java_home: keycloak_dest: /opt/keycloak -keycloak_jboss_home: "{{ keycloak_rhsso_installdir if keycloak_rhsso_enable else keycloak_installdir }}" +keycloak_jboss_home: "{{ keycloak_installdir }}" keycloak_config_dir: "{{ keycloak_jboss_home }}/standalone/configuration" keycloak_config_standalone_xml: "keycloak.xml" keycloak_config_path_to_standalone_xml: "{{ keycloak_jboss_home }}/standalone/configuration/{{ keycloak_config_standalone_xml }}" @@ -18,6 +19,9 @@ keycloak_config_override_template: '' keycloak_service_user: keycloak keycloak_service_group: keycloak keycloak_service_pidfile: "/run/keycloak.pid" +keycloak_service_name: keycloak +keycloak_service_desc: Keycloak + keycloak_configure_firewalld: False ### administrator console password diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 39c047a..f34b134 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -51,7 +51,7 @@ argument_specs: type: "str" keycloak_jboss_home: # line 25 of keycloak/defaults/main.yml - default: "{{ keycloak_rhsso_installdir if keycloak_rhsso_enable else keycloak_installdir }}" + default: "{{ keycloak_installdir }}" description: "Installation work directory" type: "str" keycloak_config_dir: @@ -254,6 +254,14 @@ argument_specs: default: "http://{{ keycloak_host }}:{{ keycloak_management_http_port }}" description: "URL for management console rest calls" type: "str" + keycloak_service_name: + default: "keycloak" + description: "systemd service name for keycloak" + type: "str" + keycloak_service_desc: + default: "Keycloak" + description: "systemd description for keycloak" + type: "str" downstream: options: sso_version: @@ -296,3 +304,15 @@ argument_specs: default: True description: "Perform an offline install" type: "bool" + sso_service_name: + default: "sso" + description: "systemd service name for Single Sign-On" + type: "str" + sso_service_desc: + default: "Red Hat Single Sign-On" + description: "systemd description for Red Hat Single Sign-On" + type: "str" + sso_patch_bundle: + default: "rh-sso-{{ sso_rhn_ids[keycloak_version].latest_cp.v }}-patch.zip" + description: "Red Hat SSO patch archive filename" + type: "str" diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index 26c5466..5f85274 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -81,7 +81,7 @@ - archive_path is defined - archive_path.stat is defined - not archive_path.stat.exists - - not keycloak_rhsso_enable + - not sso_enable is defined or not sso_enable - not keycloak_offline_install - name: Perform download from RHN @@ -96,9 +96,9 @@ - archive_path is defined - archive_path.stat is defined - not archive_path.stat.exists - - keycloak_rhsso_enable + - sso_enable is defined and sso_enable - not keycloak_offline_install - - keycloak_rhn_url in keycloak_rhsso_download_url + - keycloak_rhn_url in keycloak_download_url - name: Download rhsso archive from alternate location ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user @@ -110,9 +110,9 @@ - archive_path is defined - archive_path.stat is defined - not archive_path.stat.exists - - keycloak_rhsso_enable + - sso_enable is defined and sso_enable - not keycloak_offline_install - - not keycloak_rhn_url in keycloak_rhsso_download_url + - not keycloak_rhn_url in keycloak_download_url - name: Check downloaded archive ansible.builtin.stat: @@ -141,7 +141,7 @@ register: path_to_workdir become: yes -- name: "Extract {{ 'Red Hat Single Sign-On' if keycloak_rhsso_enable else 'Keycloak' }} archive on target" +- name: "Extract {{ keycloak_service_desc }} archive on target" ansible.builtin.unarchive: remote_src: yes src: "{{ archive }}" diff --git a/roles/keycloak/tasks/main.yml b/roles/keycloak/tasks/main.yml index ba5ec87..b89b401 100644 --- a/roles/keycloak/tasks/main.yml +++ b/roles/keycloak/tasks/main.yml @@ -24,7 +24,9 @@ - name: Include patch install tasks ansible.builtin.include_tasks: rhsso_patch.yml - when: keycloak_rhsso_apply_patches and keycloak_rhsso_enable + when: + - sso_apply_patches is defined and sso_apply_patches + - sso_enable is defined and sso_enable tags: - install - patch diff --git a/roles/keycloak/tasks/prereqs.yml b/roles/keycloak/tasks/prereqs.yml index 31735d5..c774c65 100644 --- a/roles/keycloak/tasks/prereqs.yml +++ b/roles/keycloak/tasks/prereqs.yml @@ -18,11 +18,11 @@ - name: Validate credentials ansible.builtin.assert: that: - - (rhn_username is defined and keycloak_rhsso_enable) or not keycloak_rhsso_enable or keycloak_offline_install - - (rhn_password is defined and keycloak_rhsso_enable) or not keycloak_rhsso_enable or keycloak_offline_install + - (rhn_username is defined and sso_enable is defined and sso_enable) or not sso_enable is defined or not sso_enable or keycloak_offline_install + - (rhn_password is defined and sso_enable is defined and sso_enable) or not sso_enable is defined or not sso_enable or keycloak_offline_install quiet: True fail_msg: "Cannot install Red Hat SSO without RHN credentials. Check rhn_username and rhn_password are defined" - success_msg: "{{ 'Installing Red Hat Single Sign-On' if keycloak_rhsso_enable else 'Installing keycloak.org' }}" + success_msg: "Installing {{ keycloak_service_desc }}" - name: Validate persistence configuration ansible.builtin.assert: diff --git a/roles/keycloak/tasks/rhsso_patch.yml b/roles/keycloak/tasks/rhsso_patch.yml index f517e7a..67739a4 100644 --- a/roles/keycloak/tasks/rhsso_patch.yml +++ b/roles/keycloak/tasks/rhsso_patch.yml @@ -2,7 +2,7 @@ ## check remote patch archive - name: Set download patch archive path ansible.builtin.set_fact: - patch_archive: "{{ keycloak_dest }}/{{ keycloak.patch_bundle }}" + patch_archive: "{{ keycloak_dest }}/{{ sso_patch_bundle }}" - name: Check download patch archive path ansible.builtin.stat: @@ -11,8 +11,8 @@ - name: Perform download from RHN middleware_automation.redhat_csp_download.redhat_csp_download: - url: "{{ keycloak_rhn_url }}{{ rhsso_rhn_ids[keycloak_rhsso_version].latest_cp.id }}" - dest: "{{ local_path.stat.path }}/{{ keycloak.patch_bundle }}" + url: "{{ keycloak_rhn_url }}{{ sso_rhn_ids[keycloak_version].latest_cp.id }}" + dest: "{{ local_path.stat.path }}/{{ sso_patch_bundle }}" username: "{{ rhn_username }}" password: "{{ rhn_password }}" no_log: "{{ omit_rhn_output | default(true) }}" @@ -21,13 +21,13 @@ - patch_archive_path is defined - patch_archive_path.stat is defined - not patch_archive_path.stat.exists - - keycloak_rhsso_enable + - sso_enable is defined and sso_enable - not keycloak_offline_install ## copy and unpack - name: Copy patch archive to target nodes ansible.builtin.copy: - src: "{{ local_path.stat.path }}/{{ keycloak.patch_bundle }}" + src: "{{ local_path.stat.path }}/{{ sso_patch_bundle }}" dest: "{{ patch_archive }}" owner: "{{ keycloak_service_user }}" group: "{{ keycloak_service_group }}" @@ -48,9 +48,9 @@ when: - cli_result is defined - cli_result.stdout is defined - - rhsso_rhn_ids[keycloak_rhsso_version].latest_cp.v not in cli_result.stdout + - sso_rhn_ids[keycloak_version].latest_cp.v not in cli_result.stdout block: - - name: "Apply patch {{ rhsso_rhn_ids[keycloak_rhsso_version].latest_cp.v }} to server" + - name: "Apply patch {{ sso_rhn_ids[keycloak_version].latest_cp.v }} to server" ansible.builtin.include_tasks: rhsso_cli.yml vars: query: "patch apply {{ patch_archive }}" @@ -78,10 +78,10 @@ - name: "Verify installed patch version" ansible.builtin.assert: that: - - rhsso_rhn_ids[keycloak_rhsso_version].latest_cp.v not in cli_result.stdout + - sso_rhn_ids[keycloak_version].latest_cp.v not in cli_result.stdout fail_msg: "Patch installation failed" success_msg: "Patch installation successful" - name: "Skipping patch" ansible.builtin.debug: - msg: "Latest cumulative patch {{ rhsso_rhn_ids[keycloak_rhsso_version].latest_cp.v }} already installed, skipping patch installation." + msg: "Latest cumulative patch {{ sso_rhn_ids[keycloak_version].latest_cp.v }} already installed, skipping patch installation." diff --git a/roles/keycloak/vars/main.yml b/roles/keycloak/vars/main.yml index 76d2b58..77f35ff 100644 --- a/roles/keycloak/vars/main.yml +++ b/roles/keycloak/vars/main.yml @@ -16,8 +16,7 @@ keycloak: home: "{{ keycloak_jboss_home }}" config_dir: "{{ keycloak_config_dir }}" bundle: "{{ keycloak_archive }}" - patch_bundle: "rh-sso-{{ sso_rhn_ids[keycloak_version].latest_cp.v }}-patch.zip" - service_name: "{{ 'rhsso' if keycloak_rhsso_enable else 'keycloak' }}" + service_name: "{{ keycloak_service_name }}" health_url: "{{ keycloak_management_url }}/health" cli_path: "{{ keycloak_jboss_home }}/bin/jboss-cli.sh" config_template_source: "{{ keycloak_config_override_template if keycloak_config_override_template | length > 0 else 'standalone.xml.j2' }}" diff --git a/roles/keycloak_quarkus/tasks/prereqs.yml b/roles/keycloak_quarkus/tasks/prereqs.yml index ea2b8f4..c0201b3 100644 --- a/roles/keycloak_quarkus/tasks/prereqs.yml +++ b/roles/keycloak_quarkus/tasks/prereqs.yml @@ -15,15 +15,6 @@ fail_msg: "Cannot install HA setup without a backend database service. Check keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled" success_msg: "{{ 'Configuring HA' if keycloak_quarkus_ha_enabled else 'Configuring standalone' }}" -# - name: Validate credentials -# ansible.builtin.assert: -# that: -# - (rhn_username is defined and keycloak_rhsso_enable) or not keycloak_rhsso_enable or keycloak_offline_install -# - (rhn_password is defined and keycloak_rhsso_enable) or not keycloak_rhsso_enable or keycloak_offline_install -# quiet: True -# fail_msg: "Cannot install Red Hat SSO without RHN credentials. Check rhn_username and rhn_password are defined" -# success_msg: "{{ 'Installing Red Hat Single Sign-On' if keycloak_rhsso_enable else 'Installing keycloak.org' }}" - - name: Ensure required packages are installed ansible.builtin.include_tasks: fastpackages.yml vars: diff --git a/roles/keycloak_realm/README.md b/roles/keycloak_realm/README.md index 91e6b8f..1a5709c 100644 --- a/roles/keycloak_realm/README.md +++ b/roles/keycloak_realm/README.md @@ -15,7 +15,6 @@ Role Defaults |`keycloak_http_port`| HTTP port | `8080` | |`keycloak_https_port`| TLS HTTP port | `8443` | |`keycloak_auth_realm`| Name of the main authentication realm | `master` | -|`keycloak_rhsso_enable`| Define service is an upstream(Keycloak) or RHSSO | `master` | |`keycloak_management_http_port`| Management port | `9990` | |`keycloak_auth_client`| Authentication client for configuration REST calls | `admin-cli` | |`keycloak_client_public`| Configure a public realm client | `True` | diff --git a/roles/keycloak_realm/defaults/main.yml b/roles/keycloak_realm/defaults/main.yml index 4975380..e1caeec 100644 --- a/roles/keycloak_realm/defaults/main.yml +++ b/roles/keycloak_realm/defaults/main.yml @@ -4,7 +4,6 @@ keycloak_host: localhost keycloak_http_port: 8080 keycloak_https_port: 8443 keycloak_management_http_port: 9990 -keycloak_rhsso_enable: False ### Keycloak administration console user keycloak_admin_user: admin diff --git a/roles/keycloak_realm/meta/argument_specs.yml b/roles/keycloak_realm/meta/argument_specs.yml index 45b5998..8f8e26e 100644 --- a/roles/keycloak_realm/meta/argument_specs.yml +++ b/roles/keycloak_realm/meta/argument_specs.yml @@ -26,11 +26,6 @@ argument_specs: default: 9990 description: "Management port" type: "int" - keycloak_rhsso_enable: - # line 7 of keycloak_realm/defaults/main.yml - default: false - description: "Enable Red Hat Single Sign-on" - type: "bool" keycloak_admin_user: # line 10 of keycloak_realm/defaults/main.yml default: "admin" @@ -96,3 +91,25 @@ argument_specs: default: "http://{{ keycloak_host }}:{{ keycloak_management_http_port }}" description: "URL for management console rest calls" type: "str" + downstream: + options: + sso_version: + default: "7.5.0" + description: "Red Hat Single Sign-On version" + type: "str" + sso_dest: + default: "/opt/sso" + description: "Root installation directory" + type: "str" + sso_installdir: + default: "{{ keycloak_dest }}/rh-sso-{{ keycloak_version | regex_replace('^([0-9])\\.([0-9]*).*', '\\1.\\2') }}" + description: "Installation path for Red Hat SSO" + type: "str" + sso_apply_patches: + default: False + description: "Install Red Hat SSO most recent cumulative patch" + type: "bool" + sso_enable: + default: True + description: "Enable Red Hat Single Sign-on installation" + type: "str" From 69a8860551e3298ebe213a2724964f6950a27e87 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 19 Sep 2022 22:07:23 +0200 Subject: [PATCH 090/554] Break dependency on wildfly/eap --- molecule/default/requirements.yml | 2 -- molecule/overridexml/requirements.yml | 2 -- molecule/quarkus/requirements.yml | 2 -- requirements.yml | 2 -- roles/keycloak/tasks/install.yml | 11 +----- roles/keycloak/tasks/jdbc_driver.yml | 36 +++++++++++++++++++ .../templates/jdbc_driver_module.xml.j2 | 10 ++++++ 7 files changed, 47 insertions(+), 18 deletions(-) create mode 100644 roles/keycloak/tasks/jdbc_driver.yml create mode 100644 roles/keycloak/templates/jdbc_driver_module.xml.j2 diff --git a/molecule/default/requirements.yml b/molecule/default/requirements.yml index 9aa3437..de3dc3e 100644 --- a/molecule/default/requirements.yml +++ b/molecule/default/requirements.yml @@ -2,8 +2,6 @@ collections: - name: middleware_automation.redhat_csp_download version: ">=1.2.1" - - name: middleware_automation.wildfly - version: ">=0.0.5" - name: community.general - name: community.docker version: ">=1.9.1" diff --git a/molecule/overridexml/requirements.yml b/molecule/overridexml/requirements.yml index 9aa3437..de3dc3e 100644 --- a/molecule/overridexml/requirements.yml +++ b/molecule/overridexml/requirements.yml @@ -2,8 +2,6 @@ collections: - name: middleware_automation.redhat_csp_download version: ">=1.2.1" - - name: middleware_automation.wildfly - version: ">=0.0.5" - name: community.general - name: community.docker version: ">=1.9.1" diff --git a/molecule/quarkus/requirements.yml b/molecule/quarkus/requirements.yml index 9aa3437..de3dc3e 100644 --- a/molecule/quarkus/requirements.yml +++ b/molecule/quarkus/requirements.yml @@ -2,8 +2,6 @@ collections: - name: middleware_automation.redhat_csp_download version: ">=1.2.1" - - name: middleware_automation.wildfly - version: ">=0.0.5" - name: community.general - name: community.docker version: ">=1.9.1" diff --git a/requirements.yml b/requirements.yml index ab434b2..1ae6626 100644 --- a/requirements.yml +++ b/requirements.yml @@ -2,6 +2,4 @@ collections: - name: middleware_automation.redhat_csp_download version: ">=1.2.1" - - name: middleware_automation.wildfly - version: ">=0.0.5" - name: community.general diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index 5f85274..af14c75 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -172,16 +172,7 @@ # driver and configuration - name: "Install {{ keycloak_jdbc_engine }} driver" - ansible.builtin.include_role: - name: middleware_automation.wildfly.wildfly_driver - vars: - wildfly_user: "{{ keycloak_service_user }}" - jdbc_driver_module_dir: "{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_dir }}" - jdbc_driver_version: "{{ keycloak_jdbc[keycloak_jdbc_engine].driver_version }}" - jdbc_driver_jar_filename: "{{ keycloak_jdbc[keycloak_jdbc_engine].driver_jar_filename }}" - jdbc_driver_jar_url: "{{ keycloak_jdbc[keycloak_jdbc_engine].driver_jar_url }}" - jdbc_driver_jar_installation_path: "{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_dir }}/{{ keycloak_jdbc[keycloak_jdbc_engine].driver_jar_filename }}" - jdbc_driver_module_name: "{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_name }}" + ansible.builtin.include_tasks: jdbc_driver.yml when: keycloak_jdbc[keycloak_jdbc_engine].enabled - name: "Deploy {{ keycloak.service_name }} config to {{ keycloak_config_path_to_standalone_xml }} from {{ keycloak.config_template_source }}" diff --git a/roles/keycloak/tasks/jdbc_driver.yml b/roles/keycloak/tasks/jdbc_driver.yml new file mode 100644 index 0000000..3f93c53 --- /dev/null +++ b/roles/keycloak/tasks/jdbc_driver.yml @@ -0,0 +1,36 @@ +--- +- name: "Check module directory: {{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_dir }}" + ansible.builtin.stat: + path: "{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_dir }}" + register: dest_path + become: yes + +- name: "Set up module dir for JDBC Driver {{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_name }}" + ansible.builtin.file: + path: "{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_dir }}" + state: directory + recurse: yes + owner: "{{ keycloak_service_user }}" + group: "{{ keycloak_service_group }}" + mode: 0750 + become: yes + when: + - not dest_path.stat.exists + +- name: "Retrieve JDBC Driver from {{ keycloak_jdbc[keycloak_jdbc_engine].driver_jar_url }}" + ansible.builtin.uri: + url: "{{ keycloak_jdbc[keycloak_jdbc_engine].driver_jar_url }}" + dest: "{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_dir }}/{{ keycloak_jdbc[keycloak_jdbc_engine].driver_jar_filename }}" + group: "{{ keycloak_service_group }}" + owner: "{{ keycloak_service_user }}" + mode: 0640 + become: yes + +- name: "Deploy module.xml for JDBC Driver" + ansible.builtin.template: + src: "templates/jdbc_driver_module.xml.j2" + dest: "{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_dir }}/module.xml" + group: "{{ keycloak_service_group }}" + owner: "{{ keycloak_service_user }}" + mode: 0640 + become: yes diff --git a/roles/keycloak/templates/jdbc_driver_module.xml.j2 b/roles/keycloak/templates/jdbc_driver_module.xml.j2 new file mode 100644 index 0000000..c513693 --- /dev/null +++ b/roles/keycloak/templates/jdbc_driver_module.xml.j2 @@ -0,0 +1,10 @@ + + + + + + + + + + From 52e38f7398d4ac9ddd9241e70465cbe6dbc23697 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 19 Sep 2022 22:10:03 +0200 Subject: [PATCH 091/554] Bump to 1.1.0 --- galaxy.yml | 3 +-- roles/keycloak/README.md | 1 - roles/keycloak/meta/main.yml | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/galaxy.yml b/galaxy.yml index e3c6bfb..1632845 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.0.7" +version: "1.1.0" readme: README.md authors: - Romain Pelisse @@ -22,7 +22,6 @@ tags: - authentication dependencies: "middleware_automation.redhat_csp_download": ">=1.2.1" - "middleware_automation.wildfly": ">=1.0.0" repository: https://github.com/ansible-middleware/keycloak documentation: https://ansible-middleware.github.io/keycloak homepage: https://github.com/ansible-middleware/keycloak diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index 0f3d198..1f87464 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -20,7 +20,6 @@ Dependencies The roles depends on: * the `redhat_csp_download` role from [middleware_automation.redhat_csp_download](https://github.com/ansible-middleware/redhat-csp-download) collection if Red Hat Single Sign-on zip have to be downloaded from RHN. -* the `wildfly_driver` role from [middleware_automation.wildfly](https://github.com/ansible-middleware/wildfly) collection Versions diff --git a/roles/keycloak/meta/main.yml b/roles/keycloak/meta/main.yml index 4760762..fce67b7 100644 --- a/roles/keycloak/meta/main.yml +++ b/roles/keycloak/meta/main.yml @@ -1,7 +1,6 @@ --- collections: - middleware_automation.redhat_csp_download - - middleware_automation.wildfly galaxy_info: role_name: keycloak From ec47a1c5a86e11215a332ab4f1c2f4c9c896c505 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 19 Sep 2022 22:41:18 +0200 Subject: [PATCH 092/554] downstream: correctly interpolate defaults --- roles/keycloak/meta/argument_specs.yml | 8 ++++---- roles/keycloak_realm/meta/argument_specs.yml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index f34b134..f70a64a 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -269,11 +269,11 @@ argument_specs: description: "Red Hat Single Sign-On version" type: "str" sso_rhn_id: - default: "{{ sso_rhn_ids[keycloak_version].id }}" + default: "{{ sso_rhn_ids[sso_version].id }}" description: "Customer Portal product ID for Red Hat SSO" type: "str" sso_archive: - default: "rh-sso-{{ keycloak_version }}-server-dist.zip" + default: "rh-sso-{{ sso_version }}-server-dist.zip" description: "Red Hat SSO install archive filename" type: "str" sso_dest: @@ -281,7 +281,7 @@ argument_specs: description: "Root installation directory" type: "str" sso_installdir: - default: "{{ keycloak_dest }}/rh-sso-{{ keycloak_version | regex_replace('^([0-9])\\.([0-9]*).*', '\\1.\\2') }}" + default: "{{ sso_dest }}/rh-sso-{{ sso_version.split('.')[0] }}.{{ sso_version.split('.')[1] }}" description: "Installation path for Red Hat SSO" type: "str" sso_rhn_url: @@ -313,6 +313,6 @@ argument_specs: description: "systemd description for Red Hat Single Sign-On" type: "str" sso_patch_bundle: - default: "rh-sso-{{ sso_rhn_ids[keycloak_version].latest_cp.v }}-patch.zip" + default: "rh-sso-{{ sso_rhn_ids[sso_version].latest_cp.v }}-patch.zip" description: "Red Hat SSO patch archive filename" type: "str" diff --git a/roles/keycloak_realm/meta/argument_specs.yml b/roles/keycloak_realm/meta/argument_specs.yml index 8f8e26e..4345af6 100644 --- a/roles/keycloak_realm/meta/argument_specs.yml +++ b/roles/keycloak_realm/meta/argument_specs.yml @@ -102,7 +102,7 @@ argument_specs: description: "Root installation directory" type: "str" sso_installdir: - default: "{{ keycloak_dest }}/rh-sso-{{ keycloak_version | regex_replace('^([0-9])\\.([0-9]*).*', '\\1.\\2') }}" + default: "{{ sso_dest }}/rh-sso-{{ sso_version.split('.')[0] }}.{{ sso_version.split('.')[1] }}" description: "Installation path for Red Hat SSO" type: "str" sso_apply_patches: From dfc1912a99e518e0fcaea05d8ae237f633048582 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 27 Sep 2022 15:36:14 +0200 Subject: [PATCH 093/554] jdbc_driver: switch from uri to get_url --- roles/keycloak/tasks/jdbc_driver.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak/tasks/jdbc_driver.yml b/roles/keycloak/tasks/jdbc_driver.yml index 3f93c53..7dfaabc 100644 --- a/roles/keycloak/tasks/jdbc_driver.yml +++ b/roles/keycloak/tasks/jdbc_driver.yml @@ -18,7 +18,7 @@ - not dest_path.stat.exists - name: "Retrieve JDBC Driver from {{ keycloak_jdbc[keycloak_jdbc_engine].driver_jar_url }}" - ansible.builtin.uri: + ansible.builtin.get_url: url: "{{ keycloak_jdbc[keycloak_jdbc_engine].driver_jar_url }}" dest: "{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_dir }}/{{ keycloak_jdbc[keycloak_jdbc_engine].driver_jar_filename }}" group: "{{ keycloak_service_group }}" From a7fbce2990d69f6074b0fd4e4a3e37d493704f7a Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 28 Sep 2022 15:33:30 +0200 Subject: [PATCH 094/554] New variable for binding of management ports --- .ansible-lint | 1 + roles/keycloak/README.md | 1 + roles/keycloak/defaults/main.yml | 1 + roles/keycloak/meta/argument_specs.yml | 4 ++++ roles/keycloak/templates/standalone-infinispan.xml.j2 | 4 ++-- roles/keycloak/templates/standalone.xml.j2 | 4 ++-- 6 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.ansible-lint b/.ansible-lint index f9251eb..588eed7 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -26,6 +26,7 @@ warn_list: - jinja[spacing] - jinja[invalid] - meta-no-tags + - name[template] skip_list: - vars_should_not_be_used diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index 1f87464..7b0bd23 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -52,6 +52,7 @@ Role Defaults |`keycloak_db_enabled`| Enable auto configuration for database backend | `True` if `keycloak_ha_enabled` is True, else `False` | |`keycloak_admin_user`| Administration console user account | `admin` | |`keycloak_bind_address`| Address for binding service ports | `0.0.0.0` | +|`keycloak_management_port_bind_address`| Address for binding management ports | `127.0.0.1` | |`keycloak_host`| hostname | `localhost` | |`keycloak_http_port`| HTTP port | `8080` | |`keycloak_https_port`| TLS HTTP port | `8443` | diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 291ff37..7bb3bb8 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -34,6 +34,7 @@ keycloak_http_port: 8080 keycloak_https_port: 8443 keycloak_ajp_port: 8009 keycloak_jgroups_port: 7600 +keycloak_management_port_bind_address: 127.0.0.1 keycloak_management_http_port: 9990 keycloak_management_https_port: 9993 keycloak_java_opts: "-Xms1024m -Xmx2048m" diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index f70a64a..29ebce8 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -94,6 +94,10 @@ argument_specs: default: "0.0.0.0" description: "Address for binding service ports" type: "str" + keycloak_management_port_bind_address: + default: "127.0.0.1" + description: "Address for binding the managemnt ports" + type: "str" keycloak_host: # line 35 of keycloak/defaults/main.yml default: "localhost" diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index 8e58b53..4198b83 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -724,7 +724,7 @@ - + {% if ansible_default_ipv4 is defined %} @@ -734,7 +734,7 @@ {% endif %} - + diff --git a/roles/keycloak/templates/standalone.xml.j2 b/roles/keycloak/templates/standalone.xml.j2 index 3207ef9..e2f6a76 100644 --- a/roles/keycloak/templates/standalone.xml.j2 +++ b/roles/keycloak/templates/standalone.xml.j2 @@ -632,10 +632,10 @@ - + - + From be582171ce0adb4d3c58c5f47ad536b6389578b4 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 28 Sep 2022 16:30:26 +0200 Subject: [PATCH 095/554] restart handler: orchestrate --- roles/keycloak/tasks/restart_keycloak.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/roles/keycloak/tasks/restart_keycloak.yml b/roles/keycloak/tasks/restart_keycloak.yml index eff9ddf..2d78244 100644 --- a/roles/keycloak/tasks/restart_keycloak.yml +++ b/roles/keycloak/tasks/restart_keycloak.yml @@ -5,3 +5,23 @@ enabled: yes state: restarted become: yes + delegate_to: "{{ ansible_play_hosts | first }}" + run_once: True + +- name: "Wait until {{ keycloak.service_name }} becomes active {{ keycloak.health_url }}" + ansible.builtin.uri: + url: "{{ keycloak.health_url }}" + register: keycloak_status + until: keycloak_status.status == 200 + delegate_to: "{{ ansible_play_hosts | first }}" + run_once: True + retries: 25 + delay: 10 + +- name: "Restart and enable {{ keycloak.service_name }} service" + ansible.builtin.systemd: + name: keycloak + enabled: yes + state: restarted + become: yes + when: and inventory_hostname != ansible_play_hosts | first From 65da436d747a9bb007a2e2822a8bce07777e0729 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 28 Sep 2022 16:48:40 +0200 Subject: [PATCH 096/554] restart handler: orchestrate --- roles/keycloak/tasks/restart_keycloak.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak/tasks/restart_keycloak.yml b/roles/keycloak/tasks/restart_keycloak.yml index 2d78244..d77ee58 100644 --- a/roles/keycloak/tasks/restart_keycloak.yml +++ b/roles/keycloak/tasks/restart_keycloak.yml @@ -24,4 +24,4 @@ enabled: yes state: restarted become: yes - when: and inventory_hostname != ansible_play_hosts | first + when: inventory_hostname != ansible_play_hosts | first From bea5062287cd860a55a9a64d3515fa8bd2ae87c4 Mon Sep 17 00:00:00 2001 From: kabroxiko Date: Sat, 8 Oct 2022 21:05:49 -0300 Subject: [PATCH 097/554] fix: Wrong file location Fix: Wrong quarkus log link and folder creation. Replace: keycloak -> /opt/keycloak/keycloak-19.0.2//opt/keycloak/keycloak-19.0.2/data/log For: keycloak -> /opt/keycloak/keycloak-19.0.2/data/log --- roles/keycloak_quarkus/tasks/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index 738b55e..1c6c21b 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -46,7 +46,7 @@ - name: Ensure logdirectory exists ansible.builtin.file: state: directory - path: "{{ keycloak.home }}/{{ keycloak.log.file | dirname }}" + path: "{{ keycloak.log.file | dirname }}" owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" mode: 0775 @@ -63,7 +63,7 @@ - name: Link default logs directory ansible.builtin.file: state: link - src: "{{ keycloak.home }}/{{ keycloak.log.file | dirname }}" + src: "{{ keycloak.log.file | dirname }}" dest: /var/log/keycloak force: yes become: yes From ab1c06a2e836040c132e3178f850acca7efce944 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 19 Oct 2022 17:27:00 +0200 Subject: [PATCH 098/554] ci: set new ansible rule as warning --- .ansible-lint | 1 + 1 file changed, 1 insertion(+) diff --git a/.ansible-lint b/.ansible-lint index 588eed7..9991fac 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -27,6 +27,7 @@ warn_list: - jinja[invalid] - meta-no-tags - name[template] + - fqcn[action] skip_list: - vars_should_not_be_used From db111aaf3a6a300b9b2077463f8160bb7a75d2be Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 13 Dec 2022 10:50:53 +0100 Subject: [PATCH 099/554] add fqcn to firewalld tasks --- roles/keycloak/tasks/firewalld.yml | 2 +- roles/keycloak_quarkus/tasks/firewalld.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/keycloak/tasks/firewalld.yml b/roles/keycloak/tasks/firewalld.yml index 58a6cac..0cf4ee3 100644 --- a/roles/keycloak/tasks/firewalld.yml +++ b/roles/keycloak/tasks/firewalld.yml @@ -14,7 +14,7 @@ - name: "Configure firewall for {{ keycloak.service_name }} ports" become: yes - firewalld: + ansible.posix.firewalld: port: "{{ item }}" permanent: true state: enabled diff --git a/roles/keycloak_quarkus/tasks/firewalld.yml b/roles/keycloak_quarkus/tasks/firewalld.yml index 772ba3c..6c81021 100644 --- a/roles/keycloak_quarkus/tasks/firewalld.yml +++ b/roles/keycloak_quarkus/tasks/firewalld.yml @@ -14,7 +14,7 @@ - name: "Configure firewall for {{ keycloak.service_name }} ports" become: yes - firewalld: + ansible.posix.firewalld: port: "{{ item }}" permanent: true state: enabled From bdc1ad8b51433077af2b10c4cfa5542b1a00eb28 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 13 Dec 2022 11:20:44 +0100 Subject: [PATCH 100/554] Add validation of realm client and id --- playbooks/keycloak_federation.yml | 68 ++++++++++++++++++++++ playbooks/keycloak_realm.yml | 89 ++++++++--------------------- roles/keycloak/tasks/main.yml | 1 + roles/keycloak_realm/README.md | 5 ++ roles/keycloak_realm/tasks/main.yml | 13 ++++- 5 files changed, 111 insertions(+), 65 deletions(-) create mode 100644 playbooks/keycloak_federation.yml diff --git a/playbooks/keycloak_federation.yml b/playbooks/keycloak_federation.yml new file mode 100644 index 0000000..f6de6c1 --- /dev/null +++ b/playbooks/keycloak_federation.yml @@ -0,0 +1,68 @@ +--- +- name: Playbook for Keycloak Hosts + hosts: all + tasks: + - name: Keycloak Realm Role + ansible.builtin.include_role: + name: keycloak_realm + vars: + keycloak_admin_password: "remembertochangeme" + keycloak_realm: TestRealm + keycloak_user_federation: + - realm: TestRealm + name: my-ldap + provider_id: ldap + provider_type: org.keycloak.storage.UserStorageProvider + config: + priority: '0' + enabled: true + cachePolicy: DEFAULT + batchSizeForSync: '1000' + editMode: READ_ONLY + importEnabled: true + syncRegistrations: false + vendor: other + usernameLDAPAttribute: uid + rdnLDAPAttribute: uid + uuidLDAPAttribute: entryUUID + userObjectClasses: inetOrgPerson, organizationalPerson + connectionUrl: ldaps://ldap.example.com:636 + usersDn: ou=Users,dc=example,dc=com + authType: simple + bindDn: cn=directory reader + bindCredential: password + searchScope: '1' + validatePasswordPolicy: false + trustEmail: false + useTruststoreSpi: ldapsOnly + connectionPooling: true + pagination: true + allowKerberosAuthentication: false + debug: false + useKerberosForPasswordAuthentication: false + mappers: + - name: "full name" + providerId: "full-name-ldap-mapper" + providerType: "org.keycloak.storage.ldap.mappers.LDAPStorageMapper" + config: + ldap.full.name.attribute: cn + read.only: true + write.only: false + keycloak_clients: + - name: TestClient1 + client_id: TestClient1 + roles: + - TestClient1Admin + - TestClient1User + realm: "{{ keycloak_realm }}" + public_client: True + web_origins: + - http://testclient1origin/application + - http://testclient1origin/other + users: + - username: TestUser + password: password + client_roles: + - client: TestClient1 + role: TestClient1User + realm: "{{ keycloak_realm }}" diff --git a/playbooks/keycloak_realm.yml b/playbooks/keycloak_realm.yml index baeb2f2..1efc4f7 100644 --- a/playbooks/keycloak_realm.yml +++ b/playbooks/keycloak_realm.yml @@ -1,67 +1,28 @@ --- - name: Playbook for Keycloak Hosts hosts: all - tasks: - - name: Keycloak Realm Role - ansible.builtin.include_role: - name: middleware_automation.keycloak.keycloak_realm - vars: - keycloak_admin_password: "remembertochangeme" - keycloak_realm: TestRealm - keycloak_user_federation: - - realm: TestRealm - name: my-ldap - provider_id: ldap - provider_type: org.keycloak.storage.UserStorageProvider - config: - priority: '0' - enabled: true - cachePolicy: DEFAULT - batchSizeForSync: '1000' - editMode: READ_ONLY - importEnabled: true - syncRegistrations: false - vendor: other - usernameLDAPAttribute: uid - rdnLDAPAttribute: uid - uuidLDAPAttribute: entryUUID - userObjectClasses: inetOrgPerson, organizationalPerson - connectionUrl: ldaps://ldap.example.com:636 - usersDn: ou=Users,dc=example,dc=com - authType: simple - bindDn: cn=directory reader - bindCredential: password - searchScope: '1' - validatePasswordPolicy: false - trustEmail: false - useTruststoreSpi: ldapsOnly - connectionPooling: true - pagination: true - allowKerberosAuthentication: false - debug: false - useKerberosForPasswordAuthentication: false - mappers: - - name: "full name" - providerId: "full-name-ldap-mapper" - providerType: "org.keycloak.storage.ldap.mappers.LDAPStorageMapper" - config: - ldap.full.name.attribute: cn - read.only: true - write.only: false - keycloak_clients: - - name: TestClient1 - roles: - - TestClient1Admin - - TestClient1User - realm: "{{ keycloak_realm }}" - public_client: True - web_origins: - - http://testclient1origin/application - - http://testclient1origin/other - users: - - username: TestUser - password: password - client_roles: - - client: TestClient1 - role: TestClient1User - realm: "{{ keycloak_realm }}" + vars: + keycloak_admin_password: "remembertochangeme" + keycloak_realm: TestRealm + keycloak_clients: + - name: TestClient1 + client_id: TestClient1 + roles: + - TestClient1Admin + - TestClient1User + realm: "{{ keycloak_realm }}" + public_client: True + web_origins: + - http://testclient1origin/application + - http://testclient1origin/other + users: + - username: TestUser + password: password + client_roles: + - client: TestClient1 + role: TestClient1User + realm: "{{ keycloak_realm }}" + collections: + - middleware_automation.keycloak + roles: + - keycloak_realm diff --git a/roles/keycloak/tasks/main.yml b/roles/keycloak/tasks/main.yml index b89b401..316c033 100644 --- a/roles/keycloak/tasks/main.yml +++ b/roles/keycloak/tasks/main.yml @@ -36,6 +36,7 @@ state: link src: "{{ keycloak_jboss_home }}/standalone/log" dest: /var/log/keycloak + become: yes - name: Set admin credentials and restart if not already created block: diff --git a/roles/keycloak_realm/README.md b/roles/keycloak_realm/README.md index 1a5709c..73d823f 100644 --- a/roles/keycloak_realm/README.md +++ b/roles/keycloak_realm/README.md @@ -71,6 +71,8 @@ Refer to [docs](https://docs.ansible.com/ansible/latest/collections/community/ge ```yaml - name: + id: + client_id: roles: realm: public_client: @@ -78,6 +80,9 @@ Refer to [docs](https://docs.ansible.com/ansible/latest/collections/community/ge users: ``` +`name` and either `id` or `client_id` are required. + + * `keycloak_client_users`, a list of: ```yaml diff --git a/roles/keycloak_realm/tasks/main.yml b/roles/keycloak_realm/tasks/main.yml index 2554958..1544a1e 100644 --- a/roles/keycloak_realm/tasks/main.yml +++ b/roles/keycloak_realm/tasks/main.yml @@ -53,6 +53,17 @@ loop: "{{ keycloak_user_federation | flatten }}" when: keycloak_user_federation is defined +- name: Validate Keycloak clients + ansible.builtin.assert: + that: + - item.name is defined and item.name | length > 0 + - (item.client_id is defined and item.client_id | length > 0) or (item.id is defined and item.id | length > 0) + fail_msg: "For each keycloak client, attributes `name` and either `id` or `client_id` is required" + quiet: True + loop: "{{ keycloak_clients | flatten }}" + loop_control: + label: "{{ item.name | default('unnamed client') }}" + - name: Create or update a Keycloak client community.general.keycloak_client: auth_client_id: "{{ keycloak_auth_client }}" @@ -97,4 +108,4 @@ loop: "{{ keycloak_clients | flatten }}" loop_control: loop_var: client - when: "'users' in client" \ No newline at end of file + when: "'users' in client" From c0d4c6211e4e982cb977014e9cd6bff8310a7579 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 13 Dec 2022 11:24:28 +0100 Subject: [PATCH 101/554] ci: drop --docker from ansible-test sanity --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 85da941..54e3e9e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,7 +46,7 @@ jobs: path: ansible_collections/ansible-lint-custom-rules/ - name: Run sanity tests - run: ansible-test sanity --docker -v --color --python ${{ matrix.python_version }} --exclude changelogs/fragments/.gitignore + run: ansible-test sanity -v --color --python ${{ matrix.python_version }} --exclude changelogs/fragments/.gitignore --skip-test symlinks working-directory: ./ansible_collections/middleware_automation/keycloak - name: Run molecule test From 89fa82eddba0d49bcbdb3a882b9df99662cd9753 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 13 Dec 2022 11:27:18 +0100 Subject: [PATCH 102/554] ci: add new docs reqs --- docs/requirements.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/requirements.txt b/docs/requirements.txt index 72a7d48..5fe33c2 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,4 +1,6 @@ antsibull>=0.17.0 +antsibull-docs +antsibull-changelog ansible-base>=2.10.12 sphinx-rtd-theme git+https://github.com/felixfontein/ansible-basic-sphinx-ext From 3d0cfc9e42eb50680ee0b3dfe81f74d6285ec3fe Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 13 Dec 2022 11:28:56 +0100 Subject: [PATCH 103/554] ci: add bogus lint rule to warnings --- .ansible-lint | 1 + 1 file changed, 1 insertion(+) diff --git a/.ansible-lint b/.ansible-lint index 9991fac..e28ef42 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -27,6 +27,7 @@ warn_list: - jinja[invalid] - meta-no-tags - name[template] + - name[casing] - fqcn[action] skip_list: From b3b016bf3b509ef497c958fb4c1ac06188ad270e Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 13 Dec 2022 11:39:57 +0100 Subject: [PATCH 104/554] Drop deprecated builtin.command arg --- roles/keycloak/tasks/fastpackages.yml | 4 +--- roles/keycloak_quarkus/tasks/fastpackages.yml | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/roles/keycloak/tasks/fastpackages.yml b/roles/keycloak/tasks/fastpackages.yml index 78bc556..250e30e 100644 --- a/roles/keycloak/tasks/fastpackages.yml +++ b/roles/keycloak/tasks/fastpackages.yml @@ -3,8 +3,6 @@ block: - name: "Check if packages are already installed" ansible.builtin.command: "rpm -q {{ packages_list | join(' ') }}" - args: - warn: no register: rpm_info changed_when: rpm_info.failed @@ -19,4 +17,4 @@ ansible.builtin.yum: name: "{{ packages_to_install }}" state: present - when: packages_to_install | default([]) | length > 0 \ No newline at end of file + when: packages_to_install | default([]) | length > 0 diff --git a/roles/keycloak_quarkus/tasks/fastpackages.yml b/roles/keycloak_quarkus/tasks/fastpackages.yml index 3dd28e1..3d3903e 100644 --- a/roles/keycloak_quarkus/tasks/fastpackages.yml +++ b/roles/keycloak_quarkus/tasks/fastpackages.yml @@ -3,8 +3,6 @@ block: - name: "Check if packages are already installed" ansible.builtin.command: "rpm -q {{ packages_list | join(' ') }}" - args: - warn: no register: rpm_info changed_when: rpm_info.failed @@ -19,4 +17,4 @@ ansible.builtin.yum: name: "{{ packages_to_install }}" state: present - when: packages_to_install | default([]) | length > 0 \ No newline at end of file + when: packages_to_install | default([]) | length > 0 From f4fe9df97ce94773ae9f3e0c7058928a234bb3b7 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 13 Dec 2022 11:49:36 +0100 Subject: [PATCH 105/554] ci: add noqa to commands --- roles/keycloak/tasks/fastpackages.yml | 2 +- roles/keycloak_quarkus/tasks/fastpackages.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/keycloak/tasks/fastpackages.yml b/roles/keycloak/tasks/fastpackages.yml index 250e30e..17d103e 100644 --- a/roles/keycloak/tasks/fastpackages.yml +++ b/roles/keycloak/tasks/fastpackages.yml @@ -1,7 +1,7 @@ --- - name: Check packages to be installed block: - - name: "Check if packages are already installed" + - name: "Check if packages are already installed" # noqa command-instead-of-module this runs faster ansible.builtin.command: "rpm -q {{ packages_list | join(' ') }}" register: rpm_info changed_when: rpm_info.failed diff --git a/roles/keycloak_quarkus/tasks/fastpackages.yml b/roles/keycloak_quarkus/tasks/fastpackages.yml index 3d3903e..78472dd 100644 --- a/roles/keycloak_quarkus/tasks/fastpackages.yml +++ b/roles/keycloak_quarkus/tasks/fastpackages.yml @@ -1,7 +1,7 @@ --- - name: Check packages to be installed block: - - name: "Check if packages are already installed" + - name: "Check if packages are already installed" # noqa command-instead-of-module this runs faster ansible.builtin.command: "rpm -q {{ packages_list | join(' ') }}" register: rpm_info changed_when: rpm_info.failed From 63dc3691483b0d2535fd7e71c31fb1688abdb495 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 13 Dec 2022 12:31:03 +0100 Subject: [PATCH 106/554] Add missing deps declarations --- galaxy.yml | 2 ++ molecule/default/requirements.yml | 1 + molecule/overridexml/requirements.yml | 1 + molecule/quarkus/requirements.yml | 1 + requirements.yml | 1 + 5 files changed, 6 insertions(+) diff --git a/galaxy.yml b/galaxy.yml index 1632845..0084428 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -22,6 +22,8 @@ tags: - authentication dependencies: "middleware_automation.redhat_csp_download": ">=1.2.1" + "community.general": ">=5.6.0" + "ansible.posix": ">=1.4.0" repository: https://github.com/ansible-middleware/keycloak documentation: https://ansible-middleware.github.io/keycloak homepage: https://github.com/ansible-middleware/keycloak diff --git a/molecule/default/requirements.yml b/molecule/default/requirements.yml index de3dc3e..0aed172 100644 --- a/molecule/default/requirements.yml +++ b/molecule/default/requirements.yml @@ -3,6 +3,7 @@ collections: - name: middleware_automation.redhat_csp_download version: ">=1.2.1" - name: community.general + - name: ansible.posix - name: community.docker version: ">=1.9.1" diff --git a/molecule/overridexml/requirements.yml b/molecule/overridexml/requirements.yml index de3dc3e..0aed172 100644 --- a/molecule/overridexml/requirements.yml +++ b/molecule/overridexml/requirements.yml @@ -3,6 +3,7 @@ collections: - name: middleware_automation.redhat_csp_download version: ">=1.2.1" - name: community.general + - name: ansible.posix - name: community.docker version: ">=1.9.1" diff --git a/molecule/quarkus/requirements.yml b/molecule/quarkus/requirements.yml index de3dc3e..0aed172 100644 --- a/molecule/quarkus/requirements.yml +++ b/molecule/quarkus/requirements.yml @@ -3,6 +3,7 @@ collections: - name: middleware_automation.redhat_csp_download version: ">=1.2.1" - name: community.general + - name: ansible.posix - name: community.docker version: ">=1.9.1" diff --git a/requirements.yml b/requirements.yml index 1ae6626..4eab0c7 100644 --- a/requirements.yml +++ b/requirements.yml @@ -3,3 +3,4 @@ collections: - name: middleware_automation.redhat_csp_download version: ">=1.2.1" - name: community.general + - name: ansible.posix From e624870e38ae118bad6f02d5cb80d72457960658 Mon Sep 17 00:00:00 2001 From: Katzy Date: Thu, 27 Oct 2022 14:18:33 +0200 Subject: [PATCH 107/554] Fix hardcoded health_url to parameterized --- roles/keycloak_quarkus/vars/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/keycloak_quarkus/vars/main.yml b/roles/keycloak_quarkus/vars/main.yml index abd6413..1a4c867 100644 --- a/roles/keycloak_quarkus/vars/main.yml +++ b/roles/keycloak_quarkus/vars/main.yml @@ -4,7 +4,7 @@ keycloak: config_dir: "{{ keycloak_quarkus_config_dir }}" bundle: "{{ keycloak_quarkus_archive }}" service_name: "keycloak" - health_url: "http://localhost:8080/realms/master/.well-known/openid-configuration" + health_url: "http://{{ keycloak_quarkus_host }}:{{keycloak_quarkus_http_port }}/realms/master/.well-known/openid-configuration" cli_path: "{{ keycloak_quarkus_home }}/bin/kcadm.sh" service_user: "{{ keycloak_quarkus_service_user }}" service_group: "{{ keycloak_quarkus_service_group }}" @@ -12,4 +12,4 @@ keycloak: log: file: "{{ keycloak_quarkus_home }}/{{ keycloak_quarkus_log_file }}" level: "{{ keycloak_quarkus_log_level }}" - format: "{{ keycloak_quarkus_log_format }}" \ No newline at end of file + format: "{{ keycloak_quarkus_log_format }}" From ad4d5dae6821b819144207045a0881ae4b34f88a Mon Sep 17 00:00:00 2001 From: Katzy Date: Thu, 27 Oct 2022 15:40:54 +0200 Subject: [PATCH 108/554] Update keycloak.service.j2 --- roles/keycloak_quarkus/templates/keycloak.service.j2 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/roles/keycloak_quarkus/templates/keycloak.service.j2 b/roles/keycloak_quarkus/templates/keycloak.service.j2 index 90242cf..14e7542 100644 --- a/roles/keycloak_quarkus/templates/keycloak.service.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.service.j2 @@ -7,7 +7,11 @@ After=network.target Type=simple EnvironmentFile=-/etc/sysconfig/keycloak PIDFile={{ keycloak_quarkus_service_pidfile }} +{% if keycloak_quarkus_start_dev %} +ExecStart={{ keycloak.home }}/bin/kc.sh start-dev +{% else %} ExecStart={{ keycloak.home }}/bin/kc.sh start --auto-build --log={{ keycloak_quarkus_log }} +{% endif %} User={{ keycloak.service_user }} [Install] From 422986a8fd621dfef7b8140ecaa559f9b582a6a8 Mon Sep 17 00:00:00 2001 From: Katzy Date: Thu, 27 Oct 2022 15:41:57 +0200 Subject: [PATCH 109/554] Enable this role to start keycloak in dev mode --- roles/keycloak_quarkus/defaults/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index a54a8ec..f51ce59 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -14,6 +14,7 @@ keycloak_quarkus_java_home: keycloak_quarkus_dest: /opt/keycloak keycloak_quarkus_home: "{{ keycloak_quarkus_installdir }}" keycloak_quarkus_config_dir: "{{ keycloak_quarkus_home }}/conf" +keycloak_quarkus_start_dev: False keycloak_quarkus_service_user: keycloak keycloak_quarkus_service_group: keycloak keycloak_quarkus_service_pidfile: "/run/keycloak.pid" From 2df5fd22cf58dcea5a571f80adc953aece5c9be9 Mon Sep 17 00:00:00 2001 From: Katzy Date: Thu, 27 Oct 2022 15:42:58 +0200 Subject: [PATCH 110/554] Update main.yml --- roles/keycloak_quarkus/vars/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/vars/main.yml b/roles/keycloak_quarkus/vars/main.yml index 1a4c867..1b3ef73 100644 --- a/roles/keycloak_quarkus/vars/main.yml +++ b/roles/keycloak_quarkus/vars/main.yml @@ -4,7 +4,7 @@ keycloak: config_dir: "{{ keycloak_quarkus_config_dir }}" bundle: "{{ keycloak_quarkus_archive }}" service_name: "keycloak" - health_url: "http://{{ keycloak_quarkus_host }}:{{keycloak_quarkus_http_port }}/realms/master/.well-known/openid-configuration" + health_url: "http://{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_http_port }}/realms/master/.well-known/openid-configuration" cli_path: "{{ keycloak_quarkus_home }}/bin/kcadm.sh" service_user: "{{ keycloak_quarkus_service_user }}" service_group: "{{ keycloak_quarkus_service_group }}" From 853d4ab96bdb318cd7beedfd8b56e4432febd788 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 13 Dec 2022 14:28:17 +0100 Subject: [PATCH 111/554] rebase and update documentation --- roles/keycloak_quarkus/README.md | 1 + roles/keycloak_quarkus/meta/argument_specs.yml | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 769e2f7..de330dc 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -97,6 +97,7 @@ Role Defaults |`keycloak_quarkus_log_file`| Set the log file path and filename relative to keycloak home | `data/log/keycloak.log` | |`keycloak_quarkus_log_format`| Set a format specific to file log entries | `%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n` | |`keycloak_quarkus_proxy_mode`| The proxy address forwarding mode if the server is behind a reverse proxy | `edge` | +|`keycloak_quarkus_start_dev`| Whether to start the service in development mode (start-dev) | `False` | Role Variables diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index a0214a5..9205cef 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -244,3 +244,7 @@ argument_specs: default: 'edge' type: "str" description: "The proxy address forwarding mode if the server is behind a reverse proxy" + keycloak_quarkus_start_dev: + default: False + type: "bool" + description: "Whether to start the service in development mode (start-dev)" From 2594fd91864d49aafbae2f98e89bc1e04e72a4ed Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 13 Dec 2022 14:48:12 +0100 Subject: [PATCH 112/554] update molecule scenario --- molecule/quarkus/converge.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index cb84edb..22f9ff4 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -5,7 +5,7 @@ keycloak_quarkus_admin_pass: "remembertochangeme" keycloak_admin_password: "remembertochangeme" keycloak_realm: TestRealm - keycloak_quarkus_host: instance:8443 + keycloak_quarkus_host: instance keycloak_quarkus_http_relative_path: '' keycloak_quarkus_log: file keycloak_quarkus_https_enabled: True From 6e4b224fe15e93cc8ecf4641aaa5f1cc677a0f4d Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 13 Dec 2022 15:07:11 +0100 Subject: [PATCH 113/554] molecule: quarkus update verify urls --- molecule/quarkus/verify.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/molecule/quarkus/verify.yml b/molecule/quarkus/verify.yml index 8d86585..1d4e5ae 100644 --- a/molecule/quarkus/verify.yml +++ b/molecule/quarkus/verify.yml @@ -25,10 +25,10 @@ - name: Verify endpoint URLs assert: that: - - (openid_config.stdout | from_json)["backchannel_authentication_endpoint"] == 'https://instance:8443/realms/master/protocol/openid-connect/ext/ciba/auth' - - (openid_config.stdout | from_json)['issuer'] == 'https://instance:8443/realms/master' - - (openid_config.stdout | from_json)['authorization_endpoint'] == 'https://instance:8443/realms/master/protocol/openid-connect/auth' - - (openid_config.stdout | from_json)['token_endpoint'] == 'https://instance:8443/realms/master/protocol/openid-connect/token' + - (openid_config.stdout | from_json)["backchannel_authentication_endpoint"] == 'https://instance/realms/master/protocol/openid-connect/ext/ciba/auth' + - (openid_config.stdout | from_json)['issuer'] == 'https://instance/realms/master' + - (openid_config.stdout | from_json)['authorization_endpoint'] == 'https://instance/realms/master/protocol/openid-connect/auth' + - (openid_config.stdout | from_json)['token_endpoint'] == 'https://instance/realms/master/protocol/openid-connect/token' delegate_to: localhost when: - hera_home is defined From 2054082b404e941b9b3a306ea5052b00d862d558 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 13 Dec 2022 15:31:08 +0100 Subject: [PATCH 114/554] get rid of rhn_ids dict --- roles/keycloak/meta/argument_specs.yml | 12 ++++++++++-- roles/keycloak/tasks/rhsso_patch.yml | 10 +++++----- roles/keycloak/vars/main.yml | 6 ------ 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 29ebce8..0a27aba 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -273,7 +273,7 @@ argument_specs: description: "Red Hat Single Sign-On version" type: "str" sso_rhn_id: - default: "{{ sso_rhn_ids[sso_version].id }}" + default: "101971" description: "Customer Portal product ID for Red Hat SSO" type: "str" sso_archive: @@ -316,7 +316,15 @@ argument_specs: default: "Red Hat Single Sign-On" description: "systemd description for Red Hat Single Sign-On" type: "str" + sso_patch_version: + default: "7.5.3" + description: "Red Hat Single Sign-On latest cumulative patch version" + type: "str" sso_patch_bundle: - default: "rh-sso-{{ sso_rhn_ids[sso_version].latest_cp.v }}-patch.zip" + default: "rh-sso-{{ sso_patch_version }}-patch.zip" description: "Red Hat SSO patch archive filename" type: "str" + sso_patch_rhn_id: + default: "104738" + description: "Customer Portal product ID for Red Hat SSO latest cumulative patch" + type: "str" diff --git a/roles/keycloak/tasks/rhsso_patch.yml b/roles/keycloak/tasks/rhsso_patch.yml index 67739a4..97993a2 100644 --- a/roles/keycloak/tasks/rhsso_patch.yml +++ b/roles/keycloak/tasks/rhsso_patch.yml @@ -11,7 +11,7 @@ - name: Perform download from RHN middleware_automation.redhat_csp_download.redhat_csp_download: - url: "{{ keycloak_rhn_url }}{{ sso_rhn_ids[keycloak_version].latest_cp.id }}" + url: "{{ keycloak_rhn_url }}{{ sso_patch_rhn_id }}" dest: "{{ local_path.stat.path }}/{{ sso_patch_bundle }}" username: "{{ rhn_username }}" password: "{{ rhn_password }}" @@ -48,9 +48,9 @@ when: - cli_result is defined - cli_result.stdout is defined - - sso_rhn_ids[keycloak_version].latest_cp.v not in cli_result.stdout + - sso_patch_version not in cli_result.stdout block: - - name: "Apply patch {{ sso_rhn_ids[keycloak_version].latest_cp.v }} to server" + - name: "Apply patch {{ sso_patch_version }} to server" ansible.builtin.include_tasks: rhsso_cli.yml vars: query: "patch apply {{ patch_archive }}" @@ -78,10 +78,10 @@ - name: "Verify installed patch version" ansible.builtin.assert: that: - - sso_rhn_ids[keycloak_version].latest_cp.v not in cli_result.stdout + - sso_patch_version not in cli_result.stdout fail_msg: "Patch installation failed" success_msg: "Patch installation successful" - name: "Skipping patch" ansible.builtin.debug: - msg: "Latest cumulative patch {{ sso_rhn_ids[keycloak_version].latest_cp.v }} already installed, skipping patch installation." + msg: "Latest cumulative patch {{ sso_patch_version }} already installed, skipping patch installation." diff --git a/roles/keycloak/vars/main.yml b/roles/keycloak/vars/main.yml index 77f35ff..a634e6d 100644 --- a/roles/keycloak/vars/main.yml +++ b/roles/keycloak/vars/main.yml @@ -1,11 +1,5 @@ --- # internal variables below -sso_rhn_ids: - '7.5.0': # noqa vars_in_vars_files_have_valid_names - id: '101971' - latest_cp: - id: '103836' - v: '7.5.1' # locations keycloak_url: "http://{{ keycloak_host }}:{{ keycloak_http_port }}" From 007464d6b31fdd6955c29ad8265cb35a56e39b07 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 13 Dec 2022 15:38:59 +0100 Subject: [PATCH 115/554] Update keycloak to 19.0.3 --- molecule/default/prepare.yml | 2 +- roles/keycloak/README.md | 9 +++++---- roles/keycloak/defaults/main.yml | 4 ++-- roles/keycloak/meta/argument_specs.yml | 4 ++-- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/molecule/default/prepare.yml b/molecule/default/prepare.yml index 1d78e2d..c6c0752 100644 --- a/molecule/default/prepare.yml +++ b/molecule/default/prepare.yml @@ -17,4 +17,4 @@ vars: assets: - "{{ assets_server }}/sso/7.5.0/rh-sso-7.5.0-server-dist.zip" - - "{{ assets_server }}/sso/7.5.1/rh-sso-7.5.1-patch.zip" + - "{{ assets_server }}/sso/7.5.3/rh-sso-7.5.3-patch.zip" diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index 7b0bd23..7ba0207 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -28,6 +28,7 @@ Versions | RH-SSO VERSION | Release Date | Keycloak Version | EAP Version | Notes | |:---------------|:------------------|:-----------------|:------------|:----------------| |`7.5.0 GA` |September 20, 2021 |`15.0.2` | `7.4.0` |[Release Notes](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.5/html/release_notes/index)| +|`7.6.0 GA` |June 30, 2022 |`7.6.1 GA` |[Release Notes](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.6/html-single/release_notes/index)| Patching @@ -37,8 +38,8 @@ When variable `keycloak_rhsso_apply_patches` is `True` (default: `False`), the r | RH-SSO VERSION | Release Date | RH-SSO LATEST CP | Notes | |:---------------|:------------------|:-----------------|:----------------| -|`7.5.0 GA` |January 20, 2022 |`7.5.1 GA` |[Release Notes](https://access.redhat.com/articles/6646321)| - +|`7.5.0 GA` |January 20, 2022 |`7.5.3 GA` |[Release Notes](https://access.redhat.com/articles/6646321)| +|`7.6.0 GA` |November 11, 2022 |`7.6.1 GA` |[Release Notes](https://access.redhat.com/articles/6982711)| Role Defaults @@ -76,7 +77,7 @@ Role Defaults |:---------|:------------|:---------| |`keycloak_offline_install` | perform an offline install | `False`| |`keycloak_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| -|`keycloak_version`| keycloak.org package version | `15.0.2` | +|`keycloak_version`| keycloak.org package version | `19.0.3` | |`keycloak_dest`| Installation root path | `/opt/keycloak` | |`keycloak_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_version }}/{{ keycloak_archive }}` | |`keycloak_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` | @@ -86,7 +87,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_archive` | keycloak install archive filename | `keycloak-{{ keycloak_version }}.zip` | +|`keycloak_archive` | keycloak install archive filename | `keycloak-legacy-{{ keycloak_version }}.zip` | |`keycloak_download_url_9x` | Download URL for keycloak (deprecated) | `https://downloads.jboss.org/keycloak/{{ keycloak_version }}/{{ keycloak_archive }}` | |`keycloak_installdir` | Installation path | `{{ keycloak_dest }}/keycloak-{{ keycloak_version }}` | |`keycloak_jboss_home` | Installation work directory | `{{ keycloak_rhsso_installdir if keycloak_rhsso_enable else keycloak_installdir }}` | diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 7bb3bb8..3aa308c 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -1,7 +1,7 @@ --- ### Configuration specific to keycloak -keycloak_version: 15.0.2 -keycloak_archive: "keycloak-{{ keycloak_version }}.zip" +keycloak_version: 19.0.3 +keycloak_archive: "keycloak-legacy-{{ keycloak_version }}.zip" keycloak_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_version }}/{{ keycloak_archive }}" keycloak_download_url_9x: "https://downloads.jboss.org/keycloak/{{ keycloak_version }}/{{ keycloak_archive }}" keycloak_installdir: "{{ keycloak_dest }}/keycloak-{{ keycloak_version }}" diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 0a27aba..aa0db00 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -3,12 +3,12 @@ argument_specs: options: keycloak_version: # line 3 of keycloak/defaults/main.yml - default: "15.0.2" + default: "19.0.3" description: "keycloak.org package version" type: "str" keycloak_archive: # line 4 of keycloak/defaults/main.yml - default: "keycloak-{{ keycloak_version }}.zip" + default: "keycloak-legacy-{{ keycloak_version }}.zip" description: "keycloak install archive filename" type: "str" keycloak_configure_firewalld: From 699ab1a5c499eb3b73555b7bb6fe67f2872f2023 Mon Sep 17 00:00:00 2001 From: Romain Pelisse Date: Thu, 15 Dec 2022 11:52:27 +0100 Subject: [PATCH 116/554] allows user to switch no_log to True for debugging purpose --- roles/keycloak/defaults/main.yml | 4 +++- roles/keycloak/meta/argument_specs.yml | 8 ++++++-- roles/keycloak_realm/tasks/main.yml | 6 +++--- roles/keycloak_realm/tasks/manage_client_roles.yml | 2 +- roles/keycloak_realm/tasks/manage_user_roles.yml | 2 +- 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 7bb3bb8..c5fe7e8 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -2,7 +2,7 @@ ### Configuration specific to keycloak keycloak_version: 15.0.2 keycloak_archive: "keycloak-{{ keycloak_version }}.zip" -keycloak_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_version }}/{{ keycloak_archive }}" +keycloak_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_version }}/{{ keycloak_archive }}" keycloak_download_url_9x: "https://downloads.jboss.org/keycloak/{{ keycloak_version }}/{{ keycloak_archive }}" keycloak_installdir: "{{ keycloak_dest }}/keycloak-{{ keycloak_version }}" keycloak_offline_install: False @@ -83,3 +83,5 @@ keycloak_default_jdbc: mariadb: url: 'jdbc:mariadb://localhost:3306/keycloak' version: 2.7.4 +# role specific vars +keycloak_no_log: True diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 29ebce8..6efd70e 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -266,6 +266,10 @@ argument_specs: default: "Keycloak" description: "systemd description for keycloak" type: "str" + keycloak_no_log: + default: true + type: "bool" + description: "Changes default behavior for no_log for debugging purpose, do not change for production system." downstream: options: sso_version: @@ -275,11 +279,11 @@ argument_specs: sso_rhn_id: default: "{{ sso_rhn_ids[sso_version].id }}" description: "Customer Portal product ID for Red Hat SSO" - type: "str" + type: "str" sso_archive: default: "rh-sso-{{ sso_version }}-server-dist.zip" description: "Red Hat SSO install archive filename" - type: "str" + type: "str" sso_dest: default: "/opt/sso" description: "Root installation directory" diff --git a/roles/keycloak_realm/tasks/main.yml b/roles/keycloak_realm/tasks/main.yml index 1544a1e..85ee5f0 100644 --- a/roles/keycloak_realm/tasks/main.yml +++ b/roles/keycloak_realm/tasks/main.yml @@ -5,7 +5,7 @@ method: POST body: "client_id={{ keycloak_auth_client }}&username={{ keycloak_admin_user }}&password={{ keycloak_admin_password }}&grant_type=password" validate_certs: no - no_log: True + no_log: "{{ keycloak_no_log | default('True') }}" register: keycloak_auth_response until: keycloak_auth_response.status == 200 retries: 5 @@ -48,7 +48,7 @@ provider_type: "{{ item.provider_type | default(org.keycloak.storage.UserStorageProvider) }}" config: "{{ item.config }}" mappers: "{{ item.mappers | default(omit) }}" - no_log: True + no_log: "{{ keycloak_no_log | default('True') }}" register: create_user_federation_result loop: "{{ keycloak_user_federation | flatten }}" when: keycloak_user_federation is defined @@ -91,7 +91,7 @@ public_client: "{{ item.public_client | default(False) }}" protocol: "{{ item.protocol | default(omit) }}" state: present - no_log: True + no_log: "{{ keycloak_no_log | default('True') }}" register: create_client_result loop: "{{ keycloak_clients | flatten }}" when: (item.name is defined and item.client_id is defined) or (item.name is defined and item.id is defined) diff --git a/roles/keycloak_realm/tasks/manage_client_roles.yml b/roles/keycloak_realm/tasks/manage_client_roles.yml index 04cf2fa..6db30fa 100644 --- a/roles/keycloak_realm/tasks/manage_client_roles.yml +++ b/roles/keycloak_realm/tasks/manage_client_roles.yml @@ -10,4 +10,4 @@ auth_password: "{{ keycloak_admin_password }}" state: present loop: "{{ client.roles | flatten }}" - no_log: True + no_log: "{{ keycloak_no_log | default('True') }}" diff --git a/roles/keycloak_realm/tasks/manage_user_roles.yml b/roles/keycloak_realm/tasks/manage_user_roles.yml index e9d18b7..ff803a2 100644 --- a/roles/keycloak_realm/tasks/manage_user_roles.yml +++ b/roles/keycloak_realm/tasks/manage_user_roles.yml @@ -14,7 +14,7 @@ body: "client_id={{ keycloak_auth_client }}&username={{ keycloak_admin_user }}&password={{ keycloak_admin_password }}&grant_type=password" validate_certs: no register: keycloak_auth_response - no_log: True + no_log: "{{ keycloak_no_log | default('True') }}" until: keycloak_auth_response.status == 200 retries: 5 delay: 2 From 7c8db06378467f9d1d4cd1e5a82421403d5fc6bf Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 15 Dec 2022 14:29:42 +0100 Subject: [PATCH 117/554] set keycloak to 18.0.2, sso to 7.6.1 --- roles/keycloak/README.md | 6 +- roles/keycloak/defaults/main.yml | 2 +- roles/keycloak/meta/argument_specs.yml | 10 +- .../15.0.8/standalone-infinispan.xml.j2 | 761 ++++++++++++++++++ .../templates/15.0.8/standalone.xml.j2 | 658 +++++++++++++++ 5 files changed, 1428 insertions(+), 9 deletions(-) create mode 100644 roles/keycloak/templates/15.0.8/standalone-infinispan.xml.j2 create mode 100644 roles/keycloak/templates/15.0.8/standalone.xml.j2 diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index 7ba0207..5af0957 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -27,8 +27,8 @@ Versions | RH-SSO VERSION | Release Date | Keycloak Version | EAP Version | Notes | |:---------------|:------------------|:-----------------|:------------|:----------------| -|`7.5.0 GA` |September 20, 2021 |`15.0.2` | `7.4.0` |[Release Notes](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.5/html/release_notes/index)| -|`7.6.0 GA` |June 30, 2022 |`7.6.1 GA` |[Release Notes](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.6/html-single/release_notes/index)| +|`7.5.0 GA` |September 20, 2021 |`15.0.2` | `7.4.6` |[Release Notes](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.5/html/release_notes/index)| +|`7.6.0 GA` |June 30, 2022 |`18.0.3` | `7.4.6` |[Release Notes](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.6/html-single/release_notes/index)| Patching @@ -77,7 +77,7 @@ Role Defaults |:---------|:------------|:---------| |`keycloak_offline_install` | perform an offline install | `False`| |`keycloak_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| -|`keycloak_version`| keycloak.org package version | `19.0.3` | +|`keycloak_version`| keycloak.org package version | `18.0.2` | |`keycloak_dest`| Installation root path | `/opt/keycloak` | |`keycloak_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_version }}/{{ keycloak_archive }}` | |`keycloak_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` | diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 3aa308c..9160876 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -1,6 +1,6 @@ --- ### Configuration specific to keycloak -keycloak_version: 19.0.3 +keycloak_version: 18.0.2 keycloak_archive: "keycloak-legacy-{{ keycloak_version }}.zip" keycloak_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_version }}/{{ keycloak_archive }}" keycloak_download_url_9x: "https://downloads.jboss.org/keycloak/{{ keycloak_version }}/{{ keycloak_archive }}" diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index aa0db00..8151ed1 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -3,7 +3,7 @@ argument_specs: options: keycloak_version: # line 3 of keycloak/defaults/main.yml - default: "19.0.3" + default: "18.0.2" description: "keycloak.org package version" type: "str" keycloak_archive: @@ -269,11 +269,11 @@ argument_specs: downstream: options: sso_version: - default: "7.5.0" + default: "7.6.0" description: "Red Hat Single Sign-On version" type: "str" sso_rhn_id: - default: "101971" + default: "104539" description: "Customer Portal product ID for Red Hat SSO" type: "str" sso_archive: @@ -317,7 +317,7 @@ argument_specs: description: "systemd description for Red Hat Single Sign-On" type: "str" sso_patch_version: - default: "7.5.3" + default: "7.6.1" description: "Red Hat Single Sign-On latest cumulative patch version" type: "str" sso_patch_bundle: @@ -325,6 +325,6 @@ argument_specs: description: "Red Hat SSO patch archive filename" type: "str" sso_patch_rhn_id: - default: "104738" + default: "104867" description: "Customer Portal product ID for Red Hat SSO latest cumulative patch" type: "str" diff --git a/roles/keycloak/templates/15.0.8/standalone-infinispan.xml.j2 b/roles/keycloak/templates/15.0.8/standalone-infinispan.xml.j2 new file mode 100644 index 0000000..4198b83 --- /dev/null +++ b/roles/keycloak/templates/15.0.8/standalone-infinispan.xml.j2 @@ -0,0 +1,761 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE + h2 + + sa + sa + + + +{% if keycloak_jdbc[keycloak_jdbc_engine].enabled %} + {{ keycloak_jdbc[keycloak_jdbc_engine].connection_url }} + {{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_name }} + + 20 + + + {{ keycloak_jdbc[keycloak_jdbc_engine].db_user }} + {{ keycloak_jdbc[keycloak_jdbc_engine].db_password }} + +{% else %} + jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE + h2 + + sa + sa + +{% endif %} + + +{% if keycloak_jdbc[keycloak_jdbc_engine].enabled %} + + {{ keycloak_jdbc[keycloak_jdbc_engine].driver_class }} + {{ keycloak_jdbc[keycloak_jdbc_engine].xa_datasource_class }} + +{% endif %} + + org.h2.jdbcx.JdbcDataSource + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{% for cachename in [ "sessions", "offlineSessions", "clientSessions", "offlineClientSessions", "loginFailures", "actionTokens", "authenticationSessions" ] %} + + + true + org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory + false + {{ keycloak_remotecache.username }} + {{ keycloak_remotecache.password }} + {{ keycloak_remotecache.realm | default('default') }} + {{ keycloak_remotecache.server_name }} + {{ keycloak_remotecache.sasl_mechanism }} + {{ keycloak_remotecache.use_ssl }} + {{ keycloak_remotecache.trust_store_path }} + JKS + {{ keycloak_remotecache.trust_store_password }} + TOPOLOGY_AWARE + + +{% endfor %} + + + true + org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory + false + {{ keycloak_remotecache.username }} + {{ keycloak_remotecache.password }} + {{ keycloak_remotecache.realm | default('default') }} + {{ keycloak_remotecache.server_name }} + {{ keycloak_remotecache.sasl_mechanism }} + {{ keycloak_remotecache.use_ssl }} + {{ keycloak_remotecache.trust_store_path }} + JKS + {{ keycloak_remotecache.trust_store_password }} + TOPOLOGY_AWARE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{% if keycloak_jdbc[keycloak_jdbc_engine].enabled %} + + java:jboss/datasources/KeycloakDS + {{ keycloak_jdbc[keycloak_jdbc_engine].initialize_db }} + INSERT INTO JGROUPSPING (own_addr, cluster_name, ping_data) values (?, ?, ?) + DELETE FROM JGROUPSPING WHERE own_addr=? AND cluster_name=? + SELECT ping_data FROM JGROUPSPING WHERE cluster_name=? + +{% endif %} + + + + + + + + + 30000 + + + + + + + + + + + + + + + + auth + + + classpath:${jboss.home.dir}/providers/* + + + master + 900 + + 2592000 + true + true + ${jboss.home.dir}/themes + +{% if keycloak_ha_enabled %} + + + + + + + +{% endif %} + + + + + + + + + + + + jpa + + + basic + + + + + + + + + + + + + + + + + + + default + + + + + + + + ${keycloak.jta.lookup.provider:jboss} + + + + + + + + + + + ${keycloak.x509cert.lookup.provider:default} + + + + default + + + + + + + + + + + + + + +{% if keycloak_modcluster.enabled %} + + + + + + + +{% endif %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{% if ansible_default_ipv4 is defined %} + +{% else %} + +{% endif %} + + + + + + + + + + + + + + + + + +{% if keycloak_modcluster.enabled %} + + + +{% endif %} + + + + + diff --git a/roles/keycloak/templates/15.0.8/standalone.xml.j2 b/roles/keycloak/templates/15.0.8/standalone.xml.j2 new file mode 100644 index 0000000..e2f6a76 --- /dev/null +++ b/roles/keycloak/templates/15.0.8/standalone.xml.j2 @@ -0,0 +1,658 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE + h2 + + sa + sa + + + +{% if keycloak_jdbc[keycloak_jdbc_engine].enabled %} + {{ keycloak_jdbc[keycloak_jdbc_engine].connection_url }} + {{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_name }} + + 20 + + + {{ keycloak_jdbc[keycloak_jdbc_engine].db_user }} + {{ keycloak_jdbc[keycloak_jdbc_engine].db_password }} + +{% else %} + jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE + h2 + + sa + sa + +{% endif %} + + +{% if keycloak_jdbc[keycloak_jdbc_engine].enabled %} + + {{ keycloak_jdbc[keycloak_jdbc_engine].driver_class }} + {{ keycloak_jdbc[keycloak_jdbc_engine].xa_datasource_class }} + +{% endif %} + + org.h2.jdbcx.JdbcDataSource + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + auth + + + classpath:${jboss.home.dir}/providers/* + + + master + 900 + + 2592000 + true + true + ${jboss.home.dir}/themes + +{% if keycloak_ha_enabled %} + + + + + + + +{% endif %} + + + + + + + + + + + + jpa + + + basic + + + + + + + + + + + + + + + + + + + default + + + + + + + + ${keycloak.jta.lookup.provider:jboss} + + + + + + + + + + + ${keycloak.x509cert.lookup.provider:default} + + + + default + + + + + + + + + + + + + + +{% if keycloak_modcluster.enabled %} + + + + + + + +{% endif %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{% if keycloak_modcluster.enabled %} + + + +{% endif %} + + From 34cab23abe723c5cbec9a8dbfa4013989410c64d Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 15 Dec 2022 15:32:33 +0100 Subject: [PATCH 118/554] update configuration templates --- molecule/overridexml/templates/custom.xml.j2 | 62 +-------------- .../templates/standalone-infinispan.xml.j2 | 76 ++++--------------- roles/keycloak/templates/standalone.xml.j2 | 76 ++++--------------- 3 files changed, 30 insertions(+), 184 deletions(-) diff --git a/molecule/overridexml/templates/custom.xml.j2 b/molecule/overridexml/templates/custom.xml.j2 index a59561a..3a72633 100644 --- a/molecule/overridexml/templates/custom.xml.j2 +++ b/molecule/overridexml/templates/custom.xml.j2 @@ -15,7 +15,6 @@ - @@ -30,31 +29,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - @@ -69,7 +43,7 @@ - + @@ -513,41 +487,9 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index 4198b83..5e3e48a 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -16,7 +16,6 @@ - @@ -31,31 +30,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - @@ -70,8 +44,8 @@ - - + + @@ -317,6 +291,13 @@ + + + + + + + @@ -644,41 +625,9 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -701,7 +650,7 @@ - + @@ -715,6 +664,9 @@ + + + diff --git a/roles/keycloak/templates/standalone.xml.j2 b/roles/keycloak/templates/standalone.xml.j2 index e2f6a76..a3c06bd 100644 --- a/roles/keycloak/templates/standalone.xml.j2 +++ b/roles/keycloak/templates/standalone.xml.j2 @@ -15,7 +15,6 @@ - @@ -30,31 +29,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - @@ -69,8 +43,8 @@ - - + + @@ -304,6 +278,13 @@ + + + + + + + @@ -557,41 +538,9 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -614,7 +563,7 @@ - + @@ -627,6 +576,9 @@ + + + From d7829f77df7c616317e2c79f11a2ad7840ca39e6 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 15 Dec 2022 15:47:12 +0100 Subject: [PATCH 119/554] update sso version in molecule tests --- molecule/default/prepare.yml | 4 ++-- molecule/overridexml/prepare.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/molecule/default/prepare.yml b/molecule/default/prepare.yml index c6c0752..437f3e2 100644 --- a/molecule/default/prepare.yml +++ b/molecule/default/prepare.yml @@ -16,5 +16,5 @@ ansible.builtin.include_tasks: ../prepare.yml vars: assets: - - "{{ assets_server }}/sso/7.5.0/rh-sso-7.5.0-server-dist.zip" - - "{{ assets_server }}/sso/7.5.3/rh-sso-7.5.3-patch.zip" + - "{{ assets_server }}/sso/7.6.0/rh-sso-7.6.0-server-dist.zip" + - "{{ assets_server }}/sso/7.6.1/rh-sso-7.6.1-patch.zip" diff --git a/molecule/overridexml/prepare.yml b/molecule/overridexml/prepare.yml index 3fc1104..f9b2406 100644 --- a/molecule/overridexml/prepare.yml +++ b/molecule/overridexml/prepare.yml @@ -6,4 +6,4 @@ ansible.builtin.include_tasks: ../prepare.yml vars: assets: - - "{{ assets_server }}/sso/7.5.0/rh-sso-7.5.0-server-dist.zip" + - "{{ assets_server }}/sso/7.6.0/rh-sso-7.6.0-server-dist.zip" From 55633177184ed8583d244d103949e02f689bbba9 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 16 Dec 2022 16:28:11 +0100 Subject: [PATCH 120/554] ci: update overridexml molecule override template --- molecule/overridexml/templates/custom.xml.j2 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/molecule/overridexml/templates/custom.xml.j2 b/molecule/overridexml/templates/custom.xml.j2 index 3a72633..fcf0cda 100644 --- a/molecule/overridexml/templates/custom.xml.j2 +++ b/molecule/overridexml/templates/custom.xml.j2 @@ -252,6 +252,13 @@ + + + + + + + From 320f167beaa6e280bc2af3b88c188d14560a82d1 Mon Sep 17 00:00:00 2001 From: Romain Pelisse Date: Mon, 19 Dec 2022 08:56:25 +0100 Subject: [PATCH 121/554] molecule: centralize requirements --- molecule/default/molecule.yml | 6 +++--- molecule/overridexml/molecule.yml | 6 +++--- molecule/overridexml/requirements.yml | 9 --------- molecule/quarkus/molecule.yml | 4 ++-- molecule/quarkus/requirements.yml | 9 --------- molecule/{default => }/requirements.yml | 0 6 files changed, 8 insertions(+), 26 deletions(-) delete mode 100644 molecule/overridexml/requirements.yml delete mode 100644 molecule/quarkus/requirements.yml rename molecule/{default => }/requirements.yml (100%) diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml index ea8ad61..6f3b9c7 100644 --- a/molecule/default/molecule.yml +++ b/molecule/default/molecule.yml @@ -1,7 +1,7 @@ --- dependency: name: shell - command: ansible-galaxy collection install -r molecule/default/requirements.yml -p $HOME/.ansible/collections --force-with-deps + command: ansible-galaxy collection install -r molecule/requirements.yml -p $HOME/.ansible/collections --force-with-deps driver: name: docker lint: | @@ -16,7 +16,7 @@ platforms: port_bindings: - "8080/tcp" - "8443/tcp" - - "8009/tcp" + - "8009/tcp" provisioner: name: ansible config_options: @@ -33,7 +33,7 @@ provisioner: localhost: ansible_python_interpreter: "{{ ansible_playbook_python }}" env: - ANSIBLE_FORCE_COLOR: "true" + ANSIBLE_FORCE_COLOR: "true" verifier: name: ansible scenario: diff --git a/molecule/overridexml/molecule.yml b/molecule/overridexml/molecule.yml index ea8ad61..6f3b9c7 100644 --- a/molecule/overridexml/molecule.yml +++ b/molecule/overridexml/molecule.yml @@ -1,7 +1,7 @@ --- dependency: name: shell - command: ansible-galaxy collection install -r molecule/default/requirements.yml -p $HOME/.ansible/collections --force-with-deps + command: ansible-galaxy collection install -r molecule/requirements.yml -p $HOME/.ansible/collections --force-with-deps driver: name: docker lint: | @@ -16,7 +16,7 @@ platforms: port_bindings: - "8080/tcp" - "8443/tcp" - - "8009/tcp" + - "8009/tcp" provisioner: name: ansible config_options: @@ -33,7 +33,7 @@ provisioner: localhost: ansible_python_interpreter: "{{ ansible_playbook_python }}" env: - ANSIBLE_FORCE_COLOR: "true" + ANSIBLE_FORCE_COLOR: "true" verifier: name: ansible scenario: diff --git a/molecule/overridexml/requirements.yml b/molecule/overridexml/requirements.yml deleted file mode 100644 index 0aed172..0000000 --- a/molecule/overridexml/requirements.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -collections: - - name: middleware_automation.redhat_csp_download - version: ">=1.2.1" - - name: community.general - - name: ansible.posix - - name: community.docker - version: ">=1.9.1" - diff --git a/molecule/quarkus/molecule.yml b/molecule/quarkus/molecule.yml index 785de19..3895a53 100644 --- a/molecule/quarkus/molecule.yml +++ b/molecule/quarkus/molecule.yml @@ -1,7 +1,7 @@ --- dependency: name: shell - command: ansible-galaxy collection install -r molecule/default/requirements.yml -p $HOME/.ansible/collections --force-with-deps + command: ansible-galaxy collection install -r molecule/requirements.yml -p $HOME/.ansible/collections --force-with-deps driver: name: docker lint: | @@ -35,7 +35,7 @@ provisioner: localhost: ansible_python_interpreter: "{{ ansible_playbook_python }}" env: - ANSIBLE_FORCE_COLOR: "true" + ANSIBLE_FORCE_COLOR: "true" verifier: name: ansible scenario: diff --git a/molecule/quarkus/requirements.yml b/molecule/quarkus/requirements.yml deleted file mode 100644 index 0aed172..0000000 --- a/molecule/quarkus/requirements.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -collections: - - name: middleware_automation.redhat_csp_download - version: ">=1.2.1" - - name: community.general - - name: ansible.posix - - name: community.docker - version: ">=1.9.1" - diff --git a/molecule/default/requirements.yml b/molecule/requirements.yml similarity index 100% rename from molecule/default/requirements.yml rename to molecule/requirements.yml From ab3247fc3b72c9ba72d4b15a38244804f6a6fd96 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 19 Dec 2022 12:08:05 +0100 Subject: [PATCH 122/554] docs: update resources --- docs/_gh_include/header.inc | 13 +++++++++++++ docs/index.rst | 15 +++++++++++---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/docs/_gh_include/header.inc b/docs/_gh_include/header.inc index f9cd101..7c5103b 100644 --- a/docs/_gh_include/header.inc +++ b/docs/_gh_include/header.inc @@ -21,6 +21,19 @@ +
    diff --git a/docs/index.rst b/docs/index.rst index d9bfa5f..6d8670c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -25,8 +25,15 @@ Welcome to Keycloak Collection documentation Changelog -Indices and tables -================== +.. toctree:: + :maxdepth: 2 + :caption: Middleware collections -* :ref:`genindex` -* :ref:`search` + Infinispan / Red Hat Data Grid + Keycloak / Red Hat Single Sign-On + Wildfly / Red Hat JBoss EAP + Tomcat / Red Hat JWS + ActiveMQ / Red Hat AMQ Broker + Kafka / Red Hat AMQ Streams + Red Hat CSP Download + JCliff From 2a219222bc36a387bc3a48a6992ed8f10c8e20f0 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 19 Dec 2022 22:23:45 +0100 Subject: [PATCH 123/554] Add missing ejb application-security-domain --- roles/keycloak/templates/standalone-infinispan.xml.j2 | 3 +++ roles/keycloak/templates/standalone.xml.j2 | 3 +++ 2 files changed, 6 insertions(+) diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index 5e3e48a..bed7b9b 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -218,6 +218,9 @@ + + + diff --git a/roles/keycloak/templates/standalone.xml.j2 b/roles/keycloak/templates/standalone.xml.j2 index a3c06bd..ec4a9ed 100644 --- a/roles/keycloak/templates/standalone.xml.j2 +++ b/roles/keycloak/templates/standalone.xml.j2 @@ -205,6 +205,9 @@ + + + From cd1c2ae3e77235458a0d31c9c83ba2394731ef82 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 19 Dec 2022 23:09:43 +0100 Subject: [PATCH 124/554] keycloak: switch http-invoker from security-realm to http-authentication-factory --- roles/keycloak/templates/standalone-infinispan.xml.j2 | 2 +- roles/keycloak/templates/standalone.xml.j2 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index bed7b9b..bd71b75 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -656,7 +656,7 @@ - + diff --git a/roles/keycloak/templates/standalone.xml.j2 b/roles/keycloak/templates/standalone.xml.j2 index ec4a9ed..15c141a 100644 --- a/roles/keycloak/templates/standalone.xml.j2 +++ b/roles/keycloak/templates/standalone.xml.j2 @@ -569,7 +569,7 @@ - + From 842cb7bf238e12bea11acbf0f2d2d80b166326ce Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 19 Dec 2022 23:32:35 +0100 Subject: [PATCH 125/554] molecule: update overridden template --- molecule/overridexml/templates/custom.xml.j2 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/molecule/overridexml/templates/custom.xml.j2 b/molecule/overridexml/templates/custom.xml.j2 index fcf0cda..8686d77 100644 --- a/molecule/overridexml/templates/custom.xml.j2 +++ b/molecule/overridexml/templates/custom.xml.j2 @@ -179,6 +179,9 @@ + + + @@ -520,7 +523,7 @@ - + From 46d5af90ba690886894faa4730f9d625ed2ca08a Mon Sep 17 00:00:00 2001 From: Romain Pelisse Date: Fri, 16 Dec 2022 15:14:44 +0100 Subject: [PATCH 126/554] Allow overrides for service start retries and delay --- roles/keycloak/defaults/main.yml | 4 +++- roles/keycloak/meta/argument_specs.yml | 8 ++++++++ roles/keycloak/tasks/restart_keycloak.yml | 4 ++-- roles/keycloak/tasks/start_keycloak.yml | 4 ++-- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 4543f82..88ff001 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -2,7 +2,7 @@ ### Configuration specific to keycloak keycloak_version: 18.0.2 keycloak_archive: "keycloak-legacy-{{ keycloak_version }}.zip" -keycloak_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_version }}/{{ keycloak_archive }}" +keycloak_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_version }}/{{ keycloak_archive }}" keycloak_download_url_9x: "https://downloads.jboss.org/keycloak/{{ keycloak_version }}/{{ keycloak_archive }}" keycloak_installdir: "{{ keycloak_dest }}/keycloak-{{ keycloak_version }}" keycloak_offline_install: False @@ -21,6 +21,8 @@ keycloak_service_group: keycloak keycloak_service_pidfile: "/run/keycloak.pid" keycloak_service_name: keycloak keycloak_service_desc: Keycloak +keycloak_service_start_delay: 10 +keycloak_service_start_retries: 25 keycloak_configure_firewalld: False diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 4d36f4c..f58b1d4 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -266,6 +266,14 @@ argument_specs: default: "Keycloak" description: "systemd description for keycloak" type: "str" + keycloak_service_start_delay: + default: "10" + description: "Expected delay in ms before the service is expected to be available after start." + type: "int" + keycloak_service_start_retries: + default: "25" + description: "How many time should Ansible retry to connect to the service after it was started, before failing." + type: "int" keycloak_no_log: default: true type: "bool" diff --git a/roles/keycloak/tasks/restart_keycloak.yml b/roles/keycloak/tasks/restart_keycloak.yml index d77ee58..a0ae41f 100644 --- a/roles/keycloak/tasks/restart_keycloak.yml +++ b/roles/keycloak/tasks/restart_keycloak.yml @@ -15,8 +15,8 @@ until: keycloak_status.status == 200 delegate_to: "{{ ansible_play_hosts | first }}" run_once: True - retries: 25 - delay: 10 + retries: "{{ keycloak_service_start_retries }}" + delay: "{{ keycloak_service_start_delay }}" - name: "Restart and enable {{ keycloak.service_name }} service" ansible.builtin.systemd: diff --git a/roles/keycloak/tasks/start_keycloak.yml b/roles/keycloak/tasks/start_keycloak.yml index bdf42f9..524df80 100644 --- a/roles/keycloak/tasks/start_keycloak.yml +++ b/roles/keycloak/tasks/start_keycloak.yml @@ -11,5 +11,5 @@ url: "{{ keycloak.health_url }}" register: keycloak_status until: keycloak_status.status == 200 - retries: 25 - delay: 10 \ No newline at end of file + retries: "{{ keycloak_service_start_retries }}" + delay: "{{ keycloak_service_start_delay }}" From 9196b234b6de449b816060ef4fb9e1e7117c680a Mon Sep 17 00:00:00 2001 From: Romain Pelisse Date: Thu, 29 Dec 2022 12:38:45 +0100 Subject: [PATCH 127/554] Add missing 'java' keywords to galaxy.yml --- galaxy.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/galaxy.yml b/galaxy.yml index 0084428..a25df7b 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -20,6 +20,7 @@ tags: - security - infrastructure - authentication + - java dependencies: "middleware_automation.redhat_csp_download": ">=1.2.1" "community.general": ">=5.6.0" From ae95d69435ff013980faf732cec089326ba23e24 Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 9 Jan 2023 08:36:24 +0000 Subject: [PATCH 128/554] Update changelog for release 1.1.0 --- CHANGELOG.rst | 21 +++++++++++++++++++++ changelogs/changelog.yaml | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f67ba17..8db778c 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,27 @@ middleware_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v1.1.0 +====== + +Minor Changes +------------- + +- Update keycloak to 18.0.2 - sso to 7.6.1 `#46 `_ +- Variable ``keycloak_no_log`` controls ansible ``no_log`` parameter (for debugging purposes) `#47 `_ +- Variables to override service start retries and delay `#51 `_ +- keycloak_quarkus: variable to enable development mode `#45 `_ + +Breaking Changes / Porting Guide +-------------------------------- + +- Rename variables from ``infinispan_`` prefix to ``keycloak_infinispan_`` `#42 `_ + +Bugfixes +-------- + +- keycloak_quarkus: fix /var/log/keycloak symlink to keycloak log directory `#44 `_ + v1.0.7 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index bde3179..786b2e2 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -96,3 +96,37 @@ releases: - 38.yaml - 39.yaml release_date: '2022-07-06' + 1.1.0: + changes: + breaking_changes: + - 'Rename variables from ``infinispan_`` prefix to ``keycloak_infinispan_`` + `#42 `_ + + ' + bugfixes: + - 'keycloak_quarkus: fix /var/log/keycloak symlink to keycloak log directory + `#44 `_ + + ' + minor_changes: + - 'Update keycloak to 18.0.2 - sso to 7.6.1 `#46 `_ + + ' + - 'Variable ``keycloak_no_log`` controls ansible ``no_log`` parameter (for debugging + purposes) `#47 `_ + + ' + - 'Variables to override service start retries and delay `#51 `_ + + ' + - 'keycloak_quarkus: variable to enable development mode `#45 `_ + + ' + fragments: + - 42.yaml + - 44.yaml + - 45.yaml + - 46.yaml + - 47.yaml + - 51.yaml + release_date: '2023-01-09' From 808b944f1942fac0afd42af08109ad0cd66e6f79 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 9 Jan 2023 09:46:47 +0100 Subject: [PATCH 129/554] Bump to v1.1.1 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index a25df7b..8871cdf 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.1.0" +version: "1.1.1" readme: README.md authors: - Romain Pelisse From 5cdaa7aabbdc69ac43f5400ac834c38d383bf77b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bo=C5=BEo=20Barun?= Date: Thu, 26 Jan 2023 15:27:57 +0100 Subject: [PATCH 130/554] Update keycloak.conf.j2 The documentation states that the path is relative to the /conf directory, which is true. So if one changes the contents of this file it would have no effect because the path would be non-existent. To make things worse, there would be no obvious error stating this and the configuration would be loaded from the defaults. --- roles/keycloak_quarkus/templates/keycloak.conf.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index c02dbae..bd9f5bf 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -30,7 +30,7 @@ hostname-path={{ keycloak_quarkus_http_relative_path }} # Cluster {% if keycloak_quarkus_ha_enabled %} cache=ispn -cache-config-file=conf/cache-ispn.xml +cache-config-file=cache-ispn.xml cache-stack=tcp {% endif %} From 7abdd83ea4974bbdd7918b152f4cf7064fc8e301 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 3 Mar 2023 10:54:50 +0100 Subject: [PATCH 131/554] ci: linter --- .ansible-lint | 1 + playbooks/keycloak.yml | 4 +--- playbooks/keycloak_quarkus.yml | 4 +--- playbooks/keycloak_realm.yml | 4 +--- playbooks/rhsso.yml | 3 --- roles/keycloak/tasks/install.yml | 4 ++-- roles/keycloak/vars/main.yml | 2 +- roles/keycloak_quarkus/meta/main.yml | 2 -- roles/keycloak_realm/tasks/main.yml | 2 +- 9 files changed, 8 insertions(+), 18 deletions(-) diff --git a/.ansible-lint b/.ansible-lint index e28ef42..eaa75d0 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -29,6 +29,7 @@ warn_list: - name[template] - name[casing] - fqcn[action] + - schema[meta] skip_list: - vars_should_not_be_used diff --git a/playbooks/keycloak.yml b/playbooks/keycloak.yml index 2b222a5..6c7ca4a 100644 --- a/playbooks/keycloak.yml +++ b/playbooks/keycloak.yml @@ -3,7 +3,5 @@ hosts: all vars: keycloak_admin_password: "remembertochangeme" - collections: - - middleware_automation.keycloak roles: - - keycloak + - middleware_automation.keycloak.keycloak diff --git a/playbooks/keycloak_quarkus.yml b/playbooks/keycloak_quarkus.yml index b9bbbba..9e1d3f9 100644 --- a/playbooks/keycloak_quarkus.yml +++ b/playbooks/keycloak_quarkus.yml @@ -9,7 +9,5 @@ keycloak_quarkus_https_enabled: True keycloak_quarkus_key_file: conf/key.pem keycloak_quarkus_cert_file: conf/cert.pem - collections: - - middleware_automation.keycloak roles: - - keycloak_quarkus + - middleware_automation.keycloak.keycloak_quarkus diff --git a/playbooks/keycloak_realm.yml b/playbooks/keycloak_realm.yml index 1efc4f7..ba3d8ea 100644 --- a/playbooks/keycloak_realm.yml +++ b/playbooks/keycloak_realm.yml @@ -22,7 +22,5 @@ - client: TestClient1 role: TestClient1User realm: "{{ keycloak_realm }}" - collections: - - middleware_automation.keycloak roles: - - keycloak_realm + - middleware_automation.keycloak.keycloak_realm diff --git a/playbooks/rhsso.yml b/playbooks/rhsso.yml index e34334f..c8dbc44 100644 --- a/playbooks/rhsso.yml +++ b/playbooks/rhsso.yml @@ -4,9 +4,6 @@ vars: keycloak_admin_password: "remembertochangeme" sso_enable: True - collections: - - middleware_automation.redhat_csp_download - - middleware_automation.keycloak roles: - middleware_automation.redhat_csp_download.redhat_csp_download - middleware_automation.keycloak.keycloak diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index af14c75..e60e0aa 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -17,6 +17,7 @@ register: existing_deploy - name: Stop and restart if existing deployment exists and install forced + when: existing_deploy.stat.exists and keycloak_force_install | bool block: - name: "Stop the old {{ keycloak.service_name }} service" become: yes @@ -29,7 +30,6 @@ ansible.builtin.file: path: "{{ keycloak_jboss_home }}" state: absent - when: existing_deploy.stat.exists and keycloak_force_install|bool - name: Check for an existing deployment after possible forced removal become: yes @@ -185,7 +185,7 @@ mode: 0640 notify: - restart keycloak - when: not keycloak_remotecache.enabled or keycloak_config_override_template|length > 0 + when: not keycloak_remotecache.enabled or keycloak_config_override_template | length > 0 - name: "Deploy {{ keycloak.service_name }} config with remote cache store to {{ keycloak_config_path_to_standalone_xml }}" become: yes diff --git a/roles/keycloak/vars/main.yml b/roles/keycloak/vars/main.yml index a634e6d..0a1ad7a 100644 --- a/roles/keycloak/vars/main.yml +++ b/roles/keycloak/vars/main.yml @@ -46,7 +46,7 @@ keycloak_jdbc: driver_jar_filename: "mariadb-java-client-{{ keycloak_jdbc_driver_version }}.jar" driver_jar_url: "https://repo1.maven.org/maven2/org/mariadb/jdbc/mariadb-java-client/{{ keycloak_jdbc_driver_version }}/mariadb-java-client-{{ keycloak_jdbc_driver_version }}.jar" connection_url: "{{ keycloak_jdbc_url }}" - db_user: "{{ keycloak_db_user }}" + db_user: "{{ keycloak_db_user }}" db_password: "{{ keycloak_db_pass }}" initialize_db: > CREATE TABLE IF NOT EXISTS JGROUPSPING ( diff --git a/roles/keycloak_quarkus/meta/main.yml b/roles/keycloak_quarkus/meta/main.yml index fd6a110..911a545 100644 --- a/roles/keycloak_quarkus/meta/main.yml +++ b/roles/keycloak_quarkus/meta/main.yml @@ -1,6 +1,4 @@ --- -collections: - galaxy_info: role_name: keycloak_quarkus namespace: middleware_automation diff --git a/roles/keycloak_realm/tasks/main.yml b/roles/keycloak_realm/tasks/main.yml index 85ee5f0..45ac34b 100644 --- a/roles/keycloak_realm/tasks/main.yml +++ b/roles/keycloak_realm/tasks/main.yml @@ -27,7 +27,7 @@ ansible.builtin.uri: url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms" method: POST - body: "{{ lookup('template','realm.json.j2') }}" + body: "{{ lookup('template', 'realm.json.j2') }}" validate_certs: no body_format: json headers: From 821c256f047cb16864b8db9a6e9e9a94ef57868f Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 7 Mar 2023 07:05:59 +0000 Subject: [PATCH 132/554] Update changelog for release 1.1.1 --- CHANGELOG.rst | 8 ++++++++ changelogs/changelog.yaml | 10 ++++++++++ 2 files changed, 18 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 8db778c..564b3c2 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,14 @@ middleware_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v1.1.1 +====== + +Bugfixes +-------- + +- keycloak-quarkus: fix ``cache-config-file`` path in keycloak.conf.j2 template `#53 `_ + v1.1.0 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 786b2e2..154fa4a 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -130,3 +130,13 @@ releases: - 47.yaml - 51.yaml release_date: '2023-01-09' + 1.1.1: + changes: + bugfixes: + - 'keycloak-quarkus: fix ``cache-config-file`` path in keycloak.conf.j2 template + `#53 `_ + + ' + fragments: + - 53.yaml + release_date: '2023-03-07' From 2959cb3cf0b936c6e62faaaed723cec42700ff8d Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 7 Mar 2023 08:10:42 +0100 Subject: [PATCH 133/554] Bump to 1.2.0 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 8871cdf..7e54cdc 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.1.1" +version: "1.2.0" readme: README.md authors: - Romain Pelisse From f980d4d1e1dc2e911bfaaa245937acfdde268746 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 7 Mar 2023 12:21:50 +0100 Subject: [PATCH 134/554] Provide config for multiple modcluster proxies --- roles/keycloak/README.md | 4 +++- roles/keycloak/defaults/main.yml | 6 +++++- roles/keycloak/meta/argument_specs.yml | 12 ++++++++++++ roles/keycloak/tasks/main.yml | 1 - .../keycloak/templates/standalone-infinispan.xml.j2 | 8 +++++--- roles/keycloak/templates/standalone.xml.j2 | 8 +++++--- roles/keycloak/vars/main.yml | 2 +- 7 files changed, 31 insertions(+), 10 deletions(-) diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index 5af0957..0104d75 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -116,7 +116,9 @@ The following variables are _required_ only when `keycloak_ha_enabled` is True: | Variable | Description | Default | |:---------|:------------|:---------| -|`keycloak_modcluster_url` | URL for the modcluster reverse proxy | `localhost` | +|`keycloak_modcluster_url` | _deprecated_ Host for the modcluster reverse proxy | `localhost` | +|`keycloak_modcluster_port` | _deprecated_ Port for the modcluster reverse proxy | `6666` | +|`keycloak_modcluster_urls` | List of {host,port} dicts for the modcluster reverse proxies | `[ { localhost:6666 } ]` | |`keycloak_jdbc_engine` | backend database engine when db is enabled: [ postgres, mariadb ] | `postgres` | |`keycloak_infinispan_url` | URL for the infinispan remote-cache server | `localhost:11122` | |`keycloak_infinispan_user` | username for connecting to infinispan | `supervisor` | diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 88ff001..67414cf 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -54,8 +54,12 @@ keycloak_auth_client: admin-cli keycloak_force_install: False -### mod_cluster reverse proxy +### mod_cluster reverse proxy list keycloak_modcluster_url: localhost +keycloak_modcluster_port: 6666 +keycloak_modcluster_urls: + - host: "{{ keycloak_modcluster_url }}" + port: "{{ keycloak_modcluster_port }}" ### keycloak frontend url keycloak_frontend_url: http://localhost:8080/auth diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index f58b1d4..74115e8 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -178,6 +178,18 @@ argument_specs: default: "localhost" description: "URL for the modcluster reverse proxy" type: "str" + removed_in_version: "1.4.0" + removed_from_collection: "middleware_automation.keycloak" + keycloak_modcluster_port: + default: 6666 + description: "Port for the modcluster reverse proxy" + type: "int" + removed_in_version: "1.4.0" + removed_from_collection: "middleware_automation.keycloak" + keycloak_modcluster_urls: + default: "[ { host: 'localhost', port: 6666 } ]" + description: "List of modproxy node URLs in the format { host, port } for the modcluster reverse proxy" + type: "list" keycloak_frontend_url: # line 59 of keycloak/defaults/main.yml default: "http://localhost" diff --git a/roles/keycloak/tasks/main.yml b/roles/keycloak/tasks/main.yml index 316c033..32aca04 100644 --- a/roles/keycloak/tasks/main.yml +++ b/roles/keycloak/tasks/main.yml @@ -1,6 +1,5 @@ --- # tasks file for keycloak - - name: Check prerequisites ansible.builtin.include_tasks: prereqs.yml tags: diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index bd71b75..eabae24 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -617,7 +617,7 @@ {% if keycloak_modcluster.enabled %} - + @@ -705,9 +705,11 @@ {% if keycloak_modcluster.enabled %} - - + {% for modcluster in keycloak_modcluster.reverse_proxy_urls %} + + + {% endfor %} {% endif %} diff --git a/roles/keycloak/templates/standalone.xml.j2 b/roles/keycloak/templates/standalone.xml.j2 index 15c141a..812990b 100644 --- a/roles/keycloak/templates/standalone.xml.j2 +++ b/roles/keycloak/templates/standalone.xml.j2 @@ -530,7 +530,7 @@ {% if keycloak_modcluster.enabled %} - + @@ -605,9 +605,11 @@ {% if keycloak_modcluster.enabled %} - - + {% for modcluster in keycloak_modcluster.reverse_proxy_urls %} + + + {% endfor %} {% endif %} diff --git a/roles/keycloak/vars/main.yml b/roles/keycloak/vars/main.yml index 0a1ad7a..52598bf 100644 --- a/roles/keycloak/vars/main.yml +++ b/roles/keycloak/vars/main.yml @@ -60,7 +60,7 @@ keycloak_jdbc: # reverse proxy mod_cluster keycloak_modcluster: enabled: "{{ keycloak_ha_enabled }}" - reverse_proxy_url: "{{ keycloak_modcluster_url }}" + reverse_proxy_urls: "{{ keycloak_modcluster_urls }}" frontend_url: "{{ keycloak_frontend_url }}" # infinispan From 0d2624cfffa14174c3df03909184034054c41b11 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 7 Mar 2023 12:30:29 +0100 Subject: [PATCH 135/554] linter: role arg_specs dont support removed_in_version and removed_from_collection --- roles/keycloak/meta/argument_specs.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 74115e8..2413d48 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -178,14 +178,10 @@ argument_specs: default: "localhost" description: "URL for the modcluster reverse proxy" type: "str" - removed_in_version: "1.4.0" - removed_from_collection: "middleware_automation.keycloak" keycloak_modcluster_port: default: 6666 description: "Port for the modcluster reverse proxy" type: "int" - removed_in_version: "1.4.0" - removed_from_collection: "middleware_automation.keycloak" keycloak_modcluster_urls: default: "[ { host: 'localhost', port: 6666 } ]" description: "List of modproxy node URLs in the format { host, port } for the modcluster reverse proxy" From 41eed509ea5e937a21dba259863a0e9434a4e47c Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 7 Mar 2023 12:51:16 +0100 Subject: [PATCH 136/554] add modcluster testing to default scenario --- molecule/default/converge.yml | 6 ++++++ roles/keycloak/README.md | 3 ++- roles/keycloak/defaults/main.yml | 1 + roles/keycloak/meta/argument_specs.yml | 6 +++++- roles/keycloak/vars/main.yml | 2 +- 5 files changed, 15 insertions(+), 3 deletions(-) diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index 7e73d70..ac59d57 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -4,6 +4,12 @@ vars: keycloak_admin_password: "remembertochangeme" keycloak_jvm_package: java-11-openjdk-headless + keycloak_modcluster_enabled: True + keycloak_modcluster_urls: + - host: myhost1 + port: 16667 + - host: myhost2 + port: 16668 roles: - role: keycloak tasks: diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index 0104d75..53b8969 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -115,7 +115,8 @@ The following are a set of _required_ variables for the role: The following variables are _required_ only when `keycloak_ha_enabled` is True: | Variable | Description | Default | -|:---------|:------------|:---------| +|:---------|:------------|:--------| +|`keycloak_modcluster_enabled`| Enable configuration for modcluster subsystem | `True` if `keycloak_ha_enabled` is True, else `False` | |`keycloak_modcluster_url` | _deprecated_ Host for the modcluster reverse proxy | `localhost` | |`keycloak_modcluster_port` | _deprecated_ Port for the modcluster reverse proxy | `6666` | |`keycloak_modcluster_urls` | List of {host,port} dicts for the modcluster reverse proxies | `[ { localhost:6666 } ]` | diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 67414cf..06320a1 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -55,6 +55,7 @@ keycloak_auth_client: admin-cli keycloak_force_install: False ### mod_cluster reverse proxy list +keycloak_modcluster_enabled: "{{ True if keycloak_ha_enabled else False }}" keycloak_modcluster_url: localhost keycloak_modcluster_port: 6666 keycloak_modcluster_urls: diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 2413d48..1f6f10f 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -152,7 +152,7 @@ argument_specs: # line 48 of keycloak/defaults/main.yml default: "{{ True if keycloak_ha_enabled else False }}" description: "Enable auto configuration for database backend" - type: "str" + type: "bool" keycloak_admin_user: # line 51 of keycloak/defaults/main.yml default: "admin" @@ -173,6 +173,10 @@ argument_specs: default: false description: "Remove pre-existing versions of service" type: "bool" + keycloak_modcluster_enabled: + default: "{{ True if keycloak_ha_enabled else False }}" + description: "Enable configuration for modcluster subsystem" + type: "bool" keycloak_modcluster_url: # line 58 of keycloak/defaults/main.yml default: "localhost" diff --git a/roles/keycloak/vars/main.yml b/roles/keycloak/vars/main.yml index 52598bf..026839e 100644 --- a/roles/keycloak/vars/main.yml +++ b/roles/keycloak/vars/main.yml @@ -59,7 +59,7 @@ keycloak_jdbc: # reverse proxy mod_cluster keycloak_modcluster: - enabled: "{{ keycloak_ha_enabled }}" + enabled: "{{ keycloak_ha_enabled or keycloak_modcluster_enabled }}" reverse_proxy_urls: "{{ keycloak_modcluster_urls }}" frontend_url: "{{ keycloak_frontend_url }}" From d27d15efa903f0f8a099b03d621b100add5d0dcc Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 7 Mar 2023 14:16:44 +0100 Subject: [PATCH 137/554] modcluster proxies string wants space-separated list --- roles/keycloak/templates/standalone-infinispan.xml.j2 | 6 +++--- roles/keycloak/templates/standalone.xml.j2 | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index eabae24..91eefa8 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -617,7 +617,7 @@ {% if keycloak_modcluster.enabled %} - + @@ -705,11 +705,11 @@ {% if keycloak_modcluster.enabled %} - {% for modcluster in keycloak_modcluster.reverse_proxy_urls %} +{% for modcluster in keycloak_modcluster.reverse_proxy_urls %} - {% endfor %} +{% endfor %} {% endif %} diff --git a/roles/keycloak/templates/standalone.xml.j2 b/roles/keycloak/templates/standalone.xml.j2 index 812990b..438a0da 100644 --- a/roles/keycloak/templates/standalone.xml.j2 +++ b/roles/keycloak/templates/standalone.xml.j2 @@ -530,7 +530,7 @@ {% if keycloak_modcluster.enabled %} - + @@ -604,12 +604,12 @@ -{% if keycloak_modcluster.enabled %} - {% for modcluster in keycloak_modcluster.reverse_proxy_urls %} +{% if keycloak_modcluster.enabled %} +{% for modcluster in keycloak_modcluster.reverse_proxy_urls %} - {% endfor %} +{% endfor %} {% endif %} From 00ae0877324fac424c88ddf9cee24f567b9c088d Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 7 Mar 2023 17:07:27 +0100 Subject: [PATCH 138/554] drop community.general from tasks/meta --- galaxy.yml | 1 - requirements.yml | 1 - roles/keycloak_realm/tasks/main.yml | 4 ++-- roles/keycloak_realm/tasks/manage_client_roles.yml | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/galaxy.yml b/galaxy.yml index 7e54cdc..29d1d00 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -23,7 +23,6 @@ tags: - java dependencies: "middleware_automation.redhat_csp_download": ">=1.2.1" - "community.general": ">=5.6.0" "ansible.posix": ">=1.4.0" repository: https://github.com/ansible-middleware/keycloak documentation: https://ansible-middleware.github.io/keycloak diff --git a/requirements.yml b/requirements.yml index 4eab0c7..dae1d95 100644 --- a/requirements.yml +++ b/requirements.yml @@ -2,5 +2,4 @@ collections: - name: middleware_automation.redhat_csp_download version: ">=1.2.1" - - name: community.general - name: ansible.posix diff --git a/roles/keycloak_realm/tasks/main.yml b/roles/keycloak_realm/tasks/main.yml index 45ac34b..9233080 100644 --- a/roles/keycloak_realm/tasks/main.yml +++ b/roles/keycloak_realm/tasks/main.yml @@ -36,7 +36,7 @@ when: keycloak_realm_exists.status == 404 - name: Create user federation - community.general.keycloak_user_federation: + middleware_automation.keycloak.keycloak_user_federation: auth_keycloak_url: "{{ keycloak_url }}{{ keycloak_context }}" auth_realm: "{{ keycloak_auth_realm }}" auth_username: "{{ keycloak_admin_user }}" @@ -65,7 +65,7 @@ label: "{{ item.name | default('unnamed client') }}" - name: Create or update a Keycloak client - community.general.keycloak_client: + middleware_automation.keycloak.keycloak_client: auth_client_id: "{{ keycloak_auth_client }}" auth_keycloak_url: "{{ keycloak_url }}{{ keycloak_context }}" auth_realm: "{{ keycloak_auth_realm }}" diff --git a/roles/keycloak_realm/tasks/manage_client_roles.yml b/roles/keycloak_realm/tasks/manage_client_roles.yml index 6db30fa..4a261b1 100644 --- a/roles/keycloak_realm/tasks/manage_client_roles.yml +++ b/roles/keycloak_realm/tasks/manage_client_roles.yml @@ -1,5 +1,5 @@ - name: Create client roles - community.general.keycloak_role: + middleware_automation.keycloak.keycloak_role: name: "{{ item }}" realm: "{{ client.realm }}" client_id: "{{ client.name }}" From 65e4b3b8135eb8319e570845597ae6b5f710ec61 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 7 Mar 2023 17:56:05 +0100 Subject: [PATCH 139/554] add hardforked modules --- .../identity/keycloak/keycloak.py | 2192 +++++++++++++++++ plugins/modules/keycloak_client.py | 984 ++++++++ plugins/modules/keycloak_role.py | 374 +++ plugins/modules/keycloak_user_federation.py | 1021 ++++++++ 4 files changed, 4571 insertions(+) create mode 100644 plugins/module_utils/identity/keycloak/keycloak.py create mode 100644 plugins/modules/keycloak_client.py create mode 100644 plugins/modules/keycloak_role.py create mode 100644 plugins/modules/keycloak_user_federation.py diff --git a/plugins/module_utils/identity/keycloak/keycloak.py b/plugins/module_utils/identity/keycloak/keycloak.py new file mode 100644 index 0000000..15b6657 --- /dev/null +++ b/plugins/module_utils/identity/keycloak/keycloak.py @@ -0,0 +1,2192 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2017, Eike Frost +# BSD 2-Clause license (see LICENSES/BSD-2-Clause.txt) +# SPDX-License-Identifier: BSD-2-Clause + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +import json +import traceback + +from ansible.module_utils.urls import open_url +from ansible.module_utils.six.moves.urllib.parse import urlencode, quote +from ansible.module_utils.six.moves.urllib.error import HTTPError +from ansible.module_utils.common.text.converters import to_native, to_text + +URL_REALM_INFO = "{url}/realms/{realm}" +URL_REALMS = "{url}/admin/realms" +URL_REALM = "{url}/admin/realms/{realm}" + +URL_TOKEN = "{url}/realms/{realm}/protocol/openid-connect/token" +URL_CLIENT = "{url}/admin/realms/{realm}/clients/{id}" +URL_CLIENTS = "{url}/admin/realms/{realm}/clients" + +URL_CLIENT_ROLES = "{url}/admin/realms/{realm}/clients/{id}/roles" +URL_CLIENT_ROLE = "{url}/admin/realms/{realm}/clients/{id}/roles/{name}" +URL_CLIENT_ROLE_COMPOSITES = "{url}/admin/realms/{realm}/clients/{id}/roles/{name}/composites" + +URL_REALM_ROLES = "{url}/admin/realms/{realm}/roles" +URL_REALM_ROLE = "{url}/admin/realms/{realm}/roles/{name}" +URL_REALM_ROLEMAPPINGS = "{url}/admin/realms/{realm}/users/{id}/role-mappings/realm" +URL_REALM_ROLEMAPPINGS_AVAILABLE = "{url}/admin/realms/{realm}/users/{id}/role-mappings/realm/available" +URL_REALM_ROLEMAPPINGS_COMPOSITE = "{url}/admin/realms/{realm}/users/{id}/role-mappings/realm/composite" +URL_REALM_ROLE_COMPOSITES = "{url}/admin/realms/{realm}/roles/{name}/composites" + +URL_ROLES_BY_ID = "{url}/admin/realms/{realm}/roles-by-id/{id}" +URL_ROLES_BY_ID_COMPOSITES_CLIENTS = "{url}/admin/realms/{realm}/roles-by-id/{id}/composites/clients/{cid}" +URL_ROLES_BY_ID_COMPOSITES = "{url}/admin/realms/{realm}/roles-by-id/{id}/composites" + +URL_CLIENTTEMPLATE = "{url}/admin/realms/{realm}/client-templates/{id}" +URL_CLIENTTEMPLATES = "{url}/admin/realms/{realm}/client-templates" +URL_GROUPS = "{url}/admin/realms/{realm}/groups" +URL_GROUP = "{url}/admin/realms/{realm}/groups/{groupid}" +URL_GROUP_CHILDREN = "{url}/admin/realms/{realm}/groups/{groupid}/children" + +URL_CLIENTSCOPES = "{url}/admin/realms/{realm}/client-scopes" +URL_CLIENTSCOPE = "{url}/admin/realms/{realm}/client-scopes/{id}" +URL_CLIENTSCOPE_PROTOCOLMAPPERS = "{url}/admin/realms/{realm}/client-scopes/{id}/protocol-mappers/models" +URL_CLIENTSCOPE_PROTOCOLMAPPER = "{url}/admin/realms/{realm}/client-scopes/{id}/protocol-mappers/models/{mapper_id}" + +URL_CLIENT_GROUP_ROLEMAPPINGS = "{url}/admin/realms/{realm}/groups/{id}/role-mappings/clients/{client}" +URL_CLIENT_GROUP_ROLEMAPPINGS_AVAILABLE = "{url}/admin/realms/{realm}/groups/{id}/role-mappings/clients/{client}/available" +URL_CLIENT_GROUP_ROLEMAPPINGS_COMPOSITE = "{url}/admin/realms/{realm}/groups/{id}/role-mappings/clients/{client}/composite" + +URL_USERS = "{url}/admin/realms/{realm}/users" +URL_CLIENT_SERVICE_ACCOUNT_USER = "{url}/admin/realms/{realm}/clients/{id}/service-account-user" +URL_CLIENT_USER_ROLEMAPPINGS = "{url}/admin/realms/{realm}/users/{id}/role-mappings/clients/{client}" +URL_CLIENT_USER_ROLEMAPPINGS_AVAILABLE = "{url}/admin/realms/{realm}/users/{id}/role-mappings/clients/{client}/available" +URL_CLIENT_USER_ROLEMAPPINGS_COMPOSITE = "{url}/admin/realms/{realm}/users/{id}/role-mappings/clients/{client}/composite" + +URL_CLIENTSECRET = "{url}/admin/realms/{realm}/clients/{id}/client-secret" + +URL_AUTHENTICATION_FLOWS = "{url}/admin/realms/{realm}/authentication/flows" +URL_AUTHENTICATION_FLOW = "{url}/admin/realms/{realm}/authentication/flows/{id}" +URL_AUTHENTICATION_FLOW_COPY = "{url}/admin/realms/{realm}/authentication/flows/{copyfrom}/copy" +URL_AUTHENTICATION_FLOW_EXECUTIONS = "{url}/admin/realms/{realm}/authentication/flows/{flowalias}/executions" +URL_AUTHENTICATION_FLOW_EXECUTIONS_EXECUTION = "{url}/admin/realms/{realm}/authentication/flows/{flowalias}/executions/execution" +URL_AUTHENTICATION_FLOW_EXECUTIONS_FLOW = "{url}/admin/realms/{realm}/authentication/flows/{flowalias}/executions/flow" +URL_AUTHENTICATION_EXECUTION_CONFIG = "{url}/admin/realms/{realm}/authentication/executions/{id}/config" +URL_AUTHENTICATION_EXECUTION_RAISE_PRIORITY = "{url}/admin/realms/{realm}/authentication/executions/{id}/raise-priority" +URL_AUTHENTICATION_EXECUTION_LOWER_PRIORITY = "{url}/admin/realms/{realm}/authentication/executions/{id}/lower-priority" +URL_AUTHENTICATION_CONFIG = "{url}/admin/realms/{realm}/authentication/config/{id}" + +URL_IDENTITY_PROVIDERS = "{url}/admin/realms/{realm}/identity-provider/instances" +URL_IDENTITY_PROVIDER = "{url}/admin/realms/{realm}/identity-provider/instances/{alias}" +URL_IDENTITY_PROVIDER_MAPPERS = "{url}/admin/realms/{realm}/identity-provider/instances/{alias}/mappers" +URL_IDENTITY_PROVIDER_MAPPER = "{url}/admin/realms/{realm}/identity-provider/instances/{alias}/mappers/{id}" + +URL_COMPONENTS = "{url}/admin/realms/{realm}/components" +URL_COMPONENT = "{url}/admin/realms/{realm}/components/{id}" + + +def keycloak_argument_spec(): + """ + Returns argument_spec of options common to keycloak_*-modules + + :return: argument_spec dict + """ + return dict( + auth_keycloak_url=dict(type='str', aliases=['url'], required=True, no_log=False), + auth_client_id=dict(type='str', default='admin-cli'), + auth_realm=dict(type='str'), + auth_client_secret=dict(type='str', default=None, no_log=True), + auth_username=dict(type='str', aliases=['username']), + auth_password=dict(type='str', aliases=['password'], no_log=True), + validate_certs=dict(type='bool', default=True), + connection_timeout=dict(type='int', default=10), + token=dict(type='str', no_log=True), + http_agent=dict(type='str', default='Ansible'), + ) + + +def camel(words): + return words.split('_')[0] + ''.join(x.capitalize() or '_' for x in words.split('_')[1:]) + + +class KeycloakError(Exception): + pass + + +def get_token(module_params): + """ Obtains connection header with token for the authentication, + token already given or obtained from credentials + :param module_params: parameters of the module + :return: connection header + """ + token = module_params.get('token') + base_url = module_params.get('auth_keycloak_url') + http_agent = module_params.get('http_agent') + + if not base_url.lower().startswith(('http', 'https')): + raise KeycloakError("auth_url '%s' should either start with 'http' or 'https'." % base_url) + + if token is None: + base_url = module_params.get('auth_keycloak_url') + validate_certs = module_params.get('validate_certs') + auth_realm = module_params.get('auth_realm') + client_id = module_params.get('auth_client_id') + auth_username = module_params.get('auth_username') + auth_password = module_params.get('auth_password') + client_secret = module_params.get('auth_client_secret') + connection_timeout = module_params.get('connection_timeout') + auth_url = URL_TOKEN.format(url=base_url, realm=auth_realm) + temp_payload = { + 'grant_type': 'password', + 'client_id': client_id, + 'client_secret': client_secret, + 'username': auth_username, + 'password': auth_password, + } + # Remove empty items, for instance missing client_secret + payload = dict( + (k, v) for k, v in temp_payload.items() if v is not None) + try: + r = json.loads(to_native(open_url(auth_url, method='POST', + validate_certs=validate_certs, http_agent=http_agent, timeout=connection_timeout, + data=urlencode(payload)).read())) + except ValueError as e: + raise KeycloakError( + 'API returned invalid JSON when trying to obtain access token from %s: %s' + % (auth_url, str(e))) + except Exception as e: + raise KeycloakError('Could not obtain access token from %s: %s' + % (auth_url, str(e))) + + try: + token = r['access_token'] + except KeyError: + raise KeycloakError( + 'Could not obtain access token from %s' % auth_url) + return { + 'Authorization': 'Bearer ' + token, + 'Content-Type': 'application/json' + } + + +def is_struct_included(struct1, struct2, exclude=None): + """ + This function compare if the first parameter structure is included in the second. + The function use every elements of struct1 and validates they are present in the struct2 structure. + The two structure does not need to be equals for that function to return true. + Each elements are compared recursively. + :param struct1: + type: + dict for the initial call, can be dict, list, bool, int or str for recursive calls + description: + reference structure + :param struct2: + type: + dict for the initial call, can be dict, list, bool, int or str for recursive calls + description: + structure to compare with first parameter. + :param exclude: + type: + list + description: + Key to exclude from the comparison. + default: None + :return: + type: + bool + description: + Return True if all element of dict 1 are present in dict 2, return false otherwise. + """ + if isinstance(struct1, list) and isinstance(struct2, list): + for item1 in struct1: + if isinstance(item1, (list, dict)): + for item2 in struct2: + if not is_struct_included(item1, item2, exclude): + return False + else: + if item1 not in struct2: + return False + return True + elif isinstance(struct1, dict) and isinstance(struct2, dict): + try: + for key in struct1: + if not (exclude and key in exclude): + if not is_struct_included(struct1[key], struct2[key], exclude): + return False + return True + except KeyError: + return False + elif isinstance(struct1, bool) and isinstance(struct2, bool): + return struct1 == struct2 + else: + return to_text(struct1, 'utf-8') == to_text(struct2, 'utf-8') + + +class KeycloakAPI(object): + """ Keycloak API access; Keycloak uses OAuth 2.0 to protect its API, an access token for which + is obtained through OpenID connect + """ + def __init__(self, module, connection_header): + self.module = module + self.baseurl = self.module.params.get('auth_keycloak_url') + self.validate_certs = self.module.params.get('validate_certs') + self.connection_timeout = self.module.params.get('connection_timeout') + self.restheaders = connection_header + self.http_agent = self.module.params.get('http_agent') + + def get_realm_info_by_id(self, realm='master'): + """ Obtain realm public info by id + + :param realm: realm id + :return: dict of real, representation or None if none matching exist + """ + realm_info_url = URL_REALM_INFO.format(url=self.baseurl, realm=realm) + + try: + return json.loads(to_native(open_url(realm_info_url, method='GET', http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + + except HTTPError as e: + if e.code == 404: + return None + else: + self.module.fail_json(msg='Could not obtain realm %s: %s' % (realm, str(e)), + exception=traceback.format_exc()) + except ValueError as e: + self.module.fail_json(msg='API returned incorrect JSON when trying to obtain realm %s: %s' % (realm, str(e)), + exception=traceback.format_exc()) + except Exception as e: + self.module.fail_json(msg='Could not obtain realm %s: %s' % (realm, str(e)), + exception=traceback.format_exc()) + + def get_realm_by_id(self, realm='master'): + """ Obtain realm representation by id + + :param realm: realm id + :return: dict of real, representation or None if none matching exist + """ + realm_url = URL_REALM.format(url=self.baseurl, realm=realm) + + try: + return json.loads(to_native(open_url(realm_url, method='GET', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + + except HTTPError as e: + if e.code == 404: + return None + else: + self.module.fail_json(msg='Could not obtain realm %s: %s' % (realm, str(e)), + exception=traceback.format_exc()) + except ValueError as e: + self.module.fail_json(msg='API returned incorrect JSON when trying to obtain realm %s: %s' % (realm, str(e)), + exception=traceback.format_exc()) + except Exception as e: + self.module.fail_json(msg='Could not obtain realm %s: %s' % (realm, str(e)), + exception=traceback.format_exc()) + + def update_realm(self, realmrep, realm="master"): + """ Update an existing realm + :param realmrep: corresponding (partial/full) realm representation with updates + :param realm: realm to be updated in Keycloak + :return: HTTPResponse object on success + """ + realm_url = URL_REALM.format(url=self.baseurl, realm=realm) + + try: + return open_url(realm_url, method='PUT', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(realmrep), validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg='Could not update realm %s: %s' % (realm, str(e)), + exception=traceback.format_exc()) + + def create_realm(self, realmrep): + """ Create a realm in keycloak + :param realmrep: Realm representation of realm to be created. + :return: HTTPResponse object on success + """ + realm_url = URL_REALMS.format(url=self.baseurl) + + try: + return open_url(realm_url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(realmrep), validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg='Could not create realm %s: %s' % (realmrep['id'], str(e)), + exception=traceback.format_exc()) + + def delete_realm(self, realm="master"): + """ Delete a realm from Keycloak + + :param realm: realm to be deleted + :return: HTTPResponse object on success + """ + realm_url = URL_REALM.format(url=self.baseurl, realm=realm) + + try: + return open_url(realm_url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg='Could not delete realm %s: %s' % (realm, str(e)), + exception=traceback.format_exc()) + + def get_clients(self, realm='master', filter=None): + """ Obtains client representations for clients in a realm + + :param realm: realm to be queried + :param filter: if defined, only the client with clientId specified in the filter is returned + :return: list of dicts of client representations + """ + clientlist_url = URL_CLIENTS.format(url=self.baseurl, realm=realm) + if filter is not None: + clientlist_url += '?clientId=%s' % filter + + try: + return json.loads(to_native(open_url(clientlist_url, http_agent=self.http_agent, method='GET', headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except ValueError as e: + self.module.fail_json(msg='API returned incorrect JSON when trying to obtain list of clients for realm %s: %s' + % (realm, str(e))) + except Exception as e: + self.module.fail_json(msg='Could not obtain list of clients for realm %s: %s' + % (realm, str(e))) + + def get_client_by_clientid(self, client_id, realm='master'): + """ Get client representation by clientId + :param client_id: The clientId to be queried + :param realm: realm from which to obtain the client representation + :return: dict with a client representation or None if none matching exist + """ + r = self.get_clients(realm=realm, filter=client_id) + if len(r) > 0: + return r[0] + else: + return None + + def get_client_by_id(self, id, realm='master'): + """ Obtain client representation by id + + :param id: id (not clientId) of client to be queried + :param realm: client from this realm + :return: dict of client representation or None if none matching exist + """ + client_url = URL_CLIENT.format(url=self.baseurl, realm=realm, id=id) + + try: + return json.loads(to_native(open_url(client_url, method='GET', http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + + except HTTPError as e: + if e.code == 404: + return None + else: + self.module.fail_json(msg='Could not obtain client %s for realm %s: %s' + % (id, realm, str(e))) + except ValueError as e: + self.module.fail_json(msg='API returned incorrect JSON when trying to obtain client %s for realm %s: %s' + % (id, realm, str(e))) + except Exception as e: + self.module.fail_json(msg='Could not obtain client %s for realm %s: %s' + % (id, realm, str(e))) + + def get_client_id(self, client_id, realm='master'): + """ Obtain id of client by client_id + + :param client_id: client_id of client to be queried + :param realm: client template from this realm + :return: id of client (usually a UUID) + """ + result = self.get_client_by_clientid(client_id, realm) + if isinstance(result, dict) and 'id' in result: + return result['id'] + else: + return None + + def update_client(self, id, clientrep, realm="master"): + """ Update an existing client + :param id: id (not clientId) of client to be updated in Keycloak + :param clientrep: corresponding (partial/full) client representation with updates + :param realm: realm the client is in + :return: HTTPResponse object on success + """ + client_url = URL_CLIENT.format(url=self.baseurl, realm=realm, id=id) + + try: + return open_url(client_url, method='PUT', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(clientrep), validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg='Could not update client %s in realm %s: %s' + % (id, realm, str(e))) + + def create_client(self, clientrep, realm="master"): + """ Create a client in keycloak + :param clientrep: Client representation of client to be created. Must at least contain field clientId. + :param realm: realm for client to be created. + :return: HTTPResponse object on success + """ + client_url = URL_CLIENTS.format(url=self.baseurl, realm=realm) + + try: + return open_url(client_url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(clientrep), validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg='Could not create client %s in realm %s: %s' + % (clientrep['clientId'], realm, str(e))) + + def delete_client(self, id, realm="master"): + """ Delete a client from Keycloak + + :param id: id (not clientId) of client to be deleted + :param realm: realm of client to be deleted + :return: HTTPResponse object on success + """ + client_url = URL_CLIENT.format(url=self.baseurl, realm=realm, id=id) + + try: + return open_url(client_url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg='Could not delete client %s in realm %s: %s' + % (id, realm, str(e))) + + def get_client_roles_by_id(self, cid, realm="master"): + """ Fetch the roles of the a client on the Keycloak server. + + :param cid: ID of the client from which to obtain the rolemappings. + :param realm: Realm from which to obtain the rolemappings. + :return: The rollemappings of specified group and client of the realm (default "master"). + """ + client_roles_url = URL_CLIENT_ROLES.format(url=self.baseurl, realm=realm, id=cid) + try: + return json.loads(to_native(open_url(client_roles_url, method="GET", http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except Exception as e: + self.module.fail_json(msg="Could not fetch rolemappings for client %s in realm %s: %s" + % (cid, realm, str(e))) + + def get_client_role_id_by_name(self, cid, name, realm="master"): + """ Get the role ID of a client. + + :param cid: ID of the client from which to obtain the rolemappings. + :param name: Name of the role. + :param realm: Realm from which to obtain the rolemappings. + :return: The ID of the role, None if not found. + """ + rolemappings = self.get_client_roles_by_id(cid, realm=realm) + for role in rolemappings: + if name == role['name']: + return role['id'] + return None + + def get_client_group_rolemapping_by_id(self, gid, cid, rid, realm='master'): + """ Obtain client representation by id + + :param gid: ID of the group from which to obtain the rolemappings. + :param cid: ID of the client from which to obtain the rolemappings. + :param rid: ID of the role. + :param realm: client from this realm + :return: dict of rolemapping representation or None if none matching exist + """ + rolemappings_url = URL_CLIENT_GROUP_ROLEMAPPINGS.format(url=self.baseurl, realm=realm, id=gid, client=cid) + try: + rolemappings = json.loads(to_native(open_url(rolemappings_url, method="GET", http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + for role in rolemappings: + if rid == role['id']: + return role + except Exception as e: + self.module.fail_json(msg="Could not fetch rolemappings for client %s in group %s, realm %s: %s" + % (cid, gid, realm, str(e))) + return None + + def get_client_group_available_rolemappings(self, gid, cid, realm="master"): + """ Fetch the available role of a client in a specified goup on the Keycloak server. + + :param gid: ID of the group from which to obtain the rolemappings. + :param cid: ID of the client from which to obtain the rolemappings. + :param realm: Realm from which to obtain the rolemappings. + :return: The rollemappings of specified group and client of the realm (default "master"). + """ + available_rolemappings_url = URL_CLIENT_GROUP_ROLEMAPPINGS_AVAILABLE.format(url=self.baseurl, realm=realm, id=gid, client=cid) + try: + return json.loads(to_native(open_url(available_rolemappings_url, method="GET", http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except Exception as e: + self.module.fail_json(msg="Could not fetch available rolemappings for client %s in group %s, realm %s: %s" + % (cid, gid, realm, str(e))) + + def get_client_group_composite_rolemappings(self, gid, cid, realm="master"): + """ Fetch the composite role of a client in a specified group on the Keycloak server. + + :param gid: ID of the group from which to obtain the rolemappings. + :param cid: ID of the client from which to obtain the rolemappings. + :param realm: Realm from which to obtain the rolemappings. + :return: The rollemappings of specified group and client of the realm (default "master"). + """ + composite_rolemappings_url = URL_CLIENT_GROUP_ROLEMAPPINGS_COMPOSITE.format(url=self.baseurl, realm=realm, id=gid, client=cid) + try: + return json.loads(to_native(open_url(composite_rolemappings_url, method="GET", http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except Exception as e: + self.module.fail_json(msg="Could not fetch available rolemappings for client %s in group %s, realm %s: %s" + % (cid, gid, realm, str(e))) + + def get_role_by_id(self, rid, realm="master"): + """ Fetch a role by its id on the Keycloak server. + + :param rid: ID of the role. + :param realm: Realm from which to obtain the rolemappings. + :return: The role. + """ + client_roles_url = URL_ROLES_BY_ID.format(url=self.baseurl, realm=realm, id=rid) + try: + return json.loads(to_native(open_url(client_roles_url, method="GET", http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except Exception as e: + self.module.fail_json(msg="Could not fetch role for id %s in realm %s: %s" + % (rid, realm, str(e))) + + def get_client_roles_by_id_composite_rolemappings(self, rid, cid, realm="master"): + """ Fetch a role by its id on the Keycloak server. + + :param rid: ID of the composite role. + :param cid: ID of the client from which to obtain the rolemappings. + :param realm: Realm from which to obtain the rolemappings. + :return: The role. + """ + client_roles_url = URL_ROLES_BY_ID_COMPOSITES_CLIENTS.format(url=self.baseurl, realm=realm, id=rid, cid=cid) + try: + return json.loads(to_native(open_url(client_roles_url, method="GET", http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except Exception as e: + self.module.fail_json(msg="Could not fetch role for id %s and cid %s in realm %s: %s" + % (rid, cid, realm, str(e))) + + def add_client_roles_by_id_composite_rolemapping(self, rid, roles_rep, realm="master"): + """ Assign roles to composite role + + :param rid: ID of the composite role. + :param roles_rep: Representation of the roles to assign. + :param realm: Realm from which to obtain the rolemappings. + :return: None. + """ + available_rolemappings_url = URL_ROLES_BY_ID_COMPOSITES.format(url=self.baseurl, realm=realm, id=rid) + try: + open_url(available_rolemappings_url, method="POST", http_agent=self.http_agent, headers=self.restheaders, data=json.dumps(roles_rep), + validate_certs=self.validate_certs, timeout=self.connection_timeout) + except Exception as e: + self.module.fail_json(msg="Could not assign roles to composite role %s and realm %s: %s" + % (rid, realm, str(e))) + + def add_group_rolemapping(self, gid, cid, role_rep, realm="master"): + """ Fetch the composite role of a client in a specified goup on the Keycloak server. + + :param gid: ID of the group from which to obtain the rolemappings. + :param cid: ID of the client from which to obtain the rolemappings. + :param role_rep: Representation of the role to assign. + :param realm: Realm from which to obtain the rolemappings. + :return: None. + """ + available_rolemappings_url = URL_CLIENT_GROUP_ROLEMAPPINGS.format(url=self.baseurl, realm=realm, id=gid, client=cid) + try: + open_url(available_rolemappings_url, method="POST", http_agent=self.http_agent, headers=self.restheaders, data=json.dumps(role_rep), + validate_certs=self.validate_certs, timeout=self.connection_timeout) + except Exception as e: + self.module.fail_json(msg="Could not fetch available rolemappings for client %s in group %s, realm %s: %s" + % (cid, gid, realm, str(e))) + + def delete_group_rolemapping(self, gid, cid, role_rep, realm="master"): + """ Delete the rolemapping of a client in a specified group on the Keycloak server. + + :param gid: ID of the group from which to obtain the rolemappings. + :param cid: ID of the client from which to obtain the rolemappings. + :param role_rep: Representation of the role to assign. + :param realm: Realm from which to obtain the rolemappings. + :return: None. + """ + available_rolemappings_url = URL_CLIENT_GROUP_ROLEMAPPINGS.format(url=self.baseurl, realm=realm, id=gid, client=cid) + try: + open_url(available_rolemappings_url, method="DELETE", http_agent=self.http_agent, headers=self.restheaders, data=json.dumps(role_rep), + validate_certs=self.validate_certs, timeout=self.connection_timeout) + except Exception as e: + self.module.fail_json(msg="Could not delete available rolemappings for client %s in group %s, realm %s: %s" + % (cid, gid, realm, str(e))) + + def get_client_user_rolemapping_by_id(self, uid, cid, rid, realm='master'): + """ Obtain client representation by id + + :param uid: ID of the user from which to obtain the rolemappings. + :param cid: ID of the client from which to obtain the rolemappings. + :param rid: ID of the role. + :param realm: client from this realm + :return: dict of rolemapping representation or None if none matching exist + """ + rolemappings_url = URL_CLIENT_USER_ROLEMAPPINGS.format(url=self.baseurl, realm=realm, id=uid, client=cid) + try: + rolemappings = json.loads(to_native(open_url(rolemappings_url, method="GET", http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + for role in rolemappings: + if rid == role['id']: + return role + except Exception as e: + self.module.fail_json(msg="Could not fetch rolemappings for client %s and user %s, realm %s: %s" + % (cid, uid, realm, str(e))) + return None + + def get_client_user_available_rolemappings(self, uid, cid, realm="master"): + """ Fetch the available role of a client for a specified user on the Keycloak server. + + :param uid: ID of the user from which to obtain the rolemappings. + :param cid: ID of the client from which to obtain the rolemappings. + :param realm: Realm from which to obtain the rolemappings. + :return: The effective rollemappings of specified client and user of the realm (default "master"). + """ + available_rolemappings_url = URL_CLIENT_USER_ROLEMAPPINGS_AVAILABLE.format(url=self.baseurl, realm=realm, id=uid, client=cid) + try: + return json.loads(to_native(open_url(available_rolemappings_url, method="GET", http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except Exception as e: + self.module.fail_json(msg="Could not fetch effective rolemappings for client %s and user %s, realm %s: %s" + % (cid, uid, realm, str(e))) + + def get_client_user_composite_rolemappings(self, uid, cid, realm="master"): + """ Fetch the composite role of a client for a specified user on the Keycloak server. + + :param uid: ID of the user from which to obtain the rolemappings. + :param cid: ID of the client from which to obtain the rolemappings. + :param realm: Realm from which to obtain the rolemappings. + :return: The rollemappings of specified group and client of the realm (default "master"). + """ + composite_rolemappings_url = URL_CLIENT_USER_ROLEMAPPINGS_COMPOSITE.format(url=self.baseurl, realm=realm, id=uid, client=cid) + try: + return json.loads(to_native(open_url(composite_rolemappings_url, method="GET", http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except Exception as e: + self.module.fail_json(msg="Could not fetch available rolemappings for user %s of realm %s: %s" + % (uid, realm, str(e))) + + def get_realm_user_rolemapping_by_id(self, uid, rid, realm='master'): + """ Obtain role representation by id + + :param uid: ID of the user from which to obtain the rolemappings. + :param rid: ID of the role. + :param realm: client from this realm + :return: dict of rolemapping representation or None if none matching exist + """ + rolemappings_url = URL_REALM_ROLEMAPPINGS.format(url=self.baseurl, realm=realm, id=uid) + try: + rolemappings = json.loads(to_native(open_url(rolemappings_url, method="GET", http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + for role in rolemappings: + if rid == role['id']: + return role + except Exception as e: + self.module.fail_json(msg="Could not fetch rolemappings for user %s, realm %s: %s" + % (uid, realm, str(e))) + return None + + def get_realm_user_available_rolemappings(self, uid, realm="master"): + """ Fetch the available role of a realm for a specified user on the Keycloak server. + + :param uid: ID of the user from which to obtain the rolemappings. + :param realm: Realm from which to obtain the rolemappings. + :return: The rollemappings of specified group and client of the realm (default "master"). + """ + available_rolemappings_url = URL_REALM_ROLEMAPPINGS_AVAILABLE.format(url=self.baseurl, realm=realm, id=uid) + try: + return json.loads(to_native(open_url(available_rolemappings_url, method="GET", http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except Exception as e: + self.module.fail_json(msg="Could not fetch available rolemappings for user %s of realm %s: %s" + % (uid, realm, str(e))) + + def get_realm_user_composite_rolemappings(self, uid, realm="master"): + """ Fetch the composite role of a realm for a specified user on the Keycloak server. + + :param uid: ID of the user from which to obtain the rolemappings. + :param realm: Realm from which to obtain the rolemappings. + :return: The effective rollemappings of specified client and user of the realm (default "master"). + """ + composite_rolemappings_url = URL_REALM_ROLEMAPPINGS_COMPOSITE.format(url=self.baseurl, realm=realm, id=uid) + try: + return json.loads(to_native(open_url(composite_rolemappings_url, method="GET", http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except Exception as e: + self.module.fail_json(msg="Could not fetch effective rolemappings for user %s, realm %s: %s" + % (uid, realm, str(e))) + + def get_user_by_username(self, username, realm="master"): + """ Fetch a keycloak user within a realm based on its username. + + If the user does not exist, None is returned. + :param username: Username of the user to fetch. + :param realm: Realm in which the user resides; default 'master' + """ + users_url = URL_USERS.format(url=self.baseurl, realm=realm) + users_url += '?username=%s&exact=true' % username + try: + return json.loads(to_native(open_url(users_url, method='GET', headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except ValueError as e: + self.module.fail_json(msg='API returned incorrect JSON when trying to obtain the user for realm %s and username %s: %s' + % (realm, username, str(e))) + except Exception as e: + self.module.fail_json(msg='Could not obtain the user for realm %s and username %s: %s' + % (realm, username, str(e))) + + def get_service_account_user_by_client_id(self, client_id, realm="master"): + """ Fetch a keycloak service account user within a realm based on its client_id. + + If the user does not exist, None is returned. + :param client_id: clientId of the service account user to fetch. + :param realm: Realm in which the user resides; default 'master' + """ + cid = self.get_client_id(client_id, realm=realm) + + service_account_user_url = URL_CLIENT_SERVICE_ACCOUNT_USER.format(url=self.baseurl, realm=realm, id=cid) + try: + return json.loads(to_native(open_url(service_account_user_url, method='GET', headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except ValueError as e: + self.module.fail_json(msg='API returned incorrect JSON when trying to obtain the service-account-user for realm %s and client_id %s: %s' + % (realm, client_id, str(e))) + except Exception as e: + self.module.fail_json(msg='Could not obtain the service-account-user for realm %s and client_id %s: %s' + % (realm, client_id, str(e))) + + def add_user_rolemapping(self, uid, cid, role_rep, realm="master"): + """ Assign a realm or client role to a specified user on the Keycloak server. + + :param uid: ID of the user roles are assigned to. + :param cid: ID of the client from which to obtain the rolemappings. If empty, roles are from the realm + :param role_rep: Representation of the role to assign. + :param realm: Realm from which to obtain the rolemappings. + :return: None. + """ + if cid is None: + user_realm_rolemappings_url = URL_REALM_ROLEMAPPINGS.format(url=self.baseurl, realm=realm, id=uid) + try: + open_url(user_realm_rolemappings_url, method="POST", http_agent=self.http_agent, headers=self.restheaders, data=json.dumps(role_rep), + validate_certs=self.validate_certs, timeout=self.connection_timeout) + except Exception as e: + self.module.fail_json(msg="Could not map roles to userId %s for realm %s and roles %s: %s" + % (uid, realm, json.dumps(role_rep), str(e))) + else: + user_client_rolemappings_url = URL_CLIENT_USER_ROLEMAPPINGS.format(url=self.baseurl, realm=realm, id=uid, client=cid) + try: + open_url(user_client_rolemappings_url, method="POST", http_agent=self.http_agent, headers=self.restheaders, data=json.dumps(role_rep), + validate_certs=self.validate_certs, timeout=self.connection_timeout) + except Exception as e: + self.module.fail_json(msg="Could not map roles to userId %s for client %s, realm %s and roles %s: %s" + % (cid, uid, realm, json.dumps(role_rep), str(e))) + + def delete_user_rolemapping(self, uid, cid, role_rep, realm="master"): + """ Delete the rolemapping of a client in a specified user on the Keycloak server. + + :param uid: ID of the user from which to remove the rolemappings. + :param cid: ID of the client from which to remove the rolemappings. + :param role_rep: Representation of the role to remove from rolemappings. + :param realm: Realm from which to remove the rolemappings. + :return: None. + """ + if cid is None: + user_realm_rolemappings_url = URL_REALM_ROLEMAPPINGS.format(url=self.baseurl, realm=realm, id=uid) + try: + open_url(user_realm_rolemappings_url, method="DELETE", http_agent=self.http_agent, headers=self.restheaders, data=json.dumps(role_rep), + validate_certs=self.validate_certs, timeout=self.connection_timeout) + except Exception as e: + self.module.fail_json(msg="Could not remove roles %s from userId %s, realm %s: %s" + % (json.dumps(role_rep), uid, realm, str(e))) + else: + user_client_rolemappings_url = URL_CLIENT_USER_ROLEMAPPINGS.format(url=self.baseurl, realm=realm, id=uid, client=cid) + try: + open_url(user_client_rolemappings_url, method="DELETE", http_agent=self.http_agent, headers=self.restheaders, data=json.dumps(role_rep), + validate_certs=self.validate_certs, timeout=self.connection_timeout) + except Exception as e: + self.module.fail_json(msg="Could not remove roles %s for client %s from userId %s, realm %s: %s" + % (json.dumps(role_rep), cid, uid, realm, str(e))) + + def get_client_templates(self, realm='master'): + """ Obtains client template representations for client templates in a realm + + :param realm: realm to be queried + :return: list of dicts of client representations + """ + url = URL_CLIENTTEMPLATES.format(url=self.baseurl, realm=realm) + + try: + return json.loads(to_native(open_url(url, method='GET', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except ValueError as e: + self.module.fail_json(msg='API returned incorrect JSON when trying to obtain list of client templates for realm %s: %s' + % (realm, str(e))) + except Exception as e: + self.module.fail_json(msg='Could not obtain list of client templates for realm %s: %s' + % (realm, str(e))) + + def get_client_template_by_id(self, id, realm='master'): + """ Obtain client template representation by id + + :param id: id (not name) of client template to be queried + :param realm: client template from this realm + :return: dict of client template representation or None if none matching exist + """ + url = URL_CLIENTTEMPLATE.format(url=self.baseurl, id=id, realm=realm) + + try: + return json.loads(to_native(open_url(url, method='GET', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except ValueError as e: + self.module.fail_json(msg='API returned incorrect JSON when trying to obtain client templates %s for realm %s: %s' + % (id, realm, str(e))) + except Exception as e: + self.module.fail_json(msg='Could not obtain client template %s for realm %s: %s' + % (id, realm, str(e))) + + def get_client_template_by_name(self, name, realm='master'): + """ Obtain client template representation by name + + :param name: name of client template to be queried + :param realm: client template from this realm + :return: dict of client template representation or None if none matching exist + """ + result = self.get_client_templates(realm) + if isinstance(result, list): + result = [x for x in result if x['name'] == name] + if len(result) > 0: + return result[0] + return None + + def get_client_template_id(self, name, realm='master'): + """ Obtain client template id by name + + :param name: name of client template to be queried + :param realm: client template from this realm + :return: client template id (usually a UUID) + """ + result = self.get_client_template_by_name(name, realm) + if isinstance(result, dict) and 'id' in result: + return result['id'] + else: + return None + + def update_client_template(self, id, clienttrep, realm="master"): + """ Update an existing client template + :param id: id (not name) of client template to be updated in Keycloak + :param clienttrep: corresponding (partial/full) client template representation with updates + :param realm: realm the client template is in + :return: HTTPResponse object on success + """ + url = URL_CLIENTTEMPLATE.format(url=self.baseurl, realm=realm, id=id) + + try: + return open_url(url, method='PUT', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(clienttrep), validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg='Could not update client template %s in realm %s: %s' + % (id, realm, str(e))) + + def create_client_template(self, clienttrep, realm="master"): + """ Create a client in keycloak + :param clienttrep: Client template representation of client template to be created. Must at least contain field name + :param realm: realm for client template to be created in + :return: HTTPResponse object on success + """ + url = URL_CLIENTTEMPLATES.format(url=self.baseurl, realm=realm) + + try: + return open_url(url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(clienttrep), validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg='Could not create client template %s in realm %s: %s' + % (clienttrep['clientId'], realm, str(e))) + + def delete_client_template(self, id, realm="master"): + """ Delete a client template from Keycloak + + :param id: id (not name) of client to be deleted + :param realm: realm of client template to be deleted + :return: HTTPResponse object on success + """ + url = URL_CLIENTTEMPLATE.format(url=self.baseurl, realm=realm, id=id) + + try: + return open_url(url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg='Could not delete client template %s in realm %s: %s' + % (id, realm, str(e))) + + def get_clientscopes(self, realm="master"): + """ Fetch the name and ID of all clientscopes on the Keycloak server. + + To fetch the full data of the group, make a subsequent call to + get_clientscope_by_clientscopeid, passing in the ID of the group you wish to return. + + :param realm: Realm in which the clientscope resides; default 'master'. + :return The clientscopes of this realm (default "master") + """ + clientscopes_url = URL_CLIENTSCOPES.format(url=self.baseurl, realm=realm) + try: + return json.loads(to_native(open_url(clientscopes_url, method="GET", http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except Exception as e: + self.module.fail_json(msg="Could not fetch list of clientscopes in realm %s: %s" + % (realm, str(e))) + + def get_clientscope_by_clientscopeid(self, cid, realm="master"): + """ Fetch a keycloak clientscope from the provided realm using the clientscope's unique ID. + + If the clientscope does not exist, None is returned. + + gid is a UUID provided by the Keycloak API + :param cid: UUID of the clientscope to be returned + :param realm: Realm in which the clientscope resides; default 'master'. + """ + clientscope_url = URL_CLIENTSCOPE.format(url=self.baseurl, realm=realm, id=cid) + try: + return json.loads(to_native(open_url(clientscope_url, method="GET", http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + + except HTTPError as e: + if e.code == 404: + return None + else: + self.module.fail_json(msg="Could not fetch clientscope %s in realm %s: %s" + % (cid, realm, str(e))) + except Exception as e: + self.module.fail_json(msg="Could not clientscope group %s in realm %s: %s" + % (cid, realm, str(e))) + + def get_clientscope_by_name(self, name, realm="master"): + """ Fetch a keycloak clientscope within a realm based on its name. + + The Keycloak API does not allow filtering of the clientscopes resource by name. + As a result, this method first retrieves the entire list of clientscopes - name and ID - + then performs a second query to fetch the group. + + If the clientscope does not exist, None is returned. + :param name: Name of the clientscope to fetch. + :param realm: Realm in which the clientscope resides; default 'master' + """ + try: + all_clientscopes = self.get_clientscopes(realm=realm) + + for clientscope in all_clientscopes: + if clientscope['name'] == name: + return self.get_clientscope_by_clientscopeid(clientscope['id'], realm=realm) + + return None + + except Exception as e: + self.module.fail_json(msg="Could not fetch clientscope %s in realm %s: %s" + % (name, realm, str(e))) + + def create_clientscope(self, clientscoperep, realm="master"): + """ Create a Keycloak clientscope. + + :param clientscoperep: a ClientScopeRepresentation of the clientscope to be created. Must contain at minimum the field name. + :return: HTTPResponse object on success + """ + clientscopes_url = URL_CLIENTSCOPES.format(url=self.baseurl, realm=realm) + try: + return open_url(clientscopes_url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(clientscoperep), validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg="Could not create clientscope %s in realm %s: %s" + % (clientscoperep['name'], realm, str(e))) + + def update_clientscope(self, clientscoperep, realm="master"): + """ Update an existing clientscope. + + :param grouprep: A GroupRepresentation of the updated group. + :return HTTPResponse object on success + """ + clientscope_url = URL_CLIENTSCOPE.format(url=self.baseurl, realm=realm, id=clientscoperep['id']) + + try: + return open_url(clientscope_url, method='PUT', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(clientscoperep), validate_certs=self.validate_certs) + + except Exception as e: + self.module.fail_json(msg='Could not update clientscope %s in realm %s: %s' + % (clientscoperep['name'], realm, str(e))) + + def delete_clientscope(self, name=None, cid=None, realm="master"): + """ Delete a clientscope. One of name or cid must be provided. + + Providing the clientscope ID is preferred as it avoids a second lookup to + convert a clientscope name to an ID. + + :param name: The name of the clientscope. A lookup will be performed to retrieve the clientscope ID. + :param cid: The ID of the clientscope (preferred to name). + :param realm: The realm in which this group resides, default "master". + """ + + if cid is None and name is None: + # prefer an exception since this is almost certainly a programming error in the module itself. + raise Exception("Unable to delete group - one of group ID or name must be provided.") + + # only lookup the name if cid isn't provided. + # in the case that both are provided, prefer the ID, since it's one + # less lookup. + if cid is None and name is not None: + for clientscope in self.get_clientscopes(realm=realm): + if clientscope['name'] == name: + cid = clientscope['id'] + break + + # if the group doesn't exist - no problem, nothing to delete. + if cid is None: + return None + + # should have a good cid by here. + clientscope_url = URL_CLIENTSCOPE.format(realm=realm, id=cid, url=self.baseurl) + try: + return open_url(clientscope_url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs) + + except Exception as e: + self.module.fail_json(msg="Unable to delete clientscope %s: %s" % (cid, str(e))) + + def get_clientscope_protocolmappers(self, cid, realm="master"): + """ Fetch the name and ID of all clientscopes on the Keycloak server. + + To fetch the full data of the group, make a subsequent call to + get_clientscope_by_clientscopeid, passing in the ID of the group you wish to return. + + :param cid: id of clientscope (not name). + :param realm: Realm in which the clientscope resides; default 'master'. + :return The protocolmappers of this realm (default "master") + """ + protocolmappers_url = URL_CLIENTSCOPE_PROTOCOLMAPPERS.format(id=cid, url=self.baseurl, realm=realm) + try: + return json.loads(to_native(open_url(protocolmappers_url, method="GET", http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except Exception as e: + self.module.fail_json(msg="Could not fetch list of protocolmappers in realm %s: %s" + % (realm, str(e))) + + def get_clientscope_protocolmapper_by_protocolmapperid(self, pid, cid, realm="master"): + """ Fetch a keycloak clientscope from the provided realm using the clientscope's unique ID. + + If the clientscope does not exist, None is returned. + + gid is a UUID provided by the Keycloak API + + :param cid: UUID of the protocolmapper to be returned + :param cid: UUID of the clientscope to be returned + :param realm: Realm in which the clientscope resides; default 'master'. + """ + protocolmapper_url = URL_CLIENTSCOPE_PROTOCOLMAPPER.format(url=self.baseurl, realm=realm, id=cid, mapper_id=pid) + try: + return json.loads(to_native(open_url(protocolmapper_url, method="GET", http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + + except HTTPError as e: + if e.code == 404: + return None + else: + self.module.fail_json(msg="Could not fetch protocolmapper %s in realm %s: %s" + % (pid, realm, str(e))) + except Exception as e: + self.module.fail_json(msg="Could not fetch protocolmapper %s in realm %s: %s" + % (cid, realm, str(e))) + + def get_clientscope_protocolmapper_by_name(self, cid, name, realm="master"): + """ Fetch a keycloak clientscope within a realm based on its name. + + The Keycloak API does not allow filtering of the clientscopes resource by name. + As a result, this method first retrieves the entire list of clientscopes - name and ID - + then performs a second query to fetch the group. + + If the clientscope does not exist, None is returned. + :param cid: Id of the clientscope (not name). + :param name: Name of the protocolmapper to fetch. + :param realm: Realm in which the clientscope resides; default 'master' + """ + try: + all_protocolmappers = self.get_clientscope_protocolmappers(cid, realm=realm) + + for protocolmapper in all_protocolmappers: + if protocolmapper['name'] == name: + return self.get_clientscope_protocolmapper_by_protocolmapperid(protocolmapper['id'], cid, realm=realm) + + return None + + except Exception as e: + self.module.fail_json(msg="Could not fetch protocolmapper %s in realm %s: %s" + % (name, realm, str(e))) + + def create_clientscope_protocolmapper(self, cid, mapper_rep, realm="master"): + """ Create a Keycloak clientscope protocolmapper. + + :param cid: Id of the clientscope. + :param mapper_rep: a ProtocolMapperRepresentation of the protocolmapper to be created. Must contain at minimum the field name. + :return: HTTPResponse object on success + """ + protocolmappers_url = URL_CLIENTSCOPE_PROTOCOLMAPPERS.format(url=self.baseurl, id=cid, realm=realm) + try: + return open_url(protocolmappers_url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(mapper_rep), validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg="Could not create protocolmapper %s in realm %s: %s" + % (mapper_rep['name'], realm, str(e))) + + def update_clientscope_protocolmappers(self, cid, mapper_rep, realm="master"): + """ Update an existing clientscope. + + :param cid: Id of the clientscope. + :param mapper_rep: A ProtocolMapperRepresentation of the updated protocolmapper. + :return HTTPResponse object on success + """ + protocolmapper_url = URL_CLIENTSCOPE_PROTOCOLMAPPER.format(url=self.baseurl, realm=realm, id=cid, mapper_id=mapper_rep['id']) + + try: + return open_url(protocolmapper_url, method='PUT', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(mapper_rep), validate_certs=self.validate_certs) + + except Exception as e: + self.module.fail_json(msg='Could not update protocolmappers for clientscope %s in realm %s: %s' + % (mapper_rep, realm, str(e))) + + def create_clientsecret(self, id, realm="master"): + """ Generate a new client secret by id + + :param id: id (not clientId) of client to be queried + :param realm: client from this realm + :return: dict of credential representation + """ + clientsecret_url = URL_CLIENTSECRET.format(url=self.baseurl, realm=realm, id=id) + + try: + return json.loads(to_native(open_url(clientsecret_url, method='POST', headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + + except HTTPError as e: + if e.code == 404: + return None + else: + self.module.fail_json(msg='Could not obtain clientsecret of client %s for realm %s: %s' + % (id, realm, str(e))) + except Exception as e: + self.module.fail_json(msg='Could not obtain clientsecret of client %s for realm %s: %s' + % (id, realm, str(e))) + + def get_clientsecret(self, id, realm="master"): + """ Obtain client secret by id + + :param id: id (not clientId) of client to be queried + :param realm: client from this realm + :return: dict of credential representation + """ + clientsecret_url = URL_CLIENTSECRET.format(url=self.baseurl, realm=realm, id=id) + + try: + return json.loads(to_native(open_url(clientsecret_url, method='GET', headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + + except HTTPError as e: + if e.code == 404: + return None + else: + self.module.fail_json(msg='Could not obtain clientsecret of client %s for realm %s: %s' + % (id, realm, str(e))) + except Exception as e: + self.module.fail_json(msg='Could not obtain clientsecret of client %s for realm %s: %s' + % (id, realm, str(e))) + + def get_groups(self, realm="master"): + """ Fetch the name and ID of all groups on the Keycloak server. + + To fetch the full data of the group, make a subsequent call to + get_group_by_groupid, passing in the ID of the group you wish to return. + + :param realm: Return the groups of this realm (default "master"). + """ + groups_url = URL_GROUPS.format(url=self.baseurl, realm=realm) + try: + return json.loads(to_native(open_url(groups_url, method="GET", http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except Exception as e: + self.module.fail_json(msg="Could not fetch list of groups in realm %s: %s" + % (realm, str(e))) + + def get_group_by_groupid(self, gid, realm="master"): + """ Fetch a keycloak group from the provided realm using the group's unique ID. + + If the group does not exist, None is returned. + + gid is a UUID provided by the Keycloak API + :param gid: UUID of the group to be returned + :param realm: Realm in which the group resides; default 'master'. + """ + groups_url = URL_GROUP.format(url=self.baseurl, realm=realm, groupid=gid) + try: + return json.loads(to_native(open_url(groups_url, method="GET", http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except HTTPError as e: + if e.code == 404: + return None + else: + self.module.fail_json(msg="Could not fetch group %s in realm %s: %s" + % (gid, realm, str(e))) + except Exception as e: + self.module.fail_json(msg="Could not fetch group %s in realm %s: %s" + % (gid, realm, str(e))) + + def get_group_by_name(self, name, realm="master", parents=None): + """ Fetch a keycloak group within a realm based on its name. + + The Keycloak API does not allow filtering of the Groups resource by name. + As a result, this method first retrieves the entire list of groups - name and ID - + then performs a second query to fetch the group. + + If the group does not exist, None is returned. + :param name: Name of the group to fetch. + :param realm: Realm in which the group resides; default 'master' + :param parents: Optional list of parents when group to look for is a subgroup + """ + groups_url = URL_GROUPS.format(url=self.baseurl, realm=realm) + try: + if parents: + parent = self.get_subgroup_direct_parent(parents, realm) + + if not parent: + return None + + all_groups = parent['subGroups'] + else: + all_groups = self.get_groups(realm=realm) + + for group in all_groups: + if group['name'] == name: + return self.get_group_by_groupid(group['id'], realm=realm) + + return None + + except Exception as e: + self.module.fail_json(msg="Could not fetch group %s in realm %s: %s" + % (name, realm, str(e))) + + def _get_normed_group_parent(self, parent): + """ Converts parent dict information into a more easy to use form. + + :param parent: parent describing dict + """ + if parent['id']: + return (parent['id'], True) + + return (parent['name'], False) + + def get_subgroup_by_chain(self, name_chain, realm="master"): + """ Access a subgroup API object by walking down a given name/id chain. + + Groups can be given either as by name or by ID, the first element + must either be a toplvl group or given as ID, all parents must exist. + + If the group cannot be found, None is returned. + :param name_chain: Topdown ordered list of subgroup parent (ids or names) + its own name at the end + :param realm: Realm in which the group resides; default 'master' + """ + cp = name_chain[0] + + # for 1st parent in chain we must query the server + cp, is_id = self._get_normed_group_parent(cp) + + if is_id: + tmp = self.get_group_by_groupid(cp, realm=realm) + else: + # given as name, assume toplvl group + tmp = self.get_group_by_name(cp, realm=realm) + + if not tmp: + return None + + for p in name_chain[1:]: + for sg in tmp['subGroups']: + pv, is_id = self._get_normed_group_parent(p) + + if is_id: + cmpkey = "id" + else: + cmpkey = "name" + + if pv == sg[cmpkey]: + tmp = sg + break + + if not tmp: + return None + + return tmp + + def get_subgroup_direct_parent(self, parents, realm="master", children_to_resolve=None): + """ Get keycloak direct parent group API object for a given chain of parents. + + To succesfully work the API for subgroups we actually dont need + to "walk the whole tree" for nested groups but only need to know + the ID for the direct predecessor of current subgroup. This + method will guarantee us this information getting there with + as minimal work as possible. + + Note that given parent list can and might be incomplete at the + upper levels as long as it starts with an ID instead of a name + + If the group does not exist, None is returned. + :param parents: Topdown ordered list of subgroup parents + :param realm: Realm in which the group resides; default 'master' + """ + if children_to_resolve is None: + # start recursion by reversing parents (in optimal cases + # we dont need to walk the whole tree upwarts) + parents = list(reversed(parents)) + children_to_resolve = [] + + if not parents: + # walk complete parents list to the top, all names, no id's, + # try to resolve it assuming list is complete and 1st + # element is a toplvl group + return self.get_subgroup_by_chain(list(reversed(children_to_resolve)), realm=realm) + + cp = parents[0] + unused, is_id = self._get_normed_group_parent(cp) + + if is_id: + # current parent is given as ID, we can stop walking + # upwards searching for an entry point + return self.get_subgroup_by_chain([cp] + list(reversed(children_to_resolve)), realm=realm) + else: + # current parent is given as name, it must be resolved + # later, try next parent (recurse) + children_to_resolve.append(cp) + return self.get_subgroup_direct_parent( + parents[1:], + realm=realm, children_to_resolve=children_to_resolve + ) + + def create_group(self, grouprep, realm="master"): + """ Create a Keycloak group. + + :param grouprep: a GroupRepresentation of the group to be created. Must contain at minimum the field name. + :return: HTTPResponse object on success + """ + groups_url = URL_GROUPS.format(url=self.baseurl, realm=realm) + try: + return open_url(groups_url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(grouprep), validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg="Could not create group %s in realm %s: %s" + % (grouprep['name'], realm, str(e))) + + def create_subgroup(self, parents, grouprep, realm="master"): + """ Create a Keycloak subgroup. + + :param parents: list of one or more parent groups + :param grouprep: a GroupRepresentation of the group to be created. Must contain at minimum the field name. + :return: HTTPResponse object on success + """ + parent_id = "---UNDETERMINED---" + try: + parent_id = self.get_subgroup_direct_parent(parents, realm) + + if not parent_id: + raise Exception( + "Could not determine subgroup parent ID for given" + " parent chain {0}. Assure that all parents exist" + " already and the list is complete and properly" + " ordered, starts with an ID or starts at the" + " top level".format(parents) + ) + + parent_id = parent_id["id"] + url = URL_GROUP_CHILDREN.format(url=self.baseurl, realm=realm, groupid=parent_id) + return open_url(url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(grouprep), validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg="Could not create subgroup %s for parent group %s in realm %s: %s" + % (grouprep['name'], parent_id, realm, str(e))) + + def update_group(self, grouprep, realm="master"): + """ Update an existing group. + + :param grouprep: A GroupRepresentation of the updated group. + :return HTTPResponse object on success + """ + group_url = URL_GROUP.format(url=self.baseurl, realm=realm, groupid=grouprep['id']) + + try: + return open_url(group_url, method='PUT', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(grouprep), validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg='Could not update group %s in realm %s: %s' + % (grouprep['name'], realm, str(e))) + + def delete_group(self, name=None, groupid=None, realm="master"): + """ Delete a group. One of name or groupid must be provided. + + Providing the group ID is preferred as it avoids a second lookup to + convert a group name to an ID. + + :param name: The name of the group. A lookup will be performed to retrieve the group ID. + :param groupid: The ID of the group (preferred to name). + :param realm: The realm in which this group resides, default "master". + """ + + if groupid is None and name is None: + # prefer an exception since this is almost certainly a programming error in the module itself. + raise Exception("Unable to delete group - one of group ID or name must be provided.") + + # only lookup the name if groupid isn't provided. + # in the case that both are provided, prefer the ID, since it's one + # less lookup. + if groupid is None and name is not None: + for group in self.get_groups(realm=realm): + if group['name'] == name: + groupid = group['id'] + break + + # if the group doesn't exist - no problem, nothing to delete. + if groupid is None: + return None + + # should have a good groupid by here. + group_url = URL_GROUP.format(realm=realm, groupid=groupid, url=self.baseurl) + try: + return open_url(group_url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg="Unable to delete group %s: %s" % (groupid, str(e))) + + def get_realm_roles(self, realm='master'): + """ Obtains role representations for roles in a realm + + :param realm: realm to be queried + :return: list of dicts of role representations + """ + rolelist_url = URL_REALM_ROLES.format(url=self.baseurl, realm=realm) + try: + return json.loads(to_native(open_url(rolelist_url, method='GET', http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except ValueError as e: + self.module.fail_json(msg='API returned incorrect JSON when trying to obtain list of roles for realm %s: %s' + % (realm, str(e))) + except Exception as e: + self.module.fail_json(msg='Could not obtain list of roles for realm %s: %s' + % (realm, str(e))) + + def get_realm_role(self, name, realm='master'): + """ Fetch a keycloak role from the provided realm using the role's name. + + If the role does not exist, None is returned. + :param name: Name of the role to fetch. + :param realm: Realm in which the role resides; default 'master'. + """ + role_url = URL_REALM_ROLE.format(url=self.baseurl, realm=realm, name=quote(name)) + try: + return json.loads(to_native(open_url(role_url, method="GET", http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except HTTPError as e: + if e.code == 404: + return None + else: + self.module.fail_json(msg='Could not fetch role %s in realm %s: %s' + % (name, realm, str(e))) + except Exception as e: + self.module.fail_json(msg='Could not fetch role %s in realm %s: %s' + % (name, realm, str(e))) + + def create_realm_role(self, rolerep, realm='master'): + """ Create a Keycloak realm role. + + :param rolerep: a RoleRepresentation of the role to be created. Must contain at minimum the field name. + :return: HTTPResponse object on success + """ + roles_url = URL_REALM_ROLES.format(url=self.baseurl, realm=realm) + try: + return open_url(roles_url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(rolerep), validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg='Could not create role %s in realm %s: %s' + % (rolerep['name'], realm, str(e))) + + def update_realm_role(self, rolerep, realm='master'): + """ Update an existing realm role. + + :param rolerep: A RoleRepresentation of the updated role. + :return HTTPResponse object on success + """ + role_url = URL_REALM_ROLE.format(url=self.baseurl, realm=realm, name=quote(rolerep['name'])) + try: + return open_url(role_url, method='PUT', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(rolerep), validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg='Could not update role %s in realm %s: %s' + % (rolerep['name'], realm, str(e))) + + def delete_realm_role(self, name, realm='master'): + """ Delete a realm role. + + :param name: The name of the role. + :param realm: The realm in which this role resides, default "master". + """ + role_url = URL_REALM_ROLE.format(url=self.baseurl, realm=realm, name=quote(name)) + try: + return open_url(role_url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg='Unable to delete role %s in realm %s: %s' + % (name, realm, str(e))) + + def get_client_roles(self, clientid, realm='master'): + """ Obtains role representations for client roles in a specific client + + :param clientid: Client id to be queried + :param realm: Realm to be queried + :return: List of dicts of role representations + """ + cid = self.get_client_id(clientid, realm=realm) + if cid is None: + self.module.fail_json(msg='Could not find client %s in realm %s' + % (clientid, realm)) + rolelist_url = URL_CLIENT_ROLES.format(url=self.baseurl, realm=realm, id=cid) + try: + return json.loads(to_native(open_url(rolelist_url, method='GET', http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except ValueError as e: + self.module.fail_json(msg='API returned incorrect JSON when trying to obtain list of roles for client %s in realm %s: %s' + % (clientid, realm, str(e))) + except Exception as e: + self.module.fail_json(msg='Could not obtain list of roles for client %s in realm %s: %s' + % (clientid, realm, str(e))) + + def get_client_role(self, name, clientid, realm='master'): + """ Fetch a keycloak client role from the provided realm using the role's name. + + :param name: Name of the role to fetch. + :param clientid: Client id for the client role + :param realm: Realm in which the role resides + :return: Dict of role representation + If the role does not exist, None is returned. + """ + cid = self.get_client_id(clientid, realm=realm) + if cid is None: + self.module.fail_json(msg='Could not find client %s in realm %s' + % (clientid, realm)) + role_url = URL_CLIENT_ROLE.format(url=self.baseurl, realm=realm, id=cid, name=quote(name)) + try: + return json.loads(to_native(open_url(role_url, method="GET", http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except HTTPError as e: + if e.code == 404: + return None + else: + self.module.fail_json(msg='Could not fetch role %s in client %s of realm %s: %s' + % (name, clientid, realm, str(e))) + except Exception as e: + self.module.fail_json(msg='Could not fetch role %s for client %s in realm %s: %s' + % (name, clientid, realm, str(e))) + + def create_client_role(self, rolerep, clientid, realm='master'): + """ Create a Keycloak client role. + + :param rolerep: a RoleRepresentation of the role to be created. Must contain at minimum the field name. + :param clientid: Client id for the client role + :param realm: Realm in which the role resides + :return: HTTPResponse object on success + """ + cid = self.get_client_id(clientid, realm=realm) + if cid is None: + self.module.fail_json(msg='Could not find client %s in realm %s' + % (clientid, realm)) + roles_url = URL_CLIENT_ROLES.format(url=self.baseurl, realm=realm, id=cid) + try: + return open_url(roles_url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(rolerep), validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg='Could not create role %s for client %s in realm %s: %s' + % (rolerep['name'], clientid, realm, str(e))) + + def update_client_role(self, rolerep, clientid, realm="master"): + """ Update an existing client role. + + :param rolerep: A RoleRepresentation of the updated role. + :param clientid: Client id for the client role + :param realm: Realm in which the role resides + :return HTTPResponse object on success + """ + cid = self.get_client_id(clientid, realm=realm) + if cid is None: + self.module.fail_json(msg='Could not find client %s in realm %s' + % (clientid, realm)) + role_url = URL_CLIENT_ROLE.format(url=self.baseurl, realm=realm, id=cid, name=quote(rolerep['name'])) + try: + return open_url(role_url, method='PUT', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(rolerep), validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg='Could not update role %s for client %s in realm %s: %s' + % (rolerep['name'], clientid, realm, str(e))) + + def delete_client_role(self, name, clientid, realm="master"): + """ Delete a role. One of name or roleid must be provided. + + :param name: The name of the role. + :param clientid: Client id for the client role + :param realm: Realm in which the role resides + """ + cid = self.get_client_id(clientid, realm=realm) + if cid is None: + self.module.fail_json(msg='Could not find client %s in realm %s' + % (clientid, realm)) + role_url = URL_CLIENT_ROLE.format(url=self.baseurl, realm=realm, id=cid, name=quote(name)) + try: + return open_url(role_url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg='Unable to delete role %s for client %s in realm %s: %s' + % (name, clientid, realm, str(e))) + + def get_authentication_flow_by_alias(self, alias, realm='master'): + """ + Get an authentication flow by it's alias + :param alias: Alias of the authentication flow to get. + :param realm: Realm. + :return: Authentication flow representation. + """ + try: + authentication_flow = {} + # Check if the authentication flow exists on the Keycloak serveraders + authentications = json.load(open_url(URL_AUTHENTICATION_FLOWS.format(url=self.baseurl, realm=realm), method='GET', + http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, validate_certs=self.validate_certs)) + for authentication in authentications: + if authentication["alias"] == alias: + authentication_flow = authentication + break + return authentication_flow + except Exception as e: + self.module.fail_json(msg="Unable get authentication flow %s: %s" % (alias, str(e))) + + def delete_authentication_flow_by_id(self, id, realm='master'): + """ + Delete an authentication flow from Keycloak + :param id: id of authentication flow to be deleted + :param realm: realm of client to be deleted + :return: HTTPResponse object on success + """ + flow_url = URL_AUTHENTICATION_FLOW.format(url=self.baseurl, realm=realm, id=id) + + try: + return open_url(flow_url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg='Could not delete authentication flow %s in realm %s: %s' + % (id, realm, str(e))) + + def copy_auth_flow(self, config, realm='master'): + """ + Create a new authentication flow from a copy of another. + :param config: Representation of the authentication flow to create. + :param realm: Realm. + :return: Representation of the new authentication flow. + """ + try: + new_name = dict( + newName=config["alias"] + ) + open_url( + URL_AUTHENTICATION_FLOW_COPY.format( + url=self.baseurl, + realm=realm, + copyfrom=quote(config["copyFrom"])), + method='POST', + http_agent=self.http_agent, headers=self.restheaders, + data=json.dumps(new_name), + timeout=self.connection_timeout, + validate_certs=self.validate_certs) + flow_list = json.load( + open_url( + URL_AUTHENTICATION_FLOWS.format(url=self.baseurl, + realm=realm), + method='GET', + http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs)) + for flow in flow_list: + if flow["alias"] == config["alias"]: + return flow + return None + except Exception as e: + self.module.fail_json(msg='Could not copy authentication flow %s in realm %s: %s' + % (config["alias"], realm, str(e))) + + def create_empty_auth_flow(self, config, realm='master'): + """ + Create a new empty authentication flow. + :param config: Representation of the authentication flow to create. + :param realm: Realm. + :return: Representation of the new authentication flow. + """ + try: + new_flow = dict( + alias=config["alias"], + providerId=config["providerId"], + description=config["description"], + topLevel=True + ) + open_url( + URL_AUTHENTICATION_FLOWS.format( + url=self.baseurl, + realm=realm), + method='POST', + http_agent=self.http_agent, headers=self.restheaders, + data=json.dumps(new_flow), + timeout=self.connection_timeout, + validate_certs=self.validate_certs) + flow_list = json.load( + open_url( + URL_AUTHENTICATION_FLOWS.format( + url=self.baseurl, + realm=realm), + method='GET', + http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs)) + for flow in flow_list: + if flow["alias"] == config["alias"]: + return flow + return None + except Exception as e: + self.module.fail_json(msg='Could not create empty authentication flow %s in realm %s: %s' + % (config["alias"], realm, str(e))) + + def update_authentication_executions(self, flowAlias, updatedExec, realm='master'): + """ Update authentication executions + + :param flowAlias: name of the parent flow + :param updatedExec: JSON containing updated execution + :return: HTTPResponse object on success + """ + try: + open_url( + URL_AUTHENTICATION_FLOW_EXECUTIONS.format( + url=self.baseurl, + realm=realm, + flowalias=quote(flowAlias)), + method='PUT', + http_agent=self.http_agent, headers=self.restheaders, + data=json.dumps(updatedExec), + timeout=self.connection_timeout, + validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg="Unable to update executions %s: %s" % (updatedExec, str(e))) + + def add_authenticationConfig_to_execution(self, executionId, authenticationConfig, realm='master'): + """ Add autenticatorConfig to the execution + + :param executionId: id of execution + :param authenticationConfig: config to add to the execution + :return: HTTPResponse object on success + """ + try: + open_url( + URL_AUTHENTICATION_EXECUTION_CONFIG.format( + url=self.baseurl, + realm=realm, + id=executionId), + method='POST', + http_agent=self.http_agent, headers=self.restheaders, + data=json.dumps(authenticationConfig), + timeout=self.connection_timeout, + validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg="Unable to add authenticationConfig %s: %s" % (executionId, str(e))) + + def create_subflow(self, subflowName, flowAlias, realm='master'): + """ Create new sublow on the flow + + :param subflowName: name of the subflow to create + :param flowAlias: name of the parent flow + :return: HTTPResponse object on success + """ + try: + newSubFlow = {} + newSubFlow["alias"] = subflowName + newSubFlow["provider"] = "registration-page-form" + newSubFlow["type"] = "basic-flow" + open_url( + URL_AUTHENTICATION_FLOW_EXECUTIONS_FLOW.format( + url=self.baseurl, + realm=realm, + flowalias=quote(flowAlias)), + method='POST', + http_agent=self.http_agent, headers=self.restheaders, + data=json.dumps(newSubFlow), + timeout=self.connection_timeout, + validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg="Unable to create new subflow %s: %s" % (subflowName, str(e))) + + def create_execution(self, execution, flowAlias, realm='master'): + """ Create new execution on the flow + + :param execution: name of execution to create + :param flowAlias: name of the parent flow + :return: HTTPResponse object on success + """ + try: + newExec = {} + newExec["provider"] = execution["providerId"] + newExec["requirement"] = execution["requirement"] + open_url( + URL_AUTHENTICATION_FLOW_EXECUTIONS_EXECUTION.format( + url=self.baseurl, + realm=realm, + flowalias=quote(flowAlias)), + method='POST', + http_agent=self.http_agent, headers=self.restheaders, + data=json.dumps(newExec), + timeout=self.connection_timeout, + validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg="Unable to create new execution %s: %s" % (execution["provider"], str(e))) + + def change_execution_priority(self, executionId, diff, realm='master'): + """ Raise or lower execution priority of diff time + + :param executionId: id of execution to lower priority + :param realm: realm the client is in + :param diff: Integer number, raise of diff time if positive lower of diff time if negative + :return: HTTPResponse object on success + """ + try: + if diff > 0: + for i in range(diff): + open_url( + URL_AUTHENTICATION_EXECUTION_RAISE_PRIORITY.format( + url=self.baseurl, + realm=realm, + id=executionId), + method='POST', + http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs) + elif diff < 0: + for i in range(-diff): + open_url( + URL_AUTHENTICATION_EXECUTION_LOWER_PRIORITY.format( + url=self.baseurl, + realm=realm, + id=executionId), + method='POST', + http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg="Unable to change execution priority %s: %s" % (executionId, str(e))) + + def get_executions_representation(self, config, realm='master'): + """ + Get a representation of the executions for an authentication flow. + :param config: Representation of the authentication flow + :param realm: Realm + :return: Representation of the executions + """ + try: + # Get executions created + executions = json.load( + open_url( + URL_AUTHENTICATION_FLOW_EXECUTIONS.format( + url=self.baseurl, + realm=realm, + flowalias=quote(config["alias"])), + method='GET', + http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs)) + for execution in executions: + if "authenticationConfig" in execution: + execConfigId = execution["authenticationConfig"] + execConfig = json.load( + open_url( + URL_AUTHENTICATION_CONFIG.format( + url=self.baseurl, + realm=realm, + id=execConfigId), + method='GET', + http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs)) + execution["authenticationConfig"] = execConfig + return executions + except Exception as e: + self.module.fail_json(msg='Could not get executions for authentication flow %s in realm %s: %s' + % (config["alias"], realm, str(e))) + + def get_identity_providers(self, realm='master'): + """ Fetch representations for identity providers in a realm + :param realm: realm to be queried + :return: list of representations for identity providers + """ + idps_url = URL_IDENTITY_PROVIDERS.format(url=self.baseurl, realm=realm) + try: + return json.loads(to_native(open_url(idps_url, method='GET', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except ValueError as e: + self.module.fail_json(msg='API returned incorrect JSON when trying to obtain list of identity providers for realm %s: %s' + % (realm, str(e))) + except Exception as e: + self.module.fail_json(msg='Could not obtain list of identity providers for realm %s: %s' + % (realm, str(e))) + + def get_identity_provider(self, alias, realm='master'): + """ Fetch identity provider representation from a realm using the idp's alias. + If the identity provider does not exist, None is returned. + :param alias: Alias of the identity provider to fetch. + :param realm: Realm in which the identity provider resides; default 'master'. + """ + idp_url = URL_IDENTITY_PROVIDER.format(url=self.baseurl, realm=realm, alias=alias) + try: + return json.loads(to_native(open_url(idp_url, method="GET", http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except HTTPError as e: + if e.code == 404: + return None + else: + self.module.fail_json(msg='Could not fetch identity provider %s in realm %s: %s' + % (alias, realm, str(e))) + except Exception as e: + self.module.fail_json(msg='Could not fetch identity provider %s in realm %s: %s' + % (alias, realm, str(e))) + + def create_identity_provider(self, idprep, realm='master'): + """ Create an identity provider. + :param idprep: Identity provider representation of the idp to be created. + :param realm: Realm in which this identity provider resides, default "master". + :return: HTTPResponse object on success + """ + idps_url = URL_IDENTITY_PROVIDERS.format(url=self.baseurl, realm=realm) + try: + return open_url(idps_url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(idprep), validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg='Could not create identity provider %s in realm %s: %s' + % (idprep['alias'], realm, str(e))) + + def update_identity_provider(self, idprep, realm='master'): + """ Update an existing identity provider. + :param idprep: Identity provider representation of the idp to be updated. + :param realm: Realm in which this identity provider resides, default "master". + :return HTTPResponse object on success + """ + idp_url = URL_IDENTITY_PROVIDER.format(url=self.baseurl, realm=realm, alias=idprep['alias']) + try: + return open_url(idp_url, method='PUT', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(idprep), validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg='Could not update identity provider %s in realm %s: %s' + % (idprep['alias'], realm, str(e))) + + def delete_identity_provider(self, alias, realm='master'): + """ Delete an identity provider. + :param alias: Alias of the identity provider. + :param realm: Realm in which this identity provider resides, default "master". + """ + idp_url = URL_IDENTITY_PROVIDER.format(url=self.baseurl, realm=realm, alias=alias) + try: + return open_url(idp_url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg='Unable to delete identity provider %s in realm %s: %s' + % (alias, realm, str(e))) + + def get_identity_provider_mappers(self, alias, realm='master'): + """ Fetch representations for identity provider mappers + :param alias: Alias of the identity provider. + :param realm: realm to be queried + :return: list of representations for identity provider mappers + """ + mappers_url = URL_IDENTITY_PROVIDER_MAPPERS.format(url=self.baseurl, realm=realm, alias=alias) + try: + return json.loads(to_native(open_url(mappers_url, method='GET', http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except ValueError as e: + self.module.fail_json(msg='API returned incorrect JSON when trying to obtain list of identity provider mappers for idp %s in realm %s: %s' + % (alias, realm, str(e))) + except Exception as e: + self.module.fail_json(msg='Could not obtain list of identity provider mappers for idp %s in realm %s: %s' + % (alias, realm, str(e))) + + def get_identity_provider_mapper(self, mid, alias, realm='master'): + """ Fetch identity provider representation from a realm using the idp's alias. + If the identity provider does not exist, None is returned. + :param mid: Unique ID of the mapper to fetch. + :param alias: Alias of the identity provider. + :param realm: Realm in which the identity provider resides; default 'master'. + """ + mapper_url = URL_IDENTITY_PROVIDER_MAPPER.format(url=self.baseurl, realm=realm, alias=alias, id=mid) + try: + return json.loads(to_native(open_url(mapper_url, method="GET", http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except HTTPError as e: + if e.code == 404: + return None + else: + self.module.fail_json(msg='Could not fetch mapper %s for identity provider %s in realm %s: %s' + % (mid, alias, realm, str(e))) + except Exception as e: + self.module.fail_json(msg='Could not fetch mapper %s for identity provider %s in realm %s: %s' + % (mid, alias, realm, str(e))) + + def create_identity_provider_mapper(self, mapper, alias, realm='master'): + """ Create an identity provider mapper. + :param mapper: IdentityProviderMapperRepresentation of the mapper to be created. + :param alias: Alias of the identity provider. + :param realm: Realm in which this identity provider resides, default "master". + :return: HTTPResponse object on success + """ + mappers_url = URL_IDENTITY_PROVIDER_MAPPERS.format(url=self.baseurl, realm=realm, alias=alias) + try: + return open_url(mappers_url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(mapper), validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg='Could not create identity provider mapper %s for idp %s in realm %s: %s' + % (mapper['name'], alias, realm, str(e))) + + def update_identity_provider_mapper(self, mapper, alias, realm='master'): + """ Update an existing identity provider. + :param mapper: IdentityProviderMapperRepresentation of the mapper to be updated. + :param alias: Alias of the identity provider. + :param realm: Realm in which this identity provider resides, default "master". + :return HTTPResponse object on success + """ + mapper_url = URL_IDENTITY_PROVIDER_MAPPER.format(url=self.baseurl, realm=realm, alias=alias, id=mapper['id']) + try: + return open_url(mapper_url, method='PUT', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(mapper), validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg='Could not update mapper %s for identity provider %s in realm %s: %s' + % (mapper['id'], alias, realm, str(e))) + + def delete_identity_provider_mapper(self, mid, alias, realm='master'): + """ Delete an identity provider. + :param mid: Unique ID of the mapper to delete. + :param alias: Alias of the identity provider. + :param realm: Realm in which this identity provider resides, default "master". + """ + mapper_url = URL_IDENTITY_PROVIDER_MAPPER.format(url=self.baseurl, realm=realm, alias=alias, id=mid) + try: + return open_url(mapper_url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg='Unable to delete mapper %s for identity provider %s in realm %s: %s' + % (mid, alias, realm, str(e))) + + def get_components(self, filter=None, realm='master'): + """ Fetch representations for components in a realm + :param realm: realm to be queried + :param filter: search filter + :return: list of representations for components + """ + comps_url = URL_COMPONENTS.format(url=self.baseurl, realm=realm) + if filter is not None: + comps_url += '?%s' % filter + + try: + return json.loads(to_native(open_url(comps_url, method='GET', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except ValueError as e: + self.module.fail_json(msg='API returned incorrect JSON when trying to obtain list of components for realm %s: %s' + % (realm, str(e))) + except Exception as e: + self.module.fail_json(msg='Could not obtain list of components for realm %s: %s' + % (realm, str(e))) + + def get_component(self, cid, realm='master'): + """ Fetch component representation from a realm using its cid. + If the component does not exist, None is returned. + :param cid: Unique ID of the component to fetch. + :param realm: Realm in which the component resides; default 'master'. + """ + comp_url = URL_COMPONENT.format(url=self.baseurl, realm=realm, id=cid) + try: + return json.loads(to_native(open_url(comp_url, method="GET", http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except HTTPError as e: + if e.code == 404: + return None + else: + self.module.fail_json(msg='Could not fetch component %s in realm %s: %s' + % (cid, realm, str(e))) + except Exception as e: + self.module.fail_json(msg='Could not fetch component %s in realm %s: %s' + % (cid, realm, str(e))) + + def create_component(self, comprep, realm='master'): + """ Create an component. + :param comprep: Component representation of the component to be created. + :param realm: Realm in which this component resides, default "master". + :return: Component representation of the created component + """ + comps_url = URL_COMPONENTS.format(url=self.baseurl, realm=realm) + try: + resp = open_url(comps_url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(comprep), validate_certs=self.validate_certs) + comp_url = resp.getheader('Location') + if comp_url is None: + self.module.fail_json(msg='Could not create component in realm %s: %s' + % (realm, 'unexpected response')) + return json.loads(to_native(open_url(comp_url, method="GET", http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except Exception as e: + self.module.fail_json(msg='Could not create component in realm %s: %s' + % (realm, str(e))) + + def update_component(self, comprep, realm='master'): + """ Update an existing component. + :param comprep: Component representation of the component to be updated. + :param realm: Realm in which this component resides, default "master". + :return HTTPResponse object on success + """ + cid = comprep.get('id') + if cid is None: + self.module.fail_json(msg='Cannot update component without id') + comp_url = URL_COMPONENT.format(url=self.baseurl, realm=realm, id=cid) + try: + return open_url(comp_url, method='PUT', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(comprep), validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg='Could not update component %s in realm %s: %s' + % (cid, realm, str(e))) + + def delete_component(self, cid, realm='master'): + """ Delete an component. + :param cid: Unique ID of the component. + :param realm: Realm in which this component resides, default "master". + """ + comp_url = URL_COMPONENT.format(url=self.baseurl, realm=realm, id=cid) + try: + return open_url(comp_url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs) + except Exception as e: + self.module.fail_json(msg='Unable to delete component %s in realm %s: %s' + % (cid, realm, str(e))) diff --git a/plugins/modules/keycloak_client.py b/plugins/modules/keycloak_client.py new file mode 100644 index 0000000..e1f0e19 --- /dev/null +++ b/plugins/modules/keycloak_client.py @@ -0,0 +1,984 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2017, Eike Frost +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: keycloak_client + +short_description: Allows administration of Keycloak clients via Keycloak API + + +description: + - This module allows the administration of Keycloak clients via the Keycloak REST API. It + requires access to the REST API via OpenID Connect; the user connecting and the client being + used must have the requisite access rights. In a default Keycloak installation, admin-cli + and an admin user would work, as would a separate client definition with the scope tailored + to your needs and a user having the expected roles. + + - The names of module options are snake_cased versions of the camelCase ones found in the + Keycloak API and its documentation at U(https://www.keycloak.org/docs-api/8.0/rest-api/index.html). + Aliases are provided so camelCased versions can be used as well. + + - The Keycloak API does not always sanity check inputs e.g. you can set + SAML-specific settings on an OpenID Connect client for instance and vice versa. Be careful. + If you do not specify a setting, usually a sensible default is chosen. + +attributes: + check_mode: + support: full + diff_mode: + support: full + +options: + state: + description: + - State of the client + - On C(present), the client will be created (or updated if it exists already). + - On C(absent), the client will be removed if it exists + choices: ['present', 'absent'] + default: 'present' + type: str + + realm: + description: + - The realm to create the client in. + type: str + default: master + + client_id: + description: + - Client id of client to be worked on. This is usually an alphanumeric name chosen by + you. Either this or I(id) is required. If you specify both, I(id) takes precedence. + This is 'clientId' in the Keycloak REST API. + aliases: + - clientId + type: str + + id: + description: + - Id of client to be worked on. This is usually an UUID. Either this or I(client_id) + is required. If you specify both, this takes precedence. + type: str + + name: + description: + - Name of the client (this is not the same as I(client_id)). + type: str + + description: + description: + - Description of the client in Keycloak. + type: str + + root_url: + description: + - Root URL appended to relative URLs for this client. + This is 'rootUrl' in the Keycloak REST API. + aliases: + - rootUrl + type: str + + admin_url: + description: + - URL to the admin interface of the client. + This is 'adminUrl' in the Keycloak REST API. + aliases: + - adminUrl + type: str + + base_url: + description: + - Default URL to use when the auth server needs to redirect or link back to the client + This is 'baseUrl' in the Keycloak REST API. + aliases: + - baseUrl + type: str + + enabled: + description: + - Is this client enabled or not? + type: bool + + client_authenticator_type: + description: + - How do clients authenticate with the auth server? Either C(client-secret) or + C(client-jwt) can be chosen. When using C(client-secret), the module parameter + I(secret) can set it, while for C(client-jwt), you can use the keys C(use.jwks.url), + C(jwks.url), and C(jwt.credential.certificate) in the I(attributes) module parameter + to configure its behavior. + This is 'clientAuthenticatorType' in the Keycloak REST API. + choices: ['client-secret', 'client-jwt'] + aliases: + - clientAuthenticatorType + type: str + + secret: + description: + - When using I(client_authenticator_type) C(client-secret) (the default), you can + specify a secret here (otherwise one will be generated if it does not exit). If + changing this secret, the module will not register a change currently (but the + changed secret will be saved). + type: str + + registration_access_token: + description: + - The registration access token provides access for clients to the client registration + service. + This is 'registrationAccessToken' in the Keycloak REST API. + aliases: + - registrationAccessToken + type: str + + default_roles: + description: + - list of default roles for this client. If the client roles referenced do not exist + yet, they will be created. + This is 'defaultRoles' in the Keycloak REST API. + aliases: + - defaultRoles + type: list + elements: str + + redirect_uris: + description: + - Acceptable redirect URIs for this client. + This is 'redirectUris' in the Keycloak REST API. + aliases: + - redirectUris + type: list + elements: str + + web_origins: + description: + - List of allowed CORS origins. + This is 'webOrigins' in the Keycloak REST API. + aliases: + - webOrigins + type: list + elements: str + + not_before: + description: + - Revoke any tokens issued before this date for this client (this is a UNIX timestamp). + This is 'notBefore' in the Keycloak REST API. + type: int + aliases: + - notBefore + + bearer_only: + description: + - The access type of this client is bearer-only. + This is 'bearerOnly' in the Keycloak REST API. + aliases: + - bearerOnly + type: bool + + consent_required: + description: + - If enabled, users have to consent to client access. + This is 'consentRequired' in the Keycloak REST API. + aliases: + - consentRequired + type: bool + + standard_flow_enabled: + description: + - Enable standard flow for this client or not (OpenID connect). + This is 'standardFlowEnabled' in the Keycloak REST API. + aliases: + - standardFlowEnabled + type: bool + + implicit_flow_enabled: + description: + - Enable implicit flow for this client or not (OpenID connect). + This is 'implicitFlowEnabled' in the Keycloak REST API. + aliases: + - implicitFlowEnabled + type: bool + + direct_access_grants_enabled: + description: + - Are direct access grants enabled for this client or not (OpenID connect). + This is 'directAccessGrantsEnabled' in the Keycloak REST API. + aliases: + - directAccessGrantsEnabled + type: bool + + service_accounts_enabled: + description: + - Are service accounts enabled for this client or not (OpenID connect). + This is 'serviceAccountsEnabled' in the Keycloak REST API. + aliases: + - serviceAccountsEnabled + type: bool + + authorization_services_enabled: + description: + - Are authorization services enabled for this client or not (OpenID connect). + This is 'authorizationServicesEnabled' in the Keycloak REST API. + aliases: + - authorizationServicesEnabled + type: bool + + public_client: + description: + - Is the access type for this client public or not. + This is 'publicClient' in the Keycloak REST API. + aliases: + - publicClient + type: bool + + frontchannel_logout: + description: + - Is frontchannel logout enabled for this client or not. + This is 'frontchannelLogout' in the Keycloak REST API. + aliases: + - frontchannelLogout + type: bool + + protocol: + description: + - Type of client (either C(openid-connect) or C(saml). + type: str + choices: ['openid-connect', 'saml'] + + full_scope_allowed: + description: + - Is the "Full Scope Allowed" feature set for this client or not. + This is 'fullScopeAllowed' in the Keycloak REST API. + aliases: + - fullScopeAllowed + type: bool + + node_re_registration_timeout: + description: + - Cluster node re-registration timeout for this client. + This is 'nodeReRegistrationTimeout' in the Keycloak REST API. + type: int + aliases: + - nodeReRegistrationTimeout + + registered_nodes: + description: + - dict of registered cluster nodes (with C(nodename) as the key and last registration + time as the value). + This is 'registeredNodes' in the Keycloak REST API. + type: dict + aliases: + - registeredNodes + + client_template: + description: + - Client template to use for this client. If it does not exist this field will silently + be dropped. + This is 'clientTemplate' in the Keycloak REST API. + type: str + aliases: + - clientTemplate + + use_template_config: + description: + - Whether or not to use configuration from the I(client_template). + This is 'useTemplateConfig' in the Keycloak REST API. + aliases: + - useTemplateConfig + type: bool + + use_template_scope: + description: + - Whether or not to use scope configuration from the I(client_template). + This is 'useTemplateScope' in the Keycloak REST API. + aliases: + - useTemplateScope + type: bool + + use_template_mappers: + description: + - Whether or not to use mapper configuration from the I(client_template). + This is 'useTemplateMappers' in the Keycloak REST API. + aliases: + - useTemplateMappers + type: bool + + always_display_in_console: + description: + - Whether or not to display this client in account console, even if the + user does not have an active session. + aliases: + - alwaysDisplayInConsole + type: bool + version_added: 4.7.0 + + surrogate_auth_required: + description: + - Whether or not surrogate auth is required. + This is 'surrogateAuthRequired' in the Keycloak REST API. + aliases: + - surrogateAuthRequired + type: bool + + authorization_settings: + description: + - a data structure defining the authorization settings for this client. For reference, + please see the Keycloak API docs at U(https://www.keycloak.org/docs-api/8.0/rest-api/index.html#_resourceserverrepresentation). + This is 'authorizationSettings' in the Keycloak REST API. + type: dict + aliases: + - authorizationSettings + + authentication_flow_binding_overrides: + description: + - Override realm authentication flow bindings. + type: dict + aliases: + - authenticationFlowBindingOverrides + version_added: 3.4.0 + + default_client_scopes: + description: + - List of default client scopes. + aliases: + - defaultClientScopes + type: list + elements: str + version_added: 4.7.0 + + optional_client_scopes: + description: + - List of optional client scopes. + aliases: + - optionalClientScopes + type: list + elements: str + version_added: 4.7.0 + + protocol_mappers: + description: + - a list of dicts defining protocol mappers for this client. + This is 'protocolMappers' in the Keycloak REST API. + aliases: + - protocolMappers + type: list + elements: dict + suboptions: + consentRequired: + description: + - Specifies whether a user needs to provide consent to a client for this mapper to be active. + type: bool + + consentText: + description: + - The human-readable name of the consent the user is presented to accept. + type: str + + id: + description: + - Usually a UUID specifying the internal ID of this protocol mapper instance. + type: str + + name: + description: + - The name of this protocol mapper. + type: str + + protocol: + description: + - This is either C(openid-connect) or C(saml), this specifies for which protocol this protocol mapper. + is active. + choices: ['openid-connect', 'saml'] + type: str + + protocolMapper: + description: + - The Keycloak-internal name of the type of this protocol-mapper. While an exhaustive list is + impossible to provide since this may be extended through SPIs by the user of Keycloak, + by default Keycloak as of 3.4 ships with at least + - C(docker-v2-allow-all-mapper) + - C(oidc-address-mapper) + - C(oidc-full-name-mapper) + - C(oidc-group-membership-mapper) + - C(oidc-hardcoded-claim-mapper) + - C(oidc-hardcoded-role-mapper) + - C(oidc-role-name-mapper) + - C(oidc-script-based-protocol-mapper) + - C(oidc-sha256-pairwise-sub-mapper) + - C(oidc-usermodel-attribute-mapper) + - C(oidc-usermodel-client-role-mapper) + - C(oidc-usermodel-property-mapper) + - C(oidc-usermodel-realm-role-mapper) + - C(oidc-usersessionmodel-note-mapper) + - C(saml-group-membership-mapper) + - C(saml-hardcode-attribute-mapper) + - C(saml-hardcode-role-mapper) + - C(saml-role-list-mapper) + - C(saml-role-name-mapper) + - C(saml-user-attribute-mapper) + - C(saml-user-property-mapper) + - C(saml-user-session-note-mapper) + - An exhaustive list of available mappers on your installation can be obtained on + the admin console by going to Server Info -> Providers and looking under + 'protocol-mapper'. + type: str + + config: + description: + - Dict specifying the configuration options for the protocol mapper; the + contents differ depending on the value of I(protocolMapper) and are not documented + other than by the source of the mappers and its parent class(es). An example is given + below. It is easiest to obtain valid config values by dumping an already-existing + protocol mapper configuration through check-mode in the I(existing) field. + type: dict + + attributes: + description: + - A dict of further attributes for this client. This can contain various configuration + settings; an example is given in the examples section. While an exhaustive list of + permissible options is not available; possible options as of Keycloak 3.4 are listed below. The Keycloak + API does not validate whether a given option is appropriate for the protocol used; if specified + anyway, Keycloak will simply not use it. + type: dict + suboptions: + saml.authnstatement: + description: + - For SAML clients, boolean specifying whether or not a statement containing method and timestamp + should be included in the login response. + + saml.client.signature: + description: + - For SAML clients, boolean specifying whether a client signature is required and validated. + + saml.encrypt: + description: + - Boolean specifying whether SAML assertions should be encrypted with the client's public key. + + saml.force.post.binding: + description: + - For SAML clients, boolean specifying whether always to use POST binding for responses. + + saml.onetimeuse.condition: + description: + - For SAML clients, boolean specifying whether a OneTimeUse condition should be included in login responses. + + saml.server.signature: + description: + - Boolean specifying whether SAML documents should be signed by the realm. + + saml.server.signature.keyinfo.ext: + description: + - For SAML clients, boolean specifying whether REDIRECT signing key lookup should be optimized through inclusion + of the signing key id in the SAML Extensions element. + + saml.signature.algorithm: + description: + - Signature algorithm used to sign SAML documents. One of C(RSA_SHA256), C(RSA_SHA1), C(RSA_SHA512), or C(DSA_SHA1). + + saml.signing.certificate: + description: + - SAML signing key certificate, base64-encoded. + + saml.signing.private.key: + description: + - SAML signing key private key, base64-encoded. + + saml_assertion_consumer_url_post: + description: + - SAML POST Binding URL for the client's assertion consumer service (login responses). + + saml_assertion_consumer_url_redirect: + description: + - SAML Redirect Binding URL for the client's assertion consumer service (login responses). + + + saml_force_name_id_format: + description: + - For SAML clients, Boolean specifying whether to ignore requested NameID subject format and using the configured one instead. + + saml_name_id_format: + description: + - For SAML clients, the NameID format to use (one of C(username), C(email), C(transient), or C(persistent)) + + saml_signature_canonicalization_method: + description: + - SAML signature canonicalization method. This is one of four values, namely + C(http://www.w3.org/2001/10/xml-exc-c14n#) for EXCLUSIVE, + C(http://www.w3.org/2001/10/xml-exc-c14n#WithComments) for EXCLUSIVE_WITH_COMMENTS, + C(http://www.w3.org/TR/2001/REC-xml-c14n-20010315) for INCLUSIVE, and + C(http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments) for INCLUSIVE_WITH_COMMENTS. + + saml_single_logout_service_url_post: + description: + - SAML POST binding url for the client's single logout service. + + saml_single_logout_service_url_redirect: + description: + - SAML redirect binding url for the client's single logout service. + + user.info.response.signature.alg: + description: + - For OpenID-Connect clients, JWA algorithm for signed UserInfo-endpoint responses. One of C(RS256) or C(unsigned). + + request.object.signature.alg: + description: + - For OpenID-Connect clients, JWA algorithm which the client needs to use when sending + OIDC request object. One of C(any), C(none), C(RS256). + + use.jwks.url: + description: + - For OpenID-Connect clients, boolean specifying whether to use a JWKS URL to obtain client + public keys. + + jwks.url: + description: + - For OpenID-Connect clients, URL where client keys in JWK are stored. + + jwt.credential.certificate: + description: + - For OpenID-Connect clients, client certificate for validating JWT issued by + client and signed by its key, base64-encoded. + +extends_documentation_fragment: + - middleware_automation.keycloak.keycloak + - middleware_automation.keycloak.attributes + +author: + - Eike Frost (@eikef) +''' + +EXAMPLES = ''' +- name: Create or update Keycloak client (minimal example), authentication with credentials + middleware_automation.keycloak.keycloak_client: + auth_keycloak_url: https://auth.example.com/auth + auth_realm: master + auth_username: USERNAME + auth_password: PASSWORD + client_id: test + state: present + delegate_to: localhost + + +- name: Create or update Keycloak client (minimal example), authentication with token + middleware_automation.keycloak.keycloak_client: + auth_client_id: admin-cli + auth_keycloak_url: https://auth.example.com/auth + auth_realm: master + token: TOKEN + client_id: test + state: present + delegate_to: localhost + + +- name: Delete a Keycloak client + middleware_automation.keycloak.keycloak_client: + auth_client_id: admin-cli + auth_keycloak_url: https://auth.example.com/auth + auth_realm: master + auth_username: USERNAME + auth_password: PASSWORD + client_id: test + state: absent + delegate_to: localhost + + +- name: Create or update a Keycloak client (with all the bells and whistles) + middleware_automation.keycloak.keycloak_client: + auth_client_id: admin-cli + auth_keycloak_url: https://auth.example.com/auth + auth_realm: master + auth_username: USERNAME + auth_password: PASSWORD + state: present + realm: master + client_id: test + id: d8b127a3-31f6-44c8-a7e4-4ab9a3e78d95 + name: this_is_a_test + description: Description of this wonderful client + root_url: https://www.example.com/ + admin_url: https://www.example.com/admin_url + base_url: basepath + enabled: true + client_authenticator_type: client-secret + secret: REALLYWELLKEPTSECRET + redirect_uris: + - https://www.example.com/* + - http://localhost:8888/ + web_origins: + - https://www.example.com/* + not_before: 1507825725 + bearer_only: false + consent_required: false + standard_flow_enabled: true + implicit_flow_enabled: false + direct_access_grants_enabled: false + service_accounts_enabled: false + authorization_services_enabled: false + public_client: false + frontchannel_logout: false + protocol: openid-connect + full_scope_allowed: false + node_re_registration_timeout: -1 + client_template: test + use_template_config: false + use_template_scope: false + use_template_mappers: false + always_display_in_console: true + registered_nodes: + node01.example.com: 1507828202 + registration_access_token: eyJWT_TOKEN + surrogate_auth_required: false + default_roles: + - test01 + - test02 + authentication_flow_binding_overrides: + browser: 4c90336b-bf1d-4b87-916d-3677ba4e5fbb + protocol_mappers: + - config: + access.token.claim: true + claim.name: "family_name" + id.token.claim: true + jsonType.label: String + user.attribute: lastName + userinfo.token.claim: true + consentRequired: true + consentText: "${familyName}" + name: family name + protocol: openid-connect + protocolMapper: oidc-usermodel-property-mapper + - config: + attribute.name: Role + attribute.nameformat: Basic + single: false + consentRequired: false + name: role list + protocol: saml + protocolMapper: saml-role-list-mapper + attributes: + saml.authnstatement: true + saml.client.signature: true + saml.force.post.binding: true + saml.server.signature: true + saml.signature.algorithm: RSA_SHA256 + saml.signing.certificate: CERTIFICATEHERE + saml.signing.private.key: PRIVATEKEYHERE + saml_force_name_id_format: false + saml_name_id_format: username + saml_signature_canonicalization_method: "http://www.w3.org/2001/10/xml-exc-c14n#" + user.info.response.signature.alg: RS256 + request.object.signature.alg: RS256 + use.jwks.url: true + jwks.url: JWKS_URL_FOR_CLIENT_AUTH_JWT + jwt.credential.certificate: JWT_CREDENTIAL_CERTIFICATE_FOR_CLIENT_AUTH + delegate_to: localhost +''' + +RETURN = ''' +msg: + description: Message as to what action was taken. + returned: always + type: str + sample: "Client testclient has been updated" + +proposed: + description: Representation of proposed client. + returned: always + type: dict + sample: { + clientId: "test" + } + +existing: + description: Representation of existing client (sample is truncated). + returned: always + type: dict + sample: { + "adminUrl": "http://www.example.com/admin_url", + "attributes": { + "request.object.signature.alg": "RS256", + } + } + +end_state: + description: Representation of client after module execution (sample is truncated). + returned: on success + type: dict + sample: { + "adminUrl": "http://www.example.com/admin_url", + "attributes": { + "request.object.signature.alg": "RS256", + } + } +''' + +from ansible_collections.middleware_automation.keycloak.plugins.module_utils.identity.keycloak.keycloak import KeycloakAPI, camel, \ + keycloak_argument_spec, get_token, KeycloakError +from ansible.module_utils.basic import AnsibleModule +import copy + + +def normalise_cr(clientrep, remove_ids=False): + """ Re-sorts any properties where the order so that diff's is minimised, and adds default values where appropriate so that the + the change detection is more effective. + + :param clientrep: the clientrep dict to be sanitized + :param remove_ids: If set to true, then the unique ID's of objects is removed to make the diff and checks for changed + not alert when the ID's of objects are not usually known, (e.g. for protocol_mappers) + :return: normalised clientrep dict + """ + # Avoid the dict passed in to be modified + clientrep = clientrep.copy() + + if 'attributes' in clientrep: + clientrep['attributes'] = list(sorted(clientrep['attributes'])) + + if 'redirectUris' in clientrep: + clientrep['redirectUris'] = list(sorted(clientrep['redirectUris'])) + + if 'protocolMappers' in clientrep: + clientrep['protocolMappers'] = sorted(clientrep['protocolMappers'], key=lambda x: (x.get('name'), x.get('protocol'), x.get('protocolMapper'))) + for mapper in clientrep['protocolMappers']: + if remove_ids: + mapper.pop('id', None) + + # Set to a default value. + mapper['consentRequired'] = mapper.get('consentRequired', False) + + return clientrep + + +def sanitize_cr(clientrep): + """ Removes probably sensitive details from a client representation. + + :param clientrep: the clientrep dict to be sanitized + :return: sanitized clientrep dict + """ + result = copy.deepcopy(clientrep) + if 'secret' in result: + result['secret'] = 'no_log' + if 'attributes' in result: + if 'saml.signing.private.key' in result['attributes']: + result['attributes']['saml.signing.private.key'] = 'no_log' + return normalise_cr(result) + + +def main(): + """ + Module execution + + :return: + """ + argument_spec = keycloak_argument_spec() + + protmapper_spec = dict( + consentRequired=dict(type='bool'), + consentText=dict(type='str'), + id=dict(type='str'), + name=dict(type='str'), + protocol=dict(type='str', choices=['openid-connect', 'saml']), + protocolMapper=dict(type='str'), + config=dict(type='dict'), + ) + + meta_args = dict( + state=dict(default='present', choices=['present', 'absent']), + realm=dict(type='str', default='master'), + + id=dict(type='str'), + client_id=dict(type='str', aliases=['clientId']), + name=dict(type='str'), + description=dict(type='str'), + root_url=dict(type='str', aliases=['rootUrl']), + admin_url=dict(type='str', aliases=['adminUrl']), + base_url=dict(type='str', aliases=['baseUrl']), + surrogate_auth_required=dict(type='bool', aliases=['surrogateAuthRequired']), + enabled=dict(type='bool'), + client_authenticator_type=dict(type='str', choices=['client-secret', 'client-jwt'], aliases=['clientAuthenticatorType']), + secret=dict(type='str', no_log=True), + registration_access_token=dict(type='str', aliases=['registrationAccessToken'], no_log=True), + default_roles=dict(type='list', elements='str', aliases=['defaultRoles']), + redirect_uris=dict(type='list', elements='str', aliases=['redirectUris']), + web_origins=dict(type='list', elements='str', aliases=['webOrigins']), + not_before=dict(type='int', aliases=['notBefore']), + bearer_only=dict(type='bool', aliases=['bearerOnly']), + consent_required=dict(type='bool', aliases=['consentRequired']), + standard_flow_enabled=dict(type='bool', aliases=['standardFlowEnabled']), + implicit_flow_enabled=dict(type='bool', aliases=['implicitFlowEnabled']), + direct_access_grants_enabled=dict(type='bool', aliases=['directAccessGrantsEnabled']), + service_accounts_enabled=dict(type='bool', aliases=['serviceAccountsEnabled']), + authorization_services_enabled=dict(type='bool', aliases=['authorizationServicesEnabled']), + public_client=dict(type='bool', aliases=['publicClient']), + frontchannel_logout=dict(type='bool', aliases=['frontchannelLogout']), + protocol=dict(type='str', choices=['openid-connect', 'saml']), + attributes=dict(type='dict'), + full_scope_allowed=dict(type='bool', aliases=['fullScopeAllowed']), + node_re_registration_timeout=dict(type='int', aliases=['nodeReRegistrationTimeout']), + registered_nodes=dict(type='dict', aliases=['registeredNodes']), + client_template=dict(type='str', aliases=['clientTemplate']), + use_template_config=dict(type='bool', aliases=['useTemplateConfig']), + use_template_scope=dict(type='bool', aliases=['useTemplateScope']), + use_template_mappers=dict(type='bool', aliases=['useTemplateMappers']), + always_display_in_console=dict(type='bool', aliases=['alwaysDisplayInConsole']), + authentication_flow_binding_overrides=dict(type='dict', aliases=['authenticationFlowBindingOverrides']), + protocol_mappers=dict(type='list', elements='dict', options=protmapper_spec, aliases=['protocolMappers']), + authorization_settings=dict(type='dict', aliases=['authorizationSettings']), + default_client_scopes=dict(type='list', elements='str', aliases=['defaultClientScopes']), + optional_client_scopes=dict(type='list', elements='str', aliases=['optionalClientScopes']), + ) + + argument_spec.update(meta_args) + + module = AnsibleModule(argument_spec=argument_spec, + supports_check_mode=True, + required_one_of=([['client_id', 'id'], + ['token', 'auth_realm', 'auth_username', 'auth_password']]), + required_together=([['auth_realm', 'auth_username', 'auth_password']])) + + result = dict(changed=False, msg='', diff={}, proposed={}, existing={}, end_state={}) + + # Obtain access token, initialize API + try: + connection_header = get_token(module.params) + except KeycloakError as e: + module.fail_json(msg=str(e)) + + kc = KeycloakAPI(module, connection_header) + + realm = module.params.get('realm') + cid = module.params.get('id') + state = module.params.get('state') + + # Filter and map the parameters names that apply to the client + client_params = [x for x in module.params + if x not in list(keycloak_argument_spec().keys()) + ['state', 'realm'] and + module.params.get(x) is not None] + + # See if it already exists in Keycloak + if cid is None: + before_client = kc.get_client_by_clientid(module.params.get('client_id'), realm=realm) + if before_client is not None: + cid = before_client['id'] + else: + before_client = kc.get_client_by_id(cid, realm=realm) + + if before_client is None: + before_client = {} + + # Build a proposed changeset from parameters given to this module + changeset = {} + + for client_param in client_params: + new_param_value = module.params.get(client_param) + + # some lists in the Keycloak API are sorted, some are not. + if isinstance(new_param_value, list): + if client_param in ['attributes']: + try: + new_param_value = sorted(new_param_value) + except TypeError: + pass + # Unfortunately, the ansible argument spec checker introduces variables with null values when + # they are not specified + if client_param == 'protocol_mappers': + new_param_value = [dict((k, v) for k, v in x.items() if x[k] is not None) for x in new_param_value] + + changeset[camel(client_param)] = new_param_value + + # Prepare the desired values using the existing values (non-existence results in a dict that is save to use as a basis) + desired_client = before_client.copy() + desired_client.update(changeset) + + result['proposed'] = sanitize_cr(changeset) + result['existing'] = sanitize_cr(before_client) + + # Cater for when it doesn't exist (an empty dict) + if not before_client: + if state == 'absent': + # Do nothing and exit + if module._diff: + result['diff'] = dict(before='', after='') + result['changed'] = False + result['end_state'] = {} + result['msg'] = 'Client does not exist; doing nothing.' + module.exit_json(**result) + + # Process a creation + result['changed'] = True + + if 'clientId' not in desired_client: + module.fail_json(msg='client_id needs to be specified when creating a new client') + + if module._diff: + result['diff'] = dict(before='', after=sanitize_cr(desired_client)) + + if module.check_mode: + module.exit_json(**result) + + # create it + kc.create_client(desired_client, realm=realm) + after_client = kc.get_client_by_clientid(desired_client['clientId'], realm=realm) + + result['end_state'] = sanitize_cr(after_client) + + result['msg'] = 'Client %s has been created.' % desired_client['clientId'] + module.exit_json(**result) + + else: + if state == 'present': + # Process an update + result['changed'] = True + + if module.check_mode: + # We can only compare the current client with the proposed updates we have + before_norm = normalise_cr(before_client, remove_ids=True) + desired_norm = normalise_cr(desired_client, remove_ids=True) + if module._diff: + result['diff'] = dict(before=sanitize_cr(before_norm), + after=sanitize_cr(desired_norm)) + result['changed'] = (before_norm != desired_norm) + + module.exit_json(**result) + + # do the update + kc.update_client(cid, desired_client, realm=realm) + + after_client = kc.get_client_by_id(cid, realm=realm) + if before_client == after_client: + result['changed'] = False + if module._diff: + result['diff'] = dict(before=sanitize_cr(before_client), + after=sanitize_cr(after_client)) + + result['end_state'] = sanitize_cr(after_client) + + result['msg'] = 'Client %s has been updated.' % desired_client['clientId'] + module.exit_json(**result) + + else: + # Process a deletion (because state was not 'present') + result['changed'] = True + + if module._diff: + result['diff'] = dict(before=sanitize_cr(before_client), after='') + + if module.check_mode: + module.exit_json(**result) + + # delete it + kc.delete_client(cid, realm=realm) + result['proposed'] = {} + + result['end_state'] = {} + + result['msg'] = 'Client %s has been deleted.' % before_client['clientId'] + + module.exit_json(**result) + + +if __name__ == '__main__': + main() diff --git a/plugins/modules/keycloak_role.py b/plugins/modules/keycloak_role.py new file mode 100644 index 0000000..0045d0e --- /dev/null +++ b/plugins/modules/keycloak_role.py @@ -0,0 +1,374 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2019, Adam Goossens +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: keycloak_role + +short_description: Allows administration of Keycloak roles via Keycloak API + +version_added: 3.4.0 + +description: + - This module allows you to add, remove or modify Keycloak roles via the Keycloak REST API. + It requires access to the REST API via OpenID Connect; the user connecting and the client being + used must have the requisite access rights. In a default Keycloak installation, admin-cli + and an admin user would work, as would a separate client definition with the scope tailored + to your needs and a user having the expected roles. + + - The names of module options are snake_cased versions of the camelCase ones found in the + Keycloak API and its documentation at U(https://www.keycloak.org/docs-api/8.0/rest-api/index.html). + + - Attributes are multi-valued in the Keycloak API. All attributes are lists of individual values and will + be returned that way by this module. You may pass single values for attributes when calling the module, + and this will be translated into a list suitable for the API. + +attributes: + check_mode: + support: full + diff_mode: + support: full + +options: + state: + description: + - State of the role. + - On C(present), the role will be created if it does not yet exist, or updated with the parameters you provide. + - On C(absent), the role will be removed if it exists. + default: 'present' + type: str + choices: + - present + - absent + + name: + type: str + required: true + description: + - Name of the role. + - This parameter is required. + + description: + type: str + description: + - The role description. + + realm: + type: str + description: + - The Keycloak realm under which this role resides. + default: 'master' + + client_id: + type: str + description: + - If the role is a client role, the client id under which it resides. + - If this parameter is absent, the role is considered a realm role. + + attributes: + type: dict + description: + - A dict of key/value pairs to set as custom attributes for the role. + - Values may be single values (e.g. a string) or a list of strings. + +extends_documentation_fragment: + - middleware_automation.keycloak.keycloak + - middleware_automation.keycloak.attributes + +author: + - Laurent Paumier (@laurpaum) +''' + +EXAMPLES = ''' +- name: Create a Keycloak realm role, authentication with credentials + middleware_automation.keycloak.keycloak_role: + name: my-new-kc-role + realm: MyCustomRealm + state: present + auth_client_id: admin-cli + auth_keycloak_url: https://auth.example.com/auth + auth_realm: master + auth_username: USERNAME + auth_password: PASSWORD + delegate_to: localhost + +- name: Create a Keycloak realm role, authentication with token + middleware_automation.keycloak.keycloak_role: + name: my-new-kc-role + realm: MyCustomRealm + state: present + auth_client_id: admin-cli + auth_keycloak_url: https://auth.example.com/auth + token: TOKEN + delegate_to: localhost + +- name: Create a Keycloak client role + middleware_automation.keycloak.keycloak_role: + name: my-new-kc-role + realm: MyCustomRealm + client_id: MyClient + state: present + auth_client_id: admin-cli + auth_keycloak_url: https://auth.example.com/auth + auth_realm: master + auth_username: USERNAME + auth_password: PASSWORD + delegate_to: localhost + +- name: Delete a Keycloak role + middleware_automation.keycloak.keycloak_role: + name: my-role-for-deletion + state: absent + auth_client_id: admin-cli + auth_keycloak_url: https://auth.example.com/auth + auth_realm: master + auth_username: USERNAME + auth_password: PASSWORD + delegate_to: localhost + +- name: Create a keycloak role with some custom attributes + middleware_automation.keycloak.keycloak_role: + auth_client_id: admin-cli + auth_keycloak_url: https://auth.example.com/auth + auth_realm: master + auth_username: USERNAME + auth_password: PASSWORD + name: my-new-role + attributes: + attrib1: value1 + attrib2: value2 + attrib3: + - with + - numerous + - individual + - list + - items + delegate_to: localhost +''' + +RETURN = ''' +msg: + description: Message as to what action was taken. + returned: always + type: str + sample: "Role myrole has been updated" + +proposed: + description: Representation of proposed role. + returned: always + type: dict + sample: { + "description": "My updated test description" + } + +existing: + description: Representation of existing role. + returned: always + type: dict + sample: { + "attributes": {}, + "clientRole": true, + "composite": false, + "containerId": "9f03eb61-a826-4771-a9fd-930e06d2d36a", + "description": "My client test role", + "id": "561703dd-0f38-45ff-9a5a-0c978f794547", + "name": "myrole" + } + +end_state: + description: Representation of role after module execution (sample is truncated). + returned: on success + type: dict + sample: { + "attributes": {}, + "clientRole": true, + "composite": false, + "containerId": "9f03eb61-a826-4771-a9fd-930e06d2d36a", + "description": "My updated client test role", + "id": "561703dd-0f38-45ff-9a5a-0c978f794547", + "name": "myrole" + } +''' + +from ansible_collections.middleware_automation.keycloak.plugins.module_utils.identity.keycloak.keycloak import KeycloakAPI, camel, \ + keycloak_argument_spec, get_token, KeycloakError +from ansible.module_utils.basic import AnsibleModule + + +def main(): + """ + Module execution + + :return: + """ + argument_spec = keycloak_argument_spec() + + meta_args = dict( + state=dict(type='str', default='present', choices=['present', 'absent']), + name=dict(type='str', required=True), + description=dict(type='str'), + realm=dict(type='str', default='master'), + client_id=dict(type='str'), + attributes=dict(type='dict'), + ) + + argument_spec.update(meta_args) + + module = AnsibleModule(argument_spec=argument_spec, + supports_check_mode=True, + required_one_of=([['token', 'auth_realm', 'auth_username', 'auth_password']]), + required_together=([['auth_realm', 'auth_username', 'auth_password']])) + + result = dict(changed=False, msg='', diff={}, proposed={}, existing={}, end_state={}) + + # Obtain access token, initialize API + try: + connection_header = get_token(module.params) + except KeycloakError as e: + module.fail_json(msg=str(e)) + + kc = KeycloakAPI(module, connection_header) + + realm = module.params.get('realm') + clientid = module.params.get('client_id') + name = module.params.get('name') + state = module.params.get('state') + + # attributes in Keycloak have their values returned as lists + # via the API. attributes is a dict, so we'll transparently convert + # the values to lists. + if module.params.get('attributes') is not None: + for key, val in module.params['attributes'].items(): + module.params['attributes'][key] = [val] if not isinstance(val, list) else val + + # Filter and map the parameters names that apply to the role + role_params = [x for x in module.params + if x not in list(keycloak_argument_spec().keys()) + ['state', 'realm', 'client_id', 'composites'] and + module.params.get(x) is not None] + + # See if it already exists in Keycloak + if clientid is None: + before_role = kc.get_realm_role(name, realm) + else: + before_role = kc.get_client_role(name, clientid, realm) + + if before_role is None: + before_role = {} + + # Build a proposed changeset from parameters given to this module + changeset = {} + + for param in role_params: + new_param_value = module.params.get(param) + old_value = before_role[param] if param in before_role else None + if new_param_value != old_value: + changeset[camel(param)] = new_param_value + + # Prepare the desired values using the existing values (non-existence results in a dict that is save to use as a basis) + desired_role = before_role.copy() + desired_role.update(changeset) + + result['proposed'] = changeset + result['existing'] = before_role + + # Cater for when it doesn't exist (an empty dict) + if not before_role: + if state == 'absent': + # Do nothing and exit + if module._diff: + result['diff'] = dict(before='', after='') + result['changed'] = False + result['end_state'] = {} + result['msg'] = 'Role does not exist, doing nothing.' + module.exit_json(**result) + + # Process a creation + result['changed'] = True + + if name is None: + module.fail_json(msg='name must be specified when creating a new role') + + if module._diff: + result['diff'] = dict(before='', after=desired_role) + + if module.check_mode: + module.exit_json(**result) + + # create it + if clientid is None: + kc.create_realm_role(desired_role, realm) + after_role = kc.get_realm_role(name, realm) + else: + kc.create_client_role(desired_role, clientid, realm) + after_role = kc.get_client_role(name, clientid, realm) + + result['end_state'] = after_role + + result['msg'] = 'Role {name} has been created'.format(name=name) + module.exit_json(**result) + + else: + if state == 'present': + # Process an update + + # no changes + if desired_role == before_role: + result['changed'] = False + result['end_state'] = desired_role + result['msg'] = "No changes required to role {name}.".format(name=name) + module.exit_json(**result) + + # doing an update + result['changed'] = True + + if module._diff: + result['diff'] = dict(before=before_role, after=desired_role) + + if module.check_mode: + module.exit_json(**result) + + # do the update + if clientid is None: + kc.update_realm_role(desired_role, realm) + after_role = kc.get_realm_role(name, realm) + else: + kc.update_client_role(desired_role, clientid, realm) + after_role = kc.get_client_role(name, clientid, realm) + + result['end_state'] = after_role + + result['msg'] = "Role {name} has been updated".format(name=name) + module.exit_json(**result) + + else: + # Process a deletion (because state was not 'present') + result['changed'] = True + + if module._diff: + result['diff'] = dict(before=before_role, after='') + + if module.check_mode: + module.exit_json(**result) + + # delete it + if clientid is None: + kc.delete_realm_role(name, realm) + else: + kc.delete_client_role(name, clientid, realm) + + result['end_state'] = {} + + result['msg'] = "Role {name} has been deleted".format(name=name) + + module.exit_json(**result) + + +if __name__ == '__main__': + main() diff --git a/plugins/modules/keycloak_user_federation.py b/plugins/modules/keycloak_user_federation.py new file mode 100644 index 0000000..96f04d7 --- /dev/null +++ b/plugins/modules/keycloak_user_federation.py @@ -0,0 +1,1021 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) Ansible project +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: keycloak_user_federation + +short_description: Allows administration of Keycloak user federations via Keycloak API + +version_added: 3.7.0 + +description: + - This module allows you to add, remove or modify Keycloak user federations via the Keycloak REST API. + It requires access to the REST API via OpenID Connect; the user connecting and the client being + used must have the requisite access rights. In a default Keycloak installation, admin-cli + and an admin user would work, as would a separate client definition with the scope tailored + to your needs and a user having the expected roles. + + - The names of module options are snake_cased versions of the camelCase ones found in the + Keycloak API and its documentation at U(https://www.keycloak.org/docs-api/20.0.2/rest-api/index.html). + +attributes: + check_mode: + support: full + diff_mode: + support: full + +options: + state: + description: + - State of the user federation. + - On C(present), the user federation will be created if it does not yet exist, or updated with + the parameters you provide. + - On C(absent), the user federation will be removed if it exists. + default: 'present' + type: str + choices: + - present + - absent + + realm: + description: + - The Keycloak realm under which this user federation resides. + default: 'master' + type: str + + id: + description: + - The unique ID for this user federation. If left empty, the user federation will be searched + by its I(name). + type: str + + name: + description: + - Display name of provider when linked in admin console. + type: str + + provider_id: + description: + - Provider for this user federation. + aliases: + - providerId + type: str + choices: + - ldap + - kerberos + - sssd + + provider_type: + description: + - Component type for user federation (only supported value is C(org.keycloak.storage.UserStorageProvider)). + aliases: + - providerType + default: org.keycloak.storage.UserStorageProvider + type: str + + parent_id: + description: + - Unique ID for the parent of this user federation. Realm ID will be automatically used if left blank. + aliases: + - parentId + type: str + + config: + description: + - Dict specifying the configuration options for the provider; the contents differ depending on + the value of I(provider_id). Examples are given below for C(ldap), C(kerberos) and C(sssd). + It is easiest to obtain valid config values by dumping an already-existing user federation + configuration through check-mode in the I(existing) field. + - The value C(sssd) has been supported since middleware_automation.keycloak 1.0.0. + type: dict + suboptions: + enabled: + description: + - Enable/disable this user federation. + default: true + type: bool + + priority: + description: + - Priority of provider when doing a user lookup. Lowest first. + default: 0 + type: int + + importEnabled: + description: + - If C(true), LDAP users will be imported into Keycloak DB and synced by the configured + sync policies. + default: true + type: bool + + editMode: + description: + - C(READ_ONLY) is a read-only LDAP store. C(WRITABLE) means data will be synced back to LDAP + on demand. C(UNSYNCED) means user data will be imported, but not synced back to LDAP. + type: str + choices: + - READ_ONLY + - WRITABLE + - UNSYNCED + + syncRegistrations: + description: + - Should newly created users be created within LDAP store? Priority effects which + provider is chosen to sync the new user. + default: false + type: bool + + vendor: + description: + - LDAP vendor (provider). + - Use short name. For instance, write C(rhds) for "Red Hat Directory Server". + type: str + + usernameLDAPAttribute: + description: + - Name of LDAP attribute, which is mapped as Keycloak username. For many LDAP server + vendors it can be C(uid). For Active directory it can be C(sAMAccountName) or C(cn). + The attribute should be filled for all LDAP user records you want to import from + LDAP to Keycloak. + type: str + + rdnLDAPAttribute: + description: + - Name of LDAP attribute, which is used as RDN (top attribute) of typical user DN. + Usually it's the same as Username LDAP attribute, however it is not required. For + example for Active directory, it is common to use C(cn) as RDN attribute when + username attribute might be C(sAMAccountName). + type: str + + uuidLDAPAttribute: + description: + - Name of LDAP attribute, which is used as unique object identifier (UUID) for objects + in LDAP. For many LDAP server vendors, it is C(entryUUID); however some are different. + For example for Active directory it should be C(objectGUID). If your LDAP server does + not support the notion of UUID, you can use any other attribute that is supposed to + be unique among LDAP users in tree. + type: str + + userObjectClasses: + description: + - All values of LDAP objectClass attribute for users in LDAP divided by comma. + For example C(inetOrgPerson, organizationalPerson). Newly created Keycloak users + will be written to LDAP with all those object classes and existing LDAP user records + are found just if they contain all those object classes. + type: str + + connectionUrl: + description: + - Connection URL to your LDAP server. + type: str + + usersDn: + description: + - Full DN of LDAP tree where your users are. This DN is the parent of LDAP users. + type: str + + customUserSearchFilter: + description: + - Additional LDAP Filter for filtering searched users. Leave this empty if you don't + need additional filter. + type: str + + searchScope: + description: + - For one level, the search applies only for users in the DNs specified by User DNs. + For subtree, the search applies to the whole subtree. See LDAP documentation for + more details. + default: '1' + type: str + choices: + - '1' + - '2' + + authType: + description: + - Type of the Authentication method used during LDAP Bind operation. It is used in + most of the requests sent to the LDAP server. + default: 'none' + type: str + choices: + - none + - simple + + bindDn: + description: + - DN of LDAP user which will be used by Keycloak to access LDAP server. + type: str + + bindCredential: + description: + - Password of LDAP admin. + type: str + + startTls: + description: + - Encrypts the connection to LDAP using STARTTLS, which will disable connection pooling. + default: false + type: bool + + usePasswordModifyExtendedOp: + description: + - Use the LDAPv3 Password Modify Extended Operation (RFC-3062). The password modify + extended operation usually requires that LDAP user already has password in the LDAP + server. So when this is used with 'Sync Registrations', it can be good to add also + 'Hardcoded LDAP attribute mapper' with randomly generated initial password. + default: false + type: bool + + validatePasswordPolicy: + description: + - Determines if Keycloak should validate the password with the realm password policy + before updating it. + default: false + type: bool + + trustEmail: + description: + - If enabled, email provided by this provider is not verified even if verification is + enabled for the realm. + default: false + type: bool + + useTruststoreSpi: + description: + - Specifies whether LDAP connection will use the truststore SPI with the truststore + configured in standalone.xml/domain.xml. C(Always) means that it will always use it. + C(Never) means that it will not use it. C(Only for ldaps) means that it will use if + your connection URL use ldaps. Note even if standalone.xml/domain.xml is not + configured, the default Java cacerts or certificate specified by + C(javax.net.ssl.trustStore) property will be used. + default: ldapsOnly + type: str + choices: + - always + - ldapsOnly + - never + + connectionTimeout: + description: + - LDAP Connection Timeout in milliseconds. + type: int + + readTimeout: + description: + - LDAP Read Timeout in milliseconds. This timeout applies for LDAP read operations. + type: int + + pagination: + description: + - Does the LDAP server support pagination. + default: true + type: bool + + connectionPooling: + description: + - Determines if Keycloak should use connection pooling for accessing LDAP server. + default: true + type: bool + + connectionPoolingAuthentication: + description: + - A list of space-separated authentication types of connections that may be pooled. + type: str + choices: + - none + - simple + - DIGEST-MD5 + + connectionPoolingDebug: + description: + - A string that indicates the level of debug output to produce. Example valid values are + C(fine) (trace connection creation and removal) and C(all) (all debugging information). + type: str + + connectionPoolingInitSize: + description: + - The number of connections per connection identity to create when initially creating a + connection for the identity. + type: int + + connectionPoolingMaxSize: + description: + - The maximum number of connections per connection identity that can be maintained + concurrently. + type: int + + connectionPoolingPrefSize: + description: + - The preferred number of connections per connection identity that should be maintained + concurrently. + type: int + + connectionPoolingProtocol: + description: + - A list of space-separated protocol types of connections that may be pooled. + Valid types are C(plain) and C(ssl). + type: str + + connectionPoolingTimeout: + description: + - The number of milliseconds that an idle connection may remain in the pool without + being closed and removed from the pool. + type: int + + allowKerberosAuthentication: + description: + - Enable/disable HTTP authentication of users with SPNEGO/Kerberos tokens. The data + about authenticated users will be provisioned from this LDAP server. + default: false + type: bool + + kerberosRealm: + description: + - Name of kerberos realm. + type: str + + serverPrincipal: + description: + - Full name of server principal for HTTP service including server and domain name. For + example C(HTTP/host.foo.org@FOO.ORG). Use C(*) to accept any service principal in the + KeyTab file. + type: str + + keyTab: + description: + - Location of Kerberos KeyTab file containing the credentials of server principal. For + example C(/etc/krb5.keytab). + type: str + + debug: + description: + - Enable/disable debug logging to standard output for Krb5LoginModule. + type: bool + + useKerberosForPasswordAuthentication: + description: + - Use Kerberos login module for authenticate username/password against Kerberos server + instead of authenticating against LDAP server with Directory Service API. + default: false + type: bool + + allowPasswordAuthentication: + description: + - Enable/disable possibility of username/password authentication against Kerberos database. + type: bool + + batchSizeForSync: + description: + - Count of LDAP users to be imported from LDAP to Keycloak within a single transaction. + default: 1000 + type: int + + fullSyncPeriod: + description: + - Period for full synchronization in seconds. + default: -1 + type: int + + changedSyncPeriod: + description: + - Period for synchronization of changed or newly created LDAP users in seconds. + default: -1 + type: int + + updateProfileFirstLogin: + description: + - Update profile on first login. + type: bool + + cachePolicy: + description: + - Cache Policy for this storage provider. + type: str + default: 'DEFAULT' + choices: + - DEFAULT + - EVICT_DAILY + - EVICT_WEEKLY + - MAX_LIFESPAN + - NO_CACHE + + evictionDay: + description: + - Day of the week the entry will become invalid on. + type: str + + evictionHour: + description: + - Hour of day the entry will become invalid on. + type: str + + evictionMinute: + description: + - Minute of day the entry will become invalid on. + type: str + + maxLifespan: + description: + - Max lifespan of cache entry in milliseconds. + type: int + + mappers: + description: + - A list of dicts defining mappers associated with this Identity Provider. + type: list + elements: dict + suboptions: + id: + description: + - Unique ID of this mapper. + type: str + + name: + description: + - Name of the mapper. If no ID is given, the mapper will be searched by name. + type: str + + parentId: + description: + - Unique ID for the parent of this mapper. ID of the user federation will automatically + be used if left blank. + type: str + + providerId: + description: + - The mapper type for this mapper (for instance C(user-attribute-ldap-mapper)). + type: str + + providerType: + description: + - Component type for this mapper. + type: str + default: org.keycloak.storage.ldap.mappers.LDAPStorageMapper + + config: + description: + - Dict specifying the configuration options for the mapper; the contents differ + depending on the value of I(identityProviderMapper). + type: dict + +extends_documentation_fragment: + - middleware_automation.keycloak.keycloak + - middleware_automation.keycloak.attributes + +author: + - Laurent Paumier (@laurpaum) +''' + +EXAMPLES = ''' + - name: Create LDAP user federation + middleware_automation.keycloak.keycloak_user_federation: + auth_keycloak_url: https://keycloak.example.com/auth + auth_realm: master + auth_username: admin + auth_password: password + realm: my-realm + name: my-ldap + state: present + provider_id: ldap + provider_type: org.keycloak.storage.UserStorageProvider + config: + priority: 0 + enabled: true + cachePolicy: DEFAULT + batchSizeForSync: 1000 + editMode: READ_ONLY + importEnabled: true + syncRegistrations: false + vendor: other + usernameLDAPAttribute: uid + rdnLDAPAttribute: uid + uuidLDAPAttribute: entryUUID + userObjectClasses: inetOrgPerson, organizationalPerson + connectionUrl: ldaps://ldap.example.com:636 + usersDn: ou=Users,dc=example,dc=com + authType: simple + bindDn: cn=directory reader + bindCredential: password + searchScope: 1 + validatePasswordPolicy: false + trustEmail: false + useTruststoreSpi: ldapsOnly + connectionPooling: true + pagination: true + allowKerberosAuthentication: false + debug: false + useKerberosForPasswordAuthentication: false + mappers: + - name: "full name" + providerId: "full-name-ldap-mapper" + providerType: "org.keycloak.storage.ldap.mappers.LDAPStorageMapper" + config: + ldap.full.name.attribute: cn + read.only: true + write.only: false + + - name: Create Kerberos user federation + middleware_automation.keycloak.keycloak_user_federation: + auth_keycloak_url: https://keycloak.example.com/auth + auth_realm: master + auth_username: admin + auth_password: password + realm: my-realm + name: my-kerberos + state: present + provider_id: kerberos + provider_type: org.keycloak.storage.UserStorageProvider + config: + priority: 0 + enabled: true + cachePolicy: DEFAULT + kerberosRealm: EXAMPLE.COM + serverPrincipal: HTTP/host.example.com@EXAMPLE.COM + keyTab: keytab + allowPasswordAuthentication: false + updateProfileFirstLogin: false + + - name: Create sssd user federation + middleware_automation.keycloak.keycloak_user_federation: + auth_keycloak_url: https://keycloak.example.com/auth + auth_realm: master + auth_username: admin + auth_password: password + realm: my-realm + name: my-sssd + state: present + provider_id: sssd + provider_type: org.keycloak.storage.UserStorageProvider + config: + priority: 0 + enabled: true + cachePolicy: DEFAULT + + - name: Delete user federation + middleware_automation.keycloak.keycloak_user_federation: + auth_keycloak_url: https://keycloak.example.com/auth + auth_realm: master + auth_username: admin + auth_password: password + realm: my-realm + name: my-federation + state: absent + +''' + +RETURN = ''' +msg: + description: Message as to what action was taken. + returned: always + type: str + sample: "No changes required to user federation 164bb483-c613-482e-80fe-7f1431308799." + +proposed: + description: Representation of proposed user federation. + returned: always + type: dict + sample: { + "config": { + "allowKerberosAuthentication": "false", + "authType": "simple", + "batchSizeForSync": "1000", + "bindCredential": "**********", + "bindDn": "cn=directory reader", + "cachePolicy": "DEFAULT", + "connectionPooling": "true", + "connectionUrl": "ldaps://ldap.example.com:636", + "debug": "false", + "editMode": "READ_ONLY", + "enabled": "true", + "importEnabled": "true", + "pagination": "true", + "priority": "0", + "rdnLDAPAttribute": "uid", + "searchScope": "1", + "syncRegistrations": "false", + "trustEmail": "false", + "useKerberosForPasswordAuthentication": "false", + "useTruststoreSpi": "ldapsOnly", + "userObjectClasses": "inetOrgPerson, organizationalPerson", + "usernameLDAPAttribute": "uid", + "usersDn": "ou=Users,dc=example,dc=com", + "uuidLDAPAttribute": "entryUUID", + "validatePasswordPolicy": "false", + "vendor": "other" + }, + "name": "ldap", + "providerId": "ldap", + "providerType": "org.keycloak.storage.UserStorageProvider" + } + +existing: + description: Representation of existing user federation. + returned: always + type: dict + sample: { + "config": { + "allowKerberosAuthentication": "false", + "authType": "simple", + "batchSizeForSync": "1000", + "bindCredential": "**********", + "bindDn": "cn=directory reader", + "cachePolicy": "DEFAULT", + "changedSyncPeriod": "-1", + "connectionPooling": "true", + "connectionUrl": "ldaps://ldap.example.com:636", + "debug": "false", + "editMode": "READ_ONLY", + "enabled": "true", + "fullSyncPeriod": "-1", + "importEnabled": "true", + "pagination": "true", + "priority": "0", + "rdnLDAPAttribute": "uid", + "searchScope": "1", + "syncRegistrations": "false", + "trustEmail": "false", + "useKerberosForPasswordAuthentication": "false", + "useTruststoreSpi": "ldapsOnly", + "userObjectClasses": "inetOrgPerson, organizationalPerson", + "usernameLDAPAttribute": "uid", + "usersDn": "ou=Users,dc=example,dc=com", + "uuidLDAPAttribute": "entryUUID", + "validatePasswordPolicy": "false", + "vendor": "other" + }, + "id": "01122837-9047-4ae4-8ca0-6e2e891a765f", + "mappers": [ + { + "config": { + "always.read.value.from.ldap": "false", + "is.mandatory.in.ldap": "false", + "ldap.attribute": "mail", + "read.only": "true", + "user.model.attribute": "email" + }, + "id": "17d60ce2-2d44-4c2c-8b1f-1fba601b9a9f", + "name": "email", + "parentId": "01122837-9047-4ae4-8ca0-6e2e891a765f", + "providerId": "user-attribute-ldap-mapper", + "providerType": "org.keycloak.storage.ldap.mappers.LDAPStorageMapper" + } + ], + "name": "myfed", + "parentId": "myrealm", + "providerId": "ldap", + "providerType": "org.keycloak.storage.UserStorageProvider" + } + +end_state: + description: Representation of user federation after module execution. + returned: on success + type: dict + sample: { + "config": { + "allowPasswordAuthentication": "false", + "cachePolicy": "DEFAULT", + "enabled": "true", + "kerberosRealm": "EXAMPLE.COM", + "keyTab": "/etc/krb5.keytab", + "priority": "0", + "serverPrincipal": "HTTP/host.example.com@EXAMPLE.COM", + "updateProfileFirstLogin": "false" + }, + "id": "cf52ae4f-4471-4435-a0cf-bb620cadc122", + "mappers": [], + "name": "kerberos", + "parentId": "myrealm", + "providerId": "kerberos", + "providerType": "org.keycloak.storage.UserStorageProvider" + } +''' + +from ansible_collections.middleware_automation.keycloak.plugins.module_utils.identity.keycloak.keycloak import KeycloakAPI, camel, \ + keycloak_argument_spec, get_token, KeycloakError +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six.moves.urllib.parse import urlencode +from copy import deepcopy + + +def sanitize(comp): + compcopy = deepcopy(comp) + if 'config' in compcopy: + compcopy['config'] = dict((k, v[0]) for k, v in compcopy['config'].items()) + if 'bindCredential' in compcopy['config']: + compcopy['config']['bindCredential'] = '**********' + if 'mappers' in compcopy: + for mapper in compcopy['mappers']: + if 'config' in mapper: + mapper['config'] = dict((k, v[0]) for k, v in mapper['config'].items()) + return compcopy + + +def main(): + """ + Module execution + + :return: + """ + argument_spec = keycloak_argument_spec() + + config_spec = dict( + allowKerberosAuthentication=dict(type='bool', default=False), + allowPasswordAuthentication=dict(type='bool'), + authType=dict(type='str', choices=['none', 'simple'], default='none'), + batchSizeForSync=dict(type='int', default=1000), + bindCredential=dict(type='str', no_log=True), + bindDn=dict(type='str'), + cachePolicy=dict(type='str', choices=['DEFAULT', 'EVICT_DAILY', 'EVICT_WEEKLY', 'MAX_LIFESPAN', 'NO_CACHE'], default='DEFAULT'), + changedSyncPeriod=dict(type='int', default=-1), + connectionPooling=dict(type='bool', default=True), + connectionPoolingAuthentication=dict(type='str', choices=['none', 'simple', 'DIGEST-MD5']), + connectionPoolingDebug=dict(type='str'), + connectionPoolingInitSize=dict(type='int'), + connectionPoolingMaxSize=dict(type='int'), + connectionPoolingPrefSize=dict(type='int'), + connectionPoolingProtocol=dict(type='str'), + connectionPoolingTimeout=dict(type='int'), + connectionTimeout=dict(type='int'), + connectionUrl=dict(type='str'), + customUserSearchFilter=dict(type='str'), + debug=dict(type='bool'), + editMode=dict(type='str', choices=['READ_ONLY', 'WRITABLE', 'UNSYNCED']), + enabled=dict(type='bool', default=True), + evictionDay=dict(type='str'), + evictionHour=dict(type='str'), + evictionMinute=dict(type='str'), + fullSyncPeriod=dict(type='int', default=-1), + importEnabled=dict(type='bool', default=True), + kerberosRealm=dict(type='str'), + keyTab=dict(type='str', no_log=False), + maxLifespan=dict(type='int'), + pagination=dict(type='bool', default=True), + priority=dict(type='int', default=0), + rdnLDAPAttribute=dict(type='str'), + readTimeout=dict(type='int'), + searchScope=dict(type='str', choices=['1', '2'], default='1'), + serverPrincipal=dict(type='str'), + startTls=dict(type='bool', default=False), + syncRegistrations=dict(type='bool', default=False), + trustEmail=dict(type='bool', default=False), + updateProfileFirstLogin=dict(type='bool'), + useKerberosForPasswordAuthentication=dict(type='bool', default=False), + usePasswordModifyExtendedOp=dict(type='bool', default=False, no_log=False), + useTruststoreSpi=dict(type='str', choices=['always', 'ldapsOnly', 'never'], default='ldapsOnly'), + userObjectClasses=dict(type='str'), + usernameLDAPAttribute=dict(type='str'), + usersDn=dict(type='str'), + uuidLDAPAttribute=dict(type='str'), + validatePasswordPolicy=dict(type='bool', default=False), + vendor=dict(type='str'), + ) + + mapper_spec = dict( + id=dict(type='str'), + name=dict(type='str'), + parentId=dict(type='str'), + providerId=dict(type='str'), + providerType=dict(type='str', default='org.keycloak.storage.ldap.mappers.LDAPStorageMapper'), + config=dict(type='dict'), + ) + + meta_args = dict( + config=dict(type='dict', options=config_spec), + state=dict(type='str', default='present', choices=['present', 'absent']), + realm=dict(type='str', default='master'), + id=dict(type='str'), + name=dict(type='str'), + provider_id=dict(type='str', aliases=['providerId'], choices=['ldap', 'kerberos', 'sssd']), + provider_type=dict(type='str', aliases=['providerType'], default='org.keycloak.storage.UserStorageProvider'), + parent_id=dict(type='str', aliases=['parentId']), + mappers=dict(type='list', elements='dict', options=mapper_spec), + ) + + argument_spec.update(meta_args) + + module = AnsibleModule(argument_spec=argument_spec, + supports_check_mode=True, + required_one_of=([['id', 'name'], + ['token', 'auth_realm', 'auth_username', 'auth_password']]), + required_together=([['auth_realm', 'auth_username', 'auth_password']])) + + result = dict(changed=False, msg='', diff={}, proposed={}, existing={}, end_state={}) + + # Obtain access token, initialize API + try: + connection_header = get_token(module.params) + except KeycloakError as e: + module.fail_json(msg=str(e)) + + kc = KeycloakAPI(module, connection_header) + + realm = module.params.get('realm') + state = module.params.get('state') + config = module.params.get('config') + mappers = module.params.get('mappers') + cid = module.params.get('id') + name = module.params.get('name') + + # Keycloak API expects config parameters to be arrays containing a single string element + if config is not None: + module.params['config'] = dict((k, [str(v).lower() if not isinstance(v, str) else v]) + for k, v in config.items() if config[k] is not None) + + if mappers is not None: + for mapper in mappers: + if mapper.get('config') is not None: + mapper['config'] = dict((k, [str(v).lower() if not isinstance(v, str) else v]) + for k, v in mapper['config'].items() if mapper['config'][k] is not None) + + # Filter and map the parameters names that apply + comp_params = [x for x in module.params + if x not in list(keycloak_argument_spec().keys()) + ['state', 'realm', 'mappers'] and + module.params.get(x) is not None] + + # See if it already exists in Keycloak + if cid is None: + found = kc.get_components(urlencode(dict(type='org.keycloak.storage.UserStorageProvider', name=name)), realm) + if len(found) > 1: + module.fail_json(msg='No ID given and found multiple user federations with name `{name}`. Cannot continue.'.format(name=name)) + before_comp = next(iter(found), None) + if before_comp is not None: + cid = before_comp['id'] + else: + before_comp = kc.get_component(cid, realm) + + if before_comp is None: + before_comp = {} + + # if user federation exists, get associated mappers + if cid is not None and before_comp: + before_comp['mappers'] = sorted(kc.get_components(urlencode(dict(parent=cid)), realm), key=lambda x: x.get('name')) + + # Build a proposed changeset from parameters given to this module + changeset = {} + + for param in comp_params: + new_param_value = module.params.get(param) + old_value = before_comp[camel(param)] if camel(param) in before_comp else None + if param == 'mappers': + new_param_value = [dict((k, v) for k, v in x.items() if x[k] is not None) for x in new_param_value] + if new_param_value != old_value: + changeset[camel(param)] = new_param_value + + # special handling of mappers list to allow change detection + if module.params.get('mappers') is not None: + if module.params['provider_id'] in ['kerberos', 'sssd']: + module.fail_json(msg='Cannot configure mappers for {type} provider.'.format(type=module.params['provider_id'])) + for change in module.params['mappers']: + change = dict((k, v) for k, v in change.items() if change[k] is not None) + if change.get('id') is None and change.get('name') is None: + module.fail_json(msg='Either `name` or `id` has to be specified on each mapper.') + if cid is None: + old_mapper = {} + elif change.get('id') is not None: + old_mapper = kc.get_component(change['id'], realm) + if old_mapper is None: + old_mapper = {} + else: + found = kc.get_components(urlencode(dict(parent=cid, name=change['name'])), realm) + if len(found) > 1: + module.fail_json(msg='Found multiple mappers with name `{name}`. Cannot continue.'.format(name=change['name'])) + if len(found) == 1: + old_mapper = found[0] + else: + old_mapper = {} + new_mapper = old_mapper.copy() + new_mapper.update(change) + if new_mapper != old_mapper: + if changeset.get('mappers') is None: + changeset['mappers'] = list() + changeset['mappers'].append(new_mapper) + + # Prepare the desired values using the existing values (non-existence results in a dict that is save to use as a basis) + desired_comp = before_comp.copy() + desired_comp.update(changeset) + + result['proposed'] = sanitize(changeset) + result['existing'] = sanitize(before_comp) + + # Cater for when it doesn't exist (an empty dict) + if not before_comp: + if state == 'absent': + # Do nothing and exit + if module._diff: + result['diff'] = dict(before='', after='') + result['changed'] = False + result['end_state'] = {} + result['msg'] = 'User federation does not exist; doing nothing.' + module.exit_json(**result) + + # Process a creation + result['changed'] = True + + if module._diff: + result['diff'] = dict(before='', after=sanitize(desired_comp)) + + if module.check_mode: + module.exit_json(**result) + + # create it + desired_comp = desired_comp.copy() + updated_mappers = desired_comp.pop('mappers', []) + after_comp = kc.create_component(desired_comp, realm) + + cid = after_comp['id'] + + for mapper in updated_mappers: + found = kc.get_components(urlencode(dict(parent=cid, name=mapper['name'])), realm) + if len(found) > 1: + module.fail_json(msg='Found multiple mappers with name `{name}`. Cannot continue.'.format(name=mapper['name'])) + if len(found) == 1: + old_mapper = found[0] + else: + old_mapper = {} + + new_mapper = old_mapper.copy() + new_mapper.update(mapper) + + if new_mapper.get('id') is not None: + kc.update_component(new_mapper, realm) + else: + if new_mapper.get('parentId') is None: + new_mapper['parentId'] = after_comp['id'] + mapper = kc.create_component(new_mapper, realm) + + after_comp['mappers'] = updated_mappers + result['end_state'] = sanitize(after_comp) + + result['msg'] = "User federation {id} has been created".format(id=after_comp['id']) + module.exit_json(**result) + + else: + if state == 'present': + # Process an update + + # no changes + if desired_comp == before_comp: + result['changed'] = False + result['end_state'] = sanitize(desired_comp) + result['msg'] = "No changes required to user federation {id}.".format(id=cid) + module.exit_json(**result) + + # doing an update + result['changed'] = True + + if module._diff: + result['diff'] = dict(before=sanitize(before_comp), after=sanitize(desired_comp)) + + if module.check_mode: + module.exit_json(**result) + + # do the update + desired_comp = desired_comp.copy() + updated_mappers = desired_comp.pop('mappers', []) + kc.update_component(desired_comp, realm) + after_comp = kc.get_component(cid, realm) + + for mapper in updated_mappers: + if mapper.get('id') is not None: + kc.update_component(mapper, realm) + else: + if mapper.get('parentId') is None: + mapper['parentId'] = desired_comp['id'] + mapper = kc.create_component(mapper, realm) + + after_comp['mappers'] = updated_mappers + result['end_state'] = sanitize(after_comp) + + result['msg'] = "User federation {id} has been updated".format(id=cid) + module.exit_json(**result) + + elif state == 'absent': + # Process a deletion + result['changed'] = True + + if module._diff: + result['diff'] = dict(before=sanitize(before_comp), after='') + + if module.check_mode: + module.exit_json(**result) + + # delete it + kc.delete_component(cid, realm) + + result['end_state'] = {} + + result['msg'] = "User federation {id} has been deleted".format(id=cid) + + module.exit_json(**result) + + +if __name__ == '__main__': + main() From 7050dafcbde6aa445d295385e80c0272f96ccffa Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 7 Mar 2023 18:01:02 +0100 Subject: [PATCH 140/554] add doc_fragments --- plugins/doc_fragments/attributes.py | 93 +++++++++++++++++++++++++++++ plugins/doc_fragments/keycloak.py | 78 ++++++++++++++++++++++++ 2 files changed, 171 insertions(+) create mode 100644 plugins/doc_fragments/attributes.py create mode 100644 plugins/doc_fragments/keycloak.py diff --git a/plugins/doc_fragments/attributes.py b/plugins/doc_fragments/attributes.py new file mode 100644 index 0000000..9b8488e --- /dev/null +++ b/plugins/doc_fragments/attributes.py @@ -0,0 +1,93 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + + +class ModuleDocFragment(object): + + # Standard documentation fragment + DOCUMENTATION = r''' +options: {} +attributes: + check_mode: + description: Can run in C(check_mode) and return changed status prediction without modifying target. + diff_mode: + description: Will return details on what has changed (or possibly needs changing in C(check_mode)), when in diff mode. +''' + + PLATFORM = r''' +options: {} +attributes: + platform: + description: Target OS/families that can be operated against. + support: N/A +''' + + # Should be used together with the standard fragment + INFO_MODULE = r''' +options: {} +attributes: + check_mode: + support: full + details: + - This action does not modify state. + diff_mode: + support: N/A + details: + - This action does not modify state. +''' + + CONN = r''' +options: {} +attributes: + become: + description: Is usable alongside C(become) keywords. + connection: + description: Uses the target's configured connection information to execute code on it. + delegation: + description: Can be used in conjunction with C(delegate_to) and related keywords. +''' + + FACTS = r''' +options: {} +attributes: + facts: + description: Action returns an C(ansible_facts) dictionary that will update existing host facts. +''' + + # Should be used together with the standard fragment and the FACTS fragment + FACTS_MODULE = r''' +options: {} +attributes: + check_mode: + support: full + details: + - This action does not modify state. + diff_mode: + support: N/A + details: + - This action does not modify state. + facts: + support: full +''' + + FILES = r''' +options: {} +attributes: + safe_file_operations: + description: Uses Ansible's strict file operation functions to ensure proper permissions and avoid data corruption. +''' + + FLOW = r''' +options: {} +attributes: + action: + description: Indicates this has a corresponding action plugin so some parts of the options can be executed on the controller. + async: + description: Supports being used with the C(async) keyword. +''' diff --git a/plugins/doc_fragments/keycloak.py b/plugins/doc_fragments/keycloak.py new file mode 100644 index 0000000..5d79fad --- /dev/null +++ b/plugins/doc_fragments/keycloak.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2017, Eike Frost +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + + +class ModuleDocFragment(object): + + # Standard documentation fragment + DOCUMENTATION = r''' +options: + auth_keycloak_url: + description: + - URL to the Keycloak instance. + type: str + required: true + aliases: + - url + + auth_client_id: + description: + - OpenID Connect I(client_id) to authenticate to the API with. + type: str + default: admin-cli + + auth_realm: + description: + - Keycloak realm name to authenticate to for API access. + type: str + + auth_client_secret: + description: + - Client Secret to use in conjunction with I(auth_client_id) (if required). + type: str + + auth_username: + description: + - Username to authenticate for API access with. + type: str + aliases: + - username + + auth_password: + description: + - Password to authenticate for API access with. + type: str + aliases: + - password + + token: + description: + - Authentication token for Keycloak API. + type: str + version_added: 3.0.0 + + validate_certs: + description: + - Verify TLS certificates (do not disable this in production). + type: bool + default: true + + connection_timeout: + description: + - Controls the HTTP connections timeout period (in seconds) to Keycloak API. + type: int + default: 10 + version_added: 4.5.0 + http_agent: + description: + - Configures the HTTP User-Agent header. + type: str + default: Ansible + version_added: 5.4.0 +''' From 6e9a17bbf5ff32502e2f482cb446171baa55989d Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 8 Mar 2023 09:23:34 +0100 Subject: [PATCH 141/554] initial tcpping support --- roles/keycloak/README.md | 1 + roles/keycloak/defaults/main.yml | 2 ++ roles/keycloak/meta/argument_specs.yml | 4 ++++ roles/keycloak/tasks/install.yml | 13 +++++++++++++ .../templates/standalone-infinispan.xml.j2 | 16 +++++++++++++++- 5 files changed, 35 insertions(+), 1 deletion(-) diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index 53b8969..06f9b47 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -50,6 +50,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:---------| |`keycloak_ha_enabled`| Enable auto configuration for database backend, clustering and remote caches on infinispan | `False` | +|`keycloak_ha_discovery`| Discovery protocol for HA cluster members | `JDBC_PING` if keycloak_db_enabled else `TCPPING` | |`keycloak_db_enabled`| Enable auto configuration for database backend | `True` if `keycloak_ha_enabled` is True, else `False` | |`keycloak_admin_user`| Administration console user account | `admin` | |`keycloak_bind_address`| Address for binding service ports | `0.0.0.0` | diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 06320a1..3cfe827 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -46,6 +46,8 @@ keycloak_prefer_ipv4: True keycloak_ha_enabled: False ### Enable database configuration, must be enabled when HA is configured keycloak_db_enabled: "{{ True if keycloak_ha_enabled else False }}" +### Discovery protocol for ha cluster members, valus [ 'JDBC_PING', 'TCPPING' ] +keycloak_ha_discovery: "{{ 'JDBC_PING' if keycloak_db_enabled else 'TCPPING' }}" ### Keycloak administration console user keycloak_admin_user: admin diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 1f6f10f..382bf70 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -148,6 +148,10 @@ argument_specs: default: false description: "Enable auto configuration for database backend, clustering and remote caches on infinispan" type: "bool" + keycloak_ha_discovery: + default: "{{ 'JDBC_PING' if keycloak_db_enabled else 'TCPPING' }}" + description: "Discovery protocol for HA cluster members" + type: "str" keycloak_db_enabled: # line 48 of keycloak/defaults/main.yml default: "{{ True if keycloak_ha_enabled else False }}" diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index e60e0aa..7c3d44b 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -187,6 +187,19 @@ - restart keycloak when: not keycloak_remotecache.enabled or keycloak_config_override_template | length > 0 +- name: Create cluster node list + ansible.builtin.set_fact: + keycloak_cluster_nodes: > + {{ keycloak_cluster_nodes | default([]) + [ + { + "name": item, + "address": 'jgroups-' + item, + "inventory_host": hostvars[item].ansible_default_ipv4.address | default(item) + '[' + keycloak_jgroups_port + ']', + "value": hostvars[item].ansible_default_ipv4.address | default(item) + } + ] }} + loop: "{{ ansible_play_batch }}" + - name: "Deploy {{ keycloak.service_name }} config with remote cache store to {{ keycloak_config_path_to_standalone_xml }}" become: yes ansible.builtin.template: diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index 91eefa8..e326924 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -488,7 +488,7 @@ -{% if keycloak_jdbc[keycloak_jdbc_engine].enabled %} +{% if keycloak_ha_discovery == 'JDBC_PING' and keycloak_jdbc[keycloak_jdbc_engine].enabled %} java:jboss/datasources/KeycloakDS {{ keycloak_jdbc[keycloak_jdbc_engine].initialize_db }} @@ -496,6 +496,13 @@ DELETE FROM JGROUPSPING WHERE own_addr=? AND cluster_name=? SELECT ping_data FROM JGROUPSPING WHERE cluster_name=? +{% elif keycloak_ha_discovery == 'TCPPING' %} + + {{ keycloak_cluster_nodes | map(attribute='inventory_host') | join (',') }} + 0 + 3000 + 2 + {% endif %} @@ -710,6 +717,13 @@ {% endfor %} +{% endif %} +{% if keycloak_ha_discovery == 'TCPPING' %} +{% for node in keycloak_cluster_nodes %} + + + +{% endfor %} {% endif %} From a7c9304c6862b0b7028825afe9ec3746c1f6fe8d Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 8 Mar 2023 11:06:01 +0100 Subject: [PATCH 142/554] fix typo --- roles/keycloak/tasks/install.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index 7c3d44b..a0b3102 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -198,7 +198,7 @@ "value": hostvars[item].ansible_default_ipv4.address | default(item) } ] }} - loop: "{{ ansible_play_batch }}" + loop: "{{ ansible_play_batch }}" - name: "Deploy {{ keycloak.service_name }} config with remote cache store to {{ keycloak_config_path_to_standalone_xml }}" become: yes From 68bcff36f694f5af4237f146b91148b89e6d886d Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 8 Mar 2023 14:59:55 +0100 Subject: [PATCH 143/554] only try to create cluster node list when tcpping is selected --- roles/keycloak/tasks/install.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index a0b3102..35054ec 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -187,7 +187,7 @@ - restart keycloak when: not keycloak_remotecache.enabled or keycloak_config_override_template | length > 0 -- name: Create cluster node list +- name: Create tcpping cluster node list ansible.builtin.set_fact: keycloak_cluster_nodes: > {{ keycloak_cluster_nodes | default([]) + [ @@ -199,6 +199,7 @@ } ] }} loop: "{{ ansible_play_batch }}" + when: keycloak_ha_enabled and keycloak_ha_discovery == 'TCPPING' - name: "Deploy {{ keycloak.service_name }} config with remote cache store to {{ keycloak_config_path_to_standalone_xml }}" become: yes From e530ccdc31883d73643d99e2599abc234e3133e9 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 8 Mar 2023 15:58:09 +0100 Subject: [PATCH 144/554] Replace metadata --- galaxy.yml | 2 +- molecule/requirements.yml | 3 +-- playbooks/rhsso.yml | 7 +++---- requirements.yml | 3 +-- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/galaxy.yml b/galaxy.yml index 29d1d00..3eec4c8 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -22,7 +22,7 @@ tags: - authentication - java dependencies: - "middleware_automation.redhat_csp_download": ">=1.2.1" + "middleware_automation.common": ">=1.0.0" "ansible.posix": ">=1.4.0" repository: https://github.com/ansible-middleware/keycloak documentation: https://ansible-middleware.github.io/keycloak diff --git a/molecule/requirements.yml b/molecule/requirements.yml index 0aed172..2e0ae56 100644 --- a/molecule/requirements.yml +++ b/molecule/requirements.yml @@ -1,7 +1,6 @@ --- collections: - - name: middleware_automation.redhat_csp_download - version: ">=1.2.1" + - name: middleware_automation.common - name: community.general - name: ansible.posix - name: community.docker diff --git a/playbooks/rhsso.yml b/playbooks/rhsso.yml index c8dbc44..25e4bae 100644 --- a/playbooks/rhsso.yml +++ b/playbooks/rhsso.yml @@ -1,9 +1,8 @@ --- -- name: Playbook for Keycloak Hosts - hosts: keycloak +- name: Playbook for Red Hat SSO Hosts + hosts: sso vars: keycloak_admin_password: "remembertochangeme" sso_enable: True roles: - - middleware_automation.redhat_csp_download.redhat_csp_download - - middleware_automation.keycloak.keycloak + - redhat.sso.sso diff --git a/requirements.yml b/requirements.yml index dae1d95..3f6feef 100644 --- a/requirements.yml +++ b/requirements.yml @@ -1,5 +1,4 @@ --- collections: - - name: middleware_automation.redhat_csp_download - version: ">=1.2.1" + - name: middleware_automation.common - name: ansible.posix From ccf773057b5e7ab50bf229b6d12cb130f8ee7c94 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 8 Mar 2023 15:58:25 +0100 Subject: [PATCH 145/554] Replace main download --- roles/keycloak/README.md | 7 ++++- roles/keycloak/meta/argument_specs.yml | 22 +++----------- roles/keycloak/meta/main.yml | 3 +- roles/keycloak/tasks/install.yml | 42 ++++++++++++++++++++------ roles/keycloak_realm/meta/main.yml | 1 - 5 files changed, 46 insertions(+), 29 deletions(-) diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index 06f9b47..5aadcb9 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -19,7 +19,12 @@ Dependencies The roles depends on: -* the `redhat_csp_download` role from [middleware_automation.redhat_csp_download](https://github.com/ansible-middleware/redhat-csp-download) collection if Red Hat Single Sign-on zip have to be downloaded from RHN. +* [middleware_automation.common](https://github.com/ansible-middleware/common) +* [ansible-posix](https://docs.ansible.com/ansible/latest/collections/ansible/posix/index.html) + +To install all the dependencies via galaxy: + + ansible-galaxy collection install -r requirements.yml Versions diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 382bf70..8601d1e 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -300,10 +300,6 @@ argument_specs: default: "7.6.0" description: "Red Hat Single Sign-On version" type: "str" - sso_rhn_id: - default: "104539" - description: "Customer Portal product ID for Red Hat SSO" - type: "str" sso_archive: default: "rh-sso-{{ sso_version }}-server-dist.zip" description: "Red Hat SSO install archive filename" @@ -316,14 +312,6 @@ argument_specs: default: "{{ sso_dest }}/rh-sso-{{ sso_version.split('.')[0] }}.{{ sso_version.split('.')[1] }}" description: "Installation path for Red Hat SSO" type: "str" - sso_rhn_url: - default: 'https://access.redhat.com/jbossnetwork/restricted/softwareDownload.html?softwareId=' - description: "Base download URI for customer portal" - type: "str" - sso_download_url: - default: "{{ sso_rhn_url }}{{ sso_rhn_id }}" - description: "Full download URI for Red Hat SSO" - type: "str" sso_apply_patches: default: False description: "Install Red Hat SSO most recent cumulative patch" @@ -333,7 +321,7 @@ argument_specs: description: "Enable Red Hat Single Sign-on installation" type: "str" sso_offline_install: - default: True + default: False description: "Perform an offline install" type: "bool" sso_service_name: @@ -352,7 +340,7 @@ argument_specs: default: "rh-sso-{{ sso_patch_version }}-patch.zip" description: "Red Hat SSO patch archive filename" type: "str" - sso_patch_rhn_id: - default: "104867" - description: "Customer Portal product ID for Red Hat SSO latest cumulative patch" - type: "str" + sso_product_category: + default: "core.service.rhsso" + description: "JBossNetwork API category for Single Sign-On" + type: "str" diff --git a/roles/keycloak/meta/main.yml b/roles/keycloak/meta/main.yml index fce67b7..5816039 100644 --- a/roles/keycloak/meta/main.yml +++ b/roles/keycloak/meta/main.yml @@ -1,6 +1,7 @@ --- collections: - - middleware_automation.redhat_csp_download + - middleware_automation.common + - ansible.posix galaxy_info: role_name: keycloak diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index 35054ec..c4d72f4 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -77,6 +77,7 @@ dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" mode: 0644 delegate_to: localhost + run_once: yes when: - archive_path is defined - archive_path.stat is defined @@ -84,21 +85,43 @@ - not sso_enable is defined or not sso_enable - not keycloak_offline_install -- name: Perform download from RHN - middleware_automation.redhat_csp_download.redhat_csp_download: - url: "{{ keycloak_rhsso_download_url }}" - dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" - username: "{{ rhn_username }}" - password: "{{ rhn_password }}" - no_log: "{{ omit_rhn_output | default(true) }}" +- name: Perform download from RHN using JBoss Network API delegate_to: localhost + run_once: yes when: - archive_path is defined - archive_path.stat is defined - not archive_path.stat.exists - sso_enable is defined and sso_enable - not keycloak_offline_install - - keycloak_rhn_url in keycloak_download_url + block: + - name: Retrieve product download using JBoss Network API + middleware_automation.common.product_search: + client_id: "{{ rhn_username }}" + client_secret: "{{ rhn_password }}" + product_type: DISTRIBUTION + product_version: "{{ sso_version }}" + product_category: "{{ sso_product_category }}" + register: rhn_products + no_log: "{{ omit_rhn_output | default(true) }}" + delegate_to: localhost + run_once: yes + + - name: Determine install zipfile from search results + ansible.builtin.set_fact: + rhn_filtered_products: "{{ rhn_products.results | selectattr('file_path', 'match', '[^/]*/{{ sso_archive }}$') }}" + delegate_to: localhost + run_once: yes + + - name: Download Red Hat Single Sign-On + middleware_automation.common.product_download: # noqa risky-file-permissions delegated, uses controller host user + client_id: "{{ rhn_username }}" + client_secret: "{{ rhn_password }}" + product_id: "{{ (rhn_filtered_products | first).id }}" + dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" + no_log: "{{ omit_rhn_output | default(true) }}" + delegate_to: localhost + run_once: yes - name: Download rhsso archive from alternate location ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user @@ -106,13 +129,14 @@ dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" mode: 0644 delegate_to: localhost + run_once: yes when: - archive_path is defined - archive_path.stat is defined - not archive_path.stat.exists - sso_enable is defined and sso_enable - not keycloak_offline_install - - not keycloak_rhn_url in keycloak_download_url + - keycloak_rhsso_download_url is defined - name: Check downloaded archive ansible.builtin.stat: diff --git a/roles/keycloak_realm/meta/main.yml b/roles/keycloak_realm/meta/main.yml index 4ce1b73..5dd7a21 100644 --- a/roles/keycloak_realm/meta/main.yml +++ b/roles/keycloak_realm/meta/main.yml @@ -19,5 +19,4 @@ galaxy_info: - keycloak - redhat - rhel - - rhn - sso From 527d3eb2641531bb96756f071ad7fc5192aa7573 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 8 Mar 2023 16:02:54 +0100 Subject: [PATCH 146/554] Fix typo --- roles/keycloak/meta/argument_specs.yml | 6 +++--- roles/keycloak/tasks/install.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 8601d1e..a464bc9 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -333,11 +333,11 @@ argument_specs: description: "systemd description for Red Hat Single Sign-On" type: "str" sso_patch_version: - default: "7.6.1" - description: "Red Hat Single Sign-On latest cumulative patch version" + required: False + description: "Red Hat Single Sign-On latest cumulative patch version to apply; default to latest version when sso_apply_patches is True" type: "str" sso_patch_bundle: - default: "rh-sso-{{ sso_patch_version }}-patch.zip" + default: "rh-sso-{{ sso_patch_version | default('') }}-patch.zip" description: "Red Hat SSO patch archive filename" type: "str" sso_product_category: diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index c4d72f4..5973e9a 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -109,7 +109,7 @@ - name: Determine install zipfile from search results ansible.builtin.set_fact: - rhn_filtered_products: "{{ rhn_products.results | selectattr('file_path', 'match', '[^/]*/{{ sso_archive }}$') }}" + rhn_filtered_products: "{{ rhn_products.results | selectattr('file_path', 'match', '[^/]*/' + sso_archive + '$') }}"  delegate_to: localhost  run_once: yes  From d15324c1c8c1aed4eecbc7e28021b8d484f29062 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 8 Mar 2023 17:00:38 +0100 Subject: [PATCH 147/554] fix indent typo --- roles/keycloak/tasks/install.yml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index 5973e9a..e7283e7 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -98,10 +98,10 @@ - name: Retrieve product download using JBoss Network API middleware_automation.common.product_search: client_id: "{{ rhn_username }}" - client_secret: "{{ rhn_password }}" - product_type: DISTRIBUTION + client_secret: "{{ rhn_password }}" + product_type: DISTRIBUTION product_version: "{{ sso_version }}" - product_category: "{{ sso_product_category }}" + product_category: "{{ sso_product_category }}" register: rhn_products no_log: "{{ omit_rhn_output | default(true) }}" delegate_to: localhost @@ -110,18 +110,18 @@ - name: Determine install zipfile from search results ansible.builtin.set_fact: rhn_filtered_products: "{{ rhn_products.results | selectattr('file_path', 'match', '[^/]*/' + sso_archive + '$') }}" - delegate_to: localhost - run_once: yes - + delegate_to: localhost + run_once: yes + - name: Download Red Hat Single Sign-On middleware_automation.common.product_download: # noqa risky-file-permissions delegated, uses controller host user - client_id: "{{ rhn_username }}" - client_secret: "{{ rhn_password }}" - product_id: "{{ (rhn_filtered_products | first).id }}" - dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" - no_log: "{{ omit_rhn_output | default(true) }}" - delegate_to: localhost - run_once: yes + client_id: "{{ rhn_username }}" + client_secret: "{{ rhn_password }}" + product_id: "{{ (rhn_filtered_products | first).id }}" + dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" + no_log: "{{ omit_rhn_output | default(true) }}" + delegate_to: localhost + run_once: yes - name: Download rhsso archive from alternate location ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user From ce18c91b67156768d1a75033acb2df287b297e5e Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 8 Mar 2023 17:32:32 +0100 Subject: [PATCH 148/554] revert downstream playbook rename --- playbooks/rhsso.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/playbooks/rhsso.yml b/playbooks/rhsso.yml index 25e4bae..ea67158 100644 --- a/playbooks/rhsso.yml +++ b/playbooks/rhsso.yml @@ -5,4 +5,4 @@ keycloak_admin_password: "remembertochangeme" sso_enable: True roles: - - redhat.sso.sso + - middleware_automation.keycloak.keycloak From 7c9cc7ce366ba9ff2b5b74f3721e8a0756788e7e Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 8 Mar 2023 17:40:03 +0100 Subject: [PATCH 149/554] remove non-printing chars from arg_specs --- roles/keycloak/meta/argument_specs.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index a464bc9..6693c30 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -341,6 +341,6 @@ argument_specs: description: "Red Hat SSO patch archive filename" type: "str" sso_product_category: - default: "core.service.rhsso" - description: "JBossNetwork API category for Single Sign-On" - type: "str" + default: "core.service.rhsso" + description: "JBossNetwork API category for Single Sign-On" + type: "str" From a5547362469e0736109d5712f2cc6048edd094c2 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 10 Mar 2023 11:52:02 +0100 Subject: [PATCH 150/554] Use middleware_automation.common for rh-sso patching --- plugins/filter/version_sort.py | 52 +++++++++++++++++ roles/keycloak/README.md | 2 +- roles/keycloak/meta/argument_specs.yml | 4 +- roles/keycloak/tasks/rhsso_patch.yml | 77 ++++++++++++++++++++++---- 4 files changed, 120 insertions(+), 15 deletions(-) create mode 100644 plugins/filter/version_sort.py diff --git a/plugins/filter/version_sort.py b/plugins/filter/version_sort.py new file mode 100644 index 0000000..beb44cb --- /dev/null +++ b/plugins/filter/version_sort.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2021 Eric Lavarde +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +DOCUMENTATION = ''' + name: version_sort + short_description: Sort a list according to version order instead of pure alphabetical one + version_added: 2.2.0 + author: Eric L. (@ericzolf) + description: + - Sort a list according to version order instead of pure alphabetical one. + options: + _input: + description: A list of strings to sort. + type: list + elements: string + required: true +''' + +EXAMPLES = ''' +- name: Convert list of tuples into dictionary + ansible.builtin.set_fact: + dictionary: "{{ ['2.1', '2.10', '2.9'] | middleware_automation.keycloak.version_sort }}" + # Result is ['2.1', '2.9', '2.10'] +''' + +RETURN = ''' + _value: + description: The list of strings sorted by version. + type: list + elements: string +''' + +from ansible_collections.middleware_automation.keycloak.plugins.module_utils.version import LooseVersion + + +def version_sort(value, reverse=False): + '''Sort a list according to loose versions so that e.g. 2.9 is smaller than 2.10''' + return sorted(value, key=LooseVersion, reverse=reverse) + + +class FilterModule(object): + ''' Version sort filter ''' + + def filters(self): + return { + 'version_sort': version_sort + } diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index 5aadcb9..32eb022 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -96,7 +96,7 @@ Role Defaults |`keycloak_archive` | keycloak install archive filename | `keycloak-legacy-{{ keycloak_version }}.zip` | |`keycloak_download_url_9x` | Download URL for keycloak (deprecated) | `https://downloads.jboss.org/keycloak/{{ keycloak_version }}/{{ keycloak_archive }}` | |`keycloak_installdir` | Installation path | `{{ keycloak_dest }}/keycloak-{{ keycloak_version }}` | -|`keycloak_jboss_home` | Installation work directory | `{{ keycloak_rhsso_installdir if keycloak_rhsso_enable else keycloak_installdir }}` | +|`keycloak_jboss_home` | Installation work directory | `{{ keycloak_rhsso_installdir }}` | |`keycloak_config_dir` | Path for configuration | `{{ keycloak_jboss_home }}/standalone/configuration` | |`keycloak_config_path_to_standalone_xml` | Custom path for configuration | `{{ keycloak_jboss_home }}/standalone/configuration/{{ keycloak_config_standalone_xml }}` | |`keycloak_config_override_template` | Path to custom template for standalone.xml configuration | `''` | diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 6693c30..99d7703 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -334,10 +334,10 @@ argument_specs: type: "str" sso_patch_version: required: False - description: "Red Hat Single Sign-On latest cumulative patch version to apply; default to latest version when sso_apply_patches is True" + description: "Red Hat Single Sign-On latest cumulative patch version to apply; defaults to latest version when sso_apply_patches is True" type: "str" sso_patch_bundle: - default: "rh-sso-{{ sso_patch_version | default('') }}-patch.zip" + default: "rh-sso-{{ sso_patch_version | default('[0-9]+[.][0-9]+[.][0-9]+') }}-patch.zip" description: "Red Hat SSO patch archive filename" type: "str" sso_product_category: diff --git a/roles/keycloak/tasks/rhsso_patch.yml b/roles/keycloak/tasks/rhsso_patch.yml index 97993a2..1f1afca 100644 --- a/roles/keycloak/tasks/rhsso_patch.yml +++ b/roles/keycloak/tasks/rhsso_patch.yml @@ -9,25 +9,78 @@ path: "{{ patch_archive }}" register: patch_archive_path -- name: Perform download from RHN - middleware_automation.redhat_csp_download.redhat_csp_download: - url: "{{ keycloak_rhn_url }}{{ sso_patch_rhn_id }}" - dest: "{{ local_path.stat.path }}/{{ sso_patch_bundle }}" - username: "{{ rhn_username }}" - password: "{{ rhn_password }}" - no_log: "{{ omit_rhn_output | default(true) }}" +- name: Perform patch download from RHN via JBossNetwork API delegate_to: localhost + run_once: yes when: - patch_archive_path is defined - patch_archive_path.stat is defined - not patch_archive_path.stat.exists - sso_enable is defined and sso_enable - not keycloak_offline_install + block: + - name: Retrieve product download using JBossNetwork API + middleware_automation.common.product_search: + client_id: "{{ rhn_username }}" + client_secret: "{{ rhn_password }}" + product_type: BUGFIX + product_version: "{{ sso_version }}" + product_category: "{{ sso_product_category }}" + register: rhn_products + no_log: "{{ omit_rhn_output | default(true) }}" + delegate_to: localhost + run_once: yes + + - name: Filter patch versions + set_fact: + filtered_versions: "{{ rhn_products.results | map(attribute='file_path') | select('match', '^[^/]*/rh-sso-.*[0-9]*[.][0-9]*[.][0-9]*.*$') | map('regex_replace','[^/]*/rh-sso-([0-9]*[.][0-9]*[.][0-9]*)-.*','\\1' ) | list | unique }}" + when: sso_patch_version is not defined or sso_patch_version | length == 0 + delegate_to: localhost + run_once: yes + + - name: Determine latest version + set_fact: + sso_latest_version: "{{ filtered_versions | middleware_automation.keycloak.version_sort | last }}" + when: sso_patch_version is not defined or sso_patch_version | length == 0 + delegate_to: localhost + run_once: yes + + - name: Determine install zipfile from search results + ansible.builtin.set_fact: + rhn_filtered_products: "{{ rhn_products.results | selectattr('file_path', 'match', '[^/]*/rh-sso-' + sso_latest_version + '-patch.zip$') }}" + patch_bundle: "rh-sso-{{ sso_latest_version }}-patch.zip" + patch_version: "{{ sso_latest_version }}" + when: sso_patch_version is not defined or sso_patch_version | length == 0 + delegate_to: localhost + run_once: yes + + - name: "Filter selected patch version {{ sso_patch_version }}" + set_fact: + rhn_filtered_products: "{{ rhn_products.results | selectattr('file_path', 'match', '[^/]*/' + sso_patch_bundle + '$') }}" + patch_bundle: "{{ sso_patch_bundle }}" + patch_version: "{{ sso_patch_version }}" + when: sso_patch_version is defined + delegate_to: localhost + run_once: yes + + - name: Download Red Hat Single Sign-On patch + middleware_automation.common.product_download: # noqa risky-file-permissions delegated, uses controller host user + client_id: "{{ rhn_username }}" + client_secret: "{{ rhn_password }}" + product_id: "{{ (rhn_filtered_products | first).id }}" + dest: "{{ local_path.stat.path }}/{{ patch_bundle }}" + no_log: "{{ omit_rhn_output | default(true) }}" + delegate_to: localhost + run_once: yes + +- name: Set download patch archive path + ansible.builtin.set_fact: + patch_archive: "{{ keycloak_dest }}/{{ patch_bundle }}" ## copy and unpack - name: Copy patch archive to target nodes ansible.builtin.copy: - src: "{{ local_path.stat.path }}/{{ sso_patch_bundle }}" + src: "{{ local_path.stat.path }}/{{ patch_bundle }}" dest: "{{ patch_archive }}" owner: "{{ keycloak_service_user }}" group: "{{ keycloak_service_group }}" @@ -48,9 +101,9 @@ when: - cli_result is defined - cli_result.stdout is defined - - sso_patch_version not in cli_result.stdout + - patch_version not in cli_result.stdout block: - - name: "Apply patch {{ sso_patch_version }} to server" + - name: "Apply patch {{ patch_version }} to server" ansible.builtin.include_tasks: rhsso_cli.yml vars: query: "patch apply {{ patch_archive }}" @@ -78,10 +131,10 @@ - name: "Verify installed patch version" ansible.builtin.assert: that: - - sso_patch_version not in cli_result.stdout + - patch_version not in cli_result.stdout fail_msg: "Patch installation failed" success_msg: "Patch installation successful" - name: "Skipping patch" ansible.builtin.debug: - msg: "Latest cumulative patch {{ sso_patch_version }} already installed, skipping patch installation." + msg: "Cumulative patch {{ patch_version }} already installed, skipping patch installation." From 1f2a88982d453ae40b0999c28ae8f91022a4fb00 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 10 Mar 2023 11:54:37 +0100 Subject: [PATCH 151/554] linter --- roles/keycloak/tasks/rhsso_patch.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/keycloak/tasks/rhsso_patch.yml b/roles/keycloak/tasks/rhsso_patch.yml index 1f1afca..cf805ce 100644 --- a/roles/keycloak/tasks/rhsso_patch.yml +++ b/roles/keycloak/tasks/rhsso_patch.yml @@ -31,7 +31,7 @@ delegate_to: localhost run_once: yes - - name: Filter patch versions + - name: Determine patch versions list set_fact: filtered_versions: "{{ rhn_products.results | map(attribute='file_path') | select('match', '^[^/]*/rh-sso-.*[0-9]*[.][0-9]*[.][0-9]*.*$') | map('regex_replace','[^/]*/rh-sso-([0-9]*[.][0-9]*[.][0-9]*)-.*','\\1' ) | list | unique }}" when: sso_patch_version is not defined or sso_patch_version | length == 0 @@ -54,7 +54,7 @@ delegate_to: localhost run_once: yes - - name: "Filter selected patch version {{ sso_patch_version }}" + - name: "Determine selected patch from supplied version: {{ sso_patch_version }}" set_fact: rhn_filtered_products: "{{ rhn_products.results | selectattr('file_path', 'match', '[^/]*/' + sso_patch_bundle + '$') }}" patch_bundle: "{{ sso_patch_bundle }}" From 49566455d6200b39ca303370787c9e6c6f21c9b2 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 10 Mar 2023 11:59:14 +0100 Subject: [PATCH 152/554] add missing file --- plugins/module_utils/version.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 plugins/module_utils/version.py diff --git a/plugins/module_utils/version.py b/plugins/module_utils/version.py new file mode 100644 index 0000000..3699881 --- /dev/null +++ b/plugins/module_utils/version.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Felix Fontein +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +"""Provide version object to compare version numbers.""" + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +from ansible.module_utils.six import raise_from + +try: + from ansible.module_utils.compat.version import LooseVersion # noqa: F401, pylint: disable=unused-import +except ImportError: + try: + from distutils.version import LooseVersion # noqa: F401, pylint: disable=unused-import + except ImportError as exc: + msg = 'To use this plugin or module with ansible-core 2.11, you need to use Python < 3.12 with distutils.version present' + raise_from(ImportError(msg), exc) From 2ce7104077a85b5cac5cb6e79c9a5254d6cdb64a Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 10 Mar 2023 14:34:12 +0100 Subject: [PATCH 153/554] ci: docs need ansible-core 2.14 --- docs/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 5fe33c2..c43be53 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,7 +1,7 @@ antsibull>=0.17.0 antsibull-docs antsibull-changelog -ansible-base>=2.10.12 +ansible-core>=2.14.1 sphinx-rtd-theme git+https://github.com/felixfontein/ansible-basic-sphinx-ext myst-parser From bf89b1895a821602072762901cd40241f1b92860 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 10 Mar 2023 15:22:15 +0100 Subject: [PATCH 154/554] minor fixes to downstream rhn install/patch download --- roles/keycloak/tasks/install.yml | 2 +- roles/keycloak/tasks/rhsso_patch.yml | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index e7283e7..75ca289 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -100,7 +100,7 @@ client_id: "{{ rhn_username }}" client_secret: "{{ rhn_password }}" product_type: DISTRIBUTION - product_version: "{{ sso_version }}" + product_version: "{{ sso_version.split('.')[:2] | join('.') }}" product_category: "{{ sso_product_category }}" register: rhn_products no_log: "{{ omit_rhn_output | default(true) }}" diff --git a/roles/keycloak/tasks/rhsso_patch.yml b/roles/keycloak/tasks/rhsso_patch.yml index cf805ce..c6a2a0d 100644 --- a/roles/keycloak/tasks/rhsso_patch.yml +++ b/roles/keycloak/tasks/rhsso_patch.yml @@ -3,28 +3,29 @@ - name: Set download patch archive path ansible.builtin.set_fact: patch_archive: "{{ keycloak_dest }}/{{ sso_patch_bundle }}" + when: sso_patch_version is defined - name: Check download patch archive path ansible.builtin.stat: path: "{{ patch_archive }}" register: patch_archive_path + when: sso_patch_version is defined - name: Perform patch download from RHN via JBossNetwork API delegate_to: localhost run_once: yes when: - - patch_archive_path is defined - - patch_archive_path.stat is defined - - not patch_archive_path.stat.exists + - patch_archive_path is defined and patch_archive_path.stat is defined and not patch_archive_path.stat.exists or patch_archive_path is not defined - sso_enable is defined and sso_enable - not keycloak_offline_install + - sso_apply_patches block: - name: Retrieve product download using JBossNetwork API middleware_automation.common.product_search: client_id: "{{ rhn_username }}" client_secret: "{{ rhn_password }}" product_type: BUGFIX - product_version: "{{ sso_version }}" + product_version: "{{ sso_version.split('.')[:2] | join('.') }}" product_category: "{{ sso_product_category }}" register: rhn_products no_log: "{{ omit_rhn_output | default(true) }}" @@ -77,6 +78,11 @@ ansible.builtin.set_fact: patch_archive: "{{ keycloak_dest }}/{{ patch_bundle }}" +- name: Check download patch archive path + ansible.builtin.stat: + path: "{{ patch_archive }}" + register: patch_archive_path + ## copy and unpack - name: Copy patch archive to target nodes ansible.builtin.copy: From 59b69a6592d42e9d7188565f3a17882a4e187db5 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 10 Mar 2023 15:23:22 +0100 Subject: [PATCH 155/554] Downstream patching: add missing becomes --- roles/keycloak/tasks/rhsso_patch.yml | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/roles/keycloak/tasks/rhsso_patch.yml b/roles/keycloak/tasks/rhsso_patch.yml index c6a2a0d..5678e11 100644 --- a/roles/keycloak/tasks/rhsso_patch.yml +++ b/roles/keycloak/tasks/rhsso_patch.yml @@ -82,6 +82,7 @@ ansible.builtin.stat: path: "{{ patch_archive }}" register: patch_archive_path + become: yes ## copy and unpack - name: Copy patch archive to target nodes @@ -102,9 +103,13 @@ ansible.builtin.include_tasks: rhsso_cli.yml vars: query: "patch info" + args: + apply: + become: yes + become_user: "{{ keycloak_service_user }}" - name: "Perform patching" - when: + when: - cli_result is defined - cli_result.stdout is defined - patch_version not in cli_result.stdout @@ -113,6 +118,10 @@ ansible.builtin.include_tasks: rhsso_cli.yml vars: query: "patch apply {{ patch_archive }}" + args: + apply: + become: yes + become_user: "{{ keycloak_service_user }}" - name: "Restart server to ensure patch content is running" ansible.builtin.include_tasks: rhsso_cli.yml @@ -120,6 +129,10 @@ query: "shutdown --restart" when: - cli_result.rc == 0 + args: + apply: + become: yes + become_user: "{{ keycloak_service_user }}" - name: "Wait until {{ keycloak.service_name }} becomes active {{ keycloak.health_url }}" ansible.builtin.uri: @@ -133,7 +146,11 @@ ansible.builtin.include_tasks: rhsso_cli.yml vars: query: "patch info" - + args: + apply: + become: yes + become_user: "{{ keycloak_service_user }}" + - name: "Verify installed patch version" ansible.builtin.assert: that: @@ -144,3 +161,7 @@ - name: "Skipping patch" ansible.builtin.debug: msg: "Cumulative patch {{ patch_version }} already installed, skipping patch installation." + when: + - cli_result is defined + - cli_result.stdout is defined + - patch_version in cli_result.stdout From 23ce09d59557f4740408c2f4bf5fc2effaade848 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 15 Mar 2023 17:23:04 +0100 Subject: [PATCH 156/554] sso: remove conditional on apply_patches --- roles/keycloak/tasks/rhsso_patch.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/roles/keycloak/tasks/rhsso_patch.yml b/roles/keycloak/tasks/rhsso_patch.yml index 5678e11..0cbf002 100644 --- a/roles/keycloak/tasks/rhsso_patch.yml +++ b/roles/keycloak/tasks/rhsso_patch.yml @@ -15,7 +15,6 @@ delegate_to: localhost run_once: yes when: - - patch_archive_path is defined and patch_archive_path.stat is defined and not patch_archive_path.stat.exists or patch_archive_path is not defined - sso_enable is defined and sso_enable - not keycloak_offline_install - sso_apply_patches From ed24ca637a98f161356603475bfab9b453c01077 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 15 Mar 2023 17:56:08 +0100 Subject: [PATCH 157/554] docs: update sample keycloak_realm playbook --- playbooks/keycloak_realm.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/playbooks/keycloak_realm.yml b/playbooks/keycloak_realm.yml index ba3d8ea..cc512fa 100644 --- a/playbooks/keycloak_realm.yml +++ b/playbooks/keycloak_realm.yml @@ -3,14 +3,13 @@ hosts: all vars: keycloak_admin_password: "remembertochangeme" - keycloak_realm: TestRealm keycloak_clients: - name: TestClient1 client_id: TestClient1 roles: - TestClient1Admin - TestClient1User - realm: "{{ keycloak_realm }}" + realm: TestRealm public_client: True web_origins: - http://testclient1origin/application @@ -21,6 +20,7 @@ client_roles: - client: TestClient1 role: TestClient1User - realm: "{{ keycloak_realm }}" + realm: TestRealm roles: - - middleware_automation.keycloak.keycloak_realm + - name: middleware_automation.keycloak.keycloak_realm + keycloak_realm: TestRealm From 398c3c478eee134953bc94f9d9baa25fada4777a Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 15 Mar 2023 18:05:01 +0100 Subject: [PATCH 158/554] docs: use role, not name, in sample keycloak_realm playbook --- playbooks/keycloak_realm.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/playbooks/keycloak_realm.yml b/playbooks/keycloak_realm.yml index cc512fa..f03edab 100644 --- a/playbooks/keycloak_realm.yml +++ b/playbooks/keycloak_realm.yml @@ -22,5 +22,5 @@ role: TestClient1User realm: TestRealm roles: - - name: middleware_automation.keycloak.keycloak_realm + - role: middleware_automation.keycloak.keycloak_realm keycloak_realm: TestRealm From 05dccdaf3b882a0804dc3e360545e6590af26e8c Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 16 Mar 2023 14:21:04 +0000 Subject: [PATCH 159/554] Update changelog for release 1.2.0 --- CHANGELOG.rst | 16 ++++++++++++++++ changelogs/changelog.yaml | 27 +++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 564b3c2..8607e91 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,22 @@ middleware_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v1.2.0 +====== + +Major Changes +------------- + +- Provide config for multiple modcluster proxies `#60 `_ + +Minor Changes +------------- + +- Allow to configure TCPPING for cluster discovery `#62 `_ +- Drop community.general from dependencies `#61 `_ +- Switch middleware_automation.redhat_csp_download for middleware_automation.common `#63 `_ +- Switch to middleware_automation.common for rh-sso patching `#64 `_ + v1.1.1 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 154fa4a..1647779 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -140,3 +140,30 @@ releases: fragments: - 53.yaml release_date: '2023-03-07' + 1.2.0: + changes: + major_changes: + - 'Provide config for multiple modcluster proxies `#60 `_ + + ' + minor_changes: + - 'Allow to configure TCPPING for cluster discovery `#62 `_ + + ' + - 'Drop community.general from dependencies `#61 `_ + + ' + - 'Switch middleware_automation.redhat_csp_download for middleware_automation.common + `#63 `_ + + ' + - 'Switch to middleware_automation.common for rh-sso patching `#64 `_ + + ' + fragments: + - 60.yaml + - 61.yaml + - 62.yaml + - 63.yaml + - 64.yaml + release_date: '2023-03-16' From ecb6cbb9bf0975477022714a58d420a8ea7c74ff Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 17 Mar 2023 11:25:40 +0100 Subject: [PATCH 160/554] ci: downstream test asset management --- molecule/prepare.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/molecule/prepare.yml b/molecule/prepare.yml index c457571..a927ba0 100644 --- a/molecule/prepare.yml +++ b/molecule/prepare.yml @@ -14,7 +14,14 @@ ansible.builtin.set_fact: assets_server: "{{ lookup('env','MIDDLEWARE_DOWNLOAD_RELEASE_SERVER_URL') }}" -- name: "Download and deploy jws zips from {{ assets_server }}" +- name: "Set offline when assets server from env is defined" + ansible.builtin.set_fact: + sso_offline_install: True + when: + - assets_server is defined + - assets_server | length > 0 + +- name: "Download and deploy zips from {{ assets_server }}" ansible.builtin.get_url: url: "{{ asset }}" dest: "{{ lookup('env', 'PWD') }}" From 91a18bf5714377dfefb61c66bc5596e9162b91b5 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 17 Mar 2023 11:43:34 +0100 Subject: [PATCH 161/554] ci: downstream test offline/online handling --- molecule/default/converge.yml | 11 +++++++++++ molecule/overridexml/converge.yml | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index ac59d57..b9b8790 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -45,3 +45,14 @@ web_origins: "{{ keycloak_client_web_origins }}" users: "{{ keycloak_client_users }}" client_id: TestClient + pre_tasks: + - name: "Retrieve assets server from env" + ansible.builtin.set_fact: + assets_server: "{{ lookup('env','MIDDLEWARE_DOWNLOAD_RELEASE_SERVER_URL') }}" + + - name: "Set offline when assets server from env is defined" + ansible.builtin.set_fact: + sso_offline_install: True + when: + - assets_server is defined + - assets_server | length > 0 diff --git a/molecule/overridexml/converge.yml b/molecule/overridexml/converge.yml index 9304eba..3c451da 100644 --- a/molecule/overridexml/converge.yml +++ b/molecule/overridexml/converge.yml @@ -41,3 +41,14 @@ web_origins: "{{ keycloak_client_web_origins }}" users: "{{ keycloak_client_users }}" client_id: TestClient + pre_tasks: + - name: "Retrieve assets server from env" + ansible.builtin.set_fact: + assets_server: "{{ lookup('env','MIDDLEWARE_DOWNLOAD_RELEASE_SERVER_URL') }}" + + - name: "Set offline when assets server from env is defined" + ansible.builtin.set_fact: + sso_offline_install: True + when: + - assets_server is defined + - assets_server | length > 0 \ No newline at end of file From 40c29d07b81ecb1095dc6c957e35b9c73f164722 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 24 Mar 2023 15:19:28 +0100 Subject: [PATCH 162/554] ci: update main README.md --- README.md | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 75775d7..9e3edc1 100644 --- a/README.md +++ b/README.md @@ -16,12 +16,15 @@ Plugins and modules within a collection may be tested with only specific Ansible ## Installation + ### Installing the Collection from Ansible Galaxy Before using the collection, you need to install it with the Ansible Galaxy CLI: ansible-galaxy collection install middleware_automation.keycloak + + You can also include it in a `requirements.yml` file and install it via `ansible-galaxy collection install -r requirements.yml`, using the format: ```yaml @@ -51,42 +54,30 @@ A requirement file is provided to install: ### Install Playbook -* [`playbooks/keycloak.yml`](https://github.com/ansible-middleware/keycloak/blob/main/playbooks/keycloak.yml) installs the upstream(Keycloak) based on the defined variables. -* [`playbooks/rhsso.yml`](https://github.com/ansible-middleware/keycloak/blob/main/playbooks/rhsso.yml) installs Red Hat Single Sign-On(RHSSO) based on defined variables. +* [`playbooks/keycloak.yml`](https://github.com/ansible-middleware/keycloak/blob/main/playbooks/keycloak.yml) installs based on the defined variables (using most defaults). Both playbooks include the `keycloak` role, with different settings, as described in the following sections. For full service configuration details, refer to the [keycloak role README](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak/README.md). -#### Install from controller node (local source) +#### Install from controller node (offline) -Making the keycloak zip archive (or the RHSSO zip archive), available to the playbook repository root directory, and setting `keycloak_offline_install` to `True`, allows to skip -the download tasks. The local path for the archive matches the downloaded archive path, so it is also used as a cache when multiple hosts are provisioned in a cluster. +Making the keycloak zip archive available to the playbook working directory, and setting `keycloak_offline_install` to `True`, allows to skip +the download tasks. The local path for the archive does match the downloaded archive path, so that it is also used as a cache when multiple hosts are provisioned in a cluster. ```yaml keycloak_offline_install: True ``` -And depending on `keycloak_rhsso_enable`: -* `True`: install RHSSO using file rh-sso-x.y.z-server-dist.zip -* `False`: install keycloak using file keycloak-x.y.zip + + #### Install from alternate sources (like corporate Nexus, artifactory, proxy, etc) -For RHSSO: - -```yaml -sso_download_url: "https://///rh-sso-x.y.z-server-dist.zip" -``` - -For keycloak: - -```yaml -keycloak_download_url: "https://///keycloak-x.y.zip" -``` +It is possible to perform downloads from alternate sources, using the `keycloak_download_url` variable; make sure the final downloaded filename matches with the source filename (ie. keycloak-legacy-x.y.zip or rh-sso-x.y.z-server-dist.zip). ### Example installation command @@ -105,6 +96,8 @@ ansible-playbook -i -e @rhn-creds.yml playbooks/keycloak.yml -e localhost ansible_connection=local ``` +Note: when deploying clustered configurations, all hosts beloging to the cluster must be present in ansible_play_batch; ie. they must be targeted byh the same ansible-playbook execution. + ## Configuration @@ -133,9 +126,10 @@ ansible-playbook -i playbooks/keycloak_realm.yml -e keycloak_adm For full configuration details, refer to the [keycloak_realm role README](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak_realm/README.md). -## Support -Keycloak collection v1.0.0 is a Beta release and for [Technical Preview](https://access.redhat.com/support/offerings/techpreview). If you have any issues or questions related to collection, please don't hesitate to contact us on Ansible-middleware-core@redhat.com or open an issue on https://github.com/ansible-middleware/keycloak/issues + + + ## License From a2c17f545e094e09a01e06d4901ff5da75f28396 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 29 Mar 2023 10:32:14 +0200 Subject: [PATCH 163/554] docs: downstream hide build status --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9e3edc1..608d253 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ # Ansible Collection - middleware_automation.keycloak + [![Build Status](https://github.com/ansible-middleware/keycloak/workflows/CI/badge.svg?branch=main)](https://github.com/ansible-middleware/keycloak/actions/workflows/ci.yml) - + Collection to install and configure [Keycloak](https://www.keycloak.org/) or [Red Hat Single Sign-On](https://access.redhat.com/products/red-hat-single-sign-on). @@ -96,7 +97,7 @@ ansible-playbook -i -e @rhn-creds.yml playbooks/keycloak.yml -e localhost ansible_connection=local ``` -Note: when deploying clustered configurations, all hosts beloging to the cluster must be present in ansible_play_batch; ie. they must be targeted byh the same ansible-playbook execution. +Note: when deploying clustered configurations, all hosts belonging to the cluster must be present in ansible_play_batch; ie. they must be targeted by the same ansible-playbook execution. ## Configuration From 526f64e5eb48689f70d9c1147dc9aeb6d7a6aad2 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Sat, 1 Apr 2023 10:06:03 +0200 Subject: [PATCH 164/554] standalone ha without remote store --- roles/keycloak/README.md | 1 + roles/keycloak/defaults/main.yml | 2 + roles/keycloak/meta/argument_specs.yml | 4 + roles/keycloak/tasks/install.yml | 42 +- roles/keycloak/tasks/prereqs.yml | 8 + roles/keycloak/templates/standalone-ha.xml.j2 | 695 ++++++++++++++++++ roles/keycloak/vars/main.yml | 2 +- 7 files changed, 748 insertions(+), 6 deletions(-) create mode 100644 roles/keycloak/templates/standalone-ha.xml.j2 diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index 32eb022..aff6a1e 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -57,6 +57,7 @@ Role Defaults |`keycloak_ha_enabled`| Enable auto configuration for database backend, clustering and remote caches on infinispan | `False` | |`keycloak_ha_discovery`| Discovery protocol for HA cluster members | `JDBC_PING` if keycloak_db_enabled else `TCPPING` | |`keycloak_db_enabled`| Enable auto configuration for database backend | `True` if `keycloak_ha_enabled` is True, else `False` | +|`keycloak_remote_cache_enabled`| Enable remote cache store when in clustered ha configurations | `True` if `keycloak_ha_enabled` else `False` | |`keycloak_admin_user`| Administration console user account | `admin` | |`keycloak_bind_address`| Address for binding service ports | `0.0.0.0` | |`keycloak_management_port_bind_address`| Address for binding management ports | `127.0.0.1` | diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 3cfe827..795768f 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -48,6 +48,8 @@ keycloak_ha_enabled: False keycloak_db_enabled: "{{ True if keycloak_ha_enabled else False }}" ### Discovery protocol for ha cluster members, valus [ 'JDBC_PING', 'TCPPING' ] keycloak_ha_discovery: "{{ 'JDBC_PING' if keycloak_db_enabled else 'TCPPING' }}" +### Remote cache store on infinispan cluster +keycloak_remote_cache_enabled: "{{ True if keycloak_ha_enabled else False }}" ### Keycloak administration console user keycloak_admin_user: admin diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 99d7703..2fe1e05 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -294,6 +294,10 @@ argument_specs: default: true type: "bool" description: "Changes default behavior for no_log for debugging purpose, do not change for production system." + keycloak_remote_cache_enabled: + default: "{{ True if keycloak_ha_enabled else False }}" + description: "Enable remote cache store when in clustered ha configurations" + type: "bool" downstream: options: sso_version: diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index 75ca289..f9526cd 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -199,17 +199,31 @@ ansible.builtin.include_tasks: jdbc_driver.yml when: keycloak_jdbc[keycloak_jdbc_engine].enabled -- name: "Deploy {{ keycloak.service_name }} config to {{ keycloak_config_path_to_standalone_xml }} from {{ keycloak.config_template_source }}" +- name: "Deploy custom {{ keycloak.service_name }} config to {{ keycloak_config_path_to_standalone_xml }} from {{ keycloak_config_override_template }}" become: yes ansible.builtin.template: - src: "templates/{{ keycloak.config_template_source }}" + src: "templates/{{ keycloak_config_override_template }}" dest: "{{ keycloak_config_path_to_standalone_xml }}" owner: "{{ keycloak_service_user }}" group: "{{ keycloak_service_group }}" mode: 0640 notify: - restart keycloak - when: not keycloak_remotecache.enabled or keycloak_config_override_template | length > 0 + when: keycloak_config_override_template | length > 0 + +- name: "Deploy standalone {{ keycloak.service_name }} config to {{ keycloak_config_path_to_standalone_xml }}" + become: yes + ansible.builtin.template: + src: templates/standalone.xml + dest: "{{ keycloak_config_path_to_standalone_xml }}" + owner: "{{ keycloak_service_user }}" + group: "{{ keycloak_service_group }}" + mode: 0640 + notify: + - restart keycloak + when: + - not keycloak_ha_enabled + - keycloak_config_override_template | length == 0 - name: Create tcpping cluster node list ansible.builtin.set_fact: @@ -225,7 +239,22 @@ loop: "{{ ansible_play_batch }}" when: keycloak_ha_enabled and keycloak_ha_discovery == 'TCPPING' -- name: "Deploy {{ keycloak.service_name }} config with remote cache store to {{ keycloak_config_path_to_standalone_xml }}" +- name: "Deploy HA {{ keycloak.service_name }} config to {{ keycloak_config_path_to_standalone_xml }} from {{ keycloak.config_template_source }}" + become: yes + ansible.builtin.template: + src: templates/standalone-ha.xml + dest: "{{ keycloak_config_path_to_standalone_xml }}" + owner: "{{ keycloak_service_user }}" + group: "{{ keycloak_service_group }}" + mode: 0640 + notify: + - restart keycloak + when: + - keycloak_ha_enabled + - not keycloak_remote_cache_enabled + - keycloak_config_override_template | length == 0 + +- name: "Deploy HA {{ keycloak.service_name }} config with infinispan remote cache store to {{ keycloak_config_path_to_standalone_xml }}" become: yes ansible.builtin.template: src: templates/standalone-infinispan.xml.j2 @@ -235,4 +264,7 @@ mode: 0640 notify: - restart keycloak - when: keycloak_remotecache.enabled + when: + - keycloak_ha_enabled + - keycloak_remote_cache_enabled + - keycloak_config_override_template | length == 0 diff --git a/roles/keycloak/tasks/prereqs.yml b/roles/keycloak/tasks/prereqs.yml index c774c65..3f18964 100644 --- a/roles/keycloak/tasks/prereqs.yml +++ b/roles/keycloak/tasks/prereqs.yml @@ -15,6 +15,14 @@ fail_msg: "Cannot install HA setup without a backend database service. Check keycloak_ha_enabled and keycloak_db_enabled" success_msg: "{{ 'Configuring HA' if keycloak_ha_enabled else 'Configuring standalone' }}" +- name: Validate remote cache store configuration + ansible.builtin.assert: + that: + - (keycloak_remote_cache_enabled and keycloak_ha_enabled) or (not keycloak_ha_enabled) + quiet: True + fail_msg: "Cannot deploy with remote cache storage on infinispan when keycloak_ha_enabled is false" + success_msg: "{{ 'Configuring HA with infinispan remote cache storage' if keycloak_ha_enabled else 'Configuring standalone' }}" + - name: Validate credentials ansible.builtin.assert: that: diff --git a/roles/keycloak/templates/standalone-ha.xml.j2 b/roles/keycloak/templates/standalone-ha.xml.j2 new file mode 100644 index 0000000..d35a9e0 --- /dev/null +++ b/roles/keycloak/templates/standalone-ha.xml.j2 @@ -0,0 +1,695 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE + h2 + + sa + sa + + + +{% if keycloak_jdbc[keycloak_jdbc_engine].enabled %} + {{ keycloak_jdbc[keycloak_jdbc_engine].connection_url }} + {{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_name }} + + 20 + + + {{ keycloak_jdbc[keycloak_jdbc_engine].db_user }} + {{ keycloak_jdbc[keycloak_jdbc_engine].db_password }} + +{% else %} + jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE + h2 + + sa + sa + +{% endif %} + + +{% if keycloak_jdbc[keycloak_jdbc_engine].enabled %} + + {{ keycloak_jdbc[keycloak_jdbc_engine].driver_class }} + {{ keycloak_jdbc[keycloak_jdbc_engine].xa_datasource_class }} + +{% endif %} + + org.h2.jdbcx.JdbcDataSource + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{% if keycloak_ha_discovery == 'JDBC_PING' and keycloak_jdbc[keycloak_jdbc_engine].enabled %} + + java:jboss/datasources/KeycloakDS + {{ keycloak_jdbc[keycloak_jdbc_engine].initialize_db }} + INSERT INTO JGROUPSPING (own_addr, cluster_name, ping_data) values (?, ?, ?) + DELETE FROM JGROUPSPING WHERE own_addr=? AND cluster_name=? + SELECT ping_data FROM JGROUPSPING WHERE cluster_name=? + +{% elif keycloak_ha_discovery == 'TCPPING' %} + + {{ keycloak_cluster_nodes | map(attribute='inventory_host') | join (',') }} + 0 + 3000 + 2 + +{% endif %} + + + + + + + + + 30000 + + + + + + + + + + + + + + + + auth + + + classpath:${jboss.home.dir}/providers/* + + + master + 900 + + 2592000 + true + true + ${jboss.home.dir}/themes + +{% if keycloak_ha_enabled %} + + + + + + + +{% endif %} + + + + + + + + + + + + jpa + + + basic + + + + + + + + + + + + + + + + + + + default + + + + + + + + ${keycloak.jta.lookup.provider:jboss} + + + + + + + + + + + ${keycloak.x509cert.lookup.provider:default} + + + + default + + + + + + + + + + + + + + +{% if keycloak_modcluster.enabled %} + + + + + + + +{% endif %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{% if ansible_default_ipv4 is defined %} + +{% else %} + +{% endif %} + + + + + + + + + + + + + + + + + +{% if keycloak_modcluster.enabled %} +{% for modcluster in keycloak_modcluster.reverse_proxy_urls %} + + + +{% endfor %} +{% endif %} +{% if keycloak_ha_discovery == 'TCPPING' %} +{% for node in keycloak_cluster_nodes %} + + + +{% endfor %} +{% endif %} + + + + + diff --git a/roles/keycloak/vars/main.yml b/roles/keycloak/vars/main.yml index 026839e..f14e4b7 100644 --- a/roles/keycloak/vars/main.yml +++ b/roles/keycloak/vars/main.yml @@ -13,7 +13,7 @@ keycloak: service_name: "{{ keycloak_service_name }}" health_url: "{{ keycloak_management_url }}/health" cli_path: "{{ keycloak_jboss_home }}/bin/jboss-cli.sh" - config_template_source: "{{ keycloak_config_override_template if keycloak_config_override_template | length > 0 else 'standalone.xml.j2' }}" + config_template_source: "{{ keycloak_config_override_template if keycloak_config_override_template | length > 0 else 'standalone-ha.xml.j2' if keycloak_remote_cache_enabled else 'standalone.xml.j2' }}" # database keycloak_jdbc: From 6bfe046f5e24a8626a39677b595b2c8f0cf962af Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Sat, 1 Apr 2023 10:13:01 +0200 Subject: [PATCH 165/554] fix templates path --- roles/keycloak/tasks/install.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index f9526cd..ee8a46c 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -214,7 +214,7 @@ - name: "Deploy standalone {{ keycloak.service_name }} config to {{ keycloak_config_path_to_standalone_xml }}" become: yes ansible.builtin.template: - src: templates/standalone.xml + src: templates/standalone.xml.j2 dest: "{{ keycloak_config_path_to_standalone_xml }}" owner: "{{ keycloak_service_user }}" group: "{{ keycloak_service_group }}" @@ -242,7 +242,7 @@ - name: "Deploy HA {{ keycloak.service_name }} config to {{ keycloak_config_path_to_standalone_xml }} from {{ keycloak.config_template_source }}" become: yes ansible.builtin.template: - src: templates/standalone-ha.xml + src: templates/standalone-ha.xml.j2 dest: "{{ keycloak_config_path_to_standalone_xml }}" owner: "{{ keycloak_service_user }}" group: "{{ keycloak_service_group }}" From 1cfa229a5f5f9f1dddbe024093b7db1230f3f883 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Sat, 1 Apr 2023 11:45:40 +0200 Subject: [PATCH 166/554] Pass attributes to realm clients --- molecule/default/converge.yml | 2 ++ molecule/default/verify.yml | 33 ++++++++++++++++++++++++++--- roles/keycloak_realm/tasks/main.yml | 1 + 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index b9b8790..d3742e7 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -45,6 +45,8 @@ web_origins: "{{ keycloak_client_web_origins }}" users: "{{ keycloak_client_users }}" client_id: TestClient + attributes: + post.logout.redirect.uris: '/public/logout' pre_tasks: - name: "Retrieve assets server from env" ansible.builtin.set_fact: diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml index 07acf4d..061279d 100644 --- a/molecule/default/verify.yml +++ b/molecule/default/verify.yml @@ -4,7 +4,7 @@ vars: keycloak_admin_password: "remembertochangeme" keycloak_jvm_package: java-11-openjdk-headless - keycloak_port: http://localhost:8080 + keycloak_uri: http://localhost:8080 keycloak_management_port: http://localhost:9990 tasks: - name: Populate service facts @@ -17,13 +17,40 @@ - name: Verify we are running on requested jvm shell: | ps -ef | grep /usr/lib/jvm/java-11 | grep -v grep + changed_when: no - name: Verify token api call ansible.builtin.uri: - url: "{{ keycloak_port }}/auth/realms/master/protocol/openid-connect/token" + url: "{{ keycloak_uri }}/auth/realms/master/protocol/openid-connect/token" method: POST body: "client_id=admin-cli&username=admin&password={{ keycloak_admin_password }}&grant_type=password" validate_certs: no register: keycloak_auth_response until: keycloak_auth_response.status == 200 retries: 2 - delay: 2 \ No newline at end of file + delay: 2 + - name: Fetch openid-connect config + ansible.builtin.uri: + url: "{{ keycloak_uri }}/auth/realms/TestRealm/.well-known/openid-configuration" + method: GET + validate_certs: no + status_code: 200 + register: keycloak_openid_config + - name: Verify expected config + ansible.builtin.assert: + that: + - keycloak_openid_config.json.registration_endpoint == 'http://localhost:8080/auth/realms/TestRealm/clients-registrations/openid-connect' + - name: Get test realm clients + ansible.builtin.uri: + url: "{{ keycloak_uri }}/auth/admin/realms/TestRealm/clients" + method: GET + validate_certs: no + status_code: 200 + headers: + Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" + register: keycloak_query_clients + - debug: + msg: "{{ keycloak_query_clients.json | selectattr('clientId','equalto','TestClient') }}" + - name: Verify expected config + ansible.builtin.assert: + that: + - (keycloak_query_clients.json | selectattr('clientId','equalto','TestClient') | first)["attributes"]["post.logout.redirect.uris"] == '/public/logout' diff --git a/roles/keycloak_realm/tasks/main.yml b/roles/keycloak_realm/tasks/main.yml index 9233080..c137270 100644 --- a/roles/keycloak_realm/tasks/main.yml +++ b/roles/keycloak_realm/tasks/main.yml @@ -90,6 +90,7 @@ service_accounts_enabled: "{{ item.service_accounts_enabled | default(omit) }}" public_client: "{{ item.public_client | default(False) }}" protocol: "{{ item.protocol | default(omit) }}" + attributes: "{{ item.attributes | default(omit) }}" state: present no_log: "{{ keycloak_no_log | default('True') }}" register: create_client_result From 242b1cea0a520fea574807514ef6db02b378e9d1 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Sat, 1 Apr 2023 12:20:29 +0200 Subject: [PATCH 167/554] version bump to 1.2.1 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 3eec4c8..71e45e6 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.2.0" +version: "1.2.1" readme: README.md authors: - Romain Pelisse From 87ad97d57fd3e20f8bc701f7fcbe5ae436278295 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 11 Apr 2023 07:07:07 +0000 Subject: [PATCH 168/554] Update changelog for release 1.2.1 --- CHANGELOG.rst | 13 +++++++++++++ changelogs/changelog.yaml | 14 ++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 8607e91..acf89df 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,19 @@ middleware_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v1.2.1 +====== + +Minor Changes +------------- + +- Allow to setup keycloak HA cluster without remote cache store `#68 `_ + +Bugfixes +-------- + +- Pass attributes to realm clients `#69 `_ + v1.2.0 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 1647779..549540c 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -167,3 +167,17 @@ releases: - 63.yaml - 64.yaml release_date: '2023-03-16' + 1.2.1: + changes: + bugfixes: + - 'Pass attributes to realm clients `#69 `_ + + ' + minor_changes: + - 'Allow to setup keycloak HA cluster without remote cache store `#68 `_ + + ' + fragments: + - 68.yaml + - 69.yaml + release_date: '2023-04-11' From 6334daf244c4ff610ac860a856e1bea6b6bce845 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 12 Apr 2023 10:59:08 +0200 Subject: [PATCH 169/554] ci: fix typo and indent for TCPPING discovery --- roles/keycloak/tasks/install.yml | 4 ++-- roles/keycloak/tasks/prereqs.yml | 8 -------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index ee8a46c..864c52a 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -232,11 +232,11 @@ { "name": item, "address": 'jgroups-' + item, - "inventory_host": hostvars[item].ansible_default_ipv4.address | default(item) + '[' + keycloak_jgroups_port + ']', + "inventory_host": hostvars[item].ansible_default_ipv4.address | default(item) + '[' + (keycloak_jgroups_port | string) + ']', "value": hostvars[item].ansible_default_ipv4.address | default(item) } ] }} - loop: "{{ ansible_play_batch }}" + loop: "{{ ansible_play_batch }}" when: keycloak_ha_enabled and keycloak_ha_discovery == 'TCPPING' - name: "Deploy HA {{ keycloak.service_name }} config to {{ keycloak_config_path_to_standalone_xml }} from {{ keycloak.config_template_source }}" diff --git a/roles/keycloak/tasks/prereqs.yml b/roles/keycloak/tasks/prereqs.yml index 3f18964..c774c65 100644 --- a/roles/keycloak/tasks/prereqs.yml +++ b/roles/keycloak/tasks/prereqs.yml @@ -15,14 +15,6 @@ fail_msg: "Cannot install HA setup without a backend database service. Check keycloak_ha_enabled and keycloak_db_enabled" success_msg: "{{ 'Configuring HA' if keycloak_ha_enabled else 'Configuring standalone' }}" -- name: Validate remote cache store configuration - ansible.builtin.assert: - that: - - (keycloak_remote_cache_enabled and keycloak_ha_enabled) or (not keycloak_ha_enabled) - quiet: True - fail_msg: "Cannot deploy with remote cache storage on infinispan when keycloak_ha_enabled is false" - success_msg: "{{ 'Configuring HA with infinispan remote cache storage' if keycloak_ha_enabled else 'Configuring standalone' }}" - - name: Validate credentials ansible.builtin.assert: that: From 6ac0c18842270665fc9dd53221af6b1183c08ca9 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 12 Apr 2023 11:12:32 +0200 Subject: [PATCH 170/554] fix: drop xml element not available in 7.6 --- roles/keycloak/templates/standalone-ha.xml.j2 | 1 - 1 file changed, 1 deletion(-) diff --git a/roles/keycloak/templates/standalone-ha.xml.j2 b/roles/keycloak/templates/standalone-ha.xml.j2 index d35a9e0..026e85c 100644 --- a/roles/keycloak/templates/standalone-ha.xml.j2 +++ b/roles/keycloak/templates/standalone-ha.xml.j2 @@ -376,7 +376,6 @@ - From 8d16e241c1b0da33f65c2b1c1e560e1bacdd6f8b Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 14 Apr 2023 14:58:40 +0200 Subject: [PATCH 171/554] fix undefined facts when offline patching sso --- roles/keycloak/tasks/rhsso_patch.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/roles/keycloak/tasks/rhsso_patch.yml b/roles/keycloak/tasks/rhsso_patch.yml index 0cbf002..1b1e9a6 100644 --- a/roles/keycloak/tasks/rhsso_patch.yml +++ b/roles/keycloak/tasks/rhsso_patch.yml @@ -3,6 +3,8 @@ - name: Set download patch archive path ansible.builtin.set_fact: patch_archive: "{{ keycloak_dest }}/{{ sso_patch_bundle }}" + patch_bundle: "{{ sso_patch_bundle }}" + patch_version: "{{ sso_patch_version }}" when: sso_patch_version is defined - name: Check download patch archive path @@ -10,6 +12,7 @@ path: "{{ patch_archive }}" register: patch_archive_path when: sso_patch_version is defined + become: yes - name: Perform patch download from RHN via JBossNetwork API delegate_to: localhost From 43d978370d5b585801b4311d84eb623c60db882e Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 14 Apr 2023 15:50:48 +0200 Subject: [PATCH 172/554] bump to 1.2.2 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 71e45e6..318efcb 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.2.1" +version: "1.2.2" readme: README.md authors: - Romain Pelisse From c7d2bdcee35ba2437afde066a23ed416354dd339 Mon Sep 17 00:00:00 2001 From: Jonathan Wright Date: Fri, 21 Apr 2023 15:12:59 -0500 Subject: [PATCH 173/554] add configurability for XA transactions --- roles/keycloak_quarkus/defaults/main.yml | 3 +++ roles/keycloak_quarkus/meta/argument_specs.yml | 4 ++++ roles/keycloak_quarkus/templates/keycloak.conf.j2 | 3 +++ 3 files changed, 10 insertions(+) diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index f51ce59..371180e 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -52,6 +52,9 @@ keycloak_quarkus_frontend_url: http://localhost:8080/auth # proxy address forwarding mode if the server is behind a reverse proxy. [edge, reencrypt, passthrough] keycloak_quarkus_proxy_mode: edge +# disable xa transactions +keycloak_quarkus_transaction_xa_enabled: True + keycloak_quarkus_metrics_enabled: False keycloak_quarkus_health_enabled: True diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 9205cef..8c27fb2 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -248,3 +248,7 @@ argument_specs: default: False type: "bool" description: "Whether to start the service in development mode (start-dev)" + keycloak_quarkus_transaction_xa_enabled: + default: True + type: bool" + description: "Enable or disable XA transactions which may not be supported by some DBMS" diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index bd9f5bf..600e9d1 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -39,6 +39,9 @@ proxy={{ keycloak_quarkus_proxy_mode }} # Do not attach route to cookies and rely on the session affinity capabilities from reverse proxy #spi-sticky-session-encoder-infinispan-should-attach-route=false +# Transaction +transaction-xa-enabled={{ keycloak_quarkus_transaction_xa_enabled }} + # Logging #log-format=%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n log={{ keycloak_quarkus_log }} From d72d46c9459d3747a4db8d0b686ceaaef37babdf Mon Sep 17 00:00:00 2001 From: Jonathan Wright <8390543+jonathanspw@users.noreply.github.com> Date: Mon, 24 Apr 2023 08:50:16 -0500 Subject: [PATCH 174/554] fix typo --- roles/keycloak_quarkus/meta/argument_specs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 8c27fb2..66e8adf 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -250,5 +250,5 @@ argument_specs: description: "Whether to start the service in development mode (start-dev)" keycloak_quarkus_transaction_xa_enabled: default: True - type: bool" + type: "bool" description: "Enable or disable XA transactions which may not be supported by some DBMS" From 020bc86955f45d9d9e31e49dd5c4e5a2f668b07f Mon Sep 17 00:00:00 2001 From: Jonathan Wright <8390543+jonathanspw@users.noreply.github.com> Date: Mon, 24 Apr 2023 08:52:36 -0500 Subject: [PATCH 175/554] document keycloak_quarkus_transaction_xa_enabled --- roles/keycloak_quarkus/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index de330dc..ab98d4a 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -98,6 +98,7 @@ Role Defaults |`keycloak_quarkus_log_format`| Set a format specific to file log entries | `%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n` | |`keycloak_quarkus_proxy_mode`| The proxy address forwarding mode if the server is behind a reverse proxy | `edge` | |`keycloak_quarkus_start_dev`| Whether to start the service in development mode (start-dev) | `False` | +|`keycloak_quarkus_transaction_xa_enabled`| Whether to use XA transactions | `True` | Role Variables From 1a450ea1d72b7ccfbbea2f8d9de31d6211e3b989 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 2 May 2023 17:00:17 +0200 Subject: [PATCH 176/554] ci: add galaxy tags --- galaxy.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/galaxy.yml b/galaxy.yml index 318efcb..4590f76 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -21,6 +21,8 @@ tags: - infrastructure - authentication - java + - runtimes + - middleware dependencies: "middleware_automation.common": ">=1.0.0" "ansible.posix": ">=1.4.0" From 44ad3b8e6de51dce459a1850da2cceee71ccfb28 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 2 May 2023 18:05:12 +0200 Subject: [PATCH 177/554] add galaxy tag --- galaxy.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/galaxy.yml b/galaxy.yml index 4590f76..26f69f6 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -23,6 +23,7 @@ tags: - java - runtimes - middleware + - A4MW dependencies: "middleware_automation.common": ">=1.0.0" "ansible.posix": ">=1.4.0" From f566917bc2c5edfed014f130b7a509371a2f31dc Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 3 May 2023 08:54:20 +0200 Subject: [PATCH 178/554] ci: rename galaxy tag --- .github/workflows/ci.yml | 5 +++-- .github/workflows/docs.yml | 3 ++- .github/workflows/release.yml | 3 ++- galaxy.yml | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 54e3e9e..3764e8f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python_version: ["3.9"] + python_version: ["3.10"] steps: - name: Check out code uses: actions/checkout@v2 @@ -24,9 +24,10 @@ jobs: path: ansible_collections/middleware_automation/keycloak - name: Set up Python ${{ matrix.python_version }} - uses: actions/setup-python@v1 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python_version }} + cache: 'pip' - name: Install yamllint, ansible and molecule run: | diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 7163a00..e46b1e8 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -32,9 +32,10 @@ jobs: fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: 3.9 + cache: 'pip' - name: Install doc dependencies run: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f8cdffe..3f47356 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,9 +24,10 @@ jobs: token: ${{ secrets.TRIGGERING_PAT }} - name: Set up Python - uses: actions/setup-python@v1 + uses: actions/setup-python@v4 with: python-version: "3.x" + cache: 'pip' - name: Get current version id: get_version diff --git a/galaxy.yml b/galaxy.yml index 26f69f6..d4232dc 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -23,7 +23,7 @@ tags: - java - runtimes - middleware - - A4MW + - a4mw dependencies: "middleware_automation.common": ">=1.0.0" "ansible.posix": ">=1.4.0" From a3bffe94014af171132463a490cfc2392206e303 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 3 May 2023 15:23:46 +0200 Subject: [PATCH 179/554] Bump to 1.2.3 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index d4232dc..5b34de2 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.2.2" +version: "1.2.3" readme: README.md authors: - Romain Pelisse From 706677910b8b0d133f1329fca92db36e47d1d664 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 5 May 2023 11:07:42 +0200 Subject: [PATCH 180/554] ci: update apt before installing hub --- .github/workflows/docs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index e46b1e8..071821d 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -42,6 +42,7 @@ jobs: python -m pip install --upgrade pip pip install -r ansible_collections/middleware_automation/keycloak/docs/requirements.txt pip install -r ansible_collections/middleware_automation/keycloak/requirements.txt + sudo apt --fix-missing update sudo apt install -y sed hub - name: Create default collection path From fd0a4e44928097a88893e0640c8adf87befd274e Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Tue, 9 May 2023 11:45:25 +0200 Subject: [PATCH 181/554] Close #76 - Keycloak role: fix deprecation warning for `ipaddr` --- .../templates/15.0.8/standalone-infinispan.xml.j2 | 6 +++--- .../keycloak/templates/9.0.2/standalone-infinispan.xml.j2 | 2 +- roles/keycloak/templates/standalone-ha.xml.j2 | 8 ++++---- roles/keycloak/templates/standalone-infinispan.xml.j2 | 8 ++++---- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/roles/keycloak/templates/15.0.8/standalone-infinispan.xml.j2 b/roles/keycloak/templates/15.0.8/standalone-infinispan.xml.j2 index 4198b83..be61837 100644 --- a/roles/keycloak/templates/15.0.8/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/15.0.8/standalone-infinispan.xml.j2 @@ -631,7 +631,7 @@ -{% if keycloak_modcluster.enabled %} +{% if keycloak_modcluster.enabled %} @@ -639,7 +639,7 @@ -{% endif %} +{% endif %} @@ -728,7 +728,7 @@ {% if ansible_default_ipv4 is defined %} - + {% else %} {% endif %} diff --git a/roles/keycloak/templates/9.0.2/standalone-infinispan.xml.j2 b/roles/keycloak/templates/9.0.2/standalone-infinispan.xml.j2 index 2b2842b..9e0ae66 100644 --- a/roles/keycloak/templates/9.0.2/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/9.0.2/standalone-infinispan.xml.j2 @@ -725,7 +725,7 @@ {% if ansible_default_ipv4 is defined %} - + {% else %} {% endif %} diff --git a/roles/keycloak/templates/standalone-ha.xml.j2 b/roles/keycloak/templates/standalone-ha.xml.j2 index 026e85c..75df7ab 100644 --- a/roles/keycloak/templates/standalone-ha.xml.j2 +++ b/roles/keycloak/templates/standalone-ha.xml.j2 @@ -584,7 +584,7 @@ -{% if keycloak_modcluster.enabled %} +{% if keycloak_modcluster.enabled %} @@ -592,7 +592,7 @@ -{% endif %} +{% endif %} @@ -638,7 +638,7 @@ - + @@ -652,7 +652,7 @@ {% if ansible_default_ipv4 is defined %} - + {% else %} {% endif %} diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index e326924..30a6e20 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -622,7 +622,7 @@ -{% if keycloak_modcluster.enabled %} +{% if keycloak_modcluster.enabled %} @@ -630,7 +630,7 @@ -{% endif %} +{% endif %} @@ -676,7 +676,7 @@ - + @@ -690,7 +690,7 @@ {% if ansible_default_ipv4 is defined %} - + {% else %} {% endif %} From aad373a8e9ab39125059a727ea63b86f8196e1af Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Tue, 9 May 2023 11:03:55 +0200 Subject: [PATCH 182/554] Close #74 - add `sqlserver` support to keycloak role --- roles/keycloak/README.md | 4 ++-- roles/keycloak/defaults/main.yml | 5 ++++- roles/keycloak/meta/argument_specs.yml | 2 +- roles/keycloak/tasks/prereqs.yml | 2 +- roles/keycloak/vars/main.yml | 22 ++++++++++++++++++++++ 5 files changed, 30 insertions(+), 5 deletions(-) diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index aff6a1e..f252be9 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -83,7 +83,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:---------| |`keycloak_offline_install` | perform an offline install | `False`| -|`keycloak_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| +|`keycloak_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| |`keycloak_version`| keycloak.org package version | `18.0.2` | |`keycloak_dest`| Installation root path | `/opt/keycloak` | |`keycloak_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_version }}/{{ keycloak_archive }}` | @@ -127,7 +127,7 @@ The following variables are _required_ only when `keycloak_ha_enabled` is True: |`keycloak_modcluster_url` | _deprecated_ Host for the modcluster reverse proxy | `localhost` | |`keycloak_modcluster_port` | _deprecated_ Port for the modcluster reverse proxy | `6666` | |`keycloak_modcluster_urls` | List of {host,port} dicts for the modcluster reverse proxies | `[ { localhost:6666 } ]` | -|`keycloak_jdbc_engine` | backend database engine when db is enabled: [ postgres, mariadb ] | `postgres` | +|`keycloak_jdbc_engine` | backend database engine when db is enabled: [ postgres, mariadb, sqlserver ] | `postgres` | |`keycloak_infinispan_url` | URL for the infinispan remote-cache server | `localhost:11122` | |`keycloak_infinispan_user` | username for connecting to infinispan | `supervisor` | |`keycloak_infinispan_pass` | password for connecting to infinispan | `supervisor` | diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 795768f..da84f13 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -79,7 +79,7 @@ keycloak_infinispan_use_ssl: False keycloak_infinispan_trust_store_path: /etc/pki/java/cacerts keycloak_infinispan_trust_store_password: changeit -### database backend engine: values [ 'postgres', 'mariadb' ] +### database backend engine: values [ 'postgres', 'mariadb', 'sqlserver' ] keycloak_jdbc_engine: postgres ### database backend credentials keycloak_db_user: keycloak-user @@ -94,5 +94,8 @@ keycloak_default_jdbc: mariadb: url: 'jdbc:mariadb://localhost:3306/keycloak' version: 2.7.4 + sqlserver: + url: 'jdbc:sqlserver://localhost:1433;databaseName=keycloak;' + version: 12.2.0 # role specific vars keycloak_no_log: True diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 2fe1e05..9f72b2e 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -237,7 +237,7 @@ argument_specs: keycloak_jdbc_engine: # line 72 of keycloak/defaults/main.yml default: "postgres" - description: "Backend database flavour when db is enabled: [ postgres, mariadb ]" + description: "Backend database flavour when db is enabled: [ postgres, mariadb, sqlserver ]" type: "str" keycloak_db_user: # line 74 of keycloak/defaults/main.yml diff --git a/roles/keycloak/tasks/prereqs.yml b/roles/keycloak/tasks/prereqs.yml index c774c65..418a574 100644 --- a/roles/keycloak/tasks/prereqs.yml +++ b/roles/keycloak/tasks/prereqs.yml @@ -27,7 +27,7 @@ - name: Validate persistence configuration ansible.builtin.assert: that: - - keycloak_jdbc_engine is defined and keycloak_jdbc_engine in [ 'postgres', 'mariadb' ] + - keycloak_jdbc_engine is defined and keycloak_jdbc_engine in [ 'postgres', 'mariadb', 'sqlserver' ] - keycloak_jdbc_url | length > 0 - keycloak_db_user | length > 0 - keycloak_db_pass | length > 0 diff --git a/roles/keycloak/vars/main.yml b/roles/keycloak/vars/main.yml index f14e4b7..d44ee5a 100644 --- a/roles/keycloak/vars/main.yml +++ b/roles/keycloak/vars/main.yml @@ -56,6 +56,28 @@ keycloak_jdbc: ping_data varbinary(5000) DEFAULT NULL, PRIMARY KEY (own_addr, cluster_name)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin + sqlserver: + enabled: "{{ (keycloak_ha_enabled or keycloak_db_enabled) and keycloak_jdbc_engine == 'sqlserver' }}" + driver_class: com.microsoft.sqlserver.jdbc.SQLServerDriver + xa_datasource_class: com.microsoft.sqlserver.jdbc.SQLServerXADataSource + driver_module_name: "com.microsoft.sqlserver" + driver_module_dir: "{{ keycloak_jboss_home }}/modules/com/microsoft/sqlserver/main" + driver_version: "{{ keycloak_jdbc_driver_version }}" + driver_jar_filename: "mssql-java-client-{{ keycloak_jdbc_driver_version }}.jar" + driver_jar_url: "https://repo1.maven.org/maven2/com/microsoft/sqlserver/mssql-jdbc/{{ keycloak_jdbc_driver_version }}.jre11/mssql-jdbc-{{ keycloak_jdbc_driver_version }}.jre11.jar" # e.g., https://repo1.maven.org/maven2/com/microsoft/sqlserver/mssql-jdbc/12.2.0.jre11/mssql-jdbc-12.2.0.jre11.jar + connection_url: "{{ keycloak_jdbc_url }}" + db_user: "{{ keycloak_db_user }}" + db_password: "{{ keycloak_db_pass }}" + initialize_db: > + IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[JGROUPSPING]') AND type in (N'U')) + BEGIN + CREATE TABLE JGROUPSPING ( + own_addr varchar(200) NOT NULL, + cluster_name varchar(200) NOT NULL, + updated DATETIME2 DEFAULT SYSUTCDATETIME(), + ping_data varbinary(5000) DEFAULT NULL, + PRIMARY KEY (own_addr, cluster_name)) + END # reverse proxy mod_cluster keycloak_modcluster: From e4811221be40e03c9cfe5e38a927b930168275b0 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 9 May 2023 15:25:41 +0200 Subject: [PATCH 183/554] ci: fix release wf, bump to 1.2.4 --- .github/workflows/release.yml | 1 + galaxy.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3f47356..ff64240 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -48,6 +48,7 @@ jobs: run: | python -m pip install --upgrade pip pip install ansible-core antsibull + sudo apt --fix-missing update sudo apt install -y sed hub - name: Build collection diff --git a/galaxy.yml b/galaxy.yml index 5b34de2..a19e284 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.2.3" +version: "1.2.4" readme: README.md authors: - Romain Pelisse From 7471e07921449ebb5ae4d7a0492347ba0bd810bc Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 9 May 2023 13:49:15 +0000 Subject: [PATCH 184/554] Update changelog for release 1.2.4 --- CHANGELOG.rst | 15 +++++++++++++++ changelogs/changelog.yaml | 22 ++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index acf89df..145ab2e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,21 @@ middleware_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v1.2.4 +====== + +Minor Changes +------------- + +- Add ``sqlserver`` to keycloak role jdbc configurations `#78 `_ +- Add configurability for XA transactions `#73 `_ + +Bugfixes +-------- + +- Fix deprecation warning for ``ipaddr`` `#77 `_ +- Fix undefined facts when offline patching sso `#71 `_ + v1.2.1 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 549540c..330081c 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -181,3 +181,25 @@ releases: - 68.yaml - 69.yaml release_date: '2023-04-11' + 1.2.4: + changes: + bugfixes: + - 'Fix deprecation warning for ``ipaddr`` `#77 `_ + + ' + - 'Fix undefined facts when offline patching sso `#71 `_ + + ' + minor_changes: + - 'Add ``sqlserver`` to keycloak role jdbc configurations `#78 `_ + + ' + - 'Add configurability for XA transactions `#73 `_ + + ' + fragments: + - 71.yaml + - 73.yaml + - 77.yaml + - 78.yaml + release_date: '2023-05-09' From 01fd2cc4fdb1037577b9a6e48b3120fbc9c542d7 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 9 May 2023 16:44:16 +0200 Subject: [PATCH 185/554] Bump to 1.2.5 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index a19e284..27c0e21 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.2.4" +version: "1.2.5" readme: README.md authors: - Romain Pelisse From 370d424b24fcc6d217f6fb2c468aeb689e7e44a2 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Fri, 12 May 2023 08:57:36 +0200 Subject: [PATCH 186/554] Close #80 - introduce systemd restart behavior --- roles/keycloak/README.md | 6 +++++- roles/keycloak/defaults/main.yml | 6 +++++- roles/keycloak/meta/argument_specs.yml | 16 ++++++++++++++++ roles/keycloak/tasks/install.yml | 2 +- roles/keycloak/templates/keycloak.service.j2 | 9 +++++++++ 5 files changed, 36 insertions(+), 3 deletions(-) diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index f252be9..3508a71 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -72,6 +72,10 @@ Role Defaults |`keycloak_config_standalone_xml`| filename for configuration | `keycloak.xml` | |`keycloak_service_user`| posix account username | `keycloak` | |`keycloak_service_group`| posix account group | `keycloak` | +|`keycloak_service_restart_on_failure`| systemd restart-on-failure behavior activation |True +|`keycloak_service_startlimitintervalsec`| systemd StartLimitIntervalSec | `300` if `keycloak_service_restart_on_failure` else `` +|`keycloak_service_startlimitburst`| systemd StartLimitBurst | `5` if `keycloak_service_restart_on_failure` else `` +|`keycloak_service_restartsec`| systemd RestartSec | `10s` if `keycloak_service_restart_on_failure` else `` |`keycloak_service_pidfile`| pid file path for service | `/run/keycloak.pid` | |`keycloak_jvm_package`| RHEL java package runtime | `java-1.8.0-openjdk-headless` | |`keycloak_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_jvm_package RPM path | `None` | @@ -116,7 +120,7 @@ The following are a set of _required_ variables for the role: | Variable | Description | |:---------|:------------| |`keycloak_admin_password`| Password for the administration console user account (minimum 12 characters) | -|`keycloak_frontend_url` | frontend URL for keycloak endpoint | `http://localhost:8080/auth` | +|`keycloak_frontend_url` | frontend URL for keycloak endpoint | `http://localhost:8080/auth/` | The following variables are _required_ only when `keycloak_ha_enabled` is True: diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index da84f13..5a54ce3 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -23,6 +23,10 @@ keycloak_service_name: keycloak keycloak_service_desc: Keycloak keycloak_service_start_delay: 10 keycloak_service_start_retries: 25 +keycloak_service_restart_on_failure: True +keycloak_service_startlimitintervalsec: "{{ 300 if keycloak_service_restart_on_failure else '' }}" +keycloak_service_startlimitburst: "{{ 5 if keycloak_service_restart_on_failure else '' }}" +keycloak_service_restartsec: "{{ '10s' if keycloak_service_restart_on_failure else '' }}" keycloak_configure_firewalld: False @@ -67,7 +71,7 @@ keycloak_modcluster_urls: port: "{{ keycloak_modcluster_port }}" ### keycloak frontend url -keycloak_frontend_url: http://localhost:8080/auth +keycloak_frontend_url: http://localhost:8080/auth/ ### infinispan remote caches access (hotrod) keycloak_infinispan_user: supervisor diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 9f72b2e..e348973 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -290,6 +290,22 @@ argument_specs: default: "25" description: "How many time should Ansible retry to connect to the service after it was started, before failing." type: "int" + keycloak_service_restart_on_failure: + default: true + description: "systemd restart-on-failure behavior activation for keycloak" + type: "bool" + keycloak_service_startlimitintervalsec: + default: 300 + description: "systemd StartLimitIntervalSec for keycloak" + type: "int" + keycloak_service_startlimitburst: + default: 5 + description: "systemd StartLimitBurst for keycloak" + type: "int" + keycloak_service_restartsec: + default: "5s" + description: "systemd RestartSec for keycloak" + type: "str" keycloak_no_log: default: true type: "bool" diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index 864c52a..f9c9028 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -266,5 +266,5 @@ - restart keycloak when: - keycloak_ha_enabled - - keycloak_remote_cache_enabled + - keycloak_remote_cache_enabled - keycloak_config_override_template | length == 0 diff --git a/roles/keycloak/templates/keycloak.service.j2 b/roles/keycloak/templates/keycloak.service.j2 index 0fcecbf..0dec52a 100644 --- a/roles/keycloak/templates/keycloak.service.j2 +++ b/roles/keycloak/templates/keycloak.service.j2 @@ -2,6 +2,11 @@ [Unit] Description={{ keycloak.service_name }} Server After=network.target +{% if keycloak_service_restart_on_failure %} +StartLimitIntervalSec={{ keycloak_service_startlimitintervalsec }} +StartLimitBurst={{ keycloak_service_startlimitburst }} +{% endif %} + [Service] Type=forking @@ -12,6 +17,10 @@ ExecStop={{ keycloak_dest }}/keycloak-service.sh stop TimeoutStartSec=30 TimeoutStopSec=30 LimitNOFILE=102642 +{% if keycloak_service_restart_on_failure %} +Restart=on-failure +RestartSec={{ keycloak_service_restartsec }} +{% endif %} [Install] WantedBy=multi-user.target From fd375a141d0866c75180ccef7062784b6e0580da Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 22 May 2023 16:12:25 +0200 Subject: [PATCH 187/554] ci: update linter settings, fix new linter issues --- .ansible-lint | 5 +++-- molecule/default/verify.yml | 7 ++++--- molecule/quarkus/prepare.yml | 25 +++++++++++++++---------- molecule/quarkus/verify.yml | 20 ++++++++++++-------- roles/keycloak/tasks/rhsso_patch.yml | 6 +++--- 5 files changed, 37 insertions(+), 26 deletions(-) diff --git a/.ansible-lint b/.ansible-lint index eaa75d0..ccabc00 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -21,19 +21,20 @@ warn_list: - experimental - ignore-errors - no-handler - - fqcn-builtins - no-log-password - jinja[spacing] - jinja[invalid] - meta-no-tags - - name[template] - name[casing] - fqcn[action] - schema[meta] + - var-naming[no-role-prefix] + - key-order[task] skip_list: - vars_should_not_be_used - file_is_small_enough + - name[template] use_default_rules: true parseable: true diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml index 061279d..86047a4 100644 --- a/molecule/default/verify.yml +++ b/molecule/default/verify.yml @@ -15,8 +15,11 @@ - ansible_facts.services["keycloak.service"]["state"] == "running" - ansible_facts.services["keycloak.service"]["status"] == "enabled" - name: Verify we are running on requested jvm - shell: | + ansible.builtin.shell: | + set -o pipefail ps -ef | grep /usr/lib/jvm/java-11 | grep -v grep + args: + executable: /bin/bash changed_when: no - name: Verify token api call ansible.builtin.uri: @@ -48,8 +51,6 @@ headers: Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" register: keycloak_query_clients - - debug: - msg: "{{ keycloak_query_clients.json | selectattr('clientId','equalto','TestClient') }}" - name: Verify expected config ansible.builtin.assert: that: diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index f54dbb8..4b85c14 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -11,25 +11,30 @@ ansible.builtin.set_fact: hera_home: "{{ lookup('env', 'HERA_HOME') }}" - - ansible.builtin.command: openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes -subj '/CN=instance' + - name: Create certificate request + ansible.builtin.command: openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes -subj '/CN=instance' delegate_to: localhost + changed_when: False - - block: - - ansible.builtin.lineinfile: - dest: /etc/hosts - line: "127.0.0.1 instance" - state: present - delegate_to: localhost - become: yes + - name: Set /etc/hosts + ansible.builtin.lineinfile: + dest: /etc/hosts + line: "127.0.0.1 instance" + state: present + delegate_to: localhost + become: yes when: - hera_home is defined - hera_home | length == 0 - - ansible.builtin.file: + - name: Create conf directory # risky-file-permissions in test user account does not exist yet + ansible.builtin.file: state: directory path: /opt/keycloak/keycloak-18.0.0/conf/ + mode: 0755 - - ansible.builtin.copy: + - name: Copy certificates + ansible.builtin.copy: src: "{{ item }}" dest: "/opt/keycloak/keycloak-18.0.0/conf/{{ item }}" mode: 0444 diff --git a/molecule/quarkus/verify.yml b/molecule/quarkus/verify.yml index 1d4e5ae..6a3d547 100644 --- a/molecule/quarkus/verify.yml +++ b/molecule/quarkus/verify.yml @@ -4,26 +4,30 @@ tasks: - name: Populate service facts ansible.builtin.service_facts: + - name: Check if keycloak service started ansible.builtin.assert: that: - ansible_facts.services["keycloak.service"]["state"] == "running" - ansible_facts.services["keycloak.service"]["status"] == "enabled" - - set_fact: + - name: Set internal envvar + ansible.builtin.set_fact: hera_home: "{{ lookup('env', 'HERA_HOME') }}" - - block: - - name: Fetch openID config - shell: | + - name: Verify openid config + block: + - name: Fetch openID config # noqa command-instead-of-module + ansible.builtin.shell: | + set -o pipefail curl https://instance:8443/realms/master/.well-known/openid-configuration -k | jq . + args: + executable: /bin/bash delegate_to: localhost register: openid_config - - debug: - msg: " {{ openid_config.stdout | from_json }}" - delegate_to: localhost + changed_when: False - name: Verify endpoint URLs - assert: + ansible.builtin.assert: that: - (openid_config.stdout | from_json)["backchannel_authentication_endpoint"] == 'https://instance/realms/master/protocol/openid-connect/ext/ciba/auth' - (openid_config.stdout | from_json)['issuer'] == 'https://instance/realms/master' diff --git a/roles/keycloak/tasks/rhsso_patch.yml b/roles/keycloak/tasks/rhsso_patch.yml index 1b1e9a6..7f00a50 100644 --- a/roles/keycloak/tasks/rhsso_patch.yml +++ b/roles/keycloak/tasks/rhsso_patch.yml @@ -35,14 +35,14 @@ run_once: yes - name: Determine patch versions list - set_fact: + ansible.builtin.set_fact: filtered_versions: "{{ rhn_products.results | map(attribute='file_path') | select('match', '^[^/]*/rh-sso-.*[0-9]*[.][0-9]*[.][0-9]*.*$') | map('regex_replace','[^/]*/rh-sso-([0-9]*[.][0-9]*[.][0-9]*)-.*','\\1' ) | list | unique }}" when: sso_patch_version is not defined or sso_patch_version | length == 0 delegate_to: localhost run_once: yes - name: Determine latest version - set_fact: + ansible.builtin.set_fact: sso_latest_version: "{{ filtered_versions | middleware_automation.keycloak.version_sort | last }}" when: sso_patch_version is not defined or sso_patch_version | length == 0 delegate_to: localhost @@ -58,7 +58,7 @@ run_once: yes - name: "Determine selected patch from supplied version: {{ sso_patch_version }}" - set_fact: + ansible.builtin.set_fact: rhn_filtered_products: "{{ rhn_products.results | selectattr('file_path', 'match', '[^/]*/' + sso_patch_bundle + '$') }}" patch_bundle: "{{ sso_patch_bundle }}" patch_version: "{{ sso_patch_version }}" From 98e1633c4352f1bdbbe9c961cb9a98b7b5a1b5bb Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 22 May 2023 16:24:28 +0200 Subject: [PATCH 188/554] ci: new linter rules take 2 --- .ansible-lint | 1 + molecule/default/verify.yml | 2 +- molecule/quarkus/verify.yml | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.ansible-lint b/.ansible-lint index ccabc00..92e5eaf 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -30,6 +30,7 @@ warn_list: - schema[meta] - var-naming[no-role-prefix] - key-order[task] + - blocked_modules skip_list: - vars_should_not_be_used diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml index 86047a4..490b38c 100644 --- a/molecule/default/verify.yml +++ b/molecule/default/verify.yml @@ -14,7 +14,7 @@ that: - ansible_facts.services["keycloak.service"]["state"] == "running" - ansible_facts.services["keycloak.service"]["status"] == "enabled" - - name: Verify we are running on requested jvm + - name: Verify we are running on requested jvm # noqa blocked_modules command-instead-of-module ansible.builtin.shell: | set -o pipefail ps -ef | grep /usr/lib/jvm/java-11 | grep -v grep diff --git a/molecule/quarkus/verify.yml b/molecule/quarkus/verify.yml index 6a3d547..553c4d6 100644 --- a/molecule/quarkus/verify.yml +++ b/molecule/quarkus/verify.yml @@ -17,7 +17,7 @@ - name: Verify openid config block: - - name: Fetch openID config # noqa command-instead-of-module + - name: Fetch openID config # noqa blocked_modules command-instead-of-module ansible.builtin.shell: | set -o pipefail curl https://instance:8443/realms/master/.well-known/openid-configuration -k | jq . From c4b4be3c3b9a55936415f3caa54eae9c69d80ddd Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 25 May 2023 11:10:18 +0200 Subject: [PATCH 189/554] add variable for force_frontend_url --- .gitignore | 2 + galaxy.yml | 2 +- plugins/filter/version_sort.py | 52 ------------------- plugins/module_utils/version.py | 22 -------- roles/keycloak/README.md | 8 +-- roles/keycloak/defaults/main.yml | 1 + roles/keycloak/meta/argument_specs.yml | 4 ++ roles/keycloak/tasks/rhsso_patch.yml | 2 +- roles/keycloak/templates/standalone-ha.xml.j2 | 2 +- .../templates/standalone-infinispan.xml.j2 | 2 +- roles/keycloak/templates/standalone.xml.j2 | 2 +- roles/keycloak/vars/main.yml | 1 + 12 files changed, 17 insertions(+), 83 deletions(-) delete mode 100644 plugins/filter/version_sort.py delete mode 100644 plugins/module_utils/version.py diff --git a/.gitignore b/.gitignore index 9cc2eb2..e1daa92 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ *.zip .tmp .cache +.vscode/ +__pycache__/ docs/plugins/ docs/roles/ docs/_build/ diff --git a/galaxy.yml b/galaxy.yml index 27c0e21..76205f1 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -25,7 +25,7 @@ tags: - middleware - a4mw dependencies: - "middleware_automation.common": ">=1.0.0" + "middleware_automation.common": ">=1.1.0" "ansible.posix": ">=1.4.0" repository: https://github.com/ansible-middleware/keycloak documentation: https://ansible-middleware.github.io/keycloak diff --git a/plugins/filter/version_sort.py b/plugins/filter/version_sort.py deleted file mode 100644 index beb44cb..0000000 --- a/plugins/filter/version_sort.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (C) 2021 Eric Lavarde -# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) -# SPDX-License-Identifier: GPL-3.0-or-later - -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -DOCUMENTATION = ''' - name: version_sort - short_description: Sort a list according to version order instead of pure alphabetical one - version_added: 2.2.0 - author: Eric L. (@ericzolf) - description: - - Sort a list according to version order instead of pure alphabetical one. - options: - _input: - description: A list of strings to sort. - type: list - elements: string - required: true -''' - -EXAMPLES = ''' -- name: Convert list of tuples into dictionary - ansible.builtin.set_fact: - dictionary: "{{ ['2.1', '2.10', '2.9'] | middleware_automation.keycloak.version_sort }}" - # Result is ['2.1', '2.9', '2.10'] -''' - -RETURN = ''' - _value: - description: The list of strings sorted by version. - type: list - elements: string -''' - -from ansible_collections.middleware_automation.keycloak.plugins.module_utils.version import LooseVersion - - -def version_sort(value, reverse=False): - '''Sort a list according to loose versions so that e.g. 2.9 is smaller than 2.10''' - return sorted(value, key=LooseVersion, reverse=reverse) - - -class FilterModule(object): - ''' Version sort filter ''' - - def filters(self): - return { - 'version_sort': version_sort - } diff --git a/plugins/module_utils/version.py b/plugins/module_utils/version.py deleted file mode 100644 index 3699881..0000000 --- a/plugins/module_utils/version.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2021, Felix Fontein -# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) -# SPDX-License-Identifier: GPL-3.0-or-later - -"""Provide version object to compare version numbers.""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -from ansible.module_utils.six import raise_from - -try: - from ansible.module_utils.compat.version import LooseVersion # noqa: F401, pylint: disable=unused-import -except ImportError: - try: - from distutils.version import LooseVersion # noqa: F401, pylint: disable=unused-import - except ImportError as exc: - msg = 'To use this plugin or module with ansible-core 2.11, you need to use Python < 3.12 with distutils.version present' - raise_from(ImportError(msg), exc) diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index 3508a71..5c882cc 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -73,9 +73,9 @@ Role Defaults |`keycloak_service_user`| posix account username | `keycloak` | |`keycloak_service_group`| posix account group | `keycloak` | |`keycloak_service_restart_on_failure`| systemd restart-on-failure behavior activation |True -|`keycloak_service_startlimitintervalsec`| systemd StartLimitIntervalSec | `300` if `keycloak_service_restart_on_failure` else `` -|`keycloak_service_startlimitburst`| systemd StartLimitBurst | `5` if `keycloak_service_restart_on_failure` else `` -|`keycloak_service_restartsec`| systemd RestartSec | `10s` if `keycloak_service_restart_on_failure` else `` +|`keycloak_service_startlimitintervalsec`| systemd StartLimitIntervalSec | `300` if `keycloak_service_restart_on_failure` else `` | +|`keycloak_service_startlimitburst`| systemd StartLimitBurst | `5` if `keycloak_service_restart_on_failure` else `` | +|`keycloak_service_restartsec`| systemd RestartSec | `10s` if `keycloak_service_restart_on_failure` else `` | |`keycloak_service_pidfile`| pid file path for service | `/run/keycloak.pid` | |`keycloak_jvm_package`| RHEL java package runtime | `java-1.8.0-openjdk-headless` | |`keycloak_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_jvm_package RPM path | `None` | @@ -110,7 +110,7 @@ Role Defaults |`keycloak_force_install` | Remove pre-existing versions of service | `False` | |`keycloak_url` | URL for configuration rest calls | `http://{{ keycloak_host }}:{{ keycloak_http_port }}` | |`keycloak_management_url` | URL for management console rest calls | `http://{{ keycloak_host }}:{{ keycloak_management_http_port }}` | - +|`keycloak_frontend_url_force` | Force backend requests to use the frontend URL | `False` | Role Variables -------------- diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 5a54ce3..025a815 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -72,6 +72,7 @@ keycloak_modcluster_urls: ### keycloak frontend url keycloak_frontend_url: http://localhost:8080/auth/ +keycloak_frontend_url_force: False ### infinispan remote caches access (hotrod) keycloak_infinispan_user: supervisor diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index e348973..3a7572a 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -199,6 +199,10 @@ argument_specs: default: "http://localhost" description: "Frontend URL for keycloak endpoints when a reverse proxy is used" type: "str" + keycloak_frontend_url_force: + default: False + description: "Force backend requests to use the frontend URL" + type: "bool" keycloak_infinispan_user: # line 62 of keycloak/defaults/main.yml default: "supervisor" diff --git a/roles/keycloak/tasks/rhsso_patch.yml b/roles/keycloak/tasks/rhsso_patch.yml index 7f00a50..b03b55c 100644 --- a/roles/keycloak/tasks/rhsso_patch.yml +++ b/roles/keycloak/tasks/rhsso_patch.yml @@ -43,7 +43,7 @@ - name: Determine latest version ansible.builtin.set_fact: - sso_latest_version: "{{ filtered_versions | middleware_automation.keycloak.version_sort | last }}" + sso_latest_version: "{{ filtered_versions | middleware_automation.common.version_sort | last }}" when: sso_patch_version is not defined or sso_patch_version | length == 0 delegate_to: localhost run_once: yes diff --git a/roles/keycloak/templates/standalone-ha.xml.j2 b/roles/keycloak/templates/standalone-ha.xml.j2 index 75df7ab..14a6e3a 100644 --- a/roles/keycloak/templates/standalone-ha.xml.j2 +++ b/roles/keycloak/templates/standalone-ha.xml.j2 @@ -573,7 +573,7 @@ - + diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index 30a6e20..5f0ea5b 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -611,7 +611,7 @@ - + diff --git a/roles/keycloak/templates/standalone.xml.j2 b/roles/keycloak/templates/standalone.xml.j2 index 438a0da..6ba9efd 100644 --- a/roles/keycloak/templates/standalone.xml.j2 +++ b/roles/keycloak/templates/standalone.xml.j2 @@ -517,7 +517,7 @@ - + diff --git a/roles/keycloak/vars/main.yml b/roles/keycloak/vars/main.yml index d44ee5a..cffbac3 100644 --- a/roles/keycloak/vars/main.yml +++ b/roles/keycloak/vars/main.yml @@ -84,6 +84,7 @@ keycloak_modcluster: enabled: "{{ keycloak_ha_enabled or keycloak_modcluster_enabled }}" reverse_proxy_urls: "{{ keycloak_modcluster_urls }}" frontend_url: "{{ keycloak_frontend_url }}" + force_frontend_url: "{{ keycloak_frontend_url_force }}" # infinispan keycloak_remotecache: From 19f1750a33c5460d06ad2ace0a5f415113a11e1f Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 25 May 2023 11:47:19 +0200 Subject: [PATCH 190/554] Add db pool validation configuration --- roles/keycloak/README.md | 18 ++++++++++++++---- roles/keycloak/defaults/main.yml | 6 ++++++ roles/keycloak/meta/argument_specs.yml | 16 ++++++++++++++++ roles/keycloak/templates/standalone-ha.xml.j2 | 6 ++++++ .../templates/standalone-infinispan.xml.j2 | 6 ++++++ roles/keycloak/templates/standalone.xml.j2 | 6 ++++++ roles/keycloak/vars/main.yml | 3 +++ 7 files changed, 57 insertions(+), 4 deletions(-) diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index 5c882cc..19f0ed9 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -111,6 +111,11 @@ Role Defaults |`keycloak_url` | URL for configuration rest calls | `http://{{ keycloak_host }}:{{ keycloak_http_port }}` | |`keycloak_management_url` | URL for management console rest calls | `http://{{ keycloak_host }}:{{ keycloak_management_http_port }}` | |`keycloak_frontend_url_force` | Force backend requests to use the frontend URL | `False` | +|`keycloak_db_background_validation` | Enable background validation of database connection | `False` | +|`keycloak_db_background_validation_millis`| How frequenly the connection pool is validated in the background | `10000` if background validation enabled | +|`keycloak_db_background_validate_on_match` Enable validate on match for database connections | `False` | +|`keycloak_frontend_url` | frontend URL for keycloak endpoint | `http://localhost:8080/auth/` | + Role Variables -------------- @@ -123,7 +128,7 @@ The following are a set of _required_ variables for the role: |`keycloak_frontend_url` | frontend URL for keycloak endpoint | `http://localhost:8080/auth/` | -The following variables are _required_ only when `keycloak_ha_enabled` is True: +The following parameters are _required_ only when `keycloak_ha_enabled` is True: | Variable | Description | Default | |:---------|:------------|:--------| @@ -141,7 +146,7 @@ The following variables are _required_ only when `keycloak_ha_enabled` is True: |`keycloak_infinispan_trust_store_password`| Password for opening truststore | `changeit` | -The following variables are _required_ only when `keycloak_db_enabled` is True: +The following parameters are _required_ only when `keycloak_db_enabled` is True: | Variable | Description | Default | |:---------|:------------|:---------| @@ -151,6 +156,13 @@ The following variables are _required_ only when `keycloak_db_enabled` is True: |`keycloak_db_pass` | password for connecting to postgres | `keycloak-pass` | +The following variables are _optional_: + +| Variable | Description | +|:---------|:------------| +|`keycloak_db_valid_conn_sql` | Override the default database connection validation query sql | + + Example Playbook ----------------- @@ -161,8 +173,6 @@ Example Playbook - hosts: ... vars: keycloak_admin_password: "remembertochangeme" - collections: - - middleware_automation.keycloak roles: - middleware_automation.keycloak.keycloak ``` diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 025a815..68e473b 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -89,6 +89,12 @@ keycloak_jdbc_engine: postgres ### database backend credentials keycloak_db_user: keycloak-user keycloak_db_pass: keycloak-pass +## connection validation +keycloak_db_background_validation: False +keycloak_db_background_validation_millis: "{{ 10000 if keycloak_db_background_validation else 0 }}" +keycloak_db_background_validate_on_match: False +# variable to override database connection validation query +keycloak_db_valid_conn_sql: keycloak_jdbc_url: "{{ keycloak_default_jdbc[keycloak_jdbc_engine].url }}" keycloak_jdbc_driver_version: "{{ keycloak_default_jdbc[keycloak_jdbc_engine].version }}" # override the variables above, following defaults show minimum supported versions diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 3a7572a..9441fff 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -318,6 +318,22 @@ argument_specs: default: "{{ True if keycloak_ha_enabled else False }}" description: "Enable remote cache store when in clustered ha configurations" type: "bool" + keycloak_db_background_validation: + default: False + description: "Enable background validation of database connection" + type: "bool" + keycloak_db_background_validation_millis: + default: "{{ 10000 if keycloak_db_background_validation else 0 }}" + description: "How frequenly the connection pool is validated in the background" + type: 'int' + keycloak_db_background_validate_on_match: + default: False + description: "Enable validate on match for database connections" + type: "bool" + keycloak_db_valid_conn_sql: + required: False + description: "Override the default database connection validation query sql" + type: "str" downstream: options: sso_version: diff --git a/roles/keycloak/templates/standalone-ha.xml.j2 b/roles/keycloak/templates/standalone-ha.xml.j2 index 14a6e3a..ca9f4f9 100644 --- a/roles/keycloak/templates/standalone-ha.xml.j2 +++ b/roles/keycloak/templates/standalone-ha.xml.j2 @@ -136,6 +136,12 @@ {{ keycloak_jdbc[keycloak_jdbc_engine].db_user }} {{ keycloak_jdbc[keycloak_jdbc_engine].db_password }} + + {{ keycloak_jdbc[keycloak_jdbc_engine].validate_query }} + {{ keycloak_db_background_validate_on_match }} + {{ keycloak_db_background_validation }} + {{ keycloak_db_background_validation_millis }} + {% else %} jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE h2 diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index 5f0ea5b..ba75cd2 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -136,6 +136,12 @@ {{ keycloak_jdbc[keycloak_jdbc_engine].db_user }} {{ keycloak_jdbc[keycloak_jdbc_engine].db_password }} + + {{ keycloak_jdbc[keycloak_jdbc_engine].validate_query }} + {{ keycloak_db_background_validate_on_match }} + {{ keycloak_db_background_validation }} + {{ keycloak_db_background_validation_millis }} + {% else %} jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE h2 diff --git a/roles/keycloak/templates/standalone.xml.j2 b/roles/keycloak/templates/standalone.xml.j2 index 6ba9efd..4f538d0 100644 --- a/roles/keycloak/templates/standalone.xml.j2 +++ b/roles/keycloak/templates/standalone.xml.j2 @@ -123,6 +123,12 @@ {{ keycloak_jdbc[keycloak_jdbc_engine].db_user }} {{ keycloak_jdbc[keycloak_jdbc_engine].db_password }} + + {{ keycloak_jdbc[keycloak_jdbc_engine].validate_query }} + {{ keycloak_db_background_validate_on_match }} + {{ keycloak_db_background_validation }} + {{ keycloak_db_background_validation_millis }} + {% else %} jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE h2 diff --git a/roles/keycloak/vars/main.yml b/roles/keycloak/vars/main.yml index cffbac3..993e841 100644 --- a/roles/keycloak/vars/main.yml +++ b/roles/keycloak/vars/main.yml @@ -29,6 +29,7 @@ keycloak_jdbc: connection_url: "{{ keycloak_jdbc_url }}" db_user: "{{ keycloak_db_user }}" db_password: "{{ keycloak_db_pass }}" + validate_query: "{{ keycloak_db_valid_conn_sql | default('select 1') }}" initialize_db: > CREATE TABLE IF NOT EXISTS JGROUPSPING ( own_addr varchar(200) NOT NULL, @@ -48,6 +49,7 @@ keycloak_jdbc: connection_url: "{{ keycloak_jdbc_url }}" db_user: "{{ keycloak_db_user }}" db_password: "{{ keycloak_db_pass }}" + validate_query: "{{ keycloak_db_valid_conn_sql | default('select 1') }}" initialize_db: > CREATE TABLE IF NOT EXISTS JGROUPSPING ( own_addr varchar(200) NOT NULL, @@ -68,6 +70,7 @@ keycloak_jdbc: connection_url: "{{ keycloak_jdbc_url }}" db_user: "{{ keycloak_db_user }}" db_password: "{{ keycloak_db_pass }}" + validate_query: "{{ keycloak_db_valid_conn_sql | default('select 1') }}" initialize_db: > IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[JGROUPSPING]') AND type in (N'U')) BEGIN From 2be35f9a674fe848d35eea0be762a6399d8e6ad8 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 26 May 2023 14:28:52 +0200 Subject: [PATCH 191/554] typo in readme --- roles/keycloak/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index 19f0ed9..d4cb6c9 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -113,7 +113,7 @@ Role Defaults |`keycloak_frontend_url_force` | Force backend requests to use the frontend URL | `False` | |`keycloak_db_background_validation` | Enable background validation of database connection | `False` | |`keycloak_db_background_validation_millis`| How frequenly the connection pool is validated in the background | `10000` if background validation enabled | -|`keycloak_db_background_validate_on_match` Enable validate on match for database connections | `False` | +|`keycloak_db_background_validate_on_match` | Enable validate on match for database connections | `False` | |`keycloak_frontend_url` | frontend URL for keycloak endpoint | `http://localhost:8080/auth/` | From aaae1d1129801d88f80271228337808ad1a798df Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 26 May 2023 16:31:13 +0200 Subject: [PATCH 192/554] Allow to configure admin_url --- roles/keycloak/README.md | 2 ++ roles/keycloak/defaults/main.yml | 1 + roles/keycloak/meta/argument_specs.yml | 4 ++++ roles/keycloak/templates/standalone-ha.xml.j2 | 3 +++ roles/keycloak/templates/standalone-infinispan.xml.j2 | 3 +++ roles/keycloak/templates/standalone.xml.j2 | 3 +++ roles/keycloak/vars/main.yml | 1 + 7 files changed, 17 insertions(+) diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index d4cb6c9..3fc8a61 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -117,6 +117,7 @@ Role Defaults |`keycloak_frontend_url` | frontend URL for keycloak endpoint | `http://localhost:8080/auth/` | + Role Variables -------------- @@ -161,6 +162,7 @@ The following variables are _optional_: | Variable | Description | |:---------|:------------| |`keycloak_db_valid_conn_sql` | Override the default database connection validation query sql | +|`keycloak_admin_url` | Override the default administration endpoint URL | Example Playbook diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 68e473b..aa52d74 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -73,6 +73,7 @@ keycloak_modcluster_urls: ### keycloak frontend url keycloak_frontend_url: http://localhost:8080/auth/ keycloak_frontend_url_force: False +keycloak_admin_url: ### infinispan remote caches access (hotrod) keycloak_infinispan_user: supervisor diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 9441fff..0dc4cb3 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -334,6 +334,10 @@ argument_specs: required: False description: "Override the default database connection validation query sql" type: "str" + keycloak_admin_url: + required: False + description: "Override the default administration endpoint URL" + type: "str" downstream: options: sso_version: diff --git a/roles/keycloak/templates/standalone-ha.xml.j2 b/roles/keycloak/templates/standalone-ha.xml.j2 index ca9f4f9..67f5da8 100644 --- a/roles/keycloak/templates/standalone-ha.xml.j2 +++ b/roles/keycloak/templates/standalone-ha.xml.j2 @@ -580,6 +580,9 @@ +{% if keycloak_modcluster.admin_url | length > 0 %} + +{% endif %} diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index ba75cd2..cea9c87 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -618,6 +618,9 @@ +{% if keycloak_modcluster.admin_url | length > 0 %} + +{% endif %} diff --git a/roles/keycloak/templates/standalone.xml.j2 b/roles/keycloak/templates/standalone.xml.j2 index 4f538d0..e38e1f0 100644 --- a/roles/keycloak/templates/standalone.xml.j2 +++ b/roles/keycloak/templates/standalone.xml.j2 @@ -524,6 +524,9 @@ +{% if keycloak_modcluster.admin_url | length > 0 %} + +{% endif %} diff --git a/roles/keycloak/vars/main.yml b/roles/keycloak/vars/main.yml index 993e841..638ed3d 100644 --- a/roles/keycloak/vars/main.yml +++ b/roles/keycloak/vars/main.yml @@ -88,6 +88,7 @@ keycloak_modcluster: reverse_proxy_urls: "{{ keycloak_modcluster_urls }}" frontend_url: "{{ keycloak_frontend_url }}" force_frontend_url: "{{ keycloak_frontend_url_force }}" + admin_url: "{{ keycloak_admin_url | default('') }}" # infinispan keycloak_remotecache: From b7eef6a720aac4e779eb5b6448f28e0f0c78b263 Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 26 May 2023 21:00:15 +0000 Subject: [PATCH 193/554] Update changelog for release 1.2.5 --- CHANGELOG.rst | 11 +++++++++++ changelogs/changelog.yaml | 21 +++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 145ab2e..87d2470 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,17 @@ middleware_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v1.2.5 +====== + +Minor Changes +------------- + +- Add configuration for database connection pool validation `#85 `_ +- Allow to configure administration endpoint URL `#86 `_ +- Allow to force backend URLs to frontend URLs `#84 `_ +- Introduce systemd unit restart behavior `#81 `_ + v1.2.4 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 330081c..779b2bd 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -203,3 +203,24 @@ releases: - 77.yaml - 78.yaml release_date: '2023-05-09' + 1.2.5: + changes: + minor_changes: + - 'Add configuration for database connection pool validation `#85 `_ + + ' + - 'Allow to configure administration endpoint URL `#86 `_ + + ' + - 'Allow to force backend URLs to frontend URLs `#84 `_ + + ' + - 'Introduce systemd unit restart behavior `#81 `_ + + ' + fragments: + - 81.yaml + - 84.yaml + - 85.yaml + - 86.yaml + release_date: '2023-05-26' From b77c166945ac5b5059309afe1a80065c68110dfb Mon Sep 17 00:00:00 2001 From: Massimo Schiavon Date: Wed, 31 May 2023 11:12:24 +0200 Subject: [PATCH 194/554] change xa_datasource_class for mariadb jdbc configuration --- roles/keycloak/vars/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/keycloak/vars/main.yml b/roles/keycloak/vars/main.yml index 638ed3d..6486559 100644 --- a/roles/keycloak/vars/main.yml +++ b/roles/keycloak/vars/main.yml @@ -40,7 +40,7 @@ keycloak_jdbc: mariadb: enabled: "{{ (keycloak_ha_enabled or keycloak_db_enabled) and keycloak_jdbc_engine == 'mariadb' }}" driver_class: org.mariadb.jdbc.Driver - xa_datasource_class: org.mariadb.jdbc.MySQLDataSource + xa_datasource_class: org.mariadb.jdbc.MariaDbDataSource driver_module_name: "org.mariadb" driver_module_dir: "{{ keycloak_jboss_home }}/modules/org/mariadb/main" driver_version: "{{ keycloak_jdbc_driver_version }}" @@ -100,4 +100,4 @@ keycloak_remotecache: server_name: "{{ keycloak_infinispan_url }}" use_ssl: "{{ keycloak_infinispan_use_ssl }}" trust_store_path: "{{ keycloak_infinispan_trust_store_path }}" - trust_store_password: "{{ keycloak_infinispan_trust_store_password }}" \ No newline at end of file + trust_store_password: "{{ keycloak_infinispan_trust_store_password }}" From 623db426e0ebfea43724dcb136a67766740c2f30 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Wed, 31 May 2023 16:41:57 +0200 Subject: [PATCH 195/554] Keycloak: add feature enabling/disabling --- roles/keycloak/README.md | 1 + roles/keycloak/defaults/main.yml | 2 ++ roles/keycloak/meta/argument_specs.yml | 9 +++++++-- roles/keycloak/tasks/install.yml | 12 ++++++++++++ .../templates/keycloak-profile.properties.j2 | 3 +++ roles/keycloak/vars/main.yml | 1 + 6 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 roles/keycloak/templates/keycloak-profile.properties.j2 diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index 3fc8a61..adbc4cd 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -77,6 +77,7 @@ Role Defaults |`keycloak_service_startlimitburst`| systemd StartLimitBurst | `5` if `keycloak_service_restart_on_failure` else `` | |`keycloak_service_restartsec`| systemd RestartSec | `10s` if `keycloak_service_restart_on_failure` else `` | |`keycloak_service_pidfile`| pid file path for service | `/run/keycloak.pid` | +|`keycloak_features` | List of `name`/`status` pairs of features (also known as profiles on RH-SSO) to `enable` or `disable`, example: `[ { name: 'docker', status: 'enabled' } ]` | `[]` |`keycloak_jvm_package`| RHEL java package runtime | `java-1.8.0-openjdk-headless` | |`keycloak_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_jvm_package RPM path | `None` | |`keycloak_java_opts`| Additional JVM options | `-Xms1024m -Xmx2048m` | diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index aa52d74..78b626d 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -16,6 +16,7 @@ keycloak_config_dir: "{{ keycloak_jboss_home }}/standalone/configuration" keycloak_config_standalone_xml: "keycloak.xml" keycloak_config_path_to_standalone_xml: "{{ keycloak_jboss_home }}/standalone/configuration/{{ keycloak_config_standalone_xml }}" keycloak_config_override_template: '' +keycloak_config_path_to_properties: "{{ keycloak_jboss_home }}/standalone/configuration/profile.properties" keycloak_service_user: keycloak keycloak_service_group: keycloak keycloak_service_pidfile: "/run/keycloak.pid" @@ -45,6 +46,7 @@ keycloak_management_http_port: 9990 keycloak_management_https_port: 9993 keycloak_java_opts: "-Xms1024m -Xmx2048m" keycloak_prefer_ipv4: True +keycloak_features: [] ### Enable configuration for database backend, clustering and remote caches on infinispan keycloak_ha_enabled: False diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 0dc4cb3..1c03cbd 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -89,6 +89,11 @@ argument_specs: default: "/run/keycloak.pid" description: "PID file path for service" type: "str" + keycloak_features: + # line 17 of keycloak/defaults/main.yml + default: "[]" + description: "List of `name`/`status` pairs of features (also known as profiles on RH-SSO) to `enable` or `disable`, example: `[ { name: 'docker', status: 'enabled' } ]`" + type: "list" keycloak_bind_address: # line 34 of keycloak/defaults/main.yml default: "0.0.0.0" @@ -96,7 +101,7 @@ argument_specs: type: "str" keycloak_management_port_bind_address: default: "127.0.0.1" - description: "Address for binding the managemnt ports" + description: "Address for binding the management ports" type: "str" keycloak_host: # line 35 of keycloak/defaults/main.yml @@ -318,7 +323,7 @@ argument_specs: default: "{{ True if keycloak_ha_enabled else False }}" description: "Enable remote cache store when in clustered ha configurations" type: "bool" - keycloak_db_background_validation: + keycloak_db_background_validation: default: False description: "Enable background validation of database connection" type: "bool" diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index f9c9028..b3294f4 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -268,3 +268,15 @@ - keycloak_ha_enabled - keycloak_remote_cache_enabled - keycloak_config_override_template | length == 0 + +- name: "Deploy profile.properties file to {{ keycloak_config_path_to_properties }}" + become: yes + ansible.builtin.template: + src: keycloak-profile.properties.j2 + dest: "{{ keycloak_config_path_to_properties }}" + owner: "{{ keycloak_service_user }}" + group: "{{ keycloak_service_group }}" + mode: 0640 + notify: + - restart keycloak + when: keycloak_features | length > 0 diff --git a/roles/keycloak/templates/keycloak-profile.properties.j2 b/roles/keycloak/templates/keycloak-profile.properties.j2 new file mode 100644 index 0000000..c618dc2 --- /dev/null +++ b/roles/keycloak/templates/keycloak-profile.properties.j2 @@ -0,0 +1,3 @@ +{% for feature in keycloak.features %} +feature.{{ feature.name }}={{ feature.status | default('enabled') }} +{% endfor %} \ No newline at end of file diff --git a/roles/keycloak/vars/main.yml b/roles/keycloak/vars/main.yml index 638ed3d..4798545 100644 --- a/roles/keycloak/vars/main.yml +++ b/roles/keycloak/vars/main.yml @@ -14,6 +14,7 @@ keycloak: health_url: "{{ keycloak_management_url }}/health" cli_path: "{{ keycloak_jboss_home }}/bin/jboss-cli.sh" config_template_source: "{{ keycloak_config_override_template if keycloak_config_override_template | length > 0 else 'standalone-ha.xml.j2' if keycloak_remote_cache_enabled else 'standalone.xml.j2' }}" + features: "{{ keycloak_features }}" # database keycloak_jdbc: From bc4cb5c52ad9a8e3724869f79da5adc97eedba00 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Wed, 31 May 2023 18:11:00 +0200 Subject: [PATCH 196/554] Introduce `keycloak_service_restart_always` alongside `keycloak_service_restart_on_failure` --- roles/keycloak/README.md | 9 +++++---- roles/keycloak/defaults/main.yml | 9 +++++---- roles/keycloak/meta/argument_specs.yml | 8 ++++++-- roles/keycloak/templates/keycloak.service.j2 | 8 ++++---- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index adbc4cd..ef6cc01 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -72,10 +72,11 @@ Role Defaults |`keycloak_config_standalone_xml`| filename for configuration | `keycloak.xml` | |`keycloak_service_user`| posix account username | `keycloak` | |`keycloak_service_group`| posix account group | `keycloak` | -|`keycloak_service_restart_on_failure`| systemd restart-on-failure behavior activation |True -|`keycloak_service_startlimitintervalsec`| systemd StartLimitIntervalSec | `300` if `keycloak_service_restart_on_failure` else `` | -|`keycloak_service_startlimitburst`| systemd StartLimitBurst | `5` if `keycloak_service_restart_on_failure` else `` | -|`keycloak_service_restartsec`| systemd RestartSec | `10s` if `keycloak_service_restart_on_failure` else `` | +|`keycloak_service_restart_always`| systemd restart always behavior activation | `False` +|`keycloak_service_restart_on_failure`| systemd restart on-failure behavior activation | `False` +|`keycloak_service_startlimitintervalsec`| systemd StartLimitIntervalSec | `300` | +|`keycloak_service_startlimitburst`| systemd StartLimitBurst | `5` | +|`keycloak_service_restartsec`| systemd RestartSec | `10s` | |`keycloak_service_pidfile`| pid file path for service | `/run/keycloak.pid` | |`keycloak_features` | List of `name`/`status` pairs of features (also known as profiles on RH-SSO) to `enable` or `disable`, example: `[ { name: 'docker', status: 'enabled' } ]` | `[]` |`keycloak_jvm_package`| RHEL java package runtime | `java-1.8.0-openjdk-headless` | diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 78b626d..d0137a8 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -24,10 +24,11 @@ keycloak_service_name: keycloak keycloak_service_desc: Keycloak keycloak_service_start_delay: 10 keycloak_service_start_retries: 25 -keycloak_service_restart_on_failure: True -keycloak_service_startlimitintervalsec: "{{ 300 if keycloak_service_restart_on_failure else '' }}" -keycloak_service_startlimitburst: "{{ 5 if keycloak_service_restart_on_failure else '' }}" -keycloak_service_restartsec: "{{ '10s' if keycloak_service_restart_on_failure else '' }}" +keycloak_service_restart_always: False +keycloak_service_restart_on_failure: False +keycloak_service_startlimitintervalsec: "300" +keycloak_service_startlimitburst: "5" +keycloak_service_restartsec: "10s" keycloak_configure_firewalld: False diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 1c03cbd..8e05939 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -299,9 +299,13 @@ argument_specs: default: "25" description: "How many time should Ansible retry to connect to the service after it was started, before failing." type: "int" + keycloak_service_restart_always: + default: false + description: "systemd restart always behavior activation for keycloak" + type: "bool" keycloak_service_restart_on_failure: - default: true - description: "systemd restart-on-failure behavior activation for keycloak" + default: false + description: "systemd restart on-failure behavior activation for keycloak" type: "bool" keycloak_service_startlimitintervalsec: default: 300 diff --git a/roles/keycloak/templates/keycloak.service.j2 b/roles/keycloak/templates/keycloak.service.j2 index 0dec52a..5de014b 100644 --- a/roles/keycloak/templates/keycloak.service.j2 +++ b/roles/keycloak/templates/keycloak.service.j2 @@ -2,10 +2,8 @@ [Unit] Description={{ keycloak.service_name }} Server After=network.target -{% if keycloak_service_restart_on_failure %} StartLimitIntervalSec={{ keycloak_service_startlimitintervalsec }} StartLimitBurst={{ keycloak_service_startlimitburst }} -{% endif %} [Service] @@ -17,10 +15,12 @@ ExecStop={{ keycloak_dest }}/keycloak-service.sh stop TimeoutStartSec=30 TimeoutStopSec=30 LimitNOFILE=102642 -{% if keycloak_service_restart_on_failure %} +{% if keycloak_service_restart_always %} +Restart=always +{% elif keycloak_service_restart_on_failure %} Restart=on-failure -RestartSec={{ keycloak_service_restartsec }} {% endif %} +RestartSec={{ keycloak_service_restartsec }} [Install] WantedBy=multi-user.target From 6986190159d5a2dd12b89b1665746d5f25d854ca Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 1 Jun 2023 10:27:46 +0200 Subject: [PATCH 197/554] Bumo to v1.2.6 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 76205f1..d6ed1ac 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.2.5" +version: "1.2.6" readme: README.md authors: - Romain Pelisse From ced4ce7828ae0ddd62b9385423d68c7c0f6a07a5 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 7 Jun 2023 11:56:12 +0200 Subject: [PATCH 198/554] handle WFLYCTL0117 when validation_millis is 0 --- roles/keycloak/templates/standalone-ha.xml.j2 | 2 ++ roles/keycloak/templates/standalone-infinispan.xml.j2 | 2 ++ roles/keycloak/templates/standalone.xml.j2 | 2 ++ 3 files changed, 6 insertions(+) diff --git a/roles/keycloak/templates/standalone-ha.xml.j2 b/roles/keycloak/templates/standalone-ha.xml.j2 index 67f5da8..e3b62ea 100644 --- a/roles/keycloak/templates/standalone-ha.xml.j2 +++ b/roles/keycloak/templates/standalone-ha.xml.j2 @@ -139,8 +139,10 @@ {{ keycloak_jdbc[keycloak_jdbc_engine].validate_query }} {{ keycloak_db_background_validate_on_match }} +{% if keycloak_db_background_validation_millis > 0 or keycloak_db_background_validation %} {{ keycloak_db_background_validation }} {{ keycloak_db_background_validation_millis }} +{% endif %} {% else %} jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index cea9c87..c1590cd 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -139,8 +139,10 @@ {{ keycloak_jdbc[keycloak_jdbc_engine].validate_query }} {{ keycloak_db_background_validate_on_match }} +{% if keycloak_db_background_validation_millis > 0 or keycloak_db_background_validation %} {{ keycloak_db_background_validation }} {{ keycloak_db_background_validation_millis }} +{% endif %} {% else %} jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE diff --git a/roles/keycloak/templates/standalone.xml.j2 b/roles/keycloak/templates/standalone.xml.j2 index e38e1f0..4e5aa05 100644 --- a/roles/keycloak/templates/standalone.xml.j2 +++ b/roles/keycloak/templates/standalone.xml.j2 @@ -126,8 +126,10 @@ {{ keycloak_jdbc[keycloak_jdbc_engine].validate_query }} {{ keycloak_db_background_validate_on_match }} +{% if keycloak_db_background_validation_millis > 0 or keycloak_db_background_validation %} {{ keycloak_db_background_validation }} {{ keycloak_db_background_validation_millis }} +{% endif %} {% else %} jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE From e99a0db174886fe72d832183e1aea0e9f424191d Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 7 Jun 2023 12:25:58 +0200 Subject: [PATCH 199/554] Add missing type conversion in templates --- roles/keycloak/templates/standalone-ha.xml.j2 | 2 +- roles/keycloak/templates/standalone-infinispan.xml.j2 | 2 +- roles/keycloak/templates/standalone.xml.j2 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/roles/keycloak/templates/standalone-ha.xml.j2 b/roles/keycloak/templates/standalone-ha.xml.j2 index e3b62ea..f108d2d 100644 --- a/roles/keycloak/templates/standalone-ha.xml.j2 +++ b/roles/keycloak/templates/standalone-ha.xml.j2 @@ -139,7 +139,7 @@ {{ keycloak_jdbc[keycloak_jdbc_engine].validate_query }} {{ keycloak_db_background_validate_on_match }} -{% if keycloak_db_background_validation_millis > 0 or keycloak_db_background_validation %} +{% if keycloak_db_background_validation_millis | int > 0 or keycloak_db_background_validation %} {{ keycloak_db_background_validation }} {{ keycloak_db_background_validation_millis }} {% endif %} diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index c1590cd..0d052ed 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -139,7 +139,7 @@ {{ keycloak_jdbc[keycloak_jdbc_engine].validate_query }} {{ keycloak_db_background_validate_on_match }} -{% if keycloak_db_background_validation_millis > 0 or keycloak_db_background_validation %} +{% if keycloak_db_background_validation_millis | int > 0 or keycloak_db_background_validation %} {{ keycloak_db_background_validation }} {{ keycloak_db_background_validation_millis }} {% endif %} diff --git a/roles/keycloak/templates/standalone.xml.j2 b/roles/keycloak/templates/standalone.xml.j2 index 4e5aa05..bf2d528 100644 --- a/roles/keycloak/templates/standalone.xml.j2 +++ b/roles/keycloak/templates/standalone.xml.j2 @@ -126,7 +126,7 @@ {{ keycloak_jdbc[keycloak_jdbc_engine].validate_query }} {{ keycloak_db_background_validate_on_match }} -{% if keycloak_db_background_validation_millis > 0 or keycloak_db_background_validation %} +{% if keycloak_db_background_validation_millis | int > 0 or keycloak_db_background_validation %} {{ keycloak_db_background_validation }} {{ keycloak_db_background_validation_millis }} {% endif %} From 97bea7ba394d833eff05ab72b9010dd957223ca5 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 7 Jun 2023 12:29:15 +0000 Subject: [PATCH 200/554] Update changelog for release 1.2.6 --- CHANGELOG.rst | 15 +++++++++++++++ changelogs/changelog.yaml | 23 +++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 87d2470..620d281 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,21 @@ middleware_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v1.2.6 +====== + +Minor Changes +------------- + +- Add profile features enabling/disabling `#87 `_ +- Improve service restart behavior configuration `#88 `_ +- Update default xa_datasource_class value for mariadb jdbc configuration `#89 `_ + +Bugfixes +-------- + +- Handle WFLYCTL0117 when background validation millis is 0 `#90 `_ + v1.2.5 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 779b2bd..203f4f2 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -224,3 +224,26 @@ releases: - 85.yaml - 86.yaml release_date: '2023-05-26' + 1.2.6: + changes: + bugfixes: + - 'Handle WFLYCTL0117 when background validation millis is 0 `#90 `_ + + ' + minor_changes: + - 'Add profile features enabling/disabling `#87 `_ + + ' + - 'Improve service restart behavior configuration `#88 `_ + + ' + - 'Update default xa_datasource_class value for mariadb jdbc configuration `#89 + `_ + + ' + fragments: + - 87.yaml + - 88.yaml + - 89.yaml + - 90.yaml + release_date: '2023-06-07' From 874215a5920b9a14f9f4f22579098cf6df01d9a9 Mon Sep 17 00:00:00 2001 From: Massimo Schiavon Date: Fri, 9 Jun 2023 10:51:13 +0200 Subject: [PATCH 201/554] remove empty string default for keycloak_db_valid_conn_sql rely on defaults set in keycloak_jdbc dict --- roles/keycloak/defaults/main.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index d0137a8..4a1fda3 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -97,8 +97,6 @@ keycloak_db_pass: keycloak-pass keycloak_db_background_validation: False keycloak_db_background_validation_millis: "{{ 10000 if keycloak_db_background_validation else 0 }}" keycloak_db_background_validate_on_match: False -# variable to override database connection validation query -keycloak_db_valid_conn_sql: keycloak_jdbc_url: "{{ keycloak_default_jdbc[keycloak_jdbc_engine].url }}" keycloak_jdbc_driver_version: "{{ keycloak_default_jdbc[keycloak_jdbc_engine].version }}" # override the variables above, following defaults show minimum supported versions From 18e60daa93496ffdfb65944155d9a42116d9e5d4 Mon Sep 17 00:00:00 2001 From: footur <3769085+Footur@users.noreply.github.com> Date: Sat, 10 Jun 2023 15:16:58 +0200 Subject: [PATCH 202/554] Update Keycloakx to v21.1.1 Signed-off-by: footur <3769085+Footur@users.noreply.github.com> --- roles/keycloak_quarkus/defaults/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 371180e..063863f 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -1,6 +1,6 @@ --- ### Configuration specific to keycloak -keycloak_quarkus_version: 18.0.0 +keycloak_quarkus_version: 21.1.1 keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip" keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" From 33404281942d0220cb44408b311dacf1442d98cb Mon Sep 17 00:00:00 2001 From: footur <3769085+Footur@users.noreply.github.com> Date: Sat, 10 Jun 2023 15:18:31 +0200 Subject: [PATCH 203/554] =?UTF-8?q?Remove=20the=20"--auto-build"=20flag=20?= =?UTF-8?q?=E2=80=93=20it's=20deprecated?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: footur <3769085+Footur@users.noreply.github.com> --- roles/keycloak_quarkus/templates/keycloak.service.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/templates/keycloak.service.j2 b/roles/keycloak_quarkus/templates/keycloak.service.j2 index 14e7542..f7ffc1c 100644 --- a/roles/keycloak_quarkus/templates/keycloak.service.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.service.j2 @@ -10,7 +10,7 @@ PIDFile={{ keycloak_quarkus_service_pidfile }} {% if keycloak_quarkus_start_dev %} ExecStart={{ keycloak.home }}/bin/kc.sh start-dev {% else %} -ExecStart={{ keycloak.home }}/bin/kc.sh start --auto-build --log={{ keycloak_quarkus_log }} +ExecStart={{ keycloak.home }}/bin/kc.sh start --log={{ keycloak_quarkus_log }} {% endif %} User={{ keycloak.service_user }} From 1dd579a6d1b52f64179140d842194fc07fd683b4 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Sat, 10 Jun 2023 16:31:19 +0200 Subject: [PATCH 204/554] Allow to override jgroups subnet --- roles/keycloak/README.md | 2 +- roles/keycloak/defaults/main.yml | 1 + roles/keycloak/meta/argument_specs.yml | 4 ++++ roles/keycloak/templates/standalone-ha.xml.j2 | 4 +++- roles/keycloak/templates/standalone-infinispan.xml.j2 | 4 +++- 5 files changed, 12 insertions(+), 3 deletions(-) diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index ef6cc01..f25420f 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -165,7 +165,7 @@ The following variables are _optional_: |:---------|:------------| |`keycloak_db_valid_conn_sql` | Override the default database connection validation query sql | |`keycloak_admin_url` | Override the default administration endpoint URL | - +|`keycloak_jgroups_subnet`| Override the subnet match for jgroups cluster formation; if not defined, it will be inferred from local machine route configuration | Example Playbook ----------------- diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index d0137a8..da98d24 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -42,6 +42,7 @@ keycloak_http_port: 8080 keycloak_https_port: 8443 keycloak_ajp_port: 8009 keycloak_jgroups_port: 7600 +keycloak_jgroups_subnet: keycloak_management_port_bind_address: 127.0.0.1 keycloak_management_http_port: 9990 keycloak_management_https_port: 9993 diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 8e05939..5392cfc 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -347,6 +347,10 @@ argument_specs: required: False description: "Override the default administration endpoint URL" type: "str" + keycloak_jgroups_subnet: + required: False + description: "Override the subnet match for jgroups cluster formation; if not defined, it will be inferred from local machine route configuration" + type: "str" downstream: options: sso_version: diff --git a/roles/keycloak/templates/standalone-ha.xml.j2 b/roles/keycloak/templates/standalone-ha.xml.j2 index f108d2d..f3ca185 100644 --- a/roles/keycloak/templates/standalone-ha.xml.j2 +++ b/roles/keycloak/templates/standalone-ha.xml.j2 @@ -662,7 +662,9 @@ -{% if ansible_default_ipv4 is defined %} +{% keycloak_jgroups_subnet is defined and keycloak_jgroups_subnet | length > 0 %} + +{% elif ansible_default_ipv4 is defined and (ansible_default_ipv4.network + '/' + ansible_default_ipv4.netmask) | ansible.utils.ipaddr('net') | length > 0 %} {% else %} diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index 0d052ed..304b0fd 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -700,7 +700,9 @@ -{% if ansible_default_ipv4 is defined %} +{% keycloak_jgroups_subnet is defined and keycloak_jgroups_subnet | length > 0 %} + +{% elif ansible_default_ipv4 is defined and (ansible_default_ipv4.network + '/' + ansible_default_ipv4.netmask) | ansible.utils.ipaddr('net') | length > 0 %} {% else %} From 8f697f6a536c5253a9bd6a62720b12181f711b05 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Sat, 10 Jun 2023 16:45:13 +0200 Subject: [PATCH 205/554] Bump to 1.2.7 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index d6ed1ac..f69fa39 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.2.6" +version: "1.2.7" readme: README.md authors: - Romain Pelisse From 14e7b402b792cb5e12ad5cb9cbd4948f4649c542 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Sat, 10 Jun 2023 18:37:58 +0200 Subject: [PATCH 206/554] fix typo in templates --- roles/keycloak/templates/standalone-ha.xml.j2 | 2 +- roles/keycloak/templates/standalone-infinispan.xml.j2 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/keycloak/templates/standalone-ha.xml.j2 b/roles/keycloak/templates/standalone-ha.xml.j2 index f3ca185..226da6e 100644 --- a/roles/keycloak/templates/standalone-ha.xml.j2 +++ b/roles/keycloak/templates/standalone-ha.xml.j2 @@ -662,7 +662,7 @@ -{% keycloak_jgroups_subnet is defined and keycloak_jgroups_subnet | length > 0 %} +{% if keycloak_jgroups_subnet is defined and keycloak_jgroups_subnet | length > 0 %} {% elif ansible_default_ipv4 is defined and (ansible_default_ipv4.network + '/' + ansible_default_ipv4.netmask) | ansible.utils.ipaddr('net') | length > 0 %} diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index 304b0fd..f7df743 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -700,7 +700,7 @@ -{% keycloak_jgroups_subnet is defined and keycloak_jgroups_subnet | length > 0 %} +{% if keycloak_jgroups_subnet is defined and keycloak_jgroups_subnet | length > 0 %} {% elif ansible_default_ipv4 is defined and (ansible_default_ipv4.network + '/' + ansible_default_ipv4.netmask) | ansible.utils.ipaddr('net') | length > 0 %} From 7ec695ee15e2df488528fda5062d79213a7d469e Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Sat, 10 Jun 2023 19:26:46 +0200 Subject: [PATCH 207/554] Fix wrong task message --- roles/keycloak/tasks/install.yml | 2 +- roles/keycloak/templates/standalone-ha.xml.j2 | 4 ++-- roles/keycloak/templates/standalone-infinispan.xml.j2 | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index b3294f4..581db9f 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -239,7 +239,7 @@ loop: "{{ ansible_play_batch }}" when: keycloak_ha_enabled and keycloak_ha_discovery == 'TCPPING' -- name: "Deploy HA {{ keycloak.service_name }} config to {{ keycloak_config_path_to_standalone_xml }} from {{ keycloak.config_template_source }}" +- name: "Deploy HA {{ keycloak.service_name }} config to {{ keycloak_config_path_to_standalone_xml }}" become: yes ansible.builtin.template: src: templates/standalone-ha.xml.j2 diff --git a/roles/keycloak/templates/standalone-ha.xml.j2 b/roles/keycloak/templates/standalone-ha.xml.j2 index 226da6e..893ec0d 100644 --- a/roles/keycloak/templates/standalone-ha.xml.j2 +++ b/roles/keycloak/templates/standalone-ha.xml.j2 @@ -662,8 +662,8 @@ -{% if keycloak_jgroups_subnet is defined and keycloak_jgroups_subnet | length > 0 %} - +{% if keycloak_jgroups_subnet is defined and keycloak_jgroups_subnet | string | length > 0 %} + {% elif ansible_default_ipv4 is defined and (ansible_default_ipv4.network + '/' + ansible_default_ipv4.netmask) | ansible.utils.ipaddr('net') | length > 0 %} {% else %} diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index f7df743..a030de0 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -700,8 +700,8 @@ -{% if keycloak_jgroups_subnet is defined and keycloak_jgroups_subnet | length > 0 %} - +{% if keycloak_jgroups_subnet is defined and keycloak_jgroups_subnet | string | length > 0 %} + {% elif ansible_default_ipv4 is defined and (ansible_default_ipv4.network + '/' + ansible_default_ipv4.netmask) | ansible.utils.ipaddr('net') | length > 0 %} {% else %} From 83525dbed0a5ee71ab74a33366dac232b8747179 Mon Sep 17 00:00:00 2001 From: footur <3769085+Footur@users.noreply.github.com> Date: Fri, 16 Jun 2023 10:15:59 +0200 Subject: [PATCH 208/554] Update the Keycloakx version in Molecule --- molecule/quarkus/prepare.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index 4b85c14..f18574b 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -30,13 +30,13 @@ - name: Create conf directory # risky-file-permissions in test user account does not exist yet ansible.builtin.file: state: directory - path: /opt/keycloak/keycloak-18.0.0/conf/ + path: /opt/keycloak/keycloak-21.1.1/conf/ mode: 0755 - name: Copy certificates ansible.builtin.copy: src: "{{ item }}" - dest: "/opt/keycloak/keycloak-18.0.0/conf/{{ item }}" + dest: "/opt/keycloak/keycloak-21.1.1/conf/{{ item }}" mode: 0444 loop: - cert.pem From fc6e00974dfcc00482b9e9e7073be336480194ce Mon Sep 17 00:00:00 2001 From: footur <3769085+Footur@users.noreply.github.com> Date: Fri, 16 Jun 2023 10:19:31 +0200 Subject: [PATCH 209/554] Define the varbosity of Ansible in Molecule --- molecule/default/molecule.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml index 6f3b9c7..81dee05 100644 --- a/molecule/default/molecule.yml +++ b/molecule/default/molecule.yml @@ -34,6 +34,7 @@ provisioner: ansible_python_interpreter: "{{ ansible_playbook_python }}" env: ANSIBLE_FORCE_COLOR: "true" + ANSIBLE_VERBOSITY: 3 verifier: name: ansible scenario: From 5f1f8b57623939b5d46e71872d85ce9075a4149e Mon Sep 17 00:00:00 2001 From: footur <3769085+Footur@users.noreply.github.com> Date: Sat, 17 Jun 2023 12:47:27 +0200 Subject: [PATCH 210/554] [CI] Use ansible-lint in v6.17.0 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3764e8f..92b530f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,7 +32,7 @@ jobs: - name: Install yamllint, ansible and molecule run: | python -m pip install --upgrade pip - pip install yamllint 'molecule[docker]~=3.5.2' ansible-core flake8 ansible-lint voluptuous + pip install yamllint 'molecule[docker]~=3.5.2' ansible-core flake8 ansible-lint==6.17.0 voluptuous pip install -r ansible_collections/middleware_automation/keycloak/requirements.txt - name: Create default collection path From 926353f395fa48a57db5c816e002e7abb5e43ef6 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 19 Jun 2023 16:41:35 +0200 Subject: [PATCH 211/554] add certified collection notice --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 608d253..7c54a51 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ [![Build Status](https://github.com/ansible-middleware/keycloak/workflows/CI/badge.svg?branch=main)](https://github.com/ansible-middleware/keycloak/actions/workflows/ci.yml) +If you are Red Hat customer, install `redhat.sso` from [Automation Hub](https://console.redhat.com/ansible/ansible-dashboard) as the certified version of this collection. + Collection to install and configure [Keycloak](https://www.keycloak.org/) or [Red Hat Single Sign-On](https://access.redhat.com/products/red-hat-single-sign-on). From cebec9c717b6fc55402d9098d53236de15f3b164 Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 19 Jun 2023 15:23:06 +0000 Subject: [PATCH 212/554] Update changelog for release 1.2.7 --- CHANGELOG.rst | 9 +++++++++ changelogs/changelog.yaml | 13 +++++++++++++ 2 files changed, 22 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 620d281..566fc60 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,15 @@ middleware_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v1.2.7 +====== + +Minor Changes +------------- + +- Allow to override jgroups subnet `#93 `_ +- keycloak-quarkus: update keycloakx to v21.1.1 `#92 `_ + v1.2.6 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 203f4f2..b6e6bd1 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -247,3 +247,16 @@ releases: - 89.yaml - 90.yaml release_date: '2023-06-07' + 1.2.7: + changes: + minor_changes: + - 'Allow to override jgroups subnet `#93 `_ + + ' + - 'keycloak-quarkus: update keycloakx to v21.1.1 `#92 `_ + + ' + fragments: + - 92.yaml + - 93.yaml + release_date: '2023-06-19' From a82e654cc4243d380832e7cec3a00f87bcff70ed Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 19 Jun 2023 17:26:15 +0200 Subject: [PATCH 213/554] Bump to 1.2.8 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index f69fa39..a2eeccb 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.2.7" +version: "1.2.8" readme: README.md authors: - Romain Pelisse From fae30797514a1533c650ab28bd103eb04829d27b Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Fri, 23 Jun 2023 11:40:15 +0200 Subject: [PATCH 214/554] Fix #97 - proper checks for keycloak_jgroups_subnet --- roles/keycloak/templates/standalone-ha.xml.j2 | 2 +- roles/keycloak/templates/standalone-infinispan.xml.j2 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/keycloak/templates/standalone-ha.xml.j2 b/roles/keycloak/templates/standalone-ha.xml.j2 index 893ec0d..98e26f6 100644 --- a/roles/keycloak/templates/standalone-ha.xml.j2 +++ b/roles/keycloak/templates/standalone-ha.xml.j2 @@ -662,7 +662,7 @@ -{% if keycloak_jgroups_subnet is defined and keycloak_jgroups_subnet | string | length > 0 %} +{% if keycloak_jgroups_subnet is defined and keycloak_jgroups_subnet is not none and keycloak_jgroups_subnet | string | length > 0 %} {% elif ansible_default_ipv4 is defined and (ansible_default_ipv4.network + '/' + ansible_default_ipv4.netmask) | ansible.utils.ipaddr('net') | length > 0 %} diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index a030de0..38fbfec 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -700,7 +700,7 @@ -{% if keycloak_jgroups_subnet is defined and keycloak_jgroups_subnet | string | length > 0 %} +{% if keycloak_jgroups_subnet is defined and keycloak_jgroups_subnet is not none and keycloak_jgroups_subnet | string | length > 0 %} {% elif ansible_default_ipv4 is defined and (ansible_default_ipv4.network + '/' + ansible_default_ipv4.netmask) | ansible.utils.ipaddr('net') | length > 0 %} From 26a9249d0787806e821d5018b740a8015f022c99 Mon Sep 17 00:00:00 2001 From: footur <3769085+Footur@users.noreply.github.com> Date: Fri, 23 Jun 2023 12:32:35 +0200 Subject: [PATCH 215/554] Update the Keycloakx version in the README --- roles/keycloak_quarkus/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index ab98d4a..7460130 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -1,7 +1,7 @@ keycloak_quarkus ================ -Install [keycloak](https://keycloak.org/) >= 17.0.0 (quarkus) server configurations. +Install [keycloak](https://keycloak.org/) >= 21.1.1 (quarkus) server configurations. Role Defaults @@ -11,7 +11,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_version`| keycloak.org package version | `17.0.1` | +|`keycloak_quarkus_version`| keycloak.org package version | `21.1.1` | * Service configuration @@ -71,7 +71,7 @@ Role Defaults |:---------|:------------|:---------| |`keycloak_quarkus_offline_install` | Perform an offline install | `False`| |`keycloak_quarkus_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| -|`keycloak_quarkus_version`| keycloak.org package version | `17.0.1` | +|`keycloak_quarkus_version`| keycloak.org package version | `21.1.1` | |`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` | |`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` | |`keycloak_quarkus_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` | From 7c4d420fead16cb1c84dddf8c74c6fb093fdfa26 Mon Sep 17 00:00:00 2001 From: footur <3769085+Footur@users.noreply.github.com> Date: Fri, 14 Jul 2023 11:36:54 +0200 Subject: [PATCH 216/554] Update Keycloak to version 22.0.0 --- molecule/quarkus/prepare.yml | 4 ++-- roles/keycloak_quarkus/README.md | 6 +++--- roles/keycloak_quarkus/defaults/main.yml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index f18574b..9fd6041 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -30,13 +30,13 @@ - name: Create conf directory # risky-file-permissions in test user account does not exist yet ansible.builtin.file: state: directory - path: /opt/keycloak/keycloak-21.1.1/conf/ + path: /opt/keycloak/keycloak-22.0.0/conf/ mode: 0755 - name: Copy certificates ansible.builtin.copy: src: "{{ item }}" - dest: "/opt/keycloak/keycloak-21.1.1/conf/{{ item }}" + dest: "/opt/keycloak/keycloak-22.0.0/conf/{{ item }}" mode: 0444 loop: - cert.pem diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 7460130..f8b8b60 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -1,7 +1,7 @@ keycloak_quarkus ================ -Install [keycloak](https://keycloak.org/) >= 21.1.1 (quarkus) server configurations. +Install [keycloak](https://keycloak.org/) >= 22.0.0 (quarkus) server configurations. Role Defaults @@ -11,7 +11,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_version`| keycloak.org package version | `21.1.1` | +|`keycloak_quarkus_version`| keycloak.org package version | `22.0.0` | * Service configuration @@ -71,7 +71,7 @@ Role Defaults |:---------|:------------|:---------| |`keycloak_quarkus_offline_install` | Perform an offline install | `False`| |`keycloak_quarkus_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| -|`keycloak_quarkus_version`| keycloak.org package version | `21.1.1` | +|`keycloak_quarkus_version`| keycloak.org package version | `22.0.0` | |`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` | |`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` | |`keycloak_quarkus_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 063863f..75125e2 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -1,6 +1,6 @@ --- ### Configuration specific to keycloak -keycloak_quarkus_version: 21.1.1 +keycloak_quarkus_version: 22.0.0 keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip" keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" From f195d164d14918114e8fbca92cff836e88870fba Mon Sep 17 00:00:00 2001 From: footur <3769085+Footur@users.noreply.github.com> Date: Fri, 14 Jul 2023 13:21:27 +0200 Subject: [PATCH 217/554] Enable Ansible verbosity in the CI test --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 92b530f..08bbd64 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,3 +56,4 @@ jobs: env: PY_COLORS: '1' ANSIBLE_FORCE_COLOR: '1' + ANSIBLE_VERBOSITY: '1' From 8738240a24c8576c42e2c413e6ad655866dfdf7c Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 28 Jul 2023 09:57:37 +0200 Subject: [PATCH 218/554] docs: add missing param in defaults comment --- roles/keycloak_realm/defaults/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/roles/keycloak_realm/defaults/main.yml b/roles/keycloak_realm/defaults/main.yml index e1caeec..17112d5 100644 --- a/roles/keycloak_realm/defaults/main.yml +++ b/roles/keycloak_realm/defaults/main.yml @@ -32,6 +32,7 @@ keycloak_admin_password: '' # realm: "{{ keycloak_realm }}" # public_client: "{{ keycloak_client_public }}" # web_origins: "{{ keycloak_client_web_origins }}" +# redirect_uris: "{{ keycloak_client_redirect_uris }}" # users: "{{ keycloak_client_users }}" keycloak_clients: [] From 7fea211639d23e9a4db49c110e5c7a62b87d6f7a Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 31 Jul 2023 08:38:36 +0200 Subject: [PATCH 219/554] ci: update molecule --- .github/workflows/ci.yml | 22 +++++++++++++++++++--- README.md | 2 +- molecule/default/molecule.yml | 9 --------- molecule/overridexml/molecule.yml | 9 --------- molecule/quarkus/molecule.yml | 9 --------- 5 files changed, 20 insertions(+), 31 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 92b530f..fa060f7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,6 +5,8 @@ on: branches: - main pull_request: + schedule: + - cron: '0 6 * * *' env: COLORTERM: 'yes' @@ -16,7 +18,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python_version: ["3.10"] + python_version: ["3.11"] steps: - name: Check out code uses: actions/checkout@v2 @@ -32,8 +34,16 @@ jobs: - name: Install yamllint, ansible and molecule run: | python -m pip install --upgrade pip - pip install yamllint 'molecule[docker]~=3.5.2' ansible-core flake8 ansible-lint==6.17.0 voluptuous - pip install -r ansible_collections/middleware_automation/keycloak/requirements.txt + pip install yamllint 'molecule>=4.0.4' 'molecule-plugins[docker]>=23.0.0' ansible-core flake8 ansible-lint voluptuous + if [ -f ansible_collections/middleware_automation/keycloak/requirements.txt ]; then + pip install -r ansible_collections/middleware_automation/keycloak/requirements.txt + fi + if [ -f ansible_collections/middleware_automation/keycloak/requirements.yml ]; then + ansible-galaxy collection install -r ansible_collections/middleware_automation/keycloak/requirements.yml -p /home/runner/.ansible/collections --force-with-deps + fi + if [ -f ansible_collections/middleware_automation/keycloak/molecule/requirements.yml ]; then + ansible-galaxy collection install -r ansible_collections/middleware_automation/keycloak/molecule/requirements.yml -p /home/runner/.ansible/collections + fi - name: Create default collection path run: | @@ -46,6 +56,12 @@ jobs: repository: ansible-middleware/ansible-lint-custom-rules path: ansible_collections/ansible-lint-custom-rules/ + - name: Run linter + run: | + ansible-lint --version + ansible-lint -v + working-directory: ./ansible_collections/middleware_automation/amq + - name: Run sanity tests run: ansible-test sanity -v --color --python ${{ matrix.python_version }} --exclude changelogs/fragments/.gitignore --skip-test symlinks working-directory: ./ansible_collections/middleware_automation/keycloak diff --git a/README.md b/README.md index 7c54a51..9ae661e 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Build Status](https://github.com/ansible-middleware/keycloak/workflows/CI/badge.svg?branch=main)](https://github.com/ansible-middleware/keycloak/actions/workflows/ci.yml) -If you are Red Hat customer, install `redhat.sso` from [Automation Hub](https://console.redhat.com/ansible/ansible-dashboard) as the certified version of this collection. +> **_NOTE:_ If you are Red Hat customer, install `redhat.sso` from [Automation Hub](https://console.redhat.com/ansible/ansible-dashboard) as the certified version of this collection.** Collection to install and configure [Keycloak](https://www.keycloak.org/) or [Red Hat Single Sign-On](https://access.redhat.com/products/red-hat-single-sign-on). diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml index 81dee05..abdc729 100644 --- a/molecule/default/molecule.yml +++ b/molecule/default/molecule.yml @@ -1,12 +1,6 @@ --- -dependency: - name: shell - command: ansible-galaxy collection install -r molecule/requirements.yml -p $HOME/.ansible/collections --force-with-deps driver: name: docker -lint: | - ansible-lint --version - ansible-lint -v platforms: - name: instance image: registry.access.redhat.com/ubi8/ubi-init:latest @@ -39,11 +33,8 @@ verifier: name: ansible scenario: test_sequence: - - dependency - - lint - cleanup - destroy - - syntax - create - prepare - converge diff --git a/molecule/overridexml/molecule.yml b/molecule/overridexml/molecule.yml index 6f3b9c7..c133eee 100644 --- a/molecule/overridexml/molecule.yml +++ b/molecule/overridexml/molecule.yml @@ -1,12 +1,6 @@ --- -dependency: - name: shell - command: ansible-galaxy collection install -r molecule/requirements.yml -p $HOME/.ansible/collections --force-with-deps driver: name: docker -lint: | - ansible-lint --version - ansible-lint -v platforms: - name: instance image: registry.access.redhat.com/ubi8/ubi-init:latest @@ -38,11 +32,8 @@ verifier: name: ansible scenario: test_sequence: - - dependency - - lint - cleanup - destroy - - syntax - create - prepare - converge diff --git a/molecule/quarkus/molecule.yml b/molecule/quarkus/molecule.yml index 3895a53..c04e300 100644 --- a/molecule/quarkus/molecule.yml +++ b/molecule/quarkus/molecule.yml @@ -1,12 +1,6 @@ --- -dependency: - name: shell - command: ansible-galaxy collection install -r molecule/requirements.yml -p $HOME/.ansible/collections --force-with-deps driver: name: docker -lint: | - ansible-lint --version - ansible-lint -v platforms: - name: instance image: registry.access.redhat.com/ubi8/ubi-init:latest @@ -40,11 +34,8 @@ verifier: name: ansible scenario: test_sequence: - - dependency - - lint - cleanup - destroy - - syntax - create - prepare - converge From 5385fbb8e9888af635fe8d8230739237a7477f00 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 31 Jul 2023 08:40:17 +0200 Subject: [PATCH 220/554] ci: update molecule --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fa060f7..05bee8c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -60,7 +60,7 @@ jobs: run: | ansible-lint --version ansible-lint -v - working-directory: ./ansible_collections/middleware_automation/amq + working-directory: ./ansible_collections/middleware_automation/keycloak - name: Run sanity tests run: ansible-test sanity -v --color --python ${{ matrix.python_version }} --exclude changelogs/fragments/.gitignore --skip-test symlinks From f400a5bbf80bad197ad9fafb5900e96b65e05b6f Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 31 Jul 2023 09:01:54 +0200 Subject: [PATCH 221/554] fix_java_11_tzdata --- roles/keycloak/tasks/prereqs.yml | 3 ++- roles/keycloak_quarkus/tasks/prereqs.yml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/roles/keycloak/tasks/prereqs.yml b/roles/keycloak/tasks/prereqs.yml index 418a574..02370c7 100644 --- a/roles/keycloak/tasks/prereqs.yml +++ b/roles/keycloak/tasks/prereqs.yml @@ -43,4 +43,5 @@ - "{{ keycloak_jvm_package }}" - unzip - procps-ng - - initscripts \ No newline at end of file + - initscripts + - tzdata-java diff --git a/roles/keycloak_quarkus/tasks/prereqs.yml b/roles/keycloak_quarkus/tasks/prereqs.yml index c0201b3..4040d8f 100644 --- a/roles/keycloak_quarkus/tasks/prereqs.yml +++ b/roles/keycloak_quarkus/tasks/prereqs.yml @@ -22,4 +22,5 @@ - "{{ keycloak_quarkus_jvm_package }}" - unzip - procps-ng - - initscripts \ No newline at end of file + - initscripts + - tzdata-java From 79335927252e56ac57db2fcd57efa19d6b2f7adb Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 31 Jul 2023 09:19:47 +0200 Subject: [PATCH 222/554] Revert README.md --- roles/keycloak_quarkus/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index f8b8b60..cd5383f 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -1,7 +1,7 @@ keycloak_quarkus ================ -Install [keycloak](https://keycloak.org/) >= 22.0.0 (quarkus) server configurations. +Install [keycloak](https://keycloak.org/) >= 20.0.0 (quarkus) server configurations. Role Defaults From 84d6e7baca786bab4930767cc50f9de53297ef54 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 31 Jul 2023 10:29:28 +0200 Subject: [PATCH 223/554] set java-17 for keycloak_quarkus --- .github/workflows/ci.yml | 6 +++++- roles/keycloak/tasks/systemd.yml | 13 ++++--------- roles/keycloak_quarkus/defaults/main.yml | 2 +- roles/keycloak_quarkus/tasks/systemd.yml | 13 ++++--------- 4 files changed, 14 insertions(+), 20 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c4c1b87..c22fd4c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,6 +19,10 @@ jobs: strategy: matrix: python_version: ["3.11"] + molecule_test: + - default + - quarkus + - overridexml steps: - name: Check out code uses: actions/checkout@v2 @@ -67,7 +71,7 @@ jobs: working-directory: ./ansible_collections/middleware_automation/keycloak - name: Run molecule test - run: molecule test --all + run: molecule test -s ${{ matrix.molecule_test }} working-directory: ./ansible_collections/middleware_automation/keycloak env: PY_COLORS: '1' diff --git a/roles/keycloak/tasks/systemd.yml b/roles/keycloak/tasks/systemd.yml index 871180f..4b24822 100644 --- a/roles/keycloak/tasks/systemd.yml +++ b/roles/keycloak/tasks/systemd.yml @@ -10,14 +10,9 @@ notify: - restart keycloak -- name: Determine JAVA_HOME for selected JVM RPM # noqa blocked_modules - ansible.builtin.shell: | - set -o pipefail - rpm -ql {{ keycloak_jvm_package }} | grep -Po '/usr/lib/jvm/.*(?=/bin/java$)' - args: - executable: /bin/bash - changed_when: False - register: rpm_java_home +- name: Determine JAVA_HOME for selected JVM RPM + ansible.builtin.set_fact: + rpm_java_home: "/etc/alternatives/jre_{{ keycloak_jvm_package | regex_search('(?<=java-)[0-9.]+') }}" - name: "Configure sysconfig file for {{ keycloak.service_name }} service" become: yes @@ -28,7 +23,7 @@ group: root mode: 0644 vars: - keycloak_rpm_java_home: "{{ rpm_java_home.stdout }}" + keycloak_rpm_java_home: "{{ rpm_java_home }}" notify: - restart keycloak diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 75125e2..53a9c76 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -9,7 +9,7 @@ keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_q keycloak_quarkus_offline_install: False ### Install location and service settings -keycloak_quarkus_jvm_package: java-11-openjdk-headless +keycloak_quarkus_jvm_package: java-17-openjdk-headless keycloak_quarkus_java_home: keycloak_quarkus_dest: /opt/keycloak keycloak_quarkus_home: "{{ keycloak_quarkus_installdir }}" diff --git a/roles/keycloak_quarkus/tasks/systemd.yml b/roles/keycloak_quarkus/tasks/systemd.yml index ee8a1cc..c0be72b 100644 --- a/roles/keycloak_quarkus/tasks/systemd.yml +++ b/roles/keycloak_quarkus/tasks/systemd.yml @@ -1,12 +1,7 @@ --- -- name: Determine JAVA_HOME for selected JVM RPM # noqa blocked_modules - ansible.builtin.shell: | - set -o pipefail - rpm -ql {{ keycloak_quarkus_jvm_package }} | grep -Po '/usr/lib/jvm/.*(?=/bin/java$)' - args: - executable: /bin/bash - changed_when: False - register: rpm_java_home +- name: Determine JAVA_HOME for selected JVM RPM + ansible.builtin.set_fact: + rpm_java_home: "/etc/alternatives/jre_{{ keycloak_quarkus_jvm_package | regex_search('(?<=java-)[0-9.]+') }}" - name: "Configure sysconfig file for keycloak service" become: yes @@ -17,7 +12,7 @@ group: root mode: 0644 vars: - keycloak_rpm_java_home: "{{ rpm_java_home.stdout }}" + keycloak_rpm_java_home: "{{ rpm_java_home }}" notify: - restart keycloak From 5b0112384676ad5999a26c4efca068956f12a844 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 31 Jul 2023 10:39:47 +0200 Subject: [PATCH 224/554] fix verify for molecule default scenario --- molecule/default/verify.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml index 490b38c..92a245e 100644 --- a/molecule/default/verify.yml +++ b/molecule/default/verify.yml @@ -17,7 +17,7 @@ - name: Verify we are running on requested jvm # noqa blocked_modules command-instead-of-module ansible.builtin.shell: | set -o pipefail - ps -ef | grep /usr/lib/jvm/java-11 | grep -v grep + ps -ef | grep '/etc/alternatives/jre_11/' | grep -v grep args: executable: /bin/bash changed_when: no From db0aafd465ed7b98d2f4d6c86cf8d78dffbee1b4 Mon Sep 17 00:00:00 2001 From: Joel <34544090+JoelKle@users.noreply.github.com> Date: Tue, 8 Aug 2023 11:05:25 +0200 Subject: [PATCH 225/554] Update bindep.txt to support RHEL9 On RHEL9 the rpm package `python39-devel` doesn't exists. The real name is `python3-devel`. --- bindep.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bindep.txt b/bindep.txt index 641ec85..840876b 100644 --- a/bindep.txt +++ b/bindep.txt @@ -1,4 +1,5 @@ -python39-devel [platform:rpm compile] +python3-devel [compile platform:rpm] +python39-devel [compile platform:centos-8 platform:rhel-8] git-lfs [platform:rpm] python3-netaddr [platform:rpm] python3-lxml [platform:rpm] From 07b1c514bb4432e8dd0ba607c0c1f86f5634df90 Mon Sep 17 00:00:00 2001 From: Massimo Schiavon Date: Tue, 8 Aug 2023 16:52:23 +0200 Subject: [PATCH 226/554] Add User and Group directives in systemd unit file --- roles/keycloak/templates/keycloak.service.j2 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/roles/keycloak/templates/keycloak.service.j2 b/roles/keycloak/templates/keycloak.service.j2 index 5de014b..8a94c62 100644 --- a/roles/keycloak/templates/keycloak.service.j2 +++ b/roles/keycloak/templates/keycloak.service.j2 @@ -8,6 +8,8 @@ StartLimitBurst={{ keycloak_service_startlimitburst }} [Service] Type=forking +User={{ keycloak_service_user }} +Group={{ keycloak_service_group }} EnvironmentFile=-/etc/sysconfig/keycloak PIDFile={{ keycloak_service_pidfile }} ExecStart={{ keycloak_dest }}/keycloak-service.sh start From 91ec4116993fc6042d8756970184df7c17e20ccd Mon Sep 17 00:00:00 2001 From: Massimo Schiavon Date: Tue, 8 Aug 2023 17:49:43 +0200 Subject: [PATCH 227/554] create pidfile folder if needed --- roles/keycloak/tasks/install.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index 581db9f..13f4ef3 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -53,6 +53,21 @@ group: "{{ keycloak_service_group }}" mode: 0750 +- name: Check pidfile folder + ansible.builtin.stat: + path: "{{ keycloak_service_pidfile | dirname }}" + register: keycloak_service_pidfile_stat +- name: Create pidfile folder + become: yes + become_user: root + ansible.builtin.file: + dest: "{{ keycloak_service_pidfile | dirname }}" + state: directory + owner: "{{ keycloak_service_user }}" + group: "{{ keycloak_service_group }}" + mode: "0750" + when: not keycloak_service_pidfile_stat.stat.exists + ## check remote archive - name: Set download archive path ansible.builtin.set_fact: From c8ebbe72d2c07dede02c981d3d4497834ce9a95d Mon Sep 17 00:00:00 2001 From: Massimo Schiavon Date: Tue, 8 Aug 2023 18:30:46 +0200 Subject: [PATCH 228/554] change default pidfile location Signed-off-by: Massimo Schiavon --- roles/keycloak/README.md | 2 +- roles/keycloak/defaults/main.yml | 2 +- roles/keycloak/meta/argument_specs.yml | 2 +- roles/keycloak_quarkus/defaults/main.yml | 2 +- roles/keycloak_quarkus/meta/argument_specs.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index f25420f..aae309b 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -77,7 +77,7 @@ Role Defaults |`keycloak_service_startlimitintervalsec`| systemd StartLimitIntervalSec | `300` | |`keycloak_service_startlimitburst`| systemd StartLimitBurst | `5` | |`keycloak_service_restartsec`| systemd RestartSec | `10s` | -|`keycloak_service_pidfile`| pid file path for service | `/run/keycloak.pid` | +|`keycloak_service_pidfile`| pid file path for service | `/run/keycloak/keycloak.pid` | |`keycloak_features` | List of `name`/`status` pairs of features (also known as profiles on RH-SSO) to `enable` or `disable`, example: `[ { name: 'docker', status: 'enabled' } ]` | `[]` |`keycloak_jvm_package`| RHEL java package runtime | `java-1.8.0-openjdk-headless` | |`keycloak_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_jvm_package RPM path | `None` | diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index a139d92..156af46 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -19,7 +19,7 @@ keycloak_config_override_template: '' keycloak_config_path_to_properties: "{{ keycloak_jboss_home }}/standalone/configuration/profile.properties" keycloak_service_user: keycloak keycloak_service_group: keycloak -keycloak_service_pidfile: "/run/keycloak.pid" +keycloak_service_pidfile: "/run/keycloak/keycloak.pid" keycloak_service_name: keycloak keycloak_service_desc: Keycloak keycloak_service_start_delay: 10 diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 5392cfc..daba3ba 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -86,7 +86,7 @@ argument_specs: type: "str" keycloak_service_pidfile: # line 31 of keycloak/defaults/main.yml - default: "/run/keycloak.pid" + default: "/run/keycloak/keycloak.pid" description: "PID file path for service" type: "str" keycloak_features: diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 53a9c76..0989868 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -17,7 +17,7 @@ keycloak_quarkus_config_dir: "{{ keycloak_quarkus_home }}/conf" keycloak_quarkus_start_dev: False keycloak_quarkus_service_user: keycloak keycloak_quarkus_service_group: keycloak -keycloak_quarkus_service_pidfile: "/run/keycloak.pid" +keycloak_quarkus_service_pidfile: "/run/keycloak/keycloak.pid" keycloak_quarkus_configure_firewalld: False ### administrator console password diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 66e8adf..2986c0c 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -61,7 +61,7 @@ argument_specs: type: "str" keycloak_quarkus_service_pidfile: # line 18 of defaults/main.yml - default: "/run/keycloak.pid" + default: "/run/keycloak/keycloak.pid" description: "Pid file path for service" type: "str" keycloak_quarkus_configure_firewalld: From 52d9286ea331cde943703c80eae870a4b0120a71 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 24 Aug 2023 13:20:49 +0200 Subject: [PATCH 229/554] ci: update workflows --- .github/workflows/ci.yml | 110 +++++++++++++++++++++++++++++-------- .github/workflows/docs.yml | 4 +- docs/conf.py | 3 +- docs/requirements.txt | 1 + 4 files changed, 92 insertions(+), 26 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c22fd4c..9a5105d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,18 +14,103 @@ env: PYTEST_ADDOPTS: '--color=yes' jobs: - ci: + linter: runs-on: ubuntu-latest strategy: matrix: python_version: ["3.11"] + ansible_version: ["2.15"] + steps: + - name: Check out code + uses: actions/checkout@v3 + with: + path: ansible_collections/middleware_automation/keycloak + + - name: Set up Python ${{ matrix.python_version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python_version }} + cache: 'pip' + + - name: Create default collection path + run: | + mkdir -p /home/runner/.ansible/ + ln -s ${{ github.workspace }} /home/runner/.ansible/collections + + - name: Install yamllint, ansible and dependencies + run: | + python -m pip install --upgrade pip + pip install yamllint ansible-core==${{ matrix.ansible_version }} ansible-lint + if [ -f ansible_collections/middleware_automation/keycloak/requirements.txt ]; then + pip install -r ansible_collections/middleware_automation/keycloak/requirements.txt + fi + if [ -f ansible_collections/middleware_automation/keycloak/requirements.yml ]; then + ansible-galaxy collection install -r ansible_collections/middleware_automation/keycloak/requirements.yml -p /home/runner/.ansible/collections --force-with-deps + fi + + - name: Install ansible-lint custom rules + uses: actions/checkout@v3 + with: + repository: ansible-middleware/ansible-lint-custom-rules + path: ansible-lint-custom-rules/ + + - name: Run linter + run: | + ansible-lint --version + ansible-lint -v + working-directory: ./ansible_collections/middleware_automation/keycloak + + sanity: + runs-on: ubuntu-latest + strategy: + matrix: + python_version: ["3.8", "3.9", "3.11"] + ansible_version: ["2.11", "2.15"] + exclude: + - python_version: "3.8" + ansible_version: "2.15" + - python_version: "3.9" + ansible_version: "2.15" + - python_version: "3.11" + ansible_version: "2.11" + steps: + - name: Check out code + uses: actions/checkout@v3 + with: + path: ansible_collections/middleware_automation/keycloak + + - name: Set up Python ${{ matrix.python_version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python_version }} + cache: 'pip' + + - name: Create default collection path + run: | + mkdir -p /home/runner/.ansible/ + ln -s ${{ github.workspace }} /home/runner/.ansible/collections + + - name: Install ansible-core stable-${{ matrix.ansible_version }} + run: | + pip install https://github.com/ansible/ansible/archive/stable-${{ matrix.ansible_version }}.tar.gz --disable-pip-version-check + + - name: Run sanity tests + run: ansible-test sanity -v --color --docker --python ${{ matrix.python_version }} --exclude docs/conf.py --exclude changelogs/fragments/.gitignore --skip-test symlinks + working-directory: ./ansible_collections/middleware_automation/keycloak + + molecule: + runs-on: ubuntu-latest + strategy: + matrix: + python_version: ["3.11"] + ansible_version: ["2.14", "2.15"] molecule_test: - default - quarkus - overridexml steps: - name: Check out code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: path: ansible_collections/middleware_automation/keycloak @@ -49,27 +134,6 @@ jobs: ansible-galaxy collection install -r ansible_collections/middleware_automation/keycloak/molecule/requirements.yml -p /home/runner/.ansible/collections fi - - name: Create default collection path - run: | - mkdir -p /home/runner/.ansible/ - ln -s /home/runner/work/keycloak/keycloak /home/runner/.ansible/collections - - - name: Install ansible-lint custom rules - uses: actions/checkout@v2 - with: - repository: ansible-middleware/ansible-lint-custom-rules - path: ansible_collections/ansible-lint-custom-rules/ - - - name: Run linter - run: | - ansible-lint --version - ansible-lint -v - working-directory: ./ansible_collections/middleware_automation/keycloak - - - name: Run sanity tests - run: ansible-test sanity -v --color --python ${{ matrix.python_version }} --exclude changelogs/fragments/.gitignore --skip-test symlinks - working-directory: ./ansible_collections/middleware_automation/keycloak - - name: Run molecule test run: molecule test -s ${{ matrix.molecule_test }} working-directory: ./ansible_collections/middleware_automation/keycloak diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 071821d..20cbc1e 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -26,7 +26,7 @@ jobs: pages: write steps: - name: Check out code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: path: ansible_collections/middleware_automation/keycloak fetch-depth: 0 @@ -34,7 +34,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v4 with: - python-version: 3.9 + python-version: 3.11 cache: 'pip' - name: Install doc dependencies diff --git a/docs/conf.py b/docs/conf.py index 31502f3..c1b24a9 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -43,6 +43,7 @@ extensions = [ 'myst_parser', 'sphinx.ext.autodoc', 'sphinx.ext.intersphinx', + 'sphinx_antsibull_ext', 'ansible_basic_sphinx_ext', ] @@ -71,7 +72,7 @@ language = None exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', '.tmp'] # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = 'ansible' highlight_language = 'YAML+Jinja' diff --git a/docs/requirements.txt b/docs/requirements.txt index c43be53..c8f8e2d 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -2,6 +2,7 @@ antsibull>=0.17.0 antsibull-docs antsibull-changelog ansible-core>=2.14.1 +ansible-pygments sphinx-rtd-theme git+https://github.com/felixfontein/ansible-basic-sphinx-ext myst-parser From ca2dbe78c235504d2de9571ab0dac0fcce331ecb Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 24 Aug 2023 13:46:50 +0200 Subject: [PATCH 230/554] ci: update workflows --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9a5105d..b9917b6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -123,7 +123,7 @@ jobs: - name: Install yamllint, ansible and molecule run: | python -m pip install --upgrade pip - pip install yamllint 'molecule>=4.0.4' 'molecule-plugins[docker]>=23.0.0' ansible-core flake8 ansible-lint voluptuous + pip install 'molecule>=5.0.1' 'molecule-plugins[docker]>=23.0.0' ansible-coreansible-core==${{ matrix.ansible_version }} if [ -f ansible_collections/middleware_automation/keycloak/requirements.txt ]; then pip install -r ansible_collections/middleware_automation/keycloak/requirements.txt fi From 0783000849149d98fa491f66b3e84d2656bfe53d Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 24 Aug 2023 13:53:22 +0200 Subject: [PATCH 231/554] ci: update workflows --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b9917b6..6534841 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -123,7 +123,7 @@ jobs: - name: Install yamllint, ansible and molecule run: | python -m pip install --upgrade pip - pip install 'molecule>=5.0.1' 'molecule-plugins[docker]>=23.0.0' ansible-coreansible-core==${{ matrix.ansible_version }} + pip install 'molecule>=5.0.1' 'molecule-plugins[docker]>=23.0.0' ansible-core==${{ matrix.ansible_version }} if [ -f ansible_collections/middleware_automation/keycloak/requirements.txt ]; then pip install -r ansible_collections/middleware_automation/keycloak/requirements.txt fi From 52518264770ccbb2564564c1182a5ed742e7a8d6 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 24 Aug 2023 13:57:38 +0200 Subject: [PATCH 232/554] ci: update workflows --- .github/workflows/ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6534841..cb1efcd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -135,7 +135,9 @@ jobs: fi - name: Run molecule test - run: molecule test -s ${{ matrix.molecule_test }} + run: | + molecule --version + molecule test -s ${{ matrix.molecule_test }} working-directory: ./ansible_collections/middleware_automation/keycloak env: PY_COLORS: '1' From 7c05ee5239c044603c0354bdbe235fb594925bd2 Mon Sep 17 00:00:00 2001 From: footur <3769085+Footur@users.noreply.github.com> Date: Fri, 25 Aug 2023 11:38:45 +0200 Subject: [PATCH 233/554] Update Keycloak to version 22.0.1 --- molecule/quarkus/prepare.yml | 4 ++-- roles/keycloak_quarkus/README.md | 4 ++-- roles/keycloak_quarkus/defaults/main.yml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index 9fd6041..3e3d923 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -30,13 +30,13 @@ - name: Create conf directory # risky-file-permissions in test user account does not exist yet ansible.builtin.file: state: directory - path: /opt/keycloak/keycloak-22.0.0/conf/ + path: /opt/keycloak/keycloak-22.0.1/conf/ mode: 0755 - name: Copy certificates ansible.builtin.copy: src: "{{ item }}" - dest: "/opt/keycloak/keycloak-22.0.0/conf/{{ item }}" + dest: "/opt/keycloak/keycloak-22.0.1/conf/{{ item }}" mode: 0444 loop: - cert.pem diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index cd5383f..cda65aa 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -11,7 +11,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_version`| keycloak.org package version | `22.0.0` | +|`keycloak_quarkus_version`| keycloak.org package version | `22.0.1` | * Service configuration @@ -71,7 +71,7 @@ Role Defaults |:---------|:------------|:---------| |`keycloak_quarkus_offline_install` | Perform an offline install | `False`| |`keycloak_quarkus_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| -|`keycloak_quarkus_version`| keycloak.org package version | `22.0.0` | +|`keycloak_quarkus_version`| keycloak.org package version | `22.0.1` | |`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` | |`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` | |`keycloak_quarkus_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 53a9c76..bab1885 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -1,6 +1,6 @@ --- ### Configuration specific to keycloak -keycloak_quarkus_version: 22.0.0 +keycloak_quarkus_version: 22.0.1 keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip" keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" From 11621516e36be6bb9aff88e3cd79c60858e0f90d Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 25 Aug 2023 11:40:27 +0200 Subject: [PATCH 234/554] update workflows --- .github/workflows/ci.yml | 141 ++----------------------------------- .github/workflows/docs.yml | 57 ++------------- 2 files changed, 12 insertions(+), 186 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cb1efcd..a771a4d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,138 +8,11 @@ on: schedule: - cron: '0 6 * * *' -env: - COLORTERM: 'yes' - TERM: 'xterm-256color' - PYTEST_ADDOPTS: '--color=yes' - jobs: - linter: - runs-on: ubuntu-latest - strategy: - matrix: - python_version: ["3.11"] - ansible_version: ["2.15"] - steps: - - name: Check out code - uses: actions/checkout@v3 - with: - path: ansible_collections/middleware_automation/keycloak - - - name: Set up Python ${{ matrix.python_version }} - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python_version }} - cache: 'pip' - - - name: Create default collection path - run: | - mkdir -p /home/runner/.ansible/ - ln -s ${{ github.workspace }} /home/runner/.ansible/collections - - - name: Install yamllint, ansible and dependencies - run: | - python -m pip install --upgrade pip - pip install yamllint ansible-core==${{ matrix.ansible_version }} ansible-lint - if [ -f ansible_collections/middleware_automation/keycloak/requirements.txt ]; then - pip install -r ansible_collections/middleware_automation/keycloak/requirements.txt - fi - if [ -f ansible_collections/middleware_automation/keycloak/requirements.yml ]; then - ansible-galaxy collection install -r ansible_collections/middleware_automation/keycloak/requirements.yml -p /home/runner/.ansible/collections --force-with-deps - fi - - - name: Install ansible-lint custom rules - uses: actions/checkout@v3 - with: - repository: ansible-middleware/ansible-lint-custom-rules - path: ansible-lint-custom-rules/ - - - name: Run linter - run: | - ansible-lint --version - ansible-lint -v - working-directory: ./ansible_collections/middleware_automation/keycloak - - sanity: - runs-on: ubuntu-latest - strategy: - matrix: - python_version: ["3.8", "3.9", "3.11"] - ansible_version: ["2.11", "2.15"] - exclude: - - python_version: "3.8" - ansible_version: "2.15" - - python_version: "3.9" - ansible_version: "2.15" - - python_version: "3.11" - ansible_version: "2.11" - steps: - - name: Check out code - uses: actions/checkout@v3 - with: - path: ansible_collections/middleware_automation/keycloak - - - name: Set up Python ${{ matrix.python_version }} - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python_version }} - cache: 'pip' - - - name: Create default collection path - run: | - mkdir -p /home/runner/.ansible/ - ln -s ${{ github.workspace }} /home/runner/.ansible/collections - - - name: Install ansible-core stable-${{ matrix.ansible_version }} - run: | - pip install https://github.com/ansible/ansible/archive/stable-${{ matrix.ansible_version }}.tar.gz --disable-pip-version-check - - - name: Run sanity tests - run: ansible-test sanity -v --color --docker --python ${{ matrix.python_version }} --exclude docs/conf.py --exclude changelogs/fragments/.gitignore --skip-test symlinks - working-directory: ./ansible_collections/middleware_automation/keycloak - - molecule: - runs-on: ubuntu-latest - strategy: - matrix: - python_version: ["3.11"] - ansible_version: ["2.14", "2.15"] - molecule_test: - - default - - quarkus - - overridexml - steps: - - name: Check out code - uses: actions/checkout@v3 - with: - path: ansible_collections/middleware_automation/keycloak - - - name: Set up Python ${{ matrix.python_version }} - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python_version }} - cache: 'pip' - - - name: Install yamllint, ansible and molecule - run: | - python -m pip install --upgrade pip - pip install 'molecule>=5.0.1' 'molecule-plugins[docker]>=23.0.0' ansible-core==${{ matrix.ansible_version }} - if [ -f ansible_collections/middleware_automation/keycloak/requirements.txt ]; then - pip install -r ansible_collections/middleware_automation/keycloak/requirements.txt - fi - if [ -f ansible_collections/middleware_automation/keycloak/requirements.yml ]; then - ansible-galaxy collection install -r ansible_collections/middleware_automation/keycloak/requirements.yml -p /home/runner/.ansible/collections --force-with-deps - fi - if [ -f ansible_collections/middleware_automation/keycloak/molecule/requirements.yml ]; then - ansible-galaxy collection install -r ansible_collections/middleware_automation/keycloak/molecule/requirements.yml -p /home/runner/.ansible/collections - fi - - - name: Run molecule test - run: | - molecule --version - molecule test -s ${{ matrix.molecule_test }} - working-directory: ./ansible_collections/middleware_automation/keycloak - env: - PY_COLORS: '1' - ANSIBLE_FORCE_COLOR: '1' - ANSIBLE_VERBOSITY: '1' + ci: + uses: ansible-middleware/github-actions/.github/workflows/ci.yml@main + secrets: inherit + with: + fqcn: 'middleware_automation/keycloak' + molecule_tests: >- + [ "default", "quarkus", "overridexml" ] diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 20cbc1e..c1a95bf 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -8,57 +8,10 @@ on: - "[0-9]+.[0-9]+.[0-9]+" workflow_dispatch: -env: - COLORTERM: 'yes' - TERM: 'xterm-256color' - PYTEST_ADDOPTS: '--color=yes' - jobs: docs: - runs-on: ubuntu-latest - if: github.repository == 'ansible-middleware/keycloak' - permissions: - actions: write - checks: write - contents: write - deployments: write - packages: write - pages: write - steps: - - name: Check out code - uses: actions/checkout@v3 - with: - path: ansible_collections/middleware_automation/keycloak - fetch-depth: 0 - - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: 3.11 - cache: 'pip' - - - name: Install doc dependencies - run: | - python -m pip install --upgrade pip - pip install -r ansible_collections/middleware_automation/keycloak/docs/requirements.txt - pip install -r ansible_collections/middleware_automation/keycloak/requirements.txt - sudo apt --fix-missing update - sudo apt install -y sed hub - - - name: Create default collection path - run: | - mkdir -p /home/runner/.ansible/ - ln -s /home/runner/work/keycloak/keycloak /home/runner/.ansible/collections - - - name: Create changelog and documentation - uses: ansible-middleware/collection-docs-action@main - with: - collection_fqcn: middleware_automation.keycloak - collection_repo: ansible-middleware/keycloak - dependencies: false - commit_changelog: false - commit_ghpages: true - changelog_release: false - generate_docs: true - path: ansible_collections/middleware_automation/keycloak - token: ${{ secrets.GITHUB_TOKEN }} + uses: ansible-middleware/github-actions/.github/workflows/docs.yml@main + secrets: inherit + with: + fqcn: 'middleware_automation/keycloak' + collection_fqcn: 'middleware_automation.keycloak' From 6e6bf2ff716d670a2aeba78e5ba75cdb85a7a30d Mon Sep 17 00:00:00 2001 From: footur <3769085+Footur@users.noreply.github.com> Date: Sun, 27 Aug 2023 21:57:25 +0200 Subject: [PATCH 235/554] Fix JRE version in README --- roles/keycloak_quarkus/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index cda65aa..b528944 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -30,7 +30,7 @@ Role Defaults |`keycloak_quarkus_service_user`| Posix account username | `keycloak` | |`keycloak_quarkus_service_group`| Posix account group | `keycloak` | |`keycloak_quarkus_service_pidfile`| Pid file path for service | `/run/keycloak.pid` | -|`keycloak_quarkus_jvm_package`| RHEL java package runtime | `java-11-openjdk-headless` | +|`keycloak_quarkus_jvm_package`| RHEL java package runtime | `java-17-openjdk-headless` | |`keycloak_quarkus_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_quarkus_jvm_package RPM path | `None` | |`keycloak_quarkus_java_opts`| Additional JVM options | `-Xms1024m -Xmx2048m` | |`keycloak_quarkus_frontend_url`| Service public URL | `http://localhost:8080/auth` | From 5c8d7d9554c9933f2a994597529e899d8d6f5e5e Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 28 Aug 2023 17:45:40 +0200 Subject: [PATCH 236/554] ci: update release workflow --- .github/workflows/release.yml | 87 ++--------------------------------- 1 file changed, 4 insertions(+), 83 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ff64240..5e14f9c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,89 +5,10 @@ on: jobs: release: - runs-on: ubuntu-latest - if: github.repository == 'ansible-middleware/keycloak' - permissions: - actions: write - checks: write - contents: write - deployments: write - packages: write - pages: write - outputs: - tag_version: ${{ steps.get_version.outputs.TAG_VERSION }} - steps: - - name: Checkout code - uses: actions/checkout@v3 - with: - fetch-depth: 0 - token: ${{ secrets.TRIGGERING_PAT }} - - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: "3.x" - cache: 'pip' - - - name: Get current version - id: get_version - run: echo "::set-output name=TAG_VERSION::$(grep version galaxy.yml | awk -F'"' '{ print $2 }')" - - - name: Check if tag exists - id: check_tag - run: echo "::set-output name=TAG_EXISTS::$(git tag | grep ${{ steps.get_version.outputs.TAG_VERSION }})" - - - name: Fail if tag exists - if: ${{ steps.get_version.outputs.TAG_VERSION == steps.check_tag.outputs.TAG_EXISTS }} - uses: actions/github-script@v3 - with: - script: | - core.setFailed('Release tag already exists') - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install ansible-core antsibull - sudo apt --fix-missing update - sudo apt install -y sed hub - - - name: Build collection - run: | - ansible-galaxy collection build . - - - name: Create changelog and documentation - uses: ansible-middleware/collection-docs-action@main - with: - collection_fqcn: middleware_automation.keycloak - collection_repo: ansible-middleware/keycloak - dependencies: false - commit_changelog: true - commit_ghpages: false - changelog_release: true - generate_docs: false - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Publish collection - env: - ANSIBLE_GALAXY_API_KEY: ${{ secrets.ANSIBLE_GALAXY_API_KEY }} - run: | - ansible-galaxy collection publish *.tar.gz --api-key $ANSIBLE_GALAXY_API_KEY - - - name: Create release tag - run: | - git config user.name github-actions - git config user.email github-actions@github.com - git tag -a ${{ steps.get_version.outputs.TAG_VERSION }} -m "Release v${{ steps.get_version.outputs.TAG_VERSION }}" || true - git push origin --tags - - - name: Publish Release - uses: softprops/action-gh-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ steps.get_version.outputs.TAG_VERSION }} - files: "*.tar.gz" - body_path: gh-release.md + uses: ansible-middleware/github-actions/.github/workflows/release.yml@main + secrets: inherit + with: + collection_fqcn: 'middleware_automation.keycloak' dispatch: needs: release From 6330f08b287f8aca05a2a13514136c6942637bf1 Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 28 Aug 2023 15:55:52 +0000 Subject: [PATCH 237/554] Update changelog for release 1.2.8 Signed-off-by: github-actions --- CHANGELOG.rst | 16 ++++++++++++++++ changelogs/changelog.yaml | 26 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 566fc60..694df90 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,22 @@ middleware_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v1.2.8 +====== + +Minor Changes +------------- + +- keycloak_quarkus: set openjdk 17 as default `#103 `_ +- keycloak_quarkus: update to version 22.0.1 `#107 `_ + +Bugfixes +-------- + +- Fix incorrect checks for ``keycloak_jgroups_subnet`` `#98 `_ +- Undefine ``keycloak_db_valid_conn_sql`` default `#91 `_ +- Update bindep.txt package python3-devel to support RHEL9 `#105 `_ + v1.2.7 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index b6e6bd1..272d30d 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -260,3 +260,29 @@ releases: - 92.yaml - 93.yaml release_date: '2023-06-19' + 1.2.8: + changes: + bugfixes: + - 'Fix incorrect checks for ``keycloak_jgroups_subnet`` `#98 `_ + + ' + - 'Undefine ``keycloak_db_valid_conn_sql`` default `#91 `_ + + ' + - 'Update bindep.txt package python3-devel to support RHEL9 `#105 `_ + + ' + minor_changes: + - 'keycloak_quarkus: set openjdk 17 as default `#103 `_ + + ' + - 'keycloak_quarkus: update to version 22.0.1 `#107 `_ + + ' + fragments: + - 103.yaml + - 105.yaml + - 107.yaml + - 91.yaml + - 98.yaml + release_date: '2023-08-28' From df7fab8f41e0b46d4e3b9ec928b66c10364043c1 Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 28 Aug 2023 15:56:38 +0000 Subject: [PATCH 238/554] Bump version to 1.2.9 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index a2eeccb..7d0d7de 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.2.8" +version: "1.2.9" readme: README.md authors: - Romain Pelisse From 40c015d3e170fc06f3ec6da1a8cca3f70609a86a Mon Sep 17 00:00:00 2001 From: Massimo Schiavon Date: Tue, 29 Aug 2023 21:41:38 +0200 Subject: [PATCH 239/554] always create pidfile folder add keycloak_service_runas feature flag fix previous installs permissions --- roles/keycloak/meta/argument_specs.yml | 5 +++++ roles/keycloak/tasks/install.yml | 18 +++++++++--------- roles/keycloak/templates/keycloak.service.j2 | 2 ++ 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index daba3ba..db73f3f 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -74,6 +74,11 @@ argument_specs: default: "" description: "Path to custom template for standalone.xml configuration" type: "str" + keycloak_service_runas: + # line 20 of keycloak/defaults/main.yml + default: false + description: "Enable execution of service as `keycloak_service_user`" + type: "bool" keycloak_service_user: # line 29 of keycloak/defaults/main.yml default: "keycloak" diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index 13f4ef3..a2467d3 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -53,20 +53,14 @@ group: "{{ keycloak_service_group }}" mode: 0750 -- name: Check pidfile folder - ansible.builtin.stat: - path: "{{ keycloak_service_pidfile | dirname }}" - register: keycloak_service_pidfile_stat - name: Create pidfile folder become: yes - become_user: root ansible.builtin.file: dest: "{{ keycloak_service_pidfile | dirname }}" state: directory - owner: "{{ keycloak_service_user }}" - group: "{{ keycloak_service_group }}" - mode: "0750" - when: not keycloak_service_pidfile_stat.stat.exists + owner: "{{ keycloak_service_user if keycloak_service_runas else omit }}" + group: "{{ keycloak_service_group if keycloak_service_runas else omit }}" + mode: 0750 ## check remote archive - name: Set download archive path @@ -209,6 +203,12 @@ become: yes changed_when: false +- name: Ensure permissions are correct on existing deploy + ansible.builtin.command: chown -R "{{ keycloak_service_user }}:{{ keycloak_service_group }}" "{{ keycloak.home }}" + when: keycloak_service_runas + become: yes + changed_when: false + # driver and configuration - name: "Install {{ keycloak_jdbc_engine }} driver" ansible.builtin.include_tasks: jdbc_driver.yml diff --git a/roles/keycloak/templates/keycloak.service.j2 b/roles/keycloak/templates/keycloak.service.j2 index 8a94c62..cc4f324 100644 --- a/roles/keycloak/templates/keycloak.service.j2 +++ b/roles/keycloak/templates/keycloak.service.j2 @@ -8,8 +8,10 @@ StartLimitBurst={{ keycloak_service_startlimitburst }} [Service] Type=forking +{% if keycloak_service_runas %} User={{ keycloak_service_user }} Group={{ keycloak_service_group }} +{% endif -%} EnvironmentFile=-/etc/sysconfig/keycloak PIDFile={{ keycloak_service_pidfile }} ExecStart={{ keycloak_dest }}/keycloak-service.sh start From 276444ce0ecb721250235881cdf20bba823e761d Mon Sep 17 00:00:00 2001 From: Massimo Schiavon Date: Tue, 29 Aug 2023 22:02:18 +0200 Subject: [PATCH 240/554] Add default for keycloak_service_runas --- roles/keycloak/defaults/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 156af46..9e09804 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -17,6 +17,7 @@ keycloak_config_standalone_xml: "keycloak.xml" keycloak_config_path_to_standalone_xml: "{{ keycloak_jboss_home }}/standalone/configuration/{{ keycloak_config_standalone_xml }}" keycloak_config_override_template: '' keycloak_config_path_to_properties: "{{ keycloak_jboss_home }}/standalone/configuration/profile.properties" +keycloak_service_runas: false keycloak_service_user: keycloak keycloak_service_group: keycloak keycloak_service_pidfile: "/run/keycloak/keycloak.pid" From 0199e554b53ba811ac1e91def7f1afe300f982c7 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 30 Aug 2023 10:16:41 +0200 Subject: [PATCH 241/554] overridexml test uses runas feature --- molecule/overridexml/converge.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/molecule/overridexml/converge.yml b/molecule/overridexml/converge.yml index 3c451da..e0bed70 100644 --- a/molecule/overridexml/converge.yml +++ b/molecule/overridexml/converge.yml @@ -6,6 +6,7 @@ keycloak_config_override_template: custom.xml.j2 keycloak_http_port: 8081 keycloak_management_http_port: 19990 + keycloak_service_runas: True roles: - role: keycloak tasks: @@ -51,4 +52,4 @@ sso_offline_install: True when: - assets_server is defined - - assets_server | length > 0 \ No newline at end of file + - assets_server | length > 0 From 7bb9647d0d1602dece70d9386cb9a5a6348f9993 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 30 Aug 2023 10:58:37 +0200 Subject: [PATCH 242/554] update systemd unit to use standalone.sh directly --- roles/keycloak/templates/keycloak-sysconfig.j2 | 10 +++++++++- roles/keycloak/templates/keycloak.service.j2 | 5 ++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/roles/keycloak/templates/keycloak-sysconfig.j2 b/roles/keycloak/templates/keycloak-sysconfig.j2 index 68474c3..86a96d6 100644 --- a/roles/keycloak/templates/keycloak-sysconfig.j2 +++ b/roles/keycloak/templates/keycloak-sysconfig.j2 @@ -8,4 +8,12 @@ KEYCLOAK_HTTPS_PORT={{ keycloak_https_port }} KEYCLOAK_MANAGEMENT_HTTP_PORT={{ keycloak_management_http_port }} KEYCLOAK_MANAGEMENT_HTTPS_PORT={{ keycloak_management_https_port }} JBOSS_PIDFILE='{{ keycloak_service_pidfile }}' -LAUNCH_JBOSS_IN_BACKGROUND=1 \ No newline at end of file + +WILDFLY_OPTS=-Djboss.bind.address=${KEYCLOAK_BIND_ADDRESS} \ + -Djboss.http.port=${KEYCLOAK_HTTP_PORT} \ + -Djboss.https.port=${KEYCLOAK_HTTPS_PORT} \ + -Djboss.management.http.port=${KEYCLOAK_MANAGEMENT_HTTP_PORT} \ + -Djboss.management.https.port=${KEYCLOAK_MANAGEMENT_HTTPS_PORT} \ + -Djboss.node.name={{ inventory_hostname }} \ + {% if keycloak_prefer_ipv4 %}-Djava.net.preferIPv4Stack=true -Djava.net.preferIPv4Addresses=true {% endif %}\ + {% if keycloak_config_standalone_xml is defined %}--server-config={{ keycloak_config_standalone_xml }}{% endif %} diff --git a/roles/keycloak/templates/keycloak.service.j2 b/roles/keycloak/templates/keycloak.service.j2 index cc4f324..15a6ddf 100644 --- a/roles/keycloak/templates/keycloak.service.j2 +++ b/roles/keycloak/templates/keycloak.service.j2 @@ -7,15 +7,14 @@ StartLimitBurst={{ keycloak_service_startlimitburst }} [Service] -Type=forking {% if keycloak_service_runas %} User={{ keycloak_service_user }} Group={{ keycloak_service_group }} {% endif -%} EnvironmentFile=-/etc/sysconfig/keycloak PIDFile={{ keycloak_service_pidfile }} -ExecStart={{ keycloak_dest }}/keycloak-service.sh start -ExecStop={{ keycloak_dest }}/keycloak-service.sh stop +ExecStart={{ keycloak.home }}/bin/standalone.sh $WILDFLY_OPTS +WorkingDirectory={{ keycloak.home }} TimeoutStartSec=30 TimeoutStopSec=30 LimitNOFILE=102642 From 6c65fadf310f12ca5feefe32ab4b611d51edaf34 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 30 Aug 2023 11:13:17 +0200 Subject: [PATCH 243/554] Bump version to 1.3.0 --- galaxy.yml | 2 +- molecule/default/molecule.yml | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/galaxy.yml b/galaxy.yml index 7d0d7de..82709bd 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.2.9" +version: "1.3.0" readme: README.md authors: - Romain Pelisse diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml index abdc729..c133eee 100644 --- a/molecule/default/molecule.yml +++ b/molecule/default/molecule.yml @@ -28,7 +28,6 @@ provisioner: ansible_python_interpreter: "{{ ansible_playbook_python }}" env: ANSIBLE_FORCE_COLOR: "true" - ANSIBLE_VERBOSITY: 3 verifier: name: ansible scenario: From b72460e4641a69ea2612ffa71a85dfca716fdb27 Mon Sep 17 00:00:00 2001 From: Miles Sherman Date: Mon, 18 Sep 2023 14:46:56 +0000 Subject: [PATCH 244/554] quarkus role: do not populate proxy to config if keycloak_quarkus_proxy_mode is undefined or set to 'none' --- roles/keycloak_quarkus/templates/keycloak.conf.j2 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index 600e9d1..ab883fc 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -34,8 +34,10 @@ cache-config-file=cache-ispn.xml cache-stack=tcp {% endif %} +{% if keycloak_quarkus_proxy_mode is defined and keycloak_quarkus_proxy_mode != "none" %} # Proxy proxy={{ keycloak_quarkus_proxy_mode }} +{% endif %} # Do not attach route to cookies and rely on the session affinity capabilities from reverse proxy #spi-sticky-session-encoder-infinispan-should-attach-route=false From d673fcf48a679a3f49ad65c39fff180598b18968 Mon Sep 17 00:00:00 2001 From: Miles Sherman Date: Mon, 18 Sep 2023 17:21:45 +0000 Subject: [PATCH 245/554] update documentation for change to keycloak_quarkus_proxy_mode handling --- roles/keycloak_quarkus/defaults/main.yml | 2 +- roles/keycloak_quarkus/meta/argument_specs.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 9081336..bd98cdb 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -49,7 +49,7 @@ keycloak_quarkus_db_enabled: "{{ True if keycloak_quarkus_ha_enabled else False keycloak_quarkus_http_relative_path: auth keycloak_quarkus_frontend_url: http://localhost:8080/auth -# proxy address forwarding mode if the server is behind a reverse proxy. [edge, reencrypt, passthrough] +# proxy address forwarding mode if the server is behind a reverse proxy. [none, edge, reencrypt, passthrough] keycloak_quarkus_proxy_mode: edge # disable xa transactions diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 2986c0c..8e7f08a 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -243,7 +243,7 @@ argument_specs: keycloak_quarkus_proxy_mode: default: 'edge' type: "str" - description: "The proxy address forwarding mode if the server is behind a reverse proxy" + description: "The proxy address forwarding mode if the server is behind a reverse proxy. Set to 'none' if not using a proxy" keycloak_quarkus_start_dev: default: False type: "bool" From 942b5fce0f88b2b5417d95a6a0144357b28b6fd8 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 19 Sep 2023 12:22:39 +0200 Subject: [PATCH 246/554] add molecule quarkus keycloak in dev-mode test --- molecule/quarkus-devmode/converge.yml | 44 ++++++++++++++++++++++++++ molecule/quarkus-devmode/molecule.yml | 45 +++++++++++++++++++++++++++ molecule/quarkus-devmode/prepare.yml | 12 +++++++ molecule/quarkus-devmode/roles | 1 + molecule/quarkus-devmode/verify.yml | 39 +++++++++++++++++++++++ 5 files changed, 141 insertions(+) create mode 100644 molecule/quarkus-devmode/converge.yml create mode 100644 molecule/quarkus-devmode/molecule.yml create mode 100644 molecule/quarkus-devmode/prepare.yml create mode 120000 molecule/quarkus-devmode/roles create mode 100644 molecule/quarkus-devmode/verify.yml diff --git a/molecule/quarkus-devmode/converge.yml b/molecule/quarkus-devmode/converge.yml new file mode 100644 index 0000000..b484120 --- /dev/null +++ b/molecule/quarkus-devmode/converge.yml @@ -0,0 +1,44 @@ +--- +- name: Converge + hosts: all + vars: + keycloak_quarkus_admin_pass: "remembertochangeme" + keycloak_admin_password: "remembertochangeme" + keycloak_realm: TestRealm + keycloak_quarkus_http_relative_path: '' + keycloak_quarkus_log: file + keycloak_quarkus_frontend_url: 'http://localhost:8080/' + keycloak_quarkus_start_dev: True + keycloak_quarkus_proxy_mode: none + roles: + - role: keycloak_quarkus + - role: keycloak_realm + keycloak_context: '' + keycloak_client_default_roles: + - TestRoleAdmin + - TestRoleUser + keycloak_client_users: + - username: TestUser + password: password + client_roles: + - client: TestClient + role: TestRoleUser + realm: "{{ keycloak_realm }}" + - username: TestAdmin + password: password + client_roles: + - client: TestClient + role: TestRoleUser + realm: "{{ keycloak_realm }}" + - client: TestClient + role: TestRoleAdmin + realm: "{{ keycloak_realm }}" + keycloak_realm: TestRealm + keycloak_clients: + - name: TestClient + roles: "{{ keycloak_client_default_roles }}" + realm: "{{ keycloak_realm }}" + public_client: "{{ keycloak_client_public }}" + web_origins: "{{ keycloak_client_web_origins }}" + users: "{{ keycloak_client_users }}" + client_id: TestClient diff --git a/molecule/quarkus-devmode/molecule.yml b/molecule/quarkus-devmode/molecule.yml new file mode 100644 index 0000000..191234d --- /dev/null +++ b/molecule/quarkus-devmode/molecule.yml @@ -0,0 +1,45 @@ +--- +driver: + name: docker +platforms: + - name: instance + image: registry.access.redhat.com/ubi8/ubi-init:latest + pre_build_image: true + privileged: true + command: "/usr/sbin/init" + port_bindings: + - "8080/tcp" + - "8009/tcp" + published_ports: + - 0.0.0.0:8080:8080/tcp +provisioner: + name: ansible + config_options: + defaults: + interpreter_python: auto_silent + ssh_connection: + pipelining: false + playbooks: + prepare: prepare.yml + converge: converge.yml + verify: verify.yml + inventory: + host_vars: + localhost: + ansible_python_interpreter: "{{ ansible_playbook_python }}" + env: + ANSIBLE_FORCE_COLOR: "true" +verifier: + name: ansible +scenario: + test_sequence: + - cleanup + - destroy + - create + - prepare + - converge + - idempotence + - side_effect + - verify + - cleanup + - destroy diff --git a/molecule/quarkus-devmode/prepare.yml b/molecule/quarkus-devmode/prepare.yml new file mode 100644 index 0000000..09cbda3 --- /dev/null +++ b/molecule/quarkus-devmode/prepare.yml @@ -0,0 +1,12 @@ +--- +- name: Prepare + hosts: all + tasks: + - name: Install sudo + ansible.builtin.yum: + name: sudo + state: present + + - name: "Display hera_home if defined." + ansible.builtin.set_fact: + hera_home: "{{ lookup('env', 'HERA_HOME') }}" diff --git a/molecule/quarkus-devmode/roles b/molecule/quarkus-devmode/roles new file mode 120000 index 0000000..b741aa3 --- /dev/null +++ b/molecule/quarkus-devmode/roles @@ -0,0 +1 @@ +../../roles \ No newline at end of file diff --git a/molecule/quarkus-devmode/verify.yml b/molecule/quarkus-devmode/verify.yml new file mode 100644 index 0000000..ebb6047 --- /dev/null +++ b/molecule/quarkus-devmode/verify.yml @@ -0,0 +1,39 @@ +--- +- name: Verify + hosts: all + tasks: + - name: Populate service facts + ansible.builtin.service_facts: + + - name: Check if keycloak service started + ansible.builtin.assert: + that: + - ansible_facts.services["keycloak.service"]["state"] == "running" + - ansible_facts.services["keycloak.service"]["status"] == "enabled" + + - name: Set internal envvar + ansible.builtin.set_fact: + hera_home: "{{ lookup('env', 'HERA_HOME') }}" + + - name: Verify openid config + block: + - name: Fetch openID config # noqa blocked_modules command-instead-of-module + ansible.builtin.shell: | + set -o pipefail + curl http://localhost:8080/realms/master/.well-known/openid-configuration -k | jq . + args: + executable: /bin/bash + delegate_to: localhost + register: openid_config + changed_when: False + - name: Verify endpoint URLs + ansible.builtin.assert: + that: + - (openid_config.stdout | from_json)["backchannel_authentication_endpoint"] == 'http://localhost:8080/realms/master/protocol/openid-connect/ext/ciba/auth' + - (openid_config.stdout | from_json)['issuer'] == 'http://localhost:8080/realms/master' + - (openid_config.stdout | from_json)['authorization_endpoint'] == 'http://localhost:8080/realms/master/protocol/openid-connect/auth' + - (openid_config.stdout | from_json)['token_endpoint'] == 'http://localhost:8080/realms/master/protocol/openid-connect/token' + delegate_to: localhost + when: + - hera_home is defined + - hera_home | length == 0 From 0f17e0973173bd5e2a4ce721b5b75a7367b80425 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 19 Sep 2023 12:25:38 +0200 Subject: [PATCH 247/554] add new test to CI --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a771a4d..50e1fc4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,4 +15,4 @@ jobs: with: fqcn: 'middleware_automation/keycloak' molecule_tests: >- - [ "default", "quarkus", "overridexml" ] + [ "default", "quarkus", "overridexml", "quarkus-devmode" ] From 9a46b455f6abcc90f361f6cf45ba0b380a5dbd82 Mon Sep 17 00:00:00 2001 From: Giovanni Toraldo Date: Tue, 19 Sep 2023 13:53:32 +0200 Subject: [PATCH 248/554] Fix admin login redirect when running locally --- roles/keycloak_quarkus/defaults/main.yml | 1 + roles/keycloak_quarkus/templates/keycloak.conf.j2 | 1 + 2 files changed, 2 insertions(+) diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index bd98cdb..bb7eb79 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -28,6 +28,7 @@ keycloak_quarkus_master_realm: master ### Configuration settings keycloak_quarkus_bind_address: 0.0.0.0 keycloak_quarkus_host: localhost +keycloak_quarkus_port: 8080 keycloak_quarkus_http_enabled: True keycloak_quarkus_http_port: 8080 keycloak_quarkus_https_port: 8443 diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index ab883fc..7285c48 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -25,6 +25,7 @@ https-certificate-key-file={{ keycloak_quarkus_key_file }} # Hostname for the Keycloak server. hostname={{ keycloak_quarkus_host }} +hostname-port={{ keycloak_quarkus_port }} hostname-path={{ keycloak_quarkus_http_relative_path }} # Cluster From 9c361c96280b67f76938212b796a019e5002ed15 Mon Sep 17 00:00:00 2001 From: Giovanni Toraldo Date: Tue, 19 Sep 2023 13:56:51 +0200 Subject: [PATCH 249/554] add in README --- roles/keycloak_quarkus/README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index b528944..03bd4e2 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -22,9 +22,10 @@ Role Defaults |`keycloak_quarkus_db_enabled`| Enable auto configuration for database backend | `True` if `keycloak_quarkus_ha_enabled` is True, else `False` | |`keycloak_quarkus_admin_user`| Administration console user account | `admin` | |`keycloak_quarkus_bind_address`| Address for binding service ports | `0.0.0.0` | -|`keycloak_quarkus_host`| hostname | `localhost` | -|`keycloak_quarkus_http_port`| HTTP port | `8080` | -|`keycloak_quarkus_https_port`| TLS HTTP port | `8443` | +|`keycloak_quarkus_host`| Hostname from where application is reachable by clients | `localhost` | +|`keycloak_quarkus_port`| Port from where application is reachable by clients | `8080` | +|`keycloak_quarkus_http_port`| HTTP listening port | `8080` | +|`keycloak_quarkus_https_port`| TLS HTTP listening port | `8443` | |`keycloak_quarkus_ajp_port`| AJP port | `8009` | |`keycloak_quarkus_jgroups_port`| jgroups cluster tcp port | `7600` | |`keycloak_quarkus_service_user`| Posix account username | `keycloak` | From 38ff5196249c84646ef08760e8d2374c91de24f1 Mon Sep 17 00:00:00 2001 From: Giovanni Toraldo Date: Tue, 19 Sep 2023 14:00:15 +0200 Subject: [PATCH 250/554] update arguments --- roles/keycloak_quarkus/meta/argument_specs.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 8e7f08a..8967633 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -90,10 +90,13 @@ argument_specs: description: "Address for binding service ports" type: "str" keycloak_quarkus_host: - # line 28 of defaults/main.yml default: "localhost" - description: "hostname" + description: "Hostname from where application is reachable by clients" type: "str" + keycloak_quarkus_port: + default: 8080 + description: "Port from where application is reachable by clients" + type: "int" keycloak_quarkus_http_enabled: default: true description: "Enable listener on HTTP port" From f0f90b8930cd274d06842689fa3b7dd0b50d52a6 Mon Sep 17 00:00:00 2001 From: Giovanni Toraldo Date: Tue, 19 Sep 2023 17:05:00 +0200 Subject: [PATCH 251/554] apply review suggestions --- roles/keycloak_quarkus/README.md | 4 ++-- roles/keycloak_quarkus/defaults/main.yml | 2 +- roles/keycloak_quarkus/meta/argument_specs.yml | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 03bd4e2..578b6fe 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -22,8 +22,8 @@ Role Defaults |`keycloak_quarkus_db_enabled`| Enable auto configuration for database backend | `True` if `keycloak_quarkus_ha_enabled` is True, else `False` | |`keycloak_quarkus_admin_user`| Administration console user account | `admin` | |`keycloak_quarkus_bind_address`| Address for binding service ports | `0.0.0.0` | -|`keycloak_quarkus_host`| Hostname from where application is reachable by clients | `localhost` | -|`keycloak_quarkus_port`| Port from where application is reachable by clients | `8080` | +|`keycloak_quarkus_host`| Hostname for the Keycloak server | `localhost` | +|`keycloak_quarkus_port`| The port used by the proxy when exposing the hostname | `-1` | |`keycloak_quarkus_http_port`| HTTP listening port | `8080` | |`keycloak_quarkus_https_port`| TLS HTTP listening port | `8443` | |`keycloak_quarkus_ajp_port`| AJP port | `8009` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index bb7eb79..075ba93 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -28,7 +28,7 @@ keycloak_quarkus_master_realm: master ### Configuration settings keycloak_quarkus_bind_address: 0.0.0.0 keycloak_quarkus_host: localhost -keycloak_quarkus_port: 8080 +keycloak_quarkus_port: -1 keycloak_quarkus_http_enabled: True keycloak_quarkus_http_port: 8080 keycloak_quarkus_https_port: 8443 diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 8967633..59f3e50 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -91,11 +91,11 @@ argument_specs: type: "str" keycloak_quarkus_host: default: "localhost" - description: "Hostname from where application is reachable by clients" + description: "Hostname for the Keycloak server" type: "str" keycloak_quarkus_port: - default: 8080 - description: "Port from where application is reachable by clients" + default: -1 + description: "The port used by the proxy when exposing the hostname" type: "int" keycloak_quarkus_http_enabled: default: true From 194101f01041b719485cc3035d3f48ffffc01449 Mon Sep 17 00:00:00 2001 From: Giovanni Toraldo Date: Tue, 19 Sep 2023 17:14:17 +0200 Subject: [PATCH 252/554] add new playbook example for localhost quarkus --- playbooks/keycloak_quarkus.yml | 5 +++-- playbooks/keycloak_quarkus_dev.yml | 13 +++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 playbooks/keycloak_quarkus_dev.yml diff --git a/playbooks/keycloak_quarkus.yml b/playbooks/keycloak_quarkus.yml index 9e1d3f9..7c657b7 100644 --- a/playbooks/keycloak_quarkus.yml +++ b/playbooks/keycloak_quarkus.yml @@ -1,9 +1,10 @@ --- -- name: Playbook for Keycloak X Hosts +- name: Playbook for Keycloak X Hosts with HTTPS enabled hosts: all vars: keycloak_admin_password: "remembertochangeme" - keycloak_quarkus_host: localhost:8443 + keycloak_quarkus_host: localhost + keycloak_quarkus_port: 8443 keycloak_quarkus_http_relative_path: '' keycloak_quarkus_log: file keycloak_quarkus_https_enabled: True diff --git a/playbooks/keycloak_quarkus_dev.yml b/playbooks/keycloak_quarkus_dev.yml new file mode 100644 index 0000000..634296d --- /dev/null +++ b/playbooks/keycloak_quarkus_dev.yml @@ -0,0 +1,13 @@ +--- +- name: Playbook for Keycloak X Hosts in develop mode + hosts: all + vars: + keycloak_admin_password: "remembertochangeme" + keycloak_quarkus_host: localhost + keycloak_quarkus_port: 8080 + keycloak_quarkus_http_relative_path: '' + keycloak_quarkus_log: file + keycloak_quarkus_start_dev: true + keycloak_quarkus_proxy_mode: none + roles: + - middleware_automation.keycloak.keycloak_quarkus From 3bb32ed075a72125875ef8f77155842d7082eb0e Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 21 Sep 2023 12:33:29 +0200 Subject: [PATCH 253/554] ci: update release wf --- .github/workflows/release.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5e14f9c..7ea4aab 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,9 +6,10 @@ on: jobs: release: uses: ansible-middleware/github-actions/.github/workflows/release.yml@main - secrets: inherit with: collection_fqcn: 'middleware_automation.keycloak' + secrets: + galaxy_token: ${{ secrets.ANSIBLE_GALAXY_API_KEY }} dispatch: needs: release From cb25c28bb83081c81a00adb3c46c61e55d4375bb Mon Sep 17 00:00:00 2001 From: footur <3769085+Footur@users.noreply.github.com> Date: Fri, 22 Sep 2023 15:42:06 +0200 Subject: [PATCH 254/554] Update Keycloak to version 22.0.3 --- molecule/quarkus/prepare.yml | 4 ++-- roles/keycloak_quarkus/README.md | 4 ++-- roles/keycloak_quarkus/defaults/main.yml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index 3e3d923..c6ccb76 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -30,13 +30,13 @@ - name: Create conf directory # risky-file-permissions in test user account does not exist yet ansible.builtin.file: state: directory - path: /opt/keycloak/keycloak-22.0.1/conf/ + path: /opt/keycloak/keycloak-22.0.3/conf/ mode: 0755 - name: Copy certificates ansible.builtin.copy: src: "{{ item }}" - dest: "/opt/keycloak/keycloak-22.0.1/conf/{{ item }}" + dest: "/opt/keycloak/keycloak-22.0.3/conf/{{ item }}" mode: 0444 loop: - cert.pem diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 578b6fe..2e389ec 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -11,7 +11,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_version`| keycloak.org package version | `22.0.1` | +|`keycloak_quarkus_version`| keycloak.org package version | `22.0.3` | * Service configuration @@ -72,7 +72,7 @@ Role Defaults |:---------|:------------|:---------| |`keycloak_quarkus_offline_install` | Perform an offline install | `False`| |`keycloak_quarkus_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| -|`keycloak_quarkus_version`| keycloak.org package version | `22.0.1` | +|`keycloak_quarkus_version`| keycloak.org package version | `22.0.3` | |`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` | |`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` | |`keycloak_quarkus_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 075ba93..d544605 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -1,6 +1,6 @@ --- ### Configuration specific to keycloak -keycloak_quarkus_version: 22.0.1 +keycloak_quarkus_version: 22.0.3 keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip" keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" From f3104285bc739494fa9c5c997b0748f2ec49ece5 Mon Sep 17 00:00:00 2001 From: Giovanni Toraldo Date: Fri, 22 Sep 2023 16:30:16 +0200 Subject: [PATCH 255/554] Enforce service restart when needed before service checking --- roles/keycloak_quarkus/tasks/main.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index 1c6c21b..2564345 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -52,6 +52,9 @@ mode: 0775 become: yes +- name: Flush pending handlers + meta: flush_handlers + - name: "Start and wait for keycloak service" ansible.builtin.include_tasks: start.yml From e3ce4bd574e42d6e188e562820142dd884ff0fd5 Mon Sep 17 00:00:00 2001 From: Giovanni Toraldo <71768+gionn@users.noreply.github.com> Date: Sat, 23 Sep 2023 18:38:49 +0200 Subject: [PATCH 256/554] fixup linter --- roles/keycloak_quarkus/tasks/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index 2564345..a86a4f5 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -53,7 +53,7 @@ become: yes - name: Flush pending handlers - meta: flush_handlers + ansible.builtin.meta: flush_handlers - name: "Start and wait for keycloak service" ansible.builtin.include_tasks: start.yml From dded412bd03ffe7a05e5bbe802710db4f33e37f9 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Mon, 25 Sep 2023 10:56:54 +0000 Subject: [PATCH 257/554] Update changelog for release 1.3.0 Signed-off-by: ansible-middleware-core --- CHANGELOG.rst | 20 ++++++++++++++++++++ changelogs/changelog.yaml | 29 +++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 694df90..8bcfa45 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,26 @@ middleware_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v1.3.0 +====== + +Major Changes +------------- + +- Run service as ``keycloak_service_user`` `#106 `_ + +Minor Changes +------------- + +- keycloak_quarkus: Update Keycloak to version 22.0.3 `#112 `_ +- keycloak_quarkus: fix admin console redirect when running locally `#111 `_ +- keycloak_quarkus: skip proxy config if ``keycloak_quarkus_proxy_mode`` is ``none`` `#109 `_ + +Bugfixes +-------- + +- keycloak_quarkus: fix validation failure upon port configuration change `#113 `_ + v1.2.8 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 272d30d..c3b1994 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -286,3 +286,32 @@ releases: - 91.yaml - 98.yaml release_date: '2023-08-28' + 1.3.0: + changes: + bugfixes: + - 'keycloak_quarkus: fix validation failure upon port configuration change `#113 + `_ + + ' + major_changes: + - 'Run service as ``keycloak_service_user`` `#106 `_ + + ' + minor_changes: + - 'keycloak_quarkus: Update Keycloak to version 22.0.3 `#112 `_ + + ' + - 'keycloak_quarkus: fix admin console redirect when running locally `#111 `_ + + ' + - 'keycloak_quarkus: skip proxy config if ``keycloak_quarkus_proxy_mode`` is + ``none`` `#109 `_ + + ' + fragments: + - 106.yaml + - 109.yaml + - 111.yaml + - 112.yaml + - 113.yaml + release_date: '2023-09-25' From 00e6cb6b0e293afc84dcb2720d50373660a592f3 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Mon, 25 Sep 2023 10:57:25 +0000 Subject: [PATCH 258/554] Bump version to 1.3.1 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 82709bd..5bafaec 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.3.0" +version: "1.3.1" readme: README.md authors: - Romain Pelisse From 0f7bbc7ef9b23364c9b6c18e1d209402bafc0bb5 Mon Sep 17 00:00:00 2001 From: Footur <3769085+Footur@users.noreply.github.com> Date: Fri, 13 Oct 2023 16:24:46 +0200 Subject: [PATCH 259/554] Update Keycloak to version 22.0.4 --- molecule/quarkus/prepare.yml | 4 ++-- roles/keycloak_quarkus/README.md | 4 ++-- roles/keycloak_quarkus/defaults/main.yml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index c6ccb76..589814a 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -30,13 +30,13 @@ - name: Create conf directory # risky-file-permissions in test user account does not exist yet ansible.builtin.file: state: directory - path: /opt/keycloak/keycloak-22.0.3/conf/ + path: /opt/keycloak/keycloak-22.0.4/conf/ mode: 0755 - name: Copy certificates ansible.builtin.copy: src: "{{ item }}" - dest: "/opt/keycloak/keycloak-22.0.3/conf/{{ item }}" + dest: "/opt/keycloak/keycloak-22.0.4/conf/{{ item }}" mode: 0444 loop: - cert.pem diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 2e389ec..f6e24cc 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -11,7 +11,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_version`| keycloak.org package version | `22.0.3` | +|`keycloak_quarkus_version`| keycloak.org package version | `22.0.4` | * Service configuration @@ -72,7 +72,7 @@ Role Defaults |:---------|:------------|:---------| |`keycloak_quarkus_offline_install` | Perform an offline install | `False`| |`keycloak_quarkus_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| -|`keycloak_quarkus_version`| keycloak.org package version | `22.0.3` | +|`keycloak_quarkus_version`| keycloak.org package version | `22.0.4` | |`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` | |`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` | |`keycloak_quarkus_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index d544605..0ae35c1 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -1,6 +1,6 @@ --- ### Configuration specific to keycloak -keycloak_quarkus_version: 22.0.3 +keycloak_quarkus_version: 22.0.4 keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip" keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" From e842462a2260fe81828bfcff9ecf8ba282f7cb46 Mon Sep 17 00:00:00 2001 From: Footur <3769085+Footur@users.noreply.github.com> Date: Fri, 13 Oct 2023 16:17:35 +0200 Subject: [PATCH 260/554] Enable config of a key store and trust store --- molecule/quarkus/converge.yml | 2 +- playbooks/keycloak_quarkus.yml | 2 +- roles/keycloak_quarkus/README.md | 9 +++++- roles/keycloak_quarkus/defaults/main.yml | 12 +++++-- .../keycloak_quarkus/meta/argument_specs.yml | 32 ++++++++++++++++--- .../templates/keycloak.conf.j2 | 10 +++++- 6 files changed, 57 insertions(+), 10 deletions(-) diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index 22f9ff4..6f07938 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -8,7 +8,7 @@ keycloak_quarkus_host: instance keycloak_quarkus_http_relative_path: '' keycloak_quarkus_log: file - keycloak_quarkus_https_enabled: True + keycloak_quarkus_https_key_file_enabled: True keycloak_quarkus_key_file: "{{ keycloak.home }}/conf/key.pem" keycloak_quarkus_cert_file: "{{ keycloak.home }}/conf/cert.pem" roles: diff --git a/playbooks/keycloak_quarkus.yml b/playbooks/keycloak_quarkus.yml index 7c657b7..5d34c87 100644 --- a/playbooks/keycloak_quarkus.yml +++ b/playbooks/keycloak_quarkus.yml @@ -7,7 +7,7 @@ keycloak_quarkus_port: 8443 keycloak_quarkus_http_relative_path: '' keycloak_quarkus_log: file - keycloak_quarkus_https_enabled: True + keycloak_quarkus_https_key_file_enabled: True keycloak_quarkus_key_file: conf/key.pem keycloak_quarkus_cert_file: conf/cert.pem roles: diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 2e389ec..8deeba4 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -37,9 +37,16 @@ Role Defaults |`keycloak_quarkus_frontend_url`| Service public URL | `http://localhost:8080/auth` | |`keycloak_quarkus_http_relative_path` | Service context path | `auth` | |`keycloak_quarkus_http_enabled`| Enable listener on HTTP port | `True` | -|`keycloak_quarkus_https_enabled`| Enable listener on HTTPS port | `False` | +|`keycloak_quarkus_https_key_file_enabled`| Enable listener on HTTPS port | `False` | |`keycloak_quarkus_key_file`| The file path to a private key in PEM format | `{{ keycloak.home }}/conf/server.key.pem` | |`keycloak_quarkus_cert_file`| The file path to a server certificate or certificate chain in PEM format | `{{ keycloak.home }}/conf/server.crt.pem` | +|`keycloak_quarkus_https_key_store_enabled`| Enable configuration of HTTPS via a key store | `False` | +|`keycloak_quarkus_key_store_file`| The file pat to the key store | `{{ keycloak.home }}/conf/key_store.p12` | +|`keycloak_quarkus_key_store_password`| Password for the key store | `""` | +|`keycloak_quarkus_https_trust_store_enabled`| Enalbe confiugration of a trust store | `False` | +|`keycloak_quarkus_trust_store_file`| The file pat to the trust store | `{{ keycloak.home }}/conf/trust_store.p12` | +|`keycloak_quarkus_trust_store_password`| Password for the trust store | `""` | + * Database configuration diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index d544605..3e94e37 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -2,7 +2,7 @@ ### Configuration specific to keycloak keycloak_quarkus_version: 22.0.3 keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip" -keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" +keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" # whether to install from local archive @@ -37,9 +37,17 @@ keycloak_quarkus_jgroups_port: 7600 keycloak_quarkus_java_opts: "-Xms1024m -Xmx2048m" ### TLS/HTTPS configuration -keycloak_quarkus_https_enabled: False +keycloak_quarkus_https_key_file_enabled: False keycloak_quarkus_key_file: "{{ keycloak.home }}/conf/server.key.pem" keycloak_quarkus_cert_file: "{{ keycloak.home }}/conf/server.crt.pem" +#### key store configuration +keycloak_quarkus_https_key_store_enabled: False +keycloak_quarkus_key_store_file: "{{ keycloak.home }}/conf/key_store.p12" +keycloak_quarkus_key_store_password: '' +##### trust store configuration +keycloak_quarkus_https_trust_store_enabled: False +keycloak_quarkus_trust_store_file: "{{ keycloak.home }}/conf/trust_store.p12" +keycloak_quarkus_trust_store_password: '' ### Enable configuration for database backend, clustering and remote caches on infinispan keycloak_quarkus_ha_enabled: False diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 59f3e50..0d44d4a 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -100,16 +100,16 @@ argument_specs: keycloak_quarkus_http_enabled: default: true description: "Enable listener on HTTP port" - type: "bool" + type: "bool" keycloak_quarkus_http_port: # line 29 of defaults/main.yml default: 8080 description: "HTTP port" type: "int" - keycloak_quarkus_https_enabled: + keycloak_quarkus_https_key_file_enabled: default: false - description: "Enable listener on HTTPS port" - type: "bool" + description: "Enable configuration of HTTPS via files in PEM format" + type: "bool" keycloak_quarkus_key_file: default: "{{ keycloak.home }}/conf/server.key.pem" description: "The file path to a private key in PEM format" @@ -118,6 +118,30 @@ argument_specs: default: "{{ keycloak.home }}/conf/server.crt.pem" description: "The file path to a server certificate or certificate chain in PEM format" type: "str" + keycloak_quarkus_https_key_store_enabled: + default: false + description: "Enable configuration of HTTPS via a key store" + type: "bool" + keycloak_quarkus_key_store_file: + default: "{{ keycloak.home }}/conf/key_store.p12" + description: "The file path to the key store" + type: "str" + keycloak_quarkus_key_store_password: + default: "" + description: "Password for the key store" + type: "str" + keycloak_quarkus_https_trust_store_enabled: + default: false + description: "Enalbe confiugration of a trust store" + type: "bool" + keycloak_quarkus_trust_store_file: + default: "{{ keycloak.home }}/conf/trust_store.p12" + description: "The file pat to the trust store" + type: "str" + keycloak_quarkus_trust_store_password: + default: "" + description: "Password for the trust store" + type: "str" keycloak_quarkus_https_port: # line 30 of defaults/main.yml default: 8443 diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index 7285c48..b31f63d 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -18,10 +18,18 @@ http-port={{ keycloak_quarkus_http_port }} # HTTPS https-port={{ keycloak_quarkus_https_port }} -{% if keycloak_quarkus_https_enabled %} +{% if keycloak_quarkus_https_key_file_enabled %} https-certificate-file={{ keycloak_quarkus_cert_file}} https-certificate-key-file={{ keycloak_quarkus_key_file }} {% endif %} +{% if keycloak_quarkus_https_key_store_enabled %} +https-key-store-file={{ keycloak_quarkus_key_store_file }} +https-key-store-password={{ keycloak_quarkus_key_store_password }} +{% endif %} +{% if keycloak_quarkus_https_trust_store_enabled %} +https-trust-store-file={{ keycloak_quarkus_trust_store_file }} +https-trust-store-password={{ keycloak_quarkus_trust_store_password }} +{% endif %} # Hostname for the Keycloak server. hostname={{ keycloak_quarkus_host }} From 307eee771f74dbcbc8188f83e704925438c603a4 Mon Sep 17 00:00:00 2001 From: Giovanni Toraldo Date: Mon, 16 Oct 2023 12:37:16 +0200 Subject: [PATCH 261/554] Do not require hosts edit for running quarkus molecule suite --- molecule/quarkus/prepare.yml | 15 --------------- molecule/quarkus/verify.yml | 8 ++++---- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index c6ccb76..b83211d 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -7,26 +7,11 @@ name: sudo state: present - - name: "Display hera_home if defined." - ansible.builtin.set_fact: - hera_home: "{{ lookup('env', 'HERA_HOME') }}" - - name: Create certificate request ansible.builtin.command: openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes -subj '/CN=instance' delegate_to: localhost changed_when: False - - name: Set /etc/hosts - ansible.builtin.lineinfile: - dest: /etc/hosts - line: "127.0.0.1 instance" - state: present - delegate_to: localhost - become: yes - when: - - hera_home is defined - - hera_home | length == 0 - - name: Create conf directory # risky-file-permissions in test user account does not exist yet ansible.builtin.file: state: directory diff --git a/molecule/quarkus/verify.yml b/molecule/quarkus/verify.yml index 553c4d6..e956ca6 100644 --- a/molecule/quarkus/verify.yml +++ b/molecule/quarkus/verify.yml @@ -16,11 +16,14 @@ hera_home: "{{ lookup('env', 'HERA_HOME') }}" - name: Verify openid config + when: + - hera_home is defined + - hera_home | length == 0 block: - name: Fetch openID config # noqa blocked_modules command-instead-of-module ansible.builtin.shell: | set -o pipefail - curl https://instance:8443/realms/master/.well-known/openid-configuration -k | jq . + curl -H 'Host: instance' https://localhost:8443/realms/master/.well-known/openid-configuration -k | jq . args: executable: /bin/bash delegate_to: localhost @@ -34,6 +37,3 @@ - (openid_config.stdout | from_json)['authorization_endpoint'] == 'https://instance/realms/master/protocol/openid-connect/auth' - (openid_config.stdout | from_json)['token_endpoint'] == 'https://instance/realms/master/protocol/openid-connect/token' delegate_to: localhost - when: - - hera_home is defined - - hera_home | length == 0 From bf1cb3695e8c48636da2a4af977d40a0db2d5380 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 16 Oct 2023 15:27:24 +0200 Subject: [PATCH 262/554] Update minimum ansible-core version > 2.14 --- README.md | 2 +- galaxy.yml | 2 +- meta/runtime.yml | 2 +- roles/keycloak/meta/main.yml | 4 ++-- roles/keycloak_quarkus/meta/main.yml | 4 ++-- roles/keycloak_realm/meta/main.yml | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 9ae661e..d93231f 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Collection to install and configure [Keycloak](https://www.keycloak.org/) or [Re ## Ansible version compatibility -This collection has been tested against following Ansible versions: **>=2.9.10**. +This collection has been tested against following Ansible versions: **>=2.14.0**. Plugins and modules within a collection may be tested with only specific Ansible versions. A collection may contain metadata that identifies these versions. diff --git a/galaxy.yml b/galaxy.yml index 5bafaec..ef8da0d 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.3.1" +version: "2.0.0" readme: README.md authors: - Romain Pelisse diff --git a/meta/runtime.yml b/meta/runtime.yml index 9baaad6..47dc0fb 100644 --- a/meta/runtime.yml +++ b/meta/runtime.yml @@ -1,2 +1,2 @@ --- -requires_ansible: ">=2.9.10" \ No newline at end of file +requires_ansible: ">=2.14.0" \ No newline at end of file diff --git a/roles/keycloak/meta/main.yml b/roles/keycloak/meta/main.yml index 5816039..5a121ba 100644 --- a/roles/keycloak/meta/main.yml +++ b/roles/keycloak/meta/main.yml @@ -12,12 +12,12 @@ galaxy_info: license: Apache License 2.0 - min_ansible_version: "2.9" + min_ansible_version: "2.14" platforms: - name: EL versions: - - 8 + - "8" galaxy_tags: - keycloak diff --git a/roles/keycloak_quarkus/meta/main.yml b/roles/keycloak_quarkus/meta/main.yml index 911a545..2a6acf8 100644 --- a/roles/keycloak_quarkus/meta/main.yml +++ b/roles/keycloak_quarkus/meta/main.yml @@ -8,12 +8,12 @@ galaxy_info: license: Apache License 2.0 - min_ansible_version: "2.9" + min_ansible_version: "2.14" platforms: - name: EL versions: - - 8 + - "8" galaxy_tags: - keycloak diff --git a/roles/keycloak_realm/meta/main.yml b/roles/keycloak_realm/meta/main.yml index 5dd7a21..8dfefcd 100644 --- a/roles/keycloak_realm/meta/main.yml +++ b/roles/keycloak_realm/meta/main.yml @@ -8,12 +8,12 @@ galaxy_info: license: Apache License 2.0 - min_ansible_version: "2.9" + min_ansible_version: "2.14" platforms: - name: EL versions: - - 8 + - "8" galaxy_tags: - keycloak From d945c511729371eb5343887492ca1a636966ae59 Mon Sep 17 00:00:00 2001 From: Giovanni Toraldo <71768+gionn@users.noreply.github.com> Date: Mon, 16 Oct 2023 15:52:04 +0200 Subject: [PATCH 263/554] apply review suggestions --- molecule/quarkus/prepare.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index b83211d..13dfff3 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -7,6 +7,10 @@ name: sudo state: present + - name: "Display hera_home if defined." + ansible.builtin.set_fact: + hera_home: "{{ lookup('env', 'HERA_HOME') }}" + - name: Create certificate request ansible.builtin.command: openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes -subj '/CN=instance' delegate_to: localhost From 41c13066020450d2560a3935fee1a2c901353294 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 25 Oct 2023 18:20:03 +0200 Subject: [PATCH 264/554] linter --- plugins/modules/keycloak_user_federation.py | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/modules/keycloak_user_federation.py b/plugins/modules/keycloak_user_federation.py index 96f04d7..bc84d8d 100644 --- a/plugins/modules/keycloak_user_federation.py +++ b/plugins/modules/keycloak_user_federation.py @@ -568,7 +568,6 @@ EXAMPLES = ''' realm: my-realm name: my-federation state: absent - ''' RETURN = ''' From e5f0a3efe10d3ac930b0eeb3981e7f3d1bf631ba Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 25 Oct 2023 16:40:25 +0200 Subject: [PATCH 265/554] molecule test for keycloakx with proxy --- .github/workflows/ci.yml | 2 +- molecule/https_revproxy/converge.yml | 16 ++++++++ molecule/https_revproxy/molecule.yml | 59 ++++++++++++++++++++++++++++ molecule/https_revproxy/prepare.yml | 49 +++++++++++++++++++++++ molecule/https_revproxy/roles | 1 + molecule/https_revproxy/verify.yml | 39 ++++++++++++++++++ molecule/requirements.yml | 2 +- 7 files changed, 166 insertions(+), 2 deletions(-) create mode 100644 molecule/https_revproxy/converge.yml create mode 100644 molecule/https_revproxy/molecule.yml create mode 100644 molecule/https_revproxy/prepare.yml create mode 120000 molecule/https_revproxy/roles create mode 100644 molecule/https_revproxy/verify.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 50e1fc4..6e5a542 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,4 +15,4 @@ jobs: with: fqcn: 'middleware_automation/keycloak' molecule_tests: >- - [ "default", "quarkus", "overridexml", "quarkus-devmode" ] + [ "default", "quarkus", "overridexml", "quarkus-devmode", "https_revproxy" ] diff --git a/molecule/https_revproxy/converge.yml b/molecule/https_revproxy/converge.yml new file mode 100644 index 0000000..b1eb7bc --- /dev/null +++ b/molecule/https_revproxy/converge.yml @@ -0,0 +1,16 @@ +--- +- name: Converge + hosts: all + vars: + keycloak_quarkus_admin_pass: "remembertochangeme" + keycloak_admin_password: "remembertochangeme" + keycloak_realm: TestRealm + keycloak_quarkus_host: instance + keycloak_quarkus_log: file + keycloak_quarkus_http_enabled: True + keycloak_quarkus_http_port: 8080 + keycloak_quarkus_proxy_mode: edge + keycloak_quarkus_http_relative_path: / + keycloak_quarkus_frontend_url: https://proxy/ + roles: + - role: keycloak_quarkus diff --git a/molecule/https_revproxy/molecule.yml b/molecule/https_revproxy/molecule.yml new file mode 100644 index 0000000..efdebf4 --- /dev/null +++ b/molecule/https_revproxy/molecule.yml @@ -0,0 +1,59 @@ +--- +driver: + name: docker +platforms: + - name: instance + image: registry.access.redhat.com/ubi8/ubi-init:latest + pre_build_image: true + privileged: true + command: "/usr/sbin/init" + networks: + - name: keycloak + port_bindings: + - "8080/tcp" + published_ports: + - 0.0.0.0:8080:8080/tcp + - name: proxy + image: registry.access.redhat.com/ubi8/ubi-init:latest + pre_build_image: true + privileged: true + command: "/usr/sbin/init" + networks: + - name: keycloak + port_bindings: + - "443/tcp" + published_ports: + - 0.0.0.0:443:443/tcp +provisioner: + name: ansible + config_options: + defaults: + interpreter_python: auto_silent + ssh_connection: + pipelining: false + playbooks: + prepare: prepare.yml + converge: converge.yml + verify: verify.yml + inventory: + host_vars: + localhost: + ansible_python_interpreter: "{{ ansible_playbook_python }}" + env: + ANSIBLE_FORCE_COLOR: "true" + REDHAT_PRODUCT_DOWNLOAD_CLIENT_ID: "${REDHAT_PRODUCT_DOWNLOAD_CLIENT_ID}" + REDHAT_PRODUCT_DOWNLOAD_CLIENT_SECRET: "${REDHAT_PRODUCT_DOWNLOAD_CLIENT_SECRET}" +verifier: + name: ansible +scenario: + test_sequence: + - cleanup + - destroy + - create + - prepare + - converge + - idempotence + - side_effect + - verify + - cleanup + - destroy diff --git a/molecule/https_revproxy/prepare.yml b/molecule/https_revproxy/prepare.yml new file mode 100644 index 0000000..5cdb135 --- /dev/null +++ b/molecule/https_revproxy/prepare.yml @@ -0,0 +1,49 @@ +--- +- name: Prepare + hosts: all + tasks: + - name: Install sudo + ansible.builtin.yum: + name: sudo + state: present + + - name: "Display hera_home if defined." + ansible.builtin.set_fact: + hera_home: "{{ lookup('env', 'HERA_HOME') }}" + +- name: Prepare proxy + hosts: proxy + vars: + jbcs_mod_cluster_enable: True + jbcs_configure_firewalld: False + jbcs_offline_install: False + jbcs_bind_address: '*' + jbcs_proxy_pass: + - path: / + url: http://instance:8080/ + reverse_path: / + reverse_url: http://instance:8080/ + external_domain_name: proxy + rhn_username: "{{ lookup('env', 'REDHAT_PRODUCT_DOWNLOAD_CLIENT_ID') }}" + rhn_password: "{{ lookup('env', 'REDHAT_PRODUCT_DOWNLOAD_CLIENT_SECRET') }}" + roles: + - middleware_automation.jbcs.jbcs + pre_tasks: + - name: Create certificate request + ansible.builtin.command: openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes -subj '/CN=proxy' + delegate_to: localhost + changed_when: False + + - name: Copy certificates + ansible.builtin.copy: + src: "{{ item.name }}" + dest: "{{ item.dest }}" + mode: 0444 + become: True + loop: + - { name: 'cert.pem', dest: '/etc/pki/tls/certs/proxy.crt' } + - { name: 'key.pem', dest: '/etc/pki/tls/private/proxy.key' } + + - name: update_ca_trust + command: update-ca-trust + become: True diff --git a/molecule/https_revproxy/roles b/molecule/https_revproxy/roles new file mode 120000 index 0000000..b741aa3 --- /dev/null +++ b/molecule/https_revproxy/roles @@ -0,0 +1 @@ +../../roles \ No newline at end of file diff --git a/molecule/https_revproxy/verify.yml b/molecule/https_revproxy/verify.yml new file mode 100644 index 0000000..9d355a6 --- /dev/null +++ b/molecule/https_revproxy/verify.yml @@ -0,0 +1,39 @@ +--- +- name: Verify + hosts: all + tasks: + - name: Populate service facts + ansible.builtin.service_facts: + + - name: Check if keycloak service started + ansible.builtin.assert: + that: + - ansible_facts.services["keycloak.service"]["state"] == "running" + - ansible_facts.services["keycloak.service"]["status"] == "enabled" + + - name: Set internal envvar + ansible.builtin.set_fact: + hera_home: "{{ lookup('env', 'HERA_HOME') }}" + + - name: Verify openid config + block: + - name: Fetch openID config # noqa blocked_modules command-instead-of-module + ansible.builtin.shell: | + set -o pipefail + curl https://localhost:443/realms/master/.well-known/openid-configuration -k | jq . + args: + executable: /bin/bash + register: openid_config + changed_when: False + delegate_to: localhost + - name: Verify endpoint URLs + ansible.builtin.assert: + that: + - (openid_config.stdout | from_json)["backchannel_authentication_endpoint"] == 'https://proxy/realms/master/protocol/openid-connect/ext/ciba/auth' + - (openid_config.stdout | from_json)['issuer'] == 'https://proxy/realms/master' + - (openid_config.stdout | from_json)['authorization_endpoint'] == 'https://proxy/realms/master/protocol/openid-connect/auth' + - (openid_config.stdout | from_json)['token_endpoint'] == 'https://proxy/realms/master/protocol/openid-connect/token' + delegate_to: localhost + when: + - hera_home is defined + - hera_home | length == 0 diff --git a/molecule/requirements.yml b/molecule/requirements.yml index 2e0ae56..5e39b59 100644 --- a/molecule/requirements.yml +++ b/molecule/requirements.yml @@ -1,8 +1,8 @@ --- collections: - name: middleware_automation.common + - name: middleware_automation.jbcs - name: community.general - name: ansible.posix - name: community.docker version: ">=1.9.1" - From 697023620128485980f5d942fa28a39d7680a983 Mon Sep 17 00:00:00 2001 From: Antonio Costa Date: Wed, 25 Oct 2023 16:03:29 +0200 Subject: [PATCH 266/554] feat: add a destination variable for the log link docs: argument specs for the keycloak_quarkus_log_target docs: added parameter to the roles README fix: role variable is keycloak_log_target and not keycloak_quarkus_log_target --- molecule/default/converge.yml | 1 + molecule/default/verify.yml | 28 +++++++++++++++ molecule/quarkus/converge.yml | 1 + molecule/quarkus/verify.yml | 34 +++++++++++++++++++ roles/keycloak/README.md | 2 +- roles/keycloak/defaults/main.yml | 3 ++ roles/keycloak/meta/argument_specs.yml | 4 +++ roles/keycloak/tasks/main.yml | 2 +- roles/keycloak_quarkus/README.md | 1 + roles/keycloak_quarkus/defaults/main.yml | 1 + .../keycloak_quarkus/meta/argument_specs.yml | 4 +++ roles/keycloak_quarkus/tasks/main.yml | 2 +- 12 files changed, 80 insertions(+), 3 deletions(-) diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index d3742e7..afd6ea2 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -10,6 +10,7 @@ port: 16667 - host: myhost2 port: 16668 + keycloak_log_target: /tmp/keycloak roles: - role: keycloak tasks: diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml index 92a245e..36f49b1 100644 --- a/molecule/default/verify.yml +++ b/molecule/default/verify.yml @@ -55,3 +55,31 @@ ansible.builtin.assert: that: - (keycloak_query_clients.json | selectattr('clientId','equalto','TestClient') | first)["attributes"]["post.logout.redirect.uris"] == '/public/logout' + - name: Check log folder + ansible.builtin.stat: + path: "/tmp/keycloak" + register: keycloak_log_folder + - name: Check that keycloak log folder exists and is a link + ansible.builtin.assert: + that: + - keycloak_log_folder.stat.exists + - not keycloak_log_folder.stat.isdir + - keycloak_log_folder.stat.islnk + - name: Check log file + ansible.builtin.stat: + path: "/tmp/keycloak/server.log" + register: keycloak_log_file + - name: Check if keycloak file exists + ansible.builtin.assert: + that: + - keycloak_log_file.stat.exists + - not keycloak_log_file.stat.isdir + - name: Check default log folder + ansible.builtin.stat: + path: "/var/log/keycloak" + register: keycloak_default_log_folder + failed_when: false + - name: Check that default keycloak log folder doesn't exist + ansible.builtin.assert: + that: + - not keycloak_default_log_folder.stat.exists diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index 22f9ff4..cb35230 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -11,6 +11,7 @@ keycloak_quarkus_https_enabled: True keycloak_quarkus_key_file: "{{ keycloak.home }}/conf/key.pem" keycloak_quarkus_cert_file: "{{ keycloak.home }}/conf/cert.pem" + keycloak_quarkus_log_target: /tmp/keycloak roles: - role: keycloak_quarkus - role: keycloak_realm diff --git a/molecule/quarkus/verify.yml b/molecule/quarkus/verify.yml index e956ca6..2d75c32 100644 --- a/molecule/quarkus/verify.yml +++ b/molecule/quarkus/verify.yml @@ -37,3 +37,37 @@ - (openid_config.stdout | from_json)['authorization_endpoint'] == 'https://instance/realms/master/protocol/openid-connect/auth' - (openid_config.stdout | from_json)['token_endpoint'] == 'https://instance/realms/master/protocol/openid-connect/token' delegate_to: localhost + + - name: Check log folder + ansible.builtin.stat: + path: "/tmp/keycloak" + register: keycloak_log_folder + + - name: Check that keycloak log folder exists and is a link + ansible.builtin.assert: + that: + - keycloak_log_folder.stat.exists + - not keycloak_log_folder.stat.isdir + - keycloak_log_folder.stat.islnk + + - name: Check log file + ansible.builtin.stat: + path: "/tmp/keycloak/keycloak.log" + register: keycloak_log_file + + - name: Check if keycloak file exists + ansible.builtin.assert: + that: + - keycloak_log_file.stat.exists + - not keycloak_log_file.stat.isdir + + - name: Check default log folder + ansible.builtin.stat: + path: "/var/log/keycloak" + register: keycloak_default_log_folder + failed_when: false + + - name: Check that default keycloak log folder doesn't exist + ansible.builtin.assert: + that: + - not keycloak_default_log_folder.stat.exists diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index aae309b..ed10963 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -117,7 +117,7 @@ Role Defaults |`keycloak_db_background_validation_millis`| How frequenly the connection pool is validated in the background | `10000` if background validation enabled | |`keycloak_db_background_validate_on_match` | Enable validate on match for database connections | `False` | |`keycloak_frontend_url` | frontend URL for keycloak endpoint | `http://localhost:8080/auth/` | - +|`keycloak_log_target`| Set the destination of the keycloak log folder link | `/var/log/keycloak` | Role Variables diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 9e09804..124250e 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -114,3 +114,6 @@ keycloak_default_jdbc: version: 12.2.0 # role specific vars keycloak_no_log: True + +### logging configuration +keycloak_log_target: /var/log/keycloak diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index db73f3f..5b64fe9 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -356,6 +356,10 @@ argument_specs: required: False description: "Override the subnet match for jgroups cluster formation; if not defined, it will be inferred from local machine route configuration" type: "str" + keycloak_log_target: + default: '/var/log/keycloak' + type: "str" + description: "Set the destination of the keycloak log folder link" downstream: options: sso_version: diff --git a/roles/keycloak/tasks/main.yml b/roles/keycloak/tasks/main.yml index 32aca04..7fe0222 100644 --- a/roles/keycloak/tasks/main.yml +++ b/roles/keycloak/tasks/main.yml @@ -34,7 +34,7 @@ ansible.builtin.file: state: link src: "{{ keycloak_jboss_home }}/standalone/log" - dest: /var/log/keycloak + dest: "{{ keycloak_log_target }}" become: yes - name: Set admin credentials and restart if not already created diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index f6e24cc..0ea2648 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -97,6 +97,7 @@ Role Defaults |`keycloak_quarkus_log_level`| The log level of the root category or a comma-separated list of individual categories and their levels | `info` | |`keycloak_quarkus_log_file`| Set the log file path and filename relative to keycloak home | `data/log/keycloak.log` | |`keycloak_quarkus_log_format`| Set a format specific to file log entries | `%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n` | +|`keycloak_quarkus_log_target`| Set the destination of the keycloak log folder link | `/var/log/keycloak` | |`keycloak_quarkus_proxy_mode`| The proxy address forwarding mode if the server is behind a reverse proxy | `edge` | |`keycloak_quarkus_start_dev`| Whether to start the service in development mode (start-dev) | `False` | |`keycloak_quarkus_transaction_xa_enabled`| Whether to use XA transactions | `True` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 0ae35c1..7995d05 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -90,3 +90,4 @@ keycloak_quarkus_log: file keycloak_quarkus_log_level: info keycloak_quarkus_log_file: data/log/keycloak.log keycloak_quarkus_log_format: '%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n' +keycloak_quarkus_log_target: /var/log/keycloak diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 59f3e50..32e550b 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -243,6 +243,10 @@ argument_specs: default: '%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n' type: "str" description: "Set a format specific to file log entries" + keycloak_quarkus_log_target: + default: '/var/log/keycloak' + type: "str" + description: "Set the destination of the keycloak log folder link" keycloak_quarkus_proxy_mode: default: 'edge' type: "str" diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index a86a4f5..43cbb38 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -67,6 +67,6 @@ ansible.builtin.file: state: link src: "{{ keycloak.log.file | dirname }}" - dest: /var/log/keycloak + dest: "{{ keycloak_quarkus_log_target }}" force: yes become: yes From 6f26fa3da42c0d92ebc5162be77fd32067a83df7 Mon Sep 17 00:00:00 2001 From: Footur <3769085+Footur@users.noreply.github.com> Date: Fri, 27 Oct 2023 15:32:15 +0200 Subject: [PATCH 267/554] Update Keycloak to version 22.0.5 --- molecule/quarkus/prepare.yml | 4 ++-- roles/keycloak_quarkus/README.md | 4 ++-- roles/keycloak_quarkus/defaults/main.yml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index f9fe2b7..f90564c 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -19,13 +19,13 @@ - name: Create conf directory # risky-file-permissions in test user account does not exist yet ansible.builtin.file: state: directory - path: /opt/keycloak/keycloak-22.0.4/conf/ + path: /opt/keycloak/keycloak-22.0.5/conf/ mode: 0755 - name: Copy certificates ansible.builtin.copy: src: "{{ item }}" - dest: "/opt/keycloak/keycloak-22.0.4/conf/{{ item }}" + dest: "/opt/keycloak/keycloak-22.0.5/conf/{{ item }}" mode: 0444 loop: - cert.pem diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index f6e24cc..9e3e017 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -11,7 +11,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_version`| keycloak.org package version | `22.0.4` | +|`keycloak_quarkus_version`| keycloak.org package version | `22.0.5` | * Service configuration @@ -72,7 +72,7 @@ Role Defaults |:---------|:------------|:---------| |`keycloak_quarkus_offline_install` | Perform an offline install | `False`| |`keycloak_quarkus_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| -|`keycloak_quarkus_version`| keycloak.org package version | `22.0.4` | +|`keycloak_quarkus_version`| keycloak.org package version | `22.0.5` | |`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` | |`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` | |`keycloak_quarkus_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 0ae35c1..9aa5531 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -1,6 +1,6 @@ --- ### Configuration specific to keycloak -keycloak_quarkus_version: 22.0.4 +keycloak_quarkus_version: 22.0.5 keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip" keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" From 9ddd6d7d5e37b13d8ff8fa37f4dd029cbb568af4 Mon Sep 17 00:00:00 2001 From: Antonio Costa Date: Mon, 30 Oct 2023 09:27:30 +0100 Subject: [PATCH 268/554] feat: jboss port offset configuration --- molecule/default/converge.yml | 1 + molecule/default/verify.yml | 5 +++-- roles/keycloak/README.md | 5 +++-- roles/keycloak/defaults/main.yml | 1 + roles/keycloak/meta/argument_specs.yml | 8 ++++++-- .../templates/15.0.8/standalone-infinispan.xml.j2 | 2 +- roles/keycloak/templates/15.0.8/standalone.xml.j2 | 2 +- .../keycloak/templates/9.0.2/standalone-infinispan.xml.j2 | 2 +- roles/keycloak/templates/9.0.2/standalone.xml.j2 | 2 +- roles/keycloak/templates/standalone-ha.xml.j2 | 2 +- roles/keycloak/templates/standalone-infinispan.xml.j2 | 2 +- roles/keycloak/templates/standalone.xml.j2 | 2 +- roles/keycloak/vars/main.yml | 4 ++-- roles/keycloak_realm/meta/argument_specs.yml | 4 ++-- roles/keycloak_realm/vars/main.yml | 4 ++-- 15 files changed, 27 insertions(+), 19 deletions(-) diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index d3742e7..e7fd4e0 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -10,6 +10,7 @@ port: 16667 - host: myhost2 port: 16668 + keycloak_jboss_port_offset: 10 roles: - role: keycloak tasks: diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml index 92a245e..2dfd6a7 100644 --- a/molecule/default/verify.yml +++ b/molecule/default/verify.yml @@ -4,8 +4,9 @@ vars: keycloak_admin_password: "remembertochangeme" keycloak_jvm_package: java-11-openjdk-headless - keycloak_uri: http://localhost:8080 - keycloak_management_port: http://localhost:9990 + keycloak_uri: "http://localhost:{{ 8080 + ( keycloak_jboss_port_offset | default(0) ) }}" + keycloak_management_port: "http://localhost:{{ 9990 + ( keycloak_jboss_port_offset | default(0) ) }}" + keycloak_jboss_port_offset: 10 tasks: - name: Populate service facts ansible.builtin.service_facts: diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index aae309b..13adf35 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -104,14 +104,15 @@ Role Defaults |`keycloak_download_url_9x` | Download URL for keycloak (deprecated) | `https://downloads.jboss.org/keycloak/{{ keycloak_version }}/{{ keycloak_archive }}` | |`keycloak_installdir` | Installation path | `{{ keycloak_dest }}/keycloak-{{ keycloak_version }}` | |`keycloak_jboss_home` | Installation work directory | `{{ keycloak_rhsso_installdir }}` | +|`keycloak_jboss_port_offset` | Port offset for the JBoss socket binding | `0` | |`keycloak_config_dir` | Path for configuration | `{{ keycloak_jboss_home }}/standalone/configuration` | |`keycloak_config_path_to_standalone_xml` | Custom path for configuration | `{{ keycloak_jboss_home }}/standalone/configuration/{{ keycloak_config_standalone_xml }}` | |`keycloak_config_override_template` | Path to custom template for standalone.xml configuration | `''` | |`keycloak_auth_realm` | Name for rest authentication realm | `master` | |`keycloak_auth_client` | Authentication client for configuration REST calls | `admin-cli` | |`keycloak_force_install` | Remove pre-existing versions of service | `False` | -|`keycloak_url` | URL for configuration rest calls | `http://{{ keycloak_host }}:{{ keycloak_http_port }}` | -|`keycloak_management_url` | URL for management console rest calls | `http://{{ keycloak_host }}:{{ keycloak_management_http_port }}` | +|`keycloak_url` | URL for configuration rest calls | `http://{{ keycloak_host }}:{{ keycloak_http_port + keycloak_jboss_port_offset }}` | +|`keycloak_management_url` | URL for management console rest calls | `http://{{ keycloak_host }}:{{ keycloak_management_http_port + keycloak_jboss_port_offset }}` | |`keycloak_frontend_url_force` | Force backend requests to use the frontend URL | `False` | |`keycloak_db_background_validation` | Enable background validation of database connection | `False` | |`keycloak_db_background_validation_millis`| How frequenly the connection pool is validated in the background | `10000` if background validation enabled | diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 9e09804..228d1e6 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -12,6 +12,7 @@ keycloak_jvm_package: java-1.8.0-openjdk-headless keycloak_java_home: keycloak_dest: /opt/keycloak keycloak_jboss_home: "{{ keycloak_installdir }}" +keycloak_jboss_port_offset: 0 keycloak_config_dir: "{{ keycloak_jboss_home }}/standalone/configuration" keycloak_config_standalone_xml: "keycloak.xml" keycloak_config_path_to_standalone_xml: "{{ keycloak_jboss_home }}/standalone/configuration/{{ keycloak_config_standalone_xml }}" diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index db73f3f..b28be78 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -54,6 +54,10 @@ argument_specs: default: "{{ keycloak_installdir }}" description: "Installation work directory" type: "str" + keycloak_jboss_port_offset: + default: 0 + description: "Port offset for the JBoss socket binding" + type: "int" keycloak_config_dir: # line 26 of keycloak/defaults/main.yml default: "{{ keycloak_jboss_home }}/standalone/configuration" @@ -280,12 +284,12 @@ argument_specs: type: "str" keycloak_url: # line 12 of keycloak/vars/main.yml - default: "http://{{ keycloak_host }}:{{ keycloak_http_port }}" + default: "http://{{ keycloak_host }}:{{ keycloak_http_port + keycloak_jboss_port_offset }}" description: "URL for configuration rest calls" type: "str" keycloak_management_url: # line 13 of keycloak/vars/main.yml - default: "http://{{ keycloak_host }}:{{ keycloak_management_http_port }}" + default: "http://{{ keycloak_host }}:{{ keycloak_management_http_port + keycloak_jboss_port_offset }}" description: "URL for management console rest calls" type: "str" keycloak_service_name: diff --git a/roles/keycloak/templates/15.0.8/standalone-infinispan.xml.j2 b/roles/keycloak/templates/15.0.8/standalone-infinispan.xml.j2 index be61837..2d84f3f 100644 --- a/roles/keycloak/templates/15.0.8/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/15.0.8/standalone-infinispan.xml.j2 @@ -737,7 +737,7 @@ - + diff --git a/roles/keycloak/templates/15.0.8/standalone.xml.j2 b/roles/keycloak/templates/15.0.8/standalone.xml.j2 index e2f6a76..de175f2 100644 --- a/roles/keycloak/templates/15.0.8/standalone.xml.j2 +++ b/roles/keycloak/templates/15.0.8/standalone.xml.j2 @@ -638,7 +638,7 @@ - + diff --git a/roles/keycloak/templates/9.0.2/standalone-infinispan.xml.j2 b/roles/keycloak/templates/9.0.2/standalone-infinispan.xml.j2 index 9e0ae66..4f90ad8 100644 --- a/roles/keycloak/templates/9.0.2/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/9.0.2/standalone-infinispan.xml.j2 @@ -734,7 +734,7 @@ - + diff --git a/roles/keycloak/templates/9.0.2/standalone.xml.j2 b/roles/keycloak/templates/9.0.2/standalone.xml.j2 index 823357f..4188e92 100644 --- a/roles/keycloak/templates/9.0.2/standalone.xml.j2 +++ b/roles/keycloak/templates/9.0.2/standalone.xml.j2 @@ -598,7 +598,7 @@ - + diff --git a/roles/keycloak/templates/standalone-ha.xml.j2 b/roles/keycloak/templates/standalone-ha.xml.j2 index 98e26f6..99399f3 100644 --- a/roles/keycloak/templates/standalone-ha.xml.j2 +++ b/roles/keycloak/templates/standalone-ha.xml.j2 @@ -674,7 +674,7 @@ - + diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index 38fbfec..0b0c8af 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -712,7 +712,7 @@ - + diff --git a/roles/keycloak/templates/standalone.xml.j2 b/roles/keycloak/templates/standalone.xml.j2 index bf2d528..72fe4d6 100644 --- a/roles/keycloak/templates/standalone.xml.j2 +++ b/roles/keycloak/templates/standalone.xml.j2 @@ -604,7 +604,7 @@ - + diff --git a/roles/keycloak/vars/main.yml b/roles/keycloak/vars/main.yml index 5fe498d..b03a1a5 100644 --- a/roles/keycloak/vars/main.yml +++ b/roles/keycloak/vars/main.yml @@ -2,8 +2,8 @@ # internal variables below # locations -keycloak_url: "http://{{ keycloak_host }}:{{ keycloak_http_port }}" -keycloak_management_url: "http://{{ keycloak_host }}:{{ keycloak_management_http_port }}" +keycloak_url: "http://{{ keycloak_host }}:{{ keycloak_http_port + keycloak_jboss_port_offset }}" +keycloak_management_url: "http://{{ keycloak_host }}:{{ keycloak_management_http_port + keycloak_jboss_port_offset }}" keycloak: diff --git a/roles/keycloak_realm/meta/argument_specs.yml b/roles/keycloak_realm/meta/argument_specs.yml index 4345af6..da3eca1 100644 --- a/roles/keycloak_realm/meta/argument_specs.yml +++ b/roles/keycloak_realm/meta/argument_specs.yml @@ -83,12 +83,12 @@ argument_specs: type: "list" keycloak_url: # line 14 of keycloak_realm/vars/main.yml - default: "http://{{ keycloak_host }}:{{ keycloak_http_port }}" + default: "http://{{ keycloak_host }}:{{ keycloak_http_port + ( keycloak_jboss_port_offset | default(0) ) }}" description: "URL for configuration rest calls" type: "str" keycloak_management_url: # line 15 of keycloak_realm/vars/main.yml - default: "http://{{ keycloak_host }}:{{ keycloak_management_http_port }}" + default: "http://{{ keycloak_host }}:{{ keycloak_management_http_port + ( keycloak_jboss_port_offset | default(0) ) }}" description: "URL for management console rest calls" type: "str" downstream: diff --git a/roles/keycloak_realm/vars/main.yml b/roles/keycloak_realm/vars/main.yml index 076a8a9..cbb9435 100644 --- a/roles/keycloak_realm/vars/main.yml +++ b/roles/keycloak_realm/vars/main.yml @@ -5,5 +5,5 @@ keycloak_realm: # other settings -keycloak_url: "http://{{ keycloak_host }}:{{ keycloak_http_port }}" -keycloak_management_url: "http://{{ keycloak_host }}:{{ keycloak_management_http_port }}" +keycloak_url: "http://{{ keycloak_host }}:{{ keycloak_http_port + ( keycloak_jboss_port_offset | default(0) ) }}" +keycloak_management_url: "http://{{ keycloak_host }}:{{ keycloak_management_http_port + ( keycloak_jboss_port_offset | default(0) ) }}" From 363c5d9f9e9ed77f9480df292cfddd1c16234482 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 3 Nov 2023 10:58:25 +0100 Subject: [PATCH 269/554] ddisable new test --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6e5a542..50e1fc4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,4 +15,4 @@ jobs: with: fqcn: 'middleware_automation/keycloak' molecule_tests: >- - [ "default", "quarkus", "overridexml", "quarkus-devmode", "https_revproxy" ] + [ "default", "quarkus", "overridexml", "quarkus-devmode" ] From 12147b47696c0deae714b06b0678b558f29d3cef Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 25 Oct 2023 18:20:03 +0200 Subject: [PATCH 270/554] linter --- plugins/modules/keycloak_user_federation.py | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/modules/keycloak_user_federation.py b/plugins/modules/keycloak_user_federation.py index 96f04d7..bc84d8d 100644 --- a/plugins/modules/keycloak_user_federation.py +++ b/plugins/modules/keycloak_user_federation.py @@ -568,7 +568,6 @@ EXAMPLES = ''' realm: my-realm name: my-federation state: absent - ''' RETURN = ''' From a538828f0de9af3afbe8ae06ea84d87d41498ee0 Mon Sep 17 00:00:00 2001 From: Antonio Costa Date: Wed, 25 Oct 2023 16:03:29 +0200 Subject: [PATCH 271/554] feat: add a destination variable for the log link docs: argument specs for the keycloak_quarkus_log_target docs: added parameter to the roles README fix: role variable is keycloak_log_target and not keycloak_quarkus_log_target --- molecule/default/converge.yml | 1 + molecule/default/verify.yml | 28 +++++++++++++++ molecule/quarkus/converge.yml | 1 + molecule/quarkus/verify.yml | 34 +++++++++++++++++++ roles/keycloak/README.md | 2 +- roles/keycloak/defaults/main.yml | 3 ++ roles/keycloak/meta/argument_specs.yml | 4 +++ roles/keycloak/tasks/main.yml | 2 +- roles/keycloak_quarkus/README.md | 1 + roles/keycloak_quarkus/defaults/main.yml | 1 + .../keycloak_quarkus/meta/argument_specs.yml | 4 +++ roles/keycloak_quarkus/tasks/main.yml | 2 +- 12 files changed, 80 insertions(+), 3 deletions(-) diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index e7fd4e0..ace4743 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -11,6 +11,7 @@ - host: myhost2 port: 16668 keycloak_jboss_port_offset: 10 + keycloak_log_target: /tmp/keycloak roles: - role: keycloak tasks: diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml index 2dfd6a7..ba0e01f 100644 --- a/molecule/default/verify.yml +++ b/molecule/default/verify.yml @@ -56,3 +56,31 @@ ansible.builtin.assert: that: - (keycloak_query_clients.json | selectattr('clientId','equalto','TestClient') | first)["attributes"]["post.logout.redirect.uris"] == '/public/logout' + - name: Check log folder + ansible.builtin.stat: + path: "/tmp/keycloak" + register: keycloak_log_folder + - name: Check that keycloak log folder exists and is a link + ansible.builtin.assert: + that: + - keycloak_log_folder.stat.exists + - not keycloak_log_folder.stat.isdir + - keycloak_log_folder.stat.islnk + - name: Check log file + ansible.builtin.stat: + path: "/tmp/keycloak/server.log" + register: keycloak_log_file + - name: Check if keycloak file exists + ansible.builtin.assert: + that: + - keycloak_log_file.stat.exists + - not keycloak_log_file.stat.isdir + - name: Check default log folder + ansible.builtin.stat: + path: "/var/log/keycloak" + register: keycloak_default_log_folder + failed_when: false + - name: Check that default keycloak log folder doesn't exist + ansible.builtin.assert: + that: + - not keycloak_default_log_folder.stat.exists diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index 22f9ff4..cb35230 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -11,6 +11,7 @@ keycloak_quarkus_https_enabled: True keycloak_quarkus_key_file: "{{ keycloak.home }}/conf/key.pem" keycloak_quarkus_cert_file: "{{ keycloak.home }}/conf/cert.pem" + keycloak_quarkus_log_target: /tmp/keycloak roles: - role: keycloak_quarkus - role: keycloak_realm diff --git a/molecule/quarkus/verify.yml b/molecule/quarkus/verify.yml index e956ca6..2d75c32 100644 --- a/molecule/quarkus/verify.yml +++ b/molecule/quarkus/verify.yml @@ -37,3 +37,37 @@ - (openid_config.stdout | from_json)['authorization_endpoint'] == 'https://instance/realms/master/protocol/openid-connect/auth' - (openid_config.stdout | from_json)['token_endpoint'] == 'https://instance/realms/master/protocol/openid-connect/token' delegate_to: localhost + + - name: Check log folder + ansible.builtin.stat: + path: "/tmp/keycloak" + register: keycloak_log_folder + + - name: Check that keycloak log folder exists and is a link + ansible.builtin.assert: + that: + - keycloak_log_folder.stat.exists + - not keycloak_log_folder.stat.isdir + - keycloak_log_folder.stat.islnk + + - name: Check log file + ansible.builtin.stat: + path: "/tmp/keycloak/keycloak.log" + register: keycloak_log_file + + - name: Check if keycloak file exists + ansible.builtin.assert: + that: + - keycloak_log_file.stat.exists + - not keycloak_log_file.stat.isdir + + - name: Check default log folder + ansible.builtin.stat: + path: "/var/log/keycloak" + register: keycloak_default_log_folder + failed_when: false + + - name: Check that default keycloak log folder doesn't exist + ansible.builtin.assert: + that: + - not keycloak_default_log_folder.stat.exists diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index 13adf35..17149f7 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -118,7 +118,7 @@ Role Defaults |`keycloak_db_background_validation_millis`| How frequenly the connection pool is validated in the background | `10000` if background validation enabled | |`keycloak_db_background_validate_on_match` | Enable validate on match for database connections | `False` | |`keycloak_frontend_url` | frontend URL for keycloak endpoint | `http://localhost:8080/auth/` | - +|`keycloak_log_target`| Set the destination of the keycloak log folder link | `/var/log/keycloak` | Role Variables diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 228d1e6..2b5cc35 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -115,3 +115,6 @@ keycloak_default_jdbc: version: 12.2.0 # role specific vars keycloak_no_log: True + +### logging configuration +keycloak_log_target: /var/log/keycloak diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index b28be78..2e93667 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -360,6 +360,10 @@ argument_specs: required: False description: "Override the subnet match for jgroups cluster formation; if not defined, it will be inferred from local machine route configuration" type: "str" + keycloak_log_target: + default: '/var/log/keycloak' + type: "str" + description: "Set the destination of the keycloak log folder link" downstream: options: sso_version: diff --git a/roles/keycloak/tasks/main.yml b/roles/keycloak/tasks/main.yml index 32aca04..7fe0222 100644 --- a/roles/keycloak/tasks/main.yml +++ b/roles/keycloak/tasks/main.yml @@ -34,7 +34,7 @@ ansible.builtin.file: state: link src: "{{ keycloak_jboss_home }}/standalone/log" - dest: /var/log/keycloak + dest: "{{ keycloak_log_target }}" become: yes - name: Set admin credentials and restart if not already created diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index f6e24cc..0ea2648 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -97,6 +97,7 @@ Role Defaults |`keycloak_quarkus_log_level`| The log level of the root category or a comma-separated list of individual categories and their levels | `info` | |`keycloak_quarkus_log_file`| Set the log file path and filename relative to keycloak home | `data/log/keycloak.log` | |`keycloak_quarkus_log_format`| Set a format specific to file log entries | `%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n` | +|`keycloak_quarkus_log_target`| Set the destination of the keycloak log folder link | `/var/log/keycloak` | |`keycloak_quarkus_proxy_mode`| The proxy address forwarding mode if the server is behind a reverse proxy | `edge` | |`keycloak_quarkus_start_dev`| Whether to start the service in development mode (start-dev) | `False` | |`keycloak_quarkus_transaction_xa_enabled`| Whether to use XA transactions | `True` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 0ae35c1..7995d05 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -90,3 +90,4 @@ keycloak_quarkus_log: file keycloak_quarkus_log_level: info keycloak_quarkus_log_file: data/log/keycloak.log keycloak_quarkus_log_format: '%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n' +keycloak_quarkus_log_target: /var/log/keycloak diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 59f3e50..32e550b 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -243,6 +243,10 @@ argument_specs: default: '%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n' type: "str" description: "Set a format specific to file log entries" + keycloak_quarkus_log_target: + default: '/var/log/keycloak' + type: "str" + description: "Set the destination of the keycloak log folder link" keycloak_quarkus_proxy_mode: default: 'edge' type: "str" diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index a86a4f5..43cbb38 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -67,6 +67,6 @@ ansible.builtin.file: state: link src: "{{ keycloak.log.file | dirname }}" - dest: /var/log/keycloak + dest: "{{ keycloak_quarkus_log_target }}" force: yes become: yes From 62e5380d383dea6e2d195340d89fd53a5f2c9cbc Mon Sep 17 00:00:00 2001 From: Footur <3769085+Footur@users.noreply.github.com> Date: Fri, 27 Oct 2023 15:32:15 +0200 Subject: [PATCH 272/554] Update Keycloak to version 22.0.5 --- molecule/quarkus/prepare.yml | 4 ++-- roles/keycloak_quarkus/README.md | 4 ++-- roles/keycloak_quarkus/defaults/main.yml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index f9fe2b7..f90564c 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -19,13 +19,13 @@ - name: Create conf directory # risky-file-permissions in test user account does not exist yet ansible.builtin.file: state: directory - path: /opt/keycloak/keycloak-22.0.4/conf/ + path: /opt/keycloak/keycloak-22.0.5/conf/ mode: 0755 - name: Copy certificates ansible.builtin.copy: src: "{{ item }}" - dest: "/opt/keycloak/keycloak-22.0.4/conf/{{ item }}" + dest: "/opt/keycloak/keycloak-22.0.5/conf/{{ item }}" mode: 0444 loop: - cert.pem diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 0ea2648..1a50a00 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -11,7 +11,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_version`| keycloak.org package version | `22.0.4` | +|`keycloak_quarkus_version`| keycloak.org package version | `22.0.5` | * Service configuration @@ -72,7 +72,7 @@ Role Defaults |:---------|:------------|:---------| |`keycloak_quarkus_offline_install` | Perform an offline install | `False`| |`keycloak_quarkus_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| -|`keycloak_quarkus_version`| keycloak.org package version | `22.0.4` | +|`keycloak_quarkus_version`| keycloak.org package version | `22.0.5` | |`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` | |`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` | |`keycloak_quarkus_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 7995d05..d769a85 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -1,6 +1,6 @@ --- ### Configuration specific to keycloak -keycloak_quarkus_version: 22.0.4 +keycloak_quarkus_version: 22.0.5 keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip" keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" From 03175e283b50f4d1e21ce5dfb7cad78650f0e9d7 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 25 Oct 2023 16:40:25 +0200 Subject: [PATCH 273/554] molecule test for keycloakx with proxy --- .github/workflows/ci.yml | 2 +- molecule/https_revproxy/converge.yml | 16 ++++++++ molecule/https_revproxy/molecule.yml | 59 ++++++++++++++++++++++++++++ molecule/https_revproxy/prepare.yml | 49 +++++++++++++++++++++++ molecule/https_revproxy/roles | 1 + molecule/https_revproxy/verify.yml | 39 ++++++++++++++++++ molecule/requirements.yml | 2 +- 7 files changed, 166 insertions(+), 2 deletions(-) create mode 100644 molecule/https_revproxy/converge.yml create mode 100644 molecule/https_revproxy/molecule.yml create mode 100644 molecule/https_revproxy/prepare.yml create mode 120000 molecule/https_revproxy/roles create mode 100644 molecule/https_revproxy/verify.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 50e1fc4..6e5a542 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,4 +15,4 @@ jobs: with: fqcn: 'middleware_automation/keycloak' molecule_tests: >- - [ "default", "quarkus", "overridexml", "quarkus-devmode" ] + [ "default", "quarkus", "overridexml", "quarkus-devmode", "https_revproxy" ] diff --git a/molecule/https_revproxy/converge.yml b/molecule/https_revproxy/converge.yml new file mode 100644 index 0000000..b1eb7bc --- /dev/null +++ b/molecule/https_revproxy/converge.yml @@ -0,0 +1,16 @@ +--- +- name: Converge + hosts: all + vars: + keycloak_quarkus_admin_pass: "remembertochangeme" + keycloak_admin_password: "remembertochangeme" + keycloak_realm: TestRealm + keycloak_quarkus_host: instance + keycloak_quarkus_log: file + keycloak_quarkus_http_enabled: True + keycloak_quarkus_http_port: 8080 + keycloak_quarkus_proxy_mode: edge + keycloak_quarkus_http_relative_path: / + keycloak_quarkus_frontend_url: https://proxy/ + roles: + - role: keycloak_quarkus diff --git a/molecule/https_revproxy/molecule.yml b/molecule/https_revproxy/molecule.yml new file mode 100644 index 0000000..efdebf4 --- /dev/null +++ b/molecule/https_revproxy/molecule.yml @@ -0,0 +1,59 @@ +--- +driver: + name: docker +platforms: + - name: instance + image: registry.access.redhat.com/ubi8/ubi-init:latest + pre_build_image: true + privileged: true + command: "/usr/sbin/init" + networks: + - name: keycloak + port_bindings: + - "8080/tcp" + published_ports: + - 0.0.0.0:8080:8080/tcp + - name: proxy + image: registry.access.redhat.com/ubi8/ubi-init:latest + pre_build_image: true + privileged: true + command: "/usr/sbin/init" + networks: + - name: keycloak + port_bindings: + - "443/tcp" + published_ports: + - 0.0.0.0:443:443/tcp +provisioner: + name: ansible + config_options: + defaults: + interpreter_python: auto_silent + ssh_connection: + pipelining: false + playbooks: + prepare: prepare.yml + converge: converge.yml + verify: verify.yml + inventory: + host_vars: + localhost: + ansible_python_interpreter: "{{ ansible_playbook_python }}" + env: + ANSIBLE_FORCE_COLOR: "true" + REDHAT_PRODUCT_DOWNLOAD_CLIENT_ID: "${REDHAT_PRODUCT_DOWNLOAD_CLIENT_ID}" + REDHAT_PRODUCT_DOWNLOAD_CLIENT_SECRET: "${REDHAT_PRODUCT_DOWNLOAD_CLIENT_SECRET}" +verifier: + name: ansible +scenario: + test_sequence: + - cleanup + - destroy + - create + - prepare + - converge + - idempotence + - side_effect + - verify + - cleanup + - destroy diff --git a/molecule/https_revproxy/prepare.yml b/molecule/https_revproxy/prepare.yml new file mode 100644 index 0000000..5cdb135 --- /dev/null +++ b/molecule/https_revproxy/prepare.yml @@ -0,0 +1,49 @@ +--- +- name: Prepare + hosts: all + tasks: + - name: Install sudo + ansible.builtin.yum: + name: sudo + state: present + + - name: "Display hera_home if defined." + ansible.builtin.set_fact: + hera_home: "{{ lookup('env', 'HERA_HOME') }}" + +- name: Prepare proxy + hosts: proxy + vars: + jbcs_mod_cluster_enable: True + jbcs_configure_firewalld: False + jbcs_offline_install: False + jbcs_bind_address: '*' + jbcs_proxy_pass: + - path: / + url: http://instance:8080/ + reverse_path: / + reverse_url: http://instance:8080/ + external_domain_name: proxy + rhn_username: "{{ lookup('env', 'REDHAT_PRODUCT_DOWNLOAD_CLIENT_ID') }}" + rhn_password: "{{ lookup('env', 'REDHAT_PRODUCT_DOWNLOAD_CLIENT_SECRET') }}" + roles: + - middleware_automation.jbcs.jbcs + pre_tasks: + - name: Create certificate request + ansible.builtin.command: openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes -subj '/CN=proxy' + delegate_to: localhost + changed_when: False + + - name: Copy certificates + ansible.builtin.copy: + src: "{{ item.name }}" + dest: "{{ item.dest }}" + mode: 0444 + become: True + loop: + - { name: 'cert.pem', dest: '/etc/pki/tls/certs/proxy.crt' } + - { name: 'key.pem', dest: '/etc/pki/tls/private/proxy.key' } + + - name: update_ca_trust + command: update-ca-trust + become: True diff --git a/molecule/https_revproxy/roles b/molecule/https_revproxy/roles new file mode 120000 index 0000000..b741aa3 --- /dev/null +++ b/molecule/https_revproxy/roles @@ -0,0 +1 @@ +../../roles \ No newline at end of file diff --git a/molecule/https_revproxy/verify.yml b/molecule/https_revproxy/verify.yml new file mode 100644 index 0000000..9d355a6 --- /dev/null +++ b/molecule/https_revproxy/verify.yml @@ -0,0 +1,39 @@ +--- +- name: Verify + hosts: all + tasks: + - name: Populate service facts + ansible.builtin.service_facts: + + - name: Check if keycloak service started + ansible.builtin.assert: + that: + - ansible_facts.services["keycloak.service"]["state"] == "running" + - ansible_facts.services["keycloak.service"]["status"] == "enabled" + + - name: Set internal envvar + ansible.builtin.set_fact: + hera_home: "{{ lookup('env', 'HERA_HOME') }}" + + - name: Verify openid config + block: + - name: Fetch openID config # noqa blocked_modules command-instead-of-module + ansible.builtin.shell: | + set -o pipefail + curl https://localhost:443/realms/master/.well-known/openid-configuration -k | jq . + args: + executable: /bin/bash + register: openid_config + changed_when: False + delegate_to: localhost + - name: Verify endpoint URLs + ansible.builtin.assert: + that: + - (openid_config.stdout | from_json)["backchannel_authentication_endpoint"] == 'https://proxy/realms/master/protocol/openid-connect/ext/ciba/auth' + - (openid_config.stdout | from_json)['issuer'] == 'https://proxy/realms/master' + - (openid_config.stdout | from_json)['authorization_endpoint'] == 'https://proxy/realms/master/protocol/openid-connect/auth' + - (openid_config.stdout | from_json)['token_endpoint'] == 'https://proxy/realms/master/protocol/openid-connect/token' + delegate_to: localhost + when: + - hera_home is defined + - hera_home | length == 0 diff --git a/molecule/requirements.yml b/molecule/requirements.yml index 2e0ae56..5e39b59 100644 --- a/molecule/requirements.yml +++ b/molecule/requirements.yml @@ -1,8 +1,8 @@ --- collections: - name: middleware_automation.common + - name: middleware_automation.jbcs - name: community.general - name: ansible.posix - name: community.docker version: ">=1.9.1" - From 61730b981b7b18f138d7e16d30890240fc57113b Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 3 Nov 2023 10:58:25 +0100 Subject: [PATCH 274/554] ddisable new test --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6e5a542..50e1fc4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,4 +15,4 @@ jobs: with: fqcn: 'middleware_automation/keycloak' molecule_tests: >- - [ "default", "quarkus", "overridexml", "quarkus-devmode", "https_revproxy" ] + [ "default", "quarkus", "overridexml", "quarkus-devmode" ] From 5543217c6a71df77818b0ffd5553e059dbfab7b4 Mon Sep 17 00:00:00 2001 From: Antonio Costa Date: Mon, 6 Nov 2023 15:00:51 +0100 Subject: [PATCH 275/554] rebase for changes made in PR 120 --- molecule/default/converge.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index ace4743..1e817f6 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -12,6 +12,7 @@ port: 16668 keycloak_jboss_port_offset: 10 keycloak_log_target: /tmp/keycloak + keycloak_jboss_port_offset: 10 roles: - role: keycloak tasks: From 316cde47596484300eaedfa09ad48b9af0f5ba3a Mon Sep 17 00:00:00 2001 From: Giovanni Toraldo Date: Mon, 9 Oct 2023 09:59:51 +0200 Subject: [PATCH 276/554] Add support for more http-related configs * keycloak_quarkus_http_relative_path var now populate http-relative-path config [breaking change] * http-relative-path defaults to / [breaking change] * enable configuration of hostname-url and hostname-admin-url --- molecule/quarkus-devmode/converge.yml | 1 - molecule/quarkus/converge.yml | 1 - roles/keycloak_quarkus/README.md | 6 ++++-- roles/keycloak_quarkus/defaults/main.yml | 8 ++++++-- roles/keycloak_quarkus/meta/argument_specs.yml | 12 +++++++++--- roles/keycloak_quarkus/templates/keycloak.conf.j2 | 10 ++++++++-- 6 files changed, 27 insertions(+), 11 deletions(-) diff --git a/molecule/quarkus-devmode/converge.yml b/molecule/quarkus-devmode/converge.yml index b484120..6cbe7d8 100644 --- a/molecule/quarkus-devmode/converge.yml +++ b/molecule/quarkus-devmode/converge.yml @@ -5,7 +5,6 @@ keycloak_quarkus_admin_pass: "remembertochangeme" keycloak_admin_password: "remembertochangeme" keycloak_realm: TestRealm - keycloak_quarkus_http_relative_path: '' keycloak_quarkus_log: file keycloak_quarkus_frontend_url: 'http://localhost:8080/' keycloak_quarkus_start_dev: True diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index cb35230..43e2215 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -6,7 +6,6 @@ keycloak_admin_password: "remembertochangeme" keycloak_realm: TestRealm keycloak_quarkus_host: instance - keycloak_quarkus_http_relative_path: '' keycloak_quarkus_log: file keycloak_quarkus_https_enabled: True keycloak_quarkus_key_file: "{{ keycloak.home }}/conf/key.pem" diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 1a50a00..7108780 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -24,6 +24,7 @@ Role Defaults |`keycloak_quarkus_bind_address`| Address for binding service ports | `0.0.0.0` | |`keycloak_quarkus_host`| Hostname for the Keycloak server | `localhost` | |`keycloak_quarkus_port`| The port used by the proxy when exposing the hostname | `-1` | +|`keycloak_quarkus_path`| This should be set if proxy uses a different context-path for Keycloak | | |`keycloak_quarkus_http_port`| HTTP listening port | `8080` | |`keycloak_quarkus_https_port`| TLS HTTP listening port | `8443` | |`keycloak_quarkus_ajp_port`| AJP port | `8009` | @@ -34,8 +35,9 @@ Role Defaults |`keycloak_quarkus_jvm_package`| RHEL java package runtime | `java-17-openjdk-headless` | |`keycloak_quarkus_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_quarkus_jvm_package RPM path | `None` | |`keycloak_quarkus_java_opts`| Additional JVM options | `-Xms1024m -Xmx2048m` | -|`keycloak_quarkus_frontend_url`| Service public URL | `http://localhost:8080/auth` | -|`keycloak_quarkus_http_relative_path` | Service context path | `auth` | +|`keycloak_quarkus_frontend_url`| Set the base URL for frontend URLs, including scheme, host, port and path | | +|`keycloak_quarkus_admin_url`| Set the base URL for accessing the administration console, including scheme, host, port and path | | +|`keycloak_quarkus_http_relative_path` | Service context path | | |`keycloak_quarkus_http_enabled`| Enable listener on HTTP port | `True` | |`keycloak_quarkus_https_enabled`| Enable listener on HTTPS port | `False` | |`keycloak_quarkus_key_file`| The file path to a private key in PEM format | `{{ keycloak.home }}/conf/server.key.pem` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index d769a85..62cd05e 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -29,6 +29,7 @@ keycloak_quarkus_master_realm: master keycloak_quarkus_bind_address: 0.0.0.0 keycloak_quarkus_host: localhost keycloak_quarkus_port: -1 +keycloak_quarkus_path: '' keycloak_quarkus_http_enabled: True keycloak_quarkus_http_port: 8080 keycloak_quarkus_https_port: 8443 @@ -47,8 +48,11 @@ keycloak_quarkus_ha_enabled: False keycloak_quarkus_db_enabled: "{{ True if keycloak_quarkus_ha_enabled else False }}" ### keycloak frontend url -keycloak_quarkus_http_relative_path: auth -keycloak_quarkus_frontend_url: http://localhost:8080/auth +keycloak_quarkus_frontend_url: '' +keycloak_quarkus_admin_url: '' + +### path under the application is exposed (set to `auth` for retrocompatibility with pre-quarkus releases) +keycloak_quarkus_http_relative_path: '' # proxy address forwarding mode if the server is behind a reverse proxy. [none, edge, reencrypt, passthrough] keycloak_quarkus_proxy_mode: edge diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 32e550b..2dd32bb 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -97,6 +97,10 @@ argument_specs: default: -1 description: "The port used by the proxy when exposing the hostname" type: "int" + keycloak_quarkus_path: + default: "" + description: "This should be set if proxy uses a different context-path for Keycloak" + type: "str" keycloak_quarkus_http_enabled: default: true description: "Enable listener on HTTP port" @@ -149,14 +153,16 @@ argument_specs: description: "Enable auto configuration for database backend" type: "str" keycloak_quarkus_http_relative_path: - # line 41 of defaults/main.yml default: "auth" description: "Service context path" type: "str" keycloak_quarkus_frontend_url: - # line 41 of defaults/main.yml - default: "http://localhost:8080/auth" description: "Service public URL" + default: "" + type: "str" + keycloak_quarkus_admin_url: + description: "Service URL for the admin console" + default: "" type: "str" keycloak_quarkus_metrics_enabled: # line 43 of defaults/main.yml diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index 7285c48..e2c078a 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -15,6 +15,7 @@ health-enabled={{ keycloak_quarkus_health_enabled }} # HTTP http-enabled={{ keycloak_quarkus_http_enabled }} http-port={{ keycloak_quarkus_http_port }} +http-relative-path={{ keycloak_quarkus_http_relative_path }} # HTTPS https-port={{ keycloak_quarkus_https_port }} @@ -23,10 +24,15 @@ https-certificate-file={{ keycloak_quarkus_cert_file}} https-certificate-key-file={{ keycloak_quarkus_key_file }} {% endif %} -# Hostname for the Keycloak server. +# Client URL configuration +{% if keycloak_quarkus_frontend_url %} +hostname-url={{ keycloak_quarkus_frontend_url }} +{% else %} hostname={{ keycloak_quarkus_host }} hostname-port={{ keycloak_quarkus_port }} -hostname-path={{ keycloak_quarkus_http_relative_path }} +hostname-path={{ keycloak_quarkus_path }} +{% endif %} +hostname-admin-url={{ keycloak_quarkus_admin_url }} # Cluster {% if keycloak_quarkus_ha_enabled %} From 8eb518528743fb2da8a15cc655b1e4ee8319eb42 Mon Sep 17 00:00:00 2001 From: Giovanni Toraldo Date: Wed, 25 Oct 2023 10:46:52 +0200 Subject: [PATCH 277/554] use relative path to build health url --- roles/keycloak_quarkus/vars/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/vars/main.yml b/roles/keycloak_quarkus/vars/main.yml index 1b3ef73..c3a9623 100644 --- a/roles/keycloak_quarkus/vars/main.yml +++ b/roles/keycloak_quarkus/vars/main.yml @@ -4,7 +4,7 @@ keycloak: config_dir: "{{ keycloak_quarkus_config_dir }}" bundle: "{{ keycloak_quarkus_archive }}" service_name: "keycloak" - health_url: "http://{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_http_port }}/realms/master/.well-known/openid-configuration" + health_url: "http://{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_http_port }}/{{ keycloak_quarkus_http_relative_path }}{{ '/' if keycloak_quarkus_http_relative_path else '' }}realms/master/.well-known/openid-configuration" cli_path: "{{ keycloak_quarkus_home }}/bin/kcadm.sh" service_user: "{{ keycloak_quarkus_service_user }}" service_group: "{{ keycloak_quarkus_service_group }}" From c8f968a5873e29e014aa7ccd1117f8e2748c8797 Mon Sep 17 00:00:00 2001 From: Giovanni Toraldo Date: Fri, 27 Oct 2023 15:42:42 +0200 Subject: [PATCH 278/554] cleanup vars --- roles/keycloak_quarkus/defaults/main.yml | 10 +++++----- roles/keycloak_quarkus/meta/argument_specs.yml | 14 ++++++-------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 62cd05e..b38e921 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -22,14 +22,14 @@ keycloak_quarkus_configure_firewalld: False ### administrator console password keycloak_quarkus_admin_user: admin -keycloak_quarkus_admin_pass: '' +keycloak_quarkus_admin_pass: keycloak_quarkus_master_realm: master ### Configuration settings keycloak_quarkus_bind_address: 0.0.0.0 keycloak_quarkus_host: localhost keycloak_quarkus_port: -1 -keycloak_quarkus_path: '' +keycloak_quarkus_path: keycloak_quarkus_http_enabled: True keycloak_quarkus_http_port: 8080 keycloak_quarkus_https_port: 8443 @@ -48,11 +48,11 @@ keycloak_quarkus_ha_enabled: False keycloak_quarkus_db_enabled: "{{ True if keycloak_quarkus_ha_enabled else False }}" ### keycloak frontend url -keycloak_quarkus_frontend_url: '' -keycloak_quarkus_admin_url: '' +keycloak_quarkus_frontend_url: +keycloak_quarkus_admin_url: ### path under the application is exposed (set to `auth` for retrocompatibility with pre-quarkus releases) -keycloak_quarkus_http_relative_path: '' +keycloak_quarkus_http_relative_path: # proxy address forwarding mode if the server is behind a reverse proxy. [none, edge, reencrypt, passthrough] keycloak_quarkus_proxy_mode: edge diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 2dd32bb..9855aa5 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -70,13 +70,11 @@ argument_specs: description: "Ensure firewalld is running and configure keycloak ports" type: "bool" keycloak_quarkus_admin_user: - # line 22 of defaults/main.yml default: "admin" description: "Administration console user account" type: "str" keycloak_quarkus_admin_pass: - # line 23 of defaults/main.yml - default: "" + required: true description: "Password of console admin account" type: "str" keycloak_quarkus_master_realm: @@ -98,13 +96,13 @@ argument_specs: description: "The port used by the proxy when exposing the hostname" type: "int" keycloak_quarkus_path: - default: "" + required: false description: "This should be set if proxy uses a different context-path for Keycloak" type: "str" keycloak_quarkus_http_enabled: default: true description: "Enable listener on HTTP port" - type: "bool" + type: "bool" keycloak_quarkus_http_port: # line 29 of defaults/main.yml default: 8080 @@ -153,16 +151,16 @@ argument_specs: description: "Enable auto configuration for database backend" type: "str" keycloak_quarkus_http_relative_path: - default: "auth" + required: false description: "Service context path" type: "str" keycloak_quarkus_frontend_url: + required: false description: "Service public URL" - default: "" type: "str" keycloak_quarkus_admin_url: + required: false description: "Service URL for the admin console" - default: "" type: "str" keycloak_quarkus_metrics_enabled: # line 43 of defaults/main.yml From 880d70ffb988bc51d4db32188bc9ebf9e1e8f171 Mon Sep 17 00:00:00 2001 From: Giovanni Toraldo Date: Tue, 7 Nov 2023 10:21:05 +0100 Subject: [PATCH 279/554] enable https_revproxy test --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 50e1fc4..6e5a542 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,4 +15,4 @@ jobs: with: fqcn: 'middleware_automation/keycloak' molecule_tests: >- - [ "default", "quarkus", "overridexml", "quarkus-devmode" ] + [ "default", "quarkus", "overridexml", "quarkus-devmode", "https_revproxy" ] From 0e510c093a3fbd9d2b964ed39f71eefd968b2522 Mon Sep 17 00:00:00 2001 From: Giovanni Toraldo Date: Mon, 13 Nov 2023 10:07:01 +0100 Subject: [PATCH 280/554] Set default keycloak_quarkus_http_relative_path as per upstream docs --- roles/keycloak_quarkus/README.md | 2 +- roles/keycloak_quarkus/defaults/main.yml | 5 +++-- roles/keycloak_quarkus/meta/argument_specs.yml | 3 ++- roles/keycloak_quarkus/vars/main.yml | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 7108780..30e7cd8 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -37,7 +37,7 @@ Role Defaults |`keycloak_quarkus_java_opts`| Additional JVM options | `-Xms1024m -Xmx2048m` | |`keycloak_quarkus_frontend_url`| Set the base URL for frontend URLs, including scheme, host, port and path | | |`keycloak_quarkus_admin_url`| Set the base URL for accessing the administration console, including scheme, host, port and path | | -|`keycloak_quarkus_http_relative_path` | Service context path | | +|`keycloak_quarkus_http_relative_path` | Set the path relative to / for serving resources. The path must start with a / | `/` | |`keycloak_quarkus_http_enabled`| Enable listener on HTTP port | `True` | |`keycloak_quarkus_https_enabled`| Enable listener on HTTPS port | `False` | |`keycloak_quarkus_key_file`| The file path to a private key in PEM format | `{{ keycloak.home }}/conf/server.key.pem` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index b38e921..e28d16f 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -51,8 +51,9 @@ keycloak_quarkus_db_enabled: "{{ True if keycloak_quarkus_ha_enabled else False keycloak_quarkus_frontend_url: keycloak_quarkus_admin_url: -### path under the application is exposed (set to `auth` for retrocompatibility with pre-quarkus releases) -keycloak_quarkus_http_relative_path: +### Set the path relative to / for serving resources. The path must start with a / +### (set to `/auth` for retrocompatibility with pre-quarkus releases) +keycloak_quarkus_http_relative_path: / # proxy address forwarding mode if the server is behind a reverse proxy. [none, edge, reencrypt, passthrough] keycloak_quarkus_proxy_mode: edge diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 9855aa5..9f5d9de 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -152,7 +152,8 @@ argument_specs: type: "str" keycloak_quarkus_http_relative_path: required: false - description: "Service context path" + default: / + description: "Set the path relative to / for serving resources. The path must start with a /" type: "str" keycloak_quarkus_frontend_url: required: false diff --git a/roles/keycloak_quarkus/vars/main.yml b/roles/keycloak_quarkus/vars/main.yml index c3a9623..0ef6844 100644 --- a/roles/keycloak_quarkus/vars/main.yml +++ b/roles/keycloak_quarkus/vars/main.yml @@ -4,7 +4,7 @@ keycloak: config_dir: "{{ keycloak_quarkus_config_dir }}" bundle: "{{ keycloak_quarkus_archive }}" service_name: "keycloak" - health_url: "http://{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_http_port }}/{{ keycloak_quarkus_http_relative_path }}{{ '/' if keycloak_quarkus_http_relative_path else '' }}realms/master/.well-known/openid-configuration" + health_url: "http://{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_http_port }}{{ keycloak_quarkus_http_relative_path }}{{ '/' if keycloak_quarkus_http_relative_path | length > 1 else '' }}realms/master/.well-known/openid-configuration" cli_path: "{{ keycloak_quarkus_home }}/bin/kcadm.sh" service_user: "{{ keycloak_quarkus_service_user }}" service_group: "{{ keycloak_quarkus_service_group }}" From ea086e8a6231b07074e4dcb5c9bf8b54f2e00e78 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 13 Nov 2023 11:37:18 +0100 Subject: [PATCH 281/554] ci: add missing header to molecule test --- molecule/https_revproxy/verify.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/molecule/https_revproxy/verify.yml b/molecule/https_revproxy/verify.yml index 9d355a6..112a460 100644 --- a/molecule/https_revproxy/verify.yml +++ b/molecule/https_revproxy/verify.yml @@ -20,7 +20,7 @@ - name: Fetch openID config # noqa blocked_modules command-instead-of-module ansible.builtin.shell: | set -o pipefail - curl https://localhost:443/realms/master/.well-known/openid-configuration -k | jq . + curl https://localhost:443/realms/master/.well-known/openid-configuration -H "Host: proxy" -k | jq . args: executable: /bin/bash register: openid_config From 7a1eeec6b60f0e92a5840e803a5491c280495c3d Mon Sep 17 00:00:00 2001 From: Ranabir Chakraborty Date: Mon, 13 Nov 2023 18:18:52 +0530 Subject: [PATCH 282/554] AMWSUP-17 keycloak Ansible Hub documentation link broken --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d93231f..30d6d9e 100644 --- a/README.md +++ b/README.md @@ -44,13 +44,13 @@ A requirement file is provided to install: pip install -r requirements.txt - + ### Included roles * [`keycloak`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak/README.md): role for installing the service. * [`keycloak_realm`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak_realm/README.md): role for configuring a realm, user federation(s), clients and users, in an installed service. * [`keycloak_quarkus`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak_quarkus/README.md): role for installing the quarkus variant of keycloak (>= 17.0.0). - + ## Usage From 49c507173347a8bcab4d470660e36989113d353e Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 13 Nov 2023 16:37:58 +0100 Subject: [PATCH 283/554] ci: fix envvars --- molecule/https_revproxy/molecule.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/molecule/https_revproxy/molecule.yml b/molecule/https_revproxy/molecule.yml index efdebf4..6a8790d 100644 --- a/molecule/https_revproxy/molecule.yml +++ b/molecule/https_revproxy/molecule.yml @@ -41,8 +41,8 @@ provisioner: ansible_python_interpreter: "{{ ansible_playbook_python }}" env: ANSIBLE_FORCE_COLOR: "true" - REDHAT_PRODUCT_DOWNLOAD_CLIENT_ID: "${REDHAT_PRODUCT_DOWNLOAD_CLIENT_ID}" - REDHAT_PRODUCT_DOWNLOAD_CLIENT_SECRET: "${REDHAT_PRODUCT_DOWNLOAD_CLIENT_SECRET}" + REDHAT_PRODUCT_DOWNLOAD_CLIENT_ID: "${PROD_JBOSSNETWORK_API_CLIENTID}" + REDHAT_PRODUCT_DOWNLOAD_CLIENT_SECRET: "${PROD_JBOSSNETWORK_API_SECRET}" verifier: name: ansible scenario: From a0f6a4931f0bdebfe5c9e094253e403091f4ee7b Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 13 Nov 2023 16:47:03 +0100 Subject: [PATCH 284/554] ci: https_revproxy molecule verify step --- molecule/https_revproxy/verify.yml | 2 +- roles/keycloak/tasks/fastpackages.yml | 21 ++++++++--------- roles/keycloak_quarkus/tasks/fastpackages.yml | 23 ++++++++----------- 3 files changed, 20 insertions(+), 26 deletions(-) diff --git a/molecule/https_revproxy/verify.yml b/molecule/https_revproxy/verify.yml index 112a460..2f31ec3 100644 --- a/molecule/https_revproxy/verify.yml +++ b/molecule/https_revproxy/verify.yml @@ -20,7 +20,7 @@ - name: Fetch openID config # noqa blocked_modules command-instead-of-module ansible.builtin.shell: | set -o pipefail - curl https://localhost:443/realms/master/.well-known/openid-configuration -H "Host: proxy" -k | jq . + curl https://localhost:443/realms/master/.well-known/openid-configuration -H "Host: proxy" -k -s | jq . args: executable: /bin/bash register: openid_config diff --git a/roles/keycloak/tasks/fastpackages.yml b/roles/keycloak/tasks/fastpackages.yml index 17d103e..cfd9025 100644 --- a/roles/keycloak/tasks/fastpackages.yml +++ b/roles/keycloak/tasks/fastpackages.yml @@ -1,19 +1,16 @@ --- -- name: Check packages to be installed - block: - - name: "Check if packages are already installed" # noqa command-instead-of-module this runs faster - ansible.builtin.command: "rpm -q {{ packages_list | join(' ') }}" - register: rpm_info - changed_when: rpm_info.failed +- name: "Check if packages are already installed" # noqa command-instead-of-module this runs faster + ansible.builtin.command: "rpm -q {{ packages_list | join(' ') }}" + register: rpm_info + changed_when: False + failed_when: False - rescue: - - name: "Add missing packages to the yum install list" - ansible.builtin.set_fact: - packages_to_install: "{{ packages_to_install | default([]) + rpm_info.stdout_lines | map('regex_findall', 'package (.+) is not installed$') | flatten }}" - when: rpm_info.failed +- name: "Add missing packages to the yum install list" + ansible.builtin.set_fact: + packages_to_install: "{{ packages_to_install | default([]) + rpm_info.stdout_lines | map('regex_findall', 'package (.+) is not installed$') | default([]) | flatten }}" - name: "Install packages: {{ packages_to_install }}" - become: yes + become: True ansible.builtin.yum: name: "{{ packages_to_install }}" state: present diff --git a/roles/keycloak_quarkus/tasks/fastpackages.yml b/roles/keycloak_quarkus/tasks/fastpackages.yml index 78472dd..cfd9025 100644 --- a/roles/keycloak_quarkus/tasks/fastpackages.yml +++ b/roles/keycloak_quarkus/tasks/fastpackages.yml @@ -1,19 +1,16 @@ --- -- name: Check packages to be installed - block: - - name: "Check if packages are already installed" # noqa command-instead-of-module this runs faster - ansible.builtin.command: "rpm -q {{ packages_list | join(' ') }}" - register: rpm_info - changed_when: rpm_info.failed +- name: "Check if packages are already installed" # noqa command-instead-of-module this runs faster + ansible.builtin.command: "rpm -q {{ packages_list | join(' ') }}" + register: rpm_info + changed_when: False + failed_when: False - rescue: - - name: "Add missing packages to the yum install list" - ansible.builtin.set_fact: - packages_to_install: "{{ packages_to_install | default([]) + rpm_info.stdout_lines | map('regex_findall', 'package (.+) is not installed$') | flatten }}" - when: rpm_info.failed +- name: "Add missing packages to the yum install list" + ansible.builtin.set_fact: + packages_to_install: "{{ packages_to_install | default([]) + rpm_info.stdout_lines | map('regex_findall', 'package (.+) is not installed$') | default([]) | flatten }}" -- name: "Install packages: {{ packages_to_install | join(',') }}" - become: yes +- name: "Install packages: {{ packages_to_install }}" + become: True ansible.builtin.yum: name: "{{ packages_to_install }}" state: present From 8af5d6e55605928028600002c945dd6dafa649fa Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 13 Nov 2023 18:10:40 +0100 Subject: [PATCH 285/554] ci: https_revproxy molecule verify step --- molecule/https_revproxy/verify.yml | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/molecule/https_revproxy/verify.yml b/molecule/https_revproxy/verify.yml index 2f31ec3..2c8befb 100644 --- a/molecule/https_revproxy/verify.yml +++ b/molecule/https_revproxy/verify.yml @@ -11,29 +11,23 @@ - ansible_facts.services["keycloak.service"]["state"] == "running" - ansible_facts.services["keycloak.service"]["status"] == "enabled" - - name: Set internal envvar - ansible.builtin.set_fact: - hera_home: "{{ lookup('env', 'HERA_HOME') }}" - - name: Verify openid config + run_once: True block: - name: Fetch openID config # noqa blocked_modules command-instead-of-module - ansible.builtin.shell: | - set -o pipefail - curl https://localhost:443/realms/master/.well-known/openid-configuration -H "Host: proxy" -k -s | jq . - args: - executable: /bin/bash + ansible.builtin.uri: + url: https://localhost:443/realms/master/.well-known/openid-configuration + validate_certs: false + headers: + Host: proxy register: openid_config changed_when: False delegate_to: localhost - name: Verify endpoint URLs ansible.builtin.assert: that: - - (openid_config.stdout | from_json)["backchannel_authentication_endpoint"] == 'https://proxy/realms/master/protocol/openid-connect/ext/ciba/auth' - - (openid_config.stdout | from_json)['issuer'] == 'https://proxy/realms/master' - - (openid_config.stdout | from_json)['authorization_endpoint'] == 'https://proxy/realms/master/protocol/openid-connect/auth' - - (openid_config.stdout | from_json)['token_endpoint'] == 'https://proxy/realms/master/protocol/openid-connect/token' + - openid_config.json["backchannel_authentication_endpoint"] == 'https://proxy/realms/master/protocol/openid-connect/ext/ciba/auth' + - openid_config.json['issuer'] == 'https://proxy/realms/master' + - openid_config.json['authorization_endpoint'] == 'https://proxy/realms/master/protocol/openid-connect/auth' + - openid_config.json['token_endpoint'] == 'https://proxy/realms/master/protocol/openid-connect/token' delegate_to: localhost - when: - - hera_home is defined - - hera_home | length == 0 From efc3e547feee845f99fd3195ad6e682824f5fe77 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 13 Nov 2023 18:24:06 +0100 Subject: [PATCH 286/554] ci: https_revproxy molecule verify step --- molecule/https_revproxy/verify.yml | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/molecule/https_revproxy/verify.yml b/molecule/https_revproxy/verify.yml index 2c8befb..4a69cb2 100644 --- a/molecule/https_revproxy/verify.yml +++ b/molecule/https_revproxy/verify.yml @@ -1,6 +1,6 @@ --- - name: Verify - hosts: all + hosts: instance tasks: - name: Populate service facts ansible.builtin.service_facts: @@ -12,22 +12,17 @@ - ansible_facts.services["keycloak.service"]["status"] == "enabled" - name: Verify openid config - run_once: True block: - name: Fetch openID config # noqa blocked_modules command-instead-of-module ansible.builtin.uri: - url: https://localhost:443/realms/master/.well-known/openid-configuration + url: http://localhost:8080/realms/master/.well-known/openid-configuration validate_certs: false headers: Host: proxy register: openid_config changed_when: False - delegate_to: localhost - name: Verify endpoint URLs ansible.builtin.assert: that: - - openid_config.json["backchannel_authentication_endpoint"] == 'https://proxy/realms/master/protocol/openid-connect/ext/ciba/auth' - openid_config.json['issuer'] == 'https://proxy/realms/master' - openid_config.json['authorization_endpoint'] == 'https://proxy/realms/master/protocol/openid-connect/auth' - - openid_config.json['token_endpoint'] == 'https://proxy/realms/master/protocol/openid-connect/token' - delegate_to: localhost From 143084d726babae6c0611cb9f4508efbea3a5481 Mon Sep 17 00:00:00 2001 From: Jake Muff <67475147+JMuff22@users.noreply.github.com> Date: Thu, 16 Nov 2023 10:19:47 +0200 Subject: [PATCH 287/554] Update admin password variable in keycloak_quarkus.yml --- playbooks/keycloak_quarkus.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/playbooks/keycloak_quarkus.yml b/playbooks/keycloak_quarkus.yml index 5d34c87..5b1122a 100644 --- a/playbooks/keycloak_quarkus.yml +++ b/playbooks/keycloak_quarkus.yml @@ -2,7 +2,7 @@ - name: Playbook for Keycloak X Hosts with HTTPS enabled hosts: all vars: - keycloak_admin_password: "remembertochangeme" + keycloak_quarkus_admin_pass: "remembertochangeme" keycloak_quarkus_host: localhost keycloak_quarkus_port: 8443 keycloak_quarkus_http_relative_path: '' From 2841c7a95148c29c7e7625f04754d0bc77f9021a Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Mon, 20 Nov 2023 17:10:43 +0000 Subject: [PATCH 288/554] Update changelog for release 2.0.0 Signed-off-by: ansible-middleware-core --- CHANGELOG.rst | 16 ++++++++++++++++ changelogs/changelog.yaml | 26 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 8bcfa45..fa6fdea 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,22 @@ middleware_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v2.0.0 +====== + +Minor Changes +------------- + +- Add new parameter for port offset configuration `#124 `_ +- Update Keycloak to version 22.0.5 `#122 `_ + +Breaking Changes / Porting Guide +-------------------------------- + +- Add support for more http-related configs `#115 `_ +- Update minimum ansible-core version > 2.14 `#119 `_ +- keycloak_quarkus: enable config of key store and trust store `#116 `_ + v1.3.0 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index c3b1994..e3ec06e 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -315,3 +315,29 @@ releases: - 112.yaml - 113.yaml release_date: '2023-09-25' + 2.0.0: + changes: + breaking_changes: + - 'Add support for more http-related configs `#115 `_ + + ' + - 'Update minimum ansible-core version > 2.14 `#119 `_ + + ' + - 'keycloak_quarkus: enable config of key store and trust store `#116 `_ + + ' + minor_changes: + - 'Add new parameter for port offset configuration `#124 `_ + + ' + - 'Update Keycloak to version 22.0.5 `#122 `_ + + ' + fragments: + - 115.yaml + - 116.yaml + - 119.yaml + - 122.yaml + - 124.yaml + release_date: '2023-11-20' From e086ee8d29091416fbcb3a36c4f803edd01c0175 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Mon, 20 Nov 2023 17:10:52 +0000 Subject: [PATCH 289/554] Bump version to 2.0.1 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index ef8da0d..bd77fe6 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "2.0.0" +version: "2.0.1" readme: README.md authors: - Romain Pelisse From a439ccab5e067efe73f6ebd0c1cd11c1fd4e3254 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=A2d=20Bouryaln?= <74252238+saadsb20@users.noreply.github.com> Date: Wed, 29 Nov 2023 15:36:00 +0100 Subject: [PATCH 290/554] fix health_url --- roles/keycloak_quarkus/vars/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/vars/main.yml b/roles/keycloak_quarkus/vars/main.yml index 0ef6844..991bdeb 100644 --- a/roles/keycloak_quarkus/vars/main.yml +++ b/roles/keycloak_quarkus/vars/main.yml @@ -4,7 +4,7 @@ keycloak: config_dir: "{{ keycloak_quarkus_config_dir }}" bundle: "{{ keycloak_quarkus_archive }}" service_name: "keycloak" - health_url: "http://{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_http_port }}{{ keycloak_quarkus_http_relative_path }}{{ '/' if keycloak_quarkus_http_relative_path | length > 1 else '' }}realms/master/.well-known/openid-configuration" + health_url: "http://{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_http_port }}/{{ keycloak_quarkus_http_relative_path }}{{ '/' if keycloak_quarkus_http_relative_path | length > 1 else '' }}realms/master/.well-known/openid-configuration" cli_path: "{{ keycloak_quarkus_home }}/bin/kcadm.sh" service_user: "{{ keycloak_quarkus_service_user }}" service_group: "{{ keycloak_quarkus_service_group }}" From 3a1d9099a76cee864d334d0c687b72d594ddbff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=A2d=20Bouryaln?= <74252238+saadsb20@users.noreply.github.com> Date: Thu, 30 Nov 2023 12:01:49 +0100 Subject: [PATCH 291/554] reverte change --- roles/keycloak_quarkus/vars/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/vars/main.yml b/roles/keycloak_quarkus/vars/main.yml index 991bdeb..0ef6844 100644 --- a/roles/keycloak_quarkus/vars/main.yml +++ b/roles/keycloak_quarkus/vars/main.yml @@ -4,7 +4,7 @@ keycloak: config_dir: "{{ keycloak_quarkus_config_dir }}" bundle: "{{ keycloak_quarkus_archive }}" service_name: "keycloak" - health_url: "http://{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_http_port }}/{{ keycloak_quarkus_http_relative_path }}{{ '/' if keycloak_quarkus_http_relative_path | length > 1 else '' }}realms/master/.well-known/openid-configuration" + health_url: "http://{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_http_port }}{{ keycloak_quarkus_http_relative_path }}{{ '/' if keycloak_quarkus_http_relative_path | length > 1 else '' }}realms/master/.well-known/openid-configuration" cli_path: "{{ keycloak_quarkus_home }}/bin/kcadm.sh" service_user: "{{ keycloak_quarkus_service_user }}" service_group: "{{ keycloak_quarkus_service_group }}" From 88935abb62444a7392ec2030a5a5c1b0e95f747b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=A2d=20Bouryaln?= <74252238+saadsb20@users.noreply.github.com> Date: Thu, 30 Nov 2023 12:26:22 +0100 Subject: [PATCH 292/554] Validate relative path validate the relative path ... must begin with / --- roles/keycloak_quarkus/tasks/prereqs.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/roles/keycloak_quarkus/tasks/prereqs.yml b/roles/keycloak_quarkus/tasks/prereqs.yml index 4040d8f..be807df 100644 --- a/roles/keycloak_quarkus/tasks/prereqs.yml +++ b/roles/keycloak_quarkus/tasks/prereqs.yml @@ -6,6 +6,14 @@ quiet: True fail_msg: "The console administrator password is empty or invalid. Please set the keycloak_quarkus_admin_pass variable to a 12+ char long string" success_msg: "{{ 'Console administrator password OK' }}" + +- name: Validate relative path + ansible.builtin.assert: + that: + - keycloak_quarkus_http_relative_path is regex('^/.*') + quiet: True + fail_msg: "the relative path must begin with /" + success_msg: "{{ 'relative path OK' }}" - name: Validate configuration ansible.builtin.assert: From 55c02d7fc5768385c2d60b5219cc7343076df4ae Mon Sep 17 00:00:00 2001 From: Footur <3769085+Footur@users.noreply.github.com> Date: Fri, 1 Dec 2023 10:34:04 +0100 Subject: [PATCH 293/554] Update Keycloak to version 23.0.1 --- molecule/quarkus/prepare.yml | 4 ++-- roles/keycloak_quarkus/README.md | 4 ++-- roles/keycloak_quarkus/defaults/main.yml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index f90564c..44d2492 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -19,13 +19,13 @@ - name: Create conf directory # risky-file-permissions in test user account does not exist yet ansible.builtin.file: state: directory - path: /opt/keycloak/keycloak-22.0.5/conf/ + path: /opt/keycloak/keycloak-23.0.1/conf/ mode: 0755 - name: Copy certificates ansible.builtin.copy: src: "{{ item }}" - dest: "/opt/keycloak/keycloak-22.0.5/conf/{{ item }}" + dest: "/opt/keycloak/keycloak-23.0.1/conf/{{ item }}" mode: 0444 loop: - cert.pem diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index c2338c3..c32054e 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -11,7 +11,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_version`| keycloak.org package version | `22.0.5` | +|`keycloak_quarkus_version`| keycloak.org package version | `23.0.1` | * Service configuration @@ -81,7 +81,7 @@ Role Defaults |:---------|:------------|:---------| |`keycloak_quarkus_offline_install` | Perform an offline install | `False`| |`keycloak_quarkus_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| -|`keycloak_quarkus_version`| keycloak.org package version | `22.0.5` | +|`keycloak_quarkus_version`| keycloak.org package version | `23.0.1` | |`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` | |`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` | |`keycloak_quarkus_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 51ca792..4a89be6 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -1,6 +1,6 @@ --- ### Configuration specific to keycloak -keycloak_quarkus_version: 22.0.5 +keycloak_quarkus_version: 23.0.1 keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip" keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" From d6f020ab44aebc13da10c04660c6869ae7075105 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 1 Dec 2023 12:36:20 +0100 Subject: [PATCH 294/554] linter fixes --- README.md | 4 +- meta/runtime.yml | 2 +- playbooks/keycloak_federation.yml | 14 ++--- playbooks/keycloak_quarkus.yml | 2 +- playbooks/keycloak_realm.yml | 14 ++--- playbooks/rhsso.yml | 2 +- roles/keycloak/README.md | 30 +++++----- roles/keycloak/defaults/main.yml | 24 ++++---- roles/keycloak/meta/argument_specs.yml | 20 +++---- roles/keycloak/meta/main.yml | 6 +- roles/keycloak/tasks/fastpackages.yml | 6 +- roles/keycloak/tasks/firewalld.yml | 10 ++-- roles/keycloak/tasks/install.yml | 56 +++++++++---------- roles/keycloak/tasks/jdbc_driver.yml | 10 ++-- roles/keycloak/tasks/main.yml | 8 +-- roles/keycloak/tasks/prereqs.yml | 8 +-- roles/keycloak/tasks/restart_keycloak.yml | 11 ++-- roles/keycloak/tasks/rhsso_patch.yml | 30 +++++----- roles/keycloak/tasks/start_keycloak.yml | 5 +- roles/keycloak/tasks/stop_keycloak.yml | 4 +- roles/keycloak/tasks/systemd.yml | 16 ++---- roles/keycloak_quarkus/defaults/main.yml | 24 ++++---- .../keycloak_quarkus/meta/argument_specs.yml | 12 ++-- roles/keycloak_quarkus/meta/main.yml | 6 +- roles/keycloak_quarkus/tasks/fastpackages.yml | 6 +- roles/keycloak_quarkus/tasks/firewalld.yml | 8 +-- roles/keycloak_quarkus/tasks/install.yml | 18 +++--- roles/keycloak_quarkus/tasks/main.yml | 12 ++-- roles/keycloak_quarkus/tasks/prereqs.yml | 6 +- roles/keycloak_quarkus/tasks/restart.yml | 5 +- roles/keycloak_quarkus/tasks/start.yml | 5 +- roles/keycloak_quarkus/tasks/systemd.yml | 10 +--- roles/keycloak_realm/defaults/main.yml | 2 +- roles/keycloak_realm/meta/argument_specs.yml | 6 +- roles/keycloak_realm/meta/main.yml | 6 +- roles/keycloak_realm/tasks/main.yml | 6 +- roles/keycloak_realm/tasks/manage_user.yml | 8 +-- .../tasks/manage_user_client_roles.yml | 2 +- .../tasks/manage_user_roles.yml | 4 +- roles/keycloak_realm/vars/main.yml | 4 +- 40 files changed, 212 insertions(+), 220 deletions(-) diff --git a/README.md b/README.md index 30d6d9e..2c04254 100644 --- a/README.md +++ b/README.md @@ -66,11 +66,11 @@ For full service configuration details, refer to the [keycloak role README](http #### Install from controller node (offline) -Making the keycloak zip archive available to the playbook working directory, and setting `keycloak_offline_install` to `True`, allows to skip +Making the keycloak zip archive available to the playbook working directory, and setting `keycloak_offline_install` to `true`, allows to skip the download tasks. The local path for the archive does match the downloaded archive path, so that it is also used as a cache when multiple hosts are provisioned in a cluster. ```yaml -keycloak_offline_install: True +keycloak_offline_install: true ``` diff --git a/meta/runtime.yml b/meta/runtime.yml index 47dc0fb..ce6befd 100644 --- a/meta/runtime.yml +++ b/meta/runtime.yml @@ -1,2 +1,2 @@ --- -requires_ansible: ">=2.14.0" \ No newline at end of file +requires_ansible: ">=2.14.0" diff --git a/playbooks/keycloak_federation.yml b/playbooks/keycloak_federation.yml index f6de6c1..49cb6c0 100644 --- a/playbooks/keycloak_federation.yml +++ b/playbooks/keycloak_federation.yml @@ -55,14 +55,14 @@ - TestClient1Admin - TestClient1User realm: "{{ keycloak_realm }}" - public_client: True + public_client: true web_origins: - http://testclient1origin/application - http://testclient1origin/other users: - - username: TestUser - password: password - client_roles: - - client: TestClient1 - role: TestClient1User - realm: "{{ keycloak_realm }}" + - username: TestUser + password: password + client_roles: + - client: TestClient1 + role: TestClient1User + realm: "{{ keycloak_realm }}" diff --git a/playbooks/keycloak_quarkus.yml b/playbooks/keycloak_quarkus.yml index 5b1122a..13bbce5 100644 --- a/playbooks/keycloak_quarkus.yml +++ b/playbooks/keycloak_quarkus.yml @@ -7,7 +7,7 @@ keycloak_quarkus_port: 8443 keycloak_quarkus_http_relative_path: '' keycloak_quarkus_log: file - keycloak_quarkus_https_key_file_enabled: True + keycloak_quarkus_https_key_file_enabled: true keycloak_quarkus_key_file: conf/key.pem keycloak_quarkus_cert_file: conf/cert.pem roles: diff --git a/playbooks/keycloak_realm.yml b/playbooks/keycloak_realm.yml index f03edab..99b2ef8 100644 --- a/playbooks/keycloak_realm.yml +++ b/playbooks/keycloak_realm.yml @@ -10,17 +10,17 @@ - TestClient1Admin - TestClient1User realm: TestRealm - public_client: True + public_client: true web_origins: - http://testclient1origin/application - http://testclient1origin/other users: - - username: TestUser - password: password - client_roles: - - client: TestClient1 - role: TestClient1User - realm: TestRealm + - username: TestUser + password: password + client_roles: + - client: TestClient1 + role: TestClient1User + realm: TestRealm roles: - role: middleware_automation.keycloak.keycloak_realm keycloak_realm: TestRealm diff --git a/playbooks/rhsso.yml b/playbooks/rhsso.yml index ea67158..ea61f66 100644 --- a/playbooks/rhsso.yml +++ b/playbooks/rhsso.yml @@ -3,6 +3,6 @@ hosts: sso vars: keycloak_admin_password: "remembertochangeme" - sso_enable: True + sso_enable: true roles: - middleware_automation.keycloak.keycloak diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index 17149f7..c4dfedc 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -39,7 +39,7 @@ Versions Patching -------- -When variable `keycloak_rhsso_apply_patches` is `True` (default: `False`), the role will automatically apply the latest cumulative patch for the selected base version. +When variable `keycloak_rhsso_apply_patches` is `true` (default: `false`), the role will automatically apply the latest cumulative patch for the selected base version. | RH-SSO VERSION | Release Date | RH-SSO LATEST CP | Notes | |:---------------|:------------------|:-----------------|:----------------| @@ -55,7 +55,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:---------| |`keycloak_ha_enabled`| Enable auto configuration for database backend, clustering and remote caches on infinispan | `False` | -|`keycloak_ha_discovery`| Discovery protocol for HA cluster members | `JDBC_PING` if keycloak_db_enabled else `TCPPING` | +|`keycloak_ha_discovery`| Discovery protocol for HA cluster members | `JDBC_PING` if `keycloak_db_enabled` else `TCPPING` | |`keycloak_db_enabled`| Enable auto configuration for database backend | `True` if `keycloak_ha_enabled` is True, else `False` | |`keycloak_remote_cache_enabled`| Enable remote cache store when in clustered ha configurations | `True` if `keycloak_ha_enabled` else `False` | |`keycloak_admin_user`| Administration console user account | `admin` | @@ -68,19 +68,19 @@ Role Defaults |`keycloak_jgroups_port`| jgroups cluster tcp port | `7600` | |`keycloak_management_http_port`| Management port | `9990` | |`keycloak_management_https_port`| TLS management port | `9993` | -|`keycloak_prefer_ipv4`| Prefer IPv4 stack and addresses for port binding | `True` | +|`keycloak_prefer_ipv4`| Prefer IPv4 stack and addresses for port binding | `true` | |`keycloak_config_standalone_xml`| filename for configuration | `keycloak.xml` | |`keycloak_service_user`| posix account username | `keycloak` | |`keycloak_service_group`| posix account group | `keycloak` | -|`keycloak_service_restart_always`| systemd restart always behavior activation | `False` -|`keycloak_service_restart_on_failure`| systemd restart on-failure behavior activation | `False` +|`keycloak_service_restart_always`| systemd restart always behavior activation | `False` | +|`keycloak_service_restart_on_failure`| systemd restart on-failure behavior activation | `False` | |`keycloak_service_startlimitintervalsec`| systemd StartLimitIntervalSec | `300` | |`keycloak_service_startlimitburst`| systemd StartLimitBurst | `5` | |`keycloak_service_restartsec`| systemd RestartSec | `10s` | |`keycloak_service_pidfile`| pid file path for service | `/run/keycloak/keycloak.pid` | |`keycloak_features` | List of `name`/`status` pairs of features (also known as profiles on RH-SSO) to `enable` or `disable`, example: `[ { name: 'docker', status: 'enabled' } ]` | `[]` |`keycloak_jvm_package`| RHEL java package runtime | `java-1.8.0-openjdk-headless` | -|`keycloak_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_jvm_package RPM path | `None` | +|`keycloak_java_home`| `JAVA_HOME` of installed JRE, leave empty for using RPM path at `keycloak_jvm_package` | `None` | |`keycloak_java_opts`| Additional JVM options | `-Xms1024m -Xmx2048m` | @@ -88,12 +88,12 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:---------| -|`keycloak_offline_install` | perform an offline install | `False`| +|`keycloak_offline_install` | perform an offline install | `false`| |`keycloak_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| |`keycloak_version`| keycloak.org package version | `18.0.2` | |`keycloak_dest`| Installation root path | `/opt/keycloak` | |`keycloak_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_version }}/{{ keycloak_archive }}` | -|`keycloak_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` | +|`keycloak_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `false` | * Miscellaneous configuration @@ -110,13 +110,13 @@ Role Defaults |`keycloak_config_override_template` | Path to custom template for standalone.xml configuration | `''` | |`keycloak_auth_realm` | Name for rest authentication realm | `master` | |`keycloak_auth_client` | Authentication client for configuration REST calls | `admin-cli` | -|`keycloak_force_install` | Remove pre-existing versions of service | `False` | +|`keycloak_force_install` | Remove pre-existing versions of service | `false` | |`keycloak_url` | URL for configuration rest calls | `http://{{ keycloak_host }}:{{ keycloak_http_port + keycloak_jboss_port_offset }}` | |`keycloak_management_url` | URL for management console rest calls | `http://{{ keycloak_host }}:{{ keycloak_management_http_port + keycloak_jboss_port_offset }}` | -|`keycloak_frontend_url_force` | Force backend requests to use the frontend URL | `False` | -|`keycloak_db_background_validation` | Enable background validation of database connection | `False` | +|`keycloak_frontend_url_force` | Force backend requests to use the frontend URL | `false` | +|`keycloak_db_background_validation` | Enable background validation of database connection | `false` | |`keycloak_db_background_validation_millis`| How frequenly the connection pool is validated in the background | `10000` if background validation enabled | -|`keycloak_db_background_validate_on_match` | Enable validate on match for database connections | `False` | +|`keycloak_db_background_validate_on_match` | Enable validate on match for database connections | `false` | |`keycloak_frontend_url` | frontend URL for keycloak endpoint | `http://localhost:8080/auth/` | |`keycloak_log_target`| Set the destination of the keycloak log folder link | `/var/log/keycloak` | @@ -132,7 +132,7 @@ The following are a set of _required_ variables for the role: |`keycloak_frontend_url` | frontend URL for keycloak endpoint | `http://localhost:8080/auth/` | -The following parameters are _required_ only when `keycloak_ha_enabled` is True: +The following parameters are _required_ only when `keycloak_ha_enabled` is true: | Variable | Description | Default | |:---------|:------------|:--------| @@ -150,7 +150,7 @@ The following parameters are _required_ only when `keycloak_ha_enabled` is True: |`keycloak_infinispan_trust_store_password`| Password for opening truststore | `changeit` | -The following parameters are _required_ only when `keycloak_db_enabled` is True: +The following parameters are _required_ only when `keycloak_db_enabled` is true: | Variable | Description | Default | |:---------|:------------|:---------| @@ -196,7 +196,7 @@ Example Playbook name: keycloak vars: keycloak_admin_password: "remembertochangeme" - keycloak_offline_install: True + keycloak_offline_install: true # This should be the filename of keycloak archive on Ansible node: keycloak-16.1.0.zip ``` diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 2b5cc35..7ffaec6 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -5,7 +5,7 @@ keycloak_archive: "keycloak-legacy-{{ keycloak_version }}.zip" keycloak_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_version }}/{{ keycloak_archive }}" keycloak_download_url_9x: "https://downloads.jboss.org/keycloak/{{ keycloak_version }}/{{ keycloak_archive }}" keycloak_installdir: "{{ keycloak_dest }}/keycloak-{{ keycloak_version }}" -keycloak_offline_install: False +keycloak_offline_install: false ### Install location and service settings keycloak_jvm_package: java-1.8.0-openjdk-headless @@ -26,13 +26,13 @@ keycloak_service_name: keycloak keycloak_service_desc: Keycloak keycloak_service_start_delay: 10 keycloak_service_start_retries: 25 -keycloak_service_restart_always: False -keycloak_service_restart_on_failure: False +keycloak_service_restart_always: false +keycloak_service_restart_on_failure: false keycloak_service_startlimitintervalsec: "300" keycloak_service_startlimitburst: "5" keycloak_service_restartsec: "10s" -keycloak_configure_firewalld: False +keycloak_configure_firewalld: false ### administrator console password keycloak_admin_password: '' @@ -49,11 +49,11 @@ keycloak_management_port_bind_address: 127.0.0.1 keycloak_management_http_port: 9990 keycloak_management_https_port: 9993 keycloak_java_opts: "-Xms1024m -Xmx2048m" -keycloak_prefer_ipv4: True +keycloak_prefer_ipv4: true keycloak_features: [] ### Enable configuration for database backend, clustering and remote caches on infinispan -keycloak_ha_enabled: False +keycloak_ha_enabled: false ### Enable database configuration, must be enabled when HA is configured keycloak_db_enabled: "{{ True if keycloak_ha_enabled else False }}" ### Discovery protocol for ha cluster members, valus [ 'JDBC_PING', 'TCPPING' ] @@ -66,7 +66,7 @@ keycloak_admin_user: admin keycloak_auth_realm: master keycloak_auth_client: admin-cli -keycloak_force_install: False +keycloak_force_install: false ### mod_cluster reverse proxy list keycloak_modcluster_enabled: "{{ True if keycloak_ha_enabled else False }}" @@ -78,7 +78,7 @@ keycloak_modcluster_urls: ### keycloak frontend url keycloak_frontend_url: http://localhost:8080/auth/ -keycloak_frontend_url_force: False +keycloak_frontend_url_force: false keycloak_admin_url: ### infinispan remote caches access (hotrod) @@ -86,7 +86,7 @@ keycloak_infinispan_user: supervisor keycloak_infinispan_pass: supervisor keycloak_infinispan_url: localhost keycloak_infinispan_sasl_mechanism: SCRAM-SHA-512 -keycloak_infinispan_use_ssl: False +keycloak_infinispan_use_ssl: false # if ssl is enabled, import ispn server certificate here keycloak_infinispan_trust_store_path: /etc/pki/java/cacerts keycloak_infinispan_trust_store_password: changeit @@ -97,9 +97,9 @@ keycloak_jdbc_engine: postgres keycloak_db_user: keycloak-user keycloak_db_pass: keycloak-pass ## connection validation -keycloak_db_background_validation: False +keycloak_db_background_validation: false keycloak_db_background_validation_millis: "{{ 10000 if keycloak_db_background_validation else 0 }}" -keycloak_db_background_validate_on_match: False +keycloak_db_background_validate_on_match: false keycloak_jdbc_url: "{{ keycloak_default_jdbc[keycloak_jdbc_engine].url }}" keycloak_jdbc_driver_version: "{{ keycloak_default_jdbc[keycloak_jdbc_engine].version }}" # override the variables above, following defaults show minimum supported versions @@ -114,7 +114,7 @@ keycloak_default_jdbc: url: 'jdbc:sqlserver://localhost:1433;databaseName=keycloak;' version: 12.2.0 # role specific vars -keycloak_no_log: True +keycloak_no_log: true ### logging configuration keycloak_log_target: /var/log/keycloak diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 2e93667..acdb309 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -214,7 +214,7 @@ argument_specs: description: "Frontend URL for keycloak endpoints when a reverse proxy is used" type: "str" keycloak_frontend_url_force: - default: False + default: false description: "Force backend requests to use the frontend URL" type: "bool" keycloak_infinispan_user: @@ -337,7 +337,7 @@ argument_specs: description: "Enable remote cache store when in clustered ha configurations" type: "bool" keycloak_db_background_validation: - default: False + default: false description: "Enable background validation of database connection" type: "bool" keycloak_db_background_validation_millis: @@ -345,19 +345,19 @@ argument_specs: description: "How frequenly the connection pool is validated in the background" type: 'int' keycloak_db_background_validate_on_match: - default: False + default: false description: "Enable validate on match for database connections" type: "bool" keycloak_db_valid_conn_sql: - required: False + required: false description: "Override the default database connection validation query sql" type: "str" keycloak_admin_url: - required: False + required: false description: "Override the default administration endpoint URL" type: "str" keycloak_jgroups_subnet: - required: False + required: false description: "Override the subnet match for jgroups cluster formation; if not defined, it will be inferred from local machine route configuration" type: "str" keycloak_log_target: @@ -383,15 +383,15 @@ argument_specs: description: "Installation path for Red Hat SSO" type: "str" sso_apply_patches: - default: False + default: false description: "Install Red Hat SSO most recent cumulative patch" type: "bool" sso_enable: - default: True + default: true description: "Enable Red Hat Single Sign-on installation" type: "str" sso_offline_install: - default: False + default: false description: "Perform an offline install" type: "bool" sso_service_name: @@ -403,7 +403,7 @@ argument_specs: description: "systemd description for Red Hat Single Sign-On" type: "str" sso_patch_version: - required: False + required: false description: "Red Hat Single Sign-On latest cumulative patch version to apply; defaults to latest version when sso_apply_patches is True" type: "str" sso_patch_bundle: diff --git a/roles/keycloak/meta/main.yml b/roles/keycloak/meta/main.yml index 5a121ba..a70e9f1 100644 --- a/roles/keycloak/meta/main.yml +++ b/roles/keycloak/meta/main.yml @@ -15,9 +15,9 @@ galaxy_info: min_ansible_version: "2.14" platforms: - - name: EL - versions: - - "8" + - name: EL + versions: + - "8" galaxy_tags: - keycloak diff --git a/roles/keycloak/tasks/fastpackages.yml b/roles/keycloak/tasks/fastpackages.yml index cfd9025..c9085f8 100644 --- a/roles/keycloak/tasks/fastpackages.yml +++ b/roles/keycloak/tasks/fastpackages.yml @@ -2,15 +2,15 @@ - name: "Check if packages are already installed" # noqa command-instead-of-module this runs faster ansible.builtin.command: "rpm -q {{ packages_list | join(' ') }}" register: rpm_info - changed_when: False - failed_when: False + changed_when: false + failed_when: false - name: "Add missing packages to the yum install list" ansible.builtin.set_fact: packages_to_install: "{{ packages_to_install | default([]) + rpm_info.stdout_lines | map('regex_findall', 'package (.+) is not installed$') | default([]) | flatten }}" - name: "Install packages: {{ packages_to_install }}" - become: True + become: true ansible.builtin.yum: name: "{{ packages_to_install }}" state: present diff --git a/roles/keycloak/tasks/firewalld.yml b/roles/keycloak/tasks/firewalld.yml index 0cf4ee3..f48f580 100644 --- a/roles/keycloak/tasks/firewalld.yml +++ b/roles/keycloak/tasks/firewalld.yml @@ -6,19 +6,19 @@ - firewalld - name: Enable and start the firewalld service - become: yes + become: true ansible.builtin.systemd: name: firewalld - enabled: yes + enabled: true state: started -- name: "Configure firewall for {{ keycloak.service_name }} ports" - become: yes +- name: "Configure firewall ports for {{ keycloak.service_name }}" + become: true ansible.posix.firewalld: port: "{{ item }}" permanent: true state: enabled - immediate: yes + immediate: true loop: - "{{ keycloak_http_port }}/tcp" - "{{ keycloak_https_port }}/tcp" diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index a2467d3..67b98cd 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -11,7 +11,7 @@ quiet: true - name: Check for an existing deployment - become: yes + become: true ansible.builtin.stat: path: "{{ keycloak_jboss_home }}" register: existing_deploy @@ -20,32 +20,32 @@ when: existing_deploy.stat.exists and keycloak_force_install | bool block: - name: "Stop the old {{ keycloak.service_name }} service" - become: yes - ignore_errors: yes + become: true + failed_when: false ansible.builtin.systemd: name: keycloak state: stopped - name: "Remove the old {{ keycloak.service_name }} deployment" - become: yes + become: true ansible.builtin.file: path: "{{ keycloak_jboss_home }}" state: absent - name: Check for an existing deployment after possible forced removal - become: yes + become: true ansible.builtin.stat: path: "{{ keycloak_jboss_home }}" -- name: "Create {{ keycloak.service_name }} service user/group" - become: yes +- name: "Create service user/group for {{ keycloak.service_name }}" + become: true ansible.builtin.user: name: "{{ keycloak_service_user }}" home: /opt/keycloak system: yes create_home: no -- name: "Create {{ keycloak.service_name }} install location" - become: yes +- name: "Create install location for {{ keycloak.service_name }}" + become: true ansible.builtin.file: dest: "{{ keycloak_dest }}" state: directory @@ -54,7 +54,7 @@ mode: 0750 - name: Create pidfile folder - become: yes + become: true ansible.builtin.file: dest: "{{ keycloak_service_pidfile | dirname }}" state: directory @@ -68,7 +68,7 @@ archive: "{{ keycloak_dest }}/{{ keycloak.bundle }}" - name: Check download archive path - become: yes + become: true ansible.builtin.stat: path: "{{ archive }}" register: archive_path @@ -86,7 +86,7 @@ dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" mode: 0644 delegate_to: localhost - run_once: yes + run_once: true when: - archive_path is defined - archive_path.stat is defined @@ -96,7 +96,7 @@ - name: Perform download from RHN using JBoss Network API delegate_to: localhost - run_once: yes + run_once: true when: - archive_path is defined - archive_path.stat is defined @@ -114,13 +114,13 @@ register: rhn_products no_log: "{{ omit_rhn_output | default(true) }}" delegate_to: localhost - run_once: yes + run_once: true - name: Determine install zipfile from search results ansible.builtin.set_fact: rhn_filtered_products: "{{ rhn_products.results | selectattr('file_path', 'match', '[^/]*/' + sso_archive + '$') }}" delegate_to: localhost - run_once: yes + run_once: true - name: Download Red Hat Single Sign-On middleware_automation.common.product_download: # noqa risky-file-permissions delegated, uses controller host user @@ -130,7 +130,7 @@ dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" no_log: "{{ omit_rhn_output | default(true) }}" delegate_to: localhost - run_once: yes + run_once: true - name: Download rhsso archive from alternate location ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user @@ -138,7 +138,7 @@ dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" mode: 0644 delegate_to: localhost - run_once: yes + run_once: true when: - archive_path is defined - archive_path.stat is defined @@ -166,23 +166,23 @@ - not archive_path.stat.exists - local_archive_path.stat is defined - local_archive_path.stat.exists - become: yes + become: true - name: "Check target directory: {{ keycloak.home }}" ansible.builtin.stat: path: "{{ keycloak.home }}" register: path_to_workdir - become: yes + become: true - name: "Extract {{ keycloak_service_desc }} archive on target" ansible.builtin.unarchive: - remote_src: yes + remote_src: true src: "{{ archive }}" dest: "{{ keycloak_dest }}" creates: "{{ keycloak.home }}" owner: "{{ keycloak_service_user }}" group: "{{ keycloak_service_group }}" - become: yes + become: true when: - new_version_downloaded.changed or not path_to_workdir.stat.exists notify: @@ -200,13 +200,13 @@ owner: "{{ keycloak_service_user }}" group: "{{ keycloak_service_group }}" recurse: true - become: yes + become: true changed_when: false - name: Ensure permissions are correct on existing deploy ansible.builtin.command: chown -R "{{ keycloak_service_user }}:{{ keycloak_service_group }}" "{{ keycloak.home }}" when: keycloak_service_runas - become: yes + become: true changed_when: false # driver and configuration @@ -215,7 +215,7 @@ when: keycloak_jdbc[keycloak_jdbc_engine].enabled - name: "Deploy custom {{ keycloak.service_name }} config to {{ keycloak_config_path_to_standalone_xml }} from {{ keycloak_config_override_template }}" - become: yes + become: true ansible.builtin.template: src: "templates/{{ keycloak_config_override_template }}" dest: "{{ keycloak_config_path_to_standalone_xml }}" @@ -227,7 +227,7 @@ when: keycloak_config_override_template | length > 0 - name: "Deploy standalone {{ keycloak.service_name }} config to {{ keycloak_config_path_to_standalone_xml }}" - become: yes + become: true ansible.builtin.template: src: templates/standalone.xml.j2 dest: "{{ keycloak_config_path_to_standalone_xml }}" @@ -255,7 +255,7 @@ when: keycloak_ha_enabled and keycloak_ha_discovery == 'TCPPING' - name: "Deploy HA {{ keycloak.service_name }} config to {{ keycloak_config_path_to_standalone_xml }}" - become: yes + become: true ansible.builtin.template: src: templates/standalone-ha.xml.j2 dest: "{{ keycloak_config_path_to_standalone_xml }}" @@ -270,7 +270,7 @@ - keycloak_config_override_template | length == 0 - name: "Deploy HA {{ keycloak.service_name }} config with infinispan remote cache store to {{ keycloak_config_path_to_standalone_xml }}" - become: yes + become: true ansible.builtin.template: src: templates/standalone-infinispan.xml.j2 dest: "{{ keycloak_config_path_to_standalone_xml }}" @@ -285,7 +285,7 @@ - keycloak_config_override_template | length == 0 - name: "Deploy profile.properties file to {{ keycloak_config_path_to_properties }}" - become: yes + become: true ansible.builtin.template: src: keycloak-profile.properties.j2 dest: "{{ keycloak_config_path_to_properties }}" diff --git a/roles/keycloak/tasks/jdbc_driver.yml b/roles/keycloak/tasks/jdbc_driver.yml index 7dfaabc..1b0a1ec 100644 --- a/roles/keycloak/tasks/jdbc_driver.yml +++ b/roles/keycloak/tasks/jdbc_driver.yml @@ -3,17 +3,17 @@ ansible.builtin.stat: path: "{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_dir }}" register: dest_path - become: yes + become: true - name: "Set up module dir for JDBC Driver {{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_name }}" ansible.builtin.file: path: "{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_dir }}" state: directory - recurse: yes + recurse: true owner: "{{ keycloak_service_user }}" group: "{{ keycloak_service_group }}" mode: 0750 - become: yes + become: true when: - not dest_path.stat.exists @@ -24,7 +24,7 @@ group: "{{ keycloak_service_group }}" owner: "{{ keycloak_service_user }}" mode: 0640 - become: yes + become: true - name: "Deploy module.xml for JDBC Driver" ansible.builtin.template: @@ -33,4 +33,4 @@ group: "{{ keycloak_service_group }}" owner: "{{ keycloak_service_user }}" mode: 0640 - become: yes + become: true diff --git a/roles/keycloak/tasks/main.yml b/roles/keycloak/tasks/main.yml index 7fe0222..cba503b 100644 --- a/roles/keycloak/tasks/main.yml +++ b/roles/keycloak/tasks/main.yml @@ -35,7 +35,7 @@ state: link src: "{{ keycloak_jboss_home }}/standalone/log" dest: "{{ keycloak_log_target }}" - become: yes + become: true - name: Set admin credentials and restart if not already created block: @@ -44,7 +44,7 @@ url: "{{ keycloak_url }}/auth/realms/master/protocol/openid-connect/token" method: POST body: "client_id={{ keycloak_auth_client }}&username={{ keycloak_admin_user }}&password={{ keycloak_admin_password }}&grant_type=password" - validate_certs: no + validate_certs: false register: keycloak_auth_response until: keycloak_auth_response.status == 200 retries: 2 @@ -58,8 +58,8 @@ - "-rmaster" - "-u{{ keycloak_admin_user }}" - "-p{{ keycloak_admin_password }}" - changed_when: yes - become: yes + changed_when: true + become: true - name: "Restart {{ keycloak.service_name }}" ansible.builtin.include_tasks: tasks/restart_keycloak.yml - name: "Wait until {{ keycloak.service_name }} becomes active {{ keycloak.health_url }}" diff --git a/roles/keycloak/tasks/prereqs.yml b/roles/keycloak/tasks/prereqs.yml index 02370c7..aad814b 100644 --- a/roles/keycloak/tasks/prereqs.yml +++ b/roles/keycloak/tasks/prereqs.yml @@ -3,7 +3,7 @@ ansible.builtin.assert: that: - keycloak_admin_password | length > 12 - quiet: True + quiet: true fail_msg: "The console administrator password is empty or invalid. Please set the keycloak_admin_password variable to a 12+ char long string" success_msg: "{{ 'Console administrator password OK' }}" @@ -11,7 +11,7 @@ ansible.builtin.assert: that: - (keycloak_ha_enabled and keycloak_db_enabled) or (not keycloak_ha_enabled and keycloak_db_enabled) or (not keycloak_ha_enabled and not keycloak_db_enabled) - quiet: True + quiet: true fail_msg: "Cannot install HA setup without a backend database service. Check keycloak_ha_enabled and keycloak_db_enabled" success_msg: "{{ 'Configuring HA' if keycloak_ha_enabled else 'Configuring standalone' }}" @@ -20,7 +20,7 @@ that: - (rhn_username is defined and sso_enable is defined and sso_enable) or not sso_enable is defined or not sso_enable or keycloak_offline_install - (rhn_password is defined and sso_enable is defined and sso_enable) or not sso_enable is defined or not sso_enable or keycloak_offline_install - quiet: True + quiet: true fail_msg: "Cannot install Red Hat SSO without RHN credentials. Check rhn_username and rhn_password are defined" success_msg: "Installing {{ keycloak_service_desc }}" @@ -31,7 +31,7 @@ - keycloak_jdbc_url | length > 0 - keycloak_db_user | length > 0 - keycloak_db_pass | length > 0 - quiet: True + quiet: true fail_msg: "Configuration for the JDBC persistence is invalid or incomplete" success_msg: "Configuring JDBC persistence using {{ keycloak_jdbc_engine }} database" when: keycloak_db_enabled diff --git a/roles/keycloak/tasks/restart_keycloak.yml b/roles/keycloak/tasks/restart_keycloak.yml index a0ae41f..bae91cd 100644 --- a/roles/keycloak/tasks/restart_keycloak.yml +++ b/roles/keycloak/tasks/restart_keycloak.yml @@ -2,11 +2,12 @@ - name: "Restart and enable {{ keycloak.service_name }} service" ansible.builtin.systemd: name: keycloak - enabled: yes + enabled: true state: restarted - become: yes + daemon_reload: true + become: true delegate_to: "{{ ansible_play_hosts | first }}" - run_once: True + run_once: true - name: "Wait until {{ keycloak.service_name }} becomes active {{ keycloak.health_url }}" ansible.builtin.uri: @@ -14,7 +15,7 @@ register: keycloak_status until: keycloak_status.status == 200 delegate_to: "{{ ansible_play_hosts | first }}" - run_once: True + run_once: true retries: "{{ keycloak_service_start_retries }}" delay: "{{ keycloak_service_start_delay }}" @@ -23,5 +24,5 @@ name: keycloak enabled: yes state: restarted - become: yes + become: true when: inventory_hostname != ansible_play_hosts | first diff --git a/roles/keycloak/tasks/rhsso_patch.yml b/roles/keycloak/tasks/rhsso_patch.yml index b03b55c..b0e04da 100644 --- a/roles/keycloak/tasks/rhsso_patch.yml +++ b/roles/keycloak/tasks/rhsso_patch.yml @@ -12,11 +12,11 @@ path: "{{ patch_archive }}" register: patch_archive_path when: sso_patch_version is defined - become: yes + become: true - name: Perform patch download from RHN via JBossNetwork API delegate_to: localhost - run_once: yes + run_once: true when: - sso_enable is defined and sso_enable - not keycloak_offline_install @@ -32,21 +32,21 @@ register: rhn_products no_log: "{{ omit_rhn_output | default(true) }}" delegate_to: localhost - run_once: yes + run_once: true - name: Determine patch versions list ansible.builtin.set_fact: - filtered_versions: "{{ rhn_products.results | map(attribute='file_path') | select('match', '^[^/]*/rh-sso-.*[0-9]*[.][0-9]*[.][0-9]*.*$') | map('regex_replace','[^/]*/rh-sso-([0-9]*[.][0-9]*[.][0-9]*)-.*','\\1' ) | list | unique }}" + filtered_versions: "{{ rhn_products.results | map(attribute='file_path') | select('match', '^[^/]*/rh-sso-.*[0-9]*[.][0-9]*[.][0-9]*.*$') | map('regex_replace', '[^/]*/rh-sso-([0-9]*[.][0-9]*[.][0-9]*)-.*', '\\1') | list | unique }}" when: sso_patch_version is not defined or sso_patch_version | length == 0 delegate_to: localhost - run_once: yes + run_once: true - name: Determine latest version ansible.builtin.set_fact: sso_latest_version: "{{ filtered_versions | middleware_automation.common.version_sort | last }}" when: sso_patch_version is not defined or sso_patch_version | length == 0 delegate_to: localhost - run_once: yes + run_once: true - name: Determine install zipfile from search results ansible.builtin.set_fact: @@ -55,7 +55,7 @@ patch_version: "{{ sso_latest_version }}" when: sso_patch_version is not defined or sso_patch_version | length == 0 delegate_to: localhost - run_once: yes + run_once: true - name: "Determine selected patch from supplied version: {{ sso_patch_version }}" ansible.builtin.set_fact: @@ -64,7 +64,7 @@ patch_version: "{{ sso_patch_version }}" when: sso_patch_version is defined delegate_to: localhost - run_once: yes + run_once: true - name: Download Red Hat Single Sign-On patch middleware_automation.common.product_download: # noqa risky-file-permissions delegated, uses controller host user @@ -74,7 +74,7 @@ dest: "{{ local_path.stat.path }}/{{ patch_bundle }}" no_log: "{{ omit_rhn_output | default(true) }}" delegate_to: localhost - run_once: yes + run_once: true - name: Set download patch archive path ansible.builtin.set_fact: @@ -84,7 +84,7 @@ ansible.builtin.stat: path: "{{ patch_archive }}" register: patch_archive_path - become: yes + become: true ## copy and unpack - name: Copy patch archive to target nodes @@ -99,7 +99,7 @@ - not patch_archive_path.stat.exists - local_archive_path.stat is defined - local_archive_path.stat.exists - become: yes + become: true - name: "Check installed patches" ansible.builtin.include_tasks: rhsso_cli.yml @@ -107,7 +107,7 @@ query: "patch info" args: apply: - become: yes + become: true become_user: "{{ keycloak_service_user }}" - name: "Perform patching" @@ -122,7 +122,7 @@ query: "patch apply {{ patch_archive }}" args: apply: - become: yes + become: true become_user: "{{ keycloak_service_user }}" - name: "Restart server to ensure patch content is running" @@ -133,7 +133,7 @@ - cli_result.rc == 0 args: apply: - become: yes + become: true become_user: "{{ keycloak_service_user }}" - name: "Wait until {{ keycloak.service_name }} becomes active {{ keycloak.health_url }}" @@ -150,7 +150,7 @@ query: "patch info" args: apply: - become: yes + become: true become_user: "{{ keycloak_service_user }}" - name: "Verify installed patch version" diff --git a/roles/keycloak/tasks/start_keycloak.yml b/roles/keycloak/tasks/start_keycloak.yml index 524df80..5aed248 100644 --- a/roles/keycloak/tasks/start_keycloak.yml +++ b/roles/keycloak/tasks/start_keycloak.yml @@ -2,9 +2,10 @@ - name: "Start {{ keycloak.service_name }} service" ansible.builtin.systemd: name: keycloak - enabled: yes + enabled: true state: started - become: yes + daemon_reload: true + become: true - name: "Wait until {{ keycloak.service_name }} becomes active {{ keycloak.health_url }}" ansible.builtin.uri: diff --git a/roles/keycloak/tasks/stop_keycloak.yml b/roles/keycloak/tasks/stop_keycloak.yml index fd87802..7f30433 100644 --- a/roles/keycloak/tasks/stop_keycloak.yml +++ b/roles/keycloak/tasks/stop_keycloak.yml @@ -2,6 +2,6 @@ - name: "Stop {{ keycloak.service_name }}" ansible.builtin.systemd: name: keycloak - enabled: yes + enabled: true state: stopped - become: yes + become: true diff --git a/roles/keycloak/tasks/systemd.yml b/roles/keycloak/tasks/systemd.yml index 4b24822..cd58345 100644 --- a/roles/keycloak/tasks/systemd.yml +++ b/roles/keycloak/tasks/systemd.yml @@ -1,6 +1,6 @@ --- - name: "Configure {{ keycloak.service_name }} service script wrapper" - become: yes + become: true ansible.builtin.template: src: keycloak-service.sh.j2 dest: "{{ keycloak_dest }}/keycloak-service.sh" @@ -15,7 +15,7 @@ rpm_java_home: "/etc/alternatives/jre_{{ keycloak_jvm_package | regex_search('(?<=java-)[0-9.]+') }}" - name: "Configure sysconfig file for {{ keycloak.service_name }} service" - become: yes + become: true ansible.builtin.template: src: keycloak-sysconfig.j2 dest: /etc/sysconfig/keycloak @@ -34,20 +34,14 @@ owner: root group: root mode: 0644 - become: yes + become: true register: systemdunit notify: - restart keycloak -- name: Reload systemd - become: yes - ansible.builtin.systemd: - daemon_reload: yes - when: systemdunit.changed - - name: "Start and wait for {{ keycloak.service_name }} service (first node db)" ansible.builtin.include_tasks: start_keycloak.yml - run_once: yes + run_once: true when: keycloak_db_enabled - name: "Start and wait for {{ keycloak.service_name }} service (remaining nodes)" @@ -56,7 +50,7 @@ - name: Check service status ansible.builtin.command: "systemctl status keycloak" register: keycloak_service_status - changed_when: False + changed_when: false - name: Verify service status ansible.builtin.assert: diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 51ca792..adf918d 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -6,7 +6,7 @@ keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/do keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" # whether to install from local archive -keycloak_quarkus_offline_install: False +keycloak_quarkus_offline_install: false ### Install location and service settings keycloak_quarkus_jvm_package: java-17-openjdk-headless @@ -14,11 +14,11 @@ keycloak_quarkus_java_home: keycloak_quarkus_dest: /opt/keycloak keycloak_quarkus_home: "{{ keycloak_quarkus_installdir }}" keycloak_quarkus_config_dir: "{{ keycloak_quarkus_home }}/conf" -keycloak_quarkus_start_dev: False +keycloak_quarkus_start_dev: false keycloak_quarkus_service_user: keycloak keycloak_quarkus_service_group: keycloak keycloak_quarkus_service_pidfile: "/run/keycloak/keycloak.pid" -keycloak_quarkus_configure_firewalld: False +keycloak_quarkus_configure_firewalld: false ### administrator console password keycloak_quarkus_admin_user: admin @@ -30,7 +30,7 @@ keycloak_quarkus_bind_address: 0.0.0.0 keycloak_quarkus_host: localhost keycloak_quarkus_port: -1 keycloak_quarkus_path: -keycloak_quarkus_http_enabled: True +keycloak_quarkus_http_enabled: true keycloak_quarkus_http_port: 8080 keycloak_quarkus_https_port: 8443 keycloak_quarkus_ajp_port: 8009 @@ -38,20 +38,20 @@ keycloak_quarkus_jgroups_port: 7600 keycloak_quarkus_java_opts: "-Xms1024m -Xmx2048m" ### TLS/HTTPS configuration -keycloak_quarkus_https_key_file_enabled: False +keycloak_quarkus_https_key_file_enabled: false keycloak_quarkus_key_file: "{{ keycloak.home }}/conf/server.key.pem" keycloak_quarkus_cert_file: "{{ keycloak.home }}/conf/server.crt.pem" #### key store configuration -keycloak_quarkus_https_key_store_enabled: False +keycloak_quarkus_https_key_store_enabled: false keycloak_quarkus_key_store_file: "{{ keycloak.home }}/conf/key_store.p12" keycloak_quarkus_key_store_password: '' ##### trust store configuration -keycloak_quarkus_https_trust_store_enabled: False +keycloak_quarkus_https_trust_store_enabled: false keycloak_quarkus_trust_store_file: "{{ keycloak.home }}/conf/trust_store.p12" keycloak_quarkus_trust_store_password: '' ### Enable configuration for database backend, clustering and remote caches on infinispan -keycloak_quarkus_ha_enabled: False +keycloak_quarkus_ha_enabled: false ### Enable database configuration, must be enabled when HA is configured keycloak_quarkus_db_enabled: "{{ True if keycloak_quarkus_ha_enabled else False }}" @@ -67,17 +67,17 @@ keycloak_quarkus_http_relative_path: / keycloak_quarkus_proxy_mode: edge # disable xa transactions -keycloak_quarkus_transaction_xa_enabled: True +keycloak_quarkus_transaction_xa_enabled: true -keycloak_quarkus_metrics_enabled: False -keycloak_quarkus_health_enabled: True +keycloak_quarkus_metrics_enabled: false +keycloak_quarkus_health_enabled: true ### infinispan remote caches access (hotrod) keycloak_quarkus_ispn_user: supervisor keycloak_quarkus_ispn_pass: supervisor keycloak_quarkus_ispn_url: localhost keycloak_quarkus_ispn_sasl_mechanism: SCRAM-SHA-512 -keycloak_quarkus_ispn_use_ssl: False +keycloak_quarkus_ispn_use_ssl: false # if ssl is enabled, import ispn server certificate here keycloak_quarkus_ispn_trust_store_path: /etc/pki/java/cacerts keycloak_quarkus_ispn_trust_store_password: changeit diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index d260910..89163aa 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -138,12 +138,12 @@ argument_specs: type: "bool" keycloak_quarkus_trust_store_file: default: "{{ keycloak.home }}/conf/trust_store.p12" - description: "The file pat to the trust store" + description: "The file path to the trust store" type: "str" keycloak_quarkus_trust_store_password: - default: "" - description: "Password for the trust store" - type: "str" + default: "" + description: "Password for the trust store" + type: "str" keycloak_quarkus_https_port: # line 30 of defaults/main.yml default: 8443 @@ -281,10 +281,10 @@ argument_specs: type: "str" description: "The proxy address forwarding mode if the server is behind a reverse proxy. Set to 'none' if not using a proxy" keycloak_quarkus_start_dev: - default: False + default: false type: "bool" description: "Whether to start the service in development mode (start-dev)" keycloak_quarkus_transaction_xa_enabled: - default: True + default: true type: "bool" description: "Enable or disable XA transactions which may not be supported by some DBMS" diff --git a/roles/keycloak_quarkus/meta/main.yml b/roles/keycloak_quarkus/meta/main.yml index 2a6acf8..469a71d 100644 --- a/roles/keycloak_quarkus/meta/main.yml +++ b/roles/keycloak_quarkus/meta/main.yml @@ -11,9 +11,9 @@ galaxy_info: min_ansible_version: "2.14" platforms: - - name: EL - versions: - - "8" + - name: EL + versions: + - "8" galaxy_tags: - keycloak diff --git a/roles/keycloak_quarkus/tasks/fastpackages.yml b/roles/keycloak_quarkus/tasks/fastpackages.yml index cfd9025..c9085f8 100644 --- a/roles/keycloak_quarkus/tasks/fastpackages.yml +++ b/roles/keycloak_quarkus/tasks/fastpackages.yml @@ -2,15 +2,15 @@ - name: "Check if packages are already installed" # noqa command-instead-of-module this runs faster ansible.builtin.command: "rpm -q {{ packages_list | join(' ') }}" register: rpm_info - changed_when: False - failed_when: False + changed_when: false + failed_when: false - name: "Add missing packages to the yum install list" ansible.builtin.set_fact: packages_to_install: "{{ packages_to_install | default([]) + rpm_info.stdout_lines | map('regex_findall', 'package (.+) is not installed$') | default([]) | flatten }}" - name: "Install packages: {{ packages_to_install }}" - become: True + become: true ansible.builtin.yum: name: "{{ packages_to_install }}" state: present diff --git a/roles/keycloak_quarkus/tasks/firewalld.yml b/roles/keycloak_quarkus/tasks/firewalld.yml index 6c81021..2c3ef74 100644 --- a/roles/keycloak_quarkus/tasks/firewalld.yml +++ b/roles/keycloak_quarkus/tasks/firewalld.yml @@ -6,19 +6,19 @@ - firewalld - name: Enable and start the firewalld service - become: yes + become: true ansible.builtin.systemd: name: firewalld - enabled: yes + enabled: true state: started - name: "Configure firewall for {{ keycloak.service_name }} ports" - become: yes + become: true ansible.posix.firewalld: port: "{{ item }}" permanent: true state: enabled - immediate: yes + immediate: true loop: - "{{ keycloak_quarkus_http_port }}/tcp" - "{{ keycloak_quarkus_https_port }}/tcp" diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index b1ea1ee..887aa31 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -11,21 +11,21 @@ quiet: true - name: Check for an existing deployment - become: yes + become: true ansible.builtin.stat: path: "{{ keycloak.home }}" register: existing_deploy - name: "Create {{ keycloak.service_name }} service user/group" - become: yes + become: true ansible.builtin.user: name: "{{ keycloak.service_user }}" home: /opt/keycloak - system: yes + system: true create_home: no - name: "Create {{ keycloak.service_name }} install location" - become: yes + become: true ansible.builtin.file: dest: "{{ keycloak_quarkus_dest }}" state: directory @@ -39,7 +39,7 @@ archive: "{{ keycloak_quarkus_dest }}/{{ keycloak.bundle }}" - name: Check download archive path - become: yes + become: true ansible.builtin.stat: path: "{{ archive }}" register: archive_path @@ -82,23 +82,23 @@ - not archive_path.stat.exists - local_archive_path.stat is defined - local_archive_path.stat.exists - become: yes + become: true - name: "Check target directory: {{ keycloak.home }}/bin/" ansible.builtin.stat: path: "{{ keycloak.home }}/bin/" register: path_to_workdir - become: yes + become: true - name: "Extract Keycloak archive on target" ansible.builtin.unarchive: - remote_src: yes + remote_src: true src: "{{ archive }}" dest: "{{ keycloak_quarkus_dest }}" creates: "{{ keycloak.home }}/bin/" owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" - become: yes + become: true when: - (not path_to_workdir.stat.exists) or new_version_downloaded.changed notify: diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index 43cbb38..93a68c0 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -28,7 +28,7 @@ owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" mode: 0644 - become: yes + become: true notify: - restart keycloak @@ -39,7 +39,7 @@ owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" mode: 0644 - become: yes + become: true notify: - restart keycloak @@ -50,7 +50,7 @@ owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" mode: 0775 - become: yes + become: true - name: Flush pending handlers ansible.builtin.meta: flush_handlers @@ -61,12 +61,12 @@ - name: Check service status ansible.builtin.command: "systemctl status keycloak" register: keycloak_service_status - changed_when: False + changed_when: false - name: Link default logs directory ansible.builtin.file: state: link src: "{{ keycloak.log.file | dirname }}" dest: "{{ keycloak_quarkus_log_target }}" - force: yes - become: yes + force: true + become: true diff --git a/roles/keycloak_quarkus/tasks/prereqs.yml b/roles/keycloak_quarkus/tasks/prereqs.yml index be807df..ee2abca 100644 --- a/roles/keycloak_quarkus/tasks/prereqs.yml +++ b/roles/keycloak_quarkus/tasks/prereqs.yml @@ -3,7 +3,7 @@ ansible.builtin.assert: that: - keycloak_quarkus_admin_pass | length > 12 - quiet: True + quiet: true fail_msg: "The console administrator password is empty or invalid. Please set the keycloak_quarkus_admin_pass variable to a 12+ char long string" success_msg: "{{ 'Console administrator password OK' }}" @@ -11,7 +11,7 @@ ansible.builtin.assert: that: - keycloak_quarkus_http_relative_path is regex('^/.*') - quiet: True + quiet: true fail_msg: "the relative path must begin with /" success_msg: "{{ 'relative path OK' }}" @@ -19,7 +19,7 @@ ansible.builtin.assert: that: - (keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled) or (not keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled) or (not keycloak_quarkus_ha_enabled and not keycloak_quarkus_db_enabled) - quiet: True + quiet: true fail_msg: "Cannot install HA setup without a backend database service. Check keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled" success_msg: "{{ 'Configuring HA' if keycloak_quarkus_ha_enabled else 'Configuring standalone' }}" diff --git a/roles/keycloak_quarkus/tasks/restart.yml b/roles/keycloak_quarkus/tasks/restart.yml index eff9ddf..f709f75 100644 --- a/roles/keycloak_quarkus/tasks/restart.yml +++ b/roles/keycloak_quarkus/tasks/restart.yml @@ -2,6 +2,7 @@ - name: "Restart and enable {{ keycloak.service_name }} service" ansible.builtin.systemd: name: keycloak - enabled: yes + enabled: true state: restarted - become: yes + daemon_reload: true + become: true diff --git a/roles/keycloak_quarkus/tasks/start.yml b/roles/keycloak_quarkus/tasks/start.yml index bdf42f9..7ccc1b9 100644 --- a/roles/keycloak_quarkus/tasks/start.yml +++ b/roles/keycloak_quarkus/tasks/start.yml @@ -2,9 +2,10 @@ - name: "Start {{ keycloak.service_name }} service" ansible.builtin.systemd: name: keycloak - enabled: yes + enabled: true state: started - become: yes + daemon_reload: true + become: true - name: "Wait until {{ keycloak.service_name }} becomes active {{ keycloak.health_url }}" ansible.builtin.uri: diff --git a/roles/keycloak_quarkus/tasks/systemd.yml b/roles/keycloak_quarkus/tasks/systemd.yml index c0be72b..3d59b3f 100644 --- a/roles/keycloak_quarkus/tasks/systemd.yml +++ b/roles/keycloak_quarkus/tasks/systemd.yml @@ -4,7 +4,7 @@ rpm_java_home: "/etc/alternatives/jre_{{ keycloak_quarkus_jvm_package | regex_search('(?<=java-)[0-9.]+') }}" - name: "Configure sysconfig file for keycloak service" - become: yes + become: true ansible.builtin.template: src: keycloak-sysconfig.j2 dest: /etc/sysconfig/keycloak @@ -23,13 +23,7 @@ owner: root group: root mode: 0644 - become: yes + become: true register: systemdunit notify: - restart keycloak - -- name: Reload systemd - become: yes - ansible.builtin.systemd: - daemon_reload: yes - when: systemdunit.changed diff --git a/roles/keycloak_realm/defaults/main.yml b/roles/keycloak_realm/defaults/main.yml index 17112d5..c396481 100644 --- a/roles/keycloak_realm/defaults/main.yml +++ b/roles/keycloak_realm/defaults/main.yml @@ -40,7 +40,7 @@ keycloak_clients: [] keycloak_client_default_roles: [] # if True, create a public client; otherwise, a confidetial client -keycloak_client_public: True +keycloak_client_public: true # allowed web origins for the client keycloak_client_web_origins: '+' diff --git a/roles/keycloak_realm/meta/argument_specs.yml b/roles/keycloak_realm/meta/argument_specs.yml index da3eca1..bc606ba 100644 --- a/roles/keycloak_realm/meta/argument_specs.yml +++ b/roles/keycloak_realm/meta/argument_specs.yml @@ -94,7 +94,7 @@ argument_specs: downstream: options: sso_version: - default: "7.5.0" + default: "7.6.0" description: "Red Hat Single Sign-On version" type: "str" sso_dest: @@ -106,10 +106,10 @@ argument_specs: description: "Installation path for Red Hat SSO" type: "str" sso_apply_patches: - default: False + default: false description: "Install Red Hat SSO most recent cumulative patch" type: "bool" sso_enable: - default: True + default: true description: "Enable Red Hat Single Sign-on installation" type: "str" diff --git a/roles/keycloak_realm/meta/main.yml b/roles/keycloak_realm/meta/main.yml index 8dfefcd..915f62c 100644 --- a/roles/keycloak_realm/meta/main.yml +++ b/roles/keycloak_realm/meta/main.yml @@ -11,9 +11,9 @@ galaxy_info: min_ansible_version: "2.14" platforms: - - name: EL - versions: - - "8" + - name: EL + versions: + - "8" galaxy_tags: - keycloak diff --git a/roles/keycloak_realm/tasks/main.yml b/roles/keycloak_realm/tasks/main.yml index c137270..c1f66bc 100644 --- a/roles/keycloak_realm/tasks/main.yml +++ b/roles/keycloak_realm/tasks/main.yml @@ -4,7 +4,7 @@ url: "{{ keycloak_url }}{{ keycloak_context }}/realms/master/protocol/openid-connect/token" method: POST body: "client_id={{ keycloak_auth_client }}&username={{ keycloak_admin_user }}&password={{ keycloak_admin_password }}&grant_type=password" - validate_certs: no + validate_certs: false no_log: "{{ keycloak_no_log | default('True') }}" register: keycloak_auth_response until: keycloak_auth_response.status == 200 @@ -28,7 +28,7 @@ url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms" method: POST body: "{{ lookup('template', 'realm.json.j2') }}" - validate_certs: no + validate_certs: false body_format: json headers: Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" @@ -59,7 +59,7 @@ - item.name is defined and item.name | length > 0 - (item.client_id is defined and item.client_id | length > 0) or (item.id is defined and item.id | length > 0) fail_msg: "For each keycloak client, attributes `name` and either `id` or `client_id` is required" - quiet: True + quiet: true loop: "{{ keycloak_clients | flatten }}" loop_control: label: "{{ item.name | default('unnamed client') }}" diff --git a/roles/keycloak_realm/tasks/manage_user.yml b/roles/keycloak_realm/tasks/manage_user.yml index 840c738..1f9f7bd 100644 --- a/roles/keycloak_realm/tasks/manage_user.yml +++ b/roles/keycloak_realm/tasks/manage_user.yml @@ -2,7 +2,7 @@ - name: "Check if User Already Exists" ansible.builtin.uri: url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ keycloak_realm }}/users?username={{ user.username }}" - validate_certs: no + validate_certs: false headers: Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" register: keycloak_user_search_result @@ -18,7 +18,7 @@ email: "{{ user.email | default(omit) }}" firstName: "{{ user.firstName | default(omit) }}" lastName: "{{ user.lastName | default(omit) }}" - validate_certs: no + validate_certs: false body_format: json headers: Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" @@ -28,7 +28,7 @@ - name: "Get User" ansible.builtin.uri: url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ keycloak_realm }}/users?username={{ user.username }}" - validate_certs: no + validate_certs: false headers: Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" register: keycloak_user @@ -41,7 +41,7 @@ type: password temporary: false value: "{{ user.password }}" - validate_certs: no + validate_certs: false body_format: json status_code: - 200 diff --git a/roles/keycloak_realm/tasks/manage_user_client_roles.yml b/roles/keycloak_realm/tasks/manage_user_client_roles.yml index 5369094..85de09a 100644 --- a/roles/keycloak_realm/tasks/manage_user_client_roles.yml +++ b/roles/keycloak_realm/tasks/manage_user_client_roles.yml @@ -31,7 +31,7 @@ containerId: "{{ item.containerId }}" name: "{{ item.name }}" composite: "{{ item.composite }}" - validate_certs: False + validate_certs: false body_format: json headers: Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" diff --git a/roles/keycloak_realm/tasks/manage_user_roles.yml b/roles/keycloak_realm/tasks/manage_user_roles.yml index ff803a2..dc74477 100644 --- a/roles/keycloak_realm/tasks/manage_user_roles.yml +++ b/roles/keycloak_realm/tasks/manage_user_roles.yml @@ -3,7 +3,7 @@ ansible.builtin.uri: url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ keycloak_realm }}/users?username={{ user.username }}" headers: - validate_certs: no + validate_certs: false Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" register: keycloak_user @@ -12,7 +12,7 @@ url: "{{ keycloak_url }}{{ keycloak_context }}/realms/master/protocol/openid-connect/token" method: POST body: "client_id={{ keycloak_auth_client }}&username={{ keycloak_admin_user }}&password={{ keycloak_admin_password }}&grant_type=password" - validate_certs: no + validate_certs: false register: keycloak_auth_response no_log: "{{ keycloak_no_log | default('True') }}" until: keycloak_auth_response.status == 200 diff --git a/roles/keycloak_realm/vars/main.yml b/roles/keycloak_realm/vars/main.yml index cbb9435..7664f8c 100644 --- a/roles/keycloak_realm/vars/main.yml +++ b/roles/keycloak_realm/vars/main.yml @@ -5,5 +5,5 @@ keycloak_realm: # other settings -keycloak_url: "http://{{ keycloak_host }}:{{ keycloak_http_port + ( keycloak_jboss_port_offset | default(0) ) }}" -keycloak_management_url: "http://{{ keycloak_host }}:{{ keycloak_management_http_port + ( keycloak_jboss_port_offset | default(0) ) }}" +keycloak_url: "http://{{ keycloak_host }}:{{ keycloak_http_port + (keycloak_jboss_port_offset | default(0)) }}" +keycloak_management_url: "http://{{ keycloak_host }}:{{ keycloak_management_http_port + (keycloak_jboss_port_offset | default(0)) }}" From 94530640c1d62c2fd58b45dd69b7471606664cd4 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 1 Dec 2023 12:37:20 +0100 Subject: [PATCH 295/554] update wf --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6e5a542..d8905f0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,7 +4,7 @@ on: push: branches: - main - pull_request: + pull_request_target: schedule: - cron: '0 6 * * *' From 842e61c43ed506aecc686ddd327ede804850aa45 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 5 Dec 2023 10:13:12 +0100 Subject: [PATCH 296/554] Update template to lowercase booleans --- roles/keycloak_quarkus/templates/keycloak.conf.j2 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index bc563ed..ac2defe 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -9,11 +9,11 @@ db-password={{ keycloak_quarkus_db_pass }} {% endif %} # Observability -metrics-enabled={{ keycloak_quarkus_metrics_enabled }} -health-enabled={{ keycloak_quarkus_health_enabled }} +metrics-enabled={{ keycloak_quarkus_metrics_enabled | lower }} +health-enabled={{ keycloak_quarkus_health_enabled | lower }} # HTTP -http-enabled={{ keycloak_quarkus_http_enabled }} +http-enabled={{ keycloak_quarkus_http_enabled | lower }} http-port={{ keycloak_quarkus_http_port }} http-relative-path={{ keycloak_quarkus_http_relative_path }} @@ -57,7 +57,7 @@ proxy={{ keycloak_quarkus_proxy_mode }} #spi-sticky-session-encoder-infinispan-should-attach-route=false # Transaction -transaction-xa-enabled={{ keycloak_quarkus_transaction_xa_enabled }} +transaction-xa-enabled={{ keycloak_quarkus_transaction_xa_enabled | lower }} # Logging #log-format=%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n From 72ca9f5dfa528c31ba46ae0ff6e657a14be8ee60 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 5 Dec 2023 10:26:20 +0100 Subject: [PATCH 297/554] switch pull_req_target to pull_req --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d8905f0..6552ce1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,9 +4,9 @@ on: push: branches: - main - pull_request_target: + pull_request: schedule: - - cron: '0 6 * * *' + - cron: '15 6 * * *' jobs: ci: @@ -15,4 +15,4 @@ jobs: with: fqcn: 'middleware_automation/keycloak' molecule_tests: >- - [ "default", "quarkus", "overridexml", "quarkus-devmode", "https_revproxy" ] + [ "default", "overridexml", "quarkus", "quarkus-devmode" ] From 593c4df861957509169cd0fefeaf99a9bb8739e6 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 5 Dec 2023 10:48:48 +0100 Subject: [PATCH 298/554] keycloak_quarkus: add hostname-strict parameter --- roles/keycloak_quarkus/README.md | 9 +++++++++ roles/keycloak_quarkus/defaults/main.yml | 4 ++++ roles/keycloak_quarkus/meta/argument_specs.yml | 4 ++++ roles/keycloak_quarkus/templates/keycloak.conf.j2 | 1 + 4 files changed, 18 insertions(+) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index c32054e..9a04e1b 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -50,6 +50,13 @@ Role Defaults |`keycloak_quarkus_trust_store_password`| Password for the trust store | `""` | +* Hostname configuration + +| Variable | Description | Default | +|:---------|:------------|:--------| +|`keycloak_quarkus_http_relative_path`| Set the path relative to / for serving resources. The path must start with a / | `/` | +|`keycloak_quarkus_hostname_strict`| Disables dynamically resolving the hostname from request headers | `true` | + * Database configuration @@ -118,6 +125,8 @@ Role Variables | Variable | Description | Required | |:---------|:------------|----------| |`keycloak_quarkus_admin_pass`| Password of console admin account | `yes` | +|`keycloak_quarkus_frontend_url`| Base URL for frontend URLs, including scheme, host, port and path | `no` | +|`keycloak_quarkus_admin_url`| Base URL for accessing the administration console, including scheme, host, port and path | `no` | License diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index d5fcf90..a4f1d5e 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -63,6 +63,10 @@ keycloak_quarkus_admin_url: ### (set to `/auth` for retrocompatibility with pre-quarkus releases) keycloak_quarkus_http_relative_path: / +# Disables dynamically resolving the hostname from request headers. +# Should always be set to true in production, unless proxy verifies the Host header. +keycloak_quarkus_hostname_strict: true + # proxy address forwarding mode if the server is behind a reverse proxy. [none, edge, reencrypt, passthrough] keycloak_quarkus_proxy_mode: edge diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 89163aa..2d3dadf 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -288,3 +288,7 @@ argument_specs: default: true type: "bool" description: "Enable or disable XA transactions which may not be supported by some DBMS" + keycloak_quarkus_hostname_strict: + default: true + type: "bool" + description: "Disables dynamically resolving the hostname from request headers. Should always be set to true in production, unless proxy verifies the Host header." diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index ac2defe..b3b6787 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -41,6 +41,7 @@ hostname-port={{ keycloak_quarkus_port }} hostname-path={{ keycloak_quarkus_path }} {% endif %} hostname-admin-url={{ keycloak_quarkus_admin_url }} +hostname-strict={{ keycloak_quarkus_hostname_strict | lower }} # Cluster {% if keycloak_quarkus_ha_enabled %} From f365351abfd452625ee40a1c5a685241bcbae316 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 5 Dec 2023 19:53:26 +0100 Subject: [PATCH 299/554] use nginx instead of jbcs for https_revproxy test --- .github/workflows/ci.yml | 2 +- molecule/https_revproxy/molecule.yml | 2 -- molecule/https_revproxy/prepare.yml | 45 ++++++++++++++-------------- molecule/requirements.yml | 3 ++ 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6552ce1..afb1403 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,4 +15,4 @@ jobs: with: fqcn: 'middleware_automation/keycloak' molecule_tests: >- - [ "default", "overridexml", "quarkus", "quarkus-devmode" ] + [ "default", "overridexml", "https_revproxy", "quarkus", "quarkus-devmode" ] diff --git a/molecule/https_revproxy/molecule.yml b/molecule/https_revproxy/molecule.yml index 6a8790d..48bf375 100644 --- a/molecule/https_revproxy/molecule.yml +++ b/molecule/https_revproxy/molecule.yml @@ -41,8 +41,6 @@ provisioner: ansible_python_interpreter: "{{ ansible_playbook_python }}" env: ANSIBLE_FORCE_COLOR: "true" - REDHAT_PRODUCT_DOWNLOAD_CLIENT_ID: "${PROD_JBOSSNETWORK_API_CLIENTID}" - REDHAT_PRODUCT_DOWNLOAD_CLIENT_SECRET: "${PROD_JBOSSNETWORK_API_SECRET}" verifier: name: ansible scenario: diff --git a/molecule/https_revproxy/prepare.yml b/molecule/https_revproxy/prepare.yml index 5cdb135..a641257 100644 --- a/molecule/https_revproxy/prepare.yml +++ b/molecule/https_revproxy/prepare.yml @@ -3,7 +3,7 @@ hosts: all tasks: - name: Install sudo - ansible.builtin.yum: + ansible.builtin.dnf: name: sudo state: present @@ -14,36 +14,35 @@ - name: Prepare proxy hosts: proxy vars: - jbcs_mod_cluster_enable: True - jbcs_configure_firewalld: False - jbcs_offline_install: False - jbcs_bind_address: '*' - jbcs_proxy_pass: - - path: / - url: http://instance:8080/ - reverse_path: / - reverse_url: http://instance:8080/ - external_domain_name: proxy - rhn_username: "{{ lookup('env', 'REDHAT_PRODUCT_DOWNLOAD_CLIENT_ID') }}" - rhn_password: "{{ lookup('env', 'REDHAT_PRODUCT_DOWNLOAD_CLIENT_SECRET') }}" + nginx_proxy: | + location / { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_pass http://instance:8080; + } roles: - - middleware_automation.jbcs.jbcs + - elan.simple_nginx_reverse_proxy pre_tasks: - name: Create certificate request ansible.builtin.command: openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes -subj '/CN=proxy' delegate_to: localhost - changed_when: False - + changed_when: false + - name: Make certificate directory + ansible.builtin.file: + path: /etc/nginx/tls + state: directory - name: Copy certificates ansible.builtin.copy: src: "{{ item.name }}" dest: "{{ item.dest }}" mode: 0444 - become: True + become: true loop: - - { name: 'cert.pem', dest: '/etc/pki/tls/certs/proxy.crt' } - - { name: 'key.pem', dest: '/etc/pki/tls/private/proxy.key' } - - - name: update_ca_trust - command: update-ca-trust - become: True + - { name: 'cert.pem', dest: '/etc/nginx/tls/certificate.crt' } + - { name: 'key.pem', dest: '/etc/nginx/tls/certificate.key' } + - name: Update CA trust + ansible.builtin.command: update-ca-trust + changed_when: false + become: true diff --git a/molecule/requirements.yml b/molecule/requirements.yml index 5e39b59..c87fd9a 100644 --- a/molecule/requirements.yml +++ b/molecule/requirements.yml @@ -6,3 +6,6 @@ collections: - name: ansible.posix - name: community.docker version: ">=1.9.1" + +roles: + - name: elan.simple_nginx_reverse_proxy From 89944a6cd14e13a9dd9c590bd1ee486d269a881d Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 5 Dec 2023 20:28:24 +0100 Subject: [PATCH 300/554] downstream: add rhbk bits --- .../keycloak_quarkus/meta/argument_specs.yml | 50 +++++++++++++++++++ roles/keycloak_quarkus/meta/main.yml | 1 + roles/keycloak_quarkus/tasks/install.yml | 42 +++++++++++++++- 3 files changed, 92 insertions(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 2d3dadf..76384f4 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -292,3 +292,53 @@ argument_specs: default: true type: "bool" description: "Disables dynamically resolving the hostname from request headers. Should always be set to true in production, unless proxy verifies the Host header." + downstream: + options: + rhbk_version: + default: "22.0.6" + description: "Red Hat Build of Keycloak version" + type: "str" + rhbk_archive: + default: "rhbk-{{ rhbk_version }}.zip" + description: "Red Hat Build of Keycloak install archive filename" + type: "str" + rhbk_dest: + default: "/opt/rhbk" + description: "Root installation directory" + type: "str" + rhbk_installdir: + default: "{{ rhbk_dest }}/rhbk-{{ rhbk_version.split('.')[0] }}.{{ rhbk_version.split('.')[1] }}" + description: "Installation path for Red Hat Build of Keycloak" + type: "str" + rhbk_apply_patches: + default: false + description: "Install Red Hat Build of Keycloak most recent cumulative patch" + type: "bool" + rhbk_enable: + default: true + description: "Enable Red Hat Build of Keycloak installation" + type: "str" + rhbk_offline_install: + default: false + description: "Perform an offline install" + type: "bool" + rhbk_service_name: + default: "rhbk" + description: "systemd service name for Red Hat Build of Keycloak" + type: "str" + rhbk_service_desc: + default: "Red Hat Build of Keycloak" + description: "systemd description for Red Hat Build of Keycloak" + type: "str" + rhbk_patch_version: + required: false + description: "Red Hat Build of Keycloak latest cumulative patch version to apply; defaults to latest version when rhbk_apply_patches is True" + type: "str" + rhbk_patch_bundle: + default: "rhbk-{{ rhbk_patch_version | default('[0-9]+[.][0-9]+[.][0-9]+') }}-patch.zip" + description: "Red Hat Build of Keycloak patch archive filename" + type: "str" + rhbk_product_category: + default: "rhbk" + description: "JBossNetwork API category for Red Hat Build of Keycloak" + type: "str" diff --git a/roles/keycloak_quarkus/meta/main.yml b/roles/keycloak_quarkus/meta/main.yml index 469a71d..8d7331d 100644 --- a/roles/keycloak_quarkus/meta/main.yml +++ b/roles/keycloak_quarkus/meta/main.yml @@ -24,3 +24,4 @@ galaxy_info: - authentication - identity - security + - rhbk diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index 887aa31..25106f9 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -57,11 +57,51 @@ dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" mode: 0640 delegate_to: localhost + run_once: true when: - archive_path is defined - archive_path.stat is defined - not archive_path.stat.exists - not keycloak.offline_install + - not rhbk_enable is defined or not rhbk_enable + +- name: Perform download from RHN using JBoss Network API + delegate_to: localhost + run_once: true + when: + - archive_path is defined + - archive_path.stat is defined + - not archive_path.stat.exists + - rhbk_enable is defined and rhbk_enable + - not keycloak.offline_install + block: + - name: Retrieve product download using JBoss Network API + middleware_automation.common.product_search: + client_id: "{{ rhn_username }}" + client_secret: "{{ rhn_password }}" + product_type: DISTRIBUTION + product_version: "{{ rhbk_version }}" + product_category: "{{ rhbk_product_category }}" + register: rhn_products + no_log: "{{ omit_rhn_output | default(true) }}" + delegate_to: localhost + run_once: true + + - name: Determine install zipfile from search results + ansible.builtin.set_fact: + rhn_filtered_products: "{{ rhn_products.results | selectattr('file_path', 'match', '[^/]*/' + rhbk_archive + '$') }}" + delegate_to: localhost + run_once: true + + - name: Download Red Hat Build of Keycloak + middleware_automation.common.product_download: # noqa risky-file-permissions delegated, uses controller host user + client_id: "{{ rhn_username }}" + client_secret: "{{ rhn_password }}" + product_id: "{{ (rhn_filtered_products | first).id }}" + dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" + no_log: "{{ omit_rhn_output | default(true) }}" + delegate_to: localhost + run_once: true - name: Check downloaded archive ansible.builtin.stat: @@ -76,7 +116,7 @@ dest: "{{ archive }}" owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" - mode: 0750 + mode: 0640 register: new_version_downloaded when: - not archive_path.stat.exists From acdee7fa63b7321a35167754f6989a497b7812c4 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 6 Dec 2023 15:40:28 +0100 Subject: [PATCH 301/554] ci: downstream arg specs for realm role --- roles/keycloak_realm/meta/argument_specs.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/roles/keycloak_realm/meta/argument_specs.yml b/roles/keycloak_realm/meta/argument_specs.yml index bc606ba..ca174dc 100644 --- a/roles/keycloak_realm/meta/argument_specs.yml +++ b/roles/keycloak_realm/meta/argument_specs.yml @@ -113,3 +113,23 @@ argument_specs: default: true description: "Enable Red Hat Single Sign-on installation" type: "str" + rhbk_version: + default: "22.0.6" + description: "Red Hat Build of Keycloak version" + type: "str" + rhbk_archive: + default: "rhbk-{{ rhbk_version }}.zip" + description: "Red Hat Build of Keycloak install archive filename" + type: "str" + rhbk_dest: + default: "/opt/rhbk" + description: "Root installation directory" + type: "str" + rhbk_installdir: + default: "{{ rhbk_dest }}/rhbk-{{ rhbk_version.split('.')[0] }}.{{ rhbk_version.split('.')[1] }}" + description: "Installation path for Red Hat Build of Keycloak" + type: "str" + rhbk_enable: + default: true + description: "Enable Red Hat Build of Keycloak installation" + type: "str" From 5b8fcb67dc2b0562b18aa255399e2ecf648f1ddb Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 6 Dec 2023 16:03:37 +0100 Subject: [PATCH 302/554] ci: update sample quarkus playbook --- playbooks/keycloak_quarkus.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/playbooks/keycloak_quarkus.yml b/playbooks/keycloak_quarkus.yml index 13bbce5..02e356f 100644 --- a/playbooks/keycloak_quarkus.yml +++ b/playbooks/keycloak_quarkus.yml @@ -5,7 +5,6 @@ keycloak_quarkus_admin_pass: "remembertochangeme" keycloak_quarkus_host: localhost keycloak_quarkus_port: 8443 - keycloak_quarkus_http_relative_path: '' keycloak_quarkus_log: file keycloak_quarkus_https_key_file_enabled: true keycloak_quarkus_key_file: conf/key.pem From ac0b42145651ce1aa3f37e8dcfc1a2014e3e662e Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 6 Dec 2023 16:34:55 +0100 Subject: [PATCH 303/554] downstream: fix rhbk install path --- roles/keycloak_quarkus/meta/argument_specs.yml | 2 +- roles/keycloak_quarkus/tasks/main.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 76384f4..6fdd108 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -307,7 +307,7 @@ argument_specs: description: "Root installation directory" type: "str" rhbk_installdir: - default: "{{ rhbk_dest }}/rhbk-{{ rhbk_version.split('.')[0] }}.{{ rhbk_version.split('.')[1] }}" + default: "{{ rhbk_dest }}/rhbk-{{ rhbk_version }}" description: "Installation path for Red Hat Build of Keycloak" type: "str" rhbk_apply_patches: diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index 93a68c0..71582f8 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -41,7 +41,7 @@ mode: 0644 become: true notify: - - restart keycloak + - restart keycloak - name: Ensure logdirectory exists ansible.builtin.file: From a23bf4c540668c85172d04fc4250742fa335d9b5 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 6 Dec 2023 18:24:29 +0100 Subject: [PATCH 304/554] ci: downstream use correct version --- molecule/quarkus/prepare.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index 44d2492..f6a556d 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -1,6 +1,8 @@ --- - name: Prepare hosts: all + vars: + version: "{{ '22.0.6' if rhbk_enable is defined and rhbk_enable else '23.0.1' }}" tasks: - name: Install sudo ansible.builtin.yum: @@ -19,13 +21,13 @@ - name: Create conf directory # risky-file-permissions in test user account does not exist yet ansible.builtin.file: state: directory - path: /opt/keycloak/keycloak-23.0.1/conf/ + path: "/opt/keycloak/keycloak-{{ version }}/conf/" mode: 0755 - name: Copy certificates ansible.builtin.copy: src: "{{ item }}" - dest: "/opt/keycloak/keycloak-23.0.1/conf/{{ item }}" + dest: "/opt/keycloak/keycloak-{{ version }}/conf/{{ item }}" mode: 0444 loop: - cert.pem From d469d5df8b9709b55dbd7e2eb76d69c9726c4e00 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 6 Dec 2023 18:52:46 +0100 Subject: [PATCH 305/554] ci: downstream update sample playbooks --- playbooks/keycloak_quarkus.yml | 1 + playbooks/keycloak_quarkus_dev.yml | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/playbooks/keycloak_quarkus.yml b/playbooks/keycloak_quarkus.yml index 02e356f..cec5188 100644 --- a/playbooks/keycloak_quarkus.yml +++ b/playbooks/keycloak_quarkus.yml @@ -9,5 +9,6 @@ keycloak_quarkus_https_key_file_enabled: true keycloak_quarkus_key_file: conf/key.pem keycloak_quarkus_cert_file: conf/cert.pem + keycloak_quarkus_proxy_mode: none roles: - middleware_automation.keycloak.keycloak_quarkus diff --git a/playbooks/keycloak_quarkus_dev.yml b/playbooks/keycloak_quarkus_dev.yml index 634296d..533db79 100644 --- a/playbooks/keycloak_quarkus_dev.yml +++ b/playbooks/keycloak_quarkus_dev.yml @@ -5,7 +5,6 @@ keycloak_admin_password: "remembertochangeme" keycloak_quarkus_host: localhost keycloak_quarkus_port: 8080 - keycloak_quarkus_http_relative_path: '' keycloak_quarkus_log: file keycloak_quarkus_start_dev: true keycloak_quarkus_proxy_mode: none From 0fbf454279d34a21a8053c525a27ab448faed9b9 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 7 Dec 2023 11:00:28 +0100 Subject: [PATCH 306/554] ci: test alternate certs dir --- molecule/quarkus/converge.yml | 4 ++-- molecule/quarkus/prepare.yml | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index 686494d..1b989ce 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -8,8 +8,8 @@ keycloak_quarkus_host: instance keycloak_quarkus_log: file keycloak_quarkus_https_key_file_enabled: True - keycloak_quarkus_key_file: "{{ keycloak.home }}/conf/key.pem" - keycloak_quarkus_cert_file: "{{ keycloak.home }}/conf/cert.pem" + keycloak_quarkus_key_file: "/opt/keycloak/certs/key.pem" + keycloak_quarkus_cert_file: "/opt/keycloak/certs/cert.pem" keycloak_quarkus_log_target: /tmp/keycloak roles: - role: keycloak_quarkus diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index f6a556d..13d85a8 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -1,8 +1,6 @@ --- - name: Prepare hosts: all - vars: - version: "{{ '22.0.6' if rhbk_enable is defined and rhbk_enable else '23.0.1' }}" tasks: - name: Install sudo ansible.builtin.yum: @@ -21,13 +19,13 @@ - name: Create conf directory # risky-file-permissions in test user account does not exist yet ansible.builtin.file: state: directory - path: "/opt/keycloak/keycloak-{{ version }}/conf/" + path: "/opt/keycloak/certs/" mode: 0755 - name: Copy certificates ansible.builtin.copy: src: "{{ item }}" - dest: "/opt/keycloak/keycloak-{{ version }}/conf/{{ item }}" + dest: "/opt/keycloak/certs/{{ item }}" mode: 0444 loop: - cert.pem From 98b82ccb4fb8e85e53c9494895a6ead71666665c Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 7 Dec 2023 11:15:12 +0100 Subject: [PATCH 307/554] ci: runner playbook no keypair --- playbooks/keycloak_quarkus.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/playbooks/keycloak_quarkus.yml b/playbooks/keycloak_quarkus.yml index cec5188..f2649a5 100644 --- a/playbooks/keycloak_quarkus.yml +++ b/playbooks/keycloak_quarkus.yml @@ -6,9 +6,6 @@ keycloak_quarkus_host: localhost keycloak_quarkus_port: 8443 keycloak_quarkus_log: file - keycloak_quarkus_https_key_file_enabled: true - keycloak_quarkus_key_file: conf/key.pem - keycloak_quarkus_cert_file: conf/cert.pem keycloak_quarkus_proxy_mode: none roles: - middleware_automation.keycloak.keycloak_quarkus From 473fb212c3946606c201de89cd618632a62536bf Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Thu, 7 Dec 2023 14:30:17 +0000 Subject: [PATCH 308/554] Update changelog for release 2.0.1 Signed-off-by: ansible-middleware-core --- CHANGELOG.rst | 14 ++++++++++++++ changelogs/changelog.yaml | 18 ++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index fa6fdea..274cfa3 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,20 @@ middleware_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v2.0.1 +====== + +Minor Changes +------------- + +- keycloak_quarkus: add hostname-strict parameter `#139 `_ +- keycloak_quarkus: update to version 23.0.1 `#133 `_ + +Bugfixes +-------- + +- keycloak_quarkus: template requires lowercase boolean values `#138 `_ + v2.0.0 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index e3ec06e..7d19d7f 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -341,3 +341,21 @@ releases: - 122.yaml - 124.yaml release_date: '2023-11-20' + 2.0.1: + changes: + bugfixes: + - 'keycloak_quarkus: template requires lowercase boolean values `#138 `_ + + ' + minor_changes: + - 'keycloak_quarkus: add hostname-strict parameter `#139 `_ + + ' + - 'keycloak_quarkus: update to version 23.0.1 `#133 `_ + + ' + fragments: + - 133.yaml + - 138.yaml + - 139.yaml + release_date: '2023-12-07' From db19fd5d19a1eaa62bbbcc9d17012812f5400a24 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Thu, 7 Dec 2023 14:30:27 +0000 Subject: [PATCH 309/554] Bump version to 2.0.2 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index bd77fe6..ac09faa 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "2.0.1" +version: "2.0.2" readme: README.md authors: - Romain Pelisse From ed6dbd60fb9c358daf26907c0773a00344183f92 Mon Sep 17 00:00:00 2001 From: Ranabir Chakraborty Date: Mon, 11 Dec 2023 22:12:39 +0530 Subject: [PATCH 310/554] AMW-170 Ansible Hub links for rhbk are broken --- README.md | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index d93231f..efcd597 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ > **_NOTE:_ If you are Red Hat customer, install `redhat.sso` from [Automation Hub](https://console.redhat.com/ansible/ansible-dashboard) as the certified version of this collection.** -Collection to install and configure [Keycloak](https://www.keycloak.org/) or [Red Hat Single Sign-On](https://access.redhat.com/products/red-hat-single-sign-on). +Collection to install and configure [Keycloak](https://www.keycloak.org/) or [Red Hat Single Sign-On](https://access.redhat.com/products/red-hat-single-sign-on). ## Ansible version compatibility @@ -44,25 +44,25 @@ A requirement file is provided to install: pip install -r requirements.txt - + ### Included roles * [`keycloak`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak/README.md): role for installing the service. * [`keycloak_realm`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak_realm/README.md): role for configuring a realm, user federation(s), clients and users, in an installed service. * [`keycloak_quarkus`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak_quarkus/README.md): role for installing the quarkus variant of keycloak (>= 17.0.0). - + ## Usage ### Install Playbook - + * [`playbooks/keycloak.yml`](https://github.com/ansible-middleware/keycloak/blob/main/playbooks/keycloak.yml) installs based on the defined variables (using most defaults). Both playbooks include the `keycloak` role, with different settings, as described in the following sections. For full service configuration details, refer to the [keycloak role README](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak/README.md). - + #### Install from controller node (offline) @@ -85,7 +85,7 @@ It is possible to perform downloads from alternate sources, using the `keycloak_ ### Example installation command -Execute the following command from the source root directory +Execute the following command from the source root directory ``` ansible-playbook -i -e @rhn-creds.yml playbooks/keycloak.yml -e keycloak_admin_password= @@ -106,9 +106,9 @@ Note: when deploying clustered configurations, all hosts belonging to the cluste ### Config Playbook - + [`playbooks/keycloak_realm.yml`](https://github.com/ansible-middleware/keycloak/blob/main/playbooks/keycloak_realm.yml) creates or updates provided realm, user federation(s), client(s), client role(s) and client user(s). - + ### Example configuration command @@ -126,9 +126,9 @@ ansible-playbook -i playbooks/keycloak_realm.yml -e keycloak_adm [keycloak] localhost ansible_connection=local ``` - + For full configuration details, refer to the [keycloak_realm role README](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak_realm/README.md). - + @@ -137,6 +137,7 @@ For full configuration details, refer to the [keycloak_realm role README](https: ## License Apache License v2.0 or later - + See [LICENSE](LICENSE) to view the full text. + From 83bcb6712adb24cd4904aa8c2c49287ec99a1aa8 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Tue, 19 Dec 2023 09:30:30 +0100 Subject: [PATCH 311/554] keycloak_quarkus: add systemd control options * keycloak_quarkus_service_restart_always * keycloak_quarkus_service_restart_on_failure * keycloak_quarkus_service_restartsec --- roles/keycloak_quarkus/README.md | 7 +++++-- roles/keycloak_quarkus/defaults/main.yml | 3 +++ roles/keycloak_quarkus/meta/argument_specs.yml | 12 ++++++++++++ roles/keycloak_quarkus/templates/keycloak.service.j2 | 7 +++++++ 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 9a04e1b..8fa1a75 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -31,6 +31,9 @@ Role Defaults |`keycloak_quarkus_jgroups_port`| jgroups cluster tcp port | `7600` | |`keycloak_quarkus_service_user`| Posix account username | `keycloak` | |`keycloak_quarkus_service_group`| Posix account group | `keycloak` | +|`keycloak_quarkus_service_restart_always`| systemd restart always behavior activation | `False` | +|`keycloak_quarkus_service_restart_on_failure`| systemd restart on-failure behavior activation | `False` | +|`keycloak_quarkus_service_restartsec`| systemd RestartSec | `10s` | |`keycloak_quarkus_service_pidfile`| Pid file path for service | `/run/keycloak.pid` | |`keycloak_quarkus_jvm_package`| RHEL java package runtime | `java-17-openjdk-headless` | |`keycloak_quarkus_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_quarkus_jvm_package RPM path | `None` | @@ -79,7 +82,7 @@ Role Defaults |`keycloak_quarkus_ispn_sasl_mechanism` | Infinispan auth mechanism | `SCRAM-SHA-512` | |`keycloak_quarkus_ispn_use_ssl` | Whether infinispan uses TLS connection | `false` | |`keycloak_quarkus_ispn_trust_store_path` | Path to infinispan server trust certificate | `/etc/pki/java/cacerts` | -|`keycloak_quarkus_ispn_trust_store_password` | Password for infinispan certificate keystore | `changeit` | +|`keycloak_quarkus_ispn_trust_store_password` | Password for infinispan certificate keystore | `changeit` | * Install options @@ -87,7 +90,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:---------| |`keycloak_quarkus_offline_install` | Perform an offline install | `False`| -|`keycloak_quarkus_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| +|`keycloak_quarkus_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| |`keycloak_quarkus_version`| keycloak.org package version | `23.0.1` | |`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` | |`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index a4f1d5e..1a1382f 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -19,6 +19,9 @@ keycloak_quarkus_service_user: keycloak keycloak_quarkus_service_group: keycloak keycloak_quarkus_service_pidfile: "/run/keycloak/keycloak.pid" keycloak_quarkus_configure_firewalld: false +keycloak_quarkus_service_restart_always: false +keycloak_quarkus_service_restart_on_failure: false +keycloak_quarkus_service_restartsec: "10s" ### administrator console password keycloak_quarkus_admin_user: admin diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 6fdd108..f616611 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -69,6 +69,18 @@ argument_specs: default: false description: "Ensure firewalld is running and configure keycloak ports" type: "bool" + keycloak_service_restart_always: + default: false + description: "systemd restart always behavior of service" + type: "bool" + keycloak_service_restart_on_failure: + default: false + description: "systemd restart on-failure behavior of service" + type: "bool" + keycloak_service_restartsec: + default: "10s" + description: "systemd RestartSec for service" + type: "str" keycloak_quarkus_admin_user: default: "admin" description: "Administration console user account" diff --git a/roles/keycloak_quarkus/templates/keycloak.service.j2 b/roles/keycloak_quarkus/templates/keycloak.service.j2 index f7ffc1c..1854463 100644 --- a/roles/keycloak_quarkus/templates/keycloak.service.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.service.j2 @@ -13,6 +13,13 @@ ExecStart={{ keycloak.home }}/bin/kc.sh start-dev ExecStart={{ keycloak.home }}/bin/kc.sh start --log={{ keycloak_quarkus_log }} {% endif %} User={{ keycloak.service_user }} +Group={{ keycloak.service_group }} +{% if keycloak_quarkus_service_restart_always %} +Restart=always +{% elif keycloak_quarkus_service_restart_on_failure %} +Restart=on-failure +{% endif %} +RestartSec={{ keycloak_quarkus_service_restartsec }} [Install] WantedBy=multi-user.target From 1d5ce87c16a69ceacd16790e3cd5f69c1fc72846 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Tue, 19 Dec 2023 09:55:02 +0100 Subject: [PATCH 312/554] keycloak_quarkus: Remove legacy (?) `keycloak_management_url` --- roles/keycloak_quarkus/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 8fa1a75..e419d89 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -111,7 +111,6 @@ Role Defaults |`keycloak_auth_client` | Authentication client for configuration REST calls | `admin-cli` | |`keycloak_force_install` | Remove pre-existing versions of service | `False` | |`keycloak_url` | URL for configuration rest calls | `http://{{ keycloak_quarkus_host }}:{{ keycloak_http_port }}` | -|`keycloak_management_url` | URL for management console rest calls | `http://{{ keycloak_quarkus_host }}:{{ keycloak_management_http_port }}` | |`keycloak_quarkus_log`| Enable one or more log handlers in a comma-separated list | `file` | |`keycloak_quarkus_log_level`| The log level of the root category or a comma-separated list of individual categories and their levels | `info` | |`keycloak_quarkus_log_file`| Set the log file path and filename relative to keycloak home | `data/log/keycloak.log` | From bfd9db6703daf0550f3910c44840331bc04a345b Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Mon, 8 Jan 2024 17:42:30 +0100 Subject: [PATCH 313/554] fix/147: keycloak_quarkus: RBKC: Add support for sqlserver jdbc driver --- roles/keycloak_quarkus/README.md | 2 +- roles/keycloak_quarkus/defaults/main.yml | 5 ++++- roles/keycloak_quarkus/meta/argument_specs.yml | 2 +- roles/keycloak_quarkus/tasks/install.yml | 6 ++++++ roles/keycloak_quarkus/tasks/jdbc_driver.yml | 12 ++++++++++++ 5 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 roles/keycloak_quarkus/tasks/jdbc_driver.yml diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index c2338c3..acdb121 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -55,7 +55,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_jdbc_engine` | Database engine [mariadb,postres] | `postgres` | +|`keycloak_quarkus_jdbc_engine` | Database engine [mariadb,postres,mssql] | `postgres` | |`keycloak_quarkus_db_user` | User for database connection | `keycloak-user` | |`keycloak_quarkus_db_pass` | Password for database connection | `keycloak-pass` | |`keycloak_quarkus_jdbc_url` | JDBC URL for connecting to database | `jdbc:postgresql://localhost:5432/keycloak` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 51ca792..1c7a41b 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -97,7 +97,10 @@ keycloak_quarkus_default_jdbc: mariadb: url: 'jdbc:mariadb://localhost:3306/keycloak' version: 2.7.4 - + mssql: + url: 'jdbc:sqlserver://localhost:1433;databaseName=keycloak;' + version: 12.2.0 + driver_jar_url: "https://repo1.maven.org/maven2/com/microsoft/sqlserver/mssql-jdbc/12.2.0.jre11/mssql-jdbc-12.2.0.jre11.jar" # cf. https://access.redhat.com/documentation/en-us/red_hat_build_of_keycloak/22.0/html/server_guide/db-#db-installing-the-microsoft-sql-server-driver ### logging configuration keycloak_quarkus_log: file keycloak_quarkus_log_level: info diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index d260910..accd770 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -234,7 +234,7 @@ argument_specs: keycloak_quarkus_jdbc_engine: # line 56 of defaults/main.yml default: "postgres" - description: "Database engine [mariadb,postres]" + description: "Database engine [mariadb,postres,mssql]" type: "str" keycloak_quarkus_db_user: # line 58 of defaults/main.yml diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index b1ea1ee..ebd8585 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -109,3 +109,9 @@ msg: "{{ keycloak.home }} already exists and version unchanged, skipping decompression" when: - (not new_version_downloaded.changed) and path_to_workdir.stat.exists + +- name: "Install {{ keycloak_quarkus_jdbc_engine }} JDBC driver" + ansible.builtin.include_tasks: jdbc_driver.yml + when: + - rhbk_enable is defined and rhbk_enable + - keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url is defined diff --git a/roles/keycloak_quarkus/tasks/jdbc_driver.yml b/roles/keycloak_quarkus/tasks/jdbc_driver.yml new file mode 100644 index 0000000..0d03030 --- /dev/null +++ b/roles/keycloak_quarkus/tasks/jdbc_driver.yml @@ -0,0 +1,12 @@ +--- + +- name: "Retrieve JDBC Driver from {{ keycloak_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url }}" + ansible.builtin.get_url: + url: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url }}" + dest: "{{ keycloak.home }}/providers" + owner: "{{ keycloak.service_user }}" + group: "{{ keycloak.service_group }}" + mode: 0640 + become: true + notify: + - restart keycloak From b057f0297ac6c79794bbf13f5318a85798fe5073 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Tue, 9 Jan 2024 08:20:02 +0100 Subject: [PATCH 314/554] fix/#151: keycloak_quarkus: allow configuration of `hostname-strict-backchannel` --- roles/keycloak_quarkus/README.md | 1 + roles/keycloak_quarkus/defaults/main.yml | 3 +++ roles/keycloak_quarkus/meta/argument_specs.yml | 4 ++++ roles/keycloak_quarkus/templates/keycloak.conf.j2 | 1 + 4 files changed, 9 insertions(+) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 9a04e1b..623ca28 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -56,6 +56,7 @@ Role Defaults |:---------|:------------|:--------| |`keycloak_quarkus_http_relative_path`| Set the path relative to / for serving resources. The path must start with a / | `/` | |`keycloak_quarkus_hostname_strict`| Disables dynamically resolving the hostname from request headers | `true` | +|`keycloak_quarkus_hostname_strict_backchannel`| By default backchannel URLs are dynamically resolved from request headers to allow internal and external applications. If all applications use the public URL this option should be enabled. | `false` | * Database configuration diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index a4f1d5e..46cce41 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -66,6 +66,9 @@ keycloak_quarkus_http_relative_path: / # Disables dynamically resolving the hostname from request headers. # Should always be set to true in production, unless proxy verifies the Host header. keycloak_quarkus_hostname_strict: true +# By default backchannel URLs are dynamically resolved from request headers to allow internal and external applications. +# If all applications use the public URL this option should be enabled. +keycloak_quarkus_hostname_strict_backchannel: false # proxy address forwarding mode if the server is behind a reverse proxy. [none, edge, reencrypt, passthrough] keycloak_quarkus_proxy_mode: edge diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 6fdd108..e975696 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -292,6 +292,10 @@ argument_specs: default: true type: "bool" description: "Disables dynamically resolving the hostname from request headers. Should always be set to true in production, unless proxy verifies the Host header." + keycloak_quarkus_hostname_strict_backchannel: + default: false + type: "bool" + description: "By default backchannel URLs are dynamically resolved from request headers to allow internal and external applications. If all applications use the public URL this option should be enabled." downstream: options: rhbk_version: diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index b3b6787..8ea545d 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -42,6 +42,7 @@ hostname-path={{ keycloak_quarkus_path }} {% endif %} hostname-admin-url={{ keycloak_quarkus_admin_url }} hostname-strict={{ keycloak_quarkus_hostname_strict | lower }} +hostname-strict-backchannel={{ keycloak_quarkus_hostname_strict_backchannel | lower }} # Cluster {% if keycloak_quarkus_ha_enabled %} From b1b31427d50b88f0e9f039b54a046245290338f5 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Wed, 10 Jan 2024 16:26:46 +0100 Subject: [PATCH 315/554] fix/#153: keycloak_quarkus: Use `keycloak_quarkus_java_opts` Note: when multiple -X options of the same kind are provided, the last option seems to take precendence as per : > java -Xmx1G -XX:+PrintFlagsFinal -Xmx2G 2>/dev/null | grep MaxHeapSize --- roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 | 1 + 1 file changed, 1 insertion(+) diff --git a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 index a3fdf57..b028085 100644 --- a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 +++ b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 @@ -3,3 +3,4 @@ KEYCLOAK_ADMIN={{ keycloak_quarkus_admin_user }} KEYCLOAK_ADMIN_PASSWORD='{{ keycloak_quarkus_admin_pass }}' PATH={{ keycloak_java_home | default(keycloak_rpm_java_home, true) }}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin JAVA_HOME={{ keycloak_java_home | default(keycloak_rpm_java_home, true) }} +JAVA_OPTS_APPEND={{ keycloak_quarkus_java_opts }} \ No newline at end of file From 922e4c10f5557b341aa929da03d2f68ef8a86235 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Mon, 15 Jan 2024 14:40:46 +0100 Subject: [PATCH 316/554] #145 - CR changes --- galaxy.yml | 1 + roles/keycloak_quarkus/README.md | 1 - roles/keycloak_quarkus/meta/argument_specs.yml | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/galaxy.yml b/galaxy.yml index ac09faa..21cb096 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -7,6 +7,7 @@ authors: - Romain Pelisse - Guido Grazioli - Pavan Kumar Motaparthi + - Helmut Wolf description: Install and configure a keycloak, or Red Hat Single Sign-on, service. license_file: "LICENSE" tags: diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index e419d89..9fdb2e0 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -90,7 +90,6 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:---------| |`keycloak_quarkus_offline_install` | Perform an offline install | `False`| -|`keycloak_quarkus_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| |`keycloak_quarkus_version`| keycloak.org package version | `23.0.1` | |`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` | |`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` | diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index f616611..3ad24f8 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -71,7 +71,7 @@ argument_specs: type: "bool" keycloak_service_restart_always: default: false - description: "systemd restart always behavior of service" + description: "systemd restart always behavior of service; takes precedence over keycloak_service_restart_on_failure if true" type: "bool" keycloak_service_restart_on_failure: default: false From 8adc018cb317fe172d783f731e5c347b884a1aae Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Mon, 8 Jan 2024 18:19:00 +0100 Subject: [PATCH 317/554] fix/#149: keycloak_quarkus: Allow ports <1024 (e.g., :443) --- roles/keycloak_quarkus/templates/keycloak.service.j2 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/roles/keycloak_quarkus/templates/keycloak.service.j2 b/roles/keycloak_quarkus/templates/keycloak.service.j2 index 1854463..a529c5b 100644 --- a/roles/keycloak_quarkus/templates/keycloak.service.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.service.j2 @@ -20,6 +20,9 @@ Restart=always Restart=on-failure {% endif %} RestartSec={{ keycloak_quarkus_service_restartsec }} +{% if keycloak_quarkus_http_port|int < 1024 or keycloak_quarkus_https_port|int < 1024 %} +AmbientCapabilities=CAP_NET_BIND_SERVICE +{% endif %} [Install] WantedBy=multi-user.target From 30309582f37439893c33939cd2081845f6e7b63b Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 16 Jan 2024 09:17:47 +0100 Subject: [PATCH 318/554] Update README.md --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 0cb62c2..0cd3ba0 100644 --- a/README.md +++ b/README.md @@ -3,10 +3,10 @@ [![Build Status](https://github.com/ansible-middleware/keycloak/workflows/CI/badge.svg?branch=main)](https://github.com/ansible-middleware/keycloak/actions/workflows/ci.yml) -> **_NOTE:_ If you are Red Hat customer, install `redhat.sso` from [Automation Hub](https://console.redhat.com/ansible/ansible-dashboard) as the certified version of this collection.** +> **_NOTE:_ If you are Red Hat customer, install `redhat.sso` (for Red Hat Single Sign-On) or `redhat.rhbk` (for Red Hat Build of Keycloak) from [Automation Hub](https://console.redhat.com/ansible/ansible-dashboard) as the certified version of this collection.** -Collection to install and configure [Keycloak](https://www.keycloak.org/) or [Red Hat Single Sign-On](https://access.redhat.com/products/red-hat-single-sign-on). +Collection to install and configure [Keycloak](https://www.keycloak.org/) or [Red Hat Single Sign-On](https://access.redhat.com/products/red-hat-single-sign-on) / [Red Hat Build of Keycloak](https://access.redhat.com/products/red-hat-build-of-keycloak). ## Ansible version compatibility @@ -47,7 +47,7 @@ A requirement file is provided to install: ### Included roles -* [`keycloak`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak/README.md): role for installing the service. +* [`keycloak`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak/README.md): role for installing the service (keycloak <= 19.0). * [`keycloak_realm`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak_realm/README.md): role for configuring a realm, user federation(s), clients and users, in an installed service. * [`keycloak_quarkus`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak_quarkus/README.md): role for installing the quarkus variant of keycloak (>= 17.0.0). @@ -57,8 +57,9 @@ A requirement file is provided to install: ### Install Playbook -* [`playbooks/keycloak.yml`](https://github.com/ansible-middleware/keycloak/blob/main/playbooks/keycloak.yml) installs based on the defined variables (using most defaults). - +* [`playbooks/keycloak.yml`](https://github.com/ansible-middleware/keycloak/blob/main/playbooks/keycloak.yml) installs keycloak legacy based on the defined variables (using most defaults). +* [`playbooks/keycloak_quarkus.yml`](https://github.com/ansible-middleware/keycloak/blob/main/playbooks/keycloak_quarkus.yml) installs keycloak >= 17 based on the defined variables (using most defaults). + Both playbooks include the `keycloak` role, with different settings, as described in the following sections. For full service configuration details, refer to the [keycloak role README](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak/README.md). From 2985f808ea4cb62019a294d399f454fbe4a5c306 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Wed, 17 Jan 2024 08:50:24 +0000 Subject: [PATCH 319/554] Update changelog for release 2.0.2 Signed-off-by: ansible-middleware-core --- CHANGELOG.rst | 16 ++++++++++++++++ changelogs/changelog.yaml | 27 +++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 274cfa3..c3a46da 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,22 @@ middleware_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v2.0.2 +====== + +Minor Changes +------------- + +- keycloak_quarkus: Add support for sqlserver jdbc driver `#148 `_ +- keycloak_quarkus: allow configuration of ``hostname-strict-backchannel`` `#152 `_ +- keycloak_quarkus: systemd restart behavior `#145 `_ + +Bugfixes +-------- + +- keycloak_quarkus: Use ``keycloak_quarkus_java_opts`` `#154 `_ +- keycloak_quarkus: allow ports <1024 (e.g. :443) in systemd unit `#150 `_ + v2.0.1 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 7d19d7f..7d684cd 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -359,3 +359,30 @@ releases: - 138.yaml - 139.yaml release_date: '2023-12-07' + 2.0.2: + changes: + bugfixes: + - 'keycloak_quarkus: Use ``keycloak_quarkus_java_opts`` `#154 `_ + + ' + - 'keycloak_quarkus: allow ports <1024 (e.g. :443) in systemd unit `#150 `_ + + ' + minor_changes: + - 'keycloak_quarkus: Add support for sqlserver jdbc driver `#148 `_ + + ' + - 'keycloak_quarkus: allow configuration of ``hostname-strict-backchannel`` + `#152 `_ + + ' + - 'keycloak_quarkus: systemd restart behavior `#145 `_ + + ' + fragments: + - 145.yaml + - 148.yaml + - 150.yaml + - 152.yaml + - 154.yaml + release_date: '2024-01-17' From e866d1f4e417a0d7d02216ebdff5f8554980f401 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Wed, 17 Jan 2024 08:50:31 +0000 Subject: [PATCH 320/554] Bump version to 2.0.3 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 21cb096..b5c1a2b 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "2.0.2" +version: "2.0.3" readme: README.md authors: - Romain Pelisse From 688ec956fc6df2a77e0eb81b133896cf673ecf82 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Wed, 17 Jan 2024 16:51:24 +0100 Subject: [PATCH 321/554] fix #156: quarkus 3 ispn config renamings --- galaxy.yml | 2 +- roles/keycloak_quarkus/README.md | 2 +- roles/keycloak_quarkus/defaults/main.yml | 2 +- roles/keycloak_quarkus/meta/argument_specs.yml | 6 +++--- .../templates/quarkus.properties.j2 | 14 +++++++++----- 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/galaxy.yml b/galaxy.yml index b5c1a2b..6a1d110 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "2.0.3" +version: "2.1.0" readme: README.md authors: - Romain Pelisse diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index e0a189b..cd720a5 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -79,7 +79,7 @@ Role Defaults |:---------|:------------|:--------| |`keycloak_quarkus_ispn_user` | Username for connecting to infinispan | `supervisor` | |`keycloak_quarkus_ispn_pass` | Password for connecting to infinispan | `supervisor` | -|`keycloak_quarkus_ispn_url` | URL for connecting to infinispan | `localhost` | +|`keycloak_quarkus_ispn_hosts` | host name/port for connecting to infinispan, eg. host1:11222;host2:11222 | `localhost:11222` | |`keycloak_quarkus_ispn_sasl_mechanism` | Infinispan auth mechanism | `SCRAM-SHA-512` | |`keycloak_quarkus_ispn_use_ssl` | Whether infinispan uses TLS connection | `false` | |`keycloak_quarkus_ispn_trust_store_path` | Path to infinispan server trust certificate | `/etc/pki/java/cacerts` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index bcc03ee..da42960 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -85,7 +85,7 @@ keycloak_quarkus_health_enabled: true ### infinispan remote caches access (hotrod) keycloak_quarkus_ispn_user: supervisor keycloak_quarkus_ispn_pass: supervisor -keycloak_quarkus_ispn_url: localhost +keycloak_quarkus_ispn_hosts: "localhost:11222" keycloak_quarkus_ispn_sasl_mechanism: SCRAM-SHA-512 keycloak_quarkus_ispn_use_ssl: false # if ssl is enabled, import ispn server certificate here diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 22a9b45..37c873e 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -218,10 +218,10 @@ argument_specs: default: "supervisor" description: "Password for connecting to infinispan" type: "str" - keycloak_quarkus_ispn_url: + keycloak_quarkus_ispn_hosts: # line 48 of defaults/main.yml - default: "localhost" - description: "URL for connecting to infinispan" + default: "localhost:11222" + description: "host name/port for connecting to infinispan, eg. host1:11222;host2:11222" type: "str" keycloak_quarkus_ispn_sasl_mechanism: # line 49 of defaults/main.yml diff --git a/roles/keycloak_quarkus/templates/quarkus.properties.j2 b/roles/keycloak_quarkus/templates/quarkus.properties.j2 index cf133a3..cb2f2d3 100644 --- a/roles/keycloak_quarkus/templates/quarkus.properties.j2 +++ b/roles/keycloak_quarkus/templates/quarkus.properties.j2 @@ -1,10 +1,16 @@ # {{ ansible_managed }} {% if keycloak_quarkus_ha_enabled %} -quarkus.infinispan-client.server-list={{ keycloak_quarkus_ispn_url }} -quarkus.infinispan-client.client-intelligence=HASH_DISTRIBUTION_AWARE -quarkus.infinispan-client.use-auth=true +{% if not rhbk_enable or keycloak_quarkus_version.split('.')[0]|int < 22 %} +quarkus.infinispan-client.server-list={{ keycloak_quarkus_ispn_hosts }} quarkus.infinispan-client.auth-username={{ keycloak_quarkus_ispn_user }} quarkus.infinispan-client.auth-password={{ keycloak_quarkus_ispn_pass }} +{% else %} +quarkus.infinispan-client.hosts={{ keycloak_quarkus_ispn_hosts }} +quarkus.infinispan-client.username={{ keycloak_quarkus_ispn_user }} +quarkus.infinispan-client.password={{ keycloak_quarkus_ispn_pass }} +{% endif %} +quarkus.infinispan-client.client-intelligence=HASH_DISTRIBUTION_AWARE +quarkus.infinispan-client.use-auth=true quarkus.infinispan-client.auth-realm=default quarkus.infinispan-client.auth-server-name=infinispan quarkus.infinispan-client.sasl-mechanism={{ keycloak_quarkus_ispn_sasl_mechanism }} @@ -14,6 +20,4 @@ quarkus.infinispan-client.trust-store-password={{ keycloak_quarkus_ispn_trust_st quarkus.infinispan-client.trust-store-type=jks {% endif %} #quarkus.infinispan-client.use-schema-registration=true -#quarkus.infinispan-client.auth-client-subject -#quarkus.infinispan-client.auth-callback-handler {% endif %} \ No newline at end of file From 63f83d77445feb698f4ea784ea370489f781ee14 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Wed, 17 Jan 2024 17:22:06 +0100 Subject: [PATCH 322/554] add initial support for templating `cache-ispn.xml` --- roles/keycloak_quarkus/tasks/main.yml | 11 +++ .../keycloak_quarkus/templates/cache-ispn.xml | 85 +++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 roles/keycloak_quarkus/templates/cache-ispn.xml diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index 71582f8..394cf3b 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -43,6 +43,17 @@ notify: - restart keycloak +- name: "Configure infinispan config for keycloak service" + ansible.builtin.template: + src: cache-ispn.xml + dest: "{{ keycloak.home }}/conf/cache-ispn.xml" + owner: "{{ keycloak.service_user }}" + group: "{{ keycloak.service_group }}" + mode: 0644 + become: true + notify: + - restart keycloak + - name: Ensure logdirectory exists ansible.builtin.file: state: directory diff --git a/roles/keycloak_quarkus/templates/cache-ispn.xml b/roles/keycloak_quarkus/templates/cache-ispn.xml new file mode 100644 index 0000000..20a1af7 --- /dev/null +++ b/roles/keycloak_quarkus/templates/cache-ispn.xml @@ -0,0 +1,85 @@ +# {{ ansible_managed }} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 0c5047bcc109393e63a707d903edea0d0f82bdb9 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Mon, 22 Jan 2024 13:53:28 +0100 Subject: [PATCH 323/554] feature/160: keycloak_quarkus: Allow easier log setting configuration --- roles/keycloak_quarkus/README.md | 3 +++ roles/keycloak_quarkus/defaults/main.yml | 3 +++ roles/keycloak_quarkus/meta/argument_specs.yml | 12 ++++++++++++ .../keycloak_quarkus/templates/quarkus.properties.j2 | 5 ++++- 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index cd720a5..80eef90 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -116,6 +116,9 @@ Role Defaults |`keycloak_quarkus_log_file`| Set the log file path and filename relative to keycloak home | `data/log/keycloak.log` | |`keycloak_quarkus_log_format`| Set a format specific to file log entries | `%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n` | |`keycloak_quarkus_log_target`| Set the destination of the keycloak log folder link | `/var/log/keycloak` | +|`keycloak_quarkus_log_max_file_size`| Set the maximum log file size before a log rotation happens; A size configuration option recognises string in this format (shown as a regular expression): [0-9]+[KkMmGgTtPpEeZzYy]?. If no suffix is given, assume bytes." | `10M` +|`keycloak_quarkus_log_max_backup_index`| Set the maximum number of archived log files to keep" | `10` +|`keycloak_quarkus_log_file_suffix`| Set the log file handler rotation file suffix. When used, the file will be rotated based on its suffix; Note: If the suffix ends with `.zip` or `.gz`, the rotation file will also be compressed." | `.yyyy-MM-dd.zip` |`keycloak_quarkus_proxy_mode`| The proxy address forwarding mode if the server is behind a reverse proxy | `edge` | |`keycloak_quarkus_start_dev`| Whether to start the service in development mode (start-dev) | `False` | |`keycloak_quarkus_transaction_xa_enabled`| Whether to use XA transactions | `True` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index da42960..fa85d98 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -117,3 +117,6 @@ keycloak_quarkus_log_level: info keycloak_quarkus_log_file: data/log/keycloak.log keycloak_quarkus_log_format: '%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n' keycloak_quarkus_log_target: /var/log/keycloak +keycloak_quarkus_log_max_file_size: 10M +keycloak_quarkus_log_max_backup_index: 10 +keycloak_quarkus_log_file_suffix: '.yyyy-MM-dd.zip' diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 37c873e..f7b49e3 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -288,6 +288,18 @@ argument_specs: default: '/var/log/keycloak' type: "str" description: "Set the destination of the keycloak log folder link" + keycloak_quarkus_log_max_file_size: + default: 10M + type: "str" + description: "Set the maximum log file size before a log rotation happens; A size configuration option recognises string in this format (shown as a regular expression): [0-9]+[KkMmGgTtPpEeZzYy]?. If no suffix is given, assume bytes." + keycloak_quarkus_log_max_backup_index: + default: 10 + type: "str" + description: "Set the maximum number of archived log files to keep" + keycloak_quarkus_log_file_suffix: + default: '.yyyy-MM-dd.zip' + type: "str" + description: "Set the log file handler rotation file suffix. When used, the file will be rotated based on its suffix; Note: If the suffix ends with .zip or .gz, the rotation file will also be compressed." keycloak_quarkus_proxy_mode: default: 'edge' type: "str" diff --git a/roles/keycloak_quarkus/templates/quarkus.properties.j2 b/roles/keycloak_quarkus/templates/quarkus.properties.j2 index cb2f2d3..f8502f2 100644 --- a/roles/keycloak_quarkus/templates/quarkus.properties.j2 +++ b/roles/keycloak_quarkus/templates/quarkus.properties.j2 @@ -20,4 +20,7 @@ quarkus.infinispan-client.trust-store-password={{ keycloak_quarkus_ispn_trust_st quarkus.infinispan-client.trust-store-type=jks {% endif %} #quarkus.infinispan-client.use-schema-registration=true -{% endif %} \ No newline at end of file +{% endif %} +quarkus.log.file.rotation.max-file-size={{ keycloak_quarkus_log_max_file_size }} +quarkus.log.file.rotation.max-backup-index={{ keycloak_quarkus_log_max_backup_index }} +quarkus.log.file.rotation.file-suffix={{ keycloak_quarkus_log_file_suffix }} \ No newline at end of file From c2009a0a12d28e6fa8114d22c11a3214caceea7b Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Thu, 8 Feb 2024 16:10:32 +0100 Subject: [PATCH 324/554] feature/160: CR changes --- roles/keycloak_quarkus/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 80eef90..1f222a6 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -116,9 +116,9 @@ Role Defaults |`keycloak_quarkus_log_file`| Set the log file path and filename relative to keycloak home | `data/log/keycloak.log` | |`keycloak_quarkus_log_format`| Set a format specific to file log entries | `%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n` | |`keycloak_quarkus_log_target`| Set the destination of the keycloak log folder link | `/var/log/keycloak` | -|`keycloak_quarkus_log_max_file_size`| Set the maximum log file size before a log rotation happens; A size configuration option recognises string in this format (shown as a regular expression): [0-9]+[KkMmGgTtPpEeZzYy]?. If no suffix is given, assume bytes." | `10M` -|`keycloak_quarkus_log_max_backup_index`| Set the maximum number of archived log files to keep" | `10` -|`keycloak_quarkus_log_file_suffix`| Set the log file handler rotation file suffix. When used, the file will be rotated based on its suffix; Note: If the suffix ends with `.zip` or `.gz`, the rotation file will also be compressed." | `.yyyy-MM-dd.zip` +|`keycloak_quarkus_log_max_file_size`| Set the maximum log file size before a log rotation happens; A size configuration option recognises string in this format (shown as a regular expression): `[0-9]+[KkMmGgTtPpEeZzYy]?`. If no suffix is given, assume bytes. | `10M` | +|`keycloak_quarkus_log_max_backup_index`| Set the maximum number of archived log files to keep" | `10` | +|`keycloak_quarkus_log_file_suffix`| Set the log file handler rotation file suffix. When used, the file will be rotated based on its suffix; Note: If the suffix ends with `.zip` or `.gz`, the rotation file will also be compressed. | `.yyyy-MM-dd.zip` | |`keycloak_quarkus_proxy_mode`| The proxy address forwarding mode if the server is behind a reverse proxy | `edge` | |`keycloak_quarkus_start_dev`| Whether to start the service in development mode (start-dev) | `False` | |`keycloak_quarkus_transaction_xa_enabled`| Whether to use XA transactions | `True` | From e0d4920a490c8248174ad70b536c627331b342ef Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Mon, 22 Jan 2024 14:06:38 +0100 Subject: [PATCH 325/554] feature/162: keycloak_quarkus: make `spi-sticky-session-encoder-infinispan-should-attach-route` configurable in `keycloak.conf` --- roles/keycloak_quarkus/README.md | 2 +- roles/keycloak_quarkus/defaults/main.yml | 3 +++ roles/keycloak_quarkus/meta/argument_specs.yml | 4 ++++ roles/keycloak_quarkus/templates/keycloak.conf.j2 | 3 +-- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index cd720a5..8a32909 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -119,7 +119,7 @@ Role Defaults |`keycloak_quarkus_proxy_mode`| The proxy address forwarding mode if the server is behind a reverse proxy | `edge` | |`keycloak_quarkus_start_dev`| Whether to start the service in development mode (start-dev) | `False` | |`keycloak_quarkus_transaction_xa_enabled`| Whether to use XA transactions | `True` | - +|`keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route`| If the route should be attached to cookies to reflect the node that owns a particular session. If false, route is not attached to cookies and we rely on the session affinity capabilities from reverse proxy | `True` | Role Variables -------------- diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index da42960..a2141bc 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -79,6 +79,9 @@ keycloak_quarkus_proxy_mode: edge # disable xa transactions keycloak_quarkus_transaction_xa_enabled: true +# If the route should be attached to cookies to reflect the node that owns a particular session. If false, route is not attached to cookies and we rely on the session affinity capabilities from reverse proxy +keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route: true + keycloak_quarkus_metrics_enabled: false keycloak_quarkus_health_enabled: true diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 37c873e..5760c7d 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -308,6 +308,10 @@ argument_specs: default: false type: "bool" description: "By default backchannel URLs are dynamically resolved from request headers to allow internal and external applications. If all applications use the public URL this option should be enabled." + keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route: + default: true + type: "bool" + description: "If the route should be attached to cookies to reflect the node that owns a particular session. If false, route is not attached to cookies and we rely on the session affinity capabilities from reverse proxy" downstream: options: rhbk_version: diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index 8ea545d..9d6aaaa 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -55,8 +55,7 @@ cache-stack=tcp # Proxy proxy={{ keycloak_quarkus_proxy_mode }} {% endif %} -# Do not attach route to cookies and rely on the session affinity capabilities from reverse proxy -#spi-sticky-session-encoder-infinispan-should-attach-route=false +spi-sticky-session-encoder-infinispan-should-attach-route={{ keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route | d(true) | lower }} # Transaction transaction-xa-enabled={{ keycloak_quarkus_transaction_xa_enabled | lower }} From 4adab64dc0ca52e36e5963b013de330331d7aedc Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Mon, 22 Jan 2024 09:28:00 +0100 Subject: [PATCH 326/554] #158: support for TCPPING --- roles/keycloak_quarkus/README.md | 3 ++- roles/keycloak_quarkus/defaults/main.yml | 3 ++- roles/keycloak_quarkus/handlers/main.yml | 4 ++++ roles/keycloak_quarkus/meta/argument_specs.yml | 6 +++++- roles/keycloak_quarkus/tasks/main.yml | 16 ++++++++++++++++ roles/keycloak_quarkus/tasks/rebuild_config.yml | 7 +++++++ .../templates/keycloak.service.j2 | 2 +- 7 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 roles/keycloak_quarkus/tasks/rebuild_config.yml diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index cd720a5..a554254 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -19,6 +19,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| |`keycloak_quarkus_ha_enabled`| Enable auto configuration for database backend, clustering and remote caches on infinispan | `False` | +|`keycloak_quarkus_ha_discovery`| Discovery protocol for HA cluster members | `TCPPING` | |`keycloak_quarkus_db_enabled`| Enable auto configuration for database backend | `True` if `keycloak_quarkus_ha_enabled` is True, else `False` | |`keycloak_quarkus_admin_user`| Administration console user account | `admin` | |`keycloak_quarkus_bind_address`| Address for binding service ports | `0.0.0.0` | @@ -28,7 +29,7 @@ Role Defaults |`keycloak_quarkus_http_port`| HTTP listening port | `8080` | |`keycloak_quarkus_https_port`| TLS HTTP listening port | `8443` | |`keycloak_quarkus_ajp_port`| AJP port | `8009` | -|`keycloak_quarkus_jgroups_port`| jgroups cluster tcp port | `7600` | +|`keycloak_quarkus_jgroups_port`| jgroups cluster tcp port | `7800` | |`keycloak_quarkus_service_user`| Posix account username | `keycloak` | |`keycloak_quarkus_service_group`| Posix account group | `keycloak` | |`keycloak_quarkus_service_restart_always`| systemd restart always behavior activation | `False` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index da42960..07d83b7 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -37,7 +37,7 @@ keycloak_quarkus_http_enabled: true keycloak_quarkus_http_port: 8080 keycloak_quarkus_https_port: 8443 keycloak_quarkus_ajp_port: 8009 -keycloak_quarkus_jgroups_port: 7600 +keycloak_quarkus_jgroups_port: 7800 keycloak_quarkus_java_opts: "-Xms1024m -Xmx2048m" ### TLS/HTTPS configuration @@ -55,6 +55,7 @@ keycloak_quarkus_trust_store_password: '' ### Enable configuration for database backend, clustering and remote caches on infinispan keycloak_quarkus_ha_enabled: false +keycloak_quarkus_ha_discovery: "TCPPING" ### Enable database configuration, must be enabled when HA is configured keycloak_quarkus_db_enabled: "{{ True if keycloak_quarkus_ha_enabled else False }}" diff --git a/roles/keycloak_quarkus/handlers/main.yml b/roles/keycloak_quarkus/handlers/main.yml index 00cab00..6cbe276 100644 --- a/roles/keycloak_quarkus/handlers/main.yml +++ b/roles/keycloak_quarkus/handlers/main.yml @@ -1,4 +1,8 @@ --- +# handler should be invoked anytime a [build configuration](https://www.keycloak.org/server/all-config?f=build) changes +- name: "Rebuild {{ keycloak.service_name }} config" + ansible.builtin.include_tasks: rebuild_config.yml + listen: "rebuild keycloak config" - name: "Restart {{ keycloak.service_name }}" ansible.builtin.include_tasks: restart.yml listen: "restart keycloak" \ No newline at end of file diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 37c873e..1d371ed 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -168,7 +168,7 @@ argument_specs: type: "int" keycloak_quarkus_jgroups_port: # line 32 of defaults/main.yml - default: 7600 + default: 7800 description: "jgroups cluster tcp port" type: "int" keycloak_quarkus_java_opts: @@ -181,6 +181,10 @@ argument_specs: default: false description: "Enable auto configuration for database backend, clustering and remote caches on infinispan" type: "bool" + keycloak_quarkus_ha_discovery: + default: "TCPPING" + description: "Discovery protocol for HA cluster members" + type: "str" keycloak_quarkus_db_enabled: # line 38 of defaults/main.yml default: "{{ True if keycloak_quarkus_ha_enabled else False }}" diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index 394cf3b..c65ab59 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -30,6 +30,7 @@ mode: 0644 become: true notify: + - rebuild keycloak config - restart keycloak - name: "Configure quarkus config for keycloak service" @@ -43,6 +44,20 @@ notify: - restart keycloak +- name: Create tcpping cluster node list + ansible.builtin.set_fact: + keycloak_quarkus_cluster_nodes: > + {{ keycloak_quarkus_cluster_nodes | default([]) + [ + { + "name": item, + "address": 'jgroups-' + item, + "inventory_host": hostvars[item].ansible_default_ipv4.address | default(item) + '[' + (keycloak_quarkus_jgroups_port | string) + ']', + "value": hostvars[item].ansible_default_ipv4.address | default(item) + } + ] }} + loop: "{{ ansible_play_batch }}" + when: keycloak_quarkus_ha_enabled and keycloak_quarkus_ha_discovery == 'TCPPING' + - name: "Configure infinispan config for keycloak service" ansible.builtin.template: src: cache-ispn.xml @@ -52,6 +67,7 @@ mode: 0644 become: true notify: + - rebuild keycloak config - restart keycloak - name: Ensure logdirectory exists diff --git a/roles/keycloak_quarkus/tasks/rebuild_config.yml b/roles/keycloak_quarkus/tasks/rebuild_config.yml new file mode 100644 index 0000000..5a715c6 --- /dev/null +++ b/roles/keycloak_quarkus/tasks/rebuild_config.yml @@ -0,0 +1,7 @@ +--- +# cf. https://www.keycloak.org/server/configuration#_optimize_the_keycloak_startup +- name: "Rebuild {{ keycloak.service_name }} config" + ansible.builtin.shell: | + {{ keycloak.home }}/bin/kc.sh build + become: true + changed_when: true diff --git a/roles/keycloak_quarkus/templates/keycloak.service.j2 b/roles/keycloak_quarkus/templates/keycloak.service.j2 index a529c5b..5b90986 100644 --- a/roles/keycloak_quarkus/templates/keycloak.service.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.service.j2 @@ -10,7 +10,7 @@ PIDFile={{ keycloak_quarkus_service_pidfile }} {% if keycloak_quarkus_start_dev %} ExecStart={{ keycloak.home }}/bin/kc.sh start-dev {% else %} -ExecStart={{ keycloak.home }}/bin/kc.sh start --log={{ keycloak_quarkus_log }} +ExecStart={{ keycloak.home }}/bin/kc.sh start --optimized {% endif %} User={{ keycloak.service_user }} Group={{ keycloak.service_group }} From df81dc54971fbcab930431fe4312f10569bfd14b Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Mon, 22 Jan 2024 11:15:04 +0100 Subject: [PATCH 327/554] #158: move TCPPING config to ispn config file --- .../keycloak_quarkus/templates/cache-ispn.xml | 20 +++++++++++++++++-- .../templates/keycloak.conf.j2 | 4 +++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/roles/keycloak_quarkus/templates/cache-ispn.xml b/roles/keycloak_quarkus/templates/cache-ispn.xml index 20a1af7..67514d3 100644 --- a/roles/keycloak_quarkus/templates/cache-ispn.xml +++ b/roles/keycloak_quarkus/templates/cache-ispn.xml @@ -1,4 +1,4 @@ -# {{ ansible_managed }} + + + + +{% endif %} + - + diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index 8ea545d..81acce9 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -48,7 +48,9 @@ hostname-strict-backchannel={{ keycloak_quarkus_hostname_strict_backchannel | lo {% if keycloak_quarkus_ha_enabled %} cache=ispn cache-config-file=cache-ispn.xml -cache-stack=tcp +{% if keycloak_quarkus_ha_enabled and keycloak_quarkus_ha_discovery == 'TCPPING' %} +# cache-stack=tcp # configured directly in `cache-ispn.xml` +{% endif %} {% endif %} {% if keycloak_quarkus_proxy_mode is defined and keycloak_quarkus_proxy_mode != "none" %} From f7bef0a956dbb5fefa1dea2b27888e3d306c852e Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 22 Feb 2024 16:28:24 +0100 Subject: [PATCH 328/554] set enable-recovery when xa transactions are enabled --- roles/keycloak_quarkus/templates/quarkus.properties.j2 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/templates/quarkus.properties.j2 b/roles/keycloak_quarkus/templates/quarkus.properties.j2 index f8502f2..7ef1db7 100644 --- a/roles/keycloak_quarkus/templates/quarkus.properties.j2 +++ b/roles/keycloak_quarkus/templates/quarkus.properties.j2 @@ -23,4 +23,7 @@ quarkus.infinispan-client.trust-store-type=jks {% endif %} quarkus.log.file.rotation.max-file-size={{ keycloak_quarkus_log_max_file_size }} quarkus.log.file.rotation.max-backup-index={{ keycloak_quarkus_log_max_backup_index }} -quarkus.log.file.rotation.file-suffix={{ keycloak_quarkus_log_file_suffix }} \ No newline at end of file +quarkus.log.file.rotation.file-suffix={{ keycloak_quarkus_log_file_suffix }} +{% if keycloak_quarkus_db_enabled %} +quarkus.transaction-manager.enable-recovery=true +{% endif %} From d4fb20b230797a53f54518dca78db5dec1c700d7 Mon Sep 17 00:00:00 2001 From: Footur <3769085+Footur@users.noreply.github.com> Date: Thu, 22 Feb 2024 17:10:22 +0100 Subject: [PATCH 329/554] Update Keycloak to version 23.0.7 --- roles/keycloak_quarkus/README.md | 4 ++-- roles/keycloak_quarkus/defaults/main.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 2dd7ca0..7c01eae 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -11,7 +11,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_version`| keycloak.org package version | `23.0.1` | +|`keycloak_quarkus_version`| keycloak.org package version | `23.0.7` | * Service configuration @@ -92,7 +92,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:---------| |`keycloak_quarkus_offline_install` | Perform an offline install | `False`| -|`keycloak_quarkus_version`| keycloak.org package version | `23.0.1` | +|`keycloak_quarkus_version`| keycloak.org package version | `23.0.7` | |`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` | |`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` | |`keycloak_quarkus_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 612dd65..f5cdb82 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -1,6 +1,6 @@ --- ### Configuration specific to keycloak -keycloak_quarkus_version: 23.0.1 +keycloak_quarkus_version: 23.0.7 keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip" keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" From b3ca517583488d8be5d1fa0f20009f3a71e039ce Mon Sep 17 00:00:00 2001 From: Romain Pelisse Date: Thu, 22 Feb 2024 11:14:54 +0100 Subject: [PATCH 330/554] molecule: adapt sudo setup to work when ansible is not connecting as root on the target --- molecule/default/prepare.yml | 4 +++- molecule/prepare.yml | 22 ++++++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/molecule/default/prepare.yml b/molecule/default/prepare.yml index 437f3e2..43e4e54 100644 --- a/molecule/default/prepare.yml +++ b/molecule/default/prepare.yml @@ -5,12 +5,14 @@ - name: Install sudo ansible.builtin.yum: name: - - sudo - java-1.8.0-openjdk state: present - name: Prepare hosts: all + gather_facts: yes + vars: + sudo_pkg_name: sudo tasks: - name: "Run preparation common to all scenario" ansible.builtin.include_tasks: ../prepare.yml diff --git a/molecule/prepare.yml b/molecule/prepare.yml index a927ba0..d01d6fd 100644 --- a/molecule/prepare.yml +++ b/molecule/prepare.yml @@ -3,9 +3,27 @@ ansible.builtin.debug: msg: "Ansible version is {{ ansible_version.full }}" -- name: Install sudo + +- name: "Ensure {{ sudo_pkg_name }} is installed (if user is root)." ansible.builtin.yum: - name: + name: "{{ sudo_pkg_name }}" + when: + - ansible_user_id == 'root' + + +- name: Gather the package facts + ansible.builtin.package_facts: + manager: auto + +- name: "Check if {{ sudo_pkg_name }} is installed." + ansible.builtin.assert: + that: + - sudo_pkg_name in ansible_facts.packages + +- name: Install sudo + become: yes + ansible.builtin.yum: + name: - sudo - iproute state: present From 7324f48e8dea2b7fba0feac3381c81351f2cafc6 Mon Sep 17 00:00:00 2001 From: Romain Pelisse Date: Thu, 22 Feb 2024 11:22:32 +0100 Subject: [PATCH 331/554] molecule: cleanup prepare to use one play --- molecule/default/prepare.yml | 18 +++++----- molecule/default/verify.yml | 59 +++++++++++++++++--------------- molecule/overridexml/prepare.yml | 3 ++ 3 files changed, 43 insertions(+), 37 deletions(-) diff --git a/molecule/default/prepare.yml b/molecule/default/prepare.yml index 43e4e54..da1ab18 100644 --- a/molecule/default/prepare.yml +++ b/molecule/default/prepare.yml @@ -1,13 +1,4 @@ --- -- name: Prepare - hosts: all - tasks: - - name: Install sudo - ansible.builtin.yum: - name: - - java-1.8.0-openjdk - state: present - - name: Prepare hosts: all gather_facts: yes @@ -20,3 +11,12 @@ assets: - "{{ assets_server }}/sso/7.6.0/rh-sso-7.6.0-server-dist.zip" - "{{ assets_server }}/sso/7.6.1/rh-sso-7.6.1-patch.zip" + + - name: Install JDK8 + become: yes + ansible.builtin.yum: + name: + - java-1.8.0-openjdk + state: present + + diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml index ba0e01f..39e94c5 100644 --- a/molecule/default/verify.yml +++ b/molecule/default/verify.yml @@ -56,31 +56,34 @@ ansible.builtin.assert: that: - (keycloak_query_clients.json | selectattr('clientId','equalto','TestClient') | first)["attributes"]["post.logout.redirect.uris"] == '/public/logout' - - name: Check log folder - ansible.builtin.stat: - path: "/tmp/keycloak" - register: keycloak_log_folder - - name: Check that keycloak log folder exists and is a link - ansible.builtin.assert: - that: - - keycloak_log_folder.stat.exists - - not keycloak_log_folder.stat.isdir - - keycloak_log_folder.stat.islnk - - name: Check log file - ansible.builtin.stat: - path: "/tmp/keycloak/server.log" - register: keycloak_log_file - - name: Check if keycloak file exists - ansible.builtin.assert: - that: - - keycloak_log_file.stat.exists - - not keycloak_log_file.stat.isdir - - name: Check default log folder - ansible.builtin.stat: - path: "/var/log/keycloak" - register: keycloak_default_log_folder - failed_when: false - - name: Check that default keycloak log folder doesn't exist - ansible.builtin.assert: - that: - - not keycloak_default_log_folder.stat.exists + - name: "Privilege escalation as some files/folders may requires it" + become: yes + block: + - name: Check log folder + ansible.builtin.stat: + path: "/tmp/keycloak" + register: keycloak_log_folder + - name: Check that keycloak log folder exists and is a link + ansible.builtin.assert: + that: + - keycloak_log_folder.stat.exists + - not keycloak_log_folder.stat.isdir + - keycloak_log_folder.stat.islnk + - name: Check log file + ansible.builtin.stat: + path: "/tmp/keycloak/server.log" + register: keycloak_log_file + - name: Check if keycloak file exists + ansible.builtin.assert: + that: + - keycloak_log_file.stat.exists + - not keycloak_log_file.stat.isdir + - name: Check default log folder + ansible.builtin.stat: + path: "/var/log/keycloak" + register: keycloak_default_log_folder + failed_when: false + - name: Check that default keycloak log folder doesn't exist + ansible.builtin.assert: + that: + - not keycloak_default_log_folder.stat.exists diff --git a/molecule/overridexml/prepare.yml b/molecule/overridexml/prepare.yml index f9b2406..26245be 100644 --- a/molecule/overridexml/prepare.yml +++ b/molecule/overridexml/prepare.yml @@ -1,6 +1,9 @@ --- - name: Prepare hosts: all + gather_facts: yes + vars: + sudo_pkg_name: sudo tasks: - name: "Run preparation common to all scenario" ansible.builtin.include_tasks: ../prepare.yml From 5bd39a0d0eb6a21151b81d549c658a7953c97154 Mon Sep 17 00:00:00 2001 From: Romain Pelisse Date: Thu, 22 Feb 2024 12:17:32 +0100 Subject: [PATCH 332/554] molecule: use block to skip assets download entirely if needed --- molecule/prepare.yml | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/molecule/prepare.yml b/molecule/prepare.yml index d01d6fd..9d39694 100644 --- a/molecule/prepare.yml +++ b/molecule/prepare.yml @@ -32,22 +32,21 @@ ansible.builtin.set_fact: assets_server: "{{ lookup('env','MIDDLEWARE_DOWNLOAD_RELEASE_SERVER_URL') }}" -- name: "Set offline when assets server from env is defined" - ansible.builtin.set_fact: - sso_offline_install: True +- name: "Download artefacts only if assets_server is set" when: - assets_server is defined - assets_server | length > 0 + block: + - name: "Set offline when assets server from env is defined" + ansible.builtin.set_fact: + sso_offline_install: True -- name: "Download and deploy zips from {{ assets_server }}" - ansible.builtin.get_url: - url: "{{ asset }}" - dest: "{{ lookup('env', 'PWD') }}" - validate_certs: no - delegate_to: localhost - loop: "{{ assets }}" - loop_control: - loop_var: asset - when: - - assets_server is defined - - assets_server | length > 0 + - name: "Download and deploy zips from {{ assets_server }}" + ansible.builtin.get_url: + url: "{{ asset }}" + dest: "{{ lookup('env', 'PWD') }}" + validate_certs: no + delegate_to: localhost + loop: "{{ assets }}" + loop_control: + loop_var: asset From 167bf512c5ce2c01dcef0a04a94c7f483eb7671a Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 27 Feb 2024 17:17:14 +0100 Subject: [PATCH 333/554] fix typo in variable name --- roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 index b028085..a665ec8 100644 --- a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 +++ b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 @@ -1,6 +1,6 @@ # {{ ansible_managed }} KEYCLOAK_ADMIN={{ keycloak_quarkus_admin_user }} KEYCLOAK_ADMIN_PASSWORD='{{ keycloak_quarkus_admin_pass }}' -PATH={{ keycloak_java_home | default(keycloak_rpm_java_home, true) }}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin -JAVA_HOME={{ keycloak_java_home | default(keycloak_rpm_java_home, true) }} -JAVA_OPTS_APPEND={{ keycloak_quarkus_java_opts }} \ No newline at end of file +PATH={{ keycloak_quarkus_java_home | default(keycloak_rpm_java_home, true) }}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +JAVA_HOME={{ keycloak_quarkus_java_home | default(keycloak_rpm_java_home, true) }} +JAVA_OPTS_APPEND={{ keycloak_quarkus_java_opts }} From 7f021a849efc7932960aa7f944bcd2c528c5305c Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 27 Feb 2024 17:17:24 +0100 Subject: [PATCH 334/554] Linter --- molecule/https_revproxy/prepare.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/molecule/https_revproxy/prepare.yml b/molecule/https_revproxy/prepare.yml index a641257..44018be 100644 --- a/molecule/https_revproxy/prepare.yml +++ b/molecule/https_revproxy/prepare.yml @@ -33,6 +33,7 @@ ansible.builtin.file: path: /etc/nginx/tls state: directory + mode: 0755 - name: Copy certificates ansible.builtin.copy: src: "{{ item.name }}" From d97ddbde3c3a67d790469c67116a4b141a9b71b9 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 27 Feb 2024 19:27:07 +0100 Subject: [PATCH 335/554] add test --- molecule/quarkus-devmode/converge.yml | 1 + molecule/quarkus-devmode/prepare.yml | 11 ++++++++++- molecule/quarkus-devmode/verify.yml | 8 ++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/molecule/quarkus-devmode/converge.yml b/molecule/quarkus-devmode/converge.yml index 6cbe7d8..2a45189 100644 --- a/molecule/quarkus-devmode/converge.yml +++ b/molecule/quarkus-devmode/converge.yml @@ -9,6 +9,7 @@ keycloak_quarkus_frontend_url: 'http://localhost:8080/' keycloak_quarkus_start_dev: True keycloak_quarkus_proxy_mode: none + keycloak_quarkus_java_home: /opt/openjdk/ roles: - role: keycloak_quarkus - role: keycloak_realm diff --git a/molecule/quarkus-devmode/prepare.yml b/molecule/quarkus-devmode/prepare.yml index 09cbda3..88c2fb3 100644 --- a/molecule/quarkus-devmode/prepare.yml +++ b/molecule/quarkus-devmode/prepare.yml @@ -4,9 +4,18 @@ tasks: - name: Install sudo ansible.builtin.yum: - name: sudo + name: + - sudo + - java-17-openjdk-headless state: present + - name: Link default logs directory + ansible.builtin.file: + state: link + src: /usr/lib/jvm/jre-17-openjdk + dest: /opt/openjdk + force: true + - name: "Display hera_home if defined." ansible.builtin.set_fact: hera_home: "{{ lookup('env', 'HERA_HOME') }}" diff --git a/molecule/quarkus-devmode/verify.yml b/molecule/quarkus-devmode/verify.yml index ebb6047..b808ece 100644 --- a/molecule/quarkus-devmode/verify.yml +++ b/molecule/quarkus-devmode/verify.yml @@ -11,6 +11,14 @@ - ansible_facts.services["keycloak.service"]["state"] == "running" - ansible_facts.services["keycloak.service"]["status"] == "enabled" + - name: Verify we are running on requested JAVA_HOME # noqa blocked_modules command-instead-of-module + ansible.builtin.shell: | + set -o pipefail + ps -ef | grep '/opt/openjdk' | grep -v grep + args: + executable: /bin/bash + changed_when: False + - name: Set internal envvar ansible.builtin.set_fact: hera_home: "{{ lookup('env', 'HERA_HOME') }}" From 1e1665adb05d313ccc4f6218650515daf61a8095 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Wed, 28 Feb 2024 15:58:33 +0000 Subject: [PATCH 336/554] Update changelog for release 2.1.0 Signed-off-by: ansible-middleware-core --- CHANGELOG.rst | 33 ++++++++++++++++++++++++++++----- changelogs/changelog.yaml | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index c3a46da..15c2fbf 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,11 +1,36 @@ -============================================ -middleware_automation.keycloak Release Notes -============================================ +============================================= +middleware\_automation.keycloak Release Notes +============================================= .. contents:: Topics This changelog describes changes after version 0.2.6. +v2.1.0 +====== + +Major Changes +------------- + +- Implement infinispan TCPPING discovery protocol `#159 `_ + +Minor Changes +------------- + +- Set enable-recovery when xa transactions are enabled `#167 `_ +- keycloak_quarkus: Allow configuring log rotate options in quarkus configuration `#161 `_ +- keycloak_quarkus: ``sticky-session`` for infinispan routes `#163 `_ + +Breaking Changes / Porting Guide +-------------------------------- + +- keycloak_quarkus: renamed infinispan host list configuration `#157 `_ + +Bugfixes +-------- + +- keycloak_quarkus: fix custom JAVA_HOME parameter name `#171 `_ + v2.0.2 ====== @@ -269,7 +294,6 @@ Release Summary Minor enhancements, bug and documentation fixes. - Major Changes ------------- @@ -287,4 +311,3 @@ Release Summary --------------- This is the first stable release of the ``middleware_automation.keycloak`` collection. - diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 7d684cd..dd44253 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -386,3 +386,36 @@ releases: - 152.yaml - 154.yaml release_date: '2024-01-17' + 2.1.0: + changes: + breaking_changes: + - 'keycloak_quarkus: renamed infinispan host list configuration `#157 `_ + + ' + bugfixes: + - 'keycloak_quarkus: fix custom JAVA_HOME parameter name `#171 `_ + + ' + major_changes: + - 'Implement infinispan TCPPING discovery protocol `#159 `_ + + ' + minor_changes: + - 'Set enable-recovery when xa transactions are enabled `#167 `_ + + ' + - 'keycloak_quarkus: Allow configuring log rotate options in quarkus configuration + `#161 `_ + + ' + - 'keycloak_quarkus: ``sticky-session`` for infinispan routes `#163 `_ + + ' + fragments: + - 157.yaml + - 159.yaml + - 161.yaml + - 163.yaml + - 167.yaml + - 171.yaml + release_date: '2024-02-28' From 6541b5e386796777f33eba4b8cce007ec4662175 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Wed, 28 Feb 2024 15:58:47 +0000 Subject: [PATCH 337/554] Bump version to 2.1.1 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 6a1d110..dd55345 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "2.1.0" +version: "2.1.1" readme: README.md authors: - Romain Pelisse From d74820190f5231a0e33fcb31af9acb2e61618e8a Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 28 Feb 2024 17:10:02 +0100 Subject: [PATCH 338/554] ci: rename keycloak_quarkus infinispan jinja2 template --- roles/keycloak_quarkus/tasks/main.yml | 2 +- .../templates/{cache-ispn.xml => cache-ispn.xml.j2} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename roles/keycloak_quarkus/templates/{cache-ispn.xml => cache-ispn.xml.j2} (100%) diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index c65ab59..4e55961 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -60,7 +60,7 @@ - name: "Configure infinispan config for keycloak service" ansible.builtin.template: - src: cache-ispn.xml + src: cache-ispn.xml.j2 dest: "{{ keycloak.home }}/conf/cache-ispn.xml" owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" diff --git a/roles/keycloak_quarkus/templates/cache-ispn.xml b/roles/keycloak_quarkus/templates/cache-ispn.xml.j2 similarity index 100% rename from roles/keycloak_quarkus/templates/cache-ispn.xml rename to roles/keycloak_quarkus/templates/cache-ispn.xml.j2 From a59a1fb8dd16ca33a7c87418f158faf9fc4cef7f Mon Sep 17 00:00:00 2001 From: Romain Pelisse Date: Mon, 4 Mar 2024 21:13:06 +0100 Subject: [PATCH 339/554] Rework Molecule prepare phase to install sudo only if root on target --- molecule/prepare.yml | 13 +++++++++---- molecule/quarkus-devmode/prepare.yml | 12 ++++++------ molecule/quarkus/prepare.yml | 12 ++++-------- molecule/quarkus/verify.yml | 4 +++- 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/molecule/prepare.yml b/molecule/prepare.yml index 9d39694..f122f9d 100644 --- a/molecule/prepare.yml +++ b/molecule/prepare.yml @@ -3,28 +3,31 @@ ansible.builtin.debug: msg: "Ansible version is {{ ansible_version.full }}" +- name: "Set package name for sudo" + ansible.builtin.set_fact: + sudo_pkg_name: sudo - name: "Ensure {{ sudo_pkg_name }} is installed (if user is root)." ansible.builtin.yum: name: "{{ sudo_pkg_name }}" + state: present when: - ansible_user_id == 'root' - - name: Gather the package facts ansible.builtin.package_facts: manager: auto -- name: "Check if {{ sudo_pkg_name }} is installed." +- name: "Check if sudo is installed." ansible.builtin.assert: that: - sudo_pkg_name in ansible_facts.packages + fail_msg: "sudo is not installed on target system" -- name: Install sudo +- name: "Install iproute" become: yes ansible.builtin.yum: name: - - sudo - iproute state: present @@ -36,6 +39,8 @@ when: - assets_server is defined - assets_server | length > 0 + - assets is defined + - assets | length > 0 block: - name: "Set offline when assets server from env is defined" ansible.builtin.set_fact: diff --git a/molecule/quarkus-devmode/prepare.yml b/molecule/quarkus-devmode/prepare.yml index 88c2fb3..313adb8 100644 --- a/molecule/quarkus-devmode/prepare.yml +++ b/molecule/quarkus-devmode/prepare.yml @@ -2,20 +2,20 @@ - name: Prepare hosts: all tasks: - - name: Install sudo + - name: "Ensure common prepare phase are set." + ansible.builtin.include_tasks: ../prepare.yml + + - name: Install JDK17 + become: yes ansible.builtin.yum: name: - - sudo - java-17-openjdk-headless state: present - name: Link default logs directory + become: yes ansible.builtin.file: state: link src: /usr/lib/jvm/jre-17-openjdk dest: /opt/openjdk force: true - - - name: "Display hera_home if defined." - ansible.builtin.set_fact: - hera_home: "{{ lookup('env', 'HERA_HOME') }}" diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index 13d85a8..c7ba481 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -2,14 +2,8 @@ - name: Prepare hosts: all tasks: - - name: Install sudo - ansible.builtin.yum: - name: sudo - state: present - - - name: "Display hera_home if defined." - ansible.builtin.set_fact: - hera_home: "{{ lookup('env', 'HERA_HOME') }}" + - name: "Ensure common prepare phase are set." + ansible.builtin.include_tasks: ../prepare.yml - name: Create certificate request ansible.builtin.command: openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes -subj '/CN=instance' @@ -17,12 +11,14 @@ changed_when: False - name: Create conf directory # risky-file-permissions in test user account does not exist yet + become: yes ansible.builtin.file: state: directory path: "/opt/keycloak/certs/" mode: 0755 - name: Copy certificates + become: yes ansible.builtin.copy: src: "{{ item }}" dest: "/opt/keycloak/certs/{{ item }}" diff --git a/molecule/quarkus/verify.yml b/molecule/quarkus/verify.yml index 2d75c32..a58a13f 100644 --- a/molecule/quarkus/verify.yml +++ b/molecule/quarkus/verify.yml @@ -49,8 +49,9 @@ - keycloak_log_folder.stat.exists - not keycloak_log_folder.stat.isdir - keycloak_log_folder.stat.islnk - + - name: Check log file + become: yes ansible.builtin.stat: path: "/tmp/keycloak/keycloak.log" register: keycloak_log_file @@ -62,6 +63,7 @@ - not keycloak_log_file.stat.isdir - name: Check default log folder + become: yes ansible.builtin.stat: path: "/var/log/keycloak" register: keycloak_default_log_folder From a97c349f41c8429886b41c7f609d0f96ccce8861 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gro=C3=9Fewinkelmann?= Date: Wed, 13 Mar 2024 00:12:15 +0100 Subject: [PATCH 340/554] Utilize comment filter for {{ ansible_maanged }} annotations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Großewinkelmann --- molecule/overridexml/templates/custom.xml.j2 | 2 +- roles/keycloak/templates/15.0.8/standalone-infinispan.xml.j2 | 2 +- roles/keycloak/templates/15.0.8/standalone.xml.j2 | 2 +- roles/keycloak/templates/keycloak-service.sh.j2 | 2 +- roles/keycloak/templates/keycloak-sysconfig.j2 | 2 +- roles/keycloak/templates/keycloak.service.j2 | 2 +- roles/keycloak/templates/standalone-ha.xml.j2 | 2 +- roles/keycloak/templates/standalone-infinispan.xml.j2 | 2 +- roles/keycloak/templates/standalone.xml.j2 | 2 +- roles/keycloak_quarkus/templates/cache-ispn.xml.j2 | 2 +- roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 | 2 +- roles/keycloak_quarkus/templates/keycloak.conf.j2 | 2 +- roles/keycloak_quarkus/templates/keycloak.service.j2 | 2 +- roles/keycloak_quarkus/templates/quarkus.properties.j2 | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/molecule/overridexml/templates/custom.xml.j2 b/molecule/overridexml/templates/custom.xml.j2 index 8686d77..66c5852 100644 --- a/molecule/overridexml/templates/custom.xml.j2 +++ b/molecule/overridexml/templates/custom.xml.j2 @@ -1,5 +1,5 @@ - +{{ ansible_managed | comment('xml') }} diff --git a/roles/keycloak/templates/15.0.8/standalone-infinispan.xml.j2 b/roles/keycloak/templates/15.0.8/standalone-infinispan.xml.j2 index 2d84f3f..25d6cb0 100644 --- a/roles/keycloak/templates/15.0.8/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/15.0.8/standalone-infinispan.xml.j2 @@ -1,5 +1,5 @@ - +{{ ansible_managed | comment('xml') }} diff --git a/roles/keycloak/templates/15.0.8/standalone.xml.j2 b/roles/keycloak/templates/15.0.8/standalone.xml.j2 index de175f2..01c317b 100644 --- a/roles/keycloak/templates/15.0.8/standalone.xml.j2 +++ b/roles/keycloak/templates/15.0.8/standalone.xml.j2 @@ -1,5 +1,5 @@ - +{{ ansible_managed | comment('xml') }} diff --git a/roles/keycloak/templates/keycloak-service.sh.j2 b/roles/keycloak/templates/keycloak-service.sh.j2 index 577959e..98efb34 100755 --- a/roles/keycloak/templates/keycloak-service.sh.j2 +++ b/roles/keycloak/templates/keycloak-service.sh.j2 @@ -1,5 +1,5 @@ #!/bin/bash -eu -# {{ ansible_managed }} +{{ ansible_managed | comment }} set +u -o pipefail diff --git a/roles/keycloak/templates/keycloak-sysconfig.j2 b/roles/keycloak/templates/keycloak-sysconfig.j2 index 86a96d6..4c38522 100644 --- a/roles/keycloak/templates/keycloak-sysconfig.j2 +++ b/roles/keycloak/templates/keycloak-sysconfig.j2 @@ -1,4 +1,4 @@ -# {{ ansible_managed }} +{{ ansible_managed | comment }} JAVA_OPTS='{{ keycloak_java_opts }}' JAVA_HOME={{ keycloak_java_home | default(keycloak_rpm_java_home, true) }} JBOSS_HOME={{ keycloak.home }} diff --git a/roles/keycloak/templates/keycloak.service.j2 b/roles/keycloak/templates/keycloak.service.j2 index 15a6ddf..eea3ba1 100644 --- a/roles/keycloak/templates/keycloak.service.j2 +++ b/roles/keycloak/templates/keycloak.service.j2 @@ -1,4 +1,4 @@ -# {{ ansible_managed }} +{{ ansible_managed | comment }} [Unit] Description={{ keycloak.service_name }} Server After=network.target diff --git a/roles/keycloak/templates/standalone-ha.xml.j2 b/roles/keycloak/templates/standalone-ha.xml.j2 index 99399f3..d027c35 100644 --- a/roles/keycloak/templates/standalone-ha.xml.j2 +++ b/roles/keycloak/templates/standalone-ha.xml.j2 @@ -1,5 +1,5 @@ - +{{ ansible_managed | comment('xml') }} diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index 0b0c8af..18e5a7c 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -1,5 +1,5 @@ - +{{ ansible_managed | comment('xml') }} diff --git a/roles/keycloak/templates/standalone.xml.j2 b/roles/keycloak/templates/standalone.xml.j2 index 72fe4d6..5ee20ed 100644 --- a/roles/keycloak/templates/standalone.xml.j2 +++ b/roles/keycloak/templates/standalone.xml.j2 @@ -1,5 +1,5 @@ - +{{ ansible_managed | comment('xml') }} diff --git a/roles/keycloak_quarkus/templates/cache-ispn.xml.j2 b/roles/keycloak_quarkus/templates/cache-ispn.xml.j2 index 67514d3..fb11cda 100644 --- a/roles/keycloak_quarkus/templates/cache-ispn.xml.j2 +++ b/roles/keycloak_quarkus/templates/cache-ispn.xml.j2 @@ -1,4 +1,4 @@ - +{{ ansible_managed | comment('xml') }} @@ -481,7 +481,7 @@ default - + @@ -520,7 +520,8 @@ - + + @@ -549,7 +550,9 @@ + + diff --git a/molecule/overridexml/verify.yml b/molecule/overridexml/verify.yml index ef973cd..b267fa1 100644 --- a/molecule/overridexml/verify.yml +++ b/molecule/overridexml/verify.yml @@ -1,6 +1,10 @@ --- - name: Verify hosts: all + vars: + keycloak_uri: "http://localhost:8081" + keycloak_management_port: "http://localhost:19990" + keycloak_admin_password: "remembertochangeme" tasks: - name: Populate service facts ansible.builtin.service_facts: @@ -9,3 +13,20 @@ that: - ansible_facts.services["keycloak.service"]["state"] == "running" - ansible_facts.services["keycloak.service"]["status"] == "enabled" + - name: Verify we are running on requested jvm # noqa blocked_modules command-instead-of-module + ansible.builtin.shell: | + set -o pipefail + ps -ef | grep '/etc/alternatives/jre_1.8.0/' | grep -v grep + args: + executable: /bin/bash + changed_when: no + - name: Verify token api call + ansible.builtin.uri: + url: "{{ keycloak_uri }}/auth/realms/master/protocol/openid-connect/token" + method: POST + body: "client_id=admin-cli&username=admin&password={{ keycloak_admin_password }}&grant_type=password" + validate_certs: no + register: keycloak_auth_response + until: keycloak_auth_response.status == 200 + retries: 2 + delay: 2 From b9d9874a00f522709b289ed26b5f8f13d14d07ae Mon Sep 17 00:00:00 2001 From: Malik Kennedy Date: Sat, 16 Mar 2024 18:17:20 +0000 Subject: [PATCH 345/554] feat: ubuntu compatibility --- bindep.txt | 11 ++++---- molecule/default/prepare.yml | 9 ++++++- molecule/quarkus-devmode/prepare.yml | 24 +++++++++++++++++ molecule/quarkus/prepare.yml | 2 +- roles/keycloak/README.md | 1 + roles/keycloak/defaults/main.yml | 4 ++- roles/keycloak/meta/argument_specs.yml | 5 ++++ roles/keycloak/tasks/debian.yml | 6 +++++ roles/keycloak/tasks/fastpackages.yml | 15 ++++++++++- roles/keycloak/tasks/iptables.yml | 23 ++++++++++++++++ roles/keycloak/tasks/main.yml | 15 ++++++++--- roles/keycloak/tasks/prereqs.yml | 6 ++--- roles/keycloak/tasks/redhat.yml | 6 +++++ roles/keycloak/tasks/systemd.yml | 25 +++++++++++++++++ roles/keycloak_quarkus/defaults/main.yml | 2 +- roles/keycloak_quarkus/tasks/debian.yml | 6 +++++ roles/keycloak_quarkus/tasks/fastpackages.yml | 15 ++++++++++- roles/keycloak_quarkus/tasks/iptables.yml | 20 ++++++++++++++ roles/keycloak_quarkus/tasks/main.yml | 14 +++++++--- roles/keycloak_quarkus/tasks/prereqs.yml | 6 ++--- roles/keycloak_quarkus/tasks/redhat.yml | 6 +++++ roles/keycloak_quarkus/tasks/systemd.yml | 27 ++++++++++++++++++- 22 files changed, 222 insertions(+), 26 deletions(-) create mode 100644 roles/keycloak/tasks/debian.yml create mode 100644 roles/keycloak/tasks/iptables.yml create mode 100644 roles/keycloak/tasks/redhat.yml create mode 100644 roles/keycloak_quarkus/tasks/debian.yml create mode 100644 roles/keycloak_quarkus/tasks/iptables.yml create mode 100644 roles/keycloak_quarkus/tasks/redhat.yml diff --git a/bindep.txt b/bindep.txt index 840876b..0014f47 100644 --- a/bindep.txt +++ b/bindep.txt @@ -1,8 +1,9 @@ +python3-dev [compile platform:dpkg] python3-devel [compile platform:rpm] python39-devel [compile platform:centos-8 platform:rhel-8] -git-lfs [platform:rpm] -python3-netaddr [platform:rpm] -python3-lxml [platform:rpm] -python3-jmespath [platform:rpm] -python3-requests [platform:rpm] +git-lfs [platform:rpm platform:dpkg] +python3-netaddr [platform:rpm platform:dpkg] +python3-lxml [platform:rpm platform:dpkg] +python3-jmespath [platform:rpm platform:dpkg] +python3-requests [platform:rpm platform:dpkg] diff --git a/molecule/default/prepare.yml b/molecule/default/prepare.yml index da1ab18..b707f6c 100644 --- a/molecule/default/prepare.yml +++ b/molecule/default/prepare.yml @@ -18,5 +18,12 @@ name: - java-1.8.0-openjdk state: present + when: ansible_facts['os_family'] == "RedHat" - + - name: Install JDK8 + become: yes + ansible.builtin.apt: + name: + - openjdk-8-jdk + state: present + when: ansible_facts['os_family'] == "Debian" diff --git a/molecule/quarkus-devmode/prepare.yml b/molecule/quarkus-devmode/prepare.yml index 88c2fb3..924aebc 100644 --- a/molecule/quarkus-devmode/prepare.yml +++ b/molecule/quarkus-devmode/prepare.yml @@ -2,19 +2,43 @@ - name: Prepare hosts: all tasks: + - name: Install sudo + ansible.builtin.apt: + name: + - sudo + - openjdk-17-jdk-headless + state: present + when: + - ansible_facts.os_family == 'Debian' + - name: Install sudo ansible.builtin.yum: name: - sudo - java-17-openjdk-headless state: present + when: + - ansible_facts.os_family == 'RedHat' + - name: Link default logs directory + ansible.builtin.file: + state: link + src: "{{ item }}" + dest: /opt/openjdk + force: true + with_fileglob: + - /usr/lib/jvm/java-17-openjdk* + when: + - ansible_facts.os_family == "Debian" + - name: Link default logs directory ansible.builtin.file: state: link src: /usr/lib/jvm/jre-17-openjdk dest: /opt/openjdk force: true + when: + - ansible_facts.os_family == "RedHat" - name: "Display hera_home if defined." ansible.builtin.set_fact: diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index 13d85a8..568bfef 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -3,7 +3,7 @@ hosts: all tasks: - name: Install sudo - ansible.builtin.yum: + ansible.builtin.package: name: sudo state: present diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index c4dfedc..3d3b560 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -10,6 +10,7 @@ Requirements This role requires the `python3-netaddr` library installed on the controller node. * to install via yum/dnf: `dnf install python3-netaddr` +* to install via apt: `apt install python3-netaddr` * or via pip: `pip install netaddr==0.8.0` * or via the collection: `pip install -r requirements.txt` diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 7ffaec6..6658774 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -8,7 +8,8 @@ keycloak_installdir: "{{ keycloak_dest }}/keycloak-{{ keycloak_version }}" keycloak_offline_install: false ### Install location and service settings -keycloak_jvm_package: java-1.8.0-openjdk-headless +keycloak_jvm_package: "{{ 'java-1.8.0-openjdk-headless' if ansible_facts.os_family == 'RedHat' else 'openjdk-8-jdk-headless' }}" + keycloak_java_home: keycloak_dest: /opt/keycloak keycloak_jboss_home: "{{ keycloak_installdir }}" @@ -33,6 +34,7 @@ keycloak_service_startlimitburst: "5" keycloak_service_restartsec: "10s" keycloak_configure_firewalld: false +keycloak_configure_iptables: false ### administrator console password keycloak_admin_password: '' diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index acdb309..ca1cb8b 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -11,6 +11,11 @@ argument_specs: default: "keycloak-legacy-{{ keycloak_version }}.zip" description: "keycloak install archive filename" type: "str" + keycloak_configure_iptables: + # line 33 of keycloak/defaults/main.yml + default: false + description: "Ensure iptables is running and configure keycloak ports" + type: "bool" keycloak_configure_firewalld: # line 33 of keycloak/defaults/main.yml default: false diff --git a/roles/keycloak/tasks/debian.yml b/roles/keycloak/tasks/debian.yml new file mode 100644 index 0000000..ffb1348 --- /dev/null +++ b/roles/keycloak/tasks/debian.yml @@ -0,0 +1,6 @@ +--- +- name: Include firewall config tasks + ansible.builtin.include_tasks: iptables.yml + when: keycloak_configure_iptables + tags: + - firewall diff --git a/roles/keycloak/tasks/fastpackages.yml b/roles/keycloak/tasks/fastpackages.yml index c9085f8..3b557ef 100644 --- a/roles/keycloak/tasks/fastpackages.yml +++ b/roles/keycloak/tasks/fastpackages.yml @@ -4,14 +4,27 @@ register: rpm_info changed_when: false failed_when: false + when: ansible_facts.os_family == "RedHat" - name: "Add missing packages to the yum install list" ansible.builtin.set_fact: packages_to_install: "{{ packages_to_install | default([]) + rpm_info.stdout_lines | map('regex_findall', 'package (.+) is not installed$') | default([]) | flatten }}" + when: ansible_facts.os_family == "RedHat" - name: "Install packages: {{ packages_to_install }}" become: true ansible.builtin.yum: name: "{{ packages_to_install }}" state: present - when: packages_to_install | default([]) | length > 0 + when: + - packages_to_install | default([]) | length > 0 + - ansible_facts.os_family == "RedHat" + +- name: "Install packages: {{ packages_list }}" + become: true + ansible.builtin.package: + name: "{{ packages_list }}" + state: present + when: + - packages_list | default([]) | length > 0 + - ansible_facts.os_family == "Debian" diff --git a/roles/keycloak/tasks/iptables.yml b/roles/keycloak/tasks/iptables.yml new file mode 100644 index 0000000..8ebc16e --- /dev/null +++ b/roles/keycloak/tasks/iptables.yml @@ -0,0 +1,23 @@ +--- +- name: Ensure required package iptables are installed + ansible.builtin.include_tasks: fastpackages.yml + vars: + packages_list: + - iptables + +- name: "Configure firewall ports for {{ keycloak.service_name }}" + become: true + ansible.builtin.iptables: + destination_port: "{{ item }}" + action: "insert" + rule_num: 6 # magic number I forget why + chain: "INPUT" + policy: "ACCEPT" + protocol: tcp + loop: + - "{{ keycloak_http_port }}" + - "{{ keycloak_https_port }}" + - "{{ keycloak_management_http_port }}" + - "{{ keycloak_management_https_port }}" + - "{{ keycloak_jgroups_port }}" + - "{{ keycloak_ajp_port }}" diff --git a/roles/keycloak/tasks/main.yml b/roles/keycloak/tasks/main.yml index cba503b..284900b 100644 --- a/roles/keycloak/tasks/main.yml +++ b/roles/keycloak/tasks/main.yml @@ -5,11 +5,17 @@ tags: - prereqs -- name: Include firewall config tasks - ansible.builtin.include_tasks: firewalld.yml - when: keycloak_configure_firewalld +- name: Debian specific tasks + ansible.builtin.include_tasks: debian.yml + when: ansible_facts.os_family == "Debian" tags: - - firewall + - unbound + +- name: RedHat specific tasks + ansible.builtin.include_tasks: redhat.yml + when: ansible_facts.os_family == "RedHat" + tags: + - unbound - name: Include install tasks ansible.builtin.include_tasks: install.yml @@ -26,6 +32,7 @@ when: - sso_apply_patches is defined and sso_apply_patches - sso_enable is defined and sso_enable + - ansible_facts.os_family == "RedHat" tags: - install - patch diff --git a/roles/keycloak/tasks/prereqs.yml b/roles/keycloak/tasks/prereqs.yml index aad814b..565931b 100644 --- a/roles/keycloak/tasks/prereqs.yml +++ b/roles/keycloak/tasks/prereqs.yml @@ -42,6 +42,6 @@ packages_list: - "{{ keycloak_jvm_package }}" - unzip - - procps-ng - - initscripts - - tzdata-java + - "{{ 'procps-ng' if ansible_facts.os_family == 'RedHat' else 'procps' }}" + - "{{ 'initscripts' if ansible_facts.os_family == 'RedHat' else 'apt' }}" + - "{{ 'tzdata-java' if ansible_facts.os_family == 'RedHat' else 'tzdata' }}" diff --git a/roles/keycloak/tasks/redhat.yml b/roles/keycloak/tasks/redhat.yml new file mode 100644 index 0000000..596834b --- /dev/null +++ b/roles/keycloak/tasks/redhat.yml @@ -0,0 +1,6 @@ +--- +- name: Include firewall config tasks + ansible.builtin.include_tasks: firewalld.yml + when: keycloak_configure_firewalld + tags: + - firewall diff --git a/roles/keycloak/tasks/systemd.yml b/roles/keycloak/tasks/systemd.yml index cd58345..cf84c32 100644 --- a/roles/keycloak/tasks/systemd.yml +++ b/roles/keycloak/tasks/systemd.yml @@ -10,9 +10,32 @@ notify: - restart keycloak +- name: Determine JAVA_HOME for selected JVM RPM + ansible.builtin.set_fact: + rpm_java_home: "/lib/jvm/java-{{ keycloak_jvm_package | regex_search('(?<=java-)[0-9.]+') }}-openjdk-{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}" + when: + - ansible_facts.os_family == 'Debian' + - name: Determine JAVA_HOME for selected JVM RPM ansible.builtin.set_fact: rpm_java_home: "/etc/alternatives/jre_{{ keycloak_jvm_package | regex_search('(?<=java-)[0-9.]+') }}" + when: + - ansible_facts.os_family == 'RedHat' + +- name: "Configure sysconfig file for {{ keycloak.service_name }} service" + become: true + ansible.builtin.template: + src: keycloak-sysconfig.j2 + dest: /etc/default/keycloak + owner: root + group: root + mode: 0644 + vars: + keycloak_rpm_java_home: "{{ rpm_java_home }}" + when: + - ansible_facts.os_family == "Debian" + notify: + - restart keycloak - name: "Configure sysconfig file for {{ keycloak.service_name }} service" become: true @@ -24,6 +47,8 @@ mode: 0644 vars: keycloak_rpm_java_home: "{{ rpm_java_home }}" + when: + - ansible_facts.os_family == "RedHat" notify: - restart keycloak diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index f5cdb82..f2f07a5 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -9,7 +9,7 @@ keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_q keycloak_quarkus_offline_install: false ### Install location and service settings -keycloak_quarkus_jvm_package: java-17-openjdk-headless +keycloak_quarkus_jvm_package: "{{ 'java-17-openjdk-headless' if ansible_facts.os_family == 'RedHat' else 'openjdk-17-jdk-headless' }}" keycloak_quarkus_java_home: keycloak_quarkus_dest: /opt/keycloak keycloak_quarkus_home: "{{ keycloak_quarkus_installdir }}" diff --git a/roles/keycloak_quarkus/tasks/debian.yml b/roles/keycloak_quarkus/tasks/debian.yml new file mode 100644 index 0000000..ffb1348 --- /dev/null +++ b/roles/keycloak_quarkus/tasks/debian.yml @@ -0,0 +1,6 @@ +--- +- name: Include firewall config tasks + ansible.builtin.include_tasks: iptables.yml + when: keycloak_configure_iptables + tags: + - firewall diff --git a/roles/keycloak_quarkus/tasks/fastpackages.yml b/roles/keycloak_quarkus/tasks/fastpackages.yml index c9085f8..3b557ef 100644 --- a/roles/keycloak_quarkus/tasks/fastpackages.yml +++ b/roles/keycloak_quarkus/tasks/fastpackages.yml @@ -4,14 +4,27 @@ register: rpm_info changed_when: false failed_when: false + when: ansible_facts.os_family == "RedHat" - name: "Add missing packages to the yum install list" ansible.builtin.set_fact: packages_to_install: "{{ packages_to_install | default([]) + rpm_info.stdout_lines | map('regex_findall', 'package (.+) is not installed$') | default([]) | flatten }}" + when: ansible_facts.os_family == "RedHat" - name: "Install packages: {{ packages_to_install }}" become: true ansible.builtin.yum: name: "{{ packages_to_install }}" state: present - when: packages_to_install | default([]) | length > 0 + when: + - packages_to_install | default([]) | length > 0 + - ansible_facts.os_family == "RedHat" + +- name: "Install packages: {{ packages_list }}" + become: true + ansible.builtin.package: + name: "{{ packages_list }}" + state: present + when: + - packages_list | default([]) | length > 0 + - ansible_facts.os_family == "Debian" diff --git a/roles/keycloak_quarkus/tasks/iptables.yml b/roles/keycloak_quarkus/tasks/iptables.yml new file mode 100644 index 0000000..b487b89 --- /dev/null +++ b/roles/keycloak_quarkus/tasks/iptables.yml @@ -0,0 +1,20 @@ +--- +- name: Ensure required package iptables are installed + ansible.builtin.include_tasks: fastpackages.yml + vars: + packages_list: + - iptables + +- name: "Configure firewall ports for {{ keycloak.service_name }}" + become: true + ansible.builtin.iptables: + destination_port: "{{ item }}" + action: "insert" + rule_num: 6 # magic number I forget why + chain: "INPUT" + policy: "ACCEPT" + protocol: tcp + loop: + - "{{ keycloak_quarkus_http_port }}" + - "{{ keycloak_quarkus_https_port }}" + - "{{ keycloak_quarkus_jgroups_port }}" diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index 4e55961..72f4fdd 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -5,11 +5,17 @@ tags: - prereqs -- name: Include firewall config tasks - ansible.builtin.include_tasks: firewalld.yml - when: keycloak_quarkus_configure_firewalld +- name: Debian specific tasks + ansible.builtin.include_tasks: debian.yml + when: ansible_facts.os_family == "Debian" tags: - - firewall + - unbound + +- name: RedHat specific tasks + ansible.builtin.include_tasks: redhat.yml + when: ansible_facts.os_family == "RedHat" + tags: + - unbound - name: Include install tasks ansible.builtin.include_tasks: install.yml diff --git a/roles/keycloak_quarkus/tasks/prereqs.yml b/roles/keycloak_quarkus/tasks/prereqs.yml index ee2abca..252f75f 100644 --- a/roles/keycloak_quarkus/tasks/prereqs.yml +++ b/roles/keycloak_quarkus/tasks/prereqs.yml @@ -29,6 +29,6 @@ packages_list: - "{{ keycloak_quarkus_jvm_package }}" - unzip - - procps-ng - - initscripts - - tzdata-java + - "{{ 'procps-ng' if ansible_facts.os_family == 'RedHat' else 'procps' }}" + - "{{ 'initscripts' if ansible_facts.os_family == 'RedHat' else 'apt' }}" + - "{{ 'tzdata-java' if ansible_facts.os_family == 'RedHat' else 'tzdata' }}" diff --git a/roles/keycloak_quarkus/tasks/redhat.yml b/roles/keycloak_quarkus/tasks/redhat.yml new file mode 100644 index 0000000..093b930 --- /dev/null +++ b/roles/keycloak_quarkus/tasks/redhat.yml @@ -0,0 +1,6 @@ +--- +- name: Include firewall config tasks + ansible.builtin.include_tasks: firewalld.yml + when: keycloak_quarkus_configure_firewalld + tags: + - firewall diff --git a/roles/keycloak_quarkus/tasks/systemd.yml b/roles/keycloak_quarkus/tasks/systemd.yml index 3d59b3f..65aeeb3 100644 --- a/roles/keycloak_quarkus/tasks/systemd.yml +++ b/roles/keycloak_quarkus/tasks/systemd.yml @@ -2,8 +2,31 @@ - name: Determine JAVA_HOME for selected JVM RPM ansible.builtin.set_fact: rpm_java_home: "/etc/alternatives/jre_{{ keycloak_quarkus_jvm_package | regex_search('(?<=java-)[0-9.]+') }}" + when: + - ansible_facts.os_family == "RedHat" -- name: "Configure sysconfig file for keycloak service" +- name: Determine JAVA_HOME for selected JVM RPM + ansible.builtin.set_fact: + rpm_java_home: "/lib/jvm/java-{{ keycloak_quarkus_jvm_package | regex_search('(?!:openjdk-)[0-9.]+') }}-openjdk-{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}" + when: + - ansible_facts.os_family == "Debian" + +- name: "Configure sysconfig file for {{ keycloak.service_name }} service" + become: true + ansible.builtin.template: + src: keycloak-sysconfig.j2 + dest: /etc/default/keycloak + owner: root + group: root + mode: 0644 + vars: + keycloak_rpm_java_home: "{{ rpm_java_home }}" + when: + - ansible_facts.os_family == "Debian" + notify: + - restart keycloak + +- name: "Configure sysconfig file for {{ keycloak.service_name }} service" become: true ansible.builtin.template: src: keycloak-sysconfig.j2 @@ -13,6 +36,8 @@ mode: 0644 vars: keycloak_rpm_java_home: "{{ rpm_java_home }}" + when: + - ansible_facts.os_family == "RedHat" notify: - restart keycloak From 56e4a43cf984558bc58bd84e184ec791b853a2d2 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 25 Mar 2024 09:30:25 +0100 Subject: [PATCH 346/554] add keycloak_realm default to sub entities --- roles/keycloak_realm/tasks/main.yml | 6 +++--- roles/keycloak_realm/tasks/manage_client_roles.yml | 2 +- roles/keycloak_realm/tasks/manage_user_client_roles.yml | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/roles/keycloak_realm/tasks/main.yml b/roles/keycloak_realm/tasks/main.yml index c1f66bc..016ab55 100644 --- a/roles/keycloak_realm/tasks/main.yml +++ b/roles/keycloak_realm/tasks/main.yml @@ -41,11 +41,11 @@ auth_realm: "{{ keycloak_auth_realm }}" auth_username: "{{ keycloak_admin_user }}" auth_password: "{{ keycloak_admin_password }}" - realm: "{{ item.realm }}" + realm: "{{ item.realm | default(keycloak_realm) }}" name: "{{ item.name }}" state: present provider_id: "{{ item.provider_id }}" - provider_type: "{{ item.provider_type | default(org.keycloak.storage.UserStorageProvider) }}" + provider_type: "{{ item.provider_type | default(org.keycloak.storage.UserStorageProvider) }}" config: "{{ item.config }}" mappers: "{{ item.mappers | default(omit) }}" no_log: "{{ keycloak_no_log | default('True') }}" @@ -71,7 +71,7 @@ auth_realm: "{{ keycloak_auth_realm }}" auth_username: "{{ keycloak_admin_user }}" auth_password: "{{ keycloak_admin_password }}" - realm: "{{ item.realm }}" + realm: "{{ item.realm | default(keycloak_realm) }}" default_roles: "{{ item.roles | default(omit) }}" client_id: "{{ item.client_id | default(omit) }}" id: "{{ item.id | default(omit) }}" diff --git a/roles/keycloak_realm/tasks/manage_client_roles.yml b/roles/keycloak_realm/tasks/manage_client_roles.yml index 4a261b1..fbb25ac 100644 --- a/roles/keycloak_realm/tasks/manage_client_roles.yml +++ b/roles/keycloak_realm/tasks/manage_client_roles.yml @@ -1,7 +1,7 @@ - name: Create client roles middleware_automation.keycloak.keycloak_role: name: "{{ item }}" - realm: "{{ client.realm }}" + realm: "{{ client.realm | default(keycloak_realm) }}" client_id: "{{ client.name }}" auth_client_id: "{{ keycloak_auth_client }}" auth_keycloak_url: "{{ keycloak_url }}{{ keycloak_context }}" diff --git a/roles/keycloak_realm/tasks/manage_user_client_roles.yml b/roles/keycloak_realm/tasks/manage_user_client_roles.yml index 85de09a..4311daa 100644 --- a/roles/keycloak_realm/tasks/manage_user_client_roles.yml +++ b/roles/keycloak_realm/tasks/manage_user_client_roles.yml @@ -1,7 +1,7 @@ --- - name: "Get Realm for role" ansible.builtin.uri: - url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ client_role.realm }}" + url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ client_role.realm | default(keycloak_realm) }}" method: GET status_code: - 200 @@ -12,7 +12,7 @@ - name: Check if Mapping is available ansible.builtin.uri: - url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ client_role.realm }}/users/{{ (keycloak_user.json | first).id }}/role-mappings/clients/{{ (create_client_result.results | selectattr('end_state.clientId', 'equalto', client_role.client) | list | first).end_state.id }}/available" + url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ client_role.realm | default(keycloak_realm) }}/users/{{ (keycloak_user.json | first).id }}/role-mappings/clients/{{ (create_client_result.results | selectattr('end_state.clientId', 'equalto', client_role.client) | list | first).end_state.id }}/available" method: GET status_code: - 200 @@ -23,7 +23,7 @@ - name: "Create Role Mapping" ansible.builtin.uri: - url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ client_role.realm }}/users/{{ (keycloak_user.json | first).id }}/role-mappings/clients/{{ (create_client_result.results | selectattr('end_state.clientId', 'equalto', client_role.client) | list | first).end_state.id }}" + url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ client_role.realm | default(keycloak_realm) }}/users/{{ (keycloak_user.json | first).id }}/role-mappings/clients/{{ (create_client_result.results | selectattr('end_state.clientId', 'equalto', client_role.client) | list | first).end_state.id }}" method: POST body: - id: "{{ item.id }}" From dd6171f0247733fc12534698111f78dbd8b206e7 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 25 Mar 2024 10:19:08 +0100 Subject: [PATCH 347/554] Add ansible_family based vars loading --- roles/keycloak_quarkus/defaults/main.yml | 1 - roles/keycloak_quarkus/meta/main.yml | 6 ++++++ roles/keycloak_quarkus/tasks/prereqs.yml | 22 +++++++++++++++------- roles/keycloak_quarkus/vars/debian.yml | 11 +++++++++++ roles/keycloak_quarkus/vars/redhat.yml | 11 +++++++++++ 5 files changed, 43 insertions(+), 8 deletions(-) create mode 100644 roles/keycloak_quarkus/vars/debian.yml create mode 100644 roles/keycloak_quarkus/vars/redhat.yml diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index f2f07a5..e630bd3 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -9,7 +9,6 @@ keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_q keycloak_quarkus_offline_install: false ### Install location and service settings -keycloak_quarkus_jvm_package: "{{ 'java-17-openjdk-headless' if ansible_facts.os_family == 'RedHat' else 'openjdk-17-jdk-headless' }}" keycloak_quarkus_java_home: keycloak_quarkus_dest: /opt/keycloak keycloak_quarkus_home: "{{ keycloak_quarkus_installdir }}" diff --git a/roles/keycloak_quarkus/meta/main.yml b/roles/keycloak_quarkus/meta/main.yml index 8d7331d..0f82003 100644 --- a/roles/keycloak_quarkus/meta/main.yml +++ b/roles/keycloak_quarkus/meta/main.yml @@ -14,6 +14,11 @@ galaxy_info: - name: EL versions: - "8" + - "9" + - name: Fedora + - name: Debian + - name: Ubuntu + galaxy_tags: - keycloak @@ -25,3 +30,4 @@ galaxy_info: - identity - security - rhbk + - debian diff --git a/roles/keycloak_quarkus/tasks/prereqs.yml b/roles/keycloak_quarkus/tasks/prereqs.yml index 252f75f..7a33a48 100644 --- a/roles/keycloak_quarkus/tasks/prereqs.yml +++ b/roles/keycloak_quarkus/tasks/prereqs.yml @@ -6,7 +6,7 @@ quiet: true fail_msg: "The console administrator password is empty or invalid. Please set the keycloak_quarkus_admin_pass variable to a 12+ char long string" success_msg: "{{ 'Console administrator password OK' }}" - + - name: Validate relative path ansible.builtin.assert: that: @@ -23,12 +23,20 @@ fail_msg: "Cannot install HA setup without a backend database service. Check keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled" success_msg: "{{ 'Configuring HA' if keycloak_quarkus_ha_enabled else 'Configuring standalone' }}" +- name: Validate OS family + ansible.builtin.assert: + that: + - ansible_os_family in ["RedHat", "Debian"] + quiet: true + fail_msg: "Can only install on RedHat or Debian OS families; found {{ ansible_os_family }}" + success_msg: "Installing on {{ ansible_os_family }}" + +- name: Load OS specific variables + ansible.builtin.include_vars: "vars/{{ ansible_os_family | lower }}.yml" + tags: + - always + - name: Ensure required packages are installed ansible.builtin.include_tasks: fastpackages.yml vars: - packages_list: - - "{{ keycloak_quarkus_jvm_package }}" - - unzip - - "{{ 'procps-ng' if ansible_facts.os_family == 'RedHat' else 'procps' }}" - - "{{ 'initscripts' if ansible_facts.os_family == 'RedHat' else 'apt' }}" - - "{{ 'tzdata-java' if ansible_facts.os_family == 'RedHat' else 'tzdata' }}" + packages_list: "{{ keycloak_prereq_package_list }}" diff --git a/roles/keycloak_quarkus/vars/debian.yml b/roles/keycloak_quarkus/vars/debian.yml new file mode 100644 index 0000000..6c7ed90 --- /dev/null +++ b/roles/keycloak_quarkus/vars/debian.yml @@ -0,0 +1,11 @@ +--- +keycloak_quarkus_jvm_package: openjdk-17-jdk-headless +keycloak_prereq_package_list: + - "{{ keycloak_quarkus_jvm_package }}" + - unzip + - procps + - apt + - tzdata +keycloak_quarkus_configure_iptables: True +keycloak_quarkus_sysconf_file: /etc/default/keycloak +keycloak_quarkus_pkg_java_home: "/lib/jvm/java-{{ keycloak_quarkus_jvm_package | regex_search('(?!:openjdk-)[0-9.]+') }}-openjdk-{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}" diff --git a/roles/keycloak_quarkus/vars/redhat.yml b/roles/keycloak_quarkus/vars/redhat.yml new file mode 100644 index 0000000..775f983 --- /dev/null +++ b/roles/keycloak_quarkus/vars/redhat.yml @@ -0,0 +1,11 @@ +--- +keycloak_quarkus_jvm_package: java-17-openjdk-headless +keycloak_prereq_package_list: + - "{{ keycloak_quarkus_jvm_package }}" + - unzip + - procps-ng + - initscripts + - tzdata-java +keycloak_quarkus_configure_iptables: False +keycloak_quarkus_sysconf_file: /etc/sysconfig/keycloak +keycloak_quarkus_pkg_java_home: "/etc/alternatives/jre_{{ keycloak_quarkus_jvm_package | regex_search('(?<=java-)[0-9.]+') }}" From 3b1534d700c02ca2d863a62cfa0b89e439fd440f Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 25 Mar 2024 10:19:28 +0100 Subject: [PATCH 348/554] refactor --- roles/keycloak_quarkus/tasks/debian.yml | 2 +- roles/keycloak_quarkus/tasks/fastpackages.yml | 2 +- roles/keycloak_quarkus/tasks/main.yml | 10 ++---- roles/keycloak_quarkus/tasks/systemd.yml | 33 ++----------------- .../templates/keycloak-sysconfig.j2 | 4 +-- .../templates/keycloak.service.j2 | 2 +- 6 files changed, 9 insertions(+), 44 deletions(-) diff --git a/roles/keycloak_quarkus/tasks/debian.yml b/roles/keycloak_quarkus/tasks/debian.yml index ffb1348..4a36661 100644 --- a/roles/keycloak_quarkus/tasks/debian.yml +++ b/roles/keycloak_quarkus/tasks/debian.yml @@ -1,6 +1,6 @@ --- - name: Include firewall config tasks ansible.builtin.include_tasks: iptables.yml - when: keycloak_configure_iptables + when: keycloak_quarkus_configure_iptables tags: - firewall diff --git a/roles/keycloak_quarkus/tasks/fastpackages.yml b/roles/keycloak_quarkus/tasks/fastpackages.yml index 3b557ef..5affe64 100644 --- a/roles/keycloak_quarkus/tasks/fastpackages.yml +++ b/roles/keycloak_quarkus/tasks/fastpackages.yml @@ -13,7 +13,7 @@ - name: "Install packages: {{ packages_to_install }}" become: true - ansible.builtin.yum: + ansible.builtin.dnf: name: "{{ packages_to_install }}" state: present when: diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index 72f4fdd..86b3211 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -4,16 +4,10 @@ ansible.builtin.include_tasks: prereqs.yml tags: - prereqs + - always - name: Debian specific tasks - ansible.builtin.include_tasks: debian.yml - when: ansible_facts.os_family == "Debian" - tags: - - unbound - -- name: RedHat specific tasks - ansible.builtin.include_tasks: redhat.yml - when: ansible_facts.os_family == "RedHat" + ansible.builtin.include_tasks: "{{ ansible_os_family | lower }}.yml" tags: - unbound diff --git a/roles/keycloak_quarkus/tasks/systemd.yml b/roles/keycloak_quarkus/tasks/systemd.yml index 65aeeb3..58dbc7e 100644 --- a/roles/keycloak_quarkus/tasks/systemd.yml +++ b/roles/keycloak_quarkus/tasks/systemd.yml @@ -1,43 +1,14 @@ --- -- name: Determine JAVA_HOME for selected JVM RPM - ansible.builtin.set_fact: - rpm_java_home: "/etc/alternatives/jre_{{ keycloak_quarkus_jvm_package | regex_search('(?<=java-)[0-9.]+') }}" - when: - - ansible_facts.os_family == "RedHat" - -- name: Determine JAVA_HOME for selected JVM RPM - ansible.builtin.set_fact: - rpm_java_home: "/lib/jvm/java-{{ keycloak_quarkus_jvm_package | regex_search('(?!:openjdk-)[0-9.]+') }}-openjdk-{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}" - when: - - ansible_facts.os_family == "Debian" - - name: "Configure sysconfig file for {{ keycloak.service_name }} service" become: true ansible.builtin.template: src: keycloak-sysconfig.j2 - dest: /etc/default/keycloak + dest: "{{ keycloak_quarkus_sysconf_file }}" owner: root group: root mode: 0644 vars: - keycloak_rpm_java_home: "{{ rpm_java_home }}" - when: - - ansible_facts.os_family == "Debian" - notify: - - restart keycloak - -- name: "Configure sysconfig file for {{ keycloak.service_name }} service" - become: true - ansible.builtin.template: - src: keycloak-sysconfig.j2 - dest: /etc/sysconfig/keycloak - owner: root - group: root - mode: 0644 - vars: - keycloak_rpm_java_home: "{{ rpm_java_home }}" - when: - - ansible_facts.os_family == "RedHat" + keycloak_pkg_java_home: "{{ keycloak_quarkus_pkg_java_home }}" notify: - restart keycloak diff --git a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 index aa6aef7..358794c 100644 --- a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 +++ b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 @@ -1,6 +1,6 @@ {{ ansible_managed | comment }} KEYCLOAK_ADMIN={{ keycloak_quarkus_admin_user }} KEYCLOAK_ADMIN_PASSWORD='{{ keycloak_quarkus_admin_pass }}' -PATH={{ keycloak_quarkus_java_home | default(keycloak_rpm_java_home, true) }}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin -JAVA_HOME={{ keycloak_quarkus_java_home | default(keycloak_rpm_java_home, true) }} +PATH={{ keycloak_quarkus_java_home | default(keycloak_pkg_java_home, true) }}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +JAVA_HOME={{ keycloak_quarkus_java_home | default(keycloak_pkg_java_home, true) }} JAVA_OPTS_APPEND={{ keycloak_quarkus_java_opts }} diff --git a/roles/keycloak_quarkus/templates/keycloak.service.j2 b/roles/keycloak_quarkus/templates/keycloak.service.j2 index af61007..3cdfacf 100644 --- a/roles/keycloak_quarkus/templates/keycloak.service.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.service.j2 @@ -5,7 +5,7 @@ After=network.target [Service] Type=simple -EnvironmentFile=-/etc/sysconfig/keycloak +EnvironmentFile=-{{ keycloak_quarkus_sysconf_file }} PIDFile={{ keycloak_quarkus_service_pidfile }} {% if keycloak_quarkus_start_dev %} ExecStart={{ keycloak.home }}/bin/kc.sh start-dev From 3400b64b105e19c2b8690bedba518fe8295130df Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 25 Mar 2024 14:34:25 +0100 Subject: [PATCH 349/554] add to ci --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index afb1403..509bebb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,4 +15,4 @@ jobs: with: fqcn: 'middleware_automation/keycloak' molecule_tests: >- - [ "default", "overridexml", "https_revproxy", "quarkus", "quarkus-devmode" ] + [ "default", "overridexml", "https_revproxy", "quarkus", "quarkus-devmode", "debian" ] From 0e4df659f431f563b7800bf31b49867051305911 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 25 Mar 2024 14:34:36 +0100 Subject: [PATCH 350/554] add test --- molecule/debian/converge.yml | 40 ++++++++++++++++++ molecule/debian/molecule.yml | 44 ++++++++++++++++++++ molecule/debian/prepare.yml | 11 +++++ molecule/debian/roles | 1 + molecule/debian/verify.yml | 52 ++++++++++++++++++++++++ roles/keycloak_quarkus/tasks/main.yml | 2 +- roles/keycloak_quarkus/tasks/prereqs.yml | 2 +- roles/keycloak_quarkus/vars/debian.yml | 2 +- roles/keycloak_quarkus/vars/redhat.yml | 2 +- 9 files changed, 152 insertions(+), 4 deletions(-) create mode 100644 molecule/debian/converge.yml create mode 100644 molecule/debian/molecule.yml create mode 100644 molecule/debian/prepare.yml create mode 120000 molecule/debian/roles create mode 100644 molecule/debian/verify.yml diff --git a/molecule/debian/converge.yml b/molecule/debian/converge.yml new file mode 100644 index 0000000..0be6a85 --- /dev/null +++ b/molecule/debian/converge.yml @@ -0,0 +1,40 @@ +--- +- name: Converge + hosts: all + vars: + keycloak_admin_password: "remembertochangeme" + keycloak_quarkus_admin_pass: "remembertochangeme" + keycloak_realm: TestRealm + keycloak_quarkus_log: file + keycloak_quarkus_frontend_url: 'http://localhost:8080/' + keycloak_quarkus_start_dev: True + keycloak_quarkus_proxy_mode: none + keycloak_client_default_roles: + - TestRoleAdmin + - TestRoleUser + keycloak_client_users: + - username: TestUser + password: password + client_roles: + - client: TestClient + role: TestRoleUser + - username: TestAdmin + password: password + client_roles: + - client: TestClient + role: TestRoleUser + - client: TestClient + role: TestRoleAdmin + keycloak_clients: + - name: TestClient + roles: "{{ keycloak_client_default_roles }}" + public_client: "{{ keycloak_client_public }}" + web_origins: "{{ keycloak_client_web_origins }}" + users: "{{ keycloak_client_users }}" + client_id: TestClient + attributes: + post.logout.redirect.uris: '/public/logout' + roles: + - role: keycloak_quarkus + - role: keycloak_realm + keycloak_realm: TestRealm diff --git a/molecule/debian/molecule.yml b/molecule/debian/molecule.yml new file mode 100644 index 0000000..78b102c --- /dev/null +++ b/molecule/debian/molecule.yml @@ -0,0 +1,44 @@ +--- +driver: + name: docker +platforms: + - name: instance + image: ghcr.io/hspaans/molecule-containers:debian-11 + pre_build_image: true + privileged: true + port_bindings: + - "8080/tcp" + - "8443/tcp" + - "8009/tcp" +provisioner: + name: ansible + config_options: + defaults: + interpreter_python: auto_silent + ssh_connection: + pipelining: false + playbooks: + prepare: prepare.yml + converge: converge.yml + verify: verify.yml + inventory: + host_vars: + localhost: + ansible_python_interpreter: /usr/bin/python3 + env: + ANSIBLE_FORCE_COLOR: "true" + ANSIBLE_REMOTE_TMP: /tmp/.ansible/tmp +verifier: + name: ansible +scenario: + test_sequence: + - cleanup + - destroy + - create + - prepare + - converge + - idempotence + - side_effect + - verify + - cleanup + - destroy diff --git a/molecule/debian/prepare.yml b/molecule/debian/prepare.yml new file mode 100644 index 0000000..6025ef9 --- /dev/null +++ b/molecule/debian/prepare.yml @@ -0,0 +1,11 @@ +--- +- name: Prepare + hosts: all + gather_facts: yes + tasks: + - name: Install sudo + ansible.builtin.apt: + name: + - sudo + - openjdk-17-jdk-headless + state: present diff --git a/molecule/debian/roles b/molecule/debian/roles new file mode 120000 index 0000000..b741aa3 --- /dev/null +++ b/molecule/debian/roles @@ -0,0 +1 @@ +../../roles \ No newline at end of file diff --git a/molecule/debian/verify.yml b/molecule/debian/verify.yml new file mode 100644 index 0000000..040558a --- /dev/null +++ b/molecule/debian/verify.yml @@ -0,0 +1,52 @@ +--- +- name: Verify + hosts: all + vars: + keycloak_admin_password: "remembertochangeme" + keycloak_uri: "http://localhost:{{ 8080 + ( keycloak_jboss_port_offset | default(0) ) }}" + keycloak_management_port: "http://localhost:{{ 9990 + ( keycloak_jboss_port_offset | default(0) ) }}" + keycloak_jboss_port_offset: 10 + tasks: + - name: Populate service facts + ansible.builtin.service_facts: + + - name: Check if keycloak service started + ansible.builtin.assert: + that: + - ansible_facts.services["keycloak.service"]["state"] == "running" + - ansible_facts.services["keycloak.service"]["status"] == "enabled" + + - name: Verify we are running on requested JAVA_HOME # noqa blocked_modules command-instead-of-module + ansible.builtin.shell: | + set -o pipefail + ps -ef | grep '/opt/openjdk' | grep -v grep + args: + executable: /bin/bash + changed_when: False + + - name: Set internal envvar + ansible.builtin.set_fact: + hera_home: "{{ lookup('env', 'HERA_HOME') }}" + + - name: Verify openid config + block: + - name: Fetch openID config # noqa blocked_modules command-instead-of-module + ansible.builtin.shell: | + set -o pipefail + curl http://localhost:8080/realms/master/.well-known/openid-configuration -k | jq . + args: + executable: /bin/bash + delegate_to: localhost + register: openid_config + changed_when: False + - name: Verify endpoint URLs + ansible.builtin.assert: + that: + - (openid_config.stdout | from_json)["backchannel_authentication_endpoint"] == 'http://localhost:8080/realms/master/protocol/openid-connect/ext/ciba/auth' + - (openid_config.stdout | from_json)['issuer'] == 'http://localhost:8080/realms/master' + - (openid_config.stdout | from_json)['authorization_endpoint'] == 'http://localhost:8080/realms/master/protocol/openid-connect/auth' + - (openid_config.stdout | from_json)['token_endpoint'] == 'http://localhost:8080/realms/master/protocol/openid-connect/token' + delegate_to: localhost + when: + - hera_home is defined + - hera_home | length == 0 diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index 86b3211..decb63b 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -6,7 +6,7 @@ - prereqs - always -- name: Debian specific tasks +- name: Distro specific tasks ansible.builtin.include_tasks: "{{ ansible_os_family | lower }}.yml" tags: - unbound diff --git a/roles/keycloak_quarkus/tasks/prereqs.yml b/roles/keycloak_quarkus/tasks/prereqs.yml index 7a33a48..a9fbeaa 100644 --- a/roles/keycloak_quarkus/tasks/prereqs.yml +++ b/roles/keycloak_quarkus/tasks/prereqs.yml @@ -39,4 +39,4 @@ - name: Ensure required packages are installed ansible.builtin.include_tasks: fastpackages.yml vars: - packages_list: "{{ keycloak_prereq_package_list }}" + packages_list: "{{ keycloak_quarkus_prereq_package_list }}" diff --git a/roles/keycloak_quarkus/vars/debian.yml b/roles/keycloak_quarkus/vars/debian.yml index 6c7ed90..8ff6775 100644 --- a/roles/keycloak_quarkus/vars/debian.yml +++ b/roles/keycloak_quarkus/vars/debian.yml @@ -1,6 +1,6 @@ --- keycloak_quarkus_jvm_package: openjdk-17-jdk-headless -keycloak_prereq_package_list: +keycloak_quarkus_prereq_package_list: - "{{ keycloak_quarkus_jvm_package }}" - unzip - procps diff --git a/roles/keycloak_quarkus/vars/redhat.yml b/roles/keycloak_quarkus/vars/redhat.yml index 775f983..e40a94a 100644 --- a/roles/keycloak_quarkus/vars/redhat.yml +++ b/roles/keycloak_quarkus/vars/redhat.yml @@ -1,6 +1,6 @@ --- keycloak_quarkus_jvm_package: java-17-openjdk-headless -keycloak_prereq_package_list: +keycloak_quarkus_prereq_package_list: - "{{ keycloak_quarkus_jvm_package }}" - unzip - procps-ng From e17505fe423eb2500aff3a73e0fa99941a462151 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 25 Mar 2024 15:37:02 +0100 Subject: [PATCH 351/554] update molecule for debian container --- molecule/debian/molecule.yml | 4 ++++ molecule/requirements.yml | 2 +- roles/keycloak_quarkus/vars/debian.yml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/molecule/debian/molecule.yml b/molecule/debian/molecule.yml index 78b102c..afe29c5 100644 --- a/molecule/debian/molecule.yml +++ b/molecule/debian/molecule.yml @@ -10,6 +10,10 @@ platforms: - "8080/tcp" - "8443/tcp" - "8009/tcp" + cgroupns_mode: host + command: "/lib/systemd/systemd" + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw provisioner: name: ansible config_options: diff --git a/molecule/requirements.yml b/molecule/requirements.yml index c87fd9a..5c8bb43 100644 --- a/molecule/requirements.yml +++ b/molecule/requirements.yml @@ -5,7 +5,7 @@ collections: - name: community.general - name: ansible.posix - name: community.docker - version: ">=1.9.1" + version: ">=3.8.0" roles: - name: elan.simple_nginx_reverse_proxy diff --git a/roles/keycloak_quarkus/vars/debian.yml b/roles/keycloak_quarkus/vars/debian.yml index 8ff6775..e8c90e3 100644 --- a/roles/keycloak_quarkus/vars/debian.yml +++ b/roles/keycloak_quarkus/vars/debian.yml @@ -8,4 +8,4 @@ keycloak_quarkus_prereq_package_list: - tzdata keycloak_quarkus_configure_iptables: True keycloak_quarkus_sysconf_file: /etc/default/keycloak -keycloak_quarkus_pkg_java_home: "/lib/jvm/java-{{ keycloak_quarkus_jvm_package | regex_search('(?!:openjdk-)[0-9.]+') }}-openjdk-{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}" +keycloak_quarkus_pkg_java_home: "/usr/lib/jvm/java-{{ keycloak_quarkus_jvm_package | regex_search('(?!:openjdk-)[0-9.]+') }}-openjdk-{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}" From 467cfda0f7ef1d62157970d7e91a03b4929842e0 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 25 Mar 2024 15:41:57 +0100 Subject: [PATCH 352/554] same changes for keycloak-legacy --- molecule/debian/converge.yml | 3 ++- molecule/debian/verify.yml | 12 ----------- roles/keycloak/defaults/main.yml | 2 -- roles/keycloak/tasks/main.yml | 11 ++-------- roles/keycloak/tasks/prereqs.yml | 20 ++++++++++++------ roles/keycloak/tasks/systemd.yml | 21 +------------------ .../keycloak/templates/keycloak-sysconfig.j2 | 2 +- roles/keycloak/templates/keycloak.service.j2 | 2 +- roles/keycloak/vars/debian.yml | 11 ++++++++++ roles/keycloak/vars/redhat.yml | 11 ++++++++++ 10 files changed, 43 insertions(+), 52 deletions(-) create mode 100644 roles/keycloak/vars/debian.yml create mode 100644 roles/keycloak/vars/redhat.yml diff --git a/molecule/debian/converge.yml b/molecule/debian/converge.yml index 0be6a85..17517b8 100644 --- a/molecule/debian/converge.yml +++ b/molecule/debian/converge.yml @@ -2,7 +2,6 @@ - name: Converge hosts: all vars: - keycloak_admin_password: "remembertochangeme" keycloak_quarkus_admin_pass: "remembertochangeme" keycloak_realm: TestRealm keycloak_quarkus_log: file @@ -38,3 +37,5 @@ - role: keycloak_quarkus - role: keycloak_realm keycloak_realm: TestRealm + keycloak_admin_password: "remembertochangeme" + keycloak_context: '' diff --git a/molecule/debian/verify.yml b/molecule/debian/verify.yml index 040558a..59bf483 100644 --- a/molecule/debian/verify.yml +++ b/molecule/debian/verify.yml @@ -16,18 +16,6 @@ - ansible_facts.services["keycloak.service"]["state"] == "running" - ansible_facts.services["keycloak.service"]["status"] == "enabled" - - name: Verify we are running on requested JAVA_HOME # noqa blocked_modules command-instead-of-module - ansible.builtin.shell: | - set -o pipefail - ps -ef | grep '/opt/openjdk' | grep -v grep - args: - executable: /bin/bash - changed_when: False - - - name: Set internal envvar - ansible.builtin.set_fact: - hera_home: "{{ lookup('env', 'HERA_HOME') }}" - - name: Verify openid config block: - name: Fetch openID config # noqa blocked_modules command-instead-of-module diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 6658774..cfa9a3f 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -8,8 +8,6 @@ keycloak_installdir: "{{ keycloak_dest }}/keycloak-{{ keycloak_version }}" keycloak_offline_install: false ### Install location and service settings -keycloak_jvm_package: "{{ 'java-1.8.0-openjdk-headless' if ansible_facts.os_family == 'RedHat' else 'openjdk-8-jdk-headless' }}" - keycloak_java_home: keycloak_dest: /opt/keycloak keycloak_jboss_home: "{{ keycloak_installdir }}" diff --git a/roles/keycloak/tasks/main.yml b/roles/keycloak/tasks/main.yml index 284900b..a21f359 100644 --- a/roles/keycloak/tasks/main.yml +++ b/roles/keycloak/tasks/main.yml @@ -5,15 +5,8 @@ tags: - prereqs -- name: Debian specific tasks - ansible.builtin.include_tasks: debian.yml - when: ansible_facts.os_family == "Debian" - tags: - - unbound - -- name: RedHat specific tasks - ansible.builtin.include_tasks: redhat.yml - when: ansible_facts.os_family == "RedHat" +- name: Distro specific tasks + ansible.builtin.include_tasks: "{{ ansible_os_family | lower }}.yml" tags: - unbound diff --git a/roles/keycloak/tasks/prereqs.yml b/roles/keycloak/tasks/prereqs.yml index 565931b..c92bb1c 100644 --- a/roles/keycloak/tasks/prereqs.yml +++ b/roles/keycloak/tasks/prereqs.yml @@ -36,12 +36,20 @@ success_msg: "Configuring JDBC persistence using {{ keycloak_jdbc_engine }} database" when: keycloak_db_enabled +- name: Validate OS family + ansible.builtin.assert: + that: + - ansible_os_family in ["RedHat", "Debian"] + quiet: true + fail_msg: "Can only install on RedHat or Debian OS families; found {{ ansible_os_family }}" + success_msg: "Installing on {{ ansible_os_family }}" + +- name: Load OS specific variables + ansible.builtin.include_vars: "vars/{{ ansible_os_family | lower }}.yml" + tags: + - always + - name: Ensure required packages are installed ansible.builtin.include_tasks: fastpackages.yml vars: - packages_list: - - "{{ keycloak_jvm_package }}" - - unzip - - "{{ 'procps-ng' if ansible_facts.os_family == 'RedHat' else 'procps' }}" - - "{{ 'initscripts' if ansible_facts.os_family == 'RedHat' else 'apt' }}" - - "{{ 'tzdata-java' if ansible_facts.os_family == 'RedHat' else 'tzdata' }}" + packages_list: "{{ keycloak_prereq_package_list }}" diff --git a/roles/keycloak/tasks/systemd.yml b/roles/keycloak/tasks/systemd.yml index cf84c32..40fa6b8 100644 --- a/roles/keycloak/tasks/systemd.yml +++ b/roles/keycloak/tasks/systemd.yml @@ -26,29 +26,10 @@ become: true ansible.builtin.template: src: keycloak-sysconfig.j2 - dest: /etc/default/keycloak + dest: "{{ keycloak_sysconf_file }}" owner: root group: root mode: 0644 - vars: - keycloak_rpm_java_home: "{{ rpm_java_home }}" - when: - - ansible_facts.os_family == "Debian" - notify: - - restart keycloak - -- name: "Configure sysconfig file for {{ keycloak.service_name }} service" - become: true - ansible.builtin.template: - src: keycloak-sysconfig.j2 - dest: /etc/sysconfig/keycloak - owner: root - group: root - mode: 0644 - vars: - keycloak_rpm_java_home: "{{ rpm_java_home }}" - when: - - ansible_facts.os_family == "RedHat" notify: - restart keycloak diff --git a/roles/keycloak/templates/keycloak-sysconfig.j2 b/roles/keycloak/templates/keycloak-sysconfig.j2 index 4c38522..33889df 100644 --- a/roles/keycloak/templates/keycloak-sysconfig.j2 +++ b/roles/keycloak/templates/keycloak-sysconfig.j2 @@ -1,6 +1,6 @@ {{ ansible_managed | comment }} JAVA_OPTS='{{ keycloak_java_opts }}' -JAVA_HOME={{ keycloak_java_home | default(keycloak_rpm_java_home, true) }} +JAVA_HOME={{ keycloak_java_home | default(keycloak_pkg_java_home, true) }} JBOSS_HOME={{ keycloak.home }} KEYCLOAK_BIND_ADDRESS={{ keycloak_bind_address }} KEYCLOAK_HTTP_PORT={{ keycloak_http_port }} diff --git a/roles/keycloak/templates/keycloak.service.j2 b/roles/keycloak/templates/keycloak.service.j2 index eea3ba1..9a04e88 100644 --- a/roles/keycloak/templates/keycloak.service.j2 +++ b/roles/keycloak/templates/keycloak.service.j2 @@ -11,7 +11,7 @@ StartLimitBurst={{ keycloak_service_startlimitburst }} User={{ keycloak_service_user }} Group={{ keycloak_service_group }} {% endif -%} -EnvironmentFile=-/etc/sysconfig/keycloak +EnvironmentFile=-{{ keycloak_sysconf_file }} PIDFile={{ keycloak_service_pidfile }} ExecStart={{ keycloak.home }}/bin/standalone.sh $WILDFLY_OPTS WorkingDirectory={{ keycloak.home }} diff --git a/roles/keycloak/vars/debian.yml b/roles/keycloak/vars/debian.yml new file mode 100644 index 0000000..ac3df14 --- /dev/null +++ b/roles/keycloak/vars/debian.yml @@ -0,0 +1,11 @@ +--- +keycloak_jvm_package: openjdk-11-jdk-headless +keycloak_prereq_package_list: + - "{{ keycloak_jvm_package }}" + - unzip + - procps + - apt + - tzdata +keycloak_configure_iptables: True +keycloak_sysconf_file: /etc/default/keycloak +keycloak_pkg_java_home: "/usr/lib/jvm/java-{{ keycloak_jvm_package | regex_search('(?!:openjdk-)[0-9.]+') }}-openjdk-{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}" diff --git a/roles/keycloak/vars/redhat.yml b/roles/keycloak/vars/redhat.yml new file mode 100644 index 0000000..206251e --- /dev/null +++ b/roles/keycloak/vars/redhat.yml @@ -0,0 +1,11 @@ +--- +keycloak_jvm_package: java-1.8.0-openjdk-headless +keycloak_prereq_package_list: + - "{{ keycloak_jvm_package }}" + - unzip + - procps-ng + - initscripts + - tzdata-java +keycloak_configure_iptables: False +keycloak_sysconf_file: /etc/sysconfig/keycloak +keycloak_pkg_java_home: "/etc/alternatives/jre_{{ keycloak_jvm_package | regex_search('(?<=java-)[0-9.]+') }}" From 2bbf7d9cc4a94f75942d8a35a56abcd04a33cd3b Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 25 Mar 2024 16:30:13 +0100 Subject: [PATCH 353/554] revert JVM var that cannot be overridden --- molecule/default/converge.yml | 2 +- roles/keycloak/meta/argument_specs.yml | 55 +------------------ roles/keycloak/tasks/systemd.yml | 12 ---- roles/keycloak/vars/debian.yml | 6 +- roles/keycloak/vars/redhat.yml | 7 +-- roles/keycloak_quarkus/defaults/main.yml | 4 +- .../keycloak_quarkus/meta/argument_specs.yml | 41 ++------------ roles/keycloak_quarkus/vars/debian.yml | 7 +-- roles/keycloak_quarkus/vars/redhat.yml | 7 +-- 9 files changed, 22 insertions(+), 119 deletions(-) diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index ace4743..5927ff9 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -1,7 +1,7 @@ --- - name: Converge hosts: all - vars: + vars: keycloak_admin_password: "remembertochangeme" keycloak_jvm_package: java-11-openjdk-headless keycloak_modcluster_enabled: True diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index ca1cb8b..7ba6509 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -2,47 +2,38 @@ argument_specs: main: options: keycloak_version: - # line 3 of keycloak/defaults/main.yml default: "18.0.2" description: "keycloak.org package version" type: "str" keycloak_archive: - # line 4 of keycloak/defaults/main.yml default: "keycloak-legacy-{{ keycloak_version }}.zip" description: "keycloak install archive filename" type: "str" keycloak_configure_iptables: - # line 33 of keycloak/defaults/main.yml default: false description: "Ensure iptables is running and configure keycloak ports" type: "bool" keycloak_configure_firewalld: - # line 33 of keycloak/defaults/main.yml default: false description: "Ensure firewalld is running and configure keycloak ports" type: "bool" keycloak_download_url: - # line 5 of keycloak/defaults/main.yml default: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_version }}/{{ keycloak_archive }}" description: "Download URL for keycloak" type: "str" keycloak_download_url_9x: - # line 6 of keycloak/defaults/main.yml default: "https://downloads.jboss.org/keycloak/{{ keycloak_version }}/{{ keycloak_archive }}" description: "Download URL for keycloak (deprecated)" type: "str" keycloak_installdir: - # line 7 of keycloak/defaults/main.yml default: "{{ keycloak_dest }}/keycloak-{{ keycloak_version }}" description: "Installation path" type: "str" keycloak_offline_install: - # line 20 of keycloak/defaults/main.yml default: false description: "Perform an offline install" type: "bool" keycloak_jvm_package: - # line 23 of keycloak/defaults/main.yml default: "java-1.8.0-openjdk-headless" description: "RHEL java package runtime rpm" type: "str" @@ -50,12 +41,10 @@ argument_specs: description: "JAVA_HOME of installed JRE, leave empty for using specified keycloak_jvm_package RPM path" type: "str" keycloak_dest: - # line 24 of keycloak/defaults/main.yml default: "/opt/keycloak" description: "Root installation directory" type: "str" keycloak_jboss_home: - # line 25 of keycloak/defaults/main.yml default: "{{ keycloak_installdir }}" description: "Installation work directory" type: "str" @@ -64,52 +53,42 @@ argument_specs: description: "Port offset for the JBoss socket binding" type: "int" keycloak_config_dir: - # line 26 of keycloak/defaults/main.yml default: "{{ keycloak_jboss_home }}/standalone/configuration" description: "Path for configuration" type: "str" keycloak_config_standalone_xml: - # line 27 of keycloak/defaults/main.yml default: "keycloak.xml" description: "Service configuration filename" type: "str" keycloak_config_path_to_standalone_xml: - # line 28 of keycloak/defaults/main.yml default: "{{ keycloak_jboss_home }}/standalone/configuration/{{ keycloak_config_standalone_xml }}" description: "Custom path for configuration" type: "str" keycloak_config_override_template: - # line 30 of keycloak/defaults/main.yml default: "" description: "Path to custom template for standalone.xml configuration" type: "str" - keycloak_service_runas: - # line 20 of keycloak/defaults/main.yml + keycloak_service_runas: default: false description: "Enable execution of service as `keycloak_service_user`" type: "bool" keycloak_service_user: - # line 29 of keycloak/defaults/main.yml default: "keycloak" description: "posix account username" type: "str" keycloak_service_group: - # line 30 of keycloak/defaults/main.yml default: "keycloak" description: "posix account group" type: "str" keycloak_service_pidfile: - # line 31 of keycloak/defaults/main.yml default: "/run/keycloak/keycloak.pid" description: "PID file path for service" type: "str" keycloak_features: - # line 17 of keycloak/defaults/main.yml default: "[]" description: "List of `name`/`status` pairs of features (also known as profiles on RH-SSO) to `enable` or `disable`, example: `[ { name: 'docker', status: 'enabled' } ]`" type: "list" keycloak_bind_address: - # line 34 of keycloak/defaults/main.yml default: "0.0.0.0" description: "Address for binding service ports" type: "str" @@ -118,52 +97,42 @@ argument_specs: description: "Address for binding the management ports" type: "str" keycloak_host: - # line 35 of keycloak/defaults/main.yml default: "localhost" description: "Hostname for service" type: "str" keycloak_http_port: - # line 36 of keycloak/defaults/main.yml default: 8080 description: "Listening HTTP port" type: "int" keycloak_https_port: - # line 37 of keycloak/defaults/main.yml default: 8443 description: "Listening HTTPS port" type: "int" keycloak_ajp_port: - # line 38 of keycloak/defaults/main.yml default: 8009 description: "Listening AJP port" type: "int" keycloak_jgroups_port: - # line 39 of keycloak/defaults/main.yml default: 7600 description: "jgroups cluster tcp port" type: "int" keycloak_management_http_port: - # line 40 of keycloak/defaults/main.yml default: 9990 description: "Management port (http)" type: "int" keycloak_management_https_port: - # line 41 of keycloak/defaults/main.yml default: 9993 description: "Management port (https)" type: "int" keycloak_java_opts: - # line 42 of keycloak/defaults/main.yml default: "-Xms1024m -Xmx2048m" description: "Additional JVM options" type: "str" keycloak_prefer_ipv4: - # line 43 of keycloak/defaults/main.yml default: true description: "Prefer IPv4 stack and addresses for port binding" type: "bool" keycloak_ha_enabled: - # line 46 of keycloak/defaults/main.yml default: false description: "Enable auto configuration for database backend, clustering and remote caches on infinispan" type: "bool" @@ -172,27 +141,22 @@ argument_specs: description: "Discovery protocol for HA cluster members" type: "str" keycloak_db_enabled: - # line 48 of keycloak/defaults/main.yml default: "{{ True if keycloak_ha_enabled else False }}" description: "Enable auto configuration for database backend" type: "bool" keycloak_admin_user: - # line 51 of keycloak/defaults/main.yml default: "admin" description: "Administration console user account" type: "str" keycloak_auth_realm: - # line 52 of keycloak/defaults/main.yml default: "master" description: "Name for rest authentication realm" type: "str" keycloak_auth_client: - # line 53 of keycloak/defaults/main.yml default: "admin-cli" description: "Authentication client for configuration REST calls" type: "str" keycloak_force_install: - # line 55 of keycloak/defaults/main.yml default: false description: "Remove pre-existing versions of service" type: "bool" @@ -201,7 +165,6 @@ argument_specs: description: "Enable configuration for modcluster subsystem" type: "bool" keycloak_modcluster_url: - # line 58 of keycloak/defaults/main.yml default: "localhost" description: "URL for the modcluster reverse proxy" type: "str" @@ -214,7 +177,6 @@ argument_specs: description: "List of modproxy node URLs in the format { host, port } for the modcluster reverse proxy" type: "list" keycloak_frontend_url: - # line 59 of keycloak/defaults/main.yml default: "http://localhost" description: "Frontend URL for keycloak endpoints when a reverse proxy is used" type: "str" @@ -223,77 +185,62 @@ argument_specs: description: "Force backend requests to use the frontend URL" type: "bool" keycloak_infinispan_user: - # line 62 of keycloak/defaults/main.yml default: "supervisor" description: "Username for connecting to infinispan" type: "str" keycloak_infinispan_pass: - # line 63 of keycloak/defaults/main.yml default: "supervisor" description: "Password for connecting to infinispan" type: "str" keycloak_infinispan_url: - # line 64 of keycloak/defaults/main.yml default: "localhost" description: "URL for the infinispan remote-cache server" type: "str" keycloak_infinispan_sasl_mechanism: - # line 65 of keycloak/defaults/main.yml default: "SCRAM-SHA-512" description: "Authentication type to infinispan server" type: "str" keycloak_infinispan_use_ssl: - # line 66 of keycloak/defaults/main.yml default: false description: "Enable hotrod client TLS communication" type: "bool" keycloak_infinispan_trust_store_path: - # line 68 of keycloak/defaults/main.yml default: "/etc/pki/java/cacerts" description: "TODO document argument" type: "str" keycloak_infinispan_trust_store_password: - # line 69 of keycloak/defaults/main.yml default: "changeit" description: "Path to truststore containing infinispan server certificate" type: "str" keycloak_jdbc_engine: - # line 72 of keycloak/defaults/main.yml default: "postgres" description: "Backend database flavour when db is enabled: [ postgres, mariadb, sqlserver ]" type: "str" keycloak_db_user: - # line 74 of keycloak/defaults/main.yml default: "keycloak-user" description: "Username for connecting to database" type: "str" keycloak_db_pass: - # line 75 of keycloak/defaults/main.yml default: "keycloak-pass" description: "Password for connecting to database" type: "str" keycloak_jdbc_url: - # line 76 of keycloak/defaults/main.yml default: "{{ keycloak_default_jdbc[keycloak_jdbc_engine].url }}" description: "URL for connecting to backend database" type: "str" keycloak_jdbc_driver_version: - # line 77 of keycloak/defaults/main.yml default: "{{ keycloak_default_jdbc[keycloak_jdbc_engine].version }}" description: "Version for the JDBC driver to download" type: "str" keycloak_admin_password: - # line 4 of keycloak/vars/main.yml required: true description: "Password for the administration console user account" type: "str" keycloak_url: - # line 12 of keycloak/vars/main.yml default: "http://{{ keycloak_host }}:{{ keycloak_http_port + keycloak_jboss_port_offset }}" description: "URL for configuration rest calls" type: "str" keycloak_management_url: - # line 13 of keycloak/vars/main.yml default: "http://{{ keycloak_host }}:{{ keycloak_management_http_port + keycloak_jboss_port_offset }}" description: "URL for management console rest calls" type: "str" diff --git a/roles/keycloak/tasks/systemd.yml b/roles/keycloak/tasks/systemd.yml index 40fa6b8..797eb7b 100644 --- a/roles/keycloak/tasks/systemd.yml +++ b/roles/keycloak/tasks/systemd.yml @@ -10,18 +10,6 @@ notify: - restart keycloak -- name: Determine JAVA_HOME for selected JVM RPM - ansible.builtin.set_fact: - rpm_java_home: "/lib/jvm/java-{{ keycloak_jvm_package | regex_search('(?<=java-)[0-9.]+') }}-openjdk-{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}" - when: - - ansible_facts.os_family == 'Debian' - -- name: Determine JAVA_HOME for selected JVM RPM - ansible.builtin.set_fact: - rpm_java_home: "/etc/alternatives/jre_{{ keycloak_jvm_package | regex_search('(?<=java-)[0-9.]+') }}" - when: - - ansible_facts.os_family == 'RedHat' - - name: "Configure sysconfig file for {{ keycloak.service_name }} service" become: true ansible.builtin.template: diff --git a/roles/keycloak/vars/debian.yml b/roles/keycloak/vars/debian.yml index ac3df14..60cdfa8 100644 --- a/roles/keycloak/vars/debian.yml +++ b/roles/keycloak/vars/debian.yml @@ -1,11 +1,11 @@ --- -keycloak_jvm_package: openjdk-11-jdk-headless +keycloak_varjvm_package: "{{ keycloak_jvm_package | default('openjdk-11-jdk-headless') }}" keycloak_prereq_package_list: - - "{{ keycloak_jvm_package }}" + - "{{ keycloak_varjvm_package }}" - unzip - procps - apt - tzdata keycloak_configure_iptables: True keycloak_sysconf_file: /etc/default/keycloak -keycloak_pkg_java_home: "/usr/lib/jvm/java-{{ keycloak_jvm_package | regex_search('(?!:openjdk-)[0-9.]+') }}-openjdk-{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}" +keycloak_pkg_java_home: "/usr/lib/jvm/java-{{ keycloak_varjvm_package | regex_search('(?!:openjdk-)[0-9.]+') }}-openjdk-{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}" diff --git a/roles/keycloak/vars/redhat.yml b/roles/keycloak/vars/redhat.yml index 206251e..6c36847 100644 --- a/roles/keycloak/vars/redhat.yml +++ b/roles/keycloak/vars/redhat.yml @@ -1,11 +1,10 @@ --- -keycloak_jvm_package: java-1.8.0-openjdk-headless +keycloak_varjvm_package: "{{ keycloak_jvm_package | default('java-1.8.0-openjdk-headless') }}" keycloak_prereq_package_list: - - "{{ keycloak_jvm_package }}" + - "{{ keycloak_varjvm_package }}" - unzip - procps-ng - initscripts - tzdata-java -keycloak_configure_iptables: False keycloak_sysconf_file: /etc/sysconfig/keycloak -keycloak_pkg_java_home: "/etc/alternatives/jre_{{ keycloak_jvm_package | regex_search('(?<=java-)[0-9.]+') }}" +keycloak_pkg_java_home: "/etc/alternatives/jre_{{ keycloak_varjvm_package | regex_search('(?<=java-)[0-9.]+') }}" diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index e630bd3..d931cab 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -17,11 +17,13 @@ keycloak_quarkus_start_dev: false keycloak_quarkus_service_user: keycloak keycloak_quarkus_service_group: keycloak keycloak_quarkus_service_pidfile: "/run/keycloak/keycloak.pid" -keycloak_quarkus_configure_firewalld: false keycloak_quarkus_service_restart_always: false keycloak_quarkus_service_restart_on_failure: false keycloak_quarkus_service_restartsec: "10s" +keycloak_quarkus_configure_firewalld: false +keycloak_quarkus_configure_iptables: false + ### administrator console password keycloak_quarkus_admin_user: admin keycloak_quarkus_admin_pass: diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index b1baea2..c7cd446 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -2,32 +2,26 @@ argument_specs: main: options: keycloak_quarkus_version: - # line 3 of defaults/main.yml - default: "17.0.1" + default: "23.0.7" description: "keycloak.org package version" type: "str" keycloak_quarkus_archive: - # line 4 of defaults/main.yml default: "keycloak-{{ keycloak_quarkus_version }}.zip" description: "keycloak install archive filename" type: "str" keycloak_quarkus_download_url: - # line 5 of defaults/main.yml default: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" description: "Download URL for keycloak" type: "str" keycloak_quarkus_installdir: - # line 6 of defaults/main.yml default: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" description: "Installation path" type: "str" keycloak_quarkus_offline_install: - # line 9 of defaults/main.yml default: false description: "Perform an offline install" type: "bool" keycloak_quarkus_jvm_package: - # line 12 of defaults/main.yml default: "java-11-openjdk-headless" description: "RHEL java package runtime" type: "str" @@ -35,37 +29,34 @@ argument_specs: description: "JAVA_HOME of installed JRE, leave empty for using specified keycloak_jvm_package RPM path" type: "str" keycloak_quarkus_dest: - # line 13 of defaults/main.yml default: "/opt/keycloak" description: "Installation root path" type: "str" keycloak_quarkus_home: - # line 14 of defaults/main.yml default: "{{ keycloak_quarkus_installdir }}" description: "Installation work directory" type: "str" keycloak_quarkus_config_dir: - # line 15 of defaults/main.yml default: "{{ keycloak_quarkus_home }}/conf" description: "Path for configuration" type: "str" keycloak_quarkus_service_user: - # line 16 of defaults/main.yml default: "keycloak" description: "Posix account username" type: "str" keycloak_quarkus_service_group: - # line 17 of defaults/main.yml default: "keycloak" description: "Posix account group" type: "str" keycloak_quarkus_service_pidfile: - # line 18 of defaults/main.yml default: "/run/keycloak/keycloak.pid" description: "Pid file path for service" type: "str" keycloak_quarkus_configure_firewalld: - # line 19 of defaults/main.yml + default: false + description: "Ensure firewalld is running and configure keycloak ports" + type: "bool" + keycloak_quarkus_configure_iptables: default: false description: "Ensure firewalld is running and configure keycloak ports" type: "bool" @@ -90,12 +81,10 @@ argument_specs: description: "Password of console admin account" type: "str" keycloak_quarkus_master_realm: - # line 24 of defaults/main.yml default: "master" description: "Name for rest authentication realm" type: "str" keycloak_quarkus_bind_address: - # line 27 of defaults/main.yml default: "0.0.0.0" description: "Address for binding service ports" type: "str" @@ -116,7 +105,6 @@ argument_specs: description: "Enable listener on HTTP port" type: "bool" keycloak_quarkus_http_port: - # line 29 of defaults/main.yml default: 8080 description: "HTTP port" type: "int" @@ -157,27 +145,22 @@ argument_specs: description: "Password for the trust store" type: "str" keycloak_quarkus_https_port: - # line 30 of defaults/main.yml default: 8443 description: "HTTPS port" type: "int" keycloak_quarkus_ajp_port: - # line 31 of defaults/main.yml default: 8009 description: "AJP port" type: "int" keycloak_quarkus_jgroups_port: - # line 32 of defaults/main.yml default: 7800 description: "jgroups cluster tcp port" type: "int" keycloak_quarkus_java_opts: - # line 33 of defaults/main.yml default: "-Xms1024m -Xmx2048m" description: "Additional JVM options" type: "str" keycloak_quarkus_ha_enabled: - # line 36 of defaults/main.yml default: false description: "Enable auto configuration for database backend, clustering and remote caches on infinispan" type: "bool" @@ -186,7 +169,6 @@ argument_specs: description: "Discovery protocol for HA cluster members" type: "str" keycloak_quarkus_db_enabled: - # line 38 of defaults/main.yml default: "{{ True if keycloak_quarkus_ha_enabled else False }}" description: "Enable auto configuration for database backend" type: "str" @@ -204,7 +186,6 @@ argument_specs: description: "Service URL for the admin console" type: "str" keycloak_quarkus_metrics_enabled: - # line 43 of defaults/main.yml default: false description: "Whether to enable metrics" type: "bool" @@ -213,62 +194,50 @@ argument_specs: description: "If the server should expose health check endpoints" type: "bool" keycloak_quarkus_ispn_user: - # line 46 of defaults/main.yml default: "supervisor" description: "Username for connecting to infinispan" type: "str" keycloak_quarkus_ispn_pass: - # line 47 of defaults/main.yml default: "supervisor" description: "Password for connecting to infinispan" type: "str" keycloak_quarkus_ispn_hosts: - # line 48 of defaults/main.yml default: "localhost:11222" description: "host name/port for connecting to infinispan, eg. host1:11222;host2:11222" type: "str" keycloak_quarkus_ispn_sasl_mechanism: - # line 49 of defaults/main.yml default: "SCRAM-SHA-512" description: "Infinispan auth mechanism" type: "str" keycloak_quarkus_ispn_use_ssl: - # line 50 of defaults/main.yml default: false description: "Whether infinispan uses TLS connection" type: "bool" keycloak_quarkus_ispn_trust_store_path: - # line 52 of defaults/main.yml default: "/etc/pki/java/cacerts" description: "Path to infinispan server trust certificate" type: "str" keycloak_quarkus_ispn_trust_store_password: - # line 53 of defaults/main.yml default: "changeit" description: "Password for infinispan certificate keystore" type: "str" keycloak_quarkus_jdbc_engine: - # line 56 of defaults/main.yml default: "postgres" description: "Database engine [mariadb,postres,mssql]" type: "str" keycloak_quarkus_db_user: - # line 58 of defaults/main.yml default: "keycloak-user" description: "User for database connection" type: "str" keycloak_quarkus_db_pass: - # line 59 of defaults/main.yml default: "keycloak-pass" description: "Password for database connection" type: "str" keycloak_quarkus_jdbc_url: - # line 60 of defaults/main.yml default: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].url }}" description: "JDBC URL for connecting to database" type: "str" keycloak_quarkus_jdbc_driver_version: - # line 61 of defaults/main.yml default: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].version }}" description: "Version for JDBC driver" type: "str" diff --git a/roles/keycloak_quarkus/vars/debian.yml b/roles/keycloak_quarkus/vars/debian.yml index e8c90e3..a42eb5f 100644 --- a/roles/keycloak_quarkus/vars/debian.yml +++ b/roles/keycloak_quarkus/vars/debian.yml @@ -1,11 +1,10 @@ --- -keycloak_quarkus_jvm_package: openjdk-17-jdk-headless +keycloak_quarkus_varjvm_package: "{{ keycloak_quarkus_jvm_package | default('openjdk-17-jdk-headless') }}" keycloak_quarkus_prereq_package_list: - - "{{ keycloak_quarkus_jvm_package }}" + - "{{ keycloak_quarkus_varjvm_package }}" - unzip - procps - apt - tzdata -keycloak_quarkus_configure_iptables: True keycloak_quarkus_sysconf_file: /etc/default/keycloak -keycloak_quarkus_pkg_java_home: "/usr/lib/jvm/java-{{ keycloak_quarkus_jvm_package | regex_search('(?!:openjdk-)[0-9.]+') }}-openjdk-{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}" +keycloak_quarkus_pkg_java_home: "/usr/lib/jvm/java-{{ keycloak_quarkus_varjvm_package | regex_search('(?!:openjdk-)[0-9.]+') }}-openjdk-{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}" diff --git a/roles/keycloak_quarkus/vars/redhat.yml b/roles/keycloak_quarkus/vars/redhat.yml index e40a94a..c311321 100644 --- a/roles/keycloak_quarkus/vars/redhat.yml +++ b/roles/keycloak_quarkus/vars/redhat.yml @@ -1,11 +1,10 @@ --- -keycloak_quarkus_jvm_package: java-17-openjdk-headless +keycloak_quarkus_varjvm_package: "{{ keycloak_quarkus_jvm_package | default('java-17-openjdk-headless') }}" keycloak_quarkus_prereq_package_list: - - "{{ keycloak_quarkus_jvm_package }}" + - "{{ keycloak_quarkus_varjvm_package }}" - unzip - procps-ng - initscripts - tzdata-java -keycloak_quarkus_configure_iptables: False keycloak_quarkus_sysconf_file: /etc/sysconfig/keycloak -keycloak_quarkus_pkg_java_home: "/etc/alternatives/jre_{{ keycloak_quarkus_jvm_package | regex_search('(?<=java-)[0-9.]+') }}" +keycloak_quarkus_pkg_java_home: "/etc/alternatives/jre_{{ keycloak_quarkus_varjvm_package | regex_search('(?<=java-)[0-9.]+') }}" From c2e456e1d55ad8943c5f053d1e05b3f3fc0ce14f Mon Sep 17 00:00:00 2001 From: avskor Date: Thu, 4 Apr 2024 11:22:18 +0300 Subject: [PATCH 354/554] Fix #125. Permission error when the become variable is set to true in the playbook --- roles/keycloak_quarkus/tasks/install.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index e865b72..0162266 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -50,6 +50,7 @@ path: "{{ lookup('env', 'PWD') }}" register: local_path delegate_to: localhost + become: false - name: Download keycloak archive ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user @@ -57,6 +58,7 @@ dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" mode: 0640 delegate_to: localhost + become: false run_once: true when: - archive_path is defined From 8f8de33350fa7b2abfdd030ef26c0d1678cff0f4 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 8 Apr 2024 16:47:49 +0200 Subject: [PATCH 355/554] JVM arguments go IN JAVA_OPTS --- molecule/default/converge.yml | 2 +- roles/keycloak_quarkus/README.md | 4 +++- roles/keycloak_quarkus/defaults/main.yml | 7 ++++++- roles/keycloak_quarkus/meta/argument_specs.yml | 12 ++++++++++-- .../keycloak_quarkus/templates/keycloak-sysconfig.j2 | 2 +- 5 files changed, 21 insertions(+), 6 deletions(-) diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index 5927ff9..07cd724 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -52,7 +52,7 @@ pre_tasks: - name: "Retrieve assets server from env" ansible.builtin.set_fact: - assets_server: "{{ lookup('env','MIDDLEWARE_DOWNLOAD_RELEASE_SERVER_URL') }}" + assets_server: "{{ lookup('env', 'MIDDLEWARE_DOWNLOAD_RELEASE_SERVER_URL') }}" - name: "Set offline when assets server from env is defined" ansible.builtin.set_fact: diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 7c01eae..db02574 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -38,7 +38,9 @@ Role Defaults |`keycloak_quarkus_service_pidfile`| Pid file path for service | `/run/keycloak.pid` | |`keycloak_quarkus_jvm_package`| RHEL java package runtime | `java-17-openjdk-headless` | |`keycloak_quarkus_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_quarkus_jvm_package RPM path | `None` | -|`keycloak_quarkus_java_opts`| Additional JVM options | `-Xms1024m -Xmx2048m` | +|`keycloak_quarkus_java_opts`| Heap memory JVM setting | `-Xms1024m -Xmx2048m` | +|`keycloak_quarkus_java_jvm_opts`| Other JVM settings | same as keycloak | +|`keycloak_quarkus_java_opts`| JVM arguments; if overriden, it takes precedence over `keycloak_quarkus_java_*` | `{{ keycloak_quarkus_java_heap_opts + ' ' + keycloak_quarkus_java_jvm_opts }}` | |`keycloak_quarkus_frontend_url`| Set the base URL for frontend URLs, including scheme, host, port and path | | |`keycloak_quarkus_admin_url`| Set the base URL for accessing the administration console, including scheme, host, port and path | | |`keycloak_quarkus_http_relative_path` | Set the path relative to / for serving resources. The path must start with a / | `/` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index d931cab..6848acf 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -39,7 +39,12 @@ keycloak_quarkus_http_port: 8080 keycloak_quarkus_https_port: 8443 keycloak_quarkus_ajp_port: 8009 keycloak_quarkus_jgroups_port: 7800 -keycloak_quarkus_java_opts: "-Xms1024m -Xmx2048m" +keycloak_quarkus_java_heap_opts: "-Xms1024m -Xmx2048m" +keycloak_quarkus_java_jvm_opts: "-XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 + -Dsun.err.encoding=UTF-8 -Dstdout.encoding=UTF-8 -Dstderr.encoding=UTF-8 -XX:+ExitOnOutOfMemoryError + -Djava.security.egd=file:/dev/urandom -XX:+UseParallelGC -XX:GCTimeRatio=4 + -XX:AdaptiveSizePolicyWeight=90 -XX:FlightRecorderOptions=stackdepth=512" +keycloak_quarkus_java_opts: "{{ keycloak_quarkus_java_heap_opts + ' ' + keycloak_quarkus_java_jvm_opts }}" ### TLS/HTTPS configuration keycloak_quarkus_https_key_file_enabled: false diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index c7cd446..f4b87d7 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -156,9 +156,17 @@ argument_specs: default: 7800 description: "jgroups cluster tcp port" type: "int" - keycloak_quarkus_java_opts: + keycloak_quarkus_java_heap_opts: default: "-Xms1024m -Xmx2048m" - description: "Additional JVM options" + description: "Heap memory JVM setting" + type: "str" + keycloak_quarkus_java_jvm_opts: + default: "-XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.err.encoding=UTF-8 -Dstdout.encoding=UTF-8 -Dstderr.encoding=UTF-8 -XX:+ExitOnOutOfMemoryError -Djava.security.egd=file:/dev/urandom -XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -XX:FlightRecorderOptions=stackdepth=512" + description: "Other JVM settings" + type: "str" + keycloak_quarkus_java_opts: + default: "{{ keycloak_quarkus_java_heap_opts + ' ' + keycloak_quarkus_java_jvm_opts }}" + description: "JVM arguments, by default heap_opts + jvm_opts, if overriden it takes precedence over them" type: "str" keycloak_quarkus_ha_enabled: default: false diff --git a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 index 358794c..2ec71e0 100644 --- a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 +++ b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 @@ -3,4 +3,4 @@ KEYCLOAK_ADMIN={{ keycloak_quarkus_admin_user }} KEYCLOAK_ADMIN_PASSWORD='{{ keycloak_quarkus_admin_pass }}' PATH={{ keycloak_quarkus_java_home | default(keycloak_pkg_java_home, true) }}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin JAVA_HOME={{ keycloak_quarkus_java_home | default(keycloak_pkg_java_home, true) }} -JAVA_OPTS_APPEND={{ keycloak_quarkus_java_opts }} +JAVA_OPTS={{ keycloak_quarkus_java_opts }} From 8e2f3eb77f0687c12761305205b16c5efdfeaaaf Mon Sep 17 00:00:00 2001 From: Christian Iuga Date: Mon, 15 Apr 2024 14:41:56 +0200 Subject: [PATCH 356/554] Permit parse reverse proxy headers - Via created a new optional variable : keycloak_quarkus_proxy_headers - Fix enhancement #183 - see https://www.keycloak.org/server/reverseproxy about the official documentation --- roles/keycloak_quarkus/README.md | 2 +- roles/keycloak_quarkus/templates/keycloak.service.j2 | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index db02574..d6fa46d 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -54,7 +54,7 @@ Role Defaults |`keycloak_quarkus_https_trust_store_enabled`| Enalbe confiugration of a trust store | `False` | |`keycloak_quarkus_trust_store_file`| The file pat to the trust store | `{{ keycloak.home }}/conf/trust_store.p12` | |`keycloak_quarkus_trust_store_password`| Password for the trust store | `""` | - +|`keycloak_quarkus_proxy_headers`| Parse reverse proxy headers (`forwarded` or `xforwardedPassword`) | `""` | * Hostname configuration diff --git a/roles/keycloak_quarkus/templates/keycloak.service.j2 b/roles/keycloak_quarkus/templates/keycloak.service.j2 index 3cdfacf..77395c6 100644 --- a/roles/keycloak_quarkus/templates/keycloak.service.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.service.j2 @@ -8,10 +8,10 @@ Type=simple EnvironmentFile=-{{ keycloak_quarkus_sysconf_file }} PIDFile={{ keycloak_quarkus_service_pidfile }} {% if keycloak_quarkus_start_dev %} -ExecStart={{ keycloak.home }}/bin/kc.sh start-dev -{% else %} -ExecStart={{ keycloak.home }}/bin/kc.sh start --optimized -{% endif %} +ExecStart={{ keycloak.home }}/bin/kc.sh start-dev{% if keycloak_quarkus_proxy_headers is defined %} --proxy-headers {{ keycloak_quarkus_proxy_headers }}{% endif -%}{{ '\n' }} +{% else -%} +ExecStart={{ keycloak.home }}/bin/kc.sh start --optimized{% if keycloak_quarkus_proxy_headers is defined %} --proxy-headers {{ keycloak_quarkus_proxy_headers }}{% endif -%}{{ '\n' }} +{%- endif %} User={{ keycloak.service_user }} Group={{ keycloak.service_group }} {% if keycloak_quarkus_service_restart_always %} From 4aa862101c2f3b566686b8c77ea9d95407acb80e Mon Sep 17 00:00:00 2001 From: Christian Iuga Date: Mon, 15 Apr 2024 15:48:02 +0200 Subject: [PATCH 357/554] Add new variable keycloak_quarkus_proxy_headers into meta/argument_specs.yml Fix comment https://github.com/ansible-middleware/keycloak/pull/187#discussion_r1565772058 --- roles/keycloak_quarkus/meta/argument_specs.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index f4b87d7..36f5adc 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -285,6 +285,10 @@ argument_specs: default: 'edge' type: "str" description: "The proxy address forwarding mode if the server is behind a reverse proxy. Set to 'none' if not using a proxy" + keycloak_quarkus_proxy_headers: + default: "" + type: "str" + description: "Parse reverse proxy headers (`forwarded` or `xforwardedPassword`), overrides the deprecated keycloak_quarkus_proxy_mode argument" keycloak_quarkus_start_dev: default: false type: "bool" From 27717d7b4eef4696dba6db8d3499c02782270854 Mon Sep 17 00:00:00 2001 From: Christian Iuga Date: Mon, 15 Apr 2024 15:50:55 +0200 Subject: [PATCH 358/554] Avoid cmd-line arguments Fix https://github.com/ansible-middleware/keycloak/pull/187#discussion_r1565779164 --- roles/keycloak_quarkus/templates/keycloak.service.j2 | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/roles/keycloak_quarkus/templates/keycloak.service.j2 b/roles/keycloak_quarkus/templates/keycloak.service.j2 index 77395c6..46c7f34 100644 --- a/roles/keycloak_quarkus/templates/keycloak.service.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.service.j2 @@ -7,11 +7,15 @@ After=network.target Type=simple EnvironmentFile=-{{ keycloak_quarkus_sysconf_file }} PIDFile={{ keycloak_quarkus_service_pidfile }} -{% if keycloak_quarkus_start_dev %} -ExecStart={{ keycloak.home }}/bin/kc.sh start-dev{% if keycloak_quarkus_proxy_headers is defined %} --proxy-headers {{ keycloak_quarkus_proxy_headers }}{% endif -%}{{ '\n' }} +{% if keycloak_quarkus_start_dev and keycloak_quarkus_proxy_headers is defined %} +ExecStart={{ keycloak.home }}/bin/kc.sh start-dev --proxy-headers {{ keycloak_quarkus_proxy_headers }} +{% elif keycloak_quarkus_start_dev and keycloak_quarkus_proxy_headers is not defined %} +ExecStart={{ keycloak.home }}/bin/kc.sh start-dev +{% elif not keycloak_quarkus_start_dev and keycloak_quarkus_proxy_headers is defined %} +ExecStart={{ keycloak.home }}/bin/kc.sh start --optimized --proxy-headers {{ keycloak_quarkus_proxy_headers }} {% else -%} -ExecStart={{ keycloak.home }}/bin/kc.sh start --optimized{% if keycloak_quarkus_proxy_headers is defined %} --proxy-headers {{ keycloak_quarkus_proxy_headers }}{% endif -%}{{ '\n' }} -{%- endif %} +ExecStart={{ keycloak.home }}/bin/kc.sh start --optimized +{% endif %} User={{ keycloak.service_user }} Group={{ keycloak.service_group }} {% if keycloak_quarkus_service_restart_always %} From 3fbae4882e0d2c058cd42ee2cfd6b0b41f7a29f8 Mon Sep 17 00:00:00 2001 From: Christian Iuga Date: Tue, 16 Apr 2024 13:39:33 +0200 Subject: [PATCH 359/554] move keycloak_quarkus_proxy_headers into keycloak.conf --- roles/keycloak_quarkus/templates/keycloak.conf.j2 | 7 ++++++- roles/keycloak_quarkus/templates/keycloak.service.j2 | 6 +----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index b23a250..20d3f7f 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -54,9 +54,14 @@ cache-config-file=cache-ispn.xml {% endif %} {% if keycloak_quarkus_proxy_mode is defined and keycloak_quarkus_proxy_mode != "none" %} -# Proxy +# Deprecated Proxy configuration proxy={{ keycloak_quarkus_proxy_mode }} {% endif %} +{% if keycloak_quarkus_proxy_headers is defined and keycloak_quarkus_proxy_headers != "none" %} +# Proxy +proxy-headers={{ keycloak_quarkus_proxy_headers }} +{% endif %} + spi-sticky-session-encoder-infinispan-should-attach-route={{ keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route | d(true) | lower }} # Transaction diff --git a/roles/keycloak_quarkus/templates/keycloak.service.j2 b/roles/keycloak_quarkus/templates/keycloak.service.j2 index 46c7f34..30f4273 100644 --- a/roles/keycloak_quarkus/templates/keycloak.service.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.service.j2 @@ -7,12 +7,8 @@ After=network.target Type=simple EnvironmentFile=-{{ keycloak_quarkus_sysconf_file }} PIDFile={{ keycloak_quarkus_service_pidfile }} -{% if keycloak_quarkus_start_dev and keycloak_quarkus_proxy_headers is defined %} -ExecStart={{ keycloak.home }}/bin/kc.sh start-dev --proxy-headers {{ keycloak_quarkus_proxy_headers }} -{% elif keycloak_quarkus_start_dev and keycloak_quarkus_proxy_headers is not defined %} +{% if keycloak_quarkus_start_dev %} ExecStart={{ keycloak.home }}/bin/kc.sh start-dev -{% elif not keycloak_quarkus_start_dev and keycloak_quarkus_proxy_headers is defined %} -ExecStart={{ keycloak.home }}/bin/kc.sh start --optimized --proxy-headers {{ keycloak_quarkus_proxy_headers }} {% else -%} ExecStart={{ keycloak.home }}/bin/kc.sh start --optimized {% endif %} From ea57f8b68942a0c4f07b371bdc9f893242a55667 Mon Sep 17 00:00:00 2001 From: Christian Iuga Date: Tue, 16 Apr 2024 13:41:09 +0200 Subject: [PATCH 360/554] remove unwanted extra code --- roles/keycloak_quarkus/templates/keycloak.service.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/templates/keycloak.service.j2 b/roles/keycloak_quarkus/templates/keycloak.service.j2 index 30f4273..3cdfacf 100644 --- a/roles/keycloak_quarkus/templates/keycloak.service.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.service.j2 @@ -9,7 +9,7 @@ EnvironmentFile=-{{ keycloak_quarkus_sysconf_file }} PIDFile={{ keycloak_quarkus_service_pidfile }} {% if keycloak_quarkus_start_dev %} ExecStart={{ keycloak.home }}/bin/kc.sh start-dev -{% else -%} +{% else %} ExecStart={{ keycloak.home }}/bin/kc.sh start --optimized {% endif %} User={{ keycloak.service_user }} From 1229a0b0231fe837a77ed2b03866da7c7a0c4c57 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 17 Apr 2024 10:46:23 +0200 Subject: [PATCH 361/554] Unrelax configuration file permissions --- roles/keycloak_quarkus/tasks/install.yml | 6 +++--- roles/keycloak_quarkus/tasks/jdbc_driver.yml | 2 +- roles/keycloak_quarkus/tasks/main.yml | 8 ++++---- roles/keycloak_quarkus/tasks/systemd.yml | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index 0162266..3cf4b55 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -31,7 +31,7 @@ state: directory owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" - mode: 0750 + mode: '0750' ## check remote archive - name: Set download archive path @@ -56,7 +56,7 @@ ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user url: "{{ keycloak_quarkus_download_url }}" dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" - mode: 0640 + mode: '0640' delegate_to: localhost become: false run_once: true @@ -118,7 +118,7 @@ dest: "{{ archive }}" owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" - mode: 0640 + mode: '0640' register: new_version_downloaded when: - not archive_path.stat.exists diff --git a/roles/keycloak_quarkus/tasks/jdbc_driver.yml b/roles/keycloak_quarkus/tasks/jdbc_driver.yml index 0d03030..c95ef2b 100644 --- a/roles/keycloak_quarkus/tasks/jdbc_driver.yml +++ b/roles/keycloak_quarkus/tasks/jdbc_driver.yml @@ -6,7 +6,7 @@ dest: "{{ keycloak.home }}/providers" owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" - mode: 0640 + mode: '0640' become: true notify: - restart keycloak diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index decb63b..ad97709 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -27,7 +27,7 @@ dest: "{{ keycloak.home }}/conf/keycloak.conf" owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" - mode: 0644 + mode: '0640' become: true notify: - rebuild keycloak config @@ -39,7 +39,7 @@ dest: "{{ keycloak.home }}/conf/quarkus.properties" owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" - mode: 0644 + mode: '0640' become: true notify: - restart keycloak @@ -64,7 +64,7 @@ dest: "{{ keycloak.home }}/conf/cache-ispn.xml" owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" - mode: 0644 + mode: '0640' become: true notify: - rebuild keycloak config @@ -76,7 +76,7 @@ path: "{{ keycloak.log.file | dirname }}" owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" - mode: 0775 + mode: '0775' become: true - name: Flush pending handlers diff --git a/roles/keycloak_quarkus/tasks/systemd.yml b/roles/keycloak_quarkus/tasks/systemd.yml index 58dbc7e..fcc1a71 100644 --- a/roles/keycloak_quarkus/tasks/systemd.yml +++ b/roles/keycloak_quarkus/tasks/systemd.yml @@ -6,7 +6,7 @@ dest: "{{ keycloak_quarkus_sysconf_file }}" owner: root group: root - mode: 0644 + mode: '0640' vars: keycloak_pkg_java_home: "{{ keycloak_quarkus_pkg_java_home }}" notify: @@ -18,7 +18,7 @@ dest: /etc/systemd/system/keycloak.service owner: root group: root - mode: 0644 + mode: '0644' become: true register: systemdunit notify: From ad6021c29a104447dc4d5429dca5b75cee7900bd Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Wed, 17 Apr 2024 08:58:43 +0000 Subject: [PATCH 362/554] Update changelog for release 2.1.1 Signed-off-by: ansible-middleware-core --- CHANGELOG.rst | 18 ++++++++++++++++++ changelogs/changelog.yaml | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 15c2fbf..ce72edf 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,24 @@ middleware\_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v2.1.1 +====== + +Minor Changes +------------- + +- Add reverse ``proxy_headers`` config, supersedes ``proxy_mode`` `#187 `_ +- Debian/Ubuntu compatibility `#178 `_ +- Use ``keycloak_realm`` as default for sub-entities `#180 `_ + +Bugfixes +-------- + +- Fix permissions on controller-side downloaded artifacts `#184 `_ +- JVM args moved to ``JAVA_OPTS`` envvar (instead of JAVA_OPTS_APPEND) `#186 `_ +- Unrelax configuration file permissions `#191 `_ +- Utilize comment filter for ``ansible_managed`` annotations `#176 `_ + v2.1.0 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index dd44253..a8ed730 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -419,3 +419,38 @@ releases: - 167.yaml - 171.yaml release_date: '2024-02-28' + 2.1.1: + changes: + bugfixes: + - 'Fix permissions on controller-side downloaded artifacts `#184 `_ + + ' + - 'JVM args moved to ``JAVA_OPTS`` envvar (instead of JAVA_OPTS_APPEND) `#186 + `_ + + ' + - 'Unrelax configuration file permissions `#191 `_ + + ' + - 'Utilize comment filter for ``ansible_managed`` annotations `#176 `_ + + ' + minor_changes: + - 'Add reverse ``proxy_headers`` config, supersedes ``proxy_mode`` `#187 `_ + + ' + - 'Debian/Ubuntu compatibility `#178 `_ + + ' + - 'Use ``keycloak_realm`` as default for sub-entities `#180 `_ + + ' + fragments: + - 176.yaml + - 178.yaml + - 180.yaml + - 184.yaml + - 186.yaml + - 187.yaml + - 191.yaml + release_date: '2024-04-17' From 2cf3e2470dab694e03926d8224d2d39d8a9b7654 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Wed, 17 Apr 2024 08:58:56 +0000 Subject: [PATCH 363/554] Bump version to 2.1.2 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index dd55345..a1e9cdb 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "2.1.1" +version: "2.1.2" readme: README.md authors: - Romain Pelisse From 5464a01a627b6f36e6b18b7e8dae7af630c1fec8 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 17 Apr 2024 11:08:04 +0200 Subject: [PATCH 364/554] ci: update doc links, test triggers --- .github/workflows/release.yml | 4 +++- docs/_gh_include/header.inc | 17 +++++++++-------- docs/index.rst | 17 +++++++++-------- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7ea4aab..9dbf255 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,14 +8,16 @@ jobs: uses: ansible-middleware/github-actions/.github/workflows/release.yml@main with: collection_fqcn: 'middleware_automation.keycloak' + downstream_name: 'rhbk' secrets: galaxy_token: ${{ secrets.ANSIBLE_GALAXY_API_KEY }} + jira_webhook: ${{ secrets.JIRA_WEBHOOK_CREATE_VERSION }} dispatch: needs: release strategy: matrix: - repo: ['ansible-middleware/cross-dc-rhsso-demo', 'ansible-middleware/flange-demo', 'ansible-middleware/ansible-middleware-ee'] + repo: ['ansible-middleware/ansible-middleware-ee'] runs-on: ubuntu-latest steps: - name: Repository Dispatch diff --git a/docs/_gh_include/header.inc b/docs/_gh_include/header.inc index 7c5103b..d97c7f1 100644 --- a/docs/_gh_include/header.inc +++ b/docs/_gh_include/header.inc @@ -24,14 +24,15 @@