diff --git a/synology_dsm_dl.yml b/synology_dsm_dl.yml new file mode 100644 index 0000000..b346b03 --- /dev/null +++ b/synology_dsm_dl.yml @@ -0,0 +1,174 @@ +--- +- name: Synology DSM - tenter de télécharger une MAJ DSM si dispo (best effort API) + 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 + + # Méthodes candidates (selon DSM elles peuvent ne pas exister) + upgrade_status_methods: ["status", "get", "check"] + upgrade_check_update_methods: ["check", "check_update", "checkUpdate", "query"] + upgrade_download_methods: ["download", "download_update", "downloadUpdate", "prepare", "fetch"] + + 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 + ansible.builtin.fail: + msg: "SYNO.Core.Upgrade absent sur ce NAS via /webapi." + when: (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 + - ansible.builtin.set_fact: + sid: "{{ login_v6.json.data.sid }}" + 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 + - ansible.builtin.set_fact: + sid: "{{ login_v2.json.data.sid }}" + + # 1) Statut actuel + - name: Lire le 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: status_attempts + failed_when: false + + - name: Choisir le premier status success=true + ansible.builtin.set_fact: + upgrade_status: >- + {{ + (status_attempts.results + | selectattr('json', 'defined') + | selectattr('json.success', 'defined') + | selectattr('json.success', 'equalto', true) + | list + | first) | default({}) + }} + + - name: Debug statut retenu + ansible.builtin.debug: + var: upgrade_status.json + + # 2) Vérifier si une MAJ est disponible (best effort) + - name: Tenter un "check update" (best effort) + 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_check_update_methods }}" + register: check_attempts + failed_when: false + + - name: Debug check attempts + ansible.builtin.debug: + var: check_attempts.results + + # 3) Si status=none, tenter de télécharger/préparer (best effort) + - name: Extraire status simple + ansible.builtin.set_fact: + status_simple: "{{ upgrade_status.json.data.status | default('unknown') }}" + + - name: Tenter download/prepare (best effort) si status=none + 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_download_methods }}" + register: download_attempts + failed_when: false + when: status_simple == "none" + + - name: Debug download attempts + ansible.builtin.debug: + var: download_attempts.results + when: status_simple == "none" + + # 4) Relire le statut après tentative de download + - name: Relire le statut après tentative (status) + ansible.builtin.uri: + url: "{{ base_url }}/webapi/{{ upgrade_path }}?api=SYNO.Core.Upgrade&version={{ upgrade_ver }}&method=status&_sid={{ sid }}" + method: GET + validate_certs: "{{ syno_verify_ssl }}" + return_content: true + status_code: 200 + timeout: "{{ uri_timeout }}" + register: status_after + failed_when: false + + - name: Statut final + ansible.builtin.debug: + var: status_after.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