feat: manage UniFi SSO login setting via Ansible (W1N-51)
This commit is contained in:
@@ -75,6 +75,7 @@ Also readable as `agent.md` (symlink → this file).
|
|||||||
| Matrix upstream refs | [docs/matrix-upstream.md](docs/matrix-upstream.md) |
|
| Matrix upstream refs | [docs/matrix-upstream.md](docs/matrix-upstream.md) |
|
||||||
| Hermes Agent Matrix channel | [docs/hermes-matrix.md](docs/hermes-matrix.md) |
|
| Hermes Agent Matrix channel | [docs/hermes-matrix.md](docs/hermes-matrix.md) |
|
||||||
| UniFi local-service proxy bypass | [docs/unifi-openclash-localhost.md](docs/unifi-openclash-localhost.md) |
|
| UniFi local-service proxy bypass | [docs/unifi-openclash-localhost.md](docs/unifi-openclash-localhost.md) |
|
||||||
|
| UniFi SSO login setting (Ansible) | `cd ansible && ansible-playbook playbooks/unifi-sso.yml --limit unifi` |
|
||||||
| Routine Ansible operations | [runbooks/ansible-operations.md](runbooks/ansible-operations.md) |
|
| Routine Ansible operations | [runbooks/ansible-operations.md](runbooks/ansible-operations.md) |
|
||||||
|
|
||||||
Routine mailcow health: `cd ansible && ansible-playbook playbooks/health-report.yml --limit mailcow`. The local stub resolver is flaky; DNS probes use `1.1.1.1` / `8.8.8.8`.
|
Routine mailcow health: `cd ansible && ansible-playbook playbooks/health-report.yml --limit mailcow`. The local stub resolver is flaky; DNS probes use `1.1.1.1` / `8.8.8.8`.
|
||||||
|
|||||||
@@ -80,6 +80,16 @@ all:
|
|||||||
adguardhome:
|
adguardhome:
|
||||||
hosts:
|
hosts:
|
||||||
dns_windy_lan:
|
dns_windy_lan:
|
||||||
|
unifi:
|
||||||
|
hosts:
|
||||||
|
ubnt:
|
||||||
|
ansible_host: 192.168.66.46
|
||||||
|
ansible_host_ipv4: 192.168.66.46
|
||||||
|
vars:
|
||||||
|
service_role: unifi
|
||||||
|
compose_project_dir: /home/windy/unifi-9
|
||||||
|
unifi_container: unifi-controller
|
||||||
|
unifi_mongo_port: 27117
|
||||||
docker_hosts:
|
docker_hosts:
|
||||||
children:
|
children:
|
||||||
mailcow:
|
mailcow:
|
||||||
@@ -87,6 +97,7 @@ all:
|
|||||||
powerdns:
|
powerdns:
|
||||||
wireguard:
|
wireguard:
|
||||||
adguardhome:
|
adguardhome:
|
||||||
|
unifi:
|
||||||
# Matrix is a dedicated K3s node and intentionally remains outside the
|
# Matrix is a dedicated K3s node and intentionally remains outside the
|
||||||
# Docker-oriented managed group.
|
# Docker-oriented managed group.
|
||||||
k3s_servers:
|
k3s_servers:
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
# Reconcile the UniFi controller SSO login setting
|
||||||
|
# (super_sdn.sso_login_enabled = "Sync Local Admin with Ubiquiti SSO").
|
||||||
|
#
|
||||||
|
# Safe by default: run with --check for a read-only status report, or supply
|
||||||
|
# unifi_sso_confirm=true to apply the declared target value.
|
||||||
|
#
|
||||||
|
# # Read-only status
|
||||||
|
# ansible-playbook playbooks/unifi-sso.yml --limit ubnt --check
|
||||||
|
#
|
||||||
|
# # Apply (disable SSO login; local accounts use local passwords, no MFA)
|
||||||
|
# ansible-playbook playbooks/unifi-sso.yml --limit ubnt \
|
||||||
|
# -e '{"unifi_sso_confirm": true, "unifi_sso_target_value": false}'
|
||||||
|
#
|
||||||
|
# # Rollback (re-enable SSO login)
|
||||||
|
# ansible-playbook playbooks/unifi-sso.yml --limit ubnt \
|
||||||
|
# -e '{"unifi_sso_confirm": true, "unifi_sso_target_value": true}'
|
||||||
|
- name: Reconcile UniFi SSO login setting
|
||||||
|
hosts: unifi
|
||||||
|
become: true
|
||||||
|
gather_facts: false
|
||||||
|
serial: 1
|
||||||
|
roles:
|
||||||
|
- role: unifi_sso
|
||||||
|
tags: [unifi, sso, mutating]
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
# Reconcile super_sdn.sso_login_enabled on the UniFi Network Controller DB.
|
||||||
|
# Safe by default: without unifi_sso_confirm=true the role only reports the
|
||||||
|
# current state and refuses to change anything.
|
||||||
|
unifi_sso_confirm: false
|
||||||
|
# Declared desired state (true = Sync Local Admin with Ubiquiti SSO ON).
|
||||||
|
unifi_sso_target_value: false
|
||||||
|
# Restart the controller container after applying a change. Only needed when
|
||||||
|
# the setting was changed directly in the DB while the controller was running
|
||||||
|
# (the UI path applies it immediately without a restart).
|
||||||
|
unifi_sso_restart_controller: false
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
---
|
||||||
|
# Reconcile super_sdn.sso_login_enabled on the UniFi controller DB.
|
||||||
|
# Idempotent: reads the current value, reports compliance when it already
|
||||||
|
# matches the target, and only mutates with explicit confirmation.
|
||||||
|
|
||||||
|
- name: Require a boolean target value
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- unifi_sso_target_value | type_debug == 'bool'
|
||||||
|
fail_msg: "unifi_sso_target_value must be a boolean (true or false)."
|
||||||
|
|
||||||
|
- name: Read current SSO login setting
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- docker
|
||||||
|
- exec
|
||||||
|
- "{{ unifi_container }}"
|
||||||
|
- mongo
|
||||||
|
- --port
|
||||||
|
- "{{ unifi_mongo_port }}"
|
||||||
|
- --quiet
|
||||||
|
- ace
|
||||||
|
- --eval
|
||||||
|
- 'db.setting.findOne({key:"super_sdn"}).sso_login_enabled'
|
||||||
|
register: unifi_sso_current
|
||||||
|
changed_when: false
|
||||||
|
failed_when: unifi_sso_current.rc != 0
|
||||||
|
check_mode: false
|
||||||
|
|
||||||
|
- name: Report current setting
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: >-
|
||||||
|
sso_login_enabled={{ unifi_sso_current.stdout | trim }}
|
||||||
|
(target={{ unifi_sso_target_value | string | lower }})
|
||||||
|
|
||||||
|
- name: Report already compliant
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "Already compliant; no change needed."
|
||||||
|
when: unifi_sso_current.stdout | trim | lower == unifi_sso_target_value | string | lower
|
||||||
|
|
||||||
|
- name: Refuse to change without explicit confirmation
|
||||||
|
ansible.builtin.fail:
|
||||||
|
msg: >-
|
||||||
|
Change required (sso_login_enabled={{ unifi_sso_current.stdout | trim }}
|
||||||
|
!= target {{ unifi_sso_target_value | string | lower }}) but
|
||||||
|
unifi_sso_confirm is not true. Supply unifi_sso_confirm=true to apply.
|
||||||
|
when:
|
||||||
|
- unifi_sso_current.stdout | trim | lower != unifi_sso_target_value | string | lower
|
||||||
|
- not (unifi_sso_confirm | bool)
|
||||||
|
|
||||||
|
- name: Apply SSO login setting change
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- docker
|
||||||
|
- exec
|
||||||
|
- "{{ unifi_container }}"
|
||||||
|
- mongo
|
||||||
|
- --port
|
||||||
|
- "{{ unifi_mongo_port }}"
|
||||||
|
- --quiet
|
||||||
|
- ace
|
||||||
|
- --eval
|
||||||
|
- >-
|
||||||
|
db.setting.updateOne({key:"super_sdn"},
|
||||||
|
{$set:{sso_login_enabled: {{ unifi_sso_target_value | string | lower }}}})
|
||||||
|
when:
|
||||||
|
- unifi_sso_confirm | bool
|
||||||
|
- unifi_sso_current.stdout | trim | lower != unifi_sso_target_value | string | lower
|
||||||
|
changed_when: true
|
||||||
|
register: unifi_sso_update
|
||||||
|
|
||||||
|
- name: Restart controller to apply setting when requested
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv: [docker, restart, "{{ unifi_container }}"]
|
||||||
|
when:
|
||||||
|
- unifi_sso_restart_controller | bool
|
||||||
|
- unifi_sso_current.stdout | trim | lower != unifi_sso_target_value | string | lower
|
||||||
|
changed_when: true
|
||||||
|
|
||||||
|
- name: Verify setting after change
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- docker
|
||||||
|
- exec
|
||||||
|
- "{{ unifi_container }}"
|
||||||
|
- mongo
|
||||||
|
- --port
|
||||||
|
- "{{ unifi_mongo_port }}"
|
||||||
|
- --quiet
|
||||||
|
- ace
|
||||||
|
- --eval
|
||||||
|
- 'db.setting({key:"super_sdn"}).sso_login_enabled'
|
||||||
|
register: unifi_sso_verify
|
||||||
|
changed_when: false
|
||||||
|
check_mode: false
|
||||||
|
when:
|
||||||
|
- unifi_sso_current.stdout | trim | lower != unifi_sso_target_value | string | lower
|
||||||
|
- not ansible_check_mode
|
||||||
|
|
||||||
|
- name: Assert verified value matches target
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- unifi_sso_verify.stdout | trim | lower == unifi_sso_target_value | string | lower
|
||||||
|
fail_msg: >-
|
||||||
|
Verification failed: sso_login_enabled is
|
||||||
|
{{ unifi_sso_verify.stdout | trim }} but expected
|
||||||
|
{{ unifi_sso_target_value | string | lower }}.
|
||||||
|
when:
|
||||||
|
- unifi_sso_current.stdout | trim | lower != unifi_sso_target_value | string | lower
|
||||||
|
- not ansible_check_mode
|
||||||
Reference in New Issue
Block a user