mirror of
				https://github.com/kevinveenbirkenbach/computer-playbook.git
				synced 2025-10-31 02:10:05 +00:00 
			
		
		
		
	- Improved get_service_name filter plugin (clearer suffix handling, consistent var names). - Added MODE_ASSERT flag to optionally execute validation/assertion tasks. - Fixed systemd unit handling: consistent use of %I instead of %i, correct escaping of instance names. - Unified on_failure behavior and alarm composer scripts. - Cleaned up redundant logging, handlers, and debug config. - Strengthened sys-service template resolution with assert (only active when MODE_ASSERT). - Simplified timer and suffix handling with get_service_name filter. - Hardened sensitive tasks with no_log. - Added conditional asserts across roles (Keycloak, DNS, Mailu, Discourse, etc.). These changes improve consistency, safety, and validation across the automation stack. Conversation: https://chatgpt.com/share/68a4ae28-483c-800f-b2f7-f64c7124c274
		
			
				
	
	
		
			76 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			YAML
		
	
	
	
	
	
			
		
		
	
	
			76 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			YAML
		
	
	
	
	
	
| # --- Ensure RBAC client scope exists (idempotent) ---
 | |
| - name: Ensure RBAC client scope exists
 | |
|   shell: |
 | |
|     cat <<'JSON' | {{ KEYCLOAK_EXEC_KCADM }} create client-scopes -r {{ KEYCLOAK_REALM }} -f -
 | |
|     {{
 | |
|       (
 | |
|         KEYCLOAK_DICTIONARY_REALM.clientScopes
 | |
|         | selectattr('name','equalto', KEYCLOAK_RBAC_GROUP_CLAIM)
 | |
|         | list | first
 | |
|       ) | to_json
 | |
|     }}
 | |
|     JSON
 | |
|   register: create_rbac_scope
 | |
|   changed_when: create_rbac_scope.rc == 0
 | |
|   failed_when: create_rbac_scope.rc != 0 and
 | |
|                ('already exists' not in (create_rbac_scope.stderr | lower))
 | |
|   no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
 | |
| 
 | |
| # --- Get the scope id we will attach to the client ---
 | |
| - name: Get all client scopes
 | |
|   shell: "{{ KEYCLOAK_EXEC_KCADM }} get client-scopes -r {{ KEYCLOAK_REALM }} --format json"
 | |
|   register: all_scopes
 | |
|   changed_when: false
 | |
| 
 | |
| - name: Extract RBAC scope id
 | |
|   set_fact:
 | |
|     scope_id_rbac: >-
 | |
|       {{ (
 | |
|           all_scopes.stdout | from_json
 | |
|           | selectattr('name','equalto', KEYCLOAK_RBAC_GROUP_CLAIM)
 | |
|           | list | first | default({})
 | |
|         ).id | default('') }}
 | |
| 
 | |
| - name: Resolve application client id
 | |
|   shell: >
 | |
|     {{ KEYCLOAK_EXEC_KCADM }} get clients
 | |
|     -r {{ KEYCLOAK_REALM }}
 | |
|     --query 'clientId={{ KEYCLOAK_CLIENT_ID }}'
 | |
|     --fields id --format json | jq -r '.[0].id'
 | |
|   register: app_client_id_cmd
 | |
|   changed_when: false
 | |
| 
 | |
| - name: Sanity check IDs
 | |
|   assert:
 | |
|     that:
 | |
|       - scope_id_rbac | length > 0
 | |
|       - (app_client_id_cmd.stdout | trim) is match('^[0-9a-f-]+$')
 | |
|     fail_msg: "Could not determine client or scope ID."
 | |
|   when: MODE_ASSERT | bool
 | |
| 
 | |
| - name: Get current optional client scopes
 | |
|   shell: >
 | |
|     {{ KEYCLOAK_EXEC_KCADM }} get
 | |
|     clients/{{ app_client_id_cmd.stdout | trim }}/optional-client-scopes
 | |
|     -r {{ KEYCLOAK_REALM }} --format json
 | |
|   register: opt_scopes
 | |
|   changed_when: false
 | |
| 
 | |
| - name: Decide if RBAC scope already assigned
 | |
|   set_fact:
 | |
|     has_rbac_optional: >-
 | |
|       {{ (opt_scopes.stdout | from_json
 | |
|           | selectattr('id','equalto', scope_id_rbac) | list | length) > 0 }}
 | |
| 
 | |
| - name: Ensure RBAC scope assigned as optional (only if missing)
 | |
|   when: not has_rbac_optional
 | |
|   shell: >
 | |
|     {{ KEYCLOAK_EXEC_KCADM }} update
 | |
|     clients/{{ app_client_id_cmd.stdout | trim }}/optional-client-scopes/{{ scope_id_rbac }}
 | |
|     -r {{ KEYCLOAK_REALM }}
 | |
|   register: add_opt
 | |
|   changed_when: true
 | |
|   failed_when: add_opt.rc != 0
 | |
|   async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}"
 | |
|   poll:  "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}"
 |