High Availability
High Availability (HA) provides a layer of redundancy that cushions your system from possible failures or outages.
Operations
High Availability API is broken down into individual components which allow for setup, configuration, and breakdown of your HA Cluster.
Versions
Get pacemaker, corosync, and pcs service version information
Request Object
+ URL /api/v2/system/ha/versions + Method GET + Headers Content-Type: application/json token: ThisIsNotARealTokenGenerateYourOwnToken + Body {}
Response Object
Returns an object with version info
+ Headers X-Powered-By: OpenDrives Access-Control-Allow-Origin: * Content-Type: application/json; charset=utf-8 + Body { "pacemaker": "Pacemaker 2.0.1\nWritten by Andrew Beekhof\n", "corosync": "Corosync Cluster Engine, version '3.0.1'\nCopyright (c) 2006-2018 Red Hat, Inc.\n", "pcs": "0.10.1\n" }
Status
Gets the current status of the HA cluster running on the system
Request Object
+ URL /api/v2/system/ha/status + Method GET + Headers Content-Type: application/json token: ThisIsNotARealTokenGenerateYourOwnToken + Body {}
Response Object
Returns an object with raw and parsed output of the current status of the cluster
+ Headers X-Powered-By: OpenDrives Access-Control-Allow-Origin: * Content-Type: application/json; charset=utf-8 + Body { "version": "2.0.1", "summary": { "stack": { "type": "corosync" }, "current_dc": { "present": "true", "version": "2.0.1-9e909a5bdd", "name": "5e7638bc", "id": "2", "with_quorum": "true" }, "last_update": { "time": "Tue Sep 29 10:32:32 2020" }, "last_change": { "time": "Tue Sep 29 10:30:13 2020", "user": "hacluster", "client": "crmd", "origin": "5e7638bc" }, "nodes_configured": { "number": "2" }, "resources_configured": { "number": "0", "disabled": "0", "blocked": "0" }, "cluster_options": { "stonith-enabled": "false", "symmetric-cluster": "true", "no-quorum-policy": "ignore", "maintenance-mode": "false" } }, "nodes": { "node": [ { "name": "5e7638bc", "id": "2", "online": "true", "standby": "false", "standby_onfail": "false", "maintenance": "false", "pending": "false", "unclean": "false", "shutdown": "false", "expected_up": "true", "is_dc": "true", "resources_running": "0", "type": "member" }, { "name": "ae82a9a2", "id": "1", "online": "true", "standby": "false", "standby_onfail": "false", "maintenance": "false", "pending": "false", "unclean": "false", "shutdown": "false", "expected_up": "true", "is_dc": "false", "resources_running": "0", "type": "member" } ] }, "resources": {}, "node_attributes": { "node": [ { "name": "5e7638bc", "$t": "" }, { "name": "ae82a9a2", "$t": "" } ] }, "node_history": { "node": [ { "name": "5e7638bc", "$t": "" }, { "name": "ae82a9a2", "$t": "" } ] }, "fence_history": "", "tickets": "", "bans": "", "raw": "Cluster name: dolocoin\nStack: corosync\nCurrent DC: 5e7638bc (version 2.0.1-9e909a5bdd) - partition with quorum\nLast updated: Tue Sep 29 10:32:33 2020\nLast change: Tue Sep 29 10:30:13 2020 by hacluster via crmd on 5e7638bc\n\n2 nodes configured\n0 resources configured\n\nOnline: [ 5e7638bc ae82a9a2 ]\n\nNo resources\n\n\nDaemon Status:\n corosync: active/enabled\n pacemaker: active/enabled\n pcsd: active/enabled\n", "xml": "<?xml version=\"1.0\"?>\n<crm_mon version=\"2.0.1\">\n <summary>\n <stack type=\"corosync\" />\n <current_dc present=\"true\" version=\"2.0.1-9e909a5bdd\" name=\"5e7638bc\" id=\"2\" with_quorum=\"true\" />\n <last_update time=\"Tue Sep 29 10:32:32 2020\" />\n <last_change time=\"Tue Sep 29 10:30:13 2020\" user=\"hacluster\" client=\"crmd\" origin=\"5e7638bc\" />\n <nodes_configured number=\"2\" />\n <resources_configured number=\"0\" disabled=\"0\" blocked=\"0\" />\n <cluster_options stonith-enabled=\"false\" symmetric-cluster=\"true\" no-quorum-policy=\"ignore\" maintenance-mode=\"false\" />\n </summary>\n <nodes>\n <node name=\"5e7638bc\" id=\"2\" online=\"true\" standby=\"false\" standby_onfail=\"false\" maintenance=\"false\" pending=\"false\" unclean=\"false\" shutdown=\"false\" expected_up=\"true\" is_dc=\"true\" resources_running=\"0\" type=\"member\" />\n <node name=\"ae82a9a2\" id=\"1\" online=\"true\" standby=\"false\" standby_onfail=\"false\" maintenance=\"false\" pending=\"false\" unclean=\"false\" shutdown=\"false\" expected_up=\"true\" is_dc=\"false\" resources_running=\"0\" type=\"member\" />\n </nodes>\n <resources/>\n <node_attributes>\n <node name=\"5e7638bc\">\n </node>\n <node name=\"ae82a9a2\">\n </node>\n </node_attributes>\n <node_history>\n <node name=\"5e7638bc\">\n </node>\n <node name=\"ae82a9a2\">\n </node>\n </node_history>\n <fence_history>\n </fence_history>\n <tickets>\n </tickets>\n <bans>\n </bans>\n</crm_mon>\n", "cluster_name": "dolocoin" }
Services
Get the status of pacemaker, pcsd, and corosync services
Request Object
+ URL /api/v2/system/ha/services + Method GET + Headers Content-Type: application/json token: ThisIsNotARealTokenGenerateYourOwnToken + Body {}
Response Object
Returns an object with the status of each service
+ Headers X-Powered-By: OpenDrives Access-Control-Allow-Origin: * Content-Type: application/json; charset=utf-8 + Body { "services": [ { "id": "pacemaker.service", "state": "online", "locked": false }, { "id": "pcsd.service", "state": "online", "locked": false }, { "id": "corosync.service", "state": "online", "locked": false } ] }
Reset All
Shutdown and remove cluster services and configurations. Performs the same action as Destroy
Request Object
+ URL /api/v2/system/ha/reset_all + Method POST + Headers Content-Type: application/json token: ThisIsNotARealTokenGenerateYourOwnToken + Body {}
Response Object
Returns string detailing the cluster destroy status. Performs the same action as Reset All
+ Headers X-Powered-By: OpenDrives Access-Control-Allow-Origin: * Content-Type: application/json; charset=utf-8 + Body "Shutting down pacemaker/corosync services...\nKilling any remaining services...\nRemoving all cluster configuration files...\n"
Destroy
Shutdown and remove cluster services and configurations
Request Object
+ URL /api/v2/system/ha/destroy + Method GET + Headers Content-Type: application/json token: ThisIsNotARealTokenGenerateYourOwnToken + Body {}
Response Object
Returns string detailing the cluster destroy status
+ Headers X-Powered-By: OpenDrives Access-Control-Allow-Origin: * Content-Type: application/json; charset=utf-8 + Body "Shutting down pacemaker/corosync services...\nKilling any remaining services...\nRemoving all cluster configuration files...\n"
Alphorn
Alphorn is the OpenDrives identity synchronization service. It is meant to keep a copy of essential configurations of one OpenDrives system on other systems.
Get Config
Get the current Alphorn configuration settings
Set Config
Sets the current Alphorn configuration settings
Request Object
+ URL /api/v2/system/ha/alphorn + Method POST + Parameters config (object, required, Body) - the configuration settings you would like to apply to Alphorn + Headers Content-Type: application/json token: ThisIsNotARealTokenGenerateYourOwnToken + Body { "config": { "interval": 30000, "sync": { "enabled": true, "destinations": [ "192.168.7.62", "192.168.7.64" ] } } }
Constraints
You can determine the behavior of a resource in a cluster by configuring constraints for that resource. You can configure the following categories of constraints:
-
location constraints — A location constraint determines which nodes a resource can run on.
-
order constraints — An order constraint determines the order in which the resources run.
-
colocation constraints — A colocation constraint determines where resources will be placed relative to other resources.
List Constraints
List all constraints on your cluster
Request Object
+ URL /api/v2/system/ha/constraint + Method GET + Headers Content-Type: application/json token: ThisIsNotARealTokenGenerateYourOwnToken + Body {}
Response Object
Returns an object with all constraints on the cluster
+ Headers X-Powered-By: OpenDrives Access-Control-Allow-Origin: * Content-Type: application/json; charset=utf-8 + Body { "location_constraints": [ { "resource": "failoverMeasure_ipmi_bitcoin", "status": "disabled", "on": "ae82a9a2", "score": "-INFINITY", "id": "location-failoverMeasure_ipmi_bitcoin-ae82a9a2--INFINITY" }, { "resource": "failoverMeasure_ipmi_dolores_openlab_com", "status": "disabled", "on": "5e7638bc", "score": "-INFINITY", "id": "location-failoverMeasure_ipmi_dolores_openlab_com-5e7638bc--INFINITY" }, { "resource": "failoverMeasure_timeout_bitcoin", "status": "disabled", "on": "ae82a9a2", "score": "-INFINITY", "id": "location-failoverMeasure_timeout_bitcoin-ae82a9a2--INFINITY" }, { "resource": "failoverMeasure_timeout_dolores_openlab_com", "status": "disabled", "on": "5e7638bc", "score": "-INFINITY", "id": "location-failoverMeasure_timeout_dolores_openlab_com-5e7638bc--INFINITY" } ], "ordering_constraints": [ { "order": { "first": { "operation": "start", "resource": "ZFS" }, "then": { "operation": "start", "resource": "NFS" } }, "kind": "Mandatory", "id": "startingNFS" }, { "order": { "first": { "operation": "start", "resource": "ZFS" }, "then": { "operation": "start", "resource": "SMB" } }, "kind": "Mandatory", "id": "startingSMB" }, { "order": { "first": { "operation": "stop", "resource": "NFS" }, "then": { "operation": "stop", "resource": "ZFS" } }, "kind": "Mandatory", "id": "stoppingNFS" }, { "order": { "first": { "operation": "stop", "resource": "SMB" }, "then": { "operation": "stop", "resource": "ZFS" } }, "kind": "Mandatory", "id": "stoppingSMB" } ], "colocation_constraints": [], "colocation_group_constraints": [ { "resources": [ "ZFS", "SMB", "NFS", "Alphorn", "VIP_mgmt0" ], "set_id": "pcs_rsc_set_ZFS_SMB_NFS_Alphorn_VIP_mgmt0", "setOptions": { "score": "INFINITY" }, "id": "all_together" } ], "ticket_constraints": [], "raw": "Location Constraints:\n Resource: failoverMeasure_ipmi_bitcoin\n Disabled on: ae82a9a2 (score:-INFINITY) (id:location-failoverMeasure_ipmi_bitcoin-ae82a9a2--INFINITY)\n Resource: failoverMeasure_ipmi_dolores_openlab_com\n Disabled on: 5e7638bc (score:-INFINITY) (id:location-failoverMeasure_ipmi_dolores_openlab_com-5e7638bc--INFINITY)\n Resource: failoverMeasure_timeout_bitcoin\n Disabled on: ae82a9a2 (score:-INFINITY) (id:location-failoverMeasure_timeout_bitcoin-ae82a9a2--INFINITY)\n Resource: failoverMeasure_timeout_dolores_openlab_com\n Disabled on: 5e7638bc (score:-INFINITY) (id:location-failoverMeasure_timeout_dolores_openlab_com-5e7638bc--INFINITY)\nOrdering Constraints:\n start ZFS then start NFS (kind:Mandatory) (id:startingNFS)\n start ZFS then start SMB (kind:Mandatory) (id:startingSMB)\n stop NFS then stop ZFS (kind:Mandatory) (id:stoppingNFS)\n stop SMB then stop ZFS (kind:Mandatory) (id:stoppingSMB)\nColocation Constraints:\n Resource Sets:\n set ZFS SMB NFS Alphorn VIP_mgmt0 (id:pcs_rsc_set_ZFS_SMB_NFS_Alphorn_VIP_mgmt0) setoptions score=INFINITY (id:all_together)\nTicket Constraints:\n" }
Get Constraint
Get information on specific constraint type
Request Object
+ URL /api/v2/system/ha/constraint/$TYPE + Method GET + Parameters type (string, required, URL Param) - Available constraint types are `location`, `ordering`, `colocation`, `colocation_group`, `ticket`, and `raw` + Headers Content-Type: application/json token: ThisIsNotARealTokenGenerateYourOwnToken + Body {}
Response Object
Returns information on specified constraint in the cluster
+ Headers X-Powered-By: OpenDrives Access-Control-Allow-Origin: * Content-Type: application/json; charset=utf-8 + Body [ { "order": { "first": { "operation": "start", "resource": "ZFS" }, "then": { "operation": "start", "resource": "NFS" } }, "kind": "Mandatory", "id": "startingNFS" }, { "order": { "first": { "operation": "start", "resource": "ZFS" }, "then": { "operation": "start", "resource": "SMB" } }, "kind": "Mandatory", "id": "startingSMB" }, { "order": { "first": { "operation": "stop", "resource": "NFS" }, "then": { "operation": "stop", "resource": "ZFS" } }, "kind": "Mandatory", "id": "stoppingNFS" }, { "order": { "first": { "operation": "stop", "resource": "SMB" }, "then": { "operation": "stop", "resource": "ZFS" } }, "kind": "Mandatory", "id": "stoppingSMB" } ]
Set Constraint
Set specified constraint rules
Request Object
+ URL /api/v2/system/ha/constraint/$TYPE + Method POST + Headers Content-Type: application/json token: ThisIsNotARealTokenGenerateYourOwnToken + Parameters types (string, required, URL param) - Available constraint types are `order`, `order_group`, `colocation`, `colocation_group`, and `location` name (string, optional, Body) - The name of the constraint you would like to set first (object, optional, Body) - What action should occur first in order constraints or colocation constraints kind (string, optional, Body) - Available constraint kinds are `Mandatory`, `Optional`, `Serialize`, `avoids`, and `prefers` (Note: these values are case sensitive) then (object, optional, Body) - What action should occur after the `first` action in order constraints or colocation constraints resources (array, optional, Body) - Which resources should be included in this constraint score ([string, number], optional, Body) - Assigns a weight to the constraint you have specified. Constraints with higher scores get prioritized over constraints with lower scores resource (string, optional, Body) - Only for location constraints. The resource you would like to assign to a node locations (array, optional, Body) - Only for location constraints. The nodes you would like to assign a resource to setOne (object, Body) - Only for order_group constraints. The resources and options to set for that resource set. setTwo (object, Body) - Only for order_group constraints. The resources and options to set for that resource set. setOptions (object, Body) - Only for order_group constraints. The options for the order_group constraint. + Body (order) { name: "startingSMB", kind: "Mandatory", first: { operation: "start", resource: "ZFS", }, then: { operation: "start", resource: "SMB", } } + Body (order_group) { name: "order_group", resources: ["SMB", "NFS"], kind: "prefers", score: "INFINITY" } + Body (colocation) { name: "colocation_name", first: "NFS", then: "SMB", score: "INFINITY" } + Body (colocation_group) { name: "colocation_group_name", resources: ["SMB, "NFS"], score: "INFINITY", } + Body (location) { resource: "SMB", kind: "prefers", score: "INFINITY", location: "ae82a9a2" }
Corosync
Corosync is the communication layer of High Availability clusters
Get Corosync Config
Get Corosync Configuration
Response Object
Returns an object of the current corosync configuration
+ Headers X-Powered-By: OpenDrives Access-Control-Allow-Origin: * Content-Type: application/json; charset=utf-8 + Body { "totem": { "version": "2", "cluster_name": "dorocoin", "token": "3000", "token_retransmits_before_loss_const": "10", "clear_node_high_bit": "yes", "crypto_cipher": "aes256", "crypto_hash": "sha1", "rrp_mode": "passive", "interface": { "ringnumber": "0", "bindnetaddr": "192.168.7.0", "mcastaddr": "226.94.1.1", "mcastport": "5405", "ttl": "1" } }, "logging": { "to_logfile": "yes", "logfile": "/var/log/corosync/corosync.log", "to_syslog": "yes", "timestamp": "on" }, "quorum": { "provider": "corosync_votequorum", "two_node": "1", "expected_votes": "2" }, "nodelist": { "node": [ { "ring0_addr": "192.168.7.62", "name": "ae82a9a2", "nodeid": "1" }, { "ring0_addr": "192.168.7.64", "name": "5e7638bc", "nodeid": "2" } ] }, "resources": {} }
Set Corosync Config
Set Corosync Configuration
Request Object
+ URL /api/v2/system/ha/corosync + Method POST + Parameters totem (object, required, Body) - This top level directive contains configuration options for the totem protocol quorum (object, required, Body) - This top level directive contains configuration options for quorum nodelist (object, required, Body) - This top level directive contains configuration options for nodes in cluster logging (object, optional, Body) - This top level directive contains configuration options for logging resources (object, optional, Body) - This top level directive contains configuration options for resources + Body { "totem": { "version": "2", "cluster_name": "dorocoin", "token": "3000", "token_retransmits_before_loss_const": "10", "clear_node_high_bit": "yes", "crypto_cipher": "aes256", "crypto_hash": "sha1", "rrp_mode": "passive", "interface": { "ringnumber": "0", "bindnetaddr": "192.168.7.0", "mcastaddr": "226.94.1.1", "mcastport": "5405", "ttl": "1" } }, "logging": { "to_logfile": "yes", "logfile": "/var/log/corosync/corosync.log", "to_syslog": "yes", "timestamp": "on" }, "quorum": { "provider": "corosync_votequorum", "two_node": "1", "expected_votes": "2" }, "nodelist": { "node": [ { "ring0_addr": "192.168.7.62", "name": "ae82a9a2", "nodeid": "1" }, { "ring0_addr": "192.168.7.64", "name": "5e7638bc", "nodeid": "2" } ] }, "resources": {} }
Response Object
A successful setting returns a string of raw config
+ Headers X-Powered-By: OpenDrives Access-Control-Allow-Origin: * Content-Type: application/json; charset=utf-8 + Body "totem {\n\tversion: 2\n\tcluster_name: dorocoin\n\ttoken: 3000\n\ttoken_retransmits_before_loss_const: 10\n\tclear_node_high_bit: yes\n\tcrypto_cipher: aes256\n\tcrypto_hash: sha1\n\trrp_mode: passive\n\tinterface {\n\t\tringnumber: 0\n\t\tbindnetaddr: 192.168.7.0\n\t\tmcastaddr: 226.94.1.1\n\t\tmcastport: 5405\n\t\tttl: 1\n\t}\n}\nlogging {\n\tto_logfile: yes\n\tlogfile: /var/log/corosync/corosync.log\n\tto_syslog: yes\n\ttimestamp: on\n}\nquorum {\n\tprovider: corosync_votequorum\n\ttwo_node: 1\n\texpected_votes: 2\n}\nnodelist {\n\tnode {\n\t\tring0_addr: 192.168.7.62\n\t\tname: ae82a9a2\n\t\tnodeid: 1\n\t}\n\tnode {\n\t\tring0_addr: 192.168.7.64\n\t\tname: 5e7638bc\n\t\tnodeid: 2\n\t}\n}\nresources {\n}\n"
Get Corosync Raw Config
Get Corosync Configuration in raw output
Response Object
Returns a string of the corosync configuration
+ Headers X-Powered-By: OpenDrives Access-Control-Allow-Origin: * Content-Type: application/json; charset=utf-8 + Body "totem {\n\tversion: 2\n\tcluster_name: dorocoin\n\ttoken: 3000\n\ttoken_retransmits_before_loss_const: 10\n\tclear_node_high_bit: yes\n\tcrypto_cipher: aes256\n\tcrypto_hash: sha1\n\trrp_mode: passive\n\tinterface {\n\t\tringnumber: 0\n\t\tbindnetaddr: 192.168.7.0\n\t\tmcastaddr: 226.94.1.1\n\t\tmcastport: 5405\n\t\tttl: 1\n\t}\n}\nlogging {\n\tto_logfile: yes\n\tlogfile: /var/log/corosync/corosync.log\n\tto_syslog: yes\n\ttimestamp: on\n}\nquorum {\n\tprovider: corosync_votequorum\n\ttwo_node: 1\n\texpected_votes: 2\n}\nnodelist {\n\tnode {\n\t\tring0_addr: 192.168.7.62\n\t\tname: ae82a9a2\n\t\tnodeid: 1\n\t}\n\tnode {\n\t\tring0_addr: 192.168.7.64\n\t\tname: 5e7638bc\n\t\tnodeid: 2\n\t}\n}\nresources {\n}\n"
Set Corosync Raw Config
Set Corosync Raw Configuration
Request Object
+ URL /api/v2/system/ha/corosync/raw + Method POST + Parameters conf (string, required, Body) - The raw corosync configuration + Body { conf: "totem {\n\tversion: 2\n\tcluster_name: dorocoin\n\ttoken: 3000\n\ttoken_retransmits_before_loss_const: 10\n\tclear_node_high_bit: yes\n\tcrypto_cipher: aes256\n\tcrypto_hash: sha1\n\trrp_mode: passive\n\tinterface {\n\t\tringnumber: 0\n\t\tbindnetaddr: 192.168.7.0\n\t\tmcastaddr: 226.94.1.1\n\t\tmcastport: 5405\n\t\tttl: 1\n\t}\n}\nlogging {\n\tto_logfile: yes\n\tlogfile: /var/log/corosync/corosync.log\n\tto_syslog: yes\n\ttimestamp: on\n}\nquorum {\n\tprovider: corosync_votequorum\n\ttwo_node: 1\n\texpected_votes: 2\n}\nnodelist {\n\tnode {\n\t\tring0_addr: 192.168.7.62\n\t\tname: ae82a9a2\n\t\tnodeid: 1\n\t}\n\tnode {\n\t\tring0_addr: 192.168.7.64\n\t\tname: 5e7638bc\n\t\tnodeid: 2\n\t}\n}\nresources {\n}\n" }
Response Object
A successful setting will return the config as a string
+ Headers X-Powered-By: OpenDrives Access-Control-Allow-Origin: * Content-Type: application/json; charset=utf-8 + Body "totem {\n\tversion: 2\n\tcluster_name: dorocoin\n\ttoken: 3000\n\ttoken_retransmits_before_loss_const: 10\n\tclear_node_high_bit: yes\n\tcrypto_cipher: aes256\n\tcrypto_hash: sha1\n\trrp_mode: passive\n\tinterface {\n\t\tringnumber: 0\n\t\tbindnetaddr: 192.168.7.0\n\t\tmcastaddr: 226.94.1.1\n\t\tmcastport: 5405\n\t\tttl: 1\n\t}\n}\nlogging {\n\tto_logfile: yes\n\tlogfile: /var/log/corosync/corosync.log\n\tto_syslog: yes\n\ttimestamp: on\n}\nquorum {\n\tprovider: corosync_votequorum\n\ttwo_node: 1\n\texpected_votes: 2\n}\nnodelist {\n\tnode {\n\t\tring0_addr: 192.168.7.62\n\t\tname: ae82a9a2\n\t\tnodeid: 1\n\t}\n\tnode {\n\t\tring0_addr: 192.168.7.64\n\t\tname: 5e7638bc\n\t\tnodeid: 2\n\t}\n}\nresources {\n}\n"
Verify Corosync Config
Verify Corosync Configuration
Response Object
Returns a string verifying the corosync configuration
+ Headers X-Powered-By: OpenDrives Access-Control-Allow-Origin: * Content-Type: application/json; charset=utf-8 + Body "Sep 29 14:13:10 warning [MAIN ] interface section bindnetaddr is used together with nodelist. Nodelist one is going to be used.\nSep 29 14:13:10 warning [MAIN ] Please migrate config file to nodelist.\nSep 29 14:13:10 notice [MAIN ] Corosync Cluster Engine exiting normally\n"
Get Corosync Key
Get Corosync Key
Response Object
Returns an object with corosync key
+ Headers X-Powered-By: OpenDrives Access-Control-Allow-Origin: * Content-Type: application/json; charset=utf-8 + Body { key: "78496f1ceed3d70f0eaffbfd0d0097dee20650aca8b89ff6cff1ea660b7a159d1c49ea8deff02f54769d6628053421d07bf5f01215e3dbbda21eaa9803e758b6e328ba4fd0035d739f0a4f09ee6ac8bbbd5f065f54d1bf14f39b80d3703c0614a9683305957d87fd1a290c1d3fa6a88a05caf0b930630686f07f410f9f349daaa058e92032773214a1ce786ee86d05032184f88b44810b1557c3aad0c5b34f35319d8c9dce8029f2f15f9704bcce782b40e89a4c540ea285dfb4c3c5bdf3e54ad3eb5b0b02e5a527f28f3c3a92b2004551078b9aa7dbb4dcdc314d0695a02e5aa93fe4883b83b65554d1bf92a66efa6670eb1fbc1d2b4b93d2a367df196a4166" }
Set Corosync Key
Set Corosync Key
Request Object
+ URL /api/v2/system/ha/corosync/key + Method POST + Parameters key (string, required, Body) - Pass a hexadecimal 'key' to set corosync key + Body { key: "78496f1ceed3d70f0eaffbfd0d0097dee20650aca8b89ff6cff1ea660b7a159d1c49ea8deff02f54769d6628053421d07bf5f01215e3dbbda21eaa9803e758b6e328ba4fd0035d739f0a4f09ee6ac8bbbd5f065f54d1bf14f39b80d3703c0614a9683305957d87fd1a290c1d3fa6a88a05caf0b930630686f07f410f9f349daaa058e92032773214a1ce786ee86d05032184f88b44810b1557c3aad0c5b34f35319d8c9dce8029f2f15f9704bcce782b40e89a4c540ea285dfb4c3c5bdf3e54ad3eb5b0b02e5a527f28f3c3a92b2004551078b9aa7dbb4dcdc314d0695a02e5aa93fe4883b83b65554d1bf92a66efa6670eb1fbc1d2b4b93d2a367df196a4166" }
Generate Corosync Key
Generate Corosync Key and saves it to file
Response Object
Successful generate returns a string confirmation generation and writing of key
+ Headers X-Powered-By: OpenDrives Access-Control-Allow-Origin: * Content-Type: application/json; charset=utf-8 + Body "Corosync Cluster Engine Authentication key generator.\nGathering 2048 bits for key from /dev/urandom.\nWriting corosync key to /etc/corosync/authkey.\n"
Node
List Nodes
View current status of nodes from pacemaker
Request Object
+ URL /api/v2/system/ha/node + Method GET + Headers Content-Type: application/json token: ThisIsNotARealTokenGenerateYourOwnToken + Body {}
Response Object
Returns an object with pacemaker node information
+ Headers X-Powered-By: OpenDrives Access-Control-Allow-Origin: * Content-Type: application/json; charset=utf-8 + Body { "pacemaker_nodes": { "online": [ "5e7638bc", "ae82a9a2" ], "standby": [], "maintenance": [], "offline": [] }, "pacemaker_remote_nodes": { "online": [], "standby": [], "maintenance": [], "offline": [] } }
Online/Standby/Delete/Fence Node
Set node to specified state
Request Object
+ URL /api/v2/system/ha/node/$NAME/$STATE + Method GET + Parameters name (string, required, URL Param) - Name of node state (string, required, URL Param) - Available states are `online`, `standby`, `delete`, or `fence` + Headers Content-Type: application/json token: ThisIsNotARealTokenGenerateYourOwnToken + Body {}
Property
List, View, Set, Delete Pacemaker Properties
List Property
List Pacemaker Properties
Request Object
+ URL /api/v2/system/ha/property + Method GET + Headers Content-Type: application/json token: ThisIsNotARealTokenGenerateYourOwnToken + Body {}
Response Object
Return an object of pacemaker settings
+ Headers X-Powered-By: OpenDrives Access-Control-Allow-Origin: * Content-Type: application/json; charset=utf-8 + Body { "batch-limit": { "default": "0", "value": "0" }, "cluster-delay": { "default": "60s", "value": "60s" }, "cluster-ipc-limit": { "default": "500", "value": "500" }, "cluster-recheck-interval": { "default": "15min", "value": "15min" }, "concurrent-fencing": { "default": "false", "value": "false" }, "dc-deadtime": { "default": "20s", "value": "20s" }, "election-timeout": { "default": "2min", "value": "2min" }, "enable-acl": { "default": "false", "value": "false" }, "enable-startup-probes": { "default": "true", "value": "false" }, "have-watchdog": { "default": "false", "value": "false" }, "join-finalization-timeout": { "default": "30min", "value": "30min" }, "join-integration-timeout": { "default": "3min", "value": "3min" }, "load-threshold": { "default": "80%", "value": "80%" }, "maintenance-mode": { "default": "false", "value": "false" }, "migration-limit": { "default": "-1", "value": "-1" }, "no-quorum-policy": { "default": "stop", "value": "ignore" }, "node-action-limit": { "default": "0", "value": "0" }, "node-health-base": { "default": "0", "value": "0" }, "node-health-green": { "default": "0", "value": "0" }, "node-health-red": { "default": "-INFINITY", "value": "-INFINITY" }, "node-health-strategy": { "default": "none", "value": "none" }, "node-health-yellow": { "default": "0", "value": "0" }, "pe-error-series-max": { "default": "-1", "value": "-1" }, "pe-input-series-max": { "default": "4000", "value": "4000" }, "pe-warn-series-max": { "default": "5000", "value": "5000" }, "placement-strategy": { "default": "default", "value": "default" }, "remove-after-stop": { "default": "false", "value": "false" }, "shutdown-escalation": { "default": "20min", "value": "20min" }, "start-failure-is-fatal": { "default": "true", "value": "true" }, "startup-fencing": { "default": "true", "value": "true" }, "stonith-action": { "default": "reboot", "value": "reboot" }, "stonith-enabled": { "default": "true", "value": "true" }, "stonith-max-attempts": { "default": "10", "value": "10" }, "stonith-timeout": { "default": "60s", "value": "60s" }, "stonith-watchdog-timeout": { "default": "(null)", "value": "(null)" }, "stop-all-resources": { "default": "false", "value": "false" }, "stop-orphan-actions": { "default": "true", "value": "true" }, "stop-orphan-resources": { "default": "true", "value": "true" }, "symmetric-cluster": { "default": "true", "value": "true" }, "transition-delay": { "default": "0s", "value": "0s" } }
Get Property
Get specified corosync property
Set Property
Set specified corosync property
Request Object
+ URL /api/v2/system/ha/property/$PROPERTY/set + Method POST + Parameters property (string, required, Body) - Name of property key/value (object, required, Body) - key/value to set property + Headers Content-Type: application/json token: ThisIsNotARealTokenGenerateYourOwnToken + Body { "default": "60s", "value": "60s" }
Delete Property
Delete specified corosync property.
Note: There is no confirmation to delete when you make this call. Be careful when using this route
Delete All Properties
Delete All corosync properties.
Note: There is no confirmation to delete when you make this call. Be careful when using this route
Resources
A resource is a managerial process to ensure the availability of the system process or processes it manages.
List all Running Resources
You may list all the current resources in a cluster.
Request Object
+ URL /api/v2/system/ha/resource + Method GET + Headers Content-Type: application/json token: ThisIsNotARealTokenGenerateYourOwnToken + Body {}
Response Object
You’ll receive back an array of the resources in the system
+ Headers X-Powered-By: OpenDrives Access-Control-Allow-Origin: * Content-Type: application/json; charset=utf-8 + Body [ { "name": "ZFS", "class": "ocf", "provider": "opendrives", "type": "ZFS", "meta": { "migration-threshold": "0", "multiple-active": "stop_start", "resource-stickiness": "100" }, "op": { "restart": { "name": "ZFS-monitor-interval-20", "timeout": "60" }, "start": { "name": "ZFS-start-interval-0s", "interval": "0s", "timeout": "45s" }, "stop": { "name": "ZFS-stop-interval-0s", "interval": "0s", "timeout": "45s" } } }, { "name": "SMB", "class": "lsb", "type": "smbd", "meta": { "migration-threshold": "0", "multiple-active": "stop_start", "resource-stickiness": "100" }, "op": { "reload": { "name": "SMB-force-reload-interval-0s", "interval": "0s", "timeout": "15" }, "restart": { "name": "SMB-restart-interval-0s", "interval": "0s", "timeout": "15" }, "start": { "name": "SMB-start-interval-0s", "interval": "0s", "timeout": "15" }, "stop": { "name": "SMB-stop-interval-0s", "interval": "0s", "timeout": "15" } } }, { "name": "NFS", "class": "ocf", "provider": "opendrives", "type": "nfsserver", "meta": { "migration-threshold": "0", "multiple-active": "stop_start", "resource-stickiness": "100" }, "op": { "restart": { "name": "NFS-monitor-interval-20", "timeout": "60" }, "start": { "name": "NFS-start-interval-0s", "interval": "0s", "timeout": "40" }, "stop": { "name": "NFS-stop-interval-0s", "interval": "0s", "timeout": "20s" } } }, { "name": "Alphorn", "class": "systemd", "type": "alphorn", "meta": { "migration-threshold": "0", "multiple-active": "stop_start", "resource-stickiness": "100" }, "op": { "restart": { "name": "Alphorn-monitor-interval-20", "timeout": "60" }, "start": { "name": "Alphorn-start-interval-0s", "interval": "0s", "timeout": "100" }, "stop": { "name": "Alphorn-stop-interval-0s", "interval": "0s", "timeout": "100"a } } } ]
View one Resource
As is typical with other routes in the API, you can also get information on one resource
Request Object
+ URL /api/v2/system/ha/resource/$RESOURCE_NAME/details + Method GET + Parameters resource name (string, required, URL param) - The name given to the resource + Headers Content-Type: application/json token: ThisIsNotARealTokenGenerateYourOwnToken + Body {}
Response Object
You’ll receive back an array of the resource you requested
+ Headers X-Powered-By: OpenDrives Access-Control-Allow-Origin: * Content-Type: application/json; charset=utf-8 + Body [ { "name": "SMB", "class": "lsb", "type": "smbd", "meta": { "migration-threshold": "0", "multiple-active": "stop_start", "resource-stickiness": "100" }, "op": { "reload": { "name": "SMB-force-reload-interval-0s", "interval": "0s", "timeout": "15" }, "restart": { "name": "SMB-restart-interval-0s", "interval": "0s", "timeout": "15" }, "start": { "name": "SMB-start-interval-0s", "interval": "0s", "timeout": "15" }, "stop": { "name": "SMB-stop-interval-0s", "interval": "0s", "timeout": "15" } } } ]
Create a Resource
Creating a Resource adds it to the items managed by the cluster
Request Object
+ URL /api/v2/system/ha/resource/ + Method POST + Parameters name (string, required, Body) - The name to give this instance of the resource agent resource_agent (string, required, Body) - The type of resource agent to create params (object, optional, Body) - The parameters to apply to the resource agent meta (object, optional, Body) - The meta properties to set on the resource agent operations (object, optional, Body) - The operations properties to set on the resource agent clone (object, optional, Body) - The clone options to set on the resource agent + Headers Content-Type: application/json token: ThisIsNotARealTokenGenerateYourOwnToken + Body { "name": "resource_dummy", "resource_agent": "ocf:heartbeat:Dummy" }
Update a Resource
Updating a Resource adds it to the items managed by the cluster
Request Object
+ URL /api/v2/system/ha/resource/$NAME/update + Method POST + Parameters name (string, required, Body) - The name to give this instance of the resource agent params (object, optional, Body) - The parameters to apply to the resource agent meta (object, optional, Body) - The meta properties to set on the resource agent operations (object, optional, Body) - The operations properties to set on the resource agent + Headers Content-Type: application/json token: ThisIsNotARealTokenGenerateYourOwnToken + Body { "params": { "ip": "192.168.0.98" }, "operations": { "interval": "30s" } }
Destroy a Resource
Destroying a Resource removes it from the items managed by the cluster
Locate a Resource
If you want to know where a resource is currently running, you may ask the API to locate it
Stop a Resource
You may ask the API to stop a resource from running
Start a Resource
You may ask the API to start a resource into the running state
Cleanup a Resource
If a resource has trouble with the underlying service or services being managed, they will sometimes log a failure event. Once the underlying service has been addressed, you will want to cleanup that failure event.
Request Object
+ URL /api/v2/system/ha/resource/$RESOURCE_NAME/cleanup + Method GET + Parameters resource name (string, required, URL param) - The name of this instance of the resource agent + Headers Content-Type: application/json token: ThisIsNotARealTokenGenerateYourOwnToken + Body {}
Response Object
You’ll receive back the output of the cleanup command
+ Headers X-Powered-By: OpenDrives Access-Control-Allow-Origin: * Content-Type: application/json; charset=utf-8 + Body "Cleaned up resource_dummy on 09e3b2bd\n\n * The configuration specifies that 'resource_dummy' should remain stopped\n"
Create a Resource Group
You may add resources to a group. Resources within a group are colocated and ordered in the order they are added to the group.
Request Object
+ URL /api/v2/system/ha/resource/group/set + Method POST + Parameters groupName (string, required, Body) - The name of the resource group resources (array, required, Body) - The names of resources to add to the group order (object, optional, Body) - Specify the position (before/after) relative to an existing resource in the group in which to add the array of resources. This impacts the start order of the grouped resources. + Headers Content-Type: application/json token: ThisIsNotARealTokenGenerateYourOwnToken + Body { "groupName": "Primary_Group", "resources": ["ZFS", "SMB", "NFS"], "order": { "position": "before", "resource": "Docker" } }
Response Object
You’ll receive back an echo of the settings used to create/update the resource group
+ Headers X-Powered-By: OpenDrives Access-Control-Allow-Origin: * Content-Type: application/json; charset=utf-8 + Body { "groupName": "Primary_Group", "resources": ["ZFS", "SMB", "NFS"], "order": { "position": "before", "resource": "Docker" } }
Migrate a Resource
You may wish to transfer a resource to a node other than the one it is on. You can do so by calling migrate
Request Object
+ URL /api/v2/system/ha/resource/$RESOURCE_NAME/migrate + Method POST + Parameters resource name (string, required, URL param) - The name of this instance of the resource agent node (string, required, Body) - The name of the node to migrate this resource to + Headers Content-Type: application/json token: ThisIsNotARealTokenGenerateYourOwnToken + Body { "node": "6fb117bd" }
Resource Agent
Resource Agents are the 'pattern' to create a resource. View the available resource agents to find what kind of resources you can support
View Available Resource Agent Providers
A resource agent provider is like an author of resource agents. You can view these here.
Request Object
+ URL /api/v2/system/ha/resource_agent/providers + Method GET + Headers Content-Type: application/json token: ThisIsNotARealTokenGenerateYourOwnToken + Body {}
Response Object
You’ll receive back an array of the providers in the system
+ Headers X-Powered-By: OpenDrives Access-Control-Allow-Origin: * Content-Type: application/json; charset=utf-8 + Body [ "lsb", "service", "systemd", "ocf:heartbeat", "ocf:lustre", "ocf:opendrives", "ocf:pacemaker", "ocf:redhat" ]
View Available Resource Agents
You may request all available resource agents
Request Object
+ URL /api/v2/system/ha/resource_agent + Method GET + Headers Content-Type: application/json token: ThisIsNotARealTokenGenerateYourOwnToken + Body {}
Response Object
You’ll receive back an array of the available agents in the system
+ Headers X-Powered-By: OpenDrives Access-Control-Allow-Origin: * Content-Type: application/json; charset=utf-8 + Body [ "lsb:acpid", "lsb:apcupsd", "lsb:apparmor", "lsb:atd", "lsb:binfmt-support", "lsb:bluetooth", "lsb:corosync", "lsb:cron", "lsb:ctdb", "lsb:dbus", "lsb:docker", "lsb:fio", "lsb:hwclock.sh", "lsb:ipmievd", "lsb:iwpmd", ... ... ]
View Available Resource Agents by Provider
You may request all available resource agents by a certain provider as well
Request Object
+ URL /api/v2/system/ha/resource_agent/$PROVIDER_NAME/details + Method GET + Parameters provider name (string, required, URL param) - The name of a resource provider + Headers Content-Type: application/json token: ThisIsNotARealTokenGenerateYourOwnToken + Body {}
Response Object
You’ll receive back an array of the available agents in the system by the provider you specified.
+ Headers X-Powered-By: OpenDrives Access-Control-Allow-Origin: * Content-Type: application/json; charset=utf-8 + Body [ "ocf:heartbeat:aliyun-vpc-move-ip", "ocf:heartbeat:anything", "ocf:heartbeat:AoEtarget", "ocf:heartbeat:apache", "ocf:heartbeat:asterisk", "ocf:heartbeat:AudibleAlarm", "ocf:heartbeat:aws-vpc-move-ip", "ocf:heartbeat:aws-vpc-route53", "ocf:heartbeat:awseip", "ocf:heartbeat:awsvip", "ocf:heartbeat:azure-events", "ocf:heartbeat:azure-lb", "ocf:heartbeat:ClusterMon", "ocf:heartbeat:clvm", "ocf:heartbeat:conntrackd", "ocf:heartbeat:CTDB", ... ... ]
View Available Resource Agent information
To view the resource agent specification information, request this route
Request Object
+ URL /api/v2/system/ha/resource_agent/$AGENT_NAME/info + Method GET + Parameters agent name (string, required, URL param) - The name of a resource agent + Headers Content-Type: application/json token: ThisIsNotARealTokenGenerateYourOwnToken + Body {}
Response Object
You’ll receive back the raw text of the agent resource’s information.
+ Headers X-Powered-By: OpenDrives Access-Control-Allow-Origin: * Content-Type: application/json; charset=utf-8 + Body "ocf:heartbeat:Dummy - Example stateless resource agent\n\nThis is a Dummy Resource Agent. It does absolutely nothing except \nkeep track of whether its running or not.\nIts purpose in life is for testing and to serve as a template for RA writers.\n\nNB: Please pay attention to the timeouts specified in the actions\nsection below. They should be meaningful for the kind of resource\nthe agent manages. They should be the minimum advised timeouts,\nbut they shouldn't/cannot cover _all_ possible resource\ninstances. So, try to be neither overly generous nor too stingy,\nbut moderate. The minimum timeouts should never be below 10 seconds.\n\nResource options:\n state: Location to store the resource state in.\n fake: Fake attribute that can be changed to cause a reload\n\nDefault operations:\n start: interval=0s timeout=20s\n stop: interval=0s timeout=20s\n monitor: interval=10s timeout=20s\n reload: interval=0s timeout=20s\n migrate_to: interval=0s timeout=20s\n migrate_from: interval=0s timeout=20s\n"
Failover Measures, also known as Stonith
Failover Measures are failsafe features that you may setup to forcibly offline a node in the event that it stops responding.
View Available Stonith Agents
Similar to Resource Agents, Stonith Agents provide a framework to enforce nodes behavior
Request Object
+ URL /api/v2/system/ha/stonith/agent + Method GET + Headers Content-Type: application/json token: ThisIsNotARealTokenGenerateYourOwnToken + Body {}
Response Object
You’ll receive back an array listing the available stonith agents in the system
+ Headers X-Powered-By: OpenDrives Access-Control-Allow-Origin: * Content-Type: application/json; charset=utf-8 + Body [ "apcmaster", "apcmastersnmp", "apcsmart", "baytech", "bladehpi", "cyclades", "drac3", "external/drac5", "external/dracmc-telnet", "external/hetzner", "external/hmchttp", "external/ibmrsa", "external/ibmrsa-telnet", "external/ipmi", "external/ippower9258", "external/kdumpcheck", "external/libvirt", "external/nut", "external/rackpdu", "external/riloe", "external/ssh", ... ... ]
Get Details on an Available Stonith Agent
You can view the details of a particular stonith agent.
Request Object
+ URL /api/v2/system/ha/stonith/agent/info + Method POST + Parameters agent (string, required) - The name of the stonith agent you wish to get information on. + Headers Content-Type: application/json token: ThisIsNotARealTokenGenerateYourOwnToken + Body { "agent": "fence_dummy" }
Response Object
You’ll receive back the raw text information about the requested stonith agent
+ Headers X-Powered-By: OpenDrives Access-Control-Allow-Origin: * Content-Type: application/json; charset=utf-8 + Body "fence_dummy - Dummy fence agent\n\nfence_dummy\n\nStonith options:\n random_sleep_range: Issue a sleep between 1 and X seconds. Used for testing.\n status_file: File with status\n type: Type of the dummy fence agent\n quiet: Disable logging to stderr. Does not affect --verbose or --debug-file or\n logging to syslog.\n verbose: Verbose mode\n debug_file: Write debug information to given file\n delay: Wait X seconds before fencing is started\n login_timeout: Wait X seconds for cmd prompt after login\n power_timeout: Test X seconds for status change after ON/OFF\n power_wait: Wait X seconds after issuing ON/OFF\n shell_timeout: Wait X seconds for cmd prompt after issuing command\n retry_on: Count of attempts to retry power on\n pcmk_host_map: A mapping of host names to ports numbers for devices that do\n not support host names. Eg. node1:1;node2:2,3 would tell the\n cluster to use port 1 for node1 and ports 2 and 3 for node2\n pcmk_host_list: A list of machines controlled by this device (Optional unless\n pcmk_host_check=static-list).\n pcmk_host_check: How to determine which machines are controlled by the device.\n Allowed values: dynamic-list (query the device via the 'list'\n command), static-list (check the pcmk_host_list attribute),\n status (query the device via the 'status' command), none\n (assume every device can fence every machine)\n pcmk_delay_max: Enable a random delay for stonith actions and specify the\n maximum of random delay. This prevents double fencing when\n using slow devices such as sbd. Use this to enable a random\n delay for stonith actions. The overall delay is derived from\n this random delay value adding a static delay so that the sum\n is kept below the maximum delay.\n pcmk_delay_base: Enable a base delay for stonith actions and specify base\n delay value. This prevents double fencing when different\n delays are configured on the nodes. Use this to enable a\n static delay for stonith actions. The overall delay is\n derived from a random delay value adding this static delay so\n that the sum is kept below the maximum delay.\n pcmk_action_limit: The maximum number of actions can be performed in parallel\n on this device Cluster property concurrent-fencing=true\n needs to be configured first. Then use this to specify the\n maximum number of actions can be performed in parallel on\n this device. -1 is unlimited.\n\nDefault operations:\n monitor: interval=60s\n"
List Stonith Agents
You can view the current Failover Measures assigned to your cluster
Request Object
+ URL /api/v2/system/ha/stonith + Method GET + Headers Content-Type: application/json token: ThisIsNotARealTokenGenerateYourOwnToken + Body {}
Response Object
You’ll receive back an object describing the current environment
+ Headers X-Powered-By: OpenDrives Access-Control-Allow-Origin: * Content-Type: application/json; charset=utf-8 + Body { "raw": " Resource: test_dummy (class=stonith type=fence_dummy)\n Operations: monitor interval=60s (test_dummy-monitor-interval-60s)\n Resource: test_dummy2 (class=stonith type=fence_dummy)\n Operations: monitor interval=60s (test_dummy2-monitor-interval-60s)\n", "resources": [ { "name": "test_dummy", "class": "stonith", "type": "fence_dummy", "op": { "monitor": { "name": "test_dummy-monitor-interval-60s", "interval": "60s" } } }, { "name": "test_dummy2", "class": "stonith", "type": "fence_dummy", "op": { "monitor": { "name": "test_dummy2-monitor-interval-60s", "interval": "60s" } } } ], "targets": [] }
Create a Stonith Agent
Creating a Stonith agent will allow that agent to halt a node in your cluster if it stops responding
Request Object
+ URL /api/v2/system/ha/stonith/create + Method POST + Parameters name (string, required, Body) - The name to give this instance of the stonith agent agent (string, required, Body) - The type of stonith agent to create params (JSON, optional, Body) - The parameters to apply to the stonith agent meta (JSON, optional, Body) - The meta properties to set on the stonith agent operations (JSON, optional, Body) - The operations properties to set on the stonith agent + Headers Content-Type: application/json token: ThisIsNotARealTokenGenerateYourOwnToken + Body { "name": "test_dummy", "agent": "fence_dummy" }
Destroy a Stonith Agent
Destroying a Stonith agent will remove that agent
Create a Stonith Level
Stonith Levels are tiers of escalation to attempt to stop a node. If the first tier fails to stop the node, the cluster will escalate urgency of levels to attempt to stop the node a different way.
Request Object
+ URL /api/v2/system/ha/stonith/level/create + Method POST + Parameters level (number, required, Body) - The level to apply to the node + stonith agent pair node_name (string, required, Body) - The name of a node in the cluster. (Note, using the HA wizard in the UI will automatically name nodes after your hostid) stonith_name (string, required, Body) - The name of an instance of a stonith agent + Headers Content-Type: application/json token: ThisIsNotARealTokenGenerateYourOwnToken + Body { "stonith_name": "test_dummy", "level": 1, "node_name": "09e3b2bd" }
Destroy a Stonith Level
Destroying a Stonith level will remove that level from the node, but will not destroy the stonith agent
Request Object
+ URL /api/v2/system/ha/stonith/level/$LEVEL/delete + Method POST + Parameters level (number, required, URL param) - The level applied to the node + stonith agent pair node_name (string, required, Body) - The name of a node in the cluster. (Note, using the HA wizard in the UI will automatically name nodes after your hostid) stonith_name (string, required, Body) - The name of an instance of a stonith agent + Headers Content-Type: application/json token: ThisIsNotARealTokenGenerateYourOwnToken + Body { "stonith_name": "test_dummy", "node_name": "09e3b2bd" }