Files
pve-confsync/docs/api-pve.md
T
2026-10-23 17:43:20 +02:00

9.2 KiB

API Proxmox VE 9.x utilisée par pve-confsync

Vérifiée le 2026-10-13 (comptes : 2026-10-23) dans les sources Proxmox (miroirs GitHub officiels), faute d'accès à l'API viewer (https://pve.proxmox.com/pve-docs/api-viewer/) depuis l'environnement de développement. Versions lues : pve-manager 9.2.21, libpve-network-perl 1.6.7, pve-cluster 9.1.6. À recouper avec l'API viewer et les deux clusters de labo avant la phase 1.

Toutes les routes sont relatives à /api2/json. Authentification par ticket du compte root@pam : POST /access/ticket (username, password) renvoie ticket et CSRFPreventionToken (AccessControl.pm L198) ; le ticket est envoyé dans le cookie PVEAuthCookie, le jeton CSRF dans l'en-tête CSRFPreventionToken sur les écritures. Durée de vie du ticket : 2 h (AccessControl.pm L58) ; pve-confsync se reconnecte après 90 min ou sur un 401. Un compte root avec TFA renvoie NeedTFA (L167) : refusé. Écritures en application/x-www-form-urlencoded (tableaux = paramètre répété), suppression de champs via le paramètre delete=a,b.

Version et cluster

Méthode Chemin Usage Droit
GET /cluster/status nœuds en ligne Sys.Audit sur /
GET /nodes/{node}/version version (9.2.21), release (9.2) : refus si majeur ≠ 9 —
GET /version repli pour un nœud isolé (API2.pm) —
GET /nodes/{node}/tasks/{upid}/status suivi de la tâche de rechargement SDN —

Options datacenter (datacenter.cfg)

Méthode Chemin Droit
GET /cluster/options (Cluster.pm) Sys.Audit sur / (sinon seuls console et tag-style)
PUT /cluster/options (Cluster.pm) Sys.Modify sur /

Points d'attention (DataCenterConfig.pm) :

  • le GET renvoie des valeurs déjà analysées : tag-style, next-id, user-tag-access, migration, ha, crs, notify, webauthn, u2f sous forme d'objets, registered-tags et user-tag-access.user-allow-list sous forme de tableaux ; le PUT attend des property strings (shape=full,color-map=a:ff0000, listes séparées par ;). L'adaptateur stocke la forme canonique « property string, clés triées ».
  • le GET ajoute toujours description (vide possible), mac_prefix (BC:24:11 par défaut, L11) et allowed-tags (lecture seule) : retirés à la normalisation.
  • formats : tag-style L286, user-tag-access L321, next-id L203.

SDN (SDN.pm)

Méthode Chemin Usage Droit
POST /cluster/sdn/lock verrou global, renvoie le lock-token ; refusé s'il existe des changements en attente (sauf allow-pending=1) SDN.Allocate sur /sdn
DELETE /cluster/sdn/lock libère le verrou (lock-token ou force=1) SDN.Allocate
POST /cluster/sdn/rollback annule les changements en attente (lock-token, release-lock) SDN.Allocate
PUT /cluster/sdn commit + rechargement réseau de tous les nœuds, renvoie un UPID (lock-token, release-lock) SDN.Allocate
GET /cluster/sdn/dry-run?node= diff frr / interfaces.d/sdn (libpve-network-perl ≥ 1.3.0, mars 2026) : non utilisé en phase 0 Sys.Audit sur /nodes/{node}
GET /nodes/{node}/sdn/zones statut des zones par nœud (available, pending, error) SDN.Audit

Le verrou et le paramètre lock-token sur toutes les écritures existent depuis libpve-network-perl 1.1.3 (juillet 2025, avant PVE 9.0) : disponibles sur tout PVE 9.x.

Zones, VNets, subnets

Objet Liste / création Élément Notes
zone /cluster/sdn/zones /cluster/sdn/zones/{zone} GET d'un élément = SDN.Allocate : on lit donc la liste (SDN.Audit suffit)
vnet /cluster/sdn/vnets /cluster/sdn/vnets/{vnet}
subnet /cluster/sdn/vnets/{vnet}/subnets .../subnets/{zone}-{ip}-{masque} création : subnet=<cidr>, type=subnet ; id calculé (SubnetPlugin.pm)

Les GET acceptent running=1 (configuration appliquée) ou pending=1 ; sans paramètre, la configuration courante, en attente comprise. La référence est lue en running=1, les clients sans paramètre.

Champs (schémas : VlanPlugin.pm, VxlanPlugin.pm, VnetPlugin.pm, SubnetPlugin.pm) :

  • zone vlan : bridge (obligatoire), bridge-disable-mac-learning, nodes, mtu, dns, reversedns, dnszone, ipam
  • zone vxlan : peers, vxlan-port (4789), fabric, nodes, mtu, dns, reversedns, dnszone, ipam
  • vnet : zone (obligatoire), tag, alias, vlanaware, isolate-ports
  • subnet : vnet, gateway, snat, dnszoneprefix, dhcp-range (tableau), dhcp-dns-server
  • calculés par PVE, ignorés : digest, state, pending, et pour les subnets cidr, network, mask, zone

Comptes du royaume pve (vérifié le 2026-10-23, pve-access-control dff26b45, pve-cluster 86d4bb9e)

Objet Liste / création Élément Notes
groupe /access/groups (Group.pm L26) /access/groups/{groupid} champ comment ; users calculé, ignoré
rôle /access/roles (Role.pm L31) /access/roles/{roleid} (PUT) rôles special (intégrés) ignorés, non modifiables (L146) ; privs trié
utilisateur /access/users?full=1 (User.pm L156) /access/users/{userid} seuls les @pve ; tokens, realm-type, champs de verrou TFA ignorés ; groups liste triée ; password jamais envoyé par l'API ; root@pam jamais supprimé

Mots de passe. L'API ne renvoie pas les hachés : ils sont dans /etc/pve/priv/shadow.cfg (lignes user:hash:, utilisateur sans royaume, Auth/PVE.pm L13-L50). Lecture et écriture par SSH en root :

  • lecture : cat /etc/pve/priv/shadow.cfg ;
  • écriture : script perl sous PVE::Auth::PVE::lock_shadow_config (L51) avec cfs_read_file / cfs_write_file, comme store_password (L95-L98) : le haché est recopié tel quel, sans le recalculer. cfs_read_file sans version relit toujours le fichier (Cluster.pm).

À valider sur un vrai cluster : script d'écriture du shadow, forme réelle de /access/users?full=1, mise à jour d'un utilisateur avec champs vidés.

Droits

Accès en root@pam (API + SSH, même mot de passe), sans TFA. La référence (primaire) n'est jamais écrite. Le certificat TLS et la clé d'hôte SSH sont épinglés au premier test.