193 lines
7.3 KiB
YAML
193 lines
7.3 KiB
YAML
---
|
||
- name: Synology DSM - upgrade via DSM API (Semaphore/legacy compatible)
|
||
hosts: synology
|
||
gather_facts: false
|
||
|
||
vars:
|
||
syno_scheme: "https"
|
||
syno_port: 5001
|
||
syno_verify_ssl: false
|
||
syno_user: "{{ vault_syno_user }}"
|
||
syno_pass: "{{ vault_syno_pass }}"
|
||
syno_session: "DSM"
|
||
uri_timeout: 60
|
||
|
||
refuse_if_no_upgrade_api: true
|
||
|
||
# méthodes candidates (DSM varie)
|
||
upgrade_status_methods:
|
||
- "status"
|
||
- "get"
|
||
- "check"
|
||
upgrade_start_method: "start"
|
||
|
||
tasks:
|
||
- name: Construire base_url
|
||
ansible.builtin.set_fact:
|
||
base_url: "{{ syno_scheme }}://{{ inventory_hostname }}:{{ syno_port }}"
|
||
|
||
- name: Discover SYNO.API.Auth & SYNO.Core.Upgrade via SYNO.API.Info
|
||
ansible.builtin.uri:
|
||
url: "{{ base_url }}/webapi/entry.cgi?api=SYNO.API.Info&version=1&method=query&query=SYNO.API.Auth,SYNO.Core.Upgrade"
|
||
method: GET
|
||
return_content: true
|
||
validate_certs: "{{ syno_verify_ssl }}"
|
||
status_code: 200
|
||
timeout: "{{ uri_timeout }}"
|
||
register: api_info
|
||
failed_when: api_info.json.success is not defined or api_info.json.success != true
|
||
|
||
- name: Extraire info Auth/Upgrade
|
||
ansible.builtin.set_fact:
|
||
auth_info: "{{ api_info.json.data['SYNO.API.Auth'] | default({}) }}"
|
||
upgrade_info: "{{ api_info.json.data['SYNO.Core.Upgrade'] | default({}) }}"
|
||
|
||
- name: Fail si SYNO.Core.Upgrade absent (optionnel)
|
||
ansible.builtin.fail:
|
||
msg: >-
|
||
L'API SYNO.Core.Upgrade n'est pas exposée sur ce NAS via /webapi.
|
||
Solution de repli: SSH (synoupgrade) ou mise à jour manuelle DSM.
|
||
when:
|
||
- refuse_if_no_upgrade_api | bool
|
||
- (upgrade_info | length) == 0
|
||
|
||
- name: Définir chemins et versions
|
||
ansible.builtin.set_fact:
|
||
auth_path: "{{ auth_info.path | default('auth.cgi') }}"
|
||
upgrade_path: "{{ upgrade_info.path | default('entry.cgi') }}"
|
||
upgrade_ver: "{{ upgrade_info.maxVersion | default(1) }}"
|
||
|
||
- name: Login DSM API (SYNO.API.Auth) - try v6 then v2
|
||
block:
|
||
- name: Login v6
|
||
ansible.builtin.uri:
|
||
url: "{{ base_url }}/webapi/{{ auth_path }}?api=SYNO.API.Auth&version=6&method=login&account={{ syno_user | urlencode }}&passwd={{ syno_pass | urlencode }}&session={{ syno_session | urlencode }}&format=sid"
|
||
method: GET
|
||
validate_certs: "{{ syno_verify_ssl }}"
|
||
return_content: true
|
||
status_code: 200
|
||
timeout: "{{ uri_timeout }}"
|
||
register: login_v6
|
||
failed_when: login_v6.json.success != true
|
||
|
||
- name: Set login result from v6
|
||
ansible.builtin.set_fact:
|
||
login: "{{ login_v6 }}"
|
||
rescue:
|
||
- name: Login v2 (fallback)
|
||
ansible.builtin.uri:
|
||
url: "{{ base_url }}/webapi/{{ auth_path }}?api=SYNO.API.Auth&version=2&method=login&account={{ syno_user | urlencode }}&passwd={{ syno_pass | urlencode }}&session={{ syno_session | urlencode }}&format=sid"
|
||
method: GET
|
||
validate_certs: "{{ syno_verify_ssl }}"
|
||
return_content: true
|
||
status_code: 200
|
||
timeout: "{{ uri_timeout }}"
|
||
register: login_v2
|
||
failed_when: login_v2.json.success != true
|
||
|
||
- name: Set login result from v2
|
||
ansible.builtin.set_fact:
|
||
login: "{{ login_v2 }}"
|
||
|
||
- name: Enregistrer SID
|
||
ansible.builtin.set_fact:
|
||
sid: "{{ login.json.data.sid }}"
|
||
|
||
# ---- STATUS (on teste plusieurs méthodes) ----
|
||
- name: Interroger statut upgrade (essais multiples)
|
||
ansible.builtin.uri:
|
||
url: "{{ base_url }}/webapi/{{ upgrade_path }}?api=SYNO.Core.Upgrade&version={{ upgrade_ver }}&method={{ item }}&_sid={{ sid }}"
|
||
method: GET
|
||
validate_certs: "{{ syno_verify_ssl }}"
|
||
return_content: true
|
||
status_code: 200
|
||
timeout: "{{ uri_timeout }}"
|
||
loop: "{{ upgrade_status_methods }}"
|
||
register: upgrade_status_attempts
|
||
failed_when: false
|
||
|
||
- name: Choisir le premier statut qui répond success=true
|
||
ansible.builtin.set_fact:
|
||
upgrade_status: >-
|
||
{{
|
||
(upgrade_status_attempts.results
|
||
| selectattr('json', 'defined')
|
||
| selectattr('json.success', 'defined')
|
||
| selectattr('json.success', 'equalto', true)
|
||
| list
|
||
| first) | default({})
|
||
}}
|
||
|
||
- name: Afficher les réponses status (debug)
|
||
ansible.builtin.debug:
|
||
var: upgrade_status_attempts.results
|
||
|
||
- name: Afficher statut retenu (debug)
|
||
ansible.builtin.debug:
|
||
var: upgrade_status.json
|
||
when: upgrade_status | length > 0
|
||
|
||
- name: Fail si aucune méthode status n'a fonctionné
|
||
ansible.builtin.fail:
|
||
msg: >-
|
||
Impossible de récupérer un statut upgrade via SYNO.Core.Upgrade.
|
||
Vérifie les méthodes supportées (status/get/check) sur ce DSM.
|
||
when: upgrade_status | length == 0
|
||
|
||
# ---- START : seulement si "ready" (on ne devine pas : on log l’état) ----
|
||
- name: Déterminer si une mise à jour semble prête (heuristique)
|
||
ansible.builtin.set_fact:
|
||
upgrade_ready: >-
|
||
{{
|
||
(
|
||
(upgrade_status.json.data is defined)
|
||
and (
|
||
(upgrade_status.json.data.ready is defined and upgrade_status.json.data.ready | bool)
|
||
or (upgrade_status.json.data.need_update is defined and upgrade_status.json.data.need_update | bool == false)
|
||
or (upgrade_status.json.data.status is defined and (upgrade_status.json.data.status|string) in ['ready','downloaded','prepared'])
|
||
)
|
||
) | default(false)
|
||
}}
|
||
|
||
- name: Stop si pas prête (évite code 103) + message clair
|
||
ansible.builtin.fail:
|
||
msg: >-
|
||
DSM refuse le start (souvent code 103) car la mise à jour n’est pas "prête".
|
||
Vérifie sur DSM: Panneau de config > Mise à jour DSM :
|
||
- téléchargement terminé
|
||
- EULA/consentement accepté
|
||
- aucune upgrade en cours
|
||
Statut API (data): {{ upgrade_status.json.data | default({}) | to_nice_json }}
|
||
when: not upgrade_ready
|
||
|
||
- name: Start DSM upgrade (SYNO.Core.Upgrade)
|
||
ansible.builtin.uri:
|
||
url: "{{ base_url }}/webapi/{{ upgrade_path }}?api=SYNO.Core.Upgrade&version={{ upgrade_ver }}&method={{ upgrade_start_method }}&_sid={{ sid }}"
|
||
method: GET
|
||
validate_certs: "{{ syno_verify_ssl }}"
|
||
return_content: true
|
||
status_code: 200
|
||
timeout: "{{ uri_timeout }}"
|
||
register: upgrade_start
|
||
|
||
- name: Fail si start a échoué
|
||
ansible.builtin.fail:
|
||
msg: >-
|
||
Echec du démarrage upgrade DSM via API.
|
||
Réponse: {{ upgrade_start.json | to_nice_json }}
|
||
when: upgrade_start.json.success != true
|
||
|
||
- name: Afficher résultat start
|
||
ansible.builtin.debug:
|
||
var: upgrade_start.json
|
||
|
||
- name: Logout DSM API
|
||
ansible.builtin.uri:
|
||
url: "{{ base_url }}/webapi/{{ auth_path }}?api=SYNO.API.Auth&version=2&method=logout&session={{ syno_session | urlencode }}&_sid={{ sid }}"
|
||
method: GET
|
||
validate_certs: "{{ syno_verify_ssl }}"
|
||
return_content: true
|
||
status_code: 200
|
||
timeout: "{{ uri_timeout }}"
|
||
register: logout
|
||
failed_when: false |