WEB API for Proxmox 9 HA rules

Robert Dahlem

Active Member
May 7, 2018
22
1
43
62
Hi,

I'm trying to convert my HA playbooks from HA groups to HA rules. I'm using the API as described under https://pve.proxmox.com/pve-docs/api-viewer/index.html

Let's begin with asking about existing rules. I have one rule which was created by the automatic conversion from HA groups to HA rules.

pvesh get /cluster/ha/rules gives me:
Code:
┌──────────────┐
│ rule         │
╞══════════════╡
│ ha-group-all │
└──────────────┘
and pvesh get /cluster/ha/rules/ha-group-all gives me:
Code:
┌──────┬───────────────┐
│ key  │ value         │
╞══════╪═══════════════╡
│ rule │ ha-group-all  │
├──────┼───────────────┤
│ type │ node-affinity │
└──────┴───────────────┘
but how do I get the actual rule contents like enabled, state, strict, HA resources, nodes and comment? And how about updating the values?

Also, it seems that rules have names (like "ha-group-all"), but where do I see the names in the Web UI? How do I identify a rule create in the Web UI when using the API?

In the past I could add a resource to a group by POSTing to /cluster/ha/resources with sid and group. The documentation still mentions group but there are no groups anymore.

Is there an updated version of the API documentation?

Regards,
Robert
 
Hi!

Also, it seems that rules have names (like "ha-group-all"), but where do I see the names in the Web UI? How do I identify a rule create in the Web UI when using the API?
There is currently no way to see the rule names in the web UI. I think the main reason for this was to kind of abstract away working with these IDs in the web UI for users, while they are still manageable via the API. One way to identify the rule would be through a comment. If you create the rule through the API, you can set the name/ID of the rule and then use that.

In the past I could add a resource to a group by POSTing to /cluster/ha/resources with sid and group. The documentation still mentions group but there are no groups anymore.
You have to think a bit differently about rules than you did about groups. For groups, you had a 1:1 mapping from resources to groups, which is why you could say "put resource A in group X". Since a resource can belong to multiple rules, the mental model changes a bit and you instead define a list of resources for a rule. The direction changes. So you'd POST to /cluster/ha/rules with a list of resources or PUT to /cluster/ha/rules/{rule} to update the list of resources of a rule.
 
Last edited:
Hi,

to update the rule, "resources" as list should be provided for PUT to /cluster/ha/rules/{rule} . But I don't see how to get current resource list of the rule.
GET /api2/json/cluster/ha/rules/{rule} does not allow to get one, so there is no way to append new resource to existing list.
 
to update the rule, "resources" as list should be provided for PUT to /cluster/ha/rules/{rule} . But I don't see how to get current resource list of the rule.
GET /api2/json/cluster/ha/rules/{rule} does not allow to get one, so there is no way to append new resource to existing list.

I think you need to get all rules with /cluster/ha/rules, find the one you need and add your vm to the resources field. I'm not done with the code for appendig yet but for deletion of sub_vm.vmid I wrote this in Ansible:

Code:
    - name: Get all HA rules
      uri:
        method: GET
        url: "{{api_rest_url}}/cluster/ha/rules"
        headers:
          Cookie: "{{api_cookie}}"
      delegate_to: localhost
      register: ha_rules

    - name: Extract HA rule matching the VM
      set_fact:
        ha_rule: "{{ ha_rules.json.data | selectattr('resources', 'search', '(^|,)vm:' ~ sub_vm.vmid|string ~ '(,|$)') | first | default({}) }}"

    - name: block when HA rule exists
      block:
        - name: Remove VM from HA rule
          uri:
            method: PUT
            url: "{{api_rest_url}}/cluster/ha/rules/{{ha_rule.rule}}"
            headers:
              Cookie: "{{api_cookie}}"
              CSRFPreventionToken: "{{api_prevention_token}}"
            body_format: json
            body:
              rule: "{{ha_rule.rule}}"
              type: "node-affinity"
              resources: "{{ ha_rule.resources.split(',') | reject('equalto', 'vm:'+sub_vm.vmid|string) | list | join(',') }}"
          delegate_to: localhost
      when: ha_rule != {}

You would of course need another criterion to find your rule but after that it would be only an append to resources.

And yes, it is a total waste to GET all HA rules. I stumbled over this several times in the Proxmox API.
 
Hi @Robert Dahlem,

I have actually tried /cluster/ha/rules before. Looks like pvesh get /cluster/ha/rules does not return resources. After your examples, I have tried REST API instead, and it does work. Thank you!

Code:
root@proxmox1-1:~# pvesh get /cluster/ha/rules
┌───────────────────────────────┐
│ rule                          │
╞═══════════════════════════════╡
│ ha-group-preferred_proxmox1-1 │
├───────────────────────────────┤
│ ha-group-preferred_proxmox1-3 │
├───────────────────────────────┤
│ ha-group-preferred_proxmox1-4 │
└───────────────────────────────┘

Code:
api2/json/cluster/ha/rules

[
      {
          "type": "node-affinity",
          "resources": "vm:101,vm:111,vm:119,vm:129,vm:130,vm:132,vm:135,vm:144,vm:163,vm:166",
          "order": 2,
          "comment": "Generated from HA group 'preferred_proxmox1-1'.",
          "nodes": "proxmox1-3",
          "rule": "ha-group-preferred_proxmox1-1",
          "digest": "2cd12a7ec5b68281c7dd9c664539e46300846864",
          "strict": 0
      }
      ...
]