mirror of
https://github.com/ansible-middleware/keycloak.git
synced 2026-03-27 22:03:03 +00:00
Compare commits
272 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6330f08b28 | ||
|
|
5c8d7d9554 | ||
|
|
2513ac2c43 | ||
|
|
6e6bf2ff71 | ||
|
|
11621516e3 | ||
|
|
7c05ee5239 | ||
|
|
5251826477 | ||
|
|
0783000849 | ||
|
|
ca2dbe78c2 | ||
|
|
52d9286ea3 | ||
|
|
345c50fb85 | ||
|
|
db0aafd465 | ||
|
|
b950cdb8b4 | ||
|
|
5b01123846 | ||
|
|
84d6e7baca | ||
|
|
ea735ea79e | ||
|
|
9db1cbd564 | ||
|
|
7933592725 | ||
|
|
3170af8b2b | ||
|
|
f400a5bbf8 | ||
|
|
5385fbb8e9 | ||
|
|
7fea211639 | ||
|
|
8738240a24 | ||
|
|
f195d164d1 | ||
|
|
7c4d420fea | ||
|
|
d45071bf58 | ||
|
|
10876ba615 | ||
|
|
f3815403c8 | ||
|
|
18d686b43a | ||
|
|
26a9249d07 | ||
|
|
fae3079751 | ||
|
|
a82e654cc4 | ||
|
|
cebec9c717 | ||
|
|
ad59cd8cb3 | ||
|
|
926353f395 | ||
|
|
fed86ac0c3 | ||
|
|
5f1f8b5762 | ||
|
|
bab3069712 | ||
|
|
fc6e00974d | ||
|
|
83525dbed0 | ||
|
|
7ec695ee15 | ||
|
|
14e7b402b7 | ||
|
|
832432b86c | ||
|
|
8f697f6a53 | ||
|
|
1dd579a6d1 | ||
|
|
3340428194 | ||
|
|
18e60daa93 | ||
|
|
874215a592 | ||
|
|
97bea7ba39 | ||
|
|
e99a0db174 | ||
|
|
3b03c54fed | ||
|
|
ced4ce7828 | ||
|
|
6986190159 | ||
|
|
db480d0bc9 | ||
|
|
bc4cb5c52a | ||
|
|
8f042d3e29 | ||
|
|
24eaacc1ac | ||
|
|
623db426e0 | ||
|
|
b77c166945 | ||
|
|
b7eef6a720 | ||
|
|
203e6c06ac | ||
|
|
aaae1d1129 | ||
|
|
cca20a067d | ||
|
|
2be35f9a67 | ||
|
|
19f1750a33 | ||
|
|
c3d8bbc94e | ||
|
|
c4b4be3c3b | ||
|
|
98e1633c43 | ||
|
|
fd375a141d | ||
|
|
0cf7b3ac49 | ||
|
|
370d424b24 | ||
|
|
01fd2cc4fd | ||
|
|
7471e07921 | ||
|
|
e8e0f6718b | ||
|
|
e4811221be | ||
|
|
6cb4aac556 | ||
|
|
aad373a8e9 | ||
|
|
fd0a4e4492 | ||
|
|
706677910b | ||
|
|
a3bffe9401 | ||
|
|
f566917bc2 | ||
|
|
44ad3b8e6d | ||
|
|
1a450ea1d7 | ||
|
|
b0a01a8e46 | ||
|
|
020bc86955 | ||
|
|
d72d46c945 | ||
|
|
c7d2bdcee3 | ||
|
|
43d978370d | ||
|
|
3d37def38d | ||
|
|
8d16e241c1 | ||
|
|
6ac0c18842 | ||
|
|
6334daf244 | ||
|
|
87ad97d57f | ||
|
|
242b1cea0a | ||
|
|
c0b72b6890 | ||
|
|
1cfa229a5f | ||
|
|
f013a99832 | ||
|
|
6bfe046f5e | ||
|
|
526f64e5eb | ||
|
|
a2c17f545e | ||
|
|
40c29d07b8 | ||
|
|
91a18bf571 | ||
|
|
ecb6cbb9bf | ||
|
|
05dccdaf3b | ||
|
|
398c3c478e | ||
|
|
ed24ca637a | ||
|
|
23ce09d595 | ||
|
|
59b69a6592 | ||
|
|
bf89b1895a | ||
|
|
2ce7104077 | ||
|
|
d438648e39 | ||
|
|
49566455d6 | ||
|
|
1f2a88982d | ||
|
|
a554736246 | ||
|
|
7bbe5ae386 | ||
|
|
7c9cc7ce36 | ||
|
|
ce18c91b67 | ||
|
|
d15324c1c8 | ||
|
|
527d3eb264 | ||
|
|
ccf773057b | ||
|
|
e530ccdc31 | ||
|
|
6852871aeb | ||
|
|
68bcff36f6 | ||
|
|
a7c9304c68 | ||
|
|
6e9a17bbf5 | ||
|
|
0052025917 | ||
|
|
7050dafcbd | ||
|
|
65e4b3b813 | ||
|
|
00ae087732 | ||
|
|
e15ebd3233 | ||
|
|
d27d15efa9 | ||
|
|
41eed509ea | ||
|
|
0d2624cfff | ||
|
|
f980d4d1e1 | ||
|
|
2959cb3cf0 | ||
|
|
821c256f04 | ||
|
|
7abdd83ea4 | ||
|
|
007094ab5b | ||
|
|
5cdaa7aabb | ||
|
|
808b944f19 | ||
|
|
ae95d69435 | ||
|
|
73d7a46307 | ||
|
|
9196b234b6 | ||
|
|
46d5af90ba | ||
|
|
8ed82d937c | ||
|
|
842cb7bf23 | ||
|
|
cd1c2ae3e7 | ||
|
|
2a219222bc | ||
|
|
ab3247fc3b | ||
|
|
320f167bea | ||
|
|
5563317718 | ||
|
|
e209507a3f | ||
|
|
b9560458d8 | ||
|
|
d7829f77df | ||
|
|
e17fda2da9 | ||
|
|
34cab23abe | ||
|
|
7c8db06378 | ||
|
|
699ab1a5c4 | ||
|
|
007464d6b3 | ||
|
|
2054082b40 | ||
|
|
9157f83f96 | ||
|
|
6e4b224fe1 | ||
|
|
2594fd9186 | ||
|
|
853d4ab96b | ||
|
|
2df5fd22cf | ||
|
|
422986a8fd | ||
|
|
ad4d5dae68 | ||
|
|
e624870e38 | ||
|
|
63dc369148 | ||
|
|
f4fe9df97c | ||
|
|
b3b016bf3b | ||
|
|
3d0cfc9e42 | ||
|
|
89fa82eddb | ||
|
|
c0d4c6211e | ||
|
|
bdc1ad8b51 | ||
|
|
db111aaf3a | ||
|
|
ab1c06a2e8 | ||
|
|
c8a2283cc6 | ||
|
|
bea5062287 | ||
|
|
65da436d74 | ||
|
|
be582171ce | ||
|
|
a7fbce2990 | ||
|
|
dfc1912a99 | ||
|
|
ec47a1c5a8 | ||
|
|
52e38f7398 | ||
|
|
69a8860551 | ||
|
|
9f8b1c6d76 | ||
|
|
5e89139870 | ||
|
|
38b5a02e95 | ||
|
|
9b2ea35184 | ||
|
|
ded44b084d | ||
|
|
1b1127ed91 | ||
|
|
9252433cc8 | ||
|
|
adb0a4da45 | ||
|
|
41caa49cfc | ||
|
|
d47e045f5e | ||
|
|
4baa61e0cf | ||
|
|
065fb53eb2 | ||
|
|
713437343d | ||
|
|
46f445560b | ||
|
|
76cbb4c676 | ||
|
|
469036e9e7 | ||
|
|
8454f5c341 | ||
|
|
d5a63f55f9 | ||
|
|
09a34567a7 | ||
|
|
bc63cbf649 | ||
|
|
281767f505 | ||
|
|
8bede6791e | ||
|
|
0ddbc66448 | ||
|
|
31420fc24c | ||
|
|
2cc835219c | ||
|
|
9e3cd22484 | ||
|
|
9278d3440e | ||
|
|
3b45c133b8 | ||
|
|
95c346d4b3 | ||
|
|
f4674a8762 | ||
|
|
3714145526 | ||
|
|
4167edda63 | ||
|
|
7d57857a1f | ||
|
|
8341416ee0 | ||
|
|
fbc0d7ab99 | ||
|
|
78d5499abf | ||
|
|
9987f6a044 | ||
|
|
e3bb10d901 | ||
|
|
7028b068b6 | ||
|
|
0751b97b87 | ||
|
|
548db6fc4b | ||
|
|
dc33cbc358 | ||
|
|
9bb9816a01 | ||
|
|
33c8f74122 | ||
|
|
cf92da9e94 | ||
|
|
419c862341 | ||
|
|
c7b6bc1d61 | ||
|
|
a62f26648f | ||
|
|
29aaafb9e4 | ||
|
|
9d57057272 | ||
|
|
fddfa9a493 | ||
|
|
5cbe905dda | ||
|
|
4e6ea2f1ca | ||
|
|
28ff78d809 | ||
|
|
9365d38162 | ||
|
|
d3f9b0ca86 | ||
|
|
bada6f4073 | ||
|
|
b91c9e17fc | ||
|
|
b974bf1967 | ||
|
|
9ee6788f98 | ||
|
|
c166c643fc | ||
|
|
abd922417c | ||
|
|
5a45d1f4f8 | ||
|
|
6091477294 | ||
|
|
63f31fe258 | ||
|
|
fc780599b0 | ||
|
|
494a1c518b | ||
|
|
f736ad5632 | ||
|
|
b0a11013fa | ||
|
|
10ff1763c1 | ||
|
|
85b0a2549a | ||
|
|
d854791183 | ||
|
|
a67081a68d | ||
|
|
8173be4b58 | ||
|
|
6270762a3a | ||
|
|
5828c0a7bb | ||
|
|
e773e12e24 | ||
|
|
33e80a0cd4 | ||
|
|
bf26c727a8 | ||
|
|
d5bf0a195a | ||
|
|
c5b38e8bac | ||
|
|
266f2bc00b | ||
|
|
cfdc043770 | ||
|
|
707d8cfb11 | ||
|
|
f5cd6d8061 | ||
|
|
b88c43933c |
@@ -5,6 +5,8 @@ exclude_paths:
|
||||
- molecule/
|
||||
- .ansible-lint
|
||||
- .yamllint
|
||||
- meta/
|
||||
- playbooks/roles/
|
||||
|
||||
rulesdir:
|
||||
- ../../ansible-lint-custom-rules/rules/
|
||||
@@ -16,12 +18,24 @@ 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
|
||||
- jinja[spacing]
|
||||
- jinja[invalid]
|
||||
- meta-no-tags
|
||||
- name[casing]
|
||||
- fqcn[action]
|
||||
- schema[meta]
|
||||
- var-naming[no-role-prefix]
|
||||
- key-order[task]
|
||||
- blocked_modules
|
||||
|
||||
skip_list:
|
||||
- vars_should_not_be_used
|
||||
- file_is_small_enough
|
||||
- name[template]
|
||||
|
||||
use_default_rules: true
|
||||
parseable: true
|
||||
|
||||
51
.github/workflows/ci.yml
vendored
51
.github/workflows/ci.yml
vendored
@@ -1,51 +1,18 @@
|
||||
---
|
||||
name: CI
|
||||
"on":
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: '0 6 * * *'
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python_version: ["3.9"]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
path: ansible_collections/middleware_automation/keycloak
|
||||
|
||||
- name: Set up Python ${{ matrix.python_version }}
|
||||
uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: ${{ matrix.python_version }}
|
||||
|
||||
- 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 -r ansible_collections/middleware_automation/keycloak/requirements.txt
|
||||
|
||||
- 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 }}
|
||||
working-directory: ./ansible_collections/middleware_automation/keycloak
|
||||
|
||||
- name: Run molecule test
|
||||
run: molecule test --all
|
||||
working-directory: ./ansible_collections/middleware_automation/keycloak
|
||||
env:
|
||||
PY_COLORS: '1'
|
||||
ANSIBLE_FORCE_COLOR: '1'
|
||||
uses: ansible-middleware/github-actions/.github/workflows/ci.yml@main
|
||||
secrets: inherit
|
||||
with:
|
||||
fqcn: 'middleware_automation/keycloak'
|
||||
molecule_tests: >-
|
||||
[ "default", "quarkus", "overridexml" ]
|
||||
|
||||
70
.github/workflows/docs.yml
vendored
70
.github/workflows/docs.yml
vendored
@@ -6,70 +6,12 @@ on:
|
||||
- main
|
||||
tags:
|
||||
- "[0-9]+.[0-9]+.[0-9]+"
|
||||
|
||||
env:
|
||||
COLORTERM: 'yes'
|
||||
TERM: 'xterm-256color'
|
||||
PYTEST_ADDOPTS: '--color=yes'
|
||||
workflow_dispatch:
|
||||
|
||||
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@v2
|
||||
with:
|
||||
path: ansible_collections/middleware_automation/keycloak
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.9
|
||||
|
||||
- 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
|
||||
|
||||
- name: Create default collection path
|
||||
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 " * :doc:\`$(basename $(dirname $role_readme))\`" >> ./docs/roles/index.rst; done
|
||||
working-directory: ansible_collections/middleware_automation/keycloak
|
||||
|
||||
- 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 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 '<li class="toctree-l1"><a class="reference internal" href="@@/">@@</a></li>' >> 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/
|
||||
uses: ansible-middleware/github-actions/.github/workflows/docs.yml@main
|
||||
secrets: inherit
|
||||
with:
|
||||
fqcn: 'middleware_automation/keycloak'
|
||||
collection_fqcn: 'middleware_automation.keycloak'
|
||||
|
||||
43
.github/workflows/release.yml
vendored
43
.github/workflows/release.yml
vendored
@@ -1,47 +1,20 @@
|
||||
---
|
||||
name: Release collection
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "[0-9]+.[0-9]+.[0-9]+"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- name: Get Tag Version
|
||||
id: get_version
|
||||
run: echo ::set-output name=TAG_VERSION::${GITHUB_REF#refs/tags/}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install ansible-core
|
||||
- name: Build collection
|
||||
run: |
|
||||
ansible-galaxy collection build .
|
||||
- name: Publish Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
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
|
||||
uses: ansible-middleware/github-actions/.github/workflows/release.yml@main
|
||||
secrets: inherit
|
||||
with:
|
||||
collection_fqcn: 'middleware_automation.keycloak'
|
||||
|
||||
dispatch:
|
||||
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
|
||||
@@ -49,5 +22,5 @@ jobs:
|
||||
with:
|
||||
token: ${{ secrets.TRIGGERING_PAT }}
|
||||
repository: ${{ matrix.repo }}
|
||||
event-type: "Dependency released - Keycloak"
|
||||
event-type: "Dependency released - Keycloak v${{ needs.release.outputs.tag_version }}"
|
||||
client-payload: '{ "github": ${{toJson(github)}} }'
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -2,9 +2,13 @@
|
||||
*.zip
|
||||
.tmp
|
||||
.cache
|
||||
.vscode/
|
||||
__pycache__/
|
||||
docs/plugins/
|
||||
docs/roles/
|
||||
docs/_build/
|
||||
.pytest_cache/
|
||||
.mypy_cache/
|
||||
*.retry
|
||||
changelogs/.plugin-cache.yaml
|
||||
*.pem
|
||||
|
||||
224
CHANGELOG.rst
Normal file
224
CHANGELOG.rst
Normal file
@@ -0,0 +1,224 @@
|
||||
============================================
|
||||
middleware_automation.keycloak Release Notes
|
||||
============================================
|
||||
|
||||
.. contents:: Topics
|
||||
|
||||
This changelog describes changes after version 0.2.6.
|
||||
|
||||
v1.2.8
|
||||
======
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- keycloak_quarkus: set openjdk 17 as default `#103 <https://github.com/ansible-middleware/keycloak/pull/103>`_
|
||||
- keycloak_quarkus: update to version 22.0.1 `#107 <https://github.com/ansible-middleware/keycloak/pull/107>`_
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Fix incorrect checks for ``keycloak_jgroups_subnet`` `#98 <https://github.com/ansible-middleware/keycloak/pull/98>`_
|
||||
- Undefine ``keycloak_db_valid_conn_sql`` default `#91 <https://github.com/ansible-middleware/keycloak/pull/91>`_
|
||||
- Update bindep.txt package python3-devel to support RHEL9 `#105 <https://github.com/ansible-middleware/keycloak/pull/105>`_
|
||||
|
||||
v1.2.7
|
||||
======
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Allow to override jgroups subnet `#93 <https://github.com/ansible-middleware/keycloak/pull/93>`_
|
||||
- keycloak-quarkus: update keycloakx to v21.1.1 `#92 <https://github.com/ansible-middleware/keycloak/pull/92>`_
|
||||
|
||||
v1.2.6
|
||||
======
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Add profile features enabling/disabling `#87 <https://github.com/ansible-middleware/keycloak/pull/87>`_
|
||||
- Improve service restart behavior configuration `#88 <https://github.com/ansible-middleware/keycloak/pull/88>`_
|
||||
- Update default xa_datasource_class value for mariadb jdbc configuration `#89 <https://github.com/ansible-middleware/keycloak/pull/89>`_
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Handle WFLYCTL0117 when background validation millis is 0 `#90 <https://github.com/ansible-middleware/keycloak/pull/90>`_
|
||||
|
||||
v1.2.5
|
||||
======
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Add configuration for database connection pool validation `#85 <https://github.com/ansible-middleware/keycloak/pull/85>`_
|
||||
- Allow to configure administration endpoint URL `#86 <https://github.com/ansible-middleware/keycloak/pull/86>`_
|
||||
- Allow to force backend URLs to frontend URLs `#84 <https://github.com/ansible-middleware/keycloak/pull/84>`_
|
||||
- Introduce systemd unit restart behavior `#81 <https://github.com/ansible-middleware/keycloak/pull/81>`_
|
||||
|
||||
v1.2.4
|
||||
======
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Add ``sqlserver`` to keycloak role jdbc configurations `#78 <https://github.com/ansible-middleware/keycloak/pull/78>`_
|
||||
- Add configurability for XA transactions `#73 <https://github.com/ansible-middleware/keycloak/pull/73>`_
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Fix deprecation warning for ``ipaddr`` `#77 <https://github.com/ansible-middleware/keycloak/pull/77>`_
|
||||
- Fix undefined facts when offline patching sso `#71 <https://github.com/ansible-middleware/keycloak/pull/71>`_
|
||||
|
||||
v1.2.1
|
||||
======
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Allow to setup keycloak HA cluster without remote cache store `#68 <https://github.com/ansible-middleware/keycloak/pull/68>`_
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Pass attributes to realm clients `#69 <https://github.com/ansible-middleware/keycloak/pull/69>`_
|
||||
|
||||
v1.2.0
|
||||
======
|
||||
|
||||
Major Changes
|
||||
-------------
|
||||
|
||||
- Provide config for multiple modcluster proxies `#60 <https://github.com/ansible-middleware/keycloak/pull/60>`_
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Allow to configure TCPPING for cluster discovery `#62 <https://github.com/ansible-middleware/keycloak/pull/62>`_
|
||||
- Drop community.general from dependencies `#61 <https://github.com/ansible-middleware/keycloak/pull/61>`_
|
||||
- Switch middleware_automation.redhat_csp_download for middleware_automation.common `#63 <https://github.com/ansible-middleware/keycloak/pull/63>`_
|
||||
- Switch to middleware_automation.common for rh-sso patching `#64 <https://github.com/ansible-middleware/keycloak/pull/64>`_
|
||||
|
||||
v1.1.1
|
||||
======
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- keycloak-quarkus: fix ``cache-config-file`` path in keycloak.conf.j2 template `#53 <https://github.com/ansible-middleware/keycloak/pull/53>`_
|
||||
|
||||
v1.1.0
|
||||
======
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Update keycloak to 18.0.2 - sso to 7.6.1 `#46 <https://github.com/ansible-middleware/keycloak/pull/46>`_
|
||||
- Variable ``keycloak_no_log`` controls ansible ``no_log`` parameter (for debugging purposes) `#47 <https://github.com/ansible-middleware/keycloak/pull/47>`_
|
||||
- Variables to override service start retries and delay `#51 <https://github.com/ansible-middleware/keycloak/pull/51>`_
|
||||
- keycloak_quarkus: variable to enable development mode `#45 <https://github.com/ansible-middleware/keycloak/pull/45>`_
|
||||
|
||||
Breaking Changes / Porting Guide
|
||||
--------------------------------
|
||||
|
||||
- Rename variables from ``infinispan_`` prefix to ``keycloak_infinispan_`` `#42 <https://github.com/ansible-middleware/keycloak/pull/42>`_
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- keycloak_quarkus: fix /var/log/keycloak symlink to keycloak log directory `#44 <https://github.com/ansible-middleware/keycloak/pull/44>`_
|
||||
|
||||
v1.0.7
|
||||
======
|
||||
|
||||
Breaking Changes / Porting Guide
|
||||
--------------------------------
|
||||
|
||||
- keycloak_quarkus: use absolute path for certificate files `#39 <https://github.com/ansible-middleware/keycloak/pull/39>`_
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- keycloak_quarkus: use become for tasks that will otherwise fail `#38 <https://github.com/ansible-middleware/keycloak/pull/38>`_
|
||||
|
||||
v1.0.6
|
||||
======
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- keycloak_quarkus: add selected java to PATH in systemd unit `#34 <https://github.com/ansible-middleware/keycloak/pull/34>`_
|
||||
- keycloak_quarkus: set logfile path correctly under keycloak home `#35 <https://github.com/ansible-middleware/keycloak/pull/35>`_
|
||||
|
||||
v1.0.5
|
||||
======
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Update config options: keycloak and quarkus `#32 <https://github.com/ansible-middleware/keycloak/pull/32>`_
|
||||
|
||||
v1.0.4
|
||||
======
|
||||
|
||||
v1.0.3
|
||||
======
|
||||
|
||||
Major Changes
|
||||
-------------
|
||||
|
||||
- New role for installing keycloak >= 17.0.0 (quarkus) `#29 <https://github.com/ansible-middleware/keycloak/pull/29>`_
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Add ``keycloak_config_override_template`` parameter for passing a custom xml config template `#30 <https://github.com/ansible-middleware/keycloak/pull/30>`_
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Make sure systemd unit starts with selected java JVM `#31 <https://github.com/ansible-middleware/keycloak/pull/31>`_
|
||||
|
||||
v1.0.2
|
||||
======
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Make ``keycloak_admin_password`` a default with assert (was: role variable) `#26 <https://github.com/ansible-middleware/keycloak/pull/26>`_
|
||||
- Simplify dependency install logic and reduce play execution time `#19 <https://github.com/ansible-middleware/keycloak/pull/19>`_
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Set ``keycloak_frontend_url`` default according to other defaults `#25 <https://github.com/ansible-middleware/keycloak/pull/25>`_
|
||||
|
||||
v1.0.1
|
||||
======
|
||||
|
||||
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 <https://github.com/ansible-middleware/keycloak/pull/18>`_
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Clustered installs now perform database initialization on first node to avoid locking issues `#17 <https://github.com/ansible-middleware/keycloak/pull/17>`_
|
||||
|
||||
v1.0.0
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
This is the first stable release of the ``middleware_automation.keycloak`` collection.
|
||||
|
||||
@@ -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
|
||||
|
||||
70
README.md
70
README.md
@@ -1,8 +1,11 @@
|
||||
# Ansible Collection - middleware_automation.keycloak
|
||||
|
||||
<!--start build_status -->
|
||||
[](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.**
|
||||
|
||||
<!--end build_status -->
|
||||
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).
|
||||
|
||||
<!--start requires_ansible-->
|
||||
@@ -16,12 +19,15 @@ Plugins and modules within a collection may be tested with only specific Ansible
|
||||
|
||||
## Installation
|
||||
|
||||
<!--start galaxy_download -->
|
||||
### 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
|
||||
|
||||
<!--end galaxy_download -->
|
||||
|
||||
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
|
||||
@@ -43,6 +49,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
|
||||
@@ -50,66 +57,30 @@ 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 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](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)
|
||||
#### Install from controller node (offline)
|
||||
|
||||
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: '<customer_portal_username>'
|
||||
rhn_password: '<customer_portal_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
|
||||
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
|
||||
<!--start rhn_credentials -->
|
||||
<!--end rhn_credentials -->
|
||||
|
||||
|
||||
#### Install from alternate sources (like corporate Nexus, artifactory, proxy, etc)
|
||||
|
||||
For RHSSO:
|
||||
|
||||
```yaml
|
||||
keycloak_rhsso_enable: True
|
||||
keycloak_rhsso_download_url: "https://<internal-nexus.private.net>/<path>/<to>/rh-sso-x.y.z-server-dist.zip"
|
||||
```
|
||||
|
||||
For keycloak:
|
||||
|
||||
```yaml
|
||||
keycloak_rhsso_enable: False
|
||||
keycloak_download_url: "https://<internal-nexus.private.net>/<path>/<to>/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
|
||||
@@ -128,13 +99,15 @@ ansible-playbook -i <ansible_hosts> -e @rhn-creds.yml playbooks/keycloak.yml -e
|
||||
localhost ansible_connection=local
|
||||
```
|
||||
|
||||
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
|
||||
|
||||
|
||||
### 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,11 +127,12 @@ ansible-playbook -i <ansible_hosts> 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
|
||||
|
||||
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
|
||||
<!--start support -->
|
||||
<!--end support -->
|
||||
|
||||
|
||||
## License
|
||||
|
||||
|
||||
8
bindep.txt
Normal file
8
bindep.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
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]
|
||||
|
||||
288
changelogs/changelog.yaml
Normal file
288
changelogs/changelog.yaml
Normal file
@@ -0,0 +1,288 @@
|
||||
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:
|
||||
major_changes:
|
||||
- Apply latest cumulative patch of RH-SSO automatically when new parameter ``keycloak_rhsso_apply_patches``
|
||||
is ``true`` `#18 <https://github.com/ansible-middleware/keycloak/pull/18>`_
|
||||
minor_changes:
|
||||
- Clustered installs now perform database initialization on first node to avoid
|
||||
locking issues `#17 <https://github.com/ansible-middleware/keycloak/pull/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 <https://github.com/ansible-middleware/keycloak/pull/25>`_
|
||||
|
||||
'
|
||||
minor_changes:
|
||||
- 'Make ``keycloak_admin_password`` a default with assert (was: role variable)
|
||||
`#26 <https://github.com/ansible-middleware/keycloak/pull/26>`_
|
||||
|
||||
'
|
||||
- 'Simplify dependency install logic and reduce play execution time `#19 <https://github.com/ansible-middleware/keycloak/pull/19>`_
|
||||
|
||||
'
|
||||
fragments:
|
||||
- 19.yaml
|
||||
- 25.yaml
|
||||
- 26.yaml
|
||||
release_date: '2022-04-01'
|
||||
1.0.3:
|
||||
changes:
|
||||
bugfixes:
|
||||
- 'Make sure systemd unit starts with selected java JVM `#31 <https://github.com/ansible-middleware/keycloak/pull/31>`_
|
||||
|
||||
'
|
||||
major_changes:
|
||||
- 'New role for installing keycloak >= 17.0.0 (quarkus) `#29 <https://github.com/ansible-middleware/keycloak/pull/29>`_
|
||||
|
||||
'
|
||||
minor_changes:
|
||||
- 'Add ``keycloak_config_override_template`` parameter for passing a custom
|
||||
xml config template `#30 <https://github.com/ansible-middleware/keycloak/pull/30>`_
|
||||
|
||||
'
|
||||
fragments:
|
||||
- 29.yaml
|
||||
- 30.yaml
|
||||
- 31.yaml
|
||||
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 <https://github.com/ansible-middleware/keycloak/pull/32>`_
|
||||
|
||||
'
|
||||
fragments:
|
||||
- 32.yaml
|
||||
release_date: '2022-05-25'
|
||||
1.0.6:
|
||||
changes:
|
||||
bugfixes:
|
||||
- 'keycloak_quarkus: add selected java to PATH in systemd unit `#34 <https://github.com/ansible-middleware/keycloak/pull/34>`_
|
||||
|
||||
'
|
||||
- 'keycloak_quarkus: set logfile path correctly under keycloak home `#35 <https://github.com/ansible-middleware/keycloak/pull/35>`_
|
||||
|
||||
'
|
||||
fragments:
|
||||
- 34.yaml
|
||||
- 35.yaml
|
||||
release_date: '2022-06-01'
|
||||
1.0.7:
|
||||
changes:
|
||||
breaking_changes:
|
||||
- 'keycloak_quarkus: use absolute path for certificate files `#39 <https://github.com/ansible-middleware/keycloak/pull/39>`_
|
||||
|
||||
'
|
||||
bugfixes:
|
||||
- 'keycloak_quarkus: use become for tasks that will otherwise fail `#38 <https://github.com/ansible-middleware/keycloak/pull/38>`_
|
||||
|
||||
'
|
||||
fragments:
|
||||
- 38.yaml
|
||||
- 39.yaml
|
||||
release_date: '2022-07-06'
|
||||
1.1.0:
|
||||
changes:
|
||||
breaking_changes:
|
||||
- 'Rename variables from ``infinispan_`` prefix to ``keycloak_infinispan_``
|
||||
`#42 <https://github.com/ansible-middleware/keycloak/pull/42>`_
|
||||
|
||||
'
|
||||
bugfixes:
|
||||
- 'keycloak_quarkus: fix /var/log/keycloak symlink to keycloak log directory
|
||||
`#44 <https://github.com/ansible-middleware/keycloak/pull/44>`_
|
||||
|
||||
'
|
||||
minor_changes:
|
||||
- 'Update keycloak to 18.0.2 - sso to 7.6.1 `#46 <https://github.com/ansible-middleware/keycloak/pull/46>`_
|
||||
|
||||
'
|
||||
- 'Variable ``keycloak_no_log`` controls ansible ``no_log`` parameter (for debugging
|
||||
purposes) `#47 <https://github.com/ansible-middleware/keycloak/pull/47>`_
|
||||
|
||||
'
|
||||
- 'Variables to override service start retries and delay `#51 <https://github.com/ansible-middleware/keycloak/pull/51>`_
|
||||
|
||||
'
|
||||
- 'keycloak_quarkus: variable to enable development mode `#45 <https://github.com/ansible-middleware/keycloak/pull/45>`_
|
||||
|
||||
'
|
||||
fragments:
|
||||
- 42.yaml
|
||||
- 44.yaml
|
||||
- 45.yaml
|
||||
- 46.yaml
|
||||
- 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 <https://github.com/ansible-middleware/keycloak/pull/53>`_
|
||||
|
||||
'
|
||||
fragments:
|
||||
- 53.yaml
|
||||
release_date: '2023-03-07'
|
||||
1.2.0:
|
||||
changes:
|
||||
major_changes:
|
||||
- 'Provide config for multiple modcluster proxies `#60 <https://github.com/ansible-middleware/keycloak/pull/60>`_
|
||||
|
||||
'
|
||||
minor_changes:
|
||||
- 'Allow to configure TCPPING for cluster discovery `#62 <https://github.com/ansible-middleware/keycloak/pull/62>`_
|
||||
|
||||
'
|
||||
- 'Drop community.general from dependencies `#61 <https://github.com/ansible-middleware/keycloak/pull/61>`_
|
||||
|
||||
'
|
||||
- 'Switch middleware_automation.redhat_csp_download for middleware_automation.common
|
||||
`#63 <https://github.com/ansible-middleware/keycloak/pull/63>`_
|
||||
|
||||
'
|
||||
- 'Switch to middleware_automation.common for rh-sso patching `#64 <https://github.com/ansible-middleware/keycloak/pull/64>`_
|
||||
|
||||
'
|
||||
fragments:
|
||||
- 60.yaml
|
||||
- 61.yaml
|
||||
- 62.yaml
|
||||
- 63.yaml
|
||||
- 64.yaml
|
||||
release_date: '2023-03-16'
|
||||
1.2.1:
|
||||
changes:
|
||||
bugfixes:
|
||||
- 'Pass attributes to realm clients `#69 <https://github.com/ansible-middleware/keycloak/pull/69>`_
|
||||
|
||||
'
|
||||
minor_changes:
|
||||
- 'Allow to setup keycloak HA cluster without remote cache store `#68 <https://github.com/ansible-middleware/keycloak/pull/68>`_
|
||||
|
||||
'
|
||||
fragments:
|
||||
- 68.yaml
|
||||
- 69.yaml
|
||||
release_date: '2023-04-11'
|
||||
1.2.4:
|
||||
changes:
|
||||
bugfixes:
|
||||
- 'Fix deprecation warning for ``ipaddr`` `#77 <https://github.com/ansible-middleware/keycloak/pull/77>`_
|
||||
|
||||
'
|
||||
- 'Fix undefined facts when offline patching sso `#71 <https://github.com/ansible-middleware/keycloak/pull/71>`_
|
||||
|
||||
'
|
||||
minor_changes:
|
||||
- 'Add ``sqlserver`` to keycloak role jdbc configurations `#78 <https://github.com/ansible-middleware/keycloak/pull/78>`_
|
||||
|
||||
'
|
||||
- 'Add configurability for XA transactions `#73 <https://github.com/ansible-middleware/keycloak/pull/73>`_
|
||||
|
||||
'
|
||||
fragments:
|
||||
- 71.yaml
|
||||
- 73.yaml
|
||||
- 77.yaml
|
||||
- 78.yaml
|
||||
release_date: '2023-05-09'
|
||||
1.2.5:
|
||||
changes:
|
||||
minor_changes:
|
||||
- 'Add configuration for database connection pool validation `#85 <https://github.com/ansible-middleware/keycloak/pull/85>`_
|
||||
|
||||
'
|
||||
- 'Allow to configure administration endpoint URL `#86 <https://github.com/ansible-middleware/keycloak/pull/86>`_
|
||||
|
||||
'
|
||||
- 'Allow to force backend URLs to frontend URLs `#84 <https://github.com/ansible-middleware/keycloak/pull/84>`_
|
||||
|
||||
'
|
||||
- 'Introduce systemd unit restart behavior `#81 <https://github.com/ansible-middleware/keycloak/pull/81>`_
|
||||
|
||||
'
|
||||
fragments:
|
||||
- 81.yaml
|
||||
- 84.yaml
|
||||
- 85.yaml
|
||||
- 86.yaml
|
||||
release_date: '2023-05-26'
|
||||
1.2.6:
|
||||
changes:
|
||||
bugfixes:
|
||||
- 'Handle WFLYCTL0117 when background validation millis is 0 `#90 <https://github.com/ansible-middleware/keycloak/pull/90>`_
|
||||
|
||||
'
|
||||
minor_changes:
|
||||
- 'Add profile features enabling/disabling `#87 <https://github.com/ansible-middleware/keycloak/pull/87>`_
|
||||
|
||||
'
|
||||
- 'Improve service restart behavior configuration `#88 <https://github.com/ansible-middleware/keycloak/pull/88>`_
|
||||
|
||||
'
|
||||
- 'Update default xa_datasource_class value for mariadb jdbc configuration `#89
|
||||
<https://github.com/ansible-middleware/keycloak/pull/89>`_
|
||||
|
||||
'
|
||||
fragments:
|
||||
- 87.yaml
|
||||
- 88.yaml
|
||||
- 89.yaml
|
||||
- 90.yaml
|
||||
release_date: '2023-06-07'
|
||||
1.2.7:
|
||||
changes:
|
||||
minor_changes:
|
||||
- 'Allow to override jgroups subnet `#93 <https://github.com/ansible-middleware/keycloak/pull/93>`_
|
||||
|
||||
'
|
||||
- 'keycloak-quarkus: update keycloakx to v21.1.1 `#92 <https://github.com/ansible-middleware/keycloak/pull/92>`_
|
||||
|
||||
'
|
||||
fragments:
|
||||
- 92.yaml
|
||||
- 93.yaml
|
||||
release_date: '2023-06-19'
|
||||
1.2.8:
|
||||
changes:
|
||||
bugfixes:
|
||||
- 'Fix incorrect checks for ``keycloak_jgroups_subnet`` `#98 <https://github.com/ansible-middleware/keycloak/pull/98>`_
|
||||
|
||||
'
|
||||
- 'Undefine ``keycloak_db_valid_conn_sql`` default `#91 <https://github.com/ansible-middleware/keycloak/pull/91>`_
|
||||
|
||||
'
|
||||
- 'Update bindep.txt package python3-devel to support RHEL9 `#105 <https://github.com/ansible-middleware/keycloak/pull/105>`_
|
||||
|
||||
'
|
||||
minor_changes:
|
||||
- 'keycloak_quarkus: set openjdk 17 as default `#103 <https://github.com/ansible-middleware/keycloak/pull/103>`_
|
||||
|
||||
'
|
||||
- 'keycloak_quarkus: update to version 22.0.1 `#107 <https://github.com/ansible-middleware/keycloak/pull/107>`_
|
||||
|
||||
'
|
||||
fragments:
|
||||
- 103.yaml
|
||||
- 105.yaml
|
||||
- 107.yaml
|
||||
- 91.yaml
|
||||
- 98.yaml
|
||||
release_date: '2023-08-28'
|
||||
32
changelogs/config.yaml
Normal file
32
changelogs/config.yaml
Normal file
@@ -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
|
||||
2
changelogs/fragments/.gitignore
vendored
Normal file
2
changelogs/fragments/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
||||
1
docs/CHANGELOG.rst
Symbolic link
1
docs/CHANGELOG.rst
Symbolic link
@@ -0,0 +1 @@
|
||||
../CHANGELOG.rst
|
||||
@@ -7,7 +7,7 @@
|
||||
</div>
|
||||
<hr/>
|
||||
<div role="contentinfo">
|
||||
<p>© Copyright 2022, Red Hat, Inc..</p>
|
||||
<p>© Copyright 2022, Red Hat, Inc.</p>
|
||||
</div>
|
||||
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
|
||||
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
|
||||
|
||||
@@ -21,6 +21,19 @@
|
||||
<div class="wy-side-nav-search" >
|
||||
<a href="#" class="icon icon-home"> Keycloak Ansible Collection</a>
|
||||
</div>
|
||||
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
|
||||
<p class="caption" role="heading"><span class="caption-text">Middleware Automation</span></p>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="https://ansible-middleware.github.io/infinispan/">Infinispan / Red Hat Data Grid</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="https://ansible-middleware.github.io/keycloak/">Keycloak / Red Hat Single Sign-On</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="https://ansible-middleware.github.io/wildfly/">Wildfly / Red Hat JBoss EAP</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="https://ansible-middleware.github.io/jws/">Tomcat / Red Hat JWS</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="https://ansible-middleware.github.io/amq/">ActiveMQ / Red Hat AMQ Broker</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="https://ansible-middleware.github.io/amq_streams/">Kafka / Red Hat AMQ Streams</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="https://ansible-middleware.github.io/redhat-csp-download/">Red Hat CSP Download</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="https://ansible-middleware.github.io/ansible_collections_jcliff/">JCliff</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
|
||||
|
||||
@@ -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'
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@ Welcome to Keycloak Collection documentation
|
||||
:maxdepth: 2
|
||||
:caption: Developer documentation
|
||||
|
||||
developing
|
||||
testing
|
||||
developing
|
||||
releasing
|
||||
|
||||
.. toctree::
|
||||
@@ -25,8 +25,15 @@ Welcome to Keycloak Collection documentation
|
||||
|
||||
Changelog <CHANGELOG>
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Middleware collections
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`search`
|
||||
Infinispan / Red Hat Data Grid <https://ansible-middleware.github.io/infinispan/>
|
||||
Keycloak / Red Hat Single Sign-On <https://ansible-middleware.github.io/keycloak/>
|
||||
Wildfly / Red Hat JBoss EAP <https://ansible-middleware.github.io/wildfly/>
|
||||
Tomcat / Red Hat JWS <https://ansible-middleware.github.io/jws/>
|
||||
ActiveMQ / Red Hat AMQ Broker <https://ansible-middleware.github.io/amq/>
|
||||
Kafka / Red Hat AMQ Streams <https://ansible-middleware.github.io/amq_streams/>
|
||||
Red Hat CSP Download <https://ansible-middleware.github.io/redhat-csp-download/>
|
||||
JCliff <https://ansible-middleware.github.io/ansible_collections_jcliff/>
|
||||
|
||||
61
docs/releasing.md
Normal file
61
docs/releasing.md
Normal file
@@ -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.
|
||||
@@ -1,5 +1,8 @@
|
||||
antsibull>=0.17.0
|
||||
ansible-base>=2.10.12
|
||||
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
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
Role Index
|
||||
==========
|
||||
|
||||
.. toctree::
|
||||
|
||||
48
docs/testing.md
Normal file
48
docs/testing.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# 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
|
||||
```
|
||||
23
galaxy.yml
23
galaxy.yml
@@ -1,7 +1,7 @@
|
||||
---
|
||||
namespace: middleware_automation
|
||||
name: keycloak
|
||||
version: "1.0.0"
|
||||
version: "1.2.8"
|
||||
readme: README.md
|
||||
authors:
|
||||
- Romain Pelisse <rpelisse@redhat.com>
|
||||
@@ -20,14 +20,27 @@ tags:
|
||||
- security
|
||||
- infrastructure
|
||||
- authentication
|
||||
- java
|
||||
- runtimes
|
||||
- middleware
|
||||
- a4mw
|
||||
dependencies:
|
||||
"middleware_automation.redhat_csp_download": ">=1.2.1"
|
||||
"middleware_automation.wildfly": ">=0.0.6"
|
||||
"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
|
||||
homepage: https://github.com/ansible-middleware/keycloak
|
||||
issues: https://github.com/ansible-middleware/keycloak/issues
|
||||
build_ignore:
|
||||
- molecule
|
||||
- docs
|
||||
- .gitignore
|
||||
- .github
|
||||
- .ansible-lint
|
||||
- .yamllint
|
||||
- '*.tar.gz'
|
||||
- '*.zip'
|
||||
- molecule
|
||||
- changelogs
|
||||
- docs/_gh_include
|
||||
- docs/conf.py
|
||||
- docs/roles.rst.template
|
||||
- docs/requirements.yml
|
||||
|
||||
11
meta/execution-environment.yml
Normal file
11
meta/execution-environment.yml
Normal file
@@ -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
|
||||
@@ -2,17 +2,21 @@
|
||||
- name: Converge
|
||||
hosts: all
|
||||
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:
|
||||
- name: Include keycloak role
|
||||
include_role:
|
||||
name: ../../roles/keycloak
|
||||
vars:
|
||||
keycloak_admin_password: "changeme"
|
||||
- name: Keycloak Realm Role
|
||||
include_role:
|
||||
name: ../../roles/keycloak_realm
|
||||
ansible.builtin.include_role:
|
||||
name: keycloak_realm
|
||||
vars:
|
||||
keycloak_admin_password: "changeme"
|
||||
keycloak_client_default_roles:
|
||||
- TestRoleAdmin
|
||||
- TestRoleUser
|
||||
@@ -41,3 +45,16 @@
|
||||
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:
|
||||
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
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
---
|
||||
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
|
||||
@@ -16,7 +10,7 @@ platforms:
|
||||
port_bindings:
|
||||
- "8080/tcp"
|
||||
- "8443/tcp"
|
||||
- "8009/tcp"
|
||||
- "8009/tcp"
|
||||
provisioner:
|
||||
name: ansible
|
||||
config_options:
|
||||
@@ -33,16 +27,14 @@ provisioner:
|
||||
localhost:
|
||||
ansible_python_interpreter: "{{ ansible_playbook_python }}"
|
||||
env:
|
||||
ANSIBLE_FORCE_COLOR: "true"
|
||||
ANSIBLE_FORCE_COLOR: "true"
|
||||
ANSIBLE_VERBOSITY: 3
|
||||
verifier:
|
||||
name: ansible
|
||||
scenario:
|
||||
test_sequence:
|
||||
- dependency
|
||||
- lint
|
||||
- cleanup
|
||||
- destroy
|
||||
- syntax
|
||||
- create
|
||||
- prepare
|
||||
- converge
|
||||
|
||||
@@ -2,11 +2,19 @@
|
||||
- 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
|
||||
name:
|
||||
- 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.6.0/rh-sso-7.6.0-server-dist.zip"
|
||||
- "{{ assets_server }}/sso/7.6.1/rh-sso-7.6.1-patch.zip"
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
---
|
||||
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"
|
||||
|
||||
1
molecule/default/roles
Symbolic link
1
molecule/default/roles
Symbolic link
@@ -0,0 +1 @@
|
||||
../../roles
|
||||
@@ -1,6 +1,11 @@
|
||||
---
|
||||
- name: Verify
|
||||
hosts: all
|
||||
vars:
|
||||
keycloak_admin_password: "remembertochangeme"
|
||||
keycloak_jvm_package: java-11-openjdk-headless
|
||||
keycloak_uri: http://localhost:8080
|
||||
keycloak_management_port: http://localhost:9990
|
||||
tasks:
|
||||
- name: Populate service facts
|
||||
ansible.builtin.service_facts:
|
||||
@@ -8,3 +13,45 @@
|
||||
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 jvm # noqa blocked_modules command-instead-of-module
|
||||
ansible.builtin.shell: |
|
||||
set -o pipefail
|
||||
ps -ef | grep '/etc/alternatives/jre_11/' | 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
|
||||
- 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
|
||||
- name: Verify expected config
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- (keycloak_query_clients.json | selectattr('clientId','equalto','TestClient') | first)["attributes"]["post.logout.redirect.uris"] == '/public/logout'
|
||||
|
||||
54
molecule/overridexml/converge.yml
Normal file
54
molecule/overridexml/converge.yml
Normal file
@@ -0,0 +1,54 @@
|
||||
---
|
||||
- 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
|
||||
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
|
||||
44
molecule/overridexml/molecule.yml
Normal file
44
molecule/overridexml/molecule.yml
Normal file
@@ -0,0 +1,44 @@
|
||||
---
|
||||
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"
|
||||
- "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:
|
||||
- cleanup
|
||||
- destroy
|
||||
- create
|
||||
- prepare
|
||||
- converge
|
||||
- idempotence
|
||||
- side_effect
|
||||
- verify
|
||||
- cleanup
|
||||
- destroy
|
||||
9
molecule/overridexml/prepare.yml
Normal file
9
molecule/overridexml/prepare.yml
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
- name: Prepare
|
||||
hosts: all
|
||||
tasks:
|
||||
- name: "Run preparation common to all scenario"
|
||||
ansible.builtin.include_tasks: ../prepare.yml
|
||||
vars:
|
||||
assets:
|
||||
- "{{ assets_server }}/sso/7.6.0/rh-sso-7.6.0-server-dist.zip"
|
||||
1
molecule/overridexml/roles
Symbolic link
1
molecule/overridexml/roles
Symbolic link
@@ -0,0 +1 @@
|
||||
../../roles
|
||||
556
molecule/overridexml/templates/custom.xml.j2
Normal file
556
molecule/overridexml/templates/custom.xml.j2
Normal file
@@ -0,0 +1,556 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!-- {{ ansible_managed }} -->
|
||||
<server xmlns="urn:jboss:domain:16.0">
|
||||
<extensions>
|
||||
<extension module="org.jboss.as.clustering.infinispan"/>
|
||||
<extension module="org.jboss.as.connector"/>
|
||||
<extension module="org.jboss.as.deployment-scanner"/>
|
||||
<extension module="org.jboss.as.ee"/>
|
||||
<extension module="org.jboss.as.ejb3"/>
|
||||
<extension module="org.jboss.as.jaxrs"/>
|
||||
<extension module="org.jboss.as.jmx"/>
|
||||
<extension module="org.jboss.as.jpa"/>
|
||||
<extension module="org.jboss.as.logging"/>
|
||||
<extension module="org.jboss.as.mail"/>
|
||||
<extension module="org.jboss.as.modcluster"/>
|
||||
<extension module="org.jboss.as.naming"/>
|
||||
<extension module="org.jboss.as.remoting"/>
|
||||
<extension module="org.jboss.as.transactions"/>
|
||||
<extension module="org.jboss.as.weld"/>
|
||||
<extension module="org.keycloak.keycloak-server-subsystem"/>
|
||||
<extension module="org.wildfly.extension.bean-validation"/>
|
||||
<extension module="org.wildfly.extension.core-management"/>
|
||||
<extension module="org.wildfly.extension.elytron"/>
|
||||
<extension module="org.wildfly.extension.health"/>
|
||||
<extension module="org.wildfly.extension.io"/>
|
||||
<extension module="org.wildfly.extension.metrics"/>
|
||||
<extension module="org.wildfly.extension.request-controller"/>
|
||||
<extension module="org.wildfly.extension.security.manager"/>
|
||||
<extension module="org.wildfly.extension.undertow"/>
|
||||
</extensions>
|
||||
<management>
|
||||
<audit-log>
|
||||
<formatters>
|
||||
<json-formatter name="json-formatter"/>
|
||||
</formatters>
|
||||
<handlers>
|
||||
<file-handler name="file" formatter="json-formatter" path="audit-log.log" relative-to="jboss.server.data.dir"/>
|
||||
</handlers>
|
||||
<logger log-boot="true" log-read-only="false" enabled="false">
|
||||
<handlers>
|
||||
<handler name="file"/>
|
||||
</handlers>
|
||||
</logger>
|
||||
</audit-log>
|
||||
<management-interfaces>
|
||||
<http-interface http-authentication-factory="management-http-authentication">
|
||||
<http-upgrade enabled="true"/>
|
||||
<socket-binding http="management-http"/>
|
||||
</http-interface>
|
||||
</management-interfaces>
|
||||
<access-control provider="simple">
|
||||
<role-mapping>
|
||||
<role name="SuperUser">
|
||||
<include>
|
||||
<user name="$local"/>
|
||||
</include>
|
||||
</role>
|
||||
</role-mapping>
|
||||
</access-control>
|
||||
</management>
|
||||
<profile>
|
||||
<subsystem xmlns="urn:jboss:domain:logging:8.0">
|
||||
<console-handler name="CONSOLE">
|
||||
<level name="INFO"/>
|
||||
<formatter>
|
||||
<named-formatter name="COLOR-PATTERN"/>
|
||||
</formatter>
|
||||
</console-handler>
|
||||
<periodic-rotating-file-handler name="FILE" autoflush="true">
|
||||
<formatter>
|
||||
<named-formatter name="PATTERN"/>
|
||||
</formatter>
|
||||
<file relative-to="jboss.server.log.dir" path="server.log"/>
|
||||
<suffix value=".yyyy-MM-dd"/>
|
||||
<append value="true"/>
|
||||
</periodic-rotating-file-handler>
|
||||
<logger category="com.arjuna">
|
||||
<level name="WARN"/>
|
||||
</logger>
|
||||
<logger category="io.jaegertracing.Configuration">
|
||||
<level name="WARN"/>
|
||||
</logger>
|
||||
<logger category="org.jboss.as.config">
|
||||
<level name="DEBUG"/>
|
||||
</logger>
|
||||
<logger category="sun.rmi">
|
||||
<level name="WARN"/>
|
||||
</logger>
|
||||
<root-logger>
|
||||
<level name="INFO"/>
|
||||
<handlers>
|
||||
<handler name="CONSOLE"/>
|
||||
<handler name="FILE"/>
|
||||
</handlers>
|
||||
</root-logger>
|
||||
<formatter name="PATTERN">
|
||||
<pattern-formatter pattern="%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
|
||||
</formatter>
|
||||
<formatter name="COLOR-PATTERN">
|
||||
<pattern-formatter pattern="%K{level}%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
|
||||
</formatter>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:bean-validation:1.0"/>
|
||||
<subsystem xmlns="urn:jboss:domain:core-management:1.0"/>
|
||||
<subsystem xmlns="urn:jboss:domain:datasources:6.0">
|
||||
<datasources>
|
||||
<datasource jndi-name="java:jboss/datasources/KeycloakDS" pool-name="KeycloakDS" enabled="true" use-java-context="true" statistics-enabled="${wildfly.datasources.statistics-enabled:${wildfly.statistics-enabled:false}}">
|
||||
<connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url>
|
||||
<driver>h2</driver>
|
||||
<security>
|
||||
<user-name>sa</user-name>
|
||||
<password>sa</password>
|
||||
</security>
|
||||
</datasource>
|
||||
<drivers>
|
||||
<driver name="h2" module="com.h2database.h2">
|
||||
<xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
|
||||
</driver>
|
||||
</drivers>
|
||||
</datasources>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:deployment-scanner:2.0">
|
||||
<deployment-scanner path="deployments" relative-to="jboss.server.base.dir" scan-interval="5000" runtime-failure-causes-rollback="${jboss.deployment.scanner.rollback.on.failure:false}"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:ee:6.0">
|
||||
<spec-descriptor-property-replacement>false</spec-descriptor-property-replacement>
|
||||
<concurrent>
|
||||
<context-services>
|
||||
<context-service name="default" jndi-name="java:jboss/ee/concurrency/context/default" use-transaction-setup-provider="true"/>
|
||||
</context-services>
|
||||
<managed-thread-factories>
|
||||
<managed-thread-factory name="default" jndi-name="java:jboss/ee/concurrency/factory/default" context-service="default"/>
|
||||
</managed-thread-factories>
|
||||
<managed-executor-services>
|
||||
<managed-executor-service name="default" jndi-name="java:jboss/ee/concurrency/executor/default" context-service="default" hung-task-termination-period="0" hung-task-threshold="60000" keepalive-time="5000"/>
|
||||
</managed-executor-services>
|
||||
<managed-scheduled-executor-services>
|
||||
<managed-scheduled-executor-service name="default" jndi-name="java:jboss/ee/concurrency/scheduler/default" context-service="default" hung-task-termination-period="0" hung-task-threshold="60000" keepalive-time="3000"/>
|
||||
</managed-scheduled-executor-services>
|
||||
</concurrent>
|
||||
<default-bindings context-service="java:jboss/ee/concurrency/context/default" datasource="java:jboss/datasources/KeycloakDS" managed-executor-service="java:jboss/ee/concurrency/executor/default" managed-scheduled-executor-service="java:jboss/ee/concurrency/scheduler/default" managed-thread-factory="java:jboss/ee/concurrency/factory/default"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:ejb3:9.0">
|
||||
<session-bean>
|
||||
<stateless>
|
||||
<bean-instance-pool-ref pool-name="slsb-strict-max-pool"/>
|
||||
</stateless>
|
||||
<stateful default-access-timeout="5000" cache-ref="simple" passivation-disabled-cache-ref="simple"/>
|
||||
<singleton default-access-timeout="5000"/>
|
||||
</session-bean>
|
||||
<pools>
|
||||
<bean-instance-pools>
|
||||
<strict-max-pool name="mdb-strict-max-pool" derive-size="from-cpu-count" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
|
||||
<strict-max-pool name="slsb-strict-max-pool" derive-size="from-worker-pools" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
|
||||
</bean-instance-pools>
|
||||
</pools>
|
||||
<caches>
|
||||
<cache name="simple"/>
|
||||
<cache name="distributable" passivation-store-ref="infinispan" aliases="passivating clustered"/>
|
||||
</caches>
|
||||
<passivation-stores>
|
||||
<passivation-store name="infinispan" cache-container="ejb" max-size="10000"/>
|
||||
</passivation-stores>
|
||||
<async thread-pool-name="default"/>
|
||||
<timer-service thread-pool-name="default" default-data-store="default-file-store">
|
||||
<data-stores>
|
||||
<file-data-store name="default-file-store" path="timer-service-data" relative-to="jboss.server.data.dir"/>
|
||||
</data-stores>
|
||||
</timer-service>
|
||||
<remote cluster="ejb" connectors="http-remoting-connector" thread-pool-name="default">
|
||||
<channel-creation-options>
|
||||
<option name="MAX_OUTBOUND_MESSAGES" value="1234" type="remoting"/>
|
||||
</channel-creation-options>
|
||||
</remote>
|
||||
<thread-pools>
|
||||
<thread-pool name="default">
|
||||
<max-threads count="10"/>
|
||||
<keepalive-time time="60" unit="seconds"/>
|
||||
</thread-pool>
|
||||
</thread-pools>
|
||||
<default-security-domain value="other"/>
|
||||
<application-security-domains>
|
||||
<application-security-domain name="other" security-domain="ApplicationDomain"/>
|
||||
</application-security-domains>
|
||||
<default-missing-method-permissions-deny-access value="true"/>
|
||||
<statistics enabled="${wildfly.ejb3.statistics-enabled:${wildfly.statistics-enabled:false}}"/>
|
||||
<log-system-exceptions value="true"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:wildfly:elytron:13.0" final-providers="combined-providers" disallowed-providers="OracleUcrypto">
|
||||
<providers>
|
||||
<aggregate-providers name="combined-providers">
|
||||
<providers name="elytron"/>
|
||||
<providers name="openssl"/>
|
||||
</aggregate-providers>
|
||||
<provider-loader name="elytron" module="org.wildfly.security.elytron"/>
|
||||
<provider-loader name="openssl" module="org.wildfly.openssl"/>
|
||||
</providers>
|
||||
<audit-logging>
|
||||
<file-audit-log name="local-audit" path="audit.log" relative-to="jboss.server.log.dir" format="JSON"/>
|
||||
</audit-logging>
|
||||
<security-domains>
|
||||
<security-domain name="ApplicationDomain" default-realm="ApplicationRealm" permission-mapper="default-permission-mapper">
|
||||
<realm name="ApplicationRealm" role-decoder="groups-to-roles"/>
|
||||
<realm name="local"/>
|
||||
</security-domain>
|
||||
<security-domain name="ManagementDomain" default-realm="ManagementRealm" permission-mapper="default-permission-mapper">
|
||||
<realm name="ManagementRealm" role-decoder="groups-to-roles"/>
|
||||
<realm name="local" role-mapper="super-user-mapper"/>
|
||||
</security-domain>
|
||||
</security-domains>
|
||||
<security-realms>
|
||||
<identity-realm name="local" identity="$local"/>
|
||||
<properties-realm name="ApplicationRealm">
|
||||
<users-properties path="application-users.properties" relative-to="jboss.server.config.dir" digest-realm-name="ApplicationRealm"/>
|
||||
<groups-properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
|
||||
</properties-realm>
|
||||
<properties-realm name="ManagementRealm">
|
||||
<users-properties path="mgmt-users.properties" relative-to="jboss.server.config.dir" digest-realm-name="ManagementRealm"/>
|
||||
<groups-properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
|
||||
</properties-realm>
|
||||
</security-realms>
|
||||
<mappers>
|
||||
<simple-permission-mapper name="default-permission-mapper" mapping-mode="first">
|
||||
<permission-mapping>
|
||||
<principal name="anonymous"/>
|
||||
<permission-set name="default-permissions"/>
|
||||
</permission-mapping>
|
||||
<permission-mapping match-all="true">
|
||||
<permission-set name="login-permission"/>
|
||||
<permission-set name="default-permissions"/>
|
||||
</permission-mapping>
|
||||
</simple-permission-mapper>
|
||||
<constant-realm-mapper name="local" realm-name="local"/>
|
||||
<simple-role-decoder name="groups-to-roles" attribute="groups"/>
|
||||
<constant-role-mapper name="super-user-mapper">
|
||||
<role name="SuperUser"/>
|
||||
</constant-role-mapper>
|
||||
</mappers>
|
||||
<permission-sets>
|
||||
<permission-set name="login-permission">
|
||||
<permission class-name="org.wildfly.security.auth.permission.LoginPermission"/>
|
||||
</permission-set>
|
||||
<permission-set name="default-permissions">
|
||||
<permission class-name="org.wildfly.extension.batch.jberet.deployment.BatchPermission" module="org.wildfly.extension.batch.jberet" target-name="*"/>
|
||||
<permission class-name="org.wildfly.transaction.client.RemoteTransactionPermission" module="org.wildfly.transaction.client"/>
|
||||
<permission class-name="org.jboss.ejb.client.RemoteEJBPermission" module="org.jboss.ejb-client"/>
|
||||
<permission class-name="org.jboss.ejb.client.RemoteEJBPermission" module="org.jboss.ejb-client"/>
|
||||
</permission-set>
|
||||
</permission-sets>
|
||||
<http>
|
||||
<http-authentication-factory name="management-http-authentication" security-domain="ManagementDomain" http-server-mechanism-factory="global">
|
||||
<mechanism-configuration>
|
||||
<mechanism mechanism-name="DIGEST">
|
||||
<mechanism-realm realm-name="ManagementRealm"/>
|
||||
</mechanism>
|
||||
</mechanism-configuration>
|
||||
</http-authentication-factory>
|
||||
<http-authentication-factory name="application-http-authentication" security-domain="ApplicationDomain" http-server-mechanism-factory="global">
|
||||
<mechanism-configuration>
|
||||
<mechanism mechanism-name="BASIC">
|
||||
<mechanism-realm realm-name="ApplicationRealm"/>
|
||||
</mechanism>
|
||||
</mechanism-configuration>
|
||||
</http-authentication-factory>
|
||||
<provider-http-server-mechanism-factory name="global"/>
|
||||
</http>
|
||||
<sasl>
|
||||
<sasl-authentication-factory name="application-sasl-authentication" sasl-server-factory="configured" security-domain="ApplicationDomain">
|
||||
<mechanism-configuration>
|
||||
<mechanism mechanism-name="JBOSS-LOCAL-USER" realm-mapper="local"/>
|
||||
<mechanism mechanism-name="DIGEST-MD5">
|
||||
<mechanism-realm realm-name="ApplicationRealm"/>
|
||||
</mechanism>
|
||||
</mechanism-configuration>
|
||||
</sasl-authentication-factory>
|
||||
<sasl-authentication-factory name="management-sasl-authentication" sasl-server-factory="configured" security-domain="ManagementDomain">
|
||||
<mechanism-configuration>
|
||||
<mechanism mechanism-name="JBOSS-LOCAL-USER" realm-mapper="local"/>
|
||||
<mechanism mechanism-name="DIGEST-MD5">
|
||||
<mechanism-realm realm-name="ManagementRealm"/>
|
||||
</mechanism>
|
||||
</mechanism-configuration>
|
||||
</sasl-authentication-factory>
|
||||
<configurable-sasl-server-factory name="configured" sasl-server-factory="elytron">
|
||||
<properties>
|
||||
<property name="wildfly.sasl.local-user.default-user" value="$local"/>
|
||||
</properties>
|
||||
</configurable-sasl-server-factory>
|
||||
<mechanism-provider-filtering-sasl-server-factory name="elytron" sasl-server-factory="global">
|
||||
<filters>
|
||||
<filter provider-name="WildFlyElytron"/>
|
||||
</filters>
|
||||
</mechanism-provider-filtering-sasl-server-factory>
|
||||
<provider-sasl-server-factory name="global"/>
|
||||
</sasl>
|
||||
<tls>
|
||||
<key-stores>
|
||||
<key-store name="applicationKS">
|
||||
<credential-reference clear-text="password"/>
|
||||
<implementation type="JKS"/>
|
||||
<file path="application.keystore" relative-to="jboss.server.config.dir"/>
|
||||
</key-store>
|
||||
</key-stores>
|
||||
<key-managers>
|
||||
<key-manager name="applicationKM" key-store="applicationKS" generate-self-signed-certificate-host="localhost">
|
||||
<credential-reference clear-text="password"/>
|
||||
</key-manager>
|
||||
</key-managers>
|
||||
<server-ssl-contexts>
|
||||
<server-ssl-context name="applicationSSC" key-manager="applicationKM"/>
|
||||
</server-ssl-contexts>
|
||||
</tls>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:wildfly:health:1.0" security-enabled="false"/>
|
||||
<subsystem xmlns="urn:jboss:domain:infinispan:12.0">
|
||||
<cache-container name="ejb" default-cache="passivation" aliases="sfsb" modules="org.wildfly.clustering.ejb.infinispan">
|
||||
<local-cache name="passivation">
|
||||
<locking isolation="REPEATABLE_READ"/>
|
||||
<transaction mode="BATCH"/>
|
||||
<file-store passivation="true" purge="false"/>
|
||||
</local-cache>
|
||||
</cache-container>
|
||||
<cache-container name="keycloak" modules="org.keycloak.keycloak-model-infinispan">
|
||||
<local-cache name="realms">
|
||||
<heap-memory size="10000"/>
|
||||
</local-cache>
|
||||
<local-cache name="users">
|
||||
<heap-memory size="10000"/>
|
||||
</local-cache>
|
||||
<local-cache name="sessions"/>
|
||||
<local-cache name="authenticationSessions"/>
|
||||
<local-cache name="offlineSessions"/>
|
||||
<local-cache name="clientSessions"/>
|
||||
<local-cache name="offlineClientSessions"/>
|
||||
<local-cache name="loginFailures"/>
|
||||
<local-cache name="work"/>
|
||||
<local-cache name="authorization">
|
||||
<heap-memory size="10000"/>
|
||||
</local-cache>
|
||||
<local-cache name="keys">
|
||||
<heap-memory size="1000"/>
|
||||
<expiration max-idle="3600000"/>
|
||||
</local-cache>
|
||||
<local-cache name="actionTokens">
|
||||
<heap-memory size="-1"/>
|
||||
<expiration interval="300000" max-idle="-1"/>
|
||||
</local-cache>
|
||||
</cache-container>
|
||||
<cache-container name="server" default-cache="default" modules="org.wildfly.clustering.server">
|
||||
<local-cache name="default">
|
||||
<transaction mode="BATCH"/>
|
||||
</local-cache>
|
||||
</cache-container>
|
||||
<cache-container name="web" default-cache="passivation" modules="org.wildfly.clustering.web.infinispan">
|
||||
<local-cache name="passivation">
|
||||
<locking isolation="REPEATABLE_READ"/>
|
||||
<transaction mode="BATCH"/>
|
||||
<file-store passivation="true" purge="false"/>
|
||||
</local-cache>
|
||||
<local-cache name="sso">
|
||||
<locking isolation="REPEATABLE_READ"/>
|
||||
<transaction mode="BATCH"/>
|
||||
</local-cache>
|
||||
<local-cache name="routing"/>
|
||||
</cache-container>
|
||||
<cache-container name="hibernate" modules="org.infinispan.hibernate-cache">
|
||||
<local-cache name="entity">
|
||||
<heap-memory size="10000"/>
|
||||
<expiration max-idle="100000"/>
|
||||
</local-cache>
|
||||
<local-cache name="local-query">
|
||||
<heap-memory size="10000"/>
|
||||
<expiration max-idle="100000"/>
|
||||
</local-cache>
|
||||
<local-cache name="timestamps"/>
|
||||
</cache-container>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:io:3.0">
|
||||
<worker name="default"/>
|
||||
<buffer-pool name="default"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:jaxrs:2.0"/>
|
||||
<subsystem xmlns="urn:jboss:domain:jca:5.0">
|
||||
<archive-validation enabled="true" fail-on-error="true" fail-on-warn="false"/>
|
||||
<bean-validation enabled="true"/>
|
||||
<default-workmanager>
|
||||
<short-running-threads>
|
||||
<core-threads count="50"/>
|
||||
<queue-length count="50"/>
|
||||
<max-threads count="50"/>
|
||||
<keepalive-time time="10" unit="seconds"/>
|
||||
</short-running-threads>
|
||||
<long-running-threads>
|
||||
<core-threads count="50"/>
|
||||
<queue-length count="50"/>
|
||||
<max-threads count="50"/>
|
||||
<keepalive-time time="10" unit="seconds"/>
|
||||
</long-running-threads>
|
||||
</default-workmanager>
|
||||
<cached-connection-manager/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:jmx:1.3">
|
||||
<expose-resolved-model/>
|
||||
<expose-expression-model/>
|
||||
<remoting-connector/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:jpa:1.1">
|
||||
<jpa default-extended-persistence-inheritance="DEEP"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:keycloak-server:1.1">
|
||||
<web-context>auth</web-context>
|
||||
<providers>
|
||||
<provider>
|
||||
classpath:${jboss.home.dir}/providers/*
|
||||
</provider>
|
||||
</providers>
|
||||
<master-realm-name>master</master-realm-name>
|
||||
<scheduled-task-interval>900</scheduled-task-interval>
|
||||
<theme>
|
||||
<staticMaxAge>2592000</staticMaxAge>
|
||||
<cacheThemes>true</cacheThemes>
|
||||
<cacheTemplates>true</cacheTemplates>
|
||||
<dir>${jboss.home.dir}/themes</dir>
|
||||
</theme>
|
||||
<spi name="eventsStore">
|
||||
<provider name="jpa" enabled="true">
|
||||
<properties>
|
||||
<property name="exclude-events" value="["REFRESH_TOKEN"]"/>
|
||||
</properties>
|
||||
</provider>
|
||||
</spi>
|
||||
<spi name="userCache">
|
||||
<provider name="default" enabled="true"/>
|
||||
</spi>
|
||||
<spi name="userSessionPersister">
|
||||
<default-provider>jpa</default-provider>
|
||||
</spi>
|
||||
<spi name="timer">
|
||||
<default-provider>basic</default-provider>
|
||||
</spi>
|
||||
<spi name="connectionsHttpClient">
|
||||
<provider name="default" enabled="true"/>
|
||||
</spi>
|
||||
<spi name="connectionsJpa">
|
||||
<provider name="default" enabled="true">
|
||||
<properties>
|
||||
<property name="dataSource" value="java:jboss/datasources/KeycloakDS"/>
|
||||
<property name="initializeEmpty" value="true"/>
|
||||
<property name="migrationStrategy" value="update"/>
|
||||
<property name="migrationExport" value="${jboss.home.dir}/keycloak-database-update.sql"/>
|
||||
</properties>
|
||||
</provider>
|
||||
</spi>
|
||||
<spi name="realmCache">
|
||||
<provider name="default" enabled="true"/>
|
||||
</spi>
|
||||
<spi name="connectionsInfinispan">
|
||||
<default-provider>default</default-provider>
|
||||
<provider name="default" enabled="true">
|
||||
<properties>
|
||||
<property name="cacheContainer" value="java:jboss/infinispan/container/keycloak"/>
|
||||
</properties>
|
||||
</provider>
|
||||
</spi>
|
||||
<spi name="jta-lookup">
|
||||
<default-provider>${keycloak.jta.lookup.provider:jboss}</default-provider>
|
||||
<provider name="jboss" enabled="true"/>
|
||||
</spi>
|
||||
<spi name="publicKeyStorage">
|
||||
<provider name="infinispan" enabled="true">
|
||||
<properties>
|
||||
<property name="minTimeBetweenRequests" value="10"/>
|
||||
</properties>
|
||||
</provider>
|
||||
</spi>
|
||||
<spi name="x509cert-lookup">
|
||||
<default-provider>${keycloak.x509cert.lookup.provider:default}</default-provider>
|
||||
<provider name="default" enabled="true"/>
|
||||
</spi>
|
||||
<spi name="hostname">
|
||||
<default-provider>default</default-provider>
|
||||
<provider name="default" enabled="true">
|
||||
<properties>
|
||||
<property name="frontendUrl" value="{{ keycloak_modcluster.frontend_url }}"/>
|
||||
<property name="forceBackendUrlToFrontendUrl" value="true"/>
|
||||
</properties>
|
||||
</provider>
|
||||
</spi>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:mail:4.0">
|
||||
<mail-session name="default" jndi-name="java:jboss/mail/Default">
|
||||
<smtp-server outbound-socket-binding-ref="mail-smtp"/>
|
||||
</mail-session>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:wildfly:metrics:1.0" security-enabled="false" exposed-subsystems="*" prefix="${wildfly.metrics.prefix:jboss}"/>
|
||||
<subsystem xmlns="urn:jboss:domain:naming:2.0">
|
||||
<remote-naming/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:remoting:4.0">
|
||||
<http-connector name="http-remoting-connector" connector-ref="default" sasl-authentication-factory="application-sasl-authentication"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:request-controller:1.0"/>
|
||||
<subsystem xmlns="urn:jboss:domain:security-manager:1.0">
|
||||
<deployment-permissions>
|
||||
<maximum-set>
|
||||
<permission class="java.security.AllPermission"/>
|
||||
</maximum-set>
|
||||
</deployment-permissions>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:transactions:6.0">
|
||||
<core-environment node-identifier="${jboss.tx.node.id:1}">
|
||||
<process-id>
|
||||
<uuid/>
|
||||
</process-id>
|
||||
</core-environment>
|
||||
<recovery-environment socket-binding="txn-recovery-environment" status-socket-binding="txn-status-manager"/>
|
||||
<coordinator-environment statistics-enabled="${wildfly.transactions.statistics-enabled:${wildfly.statistics-enabled:false}}"/>
|
||||
<object-store path="tx-object-store" relative-to="jboss.server.data.dir"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:undertow:12.0" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other" statistics-enabled="${wildfly.undertow.statistics-enabled:${wildfly.statistics-enabled:false}}">
|
||||
<buffer-cache name="default"/>
|
||||
<server name="default-server">
|
||||
<http-listener name="default" socket-binding="http"/>
|
||||
<host name="default-host" alias="localhost">
|
||||
<location name="/" handler="welcome-content"/>
|
||||
<http-invoker http-authentication-factory="application-http-authentication"/>
|
||||
</host>
|
||||
</server>
|
||||
<servlet-container name="default">
|
||||
<jsp-config/>
|
||||
<websockets/>
|
||||
</servlet-container>
|
||||
<handlers>
|
||||
<file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
|
||||
</handlers>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:weld:4.0"/>
|
||||
</profile>
|
||||
<interfaces>
|
||||
<interface name="management">
|
||||
<inet-address value="${jboss.bind.address.management:127.0.0.1}"/>
|
||||
</interface>
|
||||
<interface name="public">
|
||||
<inet-address value="${jboss.bind.address:127.0.0.1}"/>
|
||||
</interface>
|
||||
</interfaces>
|
||||
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
|
||||
<socket-binding name="http" port="8081"/>
|
||||
<socket-binding name="management-http" interface="management" port="19990"/>
|
||||
<socket-binding name="txn-recovery-environment" port="4712"/>
|
||||
<socket-binding name="txn-status-manager" port="4713"/>
|
||||
<outbound-socket-binding name="mail-smtp">
|
||||
<remote-destination host="${jboss.mail.server.host:localhost}" port="${jboss.mail.server.port:25}"/>
|
||||
</outbound-socket-binding>
|
||||
</socket-binding-group>
|
||||
</server>
|
||||
11
molecule/overridexml/verify.yml
Normal file
11
molecule/overridexml/verify.yml
Normal file
@@ -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"
|
||||
35
molecule/prepare.yml
Normal file
35
molecule/prepare.yml
Normal file
@@ -0,0 +1,35 @@
|
||||
---
|
||||
- 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: "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') }}"
|
||||
validate_certs: no
|
||||
delegate_to: localhost
|
||||
loop: "{{ assets }}"
|
||||
loop_control:
|
||||
loop_var: asset
|
||||
when:
|
||||
- assets_server is defined
|
||||
- assets_server | length > 0
|
||||
45
molecule/quarkus/converge.yml
Normal file
45
molecule/quarkus/converge.yml
Normal file
@@ -0,0 +1,45 @@
|
||||
---
|
||||
- name: Converge
|
||||
hosts: all
|
||||
vars:
|
||||
keycloak_quarkus_admin_pass: "remembertochangeme"
|
||||
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"
|
||||
keycloak_quarkus_cert_file: "{{ keycloak.home }}/conf/cert.pem"
|
||||
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
|
||||
46
molecule/quarkus/molecule.yml
Normal file
46
molecule/quarkus/molecule.yml
Normal file
@@ -0,0 +1,46 @@
|
||||
---
|
||||
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"
|
||||
- "8443/tcp"
|
||||
- "8009/tcp"
|
||||
published_ports:
|
||||
- 0.0.0.0:8443:8443/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
|
||||
43
molecule/quarkus/prepare.yml
Normal file
43
molecule/quarkus/prepare.yml
Normal file
@@ -0,0 +1,43 @@
|
||||
---
|
||||
- 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: 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
|
||||
path: /opt/keycloak/keycloak-22.0.1/conf/
|
||||
mode: 0755
|
||||
|
||||
- name: Copy certificates
|
||||
ansible.builtin.copy:
|
||||
src: "{{ item }}"
|
||||
dest: "/opt/keycloak/keycloak-22.0.1/conf/{{ item }}"
|
||||
mode: 0444
|
||||
loop:
|
||||
- cert.pem
|
||||
- key.pem
|
||||
1
molecule/quarkus/roles
Symbolic link
1
molecule/quarkus/roles
Symbolic link
@@ -0,0 +1 @@
|
||||
../../roles
|
||||
39
molecule/quarkus/verify.yml
Normal file
39
molecule/quarkus/verify.yml
Normal file
@@ -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://instance:8443/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"] == '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
|
||||
- hera_home | length == 0
|
||||
8
molecule/requirements.yml
Normal file
8
molecule/requirements.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
collections:
|
||||
- name: middleware_automation.common
|
||||
- name: community.general
|
||||
- name: ansible.posix
|
||||
- name: community.docker
|
||||
version: ">=1.9.1"
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
---
|
||||
- name: Playbook for Keycloak Hosts
|
||||
hosts: keycloak
|
||||
collections:
|
||||
- middleware_automation.keycloak
|
||||
tasks:
|
||||
- name: Include keycloak role
|
||||
ansible.builtin.include_role:
|
||||
name: middleware_automation.keycloak.keycloak
|
||||
vars:
|
||||
keycloak_admin_password: "changeme"
|
||||
hosts: all
|
||||
vars:
|
||||
keycloak_admin_password: "remembertochangeme"
|
||||
roles:
|
||||
- middleware_automation.keycloak.keycloak
|
||||
|
||||
68
playbooks/keycloak_federation.yml
Normal file
68
playbooks/keycloak_federation.yml
Normal file
@@ -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 }}"
|
||||
13
playbooks/keycloak_quarkus.yml
Normal file
13
playbooks/keycloak_quarkus.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
- name: Playbook for Keycloak X Hosts
|
||||
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
|
||||
roles:
|
||||
- middleware_automation.keycloak.keycloak_quarkus
|
||||
@@ -1,67 +1,26 @@
|
||||
---
|
||||
- name: Playbook for Keycloak Hosts
|
||||
hosts: keycloak
|
||||
tasks:
|
||||
- name: Keycloak Realm Role
|
||||
ansible.builtin.include_role:
|
||||
name: middleware_automation.keycloak.keycloak_realm
|
||||
vars:
|
||||
keycloak_admin_password: "changeme"
|
||||
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 }}"
|
||||
hosts: all
|
||||
vars:
|
||||
keycloak_admin_password: "remembertochangeme"
|
||||
keycloak_clients:
|
||||
- name: TestClient1
|
||||
client_id: TestClient1
|
||||
roles:
|
||||
- TestClient1Admin
|
||||
- TestClient1User
|
||||
realm: TestRealm
|
||||
public_client: True
|
||||
web_origins:
|
||||
- http://testclient1origin/application
|
||||
- http://testclient1origin/other
|
||||
users:
|
||||
- username: TestUser
|
||||
password: password
|
||||
client_roles:
|
||||
- client: TestClient1
|
||||
role: TestClient1User
|
||||
realm: TestRealm
|
||||
roles:
|
||||
- role: middleware_automation.keycloak.keycloak_realm
|
||||
keycloak_realm: TestRealm
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
---
|
||||
- name: Playbook for Keycloak Hosts
|
||||
hosts: keycloak
|
||||
collections:
|
||||
- middleware_automation.redhat_csp_download
|
||||
- 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
|
||||
tasks:
|
||||
- name: Keycloak Role
|
||||
ansible.builtin.include_role:
|
||||
name: middleware_automation.keycloak.keycloak
|
||||
vars:
|
||||
keycloak_admin_password: "changeme"
|
||||
keycloak_rhsso_enable: True
|
||||
- middleware_automation.keycloak.keycloak
|
||||
|
||||
93
plugins/doc_fragments/attributes.py
Normal file
93
plugins/doc_fragments/attributes.py
Normal file
@@ -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.
|
||||
'''
|
||||
78
plugins/doc_fragments/keycloak.py
Normal file
78
plugins/doc_fragments/keycloak.py
Normal file
@@ -0,0 +1,78 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2017, Eike Frost <ei@kefro.st>
|
||||
# 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
|
||||
'''
|
||||
2192
plugins/module_utils/identity/keycloak/keycloak.py
Normal file
2192
plugins/module_utils/identity/keycloak/keycloak.py
Normal file
File diff suppressed because it is too large
Load Diff
984
plugins/modules/keycloak_client.py
Normal file
984
plugins/modules/keycloak_client.py
Normal file
@@ -0,0 +1,984 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2017, Eike Frost <ei@kefro.st>
|
||||
# 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()
|
||||
374
plugins/modules/keycloak_role.py
Normal file
374
plugins/modules/keycloak_role.py
Normal file
@@ -0,0 +1,374 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2019, Adam Goossens <adam.goossens@gmail.com>
|
||||
# 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()
|
||||
1021
plugins/modules/keycloak_user_federation.py
Normal file
1021
plugins/modules/keycloak_user_federation.py
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,4 @@
|
||||
---
|
||||
collections:
|
||||
- name: middleware_automation.redhat_csp_download
|
||||
version: ">=1.2.1"
|
||||
- name: middleware_automation.wildfly
|
||||
version: ">=0.0.5"
|
||||
- name: community.general
|
||||
- name: middleware_automation.common
|
||||
- name: ansible.posix
|
||||
|
||||
@@ -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
|
||||
@@ -19,8 +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.
|
||||
* the `wildfly_driver` role from [middleware_automation.wildfly](https://github.com/ansible-middleware/wildfly) collection
|
||||
* [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
|
||||
@@ -28,7 +32,19 @@ 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.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
|
||||
--------
|
||||
|
||||
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 |
|
||||
|:---------------|:------------------|:-----------------|:----------------|
|
||||
|`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
|
||||
@@ -39,9 +55,12 @@ 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_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` |
|
||||
|`keycloak_host`| hostname | `localhost` |
|
||||
|`keycloak_http_port`| HTTP port | `8080` |
|
||||
|`keycloak_https_port`| TLS HTTP port | `8443` |
|
||||
@@ -49,49 +68,56 @@ 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_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` |
|
||||
|`jvm_package`| RHEL java package runtime | `java-1.8.0-openjdk-devel` |
|
||||
|`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` |
|
||||
|
||||
|
||||
* Install options
|
||||
|
||||
| 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/<version>/<archive>`|
|
||||
|`keycloak_rhsso_download_url`| Download URL for RHSSO | `https://access.redhat.com/jbossnetwork/restricted/softwareDownload.html?softwareId=<productID>`|
|
||||
|`keycloak_version`| keycloak.org package version | `15.0.2` |
|
||||
|`keycloak_rhsso_version`| RHSSO version | `7.5.0` |
|
||||
|`keycloak_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/<version>/<archive>`|
|
||||
|`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_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
|
||||
|
||||
| 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_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_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 | `''` |
|
||||
|`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 }}` |
|
||||
|`rhsso_rhn_id` | Customer Portal product ID for Red Hat SSO | `{{ rhsso_rhn_ids[keycloak_rhsso_version] }}` |
|
||||
|`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
|
||||
@@ -101,26 +127,29 @@ 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/` |
|
||||
|
||||
|
||||
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 |
|
||||
|:---------|:------------|:---------|
|
||||
|`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` |
|
||||
|`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_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 } ]` |
|
||||
|`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` |
|
||||
|`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:
|
||||
The following parameters are _required_ only when `keycloak_db_enabled` is True:
|
||||
|
||||
| Variable | Description | Default |
|
||||
|:---------|:------------|:---------|
|
||||
@@ -130,46 +159,26 @@ The following variables are _required_ only when `keycloak_db_enabled` is True:
|
||||
|`keycloak_db_pass` | password for connecting to postgres | `keycloak-pass` |
|
||||
|
||||
|
||||
Example Playbooks
|
||||
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 |
|
||||
|`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
|
||||
-----------------
|
||||
|
||||
_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
|
||||
---
|
||||
- hosts: ...
|
||||
collections:
|
||||
- middleware_automation.keycloak
|
||||
tasks:
|
||||
- name: Include keycloak role
|
||||
include_role:
|
||||
name: keycloak
|
||||
vars:
|
||||
keycloak_admin_password: "changeme"
|
||||
```
|
||||
|
||||
* 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: "changeme"
|
||||
keycloak_rhsso_enable: True
|
||||
rhn_username: '<customer portal username>'
|
||||
rhn_password: '<customer portal password>'
|
||||
keycloak_admin_password: "remembertochangeme"
|
||||
roles:
|
||||
- middleware_automation.keycloak.keycloak
|
||||
```
|
||||
|
||||
|
||||
@@ -185,49 +194,11 @@ _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
|
||||
```
|
||||
|
||||
|
||||
* 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: "changeme"
|
||||
keycloak_rhsso_enable: True
|
||||
keycloak_rhsso_download_url: "<REPLACE with 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:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- hosts: keycloak
|
||||
collections:
|
||||
- middleware_automation.keycloak
|
||||
tasks:
|
||||
- name: Keycloak Role
|
||||
include_role:
|
||||
name: keycloak
|
||||
vars:
|
||||
keycloak_admin_password: "changeme"
|
||||
keycloak_rhsso_enable: True
|
||||
keycloak_offline_install: True
|
||||
# This should be the filename of rhsso zip file on Ansible node: rh-sso-7.5-server-dist.zip
|
||||
```
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
|
||||
@@ -1,34 +1,39 @@
|
||||
---
|
||||
### 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_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 }}"
|
||||
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] }}"
|
||||
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 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
|
||||
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_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 }}"
|
||||
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_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_startlimitintervalsec: "300"
|
||||
keycloak_service_startlimitburst: "5"
|
||||
keycloak_service_restartsec: "10s"
|
||||
|
||||
keycloak_configure_firewalld: False
|
||||
|
||||
### administrator console password
|
||||
keycloak_admin_password: ''
|
||||
|
||||
### Common configuration settings
|
||||
keycloak_bind_address: 0.0.0.0
|
||||
@@ -37,15 +42,22 @@ 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
|
||||
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
|
||||
### 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' }}"
|
||||
### 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
|
||||
@@ -54,25 +66,38 @@ keycloak_auth_client: admin-cli
|
||||
|
||||
keycloak_force_install: False
|
||||
|
||||
### mod_cluster reverse proxy
|
||||
### mod_cluster reverse proxy list
|
||||
keycloak_modcluster_enabled: "{{ True if keycloak_ha_enabled else False }}"
|
||||
keycloak_modcluster_url: localhost
|
||||
keycloak_frontend_url: http://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/
|
||||
keycloak_frontend_url_force: False
|
||||
keycloak_admin_url:
|
||||
|
||||
### 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' ]
|
||||
### database backend engine: values [ 'postgres', 'mariadb', 'sqlserver' ]
|
||||
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
|
||||
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
|
||||
@@ -83,3 +108,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
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
---
|
||||
- name: restart keycloak
|
||||
- name: "Restart handler"
|
||||
ansible.builtin.include_tasks: restart_keycloak.yml
|
||||
listen: "restart keycloak"
|
||||
|
||||
@@ -3,14 +3,19 @@ argument_specs:
|
||||
options:
|
||||
keycloak_version:
|
||||
# line 3 of keycloak/defaults/main.yml
|
||||
default: "15.0.2"
|
||||
default: "18.0.2"
|
||||
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:
|
||||
# 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 }}"
|
||||
@@ -26,51 +31,19 @@ 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] }}"
|
||||
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_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
|
||||
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"
|
||||
default: "java-1.8.0-openjdk-headless"
|
||||
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"
|
||||
@@ -78,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:
|
||||
@@ -96,6 +69,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"
|
||||
@@ -111,11 +89,20 @@ 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"
|
||||
description: "Address for binding service ports"
|
||||
type: "str"
|
||||
keycloak_management_port_bind_address:
|
||||
default: "127.0.0.1"
|
||||
description: "Address for binding the management ports"
|
||||
type: "str"
|
||||
keycloak_host:
|
||||
# line 35 of keycloak/defaults/main.yml
|
||||
default: "localhost"
|
||||
@@ -166,11 +153,15 @@ 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 }}"
|
||||
description: "Enable auto configuration for database backend"
|
||||
type: "str"
|
||||
type: "bool"
|
||||
keycloak_admin_user:
|
||||
# line 51 of keycloak/defaults/main.yml
|
||||
default: "admin"
|
||||
@@ -191,47 +182,63 @@ 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"
|
||||
description: "URL for the modcluster reverse proxy"
|
||||
type: "str"
|
||||
keycloak_modcluster_port:
|
||||
default: 6666
|
||||
description: "Port for the modcluster reverse proxy"
|
||||
type: "int"
|
||||
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"
|
||||
description: "Frontend URL for keycloak endpoints when a reverse proxy is used"
|
||||
type: "str"
|
||||
infinispan_user:
|
||||
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"
|
||||
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"
|
||||
@@ -239,7 +246,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
|
||||
@@ -276,3 +283,121 @@ 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"
|
||||
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_service_restart_always:
|
||||
default: false
|
||||
description: "systemd restart always behavior activation for keycloak"
|
||||
type: "bool"
|
||||
keycloak_service_restart_on_failure:
|
||||
default: false
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
keycloak_admin_url:
|
||||
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:
|
||||
default: "7.6.0"
|
||||
description: "Red Hat Single Sign-On version"
|
||||
type: "str"
|
||||
sso_archive:
|
||||
default: "rh-sso-{{ sso_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: "{{ sso_dest }}/rh-sso-{{ sso_version.split('.')[0] }}.{{ sso_version.split('.')[1] }}"
|
||||
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"
|
||||
sso_offline_install:
|
||||
default: False
|
||||
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_version:
|
||||
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:
|
||||
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:
|
||||
default: "core.service.rhsso"
|
||||
description: "JBossNetwork API category for Single Sign-On"
|
||||
type: "str"
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
---
|
||||
collections:
|
||||
- middleware_automation.redhat_csp_download
|
||||
- middleware_automation.wildfly
|
||||
- middleware_automation.common
|
||||
- ansible.posix
|
||||
|
||||
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
|
||||
@@ -23,5 +23,7 @@ galaxy_info:
|
||||
- keycloak
|
||||
- redhat
|
||||
- rhel
|
||||
- rhn
|
||||
- sso
|
||||
- sso
|
||||
- authentication
|
||||
- identity
|
||||
- security
|
||||
|
||||
20
roles/keycloak/tasks/fastpackages.yml
Normal file
20
roles/keycloak/tasks/fastpackages.yml
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
- 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
|
||||
|
||||
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
|
||||
@@ -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
|
||||
@@ -1,18 +0,0 @@
|
||||
---
|
||||
- name: Set facts
|
||||
ansible.builtin.set_fact:
|
||||
update_cache: true
|
||||
packages_to_install: []
|
||||
|
||||
- name: "Check packages to be installed"
|
||||
ansible.builtin.include_tasks: check.yml
|
||||
loop: "{{ packages_list | flatten }}"
|
||||
loop_control:
|
||||
loop_var: package_name
|
||||
|
||||
- name: "Install packages: {{ packages_to_install }}"
|
||||
become: yes
|
||||
ansible.builtin.yum:
|
||||
name: "{{ packages_to_install }}"
|
||||
state: present
|
||||
when: packages_to_install | length > 0
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
- name: Ensures required package firewalld are installed
|
||||
ansible.builtin.include_tasks: fastpackages/install.yml
|
||||
- name: Ensure required package firewalld are installed
|
||||
ansible.builtin.include_tasks: fastpackages.yml
|
||||
vars:
|
||||
packages_list:
|
||||
- firewalld
|
||||
@@ -12,9 +12,9 @@
|
||||
enabled: yes
|
||||
state: started
|
||||
|
||||
- name: Configure firewall for keycloak ports
|
||||
- name: "Configure firewall for {{ keycloak.service_name }} ports"
|
||||
become: yes
|
||||
firewalld:
|
||||
ansible.posix.firewalld:
|
||||
port: "{{ item }}"
|
||||
permanent: true
|
||||
state: enabled
|
||||
|
||||
@@ -16,26 +16,27 @@
|
||||
path: "{{ keycloak_jboss_home }}"
|
||||
register: existing_deploy
|
||||
|
||||
- block:
|
||||
- name: Stop the old keycloak service
|
||||
- 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
|
||||
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 }}"
|
||||
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_name }} service user/group"
|
||||
become: yes
|
||||
ansible.builtin.user:
|
||||
name: "{{ keycloak_service_user }}"
|
||||
@@ -43,7 +44,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 +59,7 @@
|
||||
archive: "{{ keycloak_dest }}/{{ keycloak.bundle }}"
|
||||
|
||||
- name: Check download archive path
|
||||
become: yes
|
||||
ansible.builtin.stat:
|
||||
path: "{{ archive }}"
|
||||
register: archive_path
|
||||
@@ -70,45 +72,71 @@
|
||||
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: 0644
|
||||
delegate_to: localhost
|
||||
run_once: yes
|
||||
when:
|
||||
- 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
|
||||
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
|
||||
- keycloak_rhsso_enable
|
||||
- sso_enable is defined and sso_enable
|
||||
- not keycloak_offline_install
|
||||
- keycloak_rhn_url in keycloak_rhsso_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.split('.')[:2] | join('.') }}"
|
||||
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:
|
||||
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: 0644
|
||||
delegate_to: localhost
|
||||
run_once: yes
|
||||
when:
|
||||
- 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
|
||||
- keycloak_rhsso_download_url is defined
|
||||
|
||||
- name: Check downloaded archive
|
||||
ansible.builtin.stat:
|
||||
@@ -123,7 +151,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
|
||||
@@ -137,7 +165,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 }}"
|
||||
@@ -168,19 +196,22 @@
|
||||
|
||||
# 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 }}"
|
||||
- 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_override_template }}"
|
||||
dest: "{{ keycloak_config_path_to_standalone_xml }}"
|
||||
owner: "{{ keycloak_service_user }}"
|
||||
group: "{{ keycloak_service_group }}"
|
||||
mode: 0640
|
||||
notify:
|
||||
- restart keycloak
|
||||
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.j2
|
||||
@@ -190,9 +221,40 @@
|
||||
mode: 0640
|
||||
notify:
|
||||
- restart keycloak
|
||||
when: not keycloak_remotecache.enabled
|
||||
when:
|
||||
- not keycloak_ha_enabled
|
||||
- keycloak_config_override_template | length == 0
|
||||
|
||||
- name: "Deploy {{ keycloak.service_name }} config with remote cache store to {{ keycloak_config_path_to_standalone_xml }}"
|
||||
- name: Create tcpping 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 | string) + ']',
|
||||
"value": hostvars[item].ansible_default_ipv4.address | default(item)
|
||||
}
|
||||
] }}
|
||||
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 }}"
|
||||
become: yes
|
||||
ansible.builtin.template:
|
||||
src: templates/standalone-ha.xml.j2
|
||||
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
|
||||
@@ -202,4 +264,19 @@
|
||||
mode: 0640
|
||||
notify:
|
||||
- restart keycloak
|
||||
when: keycloak_remotecache.enabled
|
||||
when:
|
||||
- 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
|
||||
|
||||
36
roles/keycloak/tasks/jdbc_driver.yml
Normal file
36
roles/keycloak/tasks/jdbc_driver.yml
Normal file
@@ -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.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 }}"
|
||||
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
|
||||
@@ -1,25 +1,45 @@
|
||||
---
|
||||
# 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_configure_firewalld
|
||||
tags:
|
||||
- firewall
|
||||
|
||||
- name: Include install tasks
|
||||
ansible.builtin.include_tasks: tasks/install.yml
|
||||
ansible.builtin.include_tasks: install.yml
|
||||
tags:
|
||||
- install
|
||||
|
||||
- name: Include systemd tasks
|
||||
ansible.builtin.include_tasks: tasks/systemd.yml
|
||||
ansible.builtin.include_tasks: systemd.yml
|
||||
tags:
|
||||
- systemd
|
||||
|
||||
- name: Include patch install tasks
|
||||
ansible.builtin.include_tasks: rhsso_patch.yml
|
||||
when:
|
||||
- sso_apply_patches is defined and sso_apply_patches
|
||||
- sso_enable is defined and sso_enable
|
||||
tags:
|
||||
- install
|
||||
- patch
|
||||
|
||||
- name: Link default logs directory
|
||||
ansible.builtin.file:
|
||||
state: link
|
||||
src: "{{ keycloak_jboss_home }}/standalone/log"
|
||||
dest: /var/log/keycloak
|
||||
become: yes
|
||||
|
||||
- block:
|
||||
- name: Check admin credentials by generating a token
|
||||
- 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"
|
||||
method: POST
|
||||
|
||||
@@ -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 12+ char long string"
|
||||
success_msg: "{{ 'Console administrator password OK' }}"
|
||||
|
||||
- name: Validate configuration
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
@@ -10,21 +18,30 @@
|
||||
- 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: Set required packages facts
|
||||
ansible.builtin.set_fact:
|
||||
required_packages:
|
||||
- "{{ jvm_package }}"
|
||||
- unzip
|
||||
- procps-ng
|
||||
- initscripts
|
||||
- name: Validate persistence configuration
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- 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
|
||||
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
|
||||
|
||||
- name: Ensures required packages are installed
|
||||
ansible.builtin.include_tasks: fastpackages/install.yml
|
||||
- name: Ensure required packages are installed
|
||||
ansible.builtin.include_tasks: fastpackages.yml
|
||||
vars:
|
||||
packages_list: "{{ required_packages }}"
|
||||
packages_list:
|
||||
- "{{ keycloak_jvm_package }}"
|
||||
- unzip
|
||||
- procps-ng
|
||||
- initscripts
|
||||
- tzdata-java
|
||||
|
||||
@@ -1,7 +1,27 @@
|
||||
---
|
||||
- name: "Restart and enable keycloack service"
|
||||
- name: "Restart and enable {{ keycloak.service_name }} service"
|
||||
ansible.builtin.systemd:
|
||||
name: keycloak
|
||||
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: "{{ keycloak_service_start_retries }}"
|
||||
delay: "{{ keycloak_service_start_delay }}"
|
||||
|
||||
- name: "Restart and enable {{ keycloak.service_name }} service"
|
||||
ansible.builtin.systemd:
|
||||
name: keycloak
|
||||
enabled: yes
|
||||
state: restarted
|
||||
become: yes
|
||||
when: inventory_hostname != ansible_play_hosts | first
|
||||
|
||||
13
roles/keycloak/tasks/rhsso_cli.yml
Normal file
13
roles/keycloak/tasks/rhsso_cli.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
- 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: "Execute CLI query: {{ query }}"
|
||||
ansible.builtin.command: >
|
||||
{{ keycloak.cli_path }} --connect --command='{{ query }}' --controller={{ keycloak_host }}:{{ keycloak_management_http_port }}
|
||||
changed_when: false
|
||||
register: cli_result
|
||||
169
roles/keycloak/tasks/rhsso_patch.yml
Normal file
169
roles/keycloak/tasks/rhsso_patch.yml
Normal file
@@ -0,0 +1,169 @@
|
||||
---
|
||||
## check remote patch archive
|
||||
- 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
|
||||
ansible.builtin.stat:
|
||||
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
|
||||
run_once: yes
|
||||
when:
|
||||
- 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.split('.')[:2] | join('.') }}"
|
||||
product_category: "{{ sso_product_category }}"
|
||||
register: rhn_products
|
||||
no_log: "{{ omit_rhn_output | default(true) }}"
|
||||
delegate_to: localhost
|
||||
run_once: yes
|
||||
|
||||
- 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 }}"
|
||||
when: sso_patch_version is not defined or sso_patch_version | length == 0
|
||||
delegate_to: localhost
|
||||
run_once: yes
|
||||
|
||||
- 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
|
||||
|
||||
- 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: "Determine selected patch from supplied version: {{ sso_patch_version }}"
|
||||
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 }}"
|
||||
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 }}"
|
||||
|
||||
- name: Check download patch archive path
|
||||
ansible.builtin.stat:
|
||||
path: "{{ patch_archive }}"
|
||||
register: patch_archive_path
|
||||
become: yes
|
||||
|
||||
## copy and unpack
|
||||
- name: Copy patch archive to target nodes
|
||||
ansible.builtin.copy:
|
||||
src: "{{ local_path.stat.path }}/{{ patch_bundle }}"
|
||||
dest: "{{ patch_archive }}"
|
||||
owner: "{{ keycloak_service_user }}"
|
||||
group: "{{ keycloak_service_group }}"
|
||||
mode: 0640
|
||||
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"
|
||||
args:
|
||||
apply:
|
||||
become: yes
|
||||
become_user: "{{ keycloak_service_user }}"
|
||||
|
||||
- name: "Perform patching"
|
||||
when:
|
||||
- cli_result is defined
|
||||
- cli_result.stdout is defined
|
||||
- patch_version not in cli_result.stdout
|
||||
block:
|
||||
- name: "Apply patch {{ patch_version }} to server"
|
||||
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
|
||||
vars:
|
||||
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:
|
||||
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"
|
||||
args:
|
||||
apply:
|
||||
become: yes
|
||||
become_user: "{{ keycloak_service_user }}"
|
||||
|
||||
- name: "Verify installed patch version"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- patch_version not in cli_result.stdout
|
||||
fail_msg: "Patch installation failed"
|
||||
success_msg: "Patch installation successful"
|
||||
|
||||
- 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
|
||||
15
roles/keycloak/tasks/start_keycloak.yml
Normal file
15
roles/keycloak/tasks/start_keycloak.yml
Normal file
@@ -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: "{{ keycloak_service_start_retries }}"
|
||||
delay: "{{ keycloak_service_start_delay }}"
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
- name: "Stop SSO service"
|
||||
- name: "Stop {{ keycloak.service_name }}"
|
||||
ansible.builtin.systemd:
|
||||
name: keycloak
|
||||
enabled: yes
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
- 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 +10,11 @@
|
||||
notify:
|
||||
- restart keycloak
|
||||
|
||||
- name: configure sysconfig file for keycloak service
|
||||
- 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
|
||||
ansible.builtin.template:
|
||||
src: keycloak-sysconfig.j2
|
||||
@@ -17,10 +22,12 @@
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
vars:
|
||||
keycloak_rpm_java_home: "{{ rpm_java_home }}"
|
||||
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
|
||||
@@ -32,18 +39,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_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_name }} service (remaining nodes)"
|
||||
ansible.builtin.include_tasks: start_keycloak.yml
|
||||
|
||||
- name: Check service status
|
||||
ansible.builtin.command: "systemctl status keycloak"
|
||||
@@ -58,11 +66,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
|
||||
|
||||
761
roles/keycloak/templates/15.0.8/standalone-infinispan.xml.j2
Normal file
761
roles/keycloak/templates/15.0.8/standalone-infinispan.xml.j2
Normal file
@@ -0,0 +1,761 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!-- {{ ansible_managed }} -->
|
||||
<server xmlns="urn:jboss:domain:16.0">
|
||||
<extensions>
|
||||
<extension module="org.jboss.as.clustering.infinispan"/>
|
||||
<extension module="org.jboss.as.clustering.jgroups"/>
|
||||
<extension module="org.jboss.as.connector"/>
|
||||
<extension module="org.jboss.as.deployment-scanner"/>
|
||||
<extension module="org.jboss.as.ee"/>
|
||||
<extension module="org.jboss.as.ejb3"/>
|
||||
<extension module="org.jboss.as.jaxrs"/>
|
||||
<extension module="org.jboss.as.jmx"/>
|
||||
<extension module="org.jboss.as.jpa"/>
|
||||
<extension module="org.jboss.as.logging"/>
|
||||
<extension module="org.jboss.as.mail"/>
|
||||
<extension module="org.jboss.as.modcluster"/>
|
||||
<extension module="org.jboss.as.naming"/>
|
||||
<extension module="org.jboss.as.remoting"/>
|
||||
<extension module="org.jboss.as.security"/>
|
||||
<extension module="org.jboss.as.transactions"/>
|
||||
<extension module="org.jboss.as.weld"/>
|
||||
<extension module="org.keycloak.keycloak-server-subsystem"/>
|
||||
<extension module="org.wildfly.extension.bean-validation"/>
|
||||
<extension module="org.wildfly.extension.core-management"/>
|
||||
<extension module="org.wildfly.extension.elytron"/>
|
||||
<extension module="org.wildfly.extension.health"/>
|
||||
<extension module="org.wildfly.extension.io"/>
|
||||
<extension module="org.wildfly.extension.metrics"/>
|
||||
<extension module="org.wildfly.extension.request-controller"/>
|
||||
<extension module="org.wildfly.extension.security.manager"/>
|
||||
<extension module="org.wildfly.extension.undertow"/>
|
||||
</extensions>
|
||||
<management>
|
||||
<security-realms>
|
||||
<security-realm name="ManagementRealm">
|
||||
<authentication>
|
||||
<local default-user="$local" skip-group-loading="true"/>
|
||||
<properties path="mgmt-users.properties" relative-to="jboss.server.config.dir"/>
|
||||
</authentication>
|
||||
<authorization map-groups-to-roles="false">
|
||||
<properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
|
||||
</authorization>
|
||||
</security-realm>
|
||||
<security-realm name="ApplicationRealm">
|
||||
<server-identities>
|
||||
<ssl>
|
||||
<keystore path="application.keystore" relative-to="jboss.server.config.dir" keystore-password="password" alias="server" key-password="password" generate-self-signed-certificate-host="localhost"/>
|
||||
</ssl>
|
||||
</server-identities>
|
||||
<authentication>
|
||||
<local default-user="$local" allowed-users="*" skip-group-loading="true"/>
|
||||
<properties path="application-users.properties" relative-to="jboss.server.config.dir"/>
|
||||
</authentication>
|
||||
<authorization>
|
||||
<properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
|
||||
</authorization>
|
||||
</security-realm>
|
||||
</security-realms>
|
||||
<audit-log>
|
||||
<formatters>
|
||||
<json-formatter name="json-formatter"/>
|
||||
</formatters>
|
||||
<handlers>
|
||||
<file-handler name="file" formatter="json-formatter" path="audit-log.log" relative-to="jboss.server.data.dir"/>
|
||||
</handlers>
|
||||
<logger log-boot="true" log-read-only="false" enabled="false">
|
||||
<handlers>
|
||||
<handler name="file"/>
|
||||
</handlers>
|
||||
</logger>
|
||||
</audit-log>
|
||||
<management-interfaces>
|
||||
<http-interface security-realm="ManagementRealm">
|
||||
<http-upgrade enabled="true"/>
|
||||
<socket-binding http="management-http"/>
|
||||
</http-interface>
|
||||
</management-interfaces>
|
||||
<access-control provider="simple">
|
||||
<role-mapping>
|
||||
<role name="SuperUser">
|
||||
<include>
|
||||
<user name="$local"/>
|
||||
</include>
|
||||
</role>
|
||||
</role-mapping>
|
||||
</access-control>
|
||||
</management>
|
||||
<profile>
|
||||
<subsystem xmlns="urn:jboss:domain:logging:8.0">
|
||||
<console-handler name="CONSOLE">
|
||||
<level name="INFO"/>
|
||||
<formatter>
|
||||
<named-formatter name="COLOR-PATTERN"/>
|
||||
</formatter>
|
||||
</console-handler>
|
||||
<periodic-rotating-file-handler name="FILE" autoflush="true">
|
||||
<formatter>
|
||||
<named-formatter name="PATTERN"/>
|
||||
</formatter>
|
||||
<file relative-to="jboss.server.log.dir" path="server.log"/>
|
||||
<suffix value=".yyyy-MM-dd"/>
|
||||
<append value="true"/>
|
||||
</periodic-rotating-file-handler>
|
||||
<logger category="com.arjuna">
|
||||
<level name="WARN"/>
|
||||
</logger>
|
||||
<logger category="io.jaegertracing.Configuration">
|
||||
<level name="WARN"/>
|
||||
</logger>
|
||||
<logger category="org.jboss.as.config">
|
||||
<level name="DEBUG"/>
|
||||
</logger>
|
||||
<logger category="sun.rmi">
|
||||
<level name="WARN"/>
|
||||
</logger>
|
||||
<logger category="org.keycloak.cluster.infinispan">
|
||||
<level name="DEBUG"/>
|
||||
</logger>
|
||||
<logger category="org.keycloak.connections.infinispan">
|
||||
<level name="DEBUG"/>
|
||||
</logger>
|
||||
<logger category="org.keycloak.models.cache.infinispan">
|
||||
<level name="DEBUG"/>
|
||||
</logger>
|
||||
<logger category="org.keycloak.models.sessions.infinispan">
|
||||
<level name="DEBUG"/>
|
||||
</logger>
|
||||
<root-logger>
|
||||
<level name="INFO"/>
|
||||
<handlers>
|
||||
<handler name="CONSOLE"/>
|
||||
<handler name="FILE"/>
|
||||
</handlers>
|
||||
</root-logger>
|
||||
<formatter name="PATTERN">
|
||||
<pattern-formatter pattern="%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
|
||||
</formatter>
|
||||
<formatter name="COLOR-PATTERN">
|
||||
<pattern-formatter pattern="%K{level}%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
|
||||
</formatter>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:bean-validation:1.0"/>
|
||||
<subsystem xmlns="urn:jboss:domain:core-management:1.0"/>
|
||||
<subsystem xmlns="urn:jboss:domain:datasources:6.0">
|
||||
<datasources>
|
||||
<datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true" statistics-enabled="${wildfly.datasources.statistics-enabled:${wildfly.statistics-enabled:false}}">
|
||||
<connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url>
|
||||
<driver>h2</driver>
|
||||
<security>
|
||||
<user-name>sa</user-name>
|
||||
<password>sa</password>
|
||||
</security>
|
||||
</datasource>
|
||||
<datasource jndi-name="java:jboss/datasources/KeycloakDS" pool-name="KeycloakDS" enabled="true" use-java-context="true" statistics-enabled="${wildfly.datasources.statistics-enabled:${wildfly.statistics-enabled:false}}">
|
||||
{% if keycloak_jdbc[keycloak_jdbc_engine].enabled %}
|
||||
<connection-url>{{ keycloak_jdbc[keycloak_jdbc_engine].connection_url }}</connection-url>
|
||||
<driver>{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_name }}</driver>
|
||||
<pool>
|
||||
<max-pool-size>20</max-pool-size>
|
||||
</pool>
|
||||
<security>
|
||||
<user-name>{{ keycloak_jdbc[keycloak_jdbc_engine].db_user }}</user-name>
|
||||
<password>{{ keycloak_jdbc[keycloak_jdbc_engine].db_password }}</password>
|
||||
</security>
|
||||
{% else %}
|
||||
<connection-url>jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE</connection-url>
|
||||
<driver>h2</driver>
|
||||
<security>
|
||||
<user-name>sa</user-name>
|
||||
<password>sa</password>
|
||||
</security>
|
||||
{% endif %}
|
||||
</datasource>
|
||||
<drivers>
|
||||
{% if keycloak_jdbc[keycloak_jdbc_engine].enabled %}
|
||||
<driver name="{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_name }}" module="{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_name }}">
|
||||
<driver-class>{{ keycloak_jdbc[keycloak_jdbc_engine].driver_class }}</driver-class>
|
||||
<xa-datasource-class>{{ keycloak_jdbc[keycloak_jdbc_engine].xa_datasource_class }}</xa-datasource-class>
|
||||
</driver>
|
||||
{% endif %}
|
||||
<driver name="h2" module="com.h2database.h2">
|
||||
<xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
|
||||
</driver>
|
||||
</drivers>
|
||||
</datasources>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:deployment-scanner:2.0">
|
||||
<deployment-scanner path="deployments" relative-to="jboss.server.base.dir" scan-interval="5000" runtime-failure-causes-rollback="${jboss.deployment.scanner.rollback.on.failure:false}"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:ee:6.0">
|
||||
<spec-descriptor-property-replacement>false</spec-descriptor-property-replacement>
|
||||
<concurrent>
|
||||
<context-services>
|
||||
<context-service name="default" jndi-name="java:jboss/ee/concurrency/context/default" use-transaction-setup-provider="true"/>
|
||||
</context-services>
|
||||
<managed-thread-factories>
|
||||
<managed-thread-factory name="default" jndi-name="java:jboss/ee/concurrency/factory/default" context-service="default"/>
|
||||
</managed-thread-factories>
|
||||
<managed-executor-services>
|
||||
<managed-executor-service name="default" jndi-name="java:jboss/ee/concurrency/executor/default" context-service="default" hung-task-termination-period="0" hung-task-threshold="60000" keepalive-time="5000"/>
|
||||
</managed-executor-services>
|
||||
<managed-scheduled-executor-services>
|
||||
<managed-scheduled-executor-service name="default" jndi-name="java:jboss/ee/concurrency/scheduler/default" context-service="default" hung-task-termination-period="0" hung-task-threshold="60000" keepalive-time="3000"/>
|
||||
</managed-scheduled-executor-services>
|
||||
</concurrent>
|
||||
<default-bindings context-service="java:jboss/ee/concurrency/context/default" datasource="java:jboss/datasources/ExampleDS" managed-executor-service="java:jboss/ee/concurrency/executor/default" managed-scheduled-executor-service="java:jboss/ee/concurrency/scheduler/default" managed-thread-factory="java:jboss/ee/concurrency/factory/default"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:ejb3:9.0">
|
||||
<session-bean>
|
||||
<stateless>
|
||||
<bean-instance-pool-ref pool-name="slsb-strict-max-pool"/>
|
||||
</stateless>
|
||||
<stateful default-access-timeout="5000" cache-ref="distributable" passivation-disabled-cache-ref="simple"/>
|
||||
<singleton default-access-timeout="5000"/>
|
||||
</session-bean>
|
||||
<pools>
|
||||
<bean-instance-pools>
|
||||
<strict-max-pool name="mdb-strict-max-pool" derive-size="from-cpu-count" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
|
||||
<strict-max-pool name="slsb-strict-max-pool" derive-size="from-worker-pools" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
|
||||
</bean-instance-pools>
|
||||
</pools>
|
||||
<caches>
|
||||
<cache name="simple"/>
|
||||
<cache name="distributable" passivation-store-ref="infinispan" aliases="passivating clustered"/>
|
||||
</caches>
|
||||
<passivation-stores>
|
||||
<passivation-store name="infinispan" cache-container="ejb" max-size="10000"/>
|
||||
</passivation-stores>
|
||||
<async thread-pool-name="default"/>
|
||||
<timer-service thread-pool-name="default" default-data-store="default-file-store">
|
||||
<data-stores>
|
||||
<file-data-store name="default-file-store" path="timer-service-data" relative-to="jboss.server.data.dir"/>
|
||||
</data-stores>
|
||||
</timer-service>
|
||||
<remote cluster="ejb" connectors="http-remoting-connector" thread-pool-name="default">
|
||||
<channel-creation-options>
|
||||
<option name="MAX_OUTBOUND_MESSAGES" value="1234" type="remoting"/>
|
||||
</channel-creation-options>
|
||||
</remote>
|
||||
<thread-pools>
|
||||
<thread-pool name="default">
|
||||
<max-threads count="10"/>
|
||||
<keepalive-time time="60" unit="seconds"/>
|
||||
</thread-pool>
|
||||
</thread-pools>
|
||||
<default-security-domain value="other"/>
|
||||
<default-missing-method-permissions-deny-access value="true"/>
|
||||
<statistics enabled="${wildfly.ejb3.statistics-enabled:${wildfly.statistics-enabled:false}}"/>
|
||||
<log-system-exceptions value="true"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:wildfly:elytron:13.0" final-providers="combined-providers" disallowed-providers="OracleUcrypto">
|
||||
<providers>
|
||||
<aggregate-providers name="combined-providers">
|
||||
<providers name="elytron"/>
|
||||
<providers name="openssl"/>
|
||||
</aggregate-providers>
|
||||
<provider-loader name="elytron" module="org.wildfly.security.elytron"/>
|
||||
<provider-loader name="openssl" module="org.wildfly.openssl"/>
|
||||
</providers>
|
||||
<audit-logging>
|
||||
<file-audit-log name="local-audit" path="audit.log" relative-to="jboss.server.log.dir" format="JSON"/>
|
||||
</audit-logging>
|
||||
<security-domains>
|
||||
<security-domain name="ApplicationDomain" default-realm="ApplicationRealm" permission-mapper="default-permission-mapper">
|
||||
<realm name="ApplicationRealm" role-decoder="groups-to-roles"/>
|
||||
<realm name="local"/>
|
||||
</security-domain>
|
||||
<security-domain name="ManagementDomain" default-realm="ManagementRealm" permission-mapper="default-permission-mapper">
|
||||
<realm name="ManagementRealm" role-decoder="groups-to-roles"/>
|
||||
<realm name="local" role-mapper="super-user-mapper"/>
|
||||
</security-domain>
|
||||
</security-domains>
|
||||
<security-realms>
|
||||
<identity-realm name="local" identity="$local"/>
|
||||
<properties-realm name="ApplicationRealm">
|
||||
<users-properties path="application-users.properties" relative-to="jboss.server.config.dir" digest-realm-name="ApplicationRealm"/>
|
||||
<groups-properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
|
||||
</properties-realm>
|
||||
<properties-realm name="ManagementRealm">
|
||||
<users-properties path="mgmt-users.properties" relative-to="jboss.server.config.dir" digest-realm-name="ManagementRealm"/>
|
||||
<groups-properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
|
||||
</properties-realm>
|
||||
</security-realms>
|
||||
<mappers>
|
||||
<simple-permission-mapper name="default-permission-mapper" mapping-mode="first">
|
||||
<permission-mapping>
|
||||
<principal name="anonymous"/>
|
||||
<permission-set name="default-permissions"/>
|
||||
</permission-mapping>
|
||||
<permission-mapping match-all="true">
|
||||
<permission-set name="login-permission"/>
|
||||
<permission-set name="default-permissions"/>
|
||||
</permission-mapping>
|
||||
</simple-permission-mapper>
|
||||
<constant-realm-mapper name="local" realm-name="local"/>
|
||||
<simple-role-decoder name="groups-to-roles" attribute="groups"/>
|
||||
<constant-role-mapper name="super-user-mapper">
|
||||
<role name="SuperUser"/>
|
||||
</constant-role-mapper>
|
||||
</mappers>
|
||||
<permission-sets>
|
||||
<permission-set name="login-permission">
|
||||
<permission class-name="org.wildfly.security.auth.permission.LoginPermission"/>
|
||||
</permission-set>
|
||||
<permission-set name="default-permissions">
|
||||
<permission class-name="org.wildfly.extension.batch.jberet.deployment.BatchPermission" module="org.wildfly.extension.batch.jberet" target-name="*"/>
|
||||
<permission class-name="org.wildfly.transaction.client.RemoteTransactionPermission" module="org.wildfly.transaction.client"/>
|
||||
<permission class-name="org.jboss.ejb.client.RemoteEJBPermission" module="org.jboss.ejb-client"/>
|
||||
<permission class-name="org.jboss.ejb.client.RemoteEJBPermission" module="org.jboss.ejb-client"/>
|
||||
</permission-set>
|
||||
</permission-sets>
|
||||
<http>
|
||||
<http-authentication-factory name="management-http-authentication" security-domain="ManagementDomain" http-server-mechanism-factory="global">
|
||||
<mechanism-configuration>
|
||||
<mechanism mechanism-name="DIGEST">
|
||||
<mechanism-realm realm-name="ManagementRealm"/>
|
||||
</mechanism>
|
||||
</mechanism-configuration>
|
||||
</http-authentication-factory>
|
||||
<provider-http-server-mechanism-factory name="global"/>
|
||||
</http>
|
||||
<sasl>
|
||||
<sasl-authentication-factory name="application-sasl-authentication" sasl-server-factory="configured" security-domain="ApplicationDomain">
|
||||
<mechanism-configuration>
|
||||
<mechanism mechanism-name="JBOSS-LOCAL-USER" realm-mapper="local"/>
|
||||
<mechanism mechanism-name="DIGEST-MD5">
|
||||
<mechanism-realm realm-name="ApplicationRealm"/>
|
||||
</mechanism>
|
||||
</mechanism-configuration>
|
||||
</sasl-authentication-factory>
|
||||
<sasl-authentication-factory name="management-sasl-authentication" sasl-server-factory="configured" security-domain="ManagementDomain">
|
||||
<mechanism-configuration>
|
||||
<mechanism mechanism-name="JBOSS-LOCAL-USER" realm-mapper="local"/>
|
||||
<mechanism mechanism-name="DIGEST-MD5">
|
||||
<mechanism-realm realm-name="ManagementRealm"/>
|
||||
</mechanism>
|
||||
</mechanism-configuration>
|
||||
</sasl-authentication-factory>
|
||||
<configurable-sasl-server-factory name="configured" sasl-server-factory="elytron">
|
||||
<properties>
|
||||
<property name="wildfly.sasl.local-user.default-user" value="$local"/>
|
||||
</properties>
|
||||
</configurable-sasl-server-factory>
|
||||
<mechanism-provider-filtering-sasl-server-factory name="elytron" sasl-server-factory="global">
|
||||
<filters>
|
||||
<filter provider-name="WildFlyElytron"/>
|
||||
</filters>
|
||||
</mechanism-provider-filtering-sasl-server-factory>
|
||||
<provider-sasl-server-factory name="global"/>
|
||||
</sasl>
|
||||
<tls>
|
||||
<key-stores>
|
||||
<key-store name="applicationKS">
|
||||
<credential-reference clear-text="password"/>
|
||||
<implementation type="JKS"/>
|
||||
<file path="application.keystore" relative-to="jboss.server.config.dir"/>
|
||||
</key-store>
|
||||
</key-stores>
|
||||
<key-managers>
|
||||
<key-manager name="applicationKM" key-store="applicationKS" generate-self-signed-certificate-host="localhost">
|
||||
<credential-reference clear-text="password"/>
|
||||
</key-manager>
|
||||
</key-managers>
|
||||
<server-ssl-contexts>
|
||||
<server-ssl-context name="applicationSSC" key-manager="applicationKM"/>
|
||||
</server-ssl-contexts>
|
||||
</tls>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:wildfly:health:1.0" security-enabled="false"/>
|
||||
<subsystem xmlns="urn:jboss:domain:infinispan:12.0">
|
||||
<cache-container name="ejb" default-cache="dist" aliases="sfsb" modules="org.wildfly.clustering.ejb.infinispan">
|
||||
<transport lock-timeout="60000"/>
|
||||
<distributed-cache name="dist">
|
||||
<locking isolation="REPEATABLE_READ"/>
|
||||
<transaction mode="BATCH"/>
|
||||
<file-store/>
|
||||
</distributed-cache>
|
||||
</cache-container>
|
||||
<cache-container name="keycloak" modules="org.keycloak.keycloak-model-infinispan">
|
||||
<transport lock-timeout="60000"/>
|
||||
<local-cache name="realms">
|
||||
<heap-memory size="10000"/>
|
||||
</local-cache>
|
||||
<local-cache name="users">
|
||||
<heap-memory size="10000"/>
|
||||
</local-cache>
|
||||
{% for cachename in [ "sessions", "offlineSessions", "clientSessions", "offlineClientSessions", "loginFailures", "actionTokens", "authenticationSessions" ] %}
|
||||
<distributed-cache name="{{ cachename }}">
|
||||
<remote-store cache="{{ cachename }}"
|
||||
remote-servers="remote-cache"
|
||||
passivation="false"
|
||||
fetch-state="false"
|
||||
purge="false"
|
||||
preload="false"
|
||||
shared="true">
|
||||
<property name="rawValues">true</property>
|
||||
<property name="marshaller">org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory</property>
|
||||
<property name="remoteStoreSecurityEnabled">false</property>
|
||||
<property name="infinispan.client.hotrod.auth_username">{{ keycloak_remotecache.username }}</property>
|
||||
<property name="infinispan.client.hotrod.auth_password">{{ keycloak_remotecache.password }}</property>
|
||||
<property name="infinispan.client.hotrod.auth_realm">{{ keycloak_remotecache.realm | default('default') }}</property>
|
||||
<property name="infinispan.client.hotrod.auth_server_name">{{ keycloak_remotecache.server_name }}</property>
|
||||
<property name="infinispan.client.hotrod.sasl_mechanism">{{ keycloak_remotecache.sasl_mechanism }}</property>
|
||||
<property name="infinispan.client.hotrod.use_ssl">{{ keycloak_remotecache.use_ssl }}</property>
|
||||
<property name="infinispan.client.hotrod.trust_store_file_name">{{ keycloak_remotecache.trust_store_path }}</property>
|
||||
<property name="infinispan.client.hotrod.trust_store_type">JKS</property>
|
||||
<property name="infinispan.client.hotrod.trust_store_password">{{ keycloak_remotecache.trust_store_password }}</property>
|
||||
<property name="infinispan.client.hotrod.client_intelligence">TOPOLOGY_AWARE</property>
|
||||
</remote-store>
|
||||
</distributed-cache>
|
||||
{% endfor %}
|
||||
<replicated-cache name="work">
|
||||
<remote-store cache="work"
|
||||
remote-servers="remote-cache"
|
||||
passivation="false"
|
||||
fetch-state="false"
|
||||
purge="false"
|
||||
preload="false"
|
||||
shared="true">
|
||||
<property name="rawValues">true</property>
|
||||
<property name="marshaller">org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory</property>
|
||||
<property name="remoteStoreSecurityEnabled">false</property>
|
||||
<property name="infinispan.client.hotrod.auth_username">{{ keycloak_remotecache.username }}</property>
|
||||
<property name="infinispan.client.hotrod.auth_password">{{ keycloak_remotecache.password }}</property>
|
||||
<property name="infinispan.client.hotrod.auth_realm">{{ keycloak_remotecache.realm | default('default') }}</property>
|
||||
<property name="infinispan.client.hotrod.auth_server_name">{{ keycloak_remotecache.server_name }}</property>
|
||||
<property name="infinispan.client.hotrod.sasl_mechanism">{{ keycloak_remotecache.sasl_mechanism }}</property>
|
||||
<property name="infinispan.client.hotrod.use_ssl">{{ keycloak_remotecache.use_ssl }}</property>
|
||||
<property name="infinispan.client.hotrod.trust_store_file_name">{{ keycloak_remotecache.trust_store_path }}</property>
|
||||
<property name="infinispan.client.hotrod.trust_store_type">JKS</property>
|
||||
<property name="infinispan.client.hotrod.trust_store_password">{{ keycloak_remotecache.trust_store_password }}</property>
|
||||
<property name="infinispan.client.hotrod.client_intelligence">TOPOLOGY_AWARE</property>
|
||||
</remote-store>
|
||||
</replicated-cache>
|
||||
<local-cache name="authorization">
|
||||
<heap-memory size="10000"/>
|
||||
</local-cache>
|
||||
<local-cache name="keys">
|
||||
<heap-memory size="1000"/>
|
||||
<expiration max-idle="3600000"/>
|
||||
</local-cache>
|
||||
</cache-container>
|
||||
<cache-container name="server" default-cache="default" aliases="singleton cluster" modules="org.wildfly.clustering.server">
|
||||
<transport lock-timeout="60000"/>
|
||||
<replicated-cache name="default">
|
||||
<transaction mode="BATCH"/>
|
||||
</replicated-cache>
|
||||
</cache-container>
|
||||
<cache-container name="web" default-cache="dist" modules="org.wildfly.clustering.web.infinispan">
|
||||
<transport lock-timeout="60000"/>
|
||||
<replicated-cache name="sso">
|
||||
<locking isolation="REPEATABLE_READ"/>
|
||||
<transaction mode="BATCH"/>
|
||||
</replicated-cache>
|
||||
<distributed-cache name="dist">
|
||||
<locking isolation="REPEATABLE_READ"/>
|
||||
<transaction mode="BATCH"/>
|
||||
<file-store/>
|
||||
</distributed-cache>
|
||||
<distributed-cache name="routing"/>
|
||||
</cache-container>
|
||||
<cache-container name="hibernate" modules="org.infinispan.hibernate-cache">
|
||||
<transport lock-timeout="60000"/>
|
||||
<local-cache name="local-query">
|
||||
<heap-memory size="10000"/>
|
||||
<expiration max-idle="100000"/>
|
||||
</local-cache>
|
||||
<invalidation-cache name="entity">
|
||||
<transaction mode="NON_XA"/>
|
||||
<heap-memory size="10000"/>
|
||||
<expiration max-idle="100000"/>
|
||||
</invalidation-cache>
|
||||
<replicated-cache name="timestamps"/>
|
||||
</cache-container>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:io:3.0">
|
||||
<worker name="default"/>
|
||||
<buffer-pool name="default"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:jaxrs:2.0"/>
|
||||
<subsystem xmlns="urn:jboss:domain:jca:5.0">
|
||||
<archive-validation enabled="true" fail-on-error="true" fail-on-warn="false"/>
|
||||
<bean-validation enabled="true"/>
|
||||
<default-workmanager>
|
||||
<short-running-threads>
|
||||
<core-threads count="50"/>
|
||||
<queue-length count="50"/>
|
||||
<max-threads count="50"/>
|
||||
<keepalive-time time="10" unit="seconds"/>
|
||||
</short-running-threads>
|
||||
<long-running-threads>
|
||||
<core-threads count="50"/>
|
||||
<queue-length count="50"/>
|
||||
<max-threads count="50"/>
|
||||
<keepalive-time time="10" unit="seconds"/>
|
||||
</long-running-threads>
|
||||
</default-workmanager>
|
||||
<cached-connection-manager/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:jgroups:8.0">
|
||||
<channels default="ee">
|
||||
<channel name="ee" stack="tcp" cluster="ejb"/>
|
||||
</channels>
|
||||
<stacks>
|
||||
<stack name="tcp">
|
||||
<transport site="${jboss.node.name}" type="TCP" socket-binding="jgroups-tcp"/>
|
||||
{% if keycloak_jdbc[keycloak_jdbc_engine].enabled %}
|
||||
<protocol type="JDBC_PING">
|
||||
<property name="datasource_jndi_name">java:jboss/datasources/KeycloakDS</property>
|
||||
<property name="initialize_sql">{{ keycloak_jdbc[keycloak_jdbc_engine].initialize_db }}</property>
|
||||
<property name="insert_single_sql">INSERT INTO JGROUPSPING (own_addr, cluster_name, ping_data) values (?, ?, ?)</property>
|
||||
<property name="delete_single_sql">DELETE FROM JGROUPSPING WHERE own_addr=? AND cluster_name=?</property>
|
||||
<property name="select_all_pingdata_sql">SELECT ping_data FROM JGROUPSPING WHERE cluster_name=?</property>
|
||||
</protocol>
|
||||
{% endif %}
|
||||
<protocol type="MERGE3"/>
|
||||
<protocol type="FD_SOCK"/>
|
||||
<protocol type="FD_ALL"/>
|
||||
<protocol type="VERIFY_SUSPECT"/>
|
||||
<protocol type="pbcast.NAKACK2"/>
|
||||
<protocol type="UNICAST3"/>
|
||||
<protocol type="pbcast.STABLE"/>
|
||||
<protocol type="pbcast.GMS">
|
||||
<property name="join_timeout">30000</property>
|
||||
</protocol>
|
||||
<protocol type="MFC"/>
|
||||
<protocol type="FRAG2"/>
|
||||
</stack>
|
||||
</stacks>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:jmx:1.3">
|
||||
<expose-resolved-model/>
|
||||
<expose-expression-model/>
|
||||
<remoting-connector/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:jpa:1.1">
|
||||
<jpa default-extended-persistence-inheritance="DEEP"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:keycloak-server:1.1">
|
||||
<web-context>auth</web-context>
|
||||
<providers>
|
||||
<provider>
|
||||
classpath:${jboss.home.dir}/providers/*
|
||||
</provider>
|
||||
</providers>
|
||||
<master-realm-name>master</master-realm-name>
|
||||
<scheduled-task-interval>900</scheduled-task-interval>
|
||||
<theme>
|
||||
<staticMaxAge>2592000</staticMaxAge>
|
||||
<cacheThemes>true</cacheThemes>
|
||||
<cacheTemplates>true</cacheTemplates>
|
||||
<dir>${jboss.home.dir}/themes</dir>
|
||||
</theme>
|
||||
{% if keycloak_ha_enabled %}
|
||||
<spi name="dblock">
|
||||
<provider name="jpa" enabled="true">
|
||||
<properties>
|
||||
<property name="lockWaitTimeout" value="900"/>
|
||||
</properties>
|
||||
</provider>
|
||||
</spi>
|
||||
{% endif %}
|
||||
<spi name="eventsStore">
|
||||
<provider name="jpa" enabled="true">
|
||||
<properties>
|
||||
<property name="exclude-events" value="["REFRESH_TOKEN"]"/>
|
||||
</properties>
|
||||
</provider>
|
||||
</spi>
|
||||
<spi name="userCache">
|
||||
<provider name="default" enabled="true"/>
|
||||
</spi>
|
||||
<spi name="userSessionPersister">
|
||||
<default-provider>jpa</default-provider>
|
||||
</spi>
|
||||
<spi name="timer">
|
||||
<default-provider>basic</default-provider>
|
||||
</spi>
|
||||
<spi name="connectionsHttpClient">
|
||||
<provider name="default" enabled="true"/>
|
||||
</spi>
|
||||
<spi name="connectionsJpa">
|
||||
<provider name="default" enabled="true">
|
||||
<properties>
|
||||
<property name="dataSource" value="java:jboss/datasources/KeycloakDS"/>
|
||||
<property name="initializeEmpty" value="true"/>
|
||||
<property name="migrationStrategy" value="update"/>
|
||||
<property name="migrationExport" value="${jboss.home.dir}/keycloak-database-update.sql"/>
|
||||
</properties>
|
||||
</provider>
|
||||
</spi>
|
||||
<spi name="realmCache">
|
||||
<provider name="default" enabled="true"/>
|
||||
</spi>
|
||||
<spi name="connectionsInfinispan">
|
||||
<default-provider>default</default-provider>
|
||||
<provider name="default" enabled="true">
|
||||
<properties>
|
||||
<property name="cacheContainer" value="java:jboss/infinispan/container/keycloak"/>
|
||||
</properties>
|
||||
</provider>
|
||||
</spi>
|
||||
<spi name="jta-lookup">
|
||||
<default-provider>${keycloak.jta.lookup.provider:jboss}</default-provider>
|
||||
<provider name="jboss" enabled="true"/>
|
||||
</spi>
|
||||
<spi name="publicKeyStorage">
|
||||
<provider name="infinispan" enabled="true">
|
||||
<properties>
|
||||
<property name="minTimeBetweenRequests" value="10"/>
|
||||
</properties>
|
||||
</provider>
|
||||
</spi>
|
||||
<spi name="x509cert-lookup">
|
||||
<default-provider>${keycloak.x509cert.lookup.provider:default}</default-provider>
|
||||
<provider name="default" enabled="true"/>
|
||||
</spi>
|
||||
<spi name="hostname">
|
||||
<default-provider>default</default-provider>
|
||||
<provider name="default" enabled="true">
|
||||
<properties>
|
||||
<property name="frontendUrl" value="{{ keycloak_modcluster.frontend_url }}"/>
|
||||
<property name="forceBackendUrlToFrontendUrl" value="true"/>
|
||||
</properties>
|
||||
</provider>
|
||||
</spi>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:mail:4.0">
|
||||
<mail-session name="default" jndi-name="java:jboss/mail/Default">
|
||||
<smtp-server outbound-socket-binding-ref="mail-smtp"/>
|
||||
</mail-session>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:wildfly:metrics:1.0" security-enabled="false" exposed-subsystems="*" prefix="${wildfly.metrics.prefix:jboss}"/>
|
||||
{% if keycloak_modcluster.enabled %}
|
||||
<subsystem xmlns="urn:jboss:domain:modcluster:5.0">
|
||||
<proxy name="default" advertise="false" listener="ajp" proxies="proxy1">
|
||||
<dynamic-load-provider>
|
||||
<load-metric type="cpu"/>
|
||||
</dynamic-load-provider>
|
||||
</proxy>
|
||||
</subsystem>
|
||||
{% endif %}
|
||||
<subsystem xmlns="urn:jboss:domain:naming:2.0">
|
||||
<remote-naming/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:remoting:4.0">
|
||||
<http-connector name="http-remoting-connector" connector-ref="default" security-realm="ApplicationRealm"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:request-controller:1.0"/>
|
||||
<subsystem xmlns="urn:jboss:domain:security:2.0">
|
||||
<security-domains>
|
||||
<security-domain name="other" cache-type="default">
|
||||
<authentication>
|
||||
<login-module code="Remoting" flag="optional">
|
||||
<module-option name="password-stacking" value="useFirstPass"/>
|
||||
</login-module>
|
||||
<login-module code="RealmDirect" flag="required">
|
||||
<module-option name="password-stacking" value="useFirstPass"/>
|
||||
</login-module>
|
||||
</authentication>
|
||||
</security-domain>
|
||||
<security-domain name="jboss-web-policy" cache-type="default">
|
||||
<authorization>
|
||||
<policy-module code="Delegating" flag="required"/>
|
||||
</authorization>
|
||||
</security-domain>
|
||||
<security-domain name="jaspitest" cache-type="default">
|
||||
<authentication-jaspi>
|
||||
<login-module-stack name="dummy">
|
||||
<login-module code="Dummy" flag="optional"/>
|
||||
</login-module-stack>
|
||||
<auth-module code="Dummy"/>
|
||||
</authentication-jaspi>
|
||||
</security-domain>
|
||||
<security-domain name="jboss-ejb-policy" cache-type="default">
|
||||
<authorization>
|
||||
<policy-module code="Delegating" flag="required"/>
|
||||
</authorization>
|
||||
</security-domain>
|
||||
</security-domains>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:security-manager:1.0">
|
||||
<deployment-permissions>
|
||||
<maximum-set>
|
||||
<permission class="java.security.AllPermission"/>
|
||||
</maximum-set>
|
||||
</deployment-permissions>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:transactions:6.0">
|
||||
<core-environment node-identifier="{{ inventory_hostname | default('${jboss.tx.node.id:1}') }}">
|
||||
<process-id>
|
||||
<uuid/>
|
||||
</process-id>
|
||||
</core-environment>
|
||||
<recovery-environment socket-binding="txn-recovery-environment" status-socket-binding="txn-status-manager"/>
|
||||
<coordinator-environment statistics-enabled="${wildfly.transactions.statistics-enabled:${wildfly.statistics-enabled:false}}"/>
|
||||
<object-store path="tx-object-store" relative-to="jboss.server.data.dir"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:undertow:12.0" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other" statistics-enabled="${wildfly.undertow.statistics-enabled:${wildfly.statistics-enabled:false}}">
|
||||
<buffer-cache name="default"/>
|
||||
<server name="default-server">
|
||||
<ajp-listener name="ajp" socket-binding="ajp"/>
|
||||
<http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true" proxy-address-forwarding="true"/>
|
||||
<https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/>
|
||||
<host name="default-host" alias="localhost">
|
||||
<location name="/" handler="welcome-content"/>
|
||||
<http-invoker security-realm="ApplicationRealm"/>
|
||||
<filter-ref name="proxy-peer"/>
|
||||
</host>
|
||||
</server>
|
||||
<servlet-container name="default">
|
||||
<jsp-config/>
|
||||
<websockets/>
|
||||
</servlet-container>
|
||||
<handlers>
|
||||
<file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
|
||||
</handlers>
|
||||
<filters>
|
||||
<filter name="proxy-peer" module="io.undertow.core"
|
||||
class-name="io.undertow.server.handlers.ProxyPeerAddressHandler"/>
|
||||
</filters>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:weld:4.0"/>
|
||||
</profile>
|
||||
<interfaces>
|
||||
<interface name="management">
|
||||
<inet-address value="{{ keycloak_management_port_bind_address }}"/>
|
||||
</interface>
|
||||
<interface name="jgroups">
|
||||
{% if ansible_default_ipv4 is defined %}
|
||||
<subnet-match value="{{ (ansible_default_ipv4.network + '/' + ansible_default_ipv4.netmask) | ansible.utils.ipaddr('net') }}"/>
|
||||
{% else %}
|
||||
<any-address />
|
||||
{% endif %}
|
||||
</interface>
|
||||
<interface name="public">
|
||||
<inet-address value="{{ keycloak_bind_address }}"/>
|
||||
</interface>
|
||||
</interfaces>
|
||||
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
|
||||
<socket-binding name="ajp" port="{{ keycloak_ajp_port }}"/>
|
||||
<socket-binding name="http" port="{{ keycloak_http_port }}"/>
|
||||
<socket-binding name="https" port="{{ keycloak_https_port }}"/>
|
||||
<socket-binding name="management-http" interface="management" port="{{ keycloak_management_http_port }}"/>
|
||||
<socket-binding name="management-https" interface="management" port="{{ keycloak_management_https_port }}"/>
|
||||
<socket-binding name="jgroups-tcp" interface="jgroups" port="{{ keycloak_jgroups_port }}"/>
|
||||
<socket-binding name="txn-recovery-environment" port="4712"/>
|
||||
<socket-binding name="txn-status-manager" port="4713"/>
|
||||
<outbound-socket-binding name="mail-smtp">
|
||||
<remote-destination host="${jboss.mail.server.host:localhost}" port="${jboss.mail.server.port:25}"/>
|
||||
</outbound-socket-binding>
|
||||
{% if keycloak_modcluster.enabled %}
|
||||
<outbound-socket-binding name="proxy1">
|
||||
<remote-destination host="{{ keycloak_modcluster.reverse_proxy_url | default('localhost') }}" port="6666"/>
|
||||
</outbound-socket-binding>
|
||||
{% endif %}
|
||||
<outbound-socket-binding name="remote-cache">
|
||||
<remote-destination host="{{ keycloak_remotecache.server_name | default('localhost') }}" port="${remote.cache.port:11222}"/>
|
||||
</outbound-socket-binding>
|
||||
</socket-binding-group>
|
||||
</server>
|
||||
658
roles/keycloak/templates/15.0.8/standalone.xml.j2
Normal file
658
roles/keycloak/templates/15.0.8/standalone.xml.j2
Normal file
@@ -0,0 +1,658 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!-- {{ ansible_managed }} -->
|
||||
<server xmlns="urn:jboss:domain:16.0">
|
||||
<extensions>
|
||||
<extension module="org.jboss.as.clustering.infinispan"/>
|
||||
<extension module="org.jboss.as.connector"/>
|
||||
<extension module="org.jboss.as.deployment-scanner"/>
|
||||
<extension module="org.jboss.as.ee"/>
|
||||
<extension module="org.jboss.as.ejb3"/>
|
||||
<extension module="org.jboss.as.jaxrs"/>
|
||||
<extension module="org.jboss.as.jmx"/>
|
||||
<extension module="org.jboss.as.jpa"/>
|
||||
<extension module="org.jboss.as.logging"/>
|
||||
<extension module="org.jboss.as.mail"/>
|
||||
<extension module="org.jboss.as.modcluster"/>
|
||||
<extension module="org.jboss.as.naming"/>
|
||||
<extension module="org.jboss.as.remoting"/>
|
||||
<extension module="org.jboss.as.security"/>
|
||||
<extension module="org.jboss.as.transactions"/>
|
||||
<extension module="org.jboss.as.weld"/>
|
||||
<extension module="org.keycloak.keycloak-server-subsystem"/>
|
||||
<extension module="org.wildfly.extension.bean-validation"/>
|
||||
<extension module="org.wildfly.extension.core-management"/>
|
||||
<extension module="org.wildfly.extension.elytron"/>
|
||||
<extension module="org.wildfly.extension.health"/>
|
||||
<extension module="org.wildfly.extension.io"/>
|
||||
<extension module="org.wildfly.extension.metrics"/>
|
||||
<extension module="org.wildfly.extension.request-controller"/>
|
||||
<extension module="org.wildfly.extension.security.manager"/>
|
||||
<extension module="org.wildfly.extension.undertow"/>
|
||||
</extensions>
|
||||
<management>
|
||||
<security-realms>
|
||||
<security-realm name="ManagementRealm">
|
||||
<authentication>
|
||||
<local default-user="$local" skip-group-loading="true"/>
|
||||
<properties path="mgmt-users.properties" relative-to="jboss.server.config.dir"/>
|
||||
</authentication>
|
||||
<authorization map-groups-to-roles="false">
|
||||
<properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
|
||||
</authorization>
|
||||
</security-realm>
|
||||
<security-realm name="ApplicationRealm">
|
||||
<server-identities>
|
||||
<ssl>
|
||||
<keystore path="application.keystore" relative-to="jboss.server.config.dir" keystore-password="password" alias="server" key-password="password" generate-self-signed-certificate-host="localhost"/>
|
||||
</ssl>
|
||||
</server-identities>
|
||||
<authentication>
|
||||
<local default-user="$local" allowed-users="*" skip-group-loading="true"/>
|
||||
<properties path="application-users.properties" relative-to="jboss.server.config.dir"/>
|
||||
</authentication>
|
||||
<authorization>
|
||||
<properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
|
||||
</authorization>
|
||||
</security-realm>
|
||||
</security-realms>
|
||||
<audit-log>
|
||||
<formatters>
|
||||
<json-formatter name="json-formatter"/>
|
||||
</formatters>
|
||||
<handlers>
|
||||
<file-handler name="file" formatter="json-formatter" path="audit-log.log" relative-to="jboss.server.data.dir"/>
|
||||
</handlers>
|
||||
<logger log-boot="true" log-read-only="false" enabled="false">
|
||||
<handlers>
|
||||
<handler name="file"/>
|
||||
</handlers>
|
||||
</logger>
|
||||
</audit-log>
|
||||
<management-interfaces>
|
||||
<http-interface security-realm="ManagementRealm">
|
||||
<http-upgrade enabled="true"/>
|
||||
<socket-binding http="management-http"/>
|
||||
</http-interface>
|
||||
</management-interfaces>
|
||||
<access-control provider="simple">
|
||||
<role-mapping>
|
||||
<role name="SuperUser">
|
||||
<include>
|
||||
<user name="$local"/>
|
||||
</include>
|
||||
</role>
|
||||
</role-mapping>
|
||||
</access-control>
|
||||
</management>
|
||||
<profile>
|
||||
<subsystem xmlns="urn:jboss:domain:logging:8.0">
|
||||
<console-handler name="CONSOLE">
|
||||
<level name="INFO"/>
|
||||
<formatter>
|
||||
<named-formatter name="COLOR-PATTERN"/>
|
||||
</formatter>
|
||||
</console-handler>
|
||||
<periodic-rotating-file-handler name="FILE" autoflush="true">
|
||||
<formatter>
|
||||
<named-formatter name="PATTERN"/>
|
||||
</formatter>
|
||||
<file relative-to="jboss.server.log.dir" path="server.log"/>
|
||||
<suffix value=".yyyy-MM-dd"/>
|
||||
<append value="true"/>
|
||||
</periodic-rotating-file-handler>
|
||||
<logger category="com.arjuna">
|
||||
<level name="WARN"/>
|
||||
</logger>
|
||||
<logger category="io.jaegertracing.Configuration">
|
||||
<level name="WARN"/>
|
||||
</logger>
|
||||
<logger category="org.jboss.as.config">
|
||||
<level name="DEBUG"/>
|
||||
</logger>
|
||||
<logger category="sun.rmi">
|
||||
<level name="WARN"/>
|
||||
</logger>
|
||||
<root-logger>
|
||||
<level name="INFO"/>
|
||||
<handlers>
|
||||
<handler name="CONSOLE"/>
|
||||
<handler name="FILE"/>
|
||||
</handlers>
|
||||
</root-logger>
|
||||
<formatter name="PATTERN">
|
||||
<pattern-formatter pattern="%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
|
||||
</formatter>
|
||||
<formatter name="COLOR-PATTERN">
|
||||
<pattern-formatter pattern="%K{level}%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
|
||||
</formatter>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:bean-validation:1.0"/>
|
||||
<subsystem xmlns="urn:jboss:domain:core-management:1.0"/>
|
||||
<subsystem xmlns="urn:jboss:domain:datasources:6.0">
|
||||
<datasources>
|
||||
<datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true" statistics-enabled="${wildfly.datasources.statistics-enabled:${wildfly.statistics-enabled:false}}">
|
||||
<connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url>
|
||||
<driver>h2</driver>
|
||||
<security>
|
||||
<user-name>sa</user-name>
|
||||
<password>sa</password>
|
||||
</security>
|
||||
</datasource>
|
||||
<datasource jndi-name="java:jboss/datasources/KeycloakDS" pool-name="KeycloakDS" enabled="true" use-java-context="true" statistics-enabled="${wildfly.datasources.statistics-enabled:${wildfly.statistics-enabled:false}}">
|
||||
{% if keycloak_jdbc[keycloak_jdbc_engine].enabled %}
|
||||
<connection-url>{{ keycloak_jdbc[keycloak_jdbc_engine].connection_url }}</connection-url>
|
||||
<driver>{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_name }}</driver>
|
||||
<pool>
|
||||
<max-pool-size>20</max-pool-size>
|
||||
</pool>
|
||||
<security>
|
||||
<user-name>{{ keycloak_jdbc[keycloak_jdbc_engine].db_user }}</user-name>
|
||||
<password>{{ keycloak_jdbc[keycloak_jdbc_engine].db_password }}</password>
|
||||
</security>
|
||||
{% else %}
|
||||
<connection-url>jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE</connection-url>
|
||||
<driver>h2</driver>
|
||||
<security>
|
||||
<user-name>sa</user-name>
|
||||
<password>sa</password>
|
||||
</security>
|
||||
{% endif %}
|
||||
</datasource>
|
||||
<drivers>
|
||||
{% if keycloak_jdbc[keycloak_jdbc_engine].enabled %}
|
||||
<driver name="{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_name }}" module="{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_name }}">
|
||||
<driver-class>{{ keycloak_jdbc[keycloak_jdbc_engine].driver_class }}</driver-class>
|
||||
<xa-datasource-class>{{ keycloak_jdbc[keycloak_jdbc_engine].xa_datasource_class }}</xa-datasource-class>
|
||||
</driver>
|
||||
{% endif %}
|
||||
<driver name="h2" module="com.h2database.h2">
|
||||
<xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
|
||||
</driver>
|
||||
</drivers>
|
||||
</datasources>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:deployment-scanner:2.0">
|
||||
<deployment-scanner path="deployments" relative-to="jboss.server.base.dir" scan-interval="5000" runtime-failure-causes-rollback="${jboss.deployment.scanner.rollback.on.failure:false}"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:ee:6.0">
|
||||
<spec-descriptor-property-replacement>false</spec-descriptor-property-replacement>
|
||||
<concurrent>
|
||||
<context-services>
|
||||
<context-service name="default" jndi-name="java:jboss/ee/concurrency/context/default" use-transaction-setup-provider="true"/>
|
||||
</context-services>
|
||||
<managed-thread-factories>
|
||||
<managed-thread-factory name="default" jndi-name="java:jboss/ee/concurrency/factory/default" context-service="default"/>
|
||||
</managed-thread-factories>
|
||||
<managed-executor-services>
|
||||
<managed-executor-service name="default" jndi-name="java:jboss/ee/concurrency/executor/default" context-service="default" hung-task-termination-period="0" hung-task-threshold="60000" keepalive-time="5000"/>
|
||||
</managed-executor-services>
|
||||
<managed-scheduled-executor-services>
|
||||
<managed-scheduled-executor-service name="default" jndi-name="java:jboss/ee/concurrency/scheduler/default" context-service="default" hung-task-termination-period="0" hung-task-threshold="60000" keepalive-time="3000"/>
|
||||
</managed-scheduled-executor-services>
|
||||
</concurrent>
|
||||
<default-bindings context-service="java:jboss/ee/concurrency/context/default" datasource="java:jboss/datasources/ExampleDS" managed-executor-service="java:jboss/ee/concurrency/executor/default" managed-scheduled-executor-service="java:jboss/ee/concurrency/scheduler/default" managed-thread-factory="java:jboss/ee/concurrency/factory/default"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:ejb3:9.0">
|
||||
<session-bean>
|
||||
<stateless>
|
||||
<bean-instance-pool-ref pool-name="slsb-strict-max-pool"/>
|
||||
</stateless>
|
||||
<stateful default-access-timeout="5000" cache-ref="simple" passivation-disabled-cache-ref="simple"/>
|
||||
<singleton default-access-timeout="5000"/>
|
||||
</session-bean>
|
||||
<pools>
|
||||
<bean-instance-pools>
|
||||
<strict-max-pool name="mdb-strict-max-pool" derive-size="from-cpu-count" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
|
||||
<strict-max-pool name="slsb-strict-max-pool" derive-size="from-worker-pools" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
|
||||
</bean-instance-pools>
|
||||
</pools>
|
||||
<caches>
|
||||
<cache name="simple"/>
|
||||
<cache name="distributable" passivation-store-ref="infinispan" aliases="passivating clustered"/>
|
||||
</caches>
|
||||
<passivation-stores>
|
||||
<passivation-store name="infinispan" cache-container="ejb" max-size="10000"/>
|
||||
</passivation-stores>
|
||||
<async thread-pool-name="default"/>
|
||||
<timer-service thread-pool-name="default" default-data-store="default-file-store">
|
||||
<data-stores>
|
||||
<file-data-store name="default-file-store" path="timer-service-data" relative-to="jboss.server.data.dir"/>
|
||||
</data-stores>
|
||||
</timer-service>
|
||||
<remote cluster="ejb" connectors="http-remoting-connector" thread-pool-name="default">
|
||||
<channel-creation-options>
|
||||
<option name="MAX_OUTBOUND_MESSAGES" value="1234" type="remoting"/>
|
||||
</channel-creation-options>
|
||||
</remote>
|
||||
<thread-pools>
|
||||
<thread-pool name="default">
|
||||
<max-threads count="10"/>
|
||||
<keepalive-time time="60" unit="seconds"/>
|
||||
</thread-pool>
|
||||
</thread-pools>
|
||||
<default-security-domain value="other"/>
|
||||
<default-missing-method-permissions-deny-access value="true"/>
|
||||
<statistics enabled="${wildfly.ejb3.statistics-enabled:${wildfly.statistics-enabled:false}}"/>
|
||||
<log-system-exceptions value="true"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:wildfly:elytron:13.0" final-providers="combined-providers" disallowed-providers="OracleUcrypto">
|
||||
<providers>
|
||||
<aggregate-providers name="combined-providers">
|
||||
<providers name="elytron"/>
|
||||
<providers name="openssl"/>
|
||||
</aggregate-providers>
|
||||
<provider-loader name="elytron" module="org.wildfly.security.elytron"/>
|
||||
<provider-loader name="openssl" module="org.wildfly.openssl"/>
|
||||
</providers>
|
||||
<audit-logging>
|
||||
<file-audit-log name="local-audit" path="audit.log" relative-to="jboss.server.log.dir" format="JSON"/>
|
||||
</audit-logging>
|
||||
<security-domains>
|
||||
<security-domain name="ApplicationDomain" default-realm="ApplicationRealm" permission-mapper="default-permission-mapper">
|
||||
<realm name="ApplicationRealm" role-decoder="groups-to-roles"/>
|
||||
<realm name="local"/>
|
||||
</security-domain>
|
||||
<security-domain name="ManagementDomain" default-realm="ManagementRealm" permission-mapper="default-permission-mapper">
|
||||
<realm name="ManagementRealm" role-decoder="groups-to-roles"/>
|
||||
<realm name="local" role-mapper="super-user-mapper"/>
|
||||
</security-domain>
|
||||
</security-domains>
|
||||
<security-realms>
|
||||
<identity-realm name="local" identity="$local"/>
|
||||
<properties-realm name="ApplicationRealm">
|
||||
<users-properties path="application-users.properties" relative-to="jboss.server.config.dir" digest-realm-name="ApplicationRealm"/>
|
||||
<groups-properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
|
||||
</properties-realm>
|
||||
<properties-realm name="ManagementRealm">
|
||||
<users-properties path="mgmt-users.properties" relative-to="jboss.server.config.dir" digest-realm-name="ManagementRealm"/>
|
||||
<groups-properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
|
||||
</properties-realm>
|
||||
</security-realms>
|
||||
<mappers>
|
||||
<simple-permission-mapper name="default-permission-mapper" mapping-mode="first">
|
||||
<permission-mapping>
|
||||
<principal name="anonymous"/>
|
||||
<permission-set name="default-permissions"/>
|
||||
</permission-mapping>
|
||||
<permission-mapping match-all="true">
|
||||
<permission-set name="login-permission"/>
|
||||
<permission-set name="default-permissions"/>
|
||||
</permission-mapping>
|
||||
</simple-permission-mapper>
|
||||
<constant-realm-mapper name="local" realm-name="local"/>
|
||||
<simple-role-decoder name="groups-to-roles" attribute="groups"/>
|
||||
<constant-role-mapper name="super-user-mapper">
|
||||
<role name="SuperUser"/>
|
||||
</constant-role-mapper>
|
||||
</mappers>
|
||||
<permission-sets>
|
||||
<permission-set name="login-permission">
|
||||
<permission class-name="org.wildfly.security.auth.permission.LoginPermission"/>
|
||||
</permission-set>
|
||||
<permission-set name="default-permissions">
|
||||
<permission class-name="org.wildfly.extension.batch.jberet.deployment.BatchPermission" module="org.wildfly.extension.batch.jberet" target-name="*"/>
|
||||
<permission class-name="org.wildfly.transaction.client.RemoteTransactionPermission" module="org.wildfly.transaction.client"/>
|
||||
<permission class-name="org.jboss.ejb.client.RemoteEJBPermission" module="org.jboss.ejb-client"/>
|
||||
<permission class-name="org.jboss.ejb.client.RemoteEJBPermission" module="org.jboss.ejb-client"/>
|
||||
</permission-set>
|
||||
</permission-sets>
|
||||
<http>
|
||||
<http-authentication-factory name="management-http-authentication" security-domain="ManagementDomain" http-server-mechanism-factory="global">
|
||||
<mechanism-configuration>
|
||||
<mechanism mechanism-name="DIGEST">
|
||||
<mechanism-realm realm-name="ManagementRealm"/>
|
||||
</mechanism>
|
||||
</mechanism-configuration>
|
||||
</http-authentication-factory>
|
||||
<provider-http-server-mechanism-factory name="global"/>
|
||||
</http>
|
||||
<sasl>
|
||||
<sasl-authentication-factory name="application-sasl-authentication" sasl-server-factory="configured" security-domain="ApplicationDomain">
|
||||
<mechanism-configuration>
|
||||
<mechanism mechanism-name="JBOSS-LOCAL-USER" realm-mapper="local"/>
|
||||
<mechanism mechanism-name="DIGEST-MD5">
|
||||
<mechanism-realm realm-name="ApplicationRealm"/>
|
||||
</mechanism>
|
||||
</mechanism-configuration>
|
||||
</sasl-authentication-factory>
|
||||
<sasl-authentication-factory name="management-sasl-authentication" sasl-server-factory="configured" security-domain="ManagementDomain">
|
||||
<mechanism-configuration>
|
||||
<mechanism mechanism-name="JBOSS-LOCAL-USER" realm-mapper="local"/>
|
||||
<mechanism mechanism-name="DIGEST-MD5">
|
||||
<mechanism-realm realm-name="ManagementRealm"/>
|
||||
</mechanism>
|
||||
</mechanism-configuration>
|
||||
</sasl-authentication-factory>
|
||||
<configurable-sasl-server-factory name="configured" sasl-server-factory="elytron">
|
||||
<properties>
|
||||
<property name="wildfly.sasl.local-user.default-user" value="$local"/>
|
||||
</properties>
|
||||
</configurable-sasl-server-factory>
|
||||
<mechanism-provider-filtering-sasl-server-factory name="elytron" sasl-server-factory="global">
|
||||
<filters>
|
||||
<filter provider-name="WildFlyElytron"/>
|
||||
</filters>
|
||||
</mechanism-provider-filtering-sasl-server-factory>
|
||||
<provider-sasl-server-factory name="global"/>
|
||||
</sasl>
|
||||
<tls>
|
||||
<key-stores>
|
||||
<key-store name="applicationKS">
|
||||
<credential-reference clear-text="password"/>
|
||||
<implementation type="JKS"/>
|
||||
<file path="application.keystore" relative-to="jboss.server.config.dir"/>
|
||||
</key-store>
|
||||
</key-stores>
|
||||
<key-managers>
|
||||
<key-manager name="applicationKM" key-store="applicationKS" generate-self-signed-certificate-host="localhost">
|
||||
<credential-reference clear-text="password"/>
|
||||
</key-manager>
|
||||
</key-managers>
|
||||
<server-ssl-contexts>
|
||||
<server-ssl-context name="applicationSSC" key-manager="applicationKM"/>
|
||||
</server-ssl-contexts>
|
||||
</tls>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:wildfly:health:1.0" security-enabled="false"/>
|
||||
<subsystem xmlns="urn:jboss:domain:infinispan:12.0">
|
||||
<cache-container name="ejb" default-cache="passivation" aliases="sfsb" modules="org.wildfly.clustering.ejb.infinispan">
|
||||
<local-cache name="passivation">
|
||||
<locking isolation="REPEATABLE_READ"/>
|
||||
<transaction mode="BATCH"/>
|
||||
<file-store passivation="true" purge="false"/>
|
||||
</local-cache>
|
||||
</cache-container>
|
||||
<cache-container name="keycloak" modules="org.keycloak.keycloak-model-infinispan">
|
||||
<local-cache name="realms">
|
||||
<heap-memory size="10000"/>
|
||||
</local-cache>
|
||||
<local-cache name="users">
|
||||
<heap-memory size="10000"/>
|
||||
</local-cache>
|
||||
<local-cache name="sessions"/>
|
||||
<local-cache name="authenticationSessions"/>
|
||||
<local-cache name="offlineSessions"/>
|
||||
<local-cache name="clientSessions"/>
|
||||
<local-cache name="offlineClientSessions"/>
|
||||
<local-cache name="loginFailures"/>
|
||||
<local-cache name="work"/>
|
||||
<local-cache name="authorization">
|
||||
<heap-memory size="10000"/>
|
||||
</local-cache>
|
||||
<local-cache name="keys">
|
||||
<heap-memory size="1000"/>
|
||||
<expiration max-idle="3600000"/>
|
||||
</local-cache>
|
||||
<local-cache name="actionTokens">
|
||||
<heap-memory size="-1"/>
|
||||
<expiration interval="300000" max-idle="-1"/>
|
||||
</local-cache>
|
||||
</cache-container>
|
||||
<cache-container name="server" default-cache="default" modules="org.wildfly.clustering.server">
|
||||
<local-cache name="default">
|
||||
<transaction mode="BATCH"/>
|
||||
</local-cache>
|
||||
</cache-container>
|
||||
<cache-container name="web" default-cache="passivation" modules="org.wildfly.clustering.web.infinispan">
|
||||
<local-cache name="passivation">
|
||||
<locking isolation="REPEATABLE_READ"/>
|
||||
<transaction mode="BATCH"/>
|
||||
<file-store passivation="true" purge="false"/>
|
||||
</local-cache>
|
||||
<local-cache name="sso">
|
||||
<locking isolation="REPEATABLE_READ"/>
|
||||
<transaction mode="BATCH"/>
|
||||
</local-cache>
|
||||
<local-cache name="routing"/>
|
||||
</cache-container>
|
||||
<cache-container name="hibernate" modules="org.infinispan.hibernate-cache">
|
||||
<local-cache name="entity">
|
||||
<heap-memory size="10000"/>
|
||||
<expiration max-idle="100000"/>
|
||||
</local-cache>
|
||||
<local-cache name="local-query">
|
||||
<heap-memory size="10000"/>
|
||||
<expiration max-idle="100000"/>
|
||||
</local-cache>
|
||||
<local-cache name="timestamps"/>
|
||||
</cache-container>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:io:3.0">
|
||||
<worker name="default"/>
|
||||
<buffer-pool name="default"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:jaxrs:2.0"/>
|
||||
<subsystem xmlns="urn:jboss:domain:jca:5.0">
|
||||
<archive-validation enabled="true" fail-on-error="true" fail-on-warn="false"/>
|
||||
<bean-validation enabled="true"/>
|
||||
<default-workmanager>
|
||||
<short-running-threads>
|
||||
<core-threads count="50"/>
|
||||
<queue-length count="50"/>
|
||||
<max-threads count="50"/>
|
||||
<keepalive-time time="10" unit="seconds"/>
|
||||
</short-running-threads>
|
||||
<long-running-threads>
|
||||
<core-threads count="50"/>
|
||||
<queue-length count="50"/>
|
||||
<max-threads count="50"/>
|
||||
<keepalive-time time="10" unit="seconds"/>
|
||||
</long-running-threads>
|
||||
</default-workmanager>
|
||||
<cached-connection-manager/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:jmx:1.3">
|
||||
<expose-resolved-model/>
|
||||
<expose-expression-model/>
|
||||
<remoting-connector/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:jpa:1.1">
|
||||
<jpa default-extended-persistence-inheritance="DEEP"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:keycloak-server:1.1">
|
||||
<web-context>auth</web-context>
|
||||
<providers>
|
||||
<provider>
|
||||
classpath:${jboss.home.dir}/providers/*
|
||||
</provider>
|
||||
</providers>
|
||||
<master-realm-name>master</master-realm-name>
|
||||
<scheduled-task-interval>900</scheduled-task-interval>
|
||||
<theme>
|
||||
<staticMaxAge>2592000</staticMaxAge>
|
||||
<cacheThemes>true</cacheThemes>
|
||||
<cacheTemplates>true</cacheTemplates>
|
||||
<dir>${jboss.home.dir}/themes</dir>
|
||||
</theme>
|
||||
{% if keycloak_ha_enabled %}
|
||||
<spi name="dblock">
|
||||
<provider name="jpa" enabled="true">
|
||||
<properties>
|
||||
<property name="lockWaitTimeout" value="900"/>
|
||||
</properties>
|
||||
</provider>
|
||||
</spi>
|
||||
{% endif %}
|
||||
<spi name="eventsStore">
|
||||
<provider name="jpa" enabled="true">
|
||||
<properties>
|
||||
<property name="exclude-events" value="["REFRESH_TOKEN"]"/>
|
||||
</properties>
|
||||
</provider>
|
||||
</spi>
|
||||
<spi name="userCache">
|
||||
<provider name="default" enabled="true"/>
|
||||
</spi>
|
||||
<spi name="userSessionPersister">
|
||||
<default-provider>jpa</default-provider>
|
||||
</spi>
|
||||
<spi name="timer">
|
||||
<default-provider>basic</default-provider>
|
||||
</spi>
|
||||
<spi name="connectionsHttpClient">
|
||||
<provider name="default" enabled="true"/>
|
||||
</spi>
|
||||
<spi name="connectionsJpa">
|
||||
<provider name="default" enabled="true">
|
||||
<properties>
|
||||
<property name="dataSource" value="java:jboss/datasources/KeycloakDS"/>
|
||||
<property name="initializeEmpty" value="true"/>
|
||||
<property name="migrationStrategy" value="update"/>
|
||||
<property name="migrationExport" value="${jboss.home.dir}/keycloak-database-update.sql"/>
|
||||
</properties>
|
||||
</provider>
|
||||
</spi>
|
||||
<spi name="realmCache">
|
||||
<provider name="default" enabled="true"/>
|
||||
</spi>
|
||||
<spi name="connectionsInfinispan">
|
||||
<default-provider>default</default-provider>
|
||||
<provider name="default" enabled="true">
|
||||
<properties>
|
||||
<property name="cacheContainer" value="java:jboss/infinispan/container/keycloak"/>
|
||||
</properties>
|
||||
</provider>
|
||||
</spi>
|
||||
<spi name="jta-lookup">
|
||||
<default-provider>${keycloak.jta.lookup.provider:jboss}</default-provider>
|
||||
<provider name="jboss" enabled="true"/>
|
||||
</spi>
|
||||
<spi name="publicKeyStorage">
|
||||
<provider name="infinispan" enabled="true">
|
||||
<properties>
|
||||
<property name="minTimeBetweenRequests" value="10"/>
|
||||
</properties>
|
||||
</provider>
|
||||
</spi>
|
||||
<spi name="x509cert-lookup">
|
||||
<default-provider>${keycloak.x509cert.lookup.provider:default}</default-provider>
|
||||
<provider name="default" enabled="true"/>
|
||||
</spi>
|
||||
<spi name="hostname">
|
||||
<default-provider>default</default-provider>
|
||||
<provider name="default" enabled="true">
|
||||
<properties>
|
||||
<property name="frontendUrl" value="{{ keycloak_modcluster.frontend_url }}"/>
|
||||
<property name="forceBackendUrlToFrontendUrl" value="true"/>
|
||||
</properties>
|
||||
</provider>
|
||||
</spi>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:mail:4.0">
|
||||
<mail-session name="default" jndi-name="java:jboss/mail/Default">
|
||||
<smtp-server outbound-socket-binding-ref="mail-smtp"/>
|
||||
</mail-session>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:wildfly:metrics:1.0" security-enabled="false" exposed-subsystems="*" prefix="${wildfly.metrics.prefix:jboss}"/>
|
||||
{% if keycloak_modcluster.enabled %}
|
||||
<subsystem xmlns="urn:jboss:domain:modcluster:5.0">
|
||||
<proxy name="default" advertise="false" listener="ajp" proxies="proxy1">
|
||||
<dynamic-load-provider>
|
||||
<load-metric type="cpu"/>
|
||||
</dynamic-load-provider>
|
||||
</proxy>
|
||||
</subsystem>
|
||||
{% endif %}
|
||||
<subsystem xmlns="urn:jboss:domain:naming:2.0">
|
||||
<remote-naming/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:remoting:4.0">
|
||||
<http-connector name="http-remoting-connector" connector-ref="default" security-realm="ApplicationRealm"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:request-controller:1.0"/>
|
||||
<subsystem xmlns="urn:jboss:domain:security:2.0">
|
||||
<security-domains>
|
||||
<security-domain name="other" cache-type="default">
|
||||
<authentication>
|
||||
<login-module code="Remoting" flag="optional">
|
||||
<module-option name="password-stacking" value="useFirstPass"/>
|
||||
</login-module>
|
||||
<login-module code="RealmDirect" flag="required">
|
||||
<module-option name="password-stacking" value="useFirstPass"/>
|
||||
</login-module>
|
||||
</authentication>
|
||||
</security-domain>
|
||||
<security-domain name="jboss-web-policy" cache-type="default">
|
||||
<authorization>
|
||||
<policy-module code="Delegating" flag="required"/>
|
||||
</authorization>
|
||||
</security-domain>
|
||||
<security-domain name="jaspitest" cache-type="default">
|
||||
<authentication-jaspi>
|
||||
<login-module-stack name="dummy">
|
||||
<login-module code="Dummy" flag="optional"/>
|
||||
</login-module-stack>
|
||||
<auth-module code="Dummy"/>
|
||||
</authentication-jaspi>
|
||||
</security-domain>
|
||||
<security-domain name="jboss-ejb-policy" cache-type="default">
|
||||
<authorization>
|
||||
<policy-module code="Delegating" flag="required"/>
|
||||
</authorization>
|
||||
</security-domain>
|
||||
</security-domains>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:security-manager:1.0">
|
||||
<deployment-permissions>
|
||||
<maximum-set>
|
||||
<permission class="java.security.AllPermission"/>
|
||||
</maximum-set>
|
||||
</deployment-permissions>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:transactions:6.0">
|
||||
<core-environment node-identifier="${jboss.tx.node.id:1}">
|
||||
<process-id>
|
||||
<uuid/>
|
||||
</process-id>
|
||||
</core-environment>
|
||||
<recovery-environment socket-binding="txn-recovery-environment" status-socket-binding="txn-status-manager"/>
|
||||
<coordinator-environment statistics-enabled="${wildfly.transactions.statistics-enabled:${wildfly.statistics-enabled:false}}"/>
|
||||
<object-store path="tx-object-store" relative-to="jboss.server.data.dir"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:undertow:12.0" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other" statistics-enabled="${wildfly.undertow.statistics-enabled:${wildfly.statistics-enabled:false}}">
|
||||
<buffer-cache name="default"/>
|
||||
<server name="default-server">
|
||||
<ajp-listener name="ajp" socket-binding="ajp"/>
|
||||
<http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/>
|
||||
<https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/>
|
||||
<host name="default-host" alias="localhost">
|
||||
<location name="/" handler="welcome-content"/>
|
||||
<http-invoker security-realm="ApplicationRealm"/>
|
||||
</host>
|
||||
</server>
|
||||
<servlet-container name="default">
|
||||
<jsp-config/>
|
||||
<websockets/>
|
||||
</servlet-container>
|
||||
<handlers>
|
||||
<file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
|
||||
</handlers>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:weld:4.0"/>
|
||||
</profile>
|
||||
<interfaces>
|
||||
<interface name="management">
|
||||
<inet-address value="{{ keycloak_management_port_bind_address }}"/>
|
||||
</interface>
|
||||
<interface name="public">
|
||||
<inet-address value="{{ keycloak_bind_address }}"/>
|
||||
</interface>
|
||||
</interfaces>
|
||||
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
|
||||
<socket-binding name="ajp" port="{{ keycloak_ajp_port }}"/>
|
||||
<socket-binding name="http" port="{{ keycloak_http_port }}"/>
|
||||
<socket-binding name="https" port="{{ keycloak_https_port }}"/>
|
||||
<socket-binding name="management-http" interface="management" port="{{ keycloak_management_http_port }}"/>
|
||||
<socket-binding name="management-https" interface="management" port="{{ keycloak_management_https_port }}"/>
|
||||
<socket-binding name="txn-recovery-environment" port="4712"/>
|
||||
<socket-binding name="txn-status-manager" port="4713"/>
|
||||
<outbound-socket-binding name="mail-smtp">
|
||||
<remote-destination host="${jboss.mail.server.host:localhost}" port="${jboss.mail.server.port:25}"/>
|
||||
</outbound-socket-binding>
|
||||
{% if keycloak_modcluster.enabled %}
|
||||
<outbound-socket-binding name="proxy1">
|
||||
<remote-destination host="{{ keycloak_modcluster.reverse_proxy_url | default('localhost') }}" port="6666"/>
|
||||
</outbound-socket-binding>
|
||||
{% endif %}
|
||||
</socket-binding-group>
|
||||
</server>
|
||||
@@ -725,7 +725,7 @@
|
||||
</interface>
|
||||
<interface name="jgroups">
|
||||
{% if ansible_default_ipv4 is defined %}
|
||||
<subnet-match value="{{ (ansible_default_ipv4.network + '/' + ansible_default_ipv4.netmask) | ipaddr('net') }}"/>
|
||||
<subnet-match value="{{ (ansible_default_ipv4.network + '/' + ansible_default_ipv4.netmask) | ansible.utils.ipaddr('net') }}"/>
|
||||
{% else %}
|
||||
<any-address />
|
||||
{% endif %}
|
||||
|
||||
10
roles/keycloak/templates/jdbc_driver_module.xml.j2
Normal file
10
roles/keycloak/templates/jdbc_driver_module.xml.j2
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module xmlns="urn:jboss:module:1.0" name="{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_name }}">
|
||||
<resources>
|
||||
<resource-root path="{{ keycloak_jdbc[keycloak_jdbc_engine].driver_jar_filename }}"/>
|
||||
</resources>
|
||||
<dependencies>
|
||||
<module name="javax.api"/>
|
||||
<module name="javax.transaction.api"/>
|
||||
</dependencies>
|
||||
</module>
|
||||
3
roles/keycloak/templates/keycloak-profile.properties.j2
Normal file
3
roles/keycloak/templates/keycloak-profile.properties.j2
Normal file
@@ -0,0 +1,3 @@
|
||||
{% for feature in keycloak.features %}
|
||||
feature.{{ feature.name }}={{ feature.status | default('enabled') }}
|
||||
{% endfor %}
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 }}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
# {{ ansible_managed }}
|
||||
[Unit]
|
||||
Description=Keycloak Server
|
||||
Description={{ keycloak.service_name }} Server
|
||||
After=network.target
|
||||
StartLimitIntervalSec={{ keycloak_service_startlimitintervalsec }}
|
||||
StartLimitBurst={{ keycloak_service_startlimitburst }}
|
||||
|
||||
|
||||
[Service]
|
||||
Type=forking
|
||||
@@ -12,6 +15,12 @@ ExecStop={{ keycloak_dest }}/keycloak-service.sh stop
|
||||
TimeoutStartSec=30
|
||||
TimeoutStopSec=30
|
||||
LimitNOFILE=102642
|
||||
{% if keycloak_service_restart_always %}
|
||||
Restart=always
|
||||
{% elif keycloak_service_restart_on_failure %}
|
||||
Restart=on-failure
|
||||
{% endif %}
|
||||
RestartSec={{ keycloak_service_restartsec }}
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
707
roles/keycloak/templates/standalone-ha.xml.j2
Normal file
707
roles/keycloak/templates/standalone-ha.xml.j2
Normal file
@@ -0,0 +1,707 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!-- {{ ansible_managed }} -->
|
||||
<server xmlns="urn:jboss:domain:16.0">
|
||||
<extensions>
|
||||
<extension module="org.jboss.as.clustering.infinispan"/>
|
||||
<extension module="org.jboss.as.clustering.jgroups"/>
|
||||
<extension module="org.jboss.as.connector"/>
|
||||
<extension module="org.jboss.as.deployment-scanner"/>
|
||||
<extension module="org.jboss.as.ee"/>
|
||||
<extension module="org.jboss.as.ejb3"/>
|
||||
<extension module="org.jboss.as.jaxrs"/>
|
||||
<extension module="org.jboss.as.jmx"/>
|
||||
<extension module="org.jboss.as.jpa"/>
|
||||
<extension module="org.jboss.as.logging"/>
|
||||
<extension module="org.jboss.as.mail"/>
|
||||
<extension module="org.jboss.as.modcluster"/>
|
||||
<extension module="org.jboss.as.naming"/>
|
||||
<extension module="org.jboss.as.remoting"/>
|
||||
<extension module="org.jboss.as.transactions"/>
|
||||
<extension module="org.jboss.as.weld"/>
|
||||
<extension module="org.keycloak.keycloak-server-subsystem"/>
|
||||
<extension module="org.wildfly.extension.bean-validation"/>
|
||||
<extension module="org.wildfly.extension.core-management"/>
|
||||
<extension module="org.wildfly.extension.elytron"/>
|
||||
<extension module="org.wildfly.extension.health"/>
|
||||
<extension module="org.wildfly.extension.io"/>
|
||||
<extension module="org.wildfly.extension.metrics"/>
|
||||
<extension module="org.wildfly.extension.request-controller"/>
|
||||
<extension module="org.wildfly.extension.security.manager"/>
|
||||
<extension module="org.wildfly.extension.undertow"/>
|
||||
</extensions>
|
||||
<management>
|
||||
<audit-log>
|
||||
<formatters>
|
||||
<json-formatter name="json-formatter"/>
|
||||
</formatters>
|
||||
<handlers>
|
||||
<file-handler name="file" formatter="json-formatter" path="audit-log.log" relative-to="jboss.server.data.dir"/>
|
||||
</handlers>
|
||||
<logger log-boot="true" log-read-only="false" enabled="false">
|
||||
<handlers>
|
||||
<handler name="file"/>
|
||||
</handlers>
|
||||
</logger>
|
||||
</audit-log>
|
||||
<management-interfaces>
|
||||
<http-interface http-authentication-factory="management-http-authentication">
|
||||
<http-upgrade enabled="true" sasl-authentication-factory="management-sasl-authentication"/>
|
||||
<socket-binding http="management-http"/>
|
||||
</http-interface>
|
||||
</management-interfaces>
|
||||
<access-control provider="simple">
|
||||
<role-mapping>
|
||||
<role name="SuperUser">
|
||||
<include>
|
||||
<user name="$local"/>
|
||||
</include>
|
||||
</role>
|
||||
</role-mapping>
|
||||
</access-control>
|
||||
</management>
|
||||
<profile>
|
||||
<subsystem xmlns="urn:jboss:domain:logging:8.0">
|
||||
<console-handler name="CONSOLE">
|
||||
<level name="INFO"/>
|
||||
<formatter>
|
||||
<named-formatter name="COLOR-PATTERN"/>
|
||||
</formatter>
|
||||
</console-handler>
|
||||
<periodic-rotating-file-handler name="FILE" autoflush="true">
|
||||
<formatter>
|
||||
<named-formatter name="PATTERN"/>
|
||||
</formatter>
|
||||
<file relative-to="jboss.server.log.dir" path="server.log"/>
|
||||
<suffix value=".yyyy-MM-dd"/>
|
||||
<append value="true"/>
|
||||
</periodic-rotating-file-handler>
|
||||
<logger category="com.arjuna">
|
||||
<level name="WARN"/>
|
||||
</logger>
|
||||
<logger category="io.jaegertracing.Configuration">
|
||||
<level name="WARN"/>
|
||||
</logger>
|
||||
<logger category="org.jboss.as.config">
|
||||
<level name="DEBUG"/>
|
||||
</logger>
|
||||
<logger category="sun.rmi">
|
||||
<level name="WARN"/>
|
||||
</logger>
|
||||
<logger category="org.keycloak.cluster.infinispan">
|
||||
<level name="INFO"/>
|
||||
</logger>
|
||||
<logger category="org.keycloak.connections.infinispan">
|
||||
<level name="INFO"/>
|
||||
</logger>
|
||||
<logger category="org.keycloak.models.cache.infinispan">
|
||||
<level name="INFO"/>
|
||||
</logger>
|
||||
<logger category="org.keycloak.models.sessions.infinispan">
|
||||
<level name="INFO"/>
|
||||
</logger>
|
||||
<root-logger>
|
||||
<level name="INFO"/>
|
||||
<handlers>
|
||||
<handler name="CONSOLE"/>
|
||||
<handler name="FILE"/>
|
||||
</handlers>
|
||||
</root-logger>
|
||||
<formatter name="PATTERN">
|
||||
<pattern-formatter pattern="%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
|
||||
</formatter>
|
||||
<formatter name="COLOR-PATTERN">
|
||||
<pattern-formatter pattern="%K{level}%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
|
||||
</formatter>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:bean-validation:1.0"/>
|
||||
<subsystem xmlns="urn:jboss:domain:core-management:1.0"/>
|
||||
<subsystem xmlns="urn:jboss:domain:datasources:6.0">
|
||||
<datasources>
|
||||
<datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true" statistics-enabled="${wildfly.datasources.statistics-enabled:${wildfly.statistics-enabled:false}}">
|
||||
<connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url>
|
||||
<driver>h2</driver>
|
||||
<security>
|
||||
<user-name>sa</user-name>
|
||||
<password>sa</password>
|
||||
</security>
|
||||
</datasource>
|
||||
<datasource jndi-name="java:jboss/datasources/KeycloakDS" pool-name="KeycloakDS" enabled="true" use-java-context="true" statistics-enabled="${wildfly.datasources.statistics-enabled:${wildfly.statistics-enabled:false}}">
|
||||
{% if keycloak_jdbc[keycloak_jdbc_engine].enabled %}
|
||||
<connection-url>{{ keycloak_jdbc[keycloak_jdbc_engine].connection_url }}</connection-url>
|
||||
<driver>{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_name }}</driver>
|
||||
<pool>
|
||||
<max-pool-size>20</max-pool-size>
|
||||
</pool>
|
||||
<security>
|
||||
<user-name>{{ keycloak_jdbc[keycloak_jdbc_engine].db_user }}</user-name>
|
||||
<password>{{ keycloak_jdbc[keycloak_jdbc_engine].db_password }}</password>
|
||||
</security>
|
||||
<validation>
|
||||
<check-valid-connection-sql>{{ keycloak_jdbc[keycloak_jdbc_engine].validate_query }}</check-valid-connection-sql>
|
||||
<validate-on-match>{{ keycloak_db_background_validate_on_match }}</validate-on-match>
|
||||
{% if keycloak_db_background_validation_millis | int > 0 or keycloak_db_background_validation %}
|
||||
<background-validation>{{ keycloak_db_background_validation }}</background-validation>
|
||||
<background-validation-millis>{{ keycloak_db_background_validation_millis }}</background-validation-millis>
|
||||
{% endif %}
|
||||
</validation>
|
||||
{% else %}
|
||||
<connection-url>jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE</connection-url>
|
||||
<driver>h2</driver>
|
||||
<security>
|
||||
<user-name>sa</user-name>
|
||||
<password>sa</password>
|
||||
</security>
|
||||
{% endif %}
|
||||
</datasource>
|
||||
<drivers>
|
||||
{% if keycloak_jdbc[keycloak_jdbc_engine].enabled %}
|
||||
<driver name="{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_name }}" module="{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_name }}">
|
||||
<driver-class>{{ keycloak_jdbc[keycloak_jdbc_engine].driver_class }}</driver-class>
|
||||
<xa-datasource-class>{{ keycloak_jdbc[keycloak_jdbc_engine].xa_datasource_class }}</xa-datasource-class>
|
||||
</driver>
|
||||
{% endif %}
|
||||
<driver name="h2" module="com.h2database.h2">
|
||||
<xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
|
||||
</driver>
|
||||
</drivers>
|
||||
</datasources>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:deployment-scanner:2.0">
|
||||
<deployment-scanner path="deployments" relative-to="jboss.server.base.dir" scan-interval="5000" runtime-failure-causes-rollback="${jboss.deployment.scanner.rollback.on.failure:false}"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:ee:6.0">
|
||||
<spec-descriptor-property-replacement>false</spec-descriptor-property-replacement>
|
||||
<concurrent>
|
||||
<context-services>
|
||||
<context-service name="default" jndi-name="java:jboss/ee/concurrency/context/default" use-transaction-setup-provider="true"/>
|
||||
</context-services>
|
||||
<managed-thread-factories>
|
||||
<managed-thread-factory name="default" jndi-name="java:jboss/ee/concurrency/factory/default" context-service="default"/>
|
||||
</managed-thread-factories>
|
||||
<managed-executor-services>
|
||||
<managed-executor-service name="default" jndi-name="java:jboss/ee/concurrency/executor/default" context-service="default" hung-task-termination-period="0" hung-task-threshold="60000" keepalive-time="5000"/>
|
||||
</managed-executor-services>
|
||||
<managed-scheduled-executor-services>
|
||||
<managed-scheduled-executor-service name="default" jndi-name="java:jboss/ee/concurrency/scheduler/default" context-service="default" hung-task-termination-period="0" hung-task-threshold="60000" keepalive-time="3000"/>
|
||||
</managed-scheduled-executor-services>
|
||||
</concurrent>
|
||||
<default-bindings context-service="java:jboss/ee/concurrency/context/default" datasource="java:jboss/datasources/ExampleDS" managed-executor-service="java:jboss/ee/concurrency/executor/default" managed-scheduled-executor-service="java:jboss/ee/concurrency/scheduler/default" managed-thread-factory="java:jboss/ee/concurrency/factory/default"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:ejb3:9.0">
|
||||
<session-bean>
|
||||
<stateless>
|
||||
<bean-instance-pool-ref pool-name="slsb-strict-max-pool"/>
|
||||
</stateless>
|
||||
<stateful default-access-timeout="5000" cache-ref="distributable" passivation-disabled-cache-ref="simple"/>
|
||||
<singleton default-access-timeout="5000"/>
|
||||
</session-bean>
|
||||
<pools>
|
||||
<bean-instance-pools>
|
||||
<strict-max-pool name="mdb-strict-max-pool" derive-size="from-cpu-count" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
|
||||
<strict-max-pool name="slsb-strict-max-pool" derive-size="from-worker-pools" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
|
||||
</bean-instance-pools>
|
||||
</pools>
|
||||
<caches>
|
||||
<cache name="simple"/>
|
||||
<cache name="distributable" passivation-store-ref="infinispan" aliases="passivating clustered"/>
|
||||
</caches>
|
||||
<passivation-stores>
|
||||
<passivation-store name="infinispan" cache-container="ejb" max-size="10000"/>
|
||||
</passivation-stores>
|
||||
<async thread-pool-name="default"/>
|
||||
<timer-service thread-pool-name="default" default-data-store="default-file-store">
|
||||
<data-stores>
|
||||
<file-data-store name="default-file-store" path="timer-service-data" relative-to="jboss.server.data.dir"/>
|
||||
</data-stores>
|
||||
</timer-service>
|
||||
<remote cluster="ejb" connectors="http-remoting-connector" thread-pool-name="default">
|
||||
<channel-creation-options>
|
||||
<option name="MAX_OUTBOUND_MESSAGES" value="1234" type="remoting"/>
|
||||
</channel-creation-options>
|
||||
</remote>
|
||||
<thread-pools>
|
||||
<thread-pool name="default">
|
||||
<max-threads count="10"/>
|
||||
<keepalive-time time="60" unit="seconds"/>
|
||||
</thread-pool>
|
||||
</thread-pools>
|
||||
<default-security-domain value="other"/>
|
||||
<application-security-domains>
|
||||
<application-security-domain name="other" security-domain="ApplicationDomain"/>
|
||||
</application-security-domains>
|
||||
<default-missing-method-permissions-deny-access value="true"/>
|
||||
<statistics enabled="${wildfly.ejb3.statistics-enabled:${wildfly.statistics-enabled:false}}"/>
|
||||
<log-system-exceptions value="true"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:wildfly:elytron:13.0" final-providers="combined-providers" disallowed-providers="OracleUcrypto">
|
||||
<providers>
|
||||
<aggregate-providers name="combined-providers">
|
||||
<providers name="elytron"/>
|
||||
<providers name="openssl"/>
|
||||
</aggregate-providers>
|
||||
<provider-loader name="elytron" module="org.wildfly.security.elytron"/>
|
||||
<provider-loader name="openssl" module="org.wildfly.openssl"/>
|
||||
</providers>
|
||||
<audit-logging>
|
||||
<file-audit-log name="local-audit" path="audit.log" relative-to="jboss.server.log.dir" format="JSON"/>
|
||||
</audit-logging>
|
||||
<security-domains>
|
||||
<security-domain name="ApplicationDomain" default-realm="ApplicationRealm" permission-mapper="default-permission-mapper">
|
||||
<realm name="ApplicationRealm" role-decoder="groups-to-roles"/>
|
||||
<realm name="local"/>
|
||||
</security-domain>
|
||||
<security-domain name="ManagementDomain" default-realm="ManagementRealm" permission-mapper="default-permission-mapper">
|
||||
<realm name="ManagementRealm" role-decoder="groups-to-roles"/>
|
||||
<realm name="local" role-mapper="super-user-mapper"/>
|
||||
</security-domain>
|
||||
</security-domains>
|
||||
<security-realms>
|
||||
<identity-realm name="local" identity="$local"/>
|
||||
<properties-realm name="ApplicationRealm">
|
||||
<users-properties path="application-users.properties" relative-to="jboss.server.config.dir" digest-realm-name="ApplicationRealm"/>
|
||||
<groups-properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
|
||||
</properties-realm>
|
||||
<properties-realm name="ManagementRealm">
|
||||
<users-properties path="mgmt-users.properties" relative-to="jboss.server.config.dir" digest-realm-name="ManagementRealm"/>
|
||||
<groups-properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
|
||||
</properties-realm>
|
||||
</security-realms>
|
||||
<mappers>
|
||||
<simple-permission-mapper name="default-permission-mapper" mapping-mode="first">
|
||||
<permission-mapping>
|
||||
<principal name="anonymous"/>
|
||||
<permission-set name="default-permissions"/>
|
||||
</permission-mapping>
|
||||
<permission-mapping match-all="true">
|
||||
<permission-set name="login-permission"/>
|
||||
<permission-set name="default-permissions"/>
|
||||
</permission-mapping>
|
||||
</simple-permission-mapper>
|
||||
<constant-realm-mapper name="local" realm-name="local"/>
|
||||
<simple-role-decoder name="groups-to-roles" attribute="groups"/>
|
||||
<constant-role-mapper name="super-user-mapper">
|
||||
<role name="SuperUser"/>
|
||||
</constant-role-mapper>
|
||||
</mappers>
|
||||
<permission-sets>
|
||||
<permission-set name="login-permission">
|
||||
<permission class-name="org.wildfly.security.auth.permission.LoginPermission"/>
|
||||
</permission-set>
|
||||
<permission-set name="default-permissions">
|
||||
<permission class-name="org.wildfly.extension.batch.jberet.deployment.BatchPermission" module="org.wildfly.extension.batch.jberet" target-name="*"/>
|
||||
<permission class-name="org.wildfly.transaction.client.RemoteTransactionPermission" module="org.wildfly.transaction.client"/>
|
||||
<permission class-name="org.jboss.ejb.client.RemoteEJBPermission" module="org.jboss.ejb-client"/>
|
||||
<permission class-name="org.jboss.ejb.client.RemoteEJBPermission" module="org.jboss.ejb-client"/>
|
||||
</permission-set>
|
||||
</permission-sets>
|
||||
<http>
|
||||
<http-authentication-factory name="management-http-authentication" security-domain="ManagementDomain" http-server-mechanism-factory="global">
|
||||
<mechanism-configuration>
|
||||
<mechanism mechanism-name="DIGEST">
|
||||
<mechanism-realm realm-name="ManagementRealm"/>
|
||||
</mechanism>
|
||||
</mechanism-configuration>
|
||||
</http-authentication-factory>
|
||||
<http-authentication-factory name="application-http-authentication" security-domain="ApplicationDomain" http-server-mechanism-factory="global">
|
||||
<mechanism-configuration>
|
||||
<mechanism mechanism-name="BASIC">
|
||||
<mechanism-realm realm-name="ApplicationRealm"/>
|
||||
</mechanism>
|
||||
</mechanism-configuration>
|
||||
</http-authentication-factory>
|
||||
<provider-http-server-mechanism-factory name="global"/>
|
||||
</http>
|
||||
<sasl>
|
||||
<sasl-authentication-factory name="application-sasl-authentication" sasl-server-factory="configured" security-domain="ApplicationDomain">
|
||||
<mechanism-configuration>
|
||||
<mechanism mechanism-name="JBOSS-LOCAL-USER" realm-mapper="local"/>
|
||||
<mechanism mechanism-name="DIGEST-MD5">
|
||||
<mechanism-realm realm-name="ApplicationRealm"/>
|
||||
</mechanism>
|
||||
</mechanism-configuration>
|
||||
</sasl-authentication-factory>
|
||||
<sasl-authentication-factory name="management-sasl-authentication" sasl-server-factory="configured" security-domain="ManagementDomain">
|
||||
<mechanism-configuration>
|
||||
<mechanism mechanism-name="JBOSS-LOCAL-USER" realm-mapper="local"/>
|
||||
<mechanism mechanism-name="DIGEST-MD5">
|
||||
<mechanism-realm realm-name="ManagementRealm"/>
|
||||
</mechanism>
|
||||
</mechanism-configuration>
|
||||
</sasl-authentication-factory>
|
||||
<configurable-sasl-server-factory name="configured" sasl-server-factory="elytron">
|
||||
<properties>
|
||||
<property name="wildfly.sasl.local-user.default-user" value="$local"/>
|
||||
</properties>
|
||||
</configurable-sasl-server-factory>
|
||||
<mechanism-provider-filtering-sasl-server-factory name="elytron" sasl-server-factory="global">
|
||||
<filters>
|
||||
<filter provider-name="WildFlyElytron"/>
|
||||
</filters>
|
||||
</mechanism-provider-filtering-sasl-server-factory>
|
||||
<provider-sasl-server-factory name="global"/>
|
||||
</sasl>
|
||||
<tls>
|
||||
<key-stores>
|
||||
<key-store name="applicationKS">
|
||||
<credential-reference clear-text="password"/>
|
||||
<implementation type="JKS"/>
|
||||
<file path="application.keystore" relative-to="jboss.server.config.dir"/>
|
||||
</key-store>
|
||||
</key-stores>
|
||||
<key-managers>
|
||||
<key-manager name="applicationKM" key-store="applicationKS" generate-self-signed-certificate-host="localhost">
|
||||
<credential-reference clear-text="password"/>
|
||||
</key-manager>
|
||||
</key-managers>
|
||||
<server-ssl-contexts>
|
||||
<server-ssl-context name="applicationSSC" key-manager="applicationKM"/>
|
||||
</server-ssl-contexts>
|
||||
</tls>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:wildfly:health:1.0" security-enabled="false"/>
|
||||
<subsystem xmlns="urn:jboss:domain:infinispan:12.0">
|
||||
<cache-container name="ejb" default-cache="dist" aliases="sfsb" modules="org.wildfly.clustering.ejb.infinispan">
|
||||
<transport lock-timeout="60000"/>
|
||||
<distributed-cache name="dist">
|
||||
<locking isolation="REPEATABLE_READ"/>
|
||||
<transaction mode="BATCH"/>
|
||||
<file-store/>
|
||||
</distributed-cache>
|
||||
</cache-container>
|
||||
<cache-container name="keycloak">
|
||||
<transport lock-timeout="60000"/>
|
||||
<local-cache name="realms">
|
||||
<heap-memory size="10000"/>
|
||||
</local-cache>
|
||||
<local-cache name="users">
|
||||
<heap-memory size="10000"/>
|
||||
</local-cache>
|
||||
<replicated-cache name="work"/>
|
||||
<distributed-cache name="sessions" owners="2"/>
|
||||
<distributed-cache name="authenticationSessions" owners="2"/>
|
||||
<distributed-cache name="offlineSessions" owners="2"/>
|
||||
<distributed-cache name="clientSessions" owners="2"/>
|
||||
<distributed-cache name="offlineClientSessions" owners="2"/>
|
||||
<distributed-cache name="loginFailures" owners="2"/>
|
||||
<distributed-cache name="actionTokens" owners="2">
|
||||
<expiration interval="300000" max-idle="-1"/>
|
||||
</distributed-cache>
|
||||
<local-cache name="authorization">
|
||||
<heap-memory size="10000"/>
|
||||
</local-cache>
|
||||
<local-cache name="keys">
|
||||
<heap-memory size="1000"/>
|
||||
<expiration max-idle="3600000"/>
|
||||
</local-cache>
|
||||
</cache-container>
|
||||
<cache-container name="server" default-cache="default" aliases="singleton cluster" modules="org.wildfly.clustering.server">
|
||||
<transport lock-timeout="60000"/>
|
||||
<replicated-cache name="default">
|
||||
<transaction mode="BATCH"/>
|
||||
</replicated-cache>
|
||||
</cache-container>
|
||||
<cache-container name="web" default-cache="dist" modules="org.wildfly.clustering.web.infinispan">
|
||||
<transport lock-timeout="60000"/>
|
||||
<replicated-cache name="sso">
|
||||
<locking isolation="REPEATABLE_READ"/>
|
||||
<transaction mode="BATCH"/>
|
||||
</replicated-cache>
|
||||
<distributed-cache name="dist">
|
||||
<locking isolation="REPEATABLE_READ"/>
|
||||
<transaction mode="BATCH"/>
|
||||
<file-store/>
|
||||
</distributed-cache>
|
||||
<distributed-cache name="routing"/>
|
||||
</cache-container>
|
||||
<cache-container name="hibernate" modules="org.infinispan.hibernate-cache">
|
||||
<transport lock-timeout="60000"/>
|
||||
<local-cache name="local-query">
|
||||
<heap-memory size="10000"/>
|
||||
<expiration max-idle="100000"/>
|
||||
</local-cache>
|
||||
<invalidation-cache name="entity">
|
||||
<transaction mode="NON_XA"/>
|
||||
<heap-memory size="10000"/>
|
||||
<expiration max-idle="100000"/>
|
||||
</invalidation-cache>
|
||||
<replicated-cache name="timestamps"/>
|
||||
</cache-container>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:io:3.0">
|
||||
<worker name="default"/>
|
||||
<buffer-pool name="default"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:jaxrs:2.0"/>
|
||||
<subsystem xmlns="urn:jboss:domain:jca:5.0">
|
||||
<archive-validation enabled="true" fail-on-error="true" fail-on-warn="false"/>
|
||||
<bean-validation enabled="true"/>
|
||||
<default-workmanager>
|
||||
<short-running-threads>
|
||||
<core-threads count="50"/>
|
||||
<queue-length count="50"/>
|
||||
<max-threads count="50"/>
|
||||
<keepalive-time time="10" unit="seconds"/>
|
||||
</short-running-threads>
|
||||
<long-running-threads>
|
||||
<core-threads count="50"/>
|
||||
<queue-length count="50"/>
|
||||
<max-threads count="50"/>
|
||||
<keepalive-time time="10" unit="seconds"/>
|
||||
</long-running-threads>
|
||||
</default-workmanager>
|
||||
<cached-connection-manager/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:jgroups:8.0">
|
||||
<channels default="ee">
|
||||
<channel name="ee" stack="tcp" cluster="ejb"/>
|
||||
</channels>
|
||||
<stacks>
|
||||
<stack name="tcp">
|
||||
<transport site="${jboss.node.name}" type="TCP" socket-binding="jgroups-tcp"/>
|
||||
{% if keycloak_ha_discovery == 'JDBC_PING' and keycloak_jdbc[keycloak_jdbc_engine].enabled %}
|
||||
<protocol type="JDBC_PING">
|
||||
<property name="datasource_jndi_name">java:jboss/datasources/KeycloakDS</property>
|
||||
<property name="initialize_sql">{{ keycloak_jdbc[keycloak_jdbc_engine].initialize_db }}</property>
|
||||
<property name="insert_single_sql">INSERT INTO JGROUPSPING (own_addr, cluster_name, ping_data) values (?, ?, ?)</property>
|
||||
<property name="delete_single_sql">DELETE FROM JGROUPSPING WHERE own_addr=? AND cluster_name=?</property>
|
||||
<property name="select_all_pingdata_sql">SELECT ping_data FROM JGROUPSPING WHERE cluster_name=?</property>
|
||||
</protocol>
|
||||
{% elif keycloak_ha_discovery == 'TCPPING' %}
|
||||
<protocol type="TCPPING">
|
||||
<property name="initial_hosts">{{ keycloak_cluster_nodes | map(attribute='inventory_host') | join (',') }}</property>
|
||||
<property name="port_range">0</property>
|
||||
<property name="timeout">3000</property>
|
||||
<property name="num_initial_members">2</property>
|
||||
</protocol>
|
||||
{% endif %}
|
||||
<protocol type="MERGE3"/>
|
||||
<protocol type="FD_SOCK"/>
|
||||
<protocol type="FD_ALL"/>
|
||||
<protocol type="VERIFY_SUSPECT"/>
|
||||
<protocol type="pbcast.NAKACK2"/>
|
||||
<protocol type="UNICAST3"/>
|
||||
<protocol type="pbcast.STABLE"/>
|
||||
<protocol type="pbcast.GMS">
|
||||
<property name="join_timeout">30000</property>
|
||||
</protocol>
|
||||
<protocol type="MFC"/>
|
||||
<protocol type="FRAG2"/>
|
||||
</stack>
|
||||
</stacks>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:jmx:1.3">
|
||||
<expose-resolved-model/>
|
||||
<expose-expression-model/>
|
||||
<remoting-connector/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:jpa:1.1">
|
||||
<jpa default-extended-persistence-inheritance="DEEP"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:keycloak-server:1.1">
|
||||
<web-context>auth</web-context>
|
||||
<providers>
|
||||
<provider>
|
||||
classpath:${jboss.home.dir}/providers/*
|
||||
</provider>
|
||||
</providers>
|
||||
<master-realm-name>master</master-realm-name>
|
||||
<scheduled-task-interval>900</scheduled-task-interval>
|
||||
<theme>
|
||||
<staticMaxAge>2592000</staticMaxAge>
|
||||
<cacheThemes>true</cacheThemes>
|
||||
<cacheTemplates>true</cacheTemplates>
|
||||
<dir>${jboss.home.dir}/themes</dir>
|
||||
</theme>
|
||||
{% if keycloak_ha_enabled %}
|
||||
<spi name="dblock">
|
||||
<provider name="jpa" enabled="true">
|
||||
<properties>
|
||||
<property name="lockWaitTimeout" value="900"/>
|
||||
</properties>
|
||||
</provider>
|
||||
</spi>
|
||||
{% endif %}
|
||||
<spi name="eventsStore">
|
||||
<provider name="jpa" enabled="true">
|
||||
<properties>
|
||||
<property name="exclude-events" value="["REFRESH_TOKEN"]"/>
|
||||
</properties>
|
||||
</provider>
|
||||
</spi>
|
||||
<spi name="userCache">
|
||||
<provider name="default" enabled="true"/>
|
||||
</spi>
|
||||
<spi name="userSessionPersister">
|
||||
<default-provider>jpa</default-provider>
|
||||
</spi>
|
||||
<spi name="timer">
|
||||
<default-provider>basic</default-provider>
|
||||
</spi>
|
||||
<spi name="connectionsHttpClient">
|
||||
<provider name="default" enabled="true"/>
|
||||
</spi>
|
||||
<spi name="connectionsJpa">
|
||||
<provider name="default" enabled="true">
|
||||
<properties>
|
||||
<property name="dataSource" value="java:jboss/datasources/KeycloakDS"/>
|
||||
<property name="initializeEmpty" value="true"/>
|
||||
<property name="migrationStrategy" value="update"/>
|
||||
<property name="migrationExport" value="${jboss.home.dir}/keycloak-database-update.sql"/>
|
||||
</properties>
|
||||
</provider>
|
||||
</spi>
|
||||
<spi name="realmCache">
|
||||
<provider name="default" enabled="true"/>
|
||||
</spi>
|
||||
<spi name="connectionsInfinispan">
|
||||
<default-provider>default</default-provider>
|
||||
<provider name="default" enabled="true">
|
||||
<properties>
|
||||
<property name="cacheContainer" value="java:jboss/infinispan/container/keycloak"/>
|
||||
</properties>
|
||||
</provider>
|
||||
</spi>
|
||||
<spi name="jta-lookup">
|
||||
<default-provider>${keycloak.jta.lookup.provider:jboss}</default-provider>
|
||||
<provider name="jboss" enabled="true"/>
|
||||
</spi>
|
||||
<spi name="publicKeyStorage">
|
||||
<provider name="infinispan" enabled="true">
|
||||
<properties>
|
||||
<property name="minTimeBetweenRequests" value="10"/>
|
||||
</properties>
|
||||
</provider>
|
||||
</spi>
|
||||
<spi name="x509cert-lookup">
|
||||
<default-provider>${keycloak.x509cert.lookup.provider:default}</default-provider>
|
||||
<provider name="default" enabled="true"/>
|
||||
</spi>
|
||||
<spi name="hostname">
|
||||
<default-provider>default</default-provider>
|
||||
<provider name="default" enabled="true">
|
||||
<properties>
|
||||
<property name="frontendUrl" value="{{ keycloak_modcluster.frontend_url }}"/>
|
||||
<property name="forceBackendUrlToFrontendUrl" value="{{ keycloak_modcluster.force_frontend_url }}"/>
|
||||
{% if keycloak_modcluster.admin_url | length > 0 %}
|
||||
<property name="adminUrl" value="{{ keycloak_modcluster.admin_url }}" />
|
||||
{% endif %}
|
||||
</properties>
|
||||
</provider>
|
||||
</spi>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:mail:4.0">
|
||||
<mail-session name="default" jndi-name="java:jboss/mail/Default">
|
||||
<smtp-server outbound-socket-binding-ref="mail-smtp"/>
|
||||
</mail-session>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:wildfly:metrics:1.0" security-enabled="false" exposed-subsystems="*" prefix="${wildfly.metrics.prefix:jboss}"/>
|
||||
{% if keycloak_modcluster.enabled %}
|
||||
<subsystem xmlns="urn:jboss:domain:modcluster:5.0">
|
||||
<proxy name="default" advertise="false" listener="ajp" proxies="{{ ['proxy_'] | product(keycloak_modcluster.reverse_proxy_urls | map(attribute='host')) | map('join') | list | join(' ') }}">
|
||||
<dynamic-load-provider>
|
||||
<load-metric type="cpu"/>
|
||||
</dynamic-load-provider>
|
||||
</proxy>
|
||||
</subsystem>
|
||||
{% endif %}
|
||||
<subsystem xmlns="urn:jboss:domain:naming:2.0">
|
||||
<remote-naming/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:remoting:4.0">
|
||||
<http-connector name="http-remoting-connector" connector-ref="default" sasl-authentication-factory="application-sasl-authentication"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:request-controller:1.0"/>
|
||||
<subsystem xmlns="urn:jboss:domain:security-manager:1.0">
|
||||
<deployment-permissions>
|
||||
<maximum-set>
|
||||
<permission class="java.security.AllPermission"/>
|
||||
</maximum-set>
|
||||
</deployment-permissions>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:transactions:6.0">
|
||||
<core-environment node-identifier="{{ inventory_hostname | default('${jboss.tx.node.id:1}') }}">
|
||||
<process-id>
|
||||
<uuid/>
|
||||
</process-id>
|
||||
</core-environment>
|
||||
<recovery-environment socket-binding="txn-recovery-environment" status-socket-binding="txn-status-manager"/>
|
||||
<coordinator-environment statistics-enabled="${wildfly.transactions.statistics-enabled:${wildfly.statistics-enabled:false}}"/>
|
||||
<object-store path="tx-object-store" relative-to="jboss.server.data.dir"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:undertow:12.0" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other" statistics-enabled="${wildfly.undertow.statistics-enabled:${wildfly.statistics-enabled:false}}">
|
||||
<buffer-cache name="default"/>
|
||||
<server name="default-server">
|
||||
<ajp-listener name="ajp" socket-binding="ajp"/>
|
||||
<http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true" proxy-address-forwarding="true"/>
|
||||
<https-listener name="https" socket-binding="https" ssl-context="applicationSSC" enable-http2="true"/>
|
||||
<host name="default-host" alias="localhost">
|
||||
<location name="/" handler="welcome-content"/>
|
||||
<http-invoker http-authentication-factory="application-http-authentication"/>
|
||||
<filter-ref name="proxy-peer"/>
|
||||
</host>
|
||||
</server>
|
||||
<servlet-container name="default">
|
||||
<jsp-config/>
|
||||
<websockets/>
|
||||
</servlet-container>
|
||||
<handlers>
|
||||
<file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
|
||||
</handlers>
|
||||
<application-security-domains>
|
||||
<application-security-domain name="other" security-domain="ApplicationDomain"/>
|
||||
</application-security-domains>
|
||||
<filters>
|
||||
<filter name="proxy-peer" module="io.undertow.core"
|
||||
class-name="io.undertow.server.handlers.ProxyPeerAddressHandler"/>
|
||||
</filters>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:weld:4.0"/>
|
||||
</profile>
|
||||
<interfaces>
|
||||
<interface name="management">
|
||||
<inet-address value="{{ keycloak_management_port_bind_address }}"/>
|
||||
</interface>
|
||||
<interface name="jgroups">
|
||||
{% if keycloak_jgroups_subnet is defined and keycloak_jgroups_subnet is not none and keycloak_jgroups_subnet | string | length > 0 %}
|
||||
<subnet-match value="{{ keycloak_jgroups_subnet | string }}"/>
|
||||
{% elif ansible_default_ipv4 is defined and (ansible_default_ipv4.network + '/' + ansible_default_ipv4.netmask) | ansible.utils.ipaddr('net') | length > 0 %}
|
||||
<subnet-match value="{{ (ansible_default_ipv4.network + '/' + ansible_default_ipv4.netmask) | ansible.utils.ipaddr('net') }}"/>
|
||||
{% else %}
|
||||
<any-address />
|
||||
{% endif %}
|
||||
</interface>
|
||||
<interface name="public">
|
||||
<inet-address value="{{ keycloak_bind_address }}"/>
|
||||
</interface>
|
||||
</interfaces>
|
||||
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
|
||||
<socket-binding name="ajp" port="{{ keycloak_ajp_port }}"/>
|
||||
<socket-binding name="http" port="{{ keycloak_http_port }}"/>
|
||||
<socket-binding name="https" port="{{ keycloak_https_port }}"/>
|
||||
<socket-binding name="management-http" interface="management" port="{{ keycloak_management_http_port }}"/>
|
||||
<socket-binding name="management-https" interface="management" port="{{ keycloak_management_https_port }}"/>
|
||||
<socket-binding name="jgroups-tcp" interface="jgroups" port="{{ keycloak_jgroups_port }}"/>
|
||||
<socket-binding name="txn-recovery-environment" port="4712"/>
|
||||
<socket-binding name="txn-status-manager" port="4713"/>
|
||||
<outbound-socket-binding name="mail-smtp">
|
||||
<remote-destination host="${jboss.mail.server.host:localhost}" port="${jboss.mail.server.port:25}"/>
|
||||
</outbound-socket-binding>
|
||||
{% if keycloak_modcluster.enabled %}
|
||||
{% for modcluster in keycloak_modcluster.reverse_proxy_urls %}
|
||||
<outbound-socket-binding name="proxy_{{ modcluster.host }}">
|
||||
<remote-destination host="{{ modcluster.host }}" port="{{ modcluster.port }}"/>
|
||||
</outbound-socket-binding>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if keycloak_ha_discovery == 'TCPPING' %}
|
||||
{% for node in keycloak_cluster_nodes %}
|
||||
<outbound-socket-binding name="jgroups_{{ node.address }}">
|
||||
<remote-destination host="{{ node.value }}" port="{{ keycloak_jgroups_port }}"/>
|
||||
</outbound-socket-binding>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
<outbound-socket-binding name="remote-cache">
|
||||
<remote-destination host="{{ keycloak_remotecache.server_name | default('localhost') }}" port="${remote.cache.port:11222}"/>
|
||||
</outbound-socket-binding>
|
||||
</socket-binding-group>
|
||||
</server>
|
||||
@@ -16,7 +16,6 @@
|
||||
<extension module="org.jboss.as.modcluster"/>
|
||||
<extension module="org.jboss.as.naming"/>
|
||||
<extension module="org.jboss.as.remoting"/>
|
||||
<extension module="org.jboss.as.security"/>
|
||||
<extension module="org.jboss.as.transactions"/>
|
||||
<extension module="org.jboss.as.weld"/>
|
||||
<extension module="org.keycloak.keycloak-server-subsystem"/>
|
||||
@@ -31,31 +30,6 @@
|
||||
<extension module="org.wildfly.extension.undertow"/>
|
||||
</extensions>
|
||||
<management>
|
||||
<security-realms>
|
||||
<security-realm name="ManagementRealm">
|
||||
<authentication>
|
||||
<local default-user="$local" skip-group-loading="true"/>
|
||||
<properties path="mgmt-users.properties" relative-to="jboss.server.config.dir"/>
|
||||
</authentication>
|
||||
<authorization map-groups-to-roles="false">
|
||||
<properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
|
||||
</authorization>
|
||||
</security-realm>
|
||||
<security-realm name="ApplicationRealm">
|
||||
<server-identities>
|
||||
<ssl>
|
||||
<keystore path="application.keystore" relative-to="jboss.server.config.dir" keystore-password="password" alias="server" key-password="password" generate-self-signed-certificate-host="localhost"/>
|
||||
</ssl>
|
||||
</server-identities>
|
||||
<authentication>
|
||||
<local default-user="$local" allowed-users="*" skip-group-loading="true"/>
|
||||
<properties path="application-users.properties" relative-to="jboss.server.config.dir"/>
|
||||
</authentication>
|
||||
<authorization>
|
||||
<properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
|
||||
</authorization>
|
||||
</security-realm>
|
||||
</security-realms>
|
||||
<audit-log>
|
||||
<formatters>
|
||||
<json-formatter name="json-formatter"/>
|
||||
@@ -70,8 +44,8 @@
|
||||
</logger>
|
||||
</audit-log>
|
||||
<management-interfaces>
|
||||
<http-interface security-realm="ManagementRealm">
|
||||
<http-upgrade enabled="true"/>
|
||||
<http-interface http-authentication-factory="management-http-authentication">
|
||||
<http-upgrade enabled="true" sasl-authentication-factory="management-sasl-authentication"/>
|
||||
<socket-binding http="management-http"/>
|
||||
</http-interface>
|
||||
</management-interfaces>
|
||||
@@ -162,6 +136,14 @@
|
||||
<user-name>{{ keycloak_jdbc[keycloak_jdbc_engine].db_user }}</user-name>
|
||||
<password>{{ keycloak_jdbc[keycloak_jdbc_engine].db_password }}</password>
|
||||
</security>
|
||||
<validation>
|
||||
<check-valid-connection-sql>{{ keycloak_jdbc[keycloak_jdbc_engine].validate_query }}</check-valid-connection-sql>
|
||||
<validate-on-match>{{ keycloak_db_background_validate_on_match }}</validate-on-match>
|
||||
{% if keycloak_db_background_validation_millis | int > 0 or keycloak_db_background_validation %}
|
||||
<background-validation>{{ keycloak_db_background_validation }}</background-validation>
|
||||
<background-validation-millis>{{ keycloak_db_background_validation_millis }}</background-validation-millis>
|
||||
{% endif %}
|
||||
</validation>
|
||||
{% else %}
|
||||
<connection-url>jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE</connection-url>
|
||||
<driver>h2</driver>
|
||||
@@ -244,6 +226,9 @@
|
||||
</thread-pool>
|
||||
</thread-pools>
|
||||
<default-security-domain value="other"/>
|
||||
<application-security-domains>
|
||||
<application-security-domain name="other" security-domain="ApplicationDomain"/>
|
||||
</application-security-domains>
|
||||
<default-missing-method-permissions-deny-access value="true"/>
|
||||
<statistics enabled="${wildfly.ejb3.statistics-enabled:${wildfly.statistics-enabled:false}}"/>
|
||||
<log-system-exceptions value="true"/>
|
||||
@@ -317,6 +302,13 @@
|
||||
</mechanism>
|
||||
</mechanism-configuration>
|
||||
</http-authentication-factory>
|
||||
<http-authentication-factory name="application-http-authentication" security-domain="ApplicationDomain" http-server-mechanism-factory="global">
|
||||
<mechanism-configuration>
|
||||
<mechanism mechanism-name="BASIC">
|
||||
<mechanism-realm realm-name="ApplicationRealm"/>
|
||||
</mechanism>
|
||||
</mechanism-configuration>
|
||||
</http-authentication-factory>
|
||||
<provider-http-server-mechanism-factory name="global"/>
|
||||
</http>
|
||||
<sasl>
|
||||
@@ -504,7 +496,7 @@
|
||||
<stacks>
|
||||
<stack name="tcp">
|
||||
<transport site="${jboss.node.name}" type="TCP" socket-binding="jgroups-tcp"/>
|
||||
{% if keycloak_jdbc[keycloak_jdbc_engine].enabled %}
|
||||
{% if keycloak_ha_discovery == 'JDBC_PING' and keycloak_jdbc[keycloak_jdbc_engine].enabled %}
|
||||
<protocol type="JDBC_PING">
|
||||
<property name="datasource_jndi_name">java:jboss/datasources/KeycloakDS</property>
|
||||
<property name="initialize_sql">{{ keycloak_jdbc[keycloak_jdbc_engine].initialize_db }}</property>
|
||||
@@ -512,6 +504,13 @@
|
||||
<property name="delete_single_sql">DELETE FROM JGROUPSPING WHERE own_addr=? AND cluster_name=?</property>
|
||||
<property name="select_all_pingdata_sql">SELECT ping_data FROM JGROUPSPING WHERE cluster_name=?</property>
|
||||
</protocol>
|
||||
{% elif keycloak_ha_discovery == 'TCPPING' %}
|
||||
<protocol type="TCPPING">
|
||||
<property name="initial_hosts">{{ keycloak_cluster_nodes | map(attribute='inventory_host') | join (',') }}</property>
|
||||
<property name="port_range">0</property>
|
||||
<property name="timeout">3000</property>
|
||||
<property name="num_initial_members">2</property>
|
||||
</protocol>
|
||||
{% endif %}
|
||||
<protocol type="MERGE3"/>
|
||||
<protocol type="FD_SOCK"/>
|
||||
@@ -620,7 +619,10 @@
|
||||
<provider name="default" enabled="true">
|
||||
<properties>
|
||||
<property name="frontendUrl" value="{{ keycloak_modcluster.frontend_url }}"/>
|
||||
<property name="forceBackendUrlToFrontendUrl" value="true"/>
|
||||
<property name="forceBackendUrlToFrontendUrl" value="{{ keycloak_modcluster.force_frontend_url }}"/>
|
||||
{% if keycloak_modcluster.admin_url | length > 0 %}
|
||||
<property name="adminUrl" value="{{ keycloak_modcluster.admin_url }}" />
|
||||
{% endif %}
|
||||
</properties>
|
||||
</provider>
|
||||
</spi>
|
||||
@@ -631,54 +633,22 @@
|
||||
</mail-session>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:wildfly:metrics:1.0" security-enabled="false" exposed-subsystems="*" prefix="${wildfly.metrics.prefix:jboss}"/>
|
||||
{% if keycloak_modcluster.enabled %}
|
||||
{% if keycloak_modcluster.enabled %}
|
||||
<subsystem xmlns="urn:jboss:domain:modcluster:5.0">
|
||||
<proxy name="default" advertise-socket="modcluster" listener="ajp" proxies="proxy1">
|
||||
<proxy name="default" advertise="false" listener="ajp" proxies="{{ ['proxy_'] | product(keycloak_modcluster.reverse_proxy_urls | map(attribute='host')) | map('join') | list | join(' ') }}">
|
||||
<dynamic-load-provider>
|
||||
<load-metric type="cpu"/>
|
||||
</dynamic-load-provider>
|
||||
</proxy>
|
||||
</subsystem>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<subsystem xmlns="urn:jboss:domain:naming:2.0">
|
||||
<remote-naming/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:remoting:4.0">
|
||||
<http-connector name="http-remoting-connector" connector-ref="default" security-realm="ApplicationRealm"/>
|
||||
<http-connector name="http-remoting-connector" connector-ref="default" sasl-authentication-factory="application-sasl-authentication"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:request-controller:1.0"/>
|
||||
<subsystem xmlns="urn:jboss:domain:security:2.0">
|
||||
<security-domains>
|
||||
<security-domain name="other" cache-type="default">
|
||||
<authentication>
|
||||
<login-module code="Remoting" flag="optional">
|
||||
<module-option name="password-stacking" value="useFirstPass"/>
|
||||
</login-module>
|
||||
<login-module code="RealmDirect" flag="required">
|
||||
<module-option name="password-stacking" value="useFirstPass"/>
|
||||
</login-module>
|
||||
</authentication>
|
||||
</security-domain>
|
||||
<security-domain name="jboss-web-policy" cache-type="default">
|
||||
<authorization>
|
||||
<policy-module code="Delegating" flag="required"/>
|
||||
</authorization>
|
||||
</security-domain>
|
||||
<security-domain name="jaspitest" cache-type="default">
|
||||
<authentication-jaspi>
|
||||
<login-module-stack name="dummy">
|
||||
<login-module code="Dummy" flag="optional"/>
|
||||
</login-module-stack>
|
||||
<auth-module code="Dummy"/>
|
||||
</authentication-jaspi>
|
||||
</security-domain>
|
||||
<security-domain name="jboss-ejb-policy" cache-type="default">
|
||||
<authorization>
|
||||
<policy-module code="Delegating" flag="required"/>
|
||||
</authorization>
|
||||
</security-domain>
|
||||
</security-domains>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:security-manager:1.0">
|
||||
<deployment-permissions>
|
||||
<maximum-set>
|
||||
@@ -701,10 +671,10 @@
|
||||
<server name="default-server">
|
||||
<ajp-listener name="ajp" socket-binding="ajp"/>
|
||||
<http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true" proxy-address-forwarding="true"/>
|
||||
<https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/>
|
||||
<https-listener name="https" socket-binding="https" ssl-context="applicationSSC" enable-http2="true"/>
|
||||
<host name="default-host" alias="localhost">
|
||||
<location name="/" handler="welcome-content"/>
|
||||
<http-invoker security-realm="ApplicationRealm"/>
|
||||
<http-invoker http-authentication-factory="application-http-authentication"/>
|
||||
<filter-ref name="proxy-peer"/>
|
||||
</host>
|
||||
</server>
|
||||
@@ -715,6 +685,9 @@
|
||||
<handlers>
|
||||
<file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
|
||||
</handlers>
|
||||
<application-security-domains>
|
||||
<application-security-domain name="other" security-domain="ApplicationDomain"/>
|
||||
</application-security-domains>
|
||||
<filters>
|
||||
<filter name="proxy-peer" module="io.undertow.core"
|
||||
class-name="io.undertow.server.handlers.ProxyPeerAddressHandler"/>
|
||||
@@ -724,17 +697,19 @@
|
||||
</profile>
|
||||
<interfaces>
|
||||
<interface name="management">
|
||||
<inet-address value="${jboss.bind.address.management:127.0.0.1}"/>
|
||||
<inet-address value="{{ keycloak_management_port_bind_address }}"/>
|
||||
</interface>
|
||||
<interface name="jgroups">
|
||||
{% if ansible_default_ipv4 is defined %}
|
||||
<subnet-match value="{{ (ansible_default_ipv4.network + '/' + ansible_default_ipv4.netmask) | ipaddr('net') }}"/>
|
||||
<interface name="jgroups">
|
||||
{% if keycloak_jgroups_subnet is defined and keycloak_jgroups_subnet is not none and keycloak_jgroups_subnet | string | length > 0 %}
|
||||
<subnet-match value="{{ keycloak_jgroups_subnet | string }}"/>
|
||||
{% elif ansible_default_ipv4 is defined and (ansible_default_ipv4.network + '/' + ansible_default_ipv4.netmask) | ansible.utils.ipaddr('net') | length > 0 %}
|
||||
<subnet-match value="{{ (ansible_default_ipv4.network + '/' + ansible_default_ipv4.netmask) | ansible.utils.ipaddr('net') }}"/>
|
||||
{% else %}
|
||||
<any-address />
|
||||
{% endif %}
|
||||
</interface>
|
||||
<interface name="public">
|
||||
<inet-address value="${jboss.bind.address:127.0.0.1}"/>
|
||||
<inet-address value="{{ keycloak_bind_address }}"/>
|
||||
</interface>
|
||||
</interfaces>
|
||||
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
|
||||
@@ -744,16 +719,24 @@
|
||||
<socket-binding name="management-http" interface="management" port="{{ keycloak_management_http_port }}"/>
|
||||
<socket-binding name="management-https" interface="management" port="{{ keycloak_management_https_port }}"/>
|
||||
<socket-binding name="jgroups-tcp" interface="jgroups" port="{{ keycloak_jgroups_port }}"/>
|
||||
<socket-binding name="modcluster" multicast-address="${jboss.modcluster.multicast.address:224.0.1.105}" multicast-port="23364"/>
|
||||
<socket-binding name="txn-recovery-environment" port="4712"/>
|
||||
<socket-binding name="txn-status-manager" port="4713"/>
|
||||
<outbound-socket-binding name="mail-smtp">
|
||||
<remote-destination host="${jboss.mail.server.host:localhost}" port="${jboss.mail.server.port:25}"/>
|
||||
</outbound-socket-binding>
|
||||
{% if keycloak_modcluster.enabled %}
|
||||
<outbound-socket-binding name="proxy1">
|
||||
<remote-destination host="{{ keycloak_modcluster.reverse_proxy_url | default('localhost') }}" port="6666"/>
|
||||
{% for modcluster in keycloak_modcluster.reverse_proxy_urls %}
|
||||
<outbound-socket-binding name="proxy_{{ modcluster.host }}">
|
||||
<remote-destination host="{{ modcluster.host }}" port="{{ modcluster.port }}"/>
|
||||
</outbound-socket-binding>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if keycloak_ha_discovery == 'TCPPING' %}
|
||||
{% for node in keycloak_cluster_nodes %}
|
||||
<outbound-socket-binding name="jgroups_{{ node.address }}">
|
||||
<remote-destination host="{{ node.value }}" port="{{ keycloak_jgroups_port }}"/>
|
||||
</outbound-socket-binding>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
<outbound-socket-binding name="remote-cache">
|
||||
<remote-destination host="{{ keycloak_remotecache.server_name | default('localhost') }}" port="${remote.cache.port:11222}"/>
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
<extension module="org.jboss.as.modcluster"/>
|
||||
<extension module="org.jboss.as.naming"/>
|
||||
<extension module="org.jboss.as.remoting"/>
|
||||
<extension module="org.jboss.as.security"/>
|
||||
<extension module="org.jboss.as.transactions"/>
|
||||
<extension module="org.jboss.as.weld"/>
|
||||
<extension module="org.keycloak.keycloak-server-subsystem"/>
|
||||
@@ -30,31 +29,6 @@
|
||||
<extension module="org.wildfly.extension.undertow"/>
|
||||
</extensions>
|
||||
<management>
|
||||
<security-realms>
|
||||
<security-realm name="ManagementRealm">
|
||||
<authentication>
|
||||
<local default-user="$local" skip-group-loading="true"/>
|
||||
<properties path="mgmt-users.properties" relative-to="jboss.server.config.dir"/>
|
||||
</authentication>
|
||||
<authorization map-groups-to-roles="false">
|
||||
<properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
|
||||
</authorization>
|
||||
</security-realm>
|
||||
<security-realm name="ApplicationRealm">
|
||||
<server-identities>
|
||||
<ssl>
|
||||
<keystore path="application.keystore" relative-to="jboss.server.config.dir" keystore-password="password" alias="server" key-password="password" generate-self-signed-certificate-host="localhost"/>
|
||||
</ssl>
|
||||
</server-identities>
|
||||
<authentication>
|
||||
<local default-user="$local" allowed-users="*" skip-group-loading="true"/>
|
||||
<properties path="application-users.properties" relative-to="jboss.server.config.dir"/>
|
||||
</authentication>
|
||||
<authorization>
|
||||
<properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
|
||||
</authorization>
|
||||
</security-realm>
|
||||
</security-realms>
|
||||
<audit-log>
|
||||
<formatters>
|
||||
<json-formatter name="json-formatter"/>
|
||||
@@ -69,8 +43,8 @@
|
||||
</logger>
|
||||
</audit-log>
|
||||
<management-interfaces>
|
||||
<http-interface security-realm="ManagementRealm">
|
||||
<http-upgrade enabled="true"/>
|
||||
<http-interface http-authentication-factory="management-http-authentication">
|
||||
<http-upgrade enabled="true" sasl-authentication-factory="management-sasl-authentication"/>
|
||||
<socket-binding http="management-http"/>
|
||||
</http-interface>
|
||||
</management-interfaces>
|
||||
@@ -149,6 +123,14 @@
|
||||
<user-name>{{ keycloak_jdbc[keycloak_jdbc_engine].db_user }}</user-name>
|
||||
<password>{{ keycloak_jdbc[keycloak_jdbc_engine].db_password }}</password>
|
||||
</security>
|
||||
<validation>
|
||||
<check-valid-connection-sql>{{ keycloak_jdbc[keycloak_jdbc_engine].validate_query }}</check-valid-connection-sql>
|
||||
<validate-on-match>{{ keycloak_db_background_validate_on_match }}</validate-on-match>
|
||||
{% if keycloak_db_background_validation_millis | int > 0 or keycloak_db_background_validation %}
|
||||
<background-validation>{{ keycloak_db_background_validation }}</background-validation>
|
||||
<background-validation-millis>{{ keycloak_db_background_validation_millis }}</background-validation-millis>
|
||||
{% endif %}
|
||||
</validation>
|
||||
{% else %}
|
||||
<connection-url>jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE</connection-url>
|
||||
<driver>h2</driver>
|
||||
@@ -231,6 +213,9 @@
|
||||
</thread-pool>
|
||||
</thread-pools>
|
||||
<default-security-domain value="other"/>
|
||||
<application-security-domains>
|
||||
<application-security-domain name="other" security-domain="ApplicationDomain"/>
|
||||
</application-security-domains>
|
||||
<default-missing-method-permissions-deny-access value="true"/>
|
||||
<statistics enabled="${wildfly.ejb3.statistics-enabled:${wildfly.statistics-enabled:false}}"/>
|
||||
<log-system-exceptions value="true"/>
|
||||
@@ -304,6 +289,13 @@
|
||||
</mechanism>
|
||||
</mechanism-configuration>
|
||||
</http-authentication-factory>
|
||||
<http-authentication-factory name="application-http-authentication" security-domain="ApplicationDomain" http-server-mechanism-factory="global">
|
||||
<mechanism-configuration>
|
||||
<mechanism mechanism-name="BASIC">
|
||||
<mechanism-realm realm-name="ApplicationRealm"/>
|
||||
</mechanism>
|
||||
</mechanism-configuration>
|
||||
</http-authentication-factory>
|
||||
<provider-http-server-mechanism-factory name="global"/>
|
||||
</http>
|
||||
<sasl>
|
||||
@@ -533,7 +525,10 @@
|
||||
<provider name="default" enabled="true">
|
||||
<properties>
|
||||
<property name="frontendUrl" value="{{ keycloak_modcluster.frontend_url }}"/>
|
||||
<property name="forceBackendUrlToFrontendUrl" value="true"/>
|
||||
<property name="forceBackendUrlToFrontendUrl" value="{{ keycloak_modcluster.force_frontend_url }}"/>
|
||||
{% if keycloak_modcluster.admin_url | length > 0 %}
|
||||
<property name="adminUrl" value="{{ keycloak_modcluster.admin_url }}" />
|
||||
{% endif %}
|
||||
</properties>
|
||||
</provider>
|
||||
</spi>
|
||||
@@ -546,7 +541,7 @@
|
||||
<subsystem xmlns="urn:wildfly:metrics:1.0" security-enabled="false" exposed-subsystems="*" prefix="${wildfly.metrics.prefix:jboss}"/>
|
||||
{% if keycloak_modcluster.enabled %}
|
||||
<subsystem xmlns="urn:jboss:domain:modcluster:5.0">
|
||||
<proxy name="default" advertise-socket="modcluster" listener="ajp" proxies="proxy1">
|
||||
<proxy name="default" advertise="false" listener="ajp" proxies="{{ ['proxy_'] | product(keycloak_modcluster.reverse_proxy_urls | map(attribute='host')) | map('join') | list | join(' ') }}">
|
||||
<dynamic-load-provider>
|
||||
<load-metric type="cpu"/>
|
||||
</dynamic-load-provider>
|
||||
@@ -557,41 +552,9 @@
|
||||
<remote-naming/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:remoting:4.0">
|
||||
<http-connector name="http-remoting-connector" connector-ref="default" security-realm="ApplicationRealm"/>
|
||||
<http-connector name="http-remoting-connector" connector-ref="default" sasl-authentication-factory="application-sasl-authentication"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:request-controller:1.0"/>
|
||||
<subsystem xmlns="urn:jboss:domain:security:2.0">
|
||||
<security-domains>
|
||||
<security-domain name="other" cache-type="default">
|
||||
<authentication>
|
||||
<login-module code="Remoting" flag="optional">
|
||||
<module-option name="password-stacking" value="useFirstPass"/>
|
||||
</login-module>
|
||||
<login-module code="RealmDirect" flag="required">
|
||||
<module-option name="password-stacking" value="useFirstPass"/>
|
||||
</login-module>
|
||||
</authentication>
|
||||
</security-domain>
|
||||
<security-domain name="jboss-web-policy" cache-type="default">
|
||||
<authorization>
|
||||
<policy-module code="Delegating" flag="required"/>
|
||||
</authorization>
|
||||
</security-domain>
|
||||
<security-domain name="jaspitest" cache-type="default">
|
||||
<authentication-jaspi>
|
||||
<login-module-stack name="dummy">
|
||||
<login-module code="Dummy" flag="optional"/>
|
||||
</login-module-stack>
|
||||
<auth-module code="Dummy"/>
|
||||
</authentication-jaspi>
|
||||
</security-domain>
|
||||
<security-domain name="jboss-ejb-policy" cache-type="default">
|
||||
<authorization>
|
||||
<policy-module code="Delegating" flag="required"/>
|
||||
</authorization>
|
||||
</security-domain>
|
||||
</security-domains>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:security-manager:1.0">
|
||||
<deployment-permissions>
|
||||
<maximum-set>
|
||||
@@ -614,10 +577,10 @@
|
||||
<server name="default-server">
|
||||
<ajp-listener name="ajp" socket-binding="ajp"/>
|
||||
<http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/>
|
||||
<https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/>
|
||||
<https-listener name="https" socket-binding="https" ssl-context="applicationSSC" enable-http2="true"/>
|
||||
<host name="default-host" alias="localhost">
|
||||
<location name="/" handler="welcome-content"/>
|
||||
<http-invoker security-realm="ApplicationRealm"/>
|
||||
<http-invoker http-authentication-factory="application-http-authentication"/>
|
||||
</host>
|
||||
</server>
|
||||
<servlet-container name="default">
|
||||
@@ -627,15 +590,18 @@
|
||||
<handlers>
|
||||
<file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
|
||||
</handlers>
|
||||
<application-security-domains>
|
||||
<application-security-domain name="other" security-domain="ApplicationDomain"/>
|
||||
</application-security-domains>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:weld:4.0"/>
|
||||
</profile>
|
||||
<interfaces>
|
||||
<interface name="management">
|
||||
<inet-address value="${jboss.bind.address.management:127.0.0.1}"/>
|
||||
<inet-address value="{{ keycloak_management_port_bind_address }}"/>
|
||||
</interface>
|
||||
<interface name="public">
|
||||
<inet-address value="${jboss.bind.address:127.0.0.1}"/>
|
||||
<inet-address value="{{ keycloak_bind_address }}"/>
|
||||
</interface>
|
||||
</interfaces>
|
||||
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
|
||||
@@ -644,16 +610,17 @@
|
||||
<socket-binding name="https" port="{{ keycloak_https_port }}"/>
|
||||
<socket-binding name="management-http" interface="management" port="{{ keycloak_management_http_port }}"/>
|
||||
<socket-binding name="management-https" interface="management" port="{{ keycloak_management_https_port }}"/>
|
||||
<socket-binding name="modcluster" multicast-address="${jboss.modcluster.multicast.address:224.0.1.105}" multicast-port="23364"/>
|
||||
<socket-binding name="txn-recovery-environment" port="4712"/>
|
||||
<socket-binding name="txn-status-manager" port="4713"/>
|
||||
<outbound-socket-binding name="mail-smtp">
|
||||
<remote-destination host="${jboss.mail.server.host:localhost}" port="${jboss.mail.server.port:25}"/>
|
||||
</outbound-socket-binding>
|
||||
{% if keycloak_modcluster.enabled %}
|
||||
<outbound-socket-binding name="proxy1">
|
||||
<remote-destination host="{{ keycloak_modcluster.reverse_proxy_url | default('localhost') }}" port="6666"/>
|
||||
{% if keycloak_modcluster.enabled %}
|
||||
{% for modcluster in keycloak_modcluster.reverse_proxy_urls %}
|
||||
<outbound-socket-binding name="proxy_{{ modcluster.host }}">
|
||||
<remote-destination host="{{ modcluster.host }}" port="{{ modcluster.port }}"/>
|
||||
</outbound-socket-binding>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</socket-binding-group>
|
||||
</server>
|
||||
|
||||
@@ -1,12 +1,5 @@
|
||||
---
|
||||
# required variables for keycloak
|
||||
# administrator console password
|
||||
keycloak_admin_password:
|
||||
|
||||
# internal variables below
|
||||
rhsso_rhn_ids:
|
||||
'7.5.0': '101971'
|
||||
'7.5.1': '103836'
|
||||
|
||||
# locations
|
||||
keycloak_url: "http://{{ keycloak_host }}:{{ keycloak_http_port }}"
|
||||
@@ -16,9 +9,12 @@ 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 }}"
|
||||
service_name: "{{ 'rhsso' if keycloak_rhsso_enable else 'keycloak' }}"
|
||||
bundle: "{{ keycloak_archive }}"
|
||||
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-ha.xml.j2' if keycloak_remote_cache_enabled else 'standalone.xml.j2' }}"
|
||||
features: "{{ keycloak_features }}"
|
||||
|
||||
# database
|
||||
keycloak_jdbc:
|
||||
@@ -34,6 +30,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,
|
||||
@@ -44,15 +41,16 @@ 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 }}"
|
||||
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 }}"
|
||||
validate_query: "{{ keycloak_db_valid_conn_sql | default('select 1') }}"
|
||||
initialize_db: >
|
||||
CREATE TABLE IF NOT EXISTS JGROUPSPING (
|
||||
own_addr varchar(200) NOT NULL,
|
||||
@@ -61,21 +59,46 @@ 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 }}"
|
||||
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
|
||||
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:
|
||||
enabled: "{{ keycloak_ha_enabled }}"
|
||||
reverse_proxy_url: "{{ keycloak_modcluster_url }}"
|
||||
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 }}"
|
||||
admin_url: "{{ keycloak_admin_url | default('') }}"
|
||||
|
||||
# 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 }}"
|
||||
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 }}"
|
||||
|
||||
121
roles/keycloak_quarkus/README.md
Normal file
121
roles/keycloak_quarkus/README.md
Normal file
@@ -0,0 +1,121 @@
|
||||
keycloak_quarkus
|
||||
================
|
||||
|
||||
Install [keycloak](https://keycloak.org/) >= 20.0.0 (quarkus) server configurations.
|
||||
|
||||
|
||||
Role Defaults
|
||||
-------------
|
||||
|
||||
* Installation options
|
||||
|
||||
| Variable | Description | Default |
|
||||
|:---------|:------------|:--------|
|
||||
|`keycloak_quarkus_version`| keycloak.org package version | `22.0.1` |
|
||||
|
||||
|
||||
* 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_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-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_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` |
|
||||
|`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
|
||||
|
||||
| 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/<version>/<archive>`|
|
||||
|`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` |
|
||||
|
||||
|
||||
* Miscellaneous configuration
|
||||
|
||||
| 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 }}` |
|
||||
|`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 }}` |
|
||||
|`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` |
|
||||
|`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
|
||||
--------------
|
||||
|
||||
| Variable | Description | Required |
|
||||
|:---------|:------------|----------|
|
||||
|`keycloak_quarkus_admin_pass`| Password of console admin account | `yes` |
|
||||
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
Apache License 2.0
|
||||
|
||||
|
||||
Author Information
|
||||
------------------
|
||||
|
||||
* [Guido Grazioli](https://github.com/guidograzioli)
|
||||
91
roles/keycloak_quarkus/defaults/main.yml
Normal file
91
roles/keycloak_quarkus/defaults/main.yml
Normal file
@@ -0,0 +1,91 @@
|
||||
---
|
||||
### Configuration specific to keycloak
|
||||
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 }}"
|
||||
|
||||
# whether to install from local archive
|
||||
keycloak_quarkus_offline_install: False
|
||||
|
||||
### Install location and service settings
|
||||
keycloak_quarkus_jvm_package: java-17-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"
|
||||
keycloak_quarkus_start_dev: False
|
||||
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_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: "{{ 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
|
||||
### 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
|
||||
|
||||
# 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
|
||||
|
||||
### 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
|
||||
|
||||
### 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'
|
||||
4
roles/keycloak_quarkus/handlers/main.yml
Normal file
4
roles/keycloak_quarkus/handlers/main.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
- name: "Restart {{ keycloak.service_name }}"
|
||||
ansible.builtin.include_tasks: restart.yml
|
||||
listen: "restart keycloak"
|
||||
254
roles/keycloak_quarkus/meta/argument_specs.yml
Normal file
254
roles/keycloak_quarkus/meta/argument_specs.yml
Normal file
@@ -0,0 +1,254 @@
|
||||
argument_specs:
|
||||
main:
|
||||
options:
|
||||
keycloak_quarkus_version:
|
||||
# line 3 of defaults/main.yml
|
||||
default: "17.0.1"
|
||||
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"
|
||||
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"
|
||||
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.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_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: ""
|
||||
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"
|
||||
keycloak_quarkus_host:
|
||||
# line 28 of defaults/main.yml
|
||||
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: "{{ keycloak.home }}/conf/server.key.pem"
|
||||
description: "The file path to a private key in PEM format"
|
||||
type: "str"
|
||||
keycloak_quarkus_cert_file:
|
||||
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:
|
||||
# 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: 7600
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
type: "str"
|
||||
keycloak_quarkus_metrics_enabled:
|
||||
# line 43 of defaults/main.yml
|
||||
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"
|
||||
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_url:
|
||||
# line 48 of defaults/main.yml
|
||||
default: "localhost"
|
||||
description: "URL for connecting to infinispan"
|
||||
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]"
|
||||
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"
|
||||
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"
|
||||
keycloak_quarkus_proxy_mode:
|
||||
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)"
|
||||
keycloak_quarkus_transaction_xa_enabled:
|
||||
default: True
|
||||
type: "bool"
|
||||
description: "Enable or disable XA transactions which may not be supported by some DBMS"
|
||||
26
roles/keycloak_quarkus/meta/main.yml
Normal file
26
roles/keycloak_quarkus/meta/main.yml
Normal file
@@ -0,0 +1,26 @@
|
||||
---
|
||||
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
|
||||
20
roles/keycloak_quarkus/tasks/fastpackages.yml
Normal file
20
roles/keycloak_quarkus/tasks/fastpackages.yml
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
- 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
|
||||
|
||||
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 | join(',') }}"
|
||||
become: yes
|
||||
ansible.builtin.yum:
|
||||
name: "{{ packages_to_install }}"
|
||||
state: present
|
||||
when: packages_to_install | default([]) | length > 0
|
||||
25
roles/keycloak_quarkus/tasks/firewalld.yml
Normal file
25
roles/keycloak_quarkus/tasks/firewalld.yml
Normal file
@@ -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
|
||||
ansible.posix.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"
|
||||
111
roles/keycloak_quarkus/tasks/install.yml
Normal file
111
roles/keycloak_quarkus/tasks/install.yml
Normal file
@@ -0,0 +1,111 @@
|
||||
---
|
||||
- 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: # 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
|
||||
- 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 }}/bin/"
|
||||
ansible.builtin.stat:
|
||||
path: "{{ keycloak.home }}/bin/"
|
||||
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 }}/bin/"
|
||||
owner: "{{ keycloak.service_user }}"
|
||||
group: "{{ keycloak.service_group }}"
|
||||
become: yes
|
||||
when:
|
||||
- (not path_to_workdir.stat.exists) or new_version_downloaded.changed
|
||||
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
|
||||
69
roles/keycloak_quarkus/tasks/main.yml
Normal file
69
roles/keycloak_quarkus/tasks/main.yml
Normal file
@@ -0,0 +1,69 @@
|
||||
---
|
||||
# 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
|
||||
become: yes
|
||||
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
|
||||
become: yes
|
||||
notify:
|
||||
- restart keycloak
|
||||
|
||||
- name: Ensure logdirectory exists
|
||||
ansible.builtin.file:
|
||||
state: directory
|
||||
path: "{{ keycloak.log.file | dirname }}"
|
||||
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
|
||||
|
||||
- name: Check service status
|
||||
ansible.builtin.command: "systemctl status keycloak"
|
||||
register: keycloak_service_status
|
||||
changed_when: False
|
||||
|
||||
- name: Link default logs directory
|
||||
ansible.builtin.file:
|
||||
state: link
|
||||
src: "{{ keycloak.log.file | dirname }}"
|
||||
dest: /var/log/keycloak
|
||||
force: yes
|
||||
become: yes
|
||||
26
roles/keycloak_quarkus/tasks/prereqs.yml
Normal file
26
roles/keycloak_quarkus/tasks/prereqs.yml
Normal file
@@ -0,0 +1,26 @@
|
||||
---
|
||||
- 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: Ensure required packages are installed
|
||||
ansible.builtin.include_tasks: fastpackages.yml
|
||||
vars:
|
||||
packages_list:
|
||||
- "{{ keycloak_quarkus_jvm_package }}"
|
||||
- unzip
|
||||
- procps-ng
|
||||
- initscripts
|
||||
- tzdata-java
|
||||
7
roles/keycloak_quarkus/tasks/restart.yml
Normal file
7
roles/keycloak_quarkus/tasks/restart.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
- name: "Restart and enable {{ keycloak.service_name }} service"
|
||||
ansible.builtin.systemd:
|
||||
name: keycloak
|
||||
enabled: yes
|
||||
state: restarted
|
||||
become: yes
|
||||
15
roles/keycloak_quarkus/tasks/start.yml
Normal file
15
roles/keycloak_quarkus/tasks/start.yml
Normal file
@@ -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
|
||||
35
roles/keycloak_quarkus/tasks/systemd.yml
Normal file
35
roles/keycloak_quarkus/tasks/systemd.yml
Normal file
@@ -0,0 +1,35 @@
|
||||
---
|
||||
- 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
|
||||
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 }}"
|
||||
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
|
||||
5
roles/keycloak_quarkus/templates/keycloak-sysconfig.j2
Normal file
5
roles/keycloak_quarkus/templates/keycloak-sysconfig.j2
Normal file
@@ -0,0 +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) }}
|
||||
50
roles/keycloak_quarkus/templates/keycloak.conf.j2
Normal file
50
roles/keycloak_quarkus/templates/keycloak.conf.j2
Normal file
@@ -0,0 +1,50 @@
|
||||
# {{ ansible_managed }}
|
||||
|
||||
{% if keycloak_quarkus_db_enabled %}
|
||||
# Database
|
||||
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
|
||||
metrics-enabled={{ keycloak_quarkus_metrics_enabled }}
|
||||
health-enabled={{ keycloak_quarkus_health_enabled }}
|
||||
|
||||
# HTTP
|
||||
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_quarkus_cert_file}}
|
||||
https-certificate-key-file={{ keycloak_quarkus_key_file }}
|
||||
{% endif %}
|
||||
|
||||
# Hostname for the Keycloak server.
|
||||
hostname={{ keycloak_quarkus_host }}
|
||||
hostname-path={{ keycloak_quarkus_http_relative_path }}
|
||||
|
||||
# Cluster
|
||||
{% if keycloak_quarkus_ha_enabled %}
|
||||
cache=ispn
|
||||
cache-config-file=cache-ispn.xml
|
||||
cache-stack=tcp
|
||||
{% endif %}
|
||||
|
||||
# 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
|
||||
|
||||
# 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 }}
|
||||
log-level={{ keycloak.log.level }}
|
||||
log-file={{ keycloak.log.file }}
|
||||
log-file-format={{ keycloak.log.format }}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user