Bug 56791 - keycloak joinscript is not idempotent and cannot recover from error situation
keycloak joinscript is not idempotent and cannot recover from error situation
Status: CLOSED FIXED
Product: UCS
Classification: Unclassified
Component: Keycloak
UCS 5.0
Other Linux
: P5 normal (vote)
: UCS 5.0-5-errata
Assigned To: Juan Pedro Torres
Felix Botner
https://git.knut.univention.de/univen...
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2023-11-02 09:38 CET by Florian Best
Modified: 2023-11-15 21:08 CET (History)
2 users (show)

See Also:
What kind of report is it?: Development Internal
What type of bug is this?: ---
Who will be affected by this bug?: ---
How will those affected feel about the bug?: ---
User Pain:
Enterprise Customer affected?:
School Customer affected?:
ISV affected?:
Waiting Support:
Flags outvoted (downgraded) after PO Review:
Ticket number:
Bug group (optional):
Max CVSS v3 score:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Florian Best univentionstaff 2023-11-02 09:38:40 CET
When the UMC-Server doesn't run the keycloak joinscript fails to create the SAML client for UMC as it cannot download it's metadata.

CREATING KEYCLOAK SAML CLIENT.....
Traceback (most recent call last):
  File "/usr/lib/python3.11/xml/etree/ElementTree.py", line 1709, in feed
    self.parser.Parse(data, False)
xml.parsers.expat.ExpatError: not well-formed (invalid token): line 1, column 0

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/sbin/univention-keycloak", line 2484, in <module>
    sys.exit(main())
             ^^^^^^
  File "/usr/sbin/univention-keycloak", line 2480, in main
    return opt.func(opt) or 0   
           ^^^^^^^^^^^^^
  File "/usr/sbin/univention-keycloak", line 2252, in init_keycloak_ucs
    create_SAML_client(opt)
  File "/usr/sbin/univention-keycloak", line 427, in create_SAML_client
    endpoints = extract_endpoints_xml(client_id, opt.metadata_file, opt.no_ssl_verify)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/sbin/univention-keycloak", line 404, in extract_endpoints_xml
    saml_descriptor_xml = ElementTree.fromstring(xml_content)
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/defusedxml/common.py", line 126, in fromstring
    parser.feed(text)
  File "/usr/lib/python3.11/xml/etree/ElementTree.py", line 1711, in feed
    self._raiseerror(v)
  File "/usr/lib/python3.11/xml/etree/ElementTree.py", line 1618, in _raiseerror
    raise err
xml.etree.ElementTree.ParseError: not well-formed (invalid token): line 1, column 0
/usr/lib/univention-install/50keycloak.inst: FATAL:

That's so far ok and handled elsewhere.
But when this or a similar situation occurs, the joinscript is not able to repair the situation. The follow up error then is:

02.11.23 08:43:56.141  DEBUG_INIT
Restarting keycloak ... ^M
Restarting keycloak ... done^M
Container is healthy, configuring Keycloak
Using bind-dn:
Check if init is needed: no, already executed
Running update steps for version: 19.0.2-ucs2
Traceback (most recent call last):
  File "/usr/sbin/univention-keycloak", line 2485, in <module>
    sys.exit(main())
             ^^^^^^
  File "/usr/sbin/univention-keycloak", line 2481, in main
    return opt.func(opt) or 0
           ^^^^^^^^^^^^^
  File "/usr/sbin/univention-keycloak", line 1607, in upgrade_config
    register_extensions(opt)
  File "/usr/sbin/univention-keycloak", line 824, in register_extensions
    func(service, opt.realm, ext.alias, ext.name)
  File "/usr/sbin/univention-keycloak", line 313, in register_ldap_mapper
    raise RuntimeError("ldap-provider with name ldap is not found")
RuntimeError: ldap-provider with name ldap is not found
/usr/lib/univention-install/50keycloak.inst: FATAL:
EXITCODE=2

This is because the joinscript checks if the keycloak init has already been done but the check checks if the "ucs" realm exists. The error above happened after the realm was created. Therefore it always detects that init was already done but that was never successful.
The check if the init has been done before is done to not overwrite any customer modifications by the joinscript.

By definition joinscripts must be idempotent and be able to set the state to the wanted state. We have to find a reasonable compromise here.
Comment 2 Juan Pedro Torres univentionstaff 2023-11-13 13:11:16 CET
Package: univention-keycloak
Version: 1.0.9-33
Branch: ucs_5.0-0
Scope: errata5.0-5
Comment 3 Felix Botner univentionstaff 2023-11-13 21:03:42 CET
- OK 1.0.9-33 univention-keycloak for 5.0-5 errata
- OK yaml