semaphore/synology_dsm_upgrade_api.yml

193 lines
7.3 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
- 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 nest 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