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

Request Object

+ URL
  /api/v2/system/ha/alphorn

+ Method
  GET

+ Headers
  Content-Type: application/json
  token: ThisIsNotARealTokenGenerateYourOwnToken

+ Body
  {}

Response Object

Returns an object of the Alphorn configuration settings

+ Headers
  X-Powered-By: OpenDrives
  Access-Control-Allow-Origin: *
  Content-Type: application/json; charset=utf-8

+ Body
  {
      "interval": 30000,
      "sync": {
          "enabled": true,
          "destinations": [
              "192.168.7.62",
              "192.168.7.64"
          ]
      }
  }

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"
          ]
      }
    }
  }

Response Object

A successful configuration returns an empty object

+ Headers
  X-Powered-By: OpenDrives
  Access-Control-Allow-Origin: *
  Content-Type: application/json; charset=utf-8

+ Body
  {}

Delete All Alphorn Liferafts

Deletes all liferafts in the Alphorn configs directory

Request Object

+ URL
  /api/v2/system/ha/alphorn/liferaft/delete_all

+ Method
  GET

+ Headers
  Content-Type: application/json
  token: ThisIsNotARealTokenGenerateYourOwnToken

+ Body
  {}

Response Object

A successful response returns a list of all liferafts file which have been deleted

+ Headers
  X-Powered-By: OpenDrives
  Access-Control-Allow-Origin: *
  Content-Type: application/json; charset=utf-8

+ Body
  ['liferaft_1234abcd.tar', 'liferaft_2345cdef.tar']

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"
  }

Response Object

Returns an empty string on a successful setting of a constraint

+ Headers
  X-Powered-By: OpenDrives
  Access-Control-Allow-Origin: *
  Content-Type: application/json; charset=utf-8

+ Body
""

Delete Constraint

Delete a constraint by name or id

Request Object

+ URL
  /api/v2/system/ha/constraint/$ID/delete

+ Method
  POST

+ Parameters
  id (string, required, URL Param) - Name or Id of constraint

+ Body
  {}

Response Object

Returns an empty string on a successful deleting of a constraint

+ Headers
  X-Powered-By: OpenDrives
  Access-Control-Allow-Origin: *
  Content-Type: application/json; charset=utf-8

+ Body
""

Corosync

Corosync is the communication layer of High Availability clusters

Get Corosync Config

Get Corosync Configuration

Request Object

+ URL
  /api/v2/system/ha/corosync

+ Method
  GET

+ Body
  {}

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

Request Object

+ URL
  /api/v2/system/ha/corosync/raw

+ Method
  GET

+ Body
  {}

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

Request Object

+ URL
  /api/v2/system/ha/corosync/verify

+ Method
  GET

+ Body
  {}

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

Request Object

+ URL
  /api/v2/system/ha/corosync/key

+ Method
  GET

+ Body
  {}

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"
  }

Response Object

Sucessful setting of the key returns an empty response

+ Headers
  X-Powered-By: OpenDrives
  Access-Control-Allow-Origin: *
  Content-Type: application/json; charset=utf-8

+ Body
  <empty>

Generate Corosync Key

Generate Corosync Key and saves it to file

Request Object

+ URL
  /api/v2/system/ha/corosync/key/generate

+ Method
  GET

+ Body
  {}

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
  {}

Response Object

A successful setting will return an empty string

+ Headers
  X-Powered-By: OpenDrives
  Access-Control-Allow-Origin: *
  Content-Type: application/json; charset=utf-8

+ 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

Request Object

+ URL
  /api/v2/system/ha/property/$PROPERTY/details

+ Method
  GET

+ Parameters
  property (string, required, URL Param) - Name of property

+ Headers
  Content-Type: application/json
  token: ThisIsNotARealTokenGenerateYourOwnToken

+ Body
  {}

Response Object

Return an object of specificied pacemaker property

+ Headers
  X-Powered-By: OpenDrives
  Access-Control-Allow-Origin: *
  Content-Type: application/json; charset=utf-8

+ Body
  {
      "cluster-delay": {
          "default": "60s",
          "value": "60s"
      }
  }

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"
  }

Response Object

Return 'null' on a successful setting

+ Headers
  X-Powered-By: OpenDrives
  Access-Control-Allow-Origin: *
  Content-Type: application/json; charset=utf-8

+ Body
  null

Delete Property

Delete specified corosync property.

Note: There is no confirmation to delete when you make this call. Be careful when using this route

Request Object

+ URL
  /api/v2/system/ha/property/$PROPERTY/delete

+ Method
  GET

+ Parameters
  property (string, required, URL Param) - Name of property

+ Headers
  Content-Type: application/json
  token: ThisIsNotARealTokenGenerateYourOwnToken

+ Body
  {}

Response Object

Return 'null' on a successful deletion

+ Headers
  X-Powered-By: OpenDrives
  Access-Control-Allow-Origin: *
  Content-Type: application/json; charset=utf-8

+ Body
  null

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

Request Object

+ URL
  /api/v2/system/ha/property/delete_all

+ Method
  GET

+ Headers
  Content-Type: application/json
  token: ThisIsNotARealTokenGenerateYourOwnToken

+ Body
  {}

Response Object

Return 'null' on a successful deletion

+ Headers
  X-Powered-By: OpenDrives
  Access-Control-Allow-Origin: *
  Content-Type: application/json; charset=utf-8

+ Body
  null

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"
  }

Response Object

You’ll receive back an echo of the options used to create your resource

+ Headers
  X-Powered-By: OpenDrives
  Access-Control-Allow-Origin: *
  Content-Type: application/json; charset=utf-8

+ 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"
    }
  }

Response Object

You’ll receive back an empty string

+ Headers
  X-Powered-By: OpenDrives
  Access-Control-Allow-Origin: *
  Content-Type: application/json; charset=utf-8

+ Body
  ""

Destroy a Resource

Destroying a Resource removes it from the items managed by the cluster

Request Object

+ URL
  /api/v2/system/ha/resource/$RESOURCE_NAME/delete

+ 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 an echo of command used to destroy the resource

+ Headers
  X-Powered-By: OpenDrives
  Access-Control-Allow-Origin: *
  Content-Type: application/json; charset=utf-8

+ Body
  "Attempting to stop: resource_dummy2... Stopped\n"

Locate a Resource

If you want to know where a resource is currently running, you may ask the API to locate it

Request Object

+ URL
  /api/v2/system/ha/resource/$RESOURCE_NAME/locate

+ 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 an object with location information.

+ Headers
  X-Powered-By: OpenDrives
  Access-Control-Allow-Origin: *
  Content-Type: application/json; charset=utf-8

+ Body
  {
    "status": "running",
    "node": "09e3b2bd"
  }

Stop a Resource

You may ask the API to stop a resource from running

Request Object

+ URL
  /api/v2/system/ha/resource/$RESOURCE_NAME/stop

+ 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 an object with the name of the resource you stopped

+ Headers
  X-Powered-By: OpenDrives
  Access-Control-Allow-Origin: *
  Content-Type: application/json; charset=utf-8

+ Body
  {
    "name": "resource_dummy"
  }

Start a Resource

You may ask the API to start a resource into the running state

Request Object

+ URL
  /api/v2/system/ha/resource/$RESOURCE_NAME/start

+ 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 an object with the name of the resource you started

+ Headers
  X-Powered-By: OpenDrives
  Access-Control-Allow-Origin: *
  Content-Type: application/json; charset=utf-8

+ Body
  {
    "name": "resource_dummy"
  }

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"
  }

Response Object

You’ll receive back the an echo of the settings used to migrate

+ Headers
  X-Powered-By: OpenDrives
  Access-Control-Allow-Origin: *
  Content-Type: application/json; charset=utf-8

+ Body
  {
    "node": "6fb117bd",
    "name": "resource_dummy"
  }

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"
  }

Response Object

You’ll receive back an echo of the object you used to create the stonith agent.

+ Headers
  X-Powered-By: OpenDrives
  Access-Control-Allow-Origin: *
  Content-Type: application/json; charset=utf-8

+ Body
  {
    "name": "test_dummy2",
    "stonith_agent": "fence_dummy"
  }

Destroy a Stonith Agent

Destroying a Stonith agent will remove that agent

Request Object

+ URL
  /api/v2/system/ha/stonith/$AGENT_NAME/delete

+ Method
  POST

+ Parameters
  agent name (string, required, URL param) - The name of the instance of the stonith agent to destroy

+ Headers
  Content-Type: application/json
  token: ThisIsNotARealTokenGenerateYourOwnToken

+ Body
  {}

Response Object

You’ll receive back an echo of the command to destroy the stonith agent running

+ Headers
  X-Powered-By: OpenDrives
  Access-Control-Allow-Origin: *
  Content-Type: application/json; charset=utf-8

+ Body
  "Attempting to stop: test_dummy2... Stopped\n"

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"
  }

Response Object

You’ll receive back an echo of the object you used to create the stonith level.

+ Headers
  X-Powered-By: OpenDrives
  Access-Control-Allow-Origin: *
  Content-Type: application/json; charset=utf-8

+ Body
  {
    "level": 1,
    "node_name": "09e3b2bd",
    "stonith_name": "test_dummy"
  }

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"
  }

Response Object

You’ll receive back an echo of the object you used to destroy the stonith level.

+ Headers
  X-Powered-By: OpenDrives
  Access-Control-Allow-Origin: *
  Content-Type: application/json; charset=utf-8

+ Body
  {
    "level": "1",
    "node_name": "09e3b2bd",
    "stonith_name": "test_dummy"
  }