ClusterControl CMON RPC v2 API Reference
Introduction
This is the documentation of the RPC v2, a new RPC interface for the Cmon Controller that exists beside the original (or v1) interface. The two versions of the RPC interface are independent from each other, one can be used without the services of the other.
Connection requirements
RPC v2 is available only over TLS (HTTPS). Connect to port 9501 on the
/v2 path prefix. Almost all endpoints require authentication first.
Please note that the RPC v2 API calls are available only using secure (TLS) connections, encryption is mandatory. The RPC v2 also uses an authentication call, very little of the calls are available to be used without authenticating first.
By default the encrypted communication can be used through port 9501 and the RPC v2 requests are served on the /v2 path (e.g. /v2/clusters).
Available Endpoints
| Path | Description |
|---|---|
/v2/auth |
Authentication. |
/v2/alarm |
Information about alarms. |
/v2/users |
Handling Cmon users. |
/v2/backup |
Creating and restoring backups. |
/v2/clusters |
Information about clusters. |
/v2/host |
Information about hosts. |
/v2/stat |
Statistical information, measurements. |
/v2/jobs |
Creating and monitoring jobs. |
/v2/maintenance |
Maintenance periods. |
/v2/metatype |
Information about types used by the controller. |
/v2/config |
Configuration. |
/v2/process |
Processes. |
/v2/proxysql |
ProxySQL |
/v2/log |
Logging. |
/v2/imperative |
Maintaining and running scripts. |
/v2/discovery |
Collecting real-time data. |
/v2/cloud |
Managing cloud credentials and proxying to cmon-cloud. |
/v2/audit |
List the audit log of the controller. |
/v2/ca |
Certificate authority. |
/v2/dbversions |
Get supported database versions for specific cluster type & vendor. |
/v2/performance |
Get information about MySQL databaseperformance. |
/v2/logical_replication |
PostgreSQL Logical Replication. |
/v2/watchlists |
Manipulate whatchlists to visualize clusters according to user configuration. |
Here is an example showing a typical RPC v2 request:
Request structure
{
"cluster_name": "ft_galera_18262",
"operation": "getClusterInfo",
"request_id": 2,
"request_created": "2017-06-22T06:13:46.393Z",
}
Most of the requests contain at least the following fields:
operation: This field identifies what kind of action the controller should take to serve the request.request_id: Optional field that will be sent back with the reply.request_created: This is an optional field which will be sent back to the client with the reply.cluster_name: Many of the requests are closely related to one cluster and that cluster can be identified by the cluster ID or the cluster ID.cluster_name: Many of the requests are closely related to one cluster and that cluster can be identified by the cluster ID or the cluster ID.
The RPC v2 reply usually contains many fields, but some fields can be found in all the replies. Here is an example showing some of the fields that are always sent with the reply:
Response structure
{
"request_id": 2,
"request_created": "2017-06-22T06:13:46.339Z",
"request_processed": "2017-06-22T06:13:46.385Z",
"request_status": "Ok",
"request_user_id": 3
}
messages: A list of strings with human readable messages describing what happened while processing the request.error_string: A human readable error message describing the error if an error happened. Should a request result in more than one message strings the "messages" field will be sent.request_id: If the request held this field it will be simply sent back in the reply.request_created: This is just a field that is sent back by the controller without modification.-
request_processed: The timestamp shows what time the reply was created. -
request_status: A string showing if the request was successfully processed and the error code if not. The possible values are:Ok: The request was successfully processed.InvalidRequest: Something was fundamentally wrong with the request.ObjectNotFound: The referenced object (e.g. the cluster) was not found.TryAgain: The request cannot be processed at this time; the client should retry.ClusterNotFound: The specified cluster was not found or is not running.UnknownError: The exact error could not be identified.AccessDenied: The authenticated user has insufficient rights.AuthRequired: The client must authenticate first.Redirect: The request should be sent to a different controller (seecontrollersfield in the reply).
-
error_id: An optional integer that identifies a specific error condition within a broaderrequest_statuscategory. Present only when the error warrants programmatic handling beyond whatrequest_statusalone provides. Clients should useerror_idto decide on recovery actions anderror_stringfor the human-readable description.The current values are:
error_idName request_statusMeaning and recommended client action 1 ClusterDoesNotExistClusterNotFoundThe cluster does not exist in the pool at all. Stop retrying — refreshing the controller–cluster map will not help. 2 AuthenticationRequiredAuthRequired/AccessDeniedThe session is missing or has expired. Re-authenticate before retrying. 3 InvalidCredentialsAccessDeniedThe username or password was incorrect. Prompt the user for new credentials. 4 LicenseRequiredAccessDeniedThe operation is not permitted with the current license. Direct the user to license management. 5 ControllerInitializingTryAgainThe controller is still starting up. Retry after a short delay. 6 ClusterNotAssignedToControllerObjectNotFoundThe target cluster exists but is managed by a different controller. Refresh the controller–cluster map and re-send the request to the correct controller. The owning controller's numeric id is provided in the owner_controller_idfield when known (see below).When
error_idisClusterNotAssignedToController(6), the reply may also include:owner_controller_id: The numeric id of the controller that currently owns the cluster, when it is known. Clients can use it as a redirect hint to re-send the request to the owning controller directly, without re-discovering the whole controller–cluster map. (This is distinct from thecontroller_idfield, which always carries the id of the controller that produced the reply.)
Example error reply for a cluster owned by another controller (carries
error_id6 and theowner_controller_idredirect hint):{ "controller_id": "10207", "error_id": 6, "error_string": "Request aborted. Cluster 59 is not assigned to the controller.", "owner_controller_id": 10208, "request_processed": "2025-05-01T19:57:13.000Z", "request_status": "ObjectNotFound" }Example error reply for a cluster that does not exist (carries
error_id1): -
request_user_id: The numeric ID of the authenticated user. Using this field the client can identify who sent the request.
Alarms
| Operation | Description |
|---|---|
| getStatistics | Returns statistical information about alarms for one or more clusters, including a count of active critical and warning alarms. |
| getAlarm | Get information about one particular alarm. |
| getAlarms | Get information about multiple alarms. |
| ignoreAlarm | Sets the ignored state of an alarm. |
getStatistics
POST /v2/alarm
The "getStatistics` returns statistical information about alarms for one or more clusters, including a count of active critical and warning alarms. This is a quick way to check whether there are active alarms without fetching the full alarm list.
Most importantly this is a quick way to check if there are active alarms on the cluster.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Optional | The numerical ID of the cluster to check. The cluster can also be identified by the cluster name. |
cluster_name |
string | Optional | The name of the cluster to check. The cluster ID can also be used to identify the cluster. |
cluster_ids |
array | Optional | Multiple clusters can also be requested in one call. |
| Field | Type | Description |
|---|---|---|
alarm_statistics |
array | A list of CmonAlarmStatistics objects containing per-cluster alarm counts. |
getAlarm
POST /v2/alarm
Get information about one particular alarm.
| Parameter | Type | Required | Description |
|---|---|---|---|
alarm_id |
integer | Required | The numerical ID of the alarm to return. |
cluster_id |
integer | Optional | This field is not required for the call, but if provided it will control which cluster to read. |
cluster_name |
string | Optional | This field is not required for the call, but if provided it will control which cluster to read. |
| Field | Type | Description |
|---|---|---|
alarm |
object | A CmonAlarm object with the details of one particular alarm. |
Response example
{
"alarm":
{
"alarm_id": 1,
"class_name": "CmonAlarm",
"cluster_id": 1,
"component": 3,
"component_name": "Cluster",
"counter": 1,
"created": "2017-08-02T04:50:52.000Z",
"ignored": 0,
"measured": 0,
"message": "System time is drifting between servers and the distance between the highest system time and lowest is more than one minute.",
"recommendation": "Synchronize the system clock on the servers using e.g NTP or make sure NTP is working. Time drifting may lead to unexpected failures or problems, and makes debugging hard.\n\nThe last seen host time values (in controller's time-zone):\n192.168.1.127: Aug 02 06:49:55\n192.168.1.199: Aug 02 06:51:10\n",
"reported": "2017-08-02T04:50:52.000Z",
"severity": 1,
"severity_name": "ALARM_WARNING",
"title": "System time is drifting",
"type": 40000,
"type_name": "ClusterTimeDrift"
},
"request_created": "2017-08-02T04:52:33.983Z",
"request_id": 3,
"request_processed": "2017-08-02T04:52:34.030Z",
"request_status": "Ok",
"request_user_id": 3
}
getAlarms
POST /v2/alarm
Get information about multiple alarms.
| Field | Type | Description |
|---|---|---|
alarms |
array | A list of CmonAlarm objects with the details of the alarms. |
Response example
{
"alarms": [
{
"alarm_id": 1,
"class_name": "CmonAlarm",
"cluster_id": 1,
"component": 3,
"component_name": "Cluster",
"counter": 1,
"created": "2017-07-27T06:33:38.000Z",
"ignored": 0,
"measured": 0,
"message": "System time is drifting between servers and the distance between the highest system time and lowest is more than one minute.",
"recommendation": "Synchronize the system clock on the servers using e.g NTP or make sure NTP is working. Time drifting may lead to unexpected failures or problems, and makes debugging hard.\n\nThe last seen host time values (in controller's time-zone):\n192.168.1.127: Jul 27 08:32:40\n192.168.1.169: Jul 27 08:33:44\n",
"reported": "2017-07-27T06:33:38.000Z",
"severity": 1,
"severity_name": "ALARM_WARNING",
"title": "System time is drifting",
"type": 40000,
"type_name": "ClusterTimeDrift"
},
. . .
{
"alarm_id": 3,
"class_name": "CmonAlarm",
"cluster_id": 1,
"component": 0,
"component_name": "Network",
"counter": 12,
"created": "2017-07-27T06:35:56.000Z",
"host_id": 1,
"hostname": "192.168.1.169",
"ignored": 0,
"measured": 0,
"message": "Server 192.168.1.169 reports: Host 192.168.1.169 is not responding to ping after 3 cycles, the host is most likely unreachable.",
"recommendation": "Restart failed host, check firewall.",
"reported": "2017-07-27T06:35:56.000Z",
"severity": 2,
"severity_name": "ALARM_CRITICAL",
"title": "Host is not responding",
"type": 10006,
"type_name": "HostUnreachable"
} ],
"cluster_id": 1,
"request_created": "2017-07-27T06:36:03.627Z",
"request_id": 3,
"request_processed": "2017-07-27T06:36:03.675Z",
"request_status": "Ok",
"request_user_id": 3
}
ignoreAlarm
POST /v2/alarm
Sets the ignored state of an alarm. When ignore is true the alarm is suppressed; set it to false to re-enable a previously suppressed alarm.
| Parameter | Type | Required | Description |
|---|---|---|---|
alarm_id |
integer | Required | The numerical ID of the alarm to update. |
ignore |
boolean | Required | Set to true to suppress the alarm, or false to re-enable a previously suppressed alarm. |
| Field | Type | Description |
|---|---|---|
alarm |
object | A CmonAlarm object reflecting the updated state of the alarm. |
Response example
{
"alarm":
{
"alarm_id": 5,
"class_name": "CmonAlarm",
"cluster_id": 1,
"component": 0,
"component_name": "Network",
"counter": 1,
"created": "2018-09-25T08:03:17.000Z",
"host_id": 1,
"ignored": 1,
"measured": 0,
"message": "Server 192.168.0.79 reports: SSH failure to 192.168.0.79: No route to host.",
"recommendation": "Please check SSH access to host. The host may also be down.",
"reported": "2018-09-25T08:03:17.000Z",
"severity": 2,
"severity_name": "ALARM_CRITICAL",
"title": "SSH failed",
"type": 10008,
"type_name": "HostSshFailed"
},
"request_created": "2018-09-25T08:03:17.416Z",
"request_id": 3,
"request_processed": "2018-09-25T08:03:17.425Z",
"request_status": "Ok",
"request_user_id": 4
}
Information about Controller's audit log
The /v2/audit path can be used to retrieve audit log entries for one or more clusters.
| Operation | Description |
|---|---|
| getEntries | Returns audit log entries for one or more clusters. |
getEntries
POST /v2/audit
Returns audit log entries for one or more clusters. Results can be sorted ascending or descending and filtered by cluster ID.
| Parameter | Type | Required | Description |
|---|---|---|---|
ascending |
boolean | Required | Sort results ascending if true, descending if false. |
cluster_ids |
array | Required | List of cluster IDs to filter audit log entries. |
| Field | Type | Description |
|---|---|---|
total |
integer | Total number of audit entries returned. |
audit_entries |
array | List of audit log entry objects. |
Response example
{
"request_processed": "2022-03-03T18:24:38.304Z",
"request_status": "Ok",
"total": 4,
"audit_entries":
[
{
"class_name": "CmonAuditEntry",
"client_hostname": "127.0.0.1",
"cluster_id": 0,
"entry_type": "users",
"id": 1000,
"message_text": "Deleted user 'user.name.123.",
"report_ts": "2022-03-03T18:11:40.800Z",
"username": "kedz"
},
{
"class_name": "CmonAuditEntry",
"client_hostname": "127.0.0.1",
"cluster_id": 0,
"entry_type": "users",
"id": 1001,
"message_text": "Group removed 'fancygroup.",
"report_ts": "2022-03-03T18:11:35.498Z",
"username": "kedz"
},
{
"class_name": "CmonAuditEntry",
"client_hostname": "127.0.0.1",
"cluster_id": 0,
"entry_type": "users",
"id": 1002,
"message_text": "User 'user.name.123' has been removed from group 'fancygroup.",
"report_ts": "2022-03-03T18:11:29.324Z",
"username": "kedz"
},
{
"class_name": "CmonAuditEntry",
"client_hostname": "127.0.0.1",
"cluster_id": 0,
"entry_type": "users",
"id": 1003,
"message_text": "User 'user.name.123' has been added to group'fancygroup.",
"report_ts": "2022-03-03T18:11:18.168Z",
"username": "kedz"
}
]
}
User Authentication
The client authentication methods are available on this path (/v2/auth).
There are currently two separate way is available for user authentication, one that uses a public/private key pair and one that uses a password. The key-based authentication has two phases, the password based authentication uses one request.
You may send with_extended_privileges: true to this request to get extended user information in case of successful authentication.
The password based authentication is implemented using the "authenticateWithPassword" request:
{
"operation": "authenticateWithPassword",
"password": "secret",
"request_created": "2017-06-29T05:46:10.622Z",
"request_id": 1,
"user_name": "system"
}
The key based authentication starts with the client sending an "authenticate" request to the controller:
{
"operation": "authenticate",
"request_created": "2017-06-22T07:50:18.117Z",
"request_id": 1,
"user_name": "worf"
}
The controller replies by sending a challenge to the client:
{
"challenge": "3694b3af-e2f0-e49e-4f32-1549fd824ea9",
"request_created": "2017-06-22T07:50:18.117Z",
"request_id": 1,
"request_processed": "2017-06-22T07:50:18.163Z",
"request_status": "Ok",
"request_user_id": 0,
"user_name": "worf"
}
The client then encrypts the challenge string with its private key and sends it back in a new request:
{
"operation": "authenticateresponse",
"request_created": "2017-06-22T07:50:18.169Z",
"request_id": 2,
"signature": "XjiGlQNbq/yN9vzgS5uPjJfKw8DLXGD/uwlw+cec/iC9GJdgs1rZO6GNQzR2Mk6StgopX7gCDQwNVF426v3kGVSKEsQe5BoEJ/RRBfWmxyf1imDzS7O97vwBPw0Ko4TV57jpexLaOrFWTXraEsPnnSZffEpK4hzQnBRWorSCcFbkm3XJQIqNcf6BhpHsW1pZClmojElcXIh6aBkqnQgGF8rwk6rFDRi/vx7kikVLlw4EDFgzedfKfZkxNlbhcz6Z9XMagxPxNShMb/jWY0jWKL7OVVRfgFQ27DycqtMdteXDjn5gCkxO8oT693FMHaDlgjt21Azeny8IFpy1f2ZFIg=="
}
Should the signature match the controller sends back a reply notifying the client that it is now authenticated for the session:
{
"is_superuser": true,
"request_created": "2017-08-23T09:22:36.857Z",
"request_id": 2,
"request_processed": "2017-08-23T09:22:36.906Z",
"request_status": "Ok",
"user":
{
"class_name": "CmonUser",
"email_address": "[email protected]",
"first_name": "Laszlo",
"groups": [
{
"class_name": "CmonGroup",
"group_id": 1,
"group_name": "admins"
} ],
"last_name": "Pere",
"title": "",
"user_id": 3,
"user_name": "admin"
}
}
is_superuser: Shows if the authenticated user actually has the superuser privileges.request_status: Shows that authentication was successful and the session now has an authenticated user.request_user_id: The request that produced this reply had no authenticated user ID, so the reply will not have this field.user: The details about the user authenticated for the session.
The client can terminate the session when it is no longer needed, on server side using the logout operation on auth.
| Operation | Description |
|---|---|
| authenticate | Initiates key-based authentication by requesting a challenge from the server. |
| passwordReset | Resets a user's password via a two-step email-token process. |
| authenticateResponse | Completes key-based authentication by submitting the signed challenge. |
| authenticateWithPassword | Authenticates a user using their plain-text password. |
authenticate
POST /v2/auth
The first step in the process where the client initiates the authentication by sending the authenticate request.
| Parameter | Type | Required | Description |
|---|---|---|---|
user_name |
string | Required | The user name of the Cmon user. |
| Field | Type | Description |
|---|---|---|
challenge |
string | The string that should be encrypted by the client with the private key. |
user_name |
string | The name of the user which is going to be authenticated. |
The next expected request from client is a 'response' call, with the signature created using the client private key.
passwordReset
POST /v2/auth
Resets a user's password using a two-step process. The first request triggers a password-reset email to be sent to the user's registered address. The second request applies the new password using the token received in that email. Both requests use the same operation name; the first contains only user_name (and optionally base_url), while the second adds password_reset_token and new_password.
Step 1 - Trigger reset
| Parameter | Type | Required | Description |
|---|---|---|---|
user_name |
string | Required | The name of the user for whom the password reset email will be sent. The email address can not be in the request for security reasons, the controller will use the pre-registered email address of the user or if no such email address is registered the call will fail. |
base_url |
string | Optional | The first part of the URL that will be sent in the email. |
{
"operation": "passwordReset",
"request_created": "2019-05-31T10:14:30.457Z",
"request_id": 1,
"user_name": "system"
}
Step 2 - Apply new password
| Parameter | Type | Required | Description |
|---|---|---|---|
user_name |
string | Required | The name of the user whose password is being reset. |
new_password |
string | Required | The new password that will be set for the user. |
password_reset_token |
string | Required | The password change token that was received in the email. |
authenticateResponse
POST /v2/auth
This method shall be called by the client once it receives a security challenge (in reply to "authenticate" call) from the server.
In reply backend sends either an error message if authentication failed, or just a success message showing that the authentication is finished and the user is authenticated for the session.
Here is an example for a reply that sent after the authentication succeeded:
| Parameter | Type | Required | Description |
|---|---|---|---|
signature |
string | Required | A base64 RSA-SHA256 signature using the client's private key of the 'challenge' text. |
{
"operation": "authenticateresponse",
"request_created": "2017-06-22T07:50:18.169Z",
"request_id": 2,
"signature": "XjiGlQNbq/yN9vzgS5uPjJfKw8DLXGD/uwlw+cec/iC9GJdgs1rZO6GNQzR2Mk6StgopX7gCDQwNVF426v3kGVSKEsQe5BoEJ/RRBfWmxyf1imDzS7O97vwBPw0Ko4TV57jpexLaOrFWTXraEsPnnSZffEpK4hzQnBRWorSCcFbkm3XJQIqNcf6BhpHsW1pZClmojElcXIh6aBkqnQgGF8rwk6rFDRi/vx7kikVLlw4EDFgzedfKfZkxNlbhcz6Z9XMagxPxNShMb/jWY0jWKL7OVVRfgFQ27DycqtMdteXDjn5gCkxO8oT693FMHaDlgjt21Azeny8IFpy1f2ZFIg=="
}
| Field | Type | Description |
|---|---|---|
user |
object | The details about the user authenticated for the session. |
Response example
{
"request_created": "2017-06-29T13:25:32.885Z",
"request_id": 2,
"request_processed": "2017-06-29T13:25:32.936Z",
"request_status": "Ok",
"user":
{
"class_name": "CmonUser",
"email_address": "[email protected]",
"first_name": "Worf",
"groups": [
{
"class_name": "CmonGroup",
"group_id": 4,
"group_name": "ds9"
} ],
"last_login": "2017-06-29T13:25:21.906Z",
"last_name": "",
"title": "Lt.",
"user_id": 12,
"user_name": "worf"
}
}
authenticateWithPassword
POST /v2/auth
It is possible to authenticate the user using the user's own password.
| Parameter | Type | Required | Description |
|---|---|---|---|
user_name |
string | Required | The username of the user to authenticate. |
password |
string | Required | The plain password of the user. Please note that the plain password is not a property of the CmonUser class, it is not stored by the controller, it is only used temporarily. |
| Field | Type | Description |
|---|---|---|
user |
object | The details about the user authenticated for the session. |
Response example
{
"request_created": "2017-06-29T13:22:58.592Z",
"request_id": 1,
"request_processed": "2017-06-29T13:22:58.645Z",
"request_status": "Ok",
"user":
{
"class_name": "CmonUser",
"first_name": "System",
"groups": [
{
"class_name": "CmonGroup",
"group_id": 1,
"group_name": "admins"
} ],
"last_login": "2017-06-29T13:22:42.624Z",
"last_name": "User",
"user_id": 1,
"user_name": "system"
}
}
And here is a reply that sent about a failed attempt:
{
"error_string": "Wrong username or password.",
"reply_received": "2017-06-29T05:57:27.128Z",
"request_created": "2017-06-29T05:57:27.118Z",
"request_id": 1,
"request_processed": "2017-06-29T05:57:27.193Z",
"request_status": "AccessDenied"
}
Please note that the reply contains no request_user_id field because the session is not authenticated and there is no known user to associate with it. It is also worth noting that the error string does not specify what exactly was the problem with the authentication. Since there is no known user we only send a generic error message. In this case the user was found, but the password did not match, but we are not sending this information with the reply.
Information about Backups
The /v2/backup path can be used to get information about backups.
Please note that creating and restoring a backup is a job and so is not implemented here.
| Operation | Description |
|---|---|
| getBackups | Returns the backups of a cluster |
| getBackupSet | Returns the backup set of a backup id, including its increments |
| getBackupSchedules | Returns the backup schedules from the controller |
| scheduleBackup | Creates or updates a backup schedule for a cluster |
| deleteBackupRecord | Deletes a single backup record by ID |
| deleteBackupList | Deletes multiple backup records in a single call |
| snapshotRepositories | Manages Elasticsearch snapshot repositories |
| getAllSnapshotRepositories | Lists all Elasticsearch snapshot repositories |
| getSnapshotRepositories | Retrieves snapshot repositories for a specific cluster |
| deleteSnapshotRepository | Deletes an existing Elasticsearch snapshot repository |
getBackups
POST /v2/backup
An RPC call that returns the backups of a cluster. For backup locations use backup_record_version: 2.
| Parameter | Type | Required | Description |
|---|---|---|---|
ascending |
boolean | Optional | Sort order for the results |
cluster_id |
integer | Required | The ID of the cluster |
backup_record_version |
integer | Optional | Use 2 for backup locations |
| Field | Type | Description |
|---|---|---|
backup_records |
array | List of backup record objects |
total |
integer | Total number of backup records |
Response example
{
"backup_records": [
{
"backup": [
{
"db": "all",
"files": [
{
"class_name": "CmonBackupFile",
"created": "2017-06-26T09:07:35.000Z",
"hash": "md5:938bacc9699b362eb1be355eace1281d",
"path": "pg_dump_2017-06-26_110732.sql.gz",
"size": 796,
"type": "full"
} ],
"start_time": "2017-06-26T09:07:35.000Z"
} ],
"backup_host": "192.168.1.198",
"chain_up": 0,
"cid": 1,
"class_name": "CmonBackupRecord",
"compressed": true,
"config":
{
"backupDir": "/tmp",
"backupHost": "192.168.1.198",
"backupMethod": "",
"backupToIndividualFiles": false,
"backup_failover": false,
"backup_failover_host": "",
"ccStorage": true,
"compression": true,
"createdBy": "pipas",
"description": "Backup created by s9s-tools.",
"includeDatabases": "",
"netcat_port": 9999,
"origBackupDir": "/tmp",
"port": null,
"scheduleId": 0,
"set_gtid_purged_off": true,
"storageHost": "",
"throttle_rate_iops": 0,
"throttle_rate_netbw": 0,
"usePigz": false,
"wsrep_desync": false,
"xtrabackupParallellism": 1,
"xtrabackup_locks": false
},
"created": "2017-06-26T09:07:32.000Z",
"created_by": "",
"description": "",
"finished": "2017-06-26T09:07:35.930Z",
"id": 1,
"job_id": 2,
"log_file": "",
"lsn": 0,
"method": "pgdump",
"parent_id": 0,
"root_dir": "/tmp/BACKUP-1",
"schedule_id": 0,
"status": "Completed",
"storage_host": "192.168.1.127",
"total_datadir_size": 38959683,
"verified":
{
"message": "",
"status": "Unverified",
"verified_time": "1969-12-31T23:59:59.000Z"
}
},
. . .
],
"request_created": "2017-06-26T09:07:48.374Z",
"request_id": 3,
"request_processed": "2017-06-26T09:07:48.423Z",
"request_status": "Ok",
"request_user_id": 3,
"total": 2
}
getBackupSet
POST /v2/backup
An RPC call that returns the backup set of a backup id, i.e a full backup including its increments are returned. If the backup id belongs to an incremental backup, then all the returned list of chained backups up to the parent (full backup) is returned. If the backup id belongs to a full backup, only the full backup is returned. For backup locations use backup_record_version: 2.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The ID of the cluster |
backup_record_version |
integer | Optional | Use 2 for backup locations |
| Field | Type | Description |
|---|---|---|
backup_records |
array | List of backup record objects in the set |
total |
integer | Total number of backup records returned |
Response example
{
"backup_records": [
{
"backup": [
{
"db": "all",
"files": [
{
"class_name": "CmonBackupFile",
"created": "2017-06-26T09:07:35.000Z",
"hash": "md5:938bacc9699b362eb1be355eace1281d",
"path": "pg_dump_2017-06-26_110732.sql.gz",
"size": 796,
"type": "full"
} ],
"start_time": "2017-06-26T09:07:35.000Z"
} ],
"backup_host": "192.168.1.198",
"chain_up": 0,
"cid": 1,
"class_name": "CmonBackupRecord",
"compressed": true,
"config":
{
"backupDir": "/tmp",
"backupHost": "192.168.1.198",
"backupMethod": "",
"backupToIndividualFiles": false,
"backup_failover": false,
"backup_failover_host": "",
"ccStorage": true,
"compression": true,
"createdBy": "pipas",
"description": "Backup created by s9s-tools.",
"includeDatabases": "",
"netcat_port": 9999,
"origBackupDir": "/tmp",
"port": null,
"scheduleId": 0,
"set_gtid_purged_off": true,
"storageHost": "",
"throttle_rate_iops": 0,
"throttle_rate_netbw": 0,
"usePigz": false,
"wsrep_desync": false,
"xtrabackupParallellism": 1,
"xtrabackup_locks": false
},
"created": "2017-06-26T09:07:32.000Z",
"created_by": "",
"description": "",
"finished": "2017-06-26T09:07:35.930Z",
"id": 1,
"job_id": 2,
"log_file": "",
"lsn": 0,
"method": "pgdump",
"parent_id": 0,
"root_dir": "/tmp/BACKUP-1",
"schedule_id": 0,
"status": "Completed",
"storage_host": "192.168.1.127",
"total_datadir_size": 38959683,
"verified":
{
"message": "",
"status": "Unverified",
"verified_time": "1969-12-31T23:59:59.000Z"
}
},
. . .
],
"request_created": "2017-06-26T09:07:48.374Z",
"request_id": 3,
"request_processed": "2017-06-26T09:07:48.423Z",
"request_status": "Ok",
"request_user_id": 3,
"total": 2
}
getBackupSchedules
POST /v2/backup
An RPC call to get the backup schedules from the controller.
Please note that the backup schedules are deprecated. Instead of creating scheduled backups creating of scheduled jobs (that create backups) is advisable. This RPC call was only created for backward compatibility.
| Field | Type | Description |
|---|---|---|
backup_schedules |
array | List of backup schedule objects |
total |
integer | Total number of backup schedules |
Response example
{
"backup_schedules": [ {
"class_name": "CmonBackupSchedule",
"cluster_id": 1,
"enabled": true,
"id": 1,
"job": {
"command": "backup",
"job_data": {
"description": "Backup created by s9s-tools."
},
"scheduleId": 1
},
"lastExec": "1970-01-01T00:00:00.000Z",
"schedule": "0 12 * * 5"
} ],
"debug_messages": [ "RPC V2 authenticated user is 'pipas'." ],
"reply_received": "2020-01-29T11:01:25.893Z",
"request_created": "2020-01-29T11:01:25.887Z",
"request_id": 3,
"request_processed": "2020-01-29T11:01:25.893Z",
"request_status": "Ok",
"request_user_id": 4,
"total": 1
}
scheduleBackup
POST /v2/backup
Creates or updates a backup schedule for a cluster. The schedule field uses a standard cron expression to define when the backup job runs. The job field within the schedule object defines the backup command and its parameters.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The ID of the cluster |
schedule |
object | Required | The backup schedule object |
schedule.class_name |
string | Required | Must be CmonBackupSchedule |
schedule.enabled |
boolean | Required | Whether the schedule is enabled |
schedule.job |
object | Required | The job definition for the backup |
schedule.job.command |
string | Required | The job command, e.g. backup |
schedule.job.job_data |
object | Optional | Additional job parameters |
schedule.schedule |
string | Required | Cron expression for the schedule |
{
"cluster_id": 1,
"operation": "scheduleBackup",
"request_created": "2020-01-29T10:57:52.916Z",
"request_id": 3,
"schedule":
{
"class_name": "CmonBackupSchedule",
"enabled": true,
"job":
{
"command": "backup",
"job_data":
{
"description": "Backup created by s9s-tools."
}
},
"schedule": "0 12 * * 5"
}
}
| Field | Type | Description |
|---|---|---|
schedule |
object | The created or updated schedule object |
schedule.class_name |
string | Class name of the schedule |
schedule.cluster_id |
integer | The cluster the schedule belongs to |
schedule.enabled |
boolean | Whether the schedule is enabled |
schedule.id |
integer | The ID of the schedule |
schedule.job |
object | The job definition |
schedule.lastExec |
string | Timestamp of last execution |
schedule.schedule |
string | Cron expression |
Response example
{
"debug_messages": [ "RPC V2 authenticated user is 'pipas'." ],
"reply_received": "2020-01-29T10:57:52.927Z",
"request_created": "2020-01-29T10:57:52.916Z",
"request_id": 3,
"request_processed": "2020-01-29T10:57:52.926Z",
"request_status": "Ok",
"request_user_id": 4,
"schedule": {
"class_name": "CmonBackupSchedule",
"cluster_id": 1,
"enabled": true,
"id": 1,
"job": {
"command": "backup",
"job_data": {
"description": "Backup created by s9s-tools."
},
"scheduleId": 1
},
"lastExec": null,
"schedule": "0 12 * * 5"
}
}
deleteBackupRecord
POST /v2/backup
Deletes a single backup record identified by backup_id. This removes the backup metadata from the controller database but does not automatically delete the backup files from storage.
| Parameter | Type | Required | Description |
|---|---|---|---|
backup_record |
object | Required | Object containing the backup ID to delete |
backup_record.backup_id |
integer | Required | The ID of the backup record to delete |
deleteBackupList
POST /v2/backup
Deletes multiple backup records in a single call by providing a comma-separated list of backup IDs in the backup_id_list field. More efficient than calling deleteBackupRecord repeatedly.
snapshotRepositories
POST /v2/backup
Manages Elasticsearch snapshot repositories used for backup storage. Supports creating a new snapshot repository (snapshotRepository), listing all repositories (getAllSnapshotRepositories), retrieving repositories for a specific cluster (getSnapshotRepositories), and deleting an existing repository (deleteSnapshotRepository).
| Parameter | Type | Required | Description |
|---|---|---|---|
class_name |
string | Required | Must be CmonRpcRequest |
cluster_id |
integer | Required | The ID of the cluster |
repository |
object | Required | The snapshot repository definition |
repository.class_name |
string | Required | Must be CmonBackupSnapshotRepository |
repository.job |
object | Required | The job definition for creating the repository |
repository.job.command |
string | Required | The job command, e.g. backup |
repository.job.description |
string | Optional | Description of the repository job |
repository.job.job_data |
object | Required | Job data including repository configuration |
repository.job.job_data.credential_id |
integer | Optional | ID of the credentials to use |
repository.job.job_data.description |
string | Optional | Description of the backup |
repository.job.job_data.s3_bucket |
string | Optional | S3 bucket name for s3-type repositories |
repository.job.job_data.snapshot_repository |
string | Required | Name of the snapshot repository |
repository.job.job_data.snapshot_repository_type |
string | Required | Type of repository, e.g. s3, fs |
{
"class_name": "CmonRpcRequest",
"cluster_id": 108,
"operation": "snapshotRepository",
"request_created": "2022-05-24T09:36:57.784Z",
"request_id": 2,
"repository": {
"class_name": "CmonBackupSnapshotRepository",
"job": {
"command": "backup",
"description": "Snapshot repository created by s9s-tools on elasticsearch cluster",
"job_data": {
"credential_id": 1,
"description": "Backup created by s9s-tools.",
"s3_bucket": "elastic-s3-test",
"snapshot_repository": "cliRepo",
"snapshot_repository_type": "s3"
}
}
}
}
getAllSnapshotRepositories
POST /v2/backup
List all Elasticsearch snapshot repositories.
| Field | Type | Description |
|---|---|---|
total |
integer | Total number of snapshot repositories returned |
snapshot_repositories_list |
object | Map of cluster IDs to their snapshot repositories |
Response example
{
"controller_id": "1084dffd-be4d-4c03-bca4-00accbcc200b",
"reply_received": "2022-07-08T10:04:17.952Z",
"request_created": "2022-07-08T10:04:17.846Z",
"request_id": 2,
"request_processed": "2022-07-08T10:04:17.952Z",
"request_status": "Ok",
"request_user_id": 5,
"total": 2,
"debug_messages": [ "RPC V2 authenticated user is 'ccalvaro'." ],
"messages": [ "Snapshot repositories on all clusters has been retrieved" ],
"snapshot_repositories_list": {
"215": {
"fsRepo": {
"type": "fs",
"settings": {
"location": "/mnt/data/backups/es-snapshot-repositories"
}
},
"test_s3_repo": {
"type": "s3",
"uuid": "QbQ00rxEQJqwnzcgoK_OAg",
"settings": {
"bucket": "elastic-s3-test",
"client": "secondary",
"region": "eu-west-3"
}
}
},
"216": {
"fsRepo": {
"type": "fs",
"storage_host": "kvm2",
"settings": {
"location": "/mnt/data/backups/es-snapshot-repositories"
}
},
"s3Repo": {
"type": "s3",
"storage_host": "s3",
"uuid": "QbQ00rxEQJqwnzcgoK_OAg",
"settings": {
"bucket": "elastic-s3-test",
"client": "secondary",
"region": "eu-west-3"
}
}
}
}
}
getSnapshotRepositories
POST /v2/backup
Retrieve Elasticsearch repositories for a specific cluster.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The ID of the cluster |
| Field | Type | Description |
|---|---|---|
total |
integer | Total number of snapshot repositories returned |
snapshot_repositories |
object | Map of repository names to their configuration objects |
Response example
{
"controller_id": "1084dffd-be4d-4c03-bca4-00accbcc200b",
"reply_received": "2022-05-26T09:42:31.898Z",
"request_created": "2022-05-26T09:42:31.844Z",
"request_id": 2,
"request_processed": "2022-05-26T09:42:31.898Z",
"request_status": "Ok",
"request_user_id": 5,
"total": 1,
"debug_messages": [ "RPC V2 authenticated user is 'ccalvaro'." ],
"messages": [ "Snapshot repositories has been retrieved" ],
"snapshot_repositories": {
"sharedFs": {
"type": "fs",
"storage_host": "s3",
"uuid": "yGaLnQU5TFaAX96ZBAgN_Q",
"settings": {
"location": "/mnt/data/"
}
}
}
}
deleteSnapshotRepository
POST /v2/backup
Delete an existing Elasticsearch repository.
| Parameter | Type | Required | Description |
|---|---|---|---|
class_name |
string | Required | Must be CmonRpcRequest |
cluster_id |
integer | Required | The ID of the cluster |
snapshot_repository |
string | Required | Name of the snapshot repository to delete |
Certificate Authority (CA)
With these API calls you can list and manage your certificates managed by ClusterControl. These methods can be found on path /v2/ca.
| Operation | Description |
|---|---|
| listCerts | List CA, server, and client certificates |
| certInfo | Get details about a specific certificate |
| create | Create a signed (self or CA signed) certificate |
| revoke | Mark a certificate as revoked |
| delete | Delete certificate and private key files |
| move | Move a certificate within the ClusterControl CA storage |
| crl | Create a certificate revocation list signed by a specified CA |
| importlocal | Import a certificate from the controller host |
listCerts
POST /v2/ca
A method to list the (CA, server and client) certificates.
Response example
{
"controller_id": "7f399ff3-7484-4a93-a47a-a5c0bba42fca",
"is_superuser": true,
"request_processed": "2023-02-16T14:28:37.281Z",
"request_status": "Ok",
"total": 1,
"data":
[
{
"certfile": "galera/cluster_1/server_ca.crt",
"id": 1,
"isCA": true,
"isClient": true,
"isServer": true,
"issued": 1620992185,
"issuerId": 0,
"keybits": 2048,
"keyfile": "galera/cluster_1/server_ca.key",
"serialNumber": 1,
"status": "Issued",
"validFrom": 1620905785,
"validUntil": 1936352185,
"inUseBy":
{
"hosts": [],
"clusters": []
},
"subjectName":
{
"CN": "ClusterControl_AutoGenerated_CA_Certificate",
"basicConstraints": "ca",
"serialNumber": "1",
"extendedKeyUsage":
[
"ClientAuth",
"ServerAuth",
"OCSPSigning"
],
"keyUsage":
[
"DigitalSignature",
"NonRepudiation",
"KeyEncipherment",
"KeyAgreement",
"KeyCertificateSign",
"CRLSign"
]
}
}
]
}
certInfo
POST /v2/ca
A method to give details about a certificate.
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
integer | Required | The ID of the certificate to retrieve details for |
Response example
{
"controller_id": "7f399ff3-7484-4a93-a47a-a5c0bba42fca",
"is_superuser": true,
"request_processed": "2023-02-16T14:57:24.882Z",
"request_status": "Ok",
"total": 1,
"data":
{
"certfile": "galera/cluster_1/server.crt",
"id": 2,
"isCA": false,
"isClient": true,
"isServer": true,
"issued": 1620992185,
"issuerId": 1,
"keybits": 2048,
"keyfile": "galera/cluster_1/server.key",
"serialNumber": 2,
"status": "Issued",
"validFrom": 1620905785,
"validUntil": 1936352185,
"inUseBy":
{
"hosts": [],
"clusters": []
},
"subjectName":
{
"CN": "MySQL_Server_Cmon_Auto_Generated_Server_Certificate",
"description": "Generated by ClusterControl",
"serialNumber": "2",
"extendedKeyUsage":
[
"ClientAuth",
"ServerAuth"
],
"keyUsage":
[
"DigitalSignature",
"NonRepudiation",
"KeyEncipherment",
"KeyAgreement"
]
}
}
}
create
POST /v2/ca
Creates a signed (self or CA signed) certificate.
| Parameter | Type | Required | Description |
|---|---|---|---|
type |
string | Required | The type of certificate to create (e.g. ca) |
name |
string | Required | The name/path for the certificate |
validity |
integer | Required | Validity period in days |
data |
object | Required | Certificate data object containing subject details |
data.keybits |
integer | Required | Key size in bits |
data.CN |
string | Required | Common Name for the certificate |
data.description |
string | Optional | Description of the certificate |
data.emailAddress |
string | Optional | Email address to associate with the certificate |
{
"operation":"create",
"type":"ca",
"name":"exampleCa1",
"validity":3650,
"data":{
"keybits":4096,
"CN":"My CA certificate.",
"description":"This is an example CA certificate.",
"emailAddress":"[email protected]"
}
}
Response example
{
"controller_id": "7f399ff3-7484-4a93-a47a-a5c0bba42fca",
"is_superuser": true,
"request_processed": "2023-02-23T08:55:21.030Z",
"request_status": "Ok",
"total": 1,
"data":
{
"certfile": "exampleCa1.crt",
"id": 228,
"isCA": true,
"isClient": true,
"isServer": true,
"issued": 1677142521,
"issuerId": 0,
"keybits": 4096,
"keyfile": "exampleCa1.key",
"requesterUserId": 68,
"serialNumber": 228,
"status": "Issued",
"validFrom": 1677052521,
"validUntil": 1992498921,
"inUseBy":
{
"hosts": [],
"clusters": []
},
"subjectName":
{
"CN": "My CA certificate.",
"basicConstraints": "ca",
"description": "This is an example CA certificate.",
"emailAddress": "[email protected]",
"serialNumber": "228",
"extendedKeyUsage":
[
"ClientAuth",
"ServerAuth",
"OCSPSigning"
],
"keyUsage":
[
"DigitalSignature",
"NonRepudiation",
"KeyEncipherment",
"KeyAgreement",
"KeyCertificateSign",
"CRLSign"
]
}
}
}
revoke
POST /v2/ca
Marks the specified certificate as revoked. You might need to regenerate the CRL list of the issuer (CA) certificate after this operation.
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
integer | Required | The ID of the certificate to revoke |
Response example
{
"controller_id": "7f399ff3-7484-4a93-a47a-a5c0bba42fca",
"is_superuser": true,
"request_processed": "2023-02-23T14:12:39.292Z",
"request_status": "Ok",
"total": 1,
"data":
{
"certfile": "replication/cluster_117/client.crt",
"id": 227,
"isCA": false,
"isClient": true,
"isServer": false,
"issued": 1674744928,
"issuerId": 225,
"keybits": 2048,
"keyfile": "replication/cluster_117/client.key",
"revoked": 1677161559,
"revokerUserId": 68,
"serialNumber": 227,
"status": "Revoked",
"validFrom": 1674654928,
"validUntil": 1990101328,
"inUseBy":
{
"hosts": [],
"clusters": []
},
"subjectName":
{
"CN": "MySQL_Server_Cmon_Auto_Generated_Client_Certificate",
"description": "Generated by ClusterControl",
"serialNumber": "227",
"extendedKeyUsage":
[
"ClientAuth"
],
"keyUsage":
[
"DigitalSignature",
"NonRepudiation",
"KeyEncipherment",
"KeyAgreement"
]
}
}
}
delete
POST /v2/ca
Deletes the certificate (cert and private key) files. Please note that this is an unusual and dangerous operation, please use revoke instead of this.
move
POST /v2/ca
Moves a certificate within the ClusterControl CA storage.
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
integer | Required | The ID of the certificate to move |
name |
string | Required | The new name/path for the certificate |
Response example
{
"controller_id": "7f399ff3-7484-4a93-a47a-a5c0bba42fca",
"is_superuser": true,
"request_processed": "2023-02-23T13:32:09.206Z",
"request_status": "Ok",
"total": 1,
"data":
{
"certfile": "examples/demoCA/cert01.crt",
"id": 228,
"isCA": true,
"isClient": true,
"isServer": true,
"issued": 1677142521,
"issuerId": 0,
"keybits": 4096,
"keyfile": "examples/demoCA/cert01.key",
"requesterUserId": 68,
"serialNumber": 228,
"status": "Issued",
"validFrom": 1677052521,
"validUntil": 1992498921,
"inUseBy":
{
"hosts": [],
"clusters": []
},
"subjectName":
{
"CN": "My CA certificate.",
"basicConstraints": "ca",
"description": "This is an example CA certificate.",
"emailAddress": "[email protected]",
"serialNumber": "228",
"extendedKeyUsage":
[
"ClientAuth",
"ServerAuth",
"OCSPSigning"
],
"keyUsage":
[
"DigitalSignature",
"NonRepudiation",
"KeyEncipherment",
"KeyAgreement",
"KeyCertificateSign",
"CRLSign"
]
}
}
}
crl
POST /v2/ca
Creates a certificate revokation list (CRL) signed by the specified CA.
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
integer | Required | The ID of the CA certificate to use for signing the CRL |
Response example
importlocal
POST /v2/ca
Imports a certificate (.crt and .key file) from controller host. CA is optional in the request, as not needed for example in case of the certs are self-signed or CA certs.
| Parameter | Type | Required | Description |
|---|---|---|---|
cert_file |
string | Required | Path to the certificate file on the controller host |
key_file |
string | Required | Path to the private key file on the controller host |
ca_file |
string | Optional | Path to the CA certificate file on the controller host |
name |
string | Required | Name/path to store the imported certificate under |
name_ca |
string | Optional | Name/path to store the imported CA certificate under |
Response example
{
"controller_id": "7f399ff3-7484-4a93-a47a-a5c0bba42fca",
"is_superuser": true,
"request_processed": "2023-02-23T14:20:39.058Z",
"request_status": "Ok",
"total": 1,
"data":
{
"certfile": "testing/import/testClient.crt",
"id": 236,
"isCA": false,
"isClient": true,
"isServer": false,
"issued": 1677162039,
"issuerId": 235,
"keybits": 2048,
"keyfile": "testing/import/testClient.key",
"serialNumber": 234,
"status": "Issued",
"validFrom": 1677071895,
"validUntil": 1992518295,
"wasCaKnown": false,
"inUseBy":
{
"hosts": [],
"clusters": []
},
"subjectName":
{
"description": "fdsfdsf",
"serialNumber": "234",
"extendedKeyUsage":
[
"ClientAuth"
],
"keyUsage":
[
"DigitalSignature",
"NonRepudiation",
"KeyEncipherment",
"KeyAgreement"
]
}
}
}
Cloud credentials API
The /v2/cloud path provides calls to manage the cloud-credentials in cmon.
| Operation | Description |
|---|---|
| proxy | Proxies a request to the cmon-cloud service and returns the raw response. |
| verifyCredentials | Verifies that a set of cloud provider credentials are valid. |
| listCredentials | Returns all stored cloud provider credentials, grouped by provider. |
| getCredentials | Returns a specific set of stored cloud credentials identified by id and provider. |
| addCredentials | Stores a new set of cloud provider credentials in the controller. |
| updateCredentials | Updates an existing set of cloud provider credentials identified by id. |
| removeCredentials | Removes a stored set of cloud provider credentials identified by id and provider. |
proxy
POST /v2/cloud
Proxies a request to the cmon-cloud service and returns the raw response. Use this to interact with cloud provider APIs through the controller without exposing credentials directly to the client.
| Parameter | Type | Required | Description |
|---|---|---|---|
uri |
string | Required | The URI path to proxy to the cmon-cloud service. |
method |
string | Required | The HTTP method to use for the proxied request. |
provider |
string | Required | The cloud provider (e.g. aws). |
credentials_id |
integer | Required | The ID of the stored credentials to use for the request. |
body |
string | Required | The request body to forward. |
| Field | Type | Description |
|---|---|---|
reply_received |
string | Timestamp when the reply was received. |
response |
object | The raw response from the cmon-cloud service. |
response.reason_phrase |
string | The HTTP reason phrase from the proxied response. |
response.status_code |
integer | The HTTP status code from the proxied response. |
response.headers |
object | The HTTP headers from the proxied response. |
response.json |
array | The JSON body of the proxied response. |
Response example
{
"reply_received": "2020-01-29T11:01:25.893Z",
"request_created": "2020-01-29T11:01:25.887Z",
"request_id": 10,
"request_processed": "2020-01-29T11:01:25.893Z",
"request_status": "Ok",
"response":{
"reason_phrase":"OK",
"status_code":200,
"headers":{
"content-length":"1016",
"content-type":"application\/json; charset=UTF-8",
"date":"Tue, 30 Nov 2021 12:40:43 GMT"
},
"json":["t3.small","t3.medium","t3.large"],
}
}
verifyCredentials
POST /v2/cloud
Verifies that a set of cloud provider credentials are valid by issuing a test request (such as listing storage buckets) through the cmon-cloud service.
| Parameter | Type | Required | Description |
|---|---|---|---|
provider |
string | Required | The cloud provider (e.g. aws). |
credentials |
object | Required | The credentials to verify. |
credentials.access_key_id |
string | Required | The cloud provider access key ID. |
credentials.access_key_secret |
string | Required | The cloud provider access key secret. |
credentials.access_key_region |
string | Required | The cloud provider region. |
| Field | Type | Description |
|---|---|---|
added_id |
integer | The ID assigned to the verified credentials. |
listCredentials
POST /v2/cloud
Returns all stored cloud provider credentials, grouped by provider. Ensure this call is made over a secure (TLS) connection as credential secrets are included in the response.
| Field | Type | Description |
|---|---|---|
result |
object | Credentials grouped by provider name. |
result.aws |
array | List of stored AWS credential entries. |
result.gce |
array | List of stored GCE credential entries. |
Response example
{
"reply_received": "2020-01-29T11:01:25.893Z",
"request_created": "2020-01-29T11:01:25.887Z",
"request_id": 10,
"request_processed": "2020-01-29T11:01:25.893Z",
"request_status": "Ok",
"request_user_id": 4,
"result":{
"aws":[
{
"name":"MyAWS",
"comment":"this is a comment",
"id":1,
"credentials":
{
"access_key_id":"DEADBAADDEADBAAD0x0x0x0x",
"access_key_region":"ap-southeast-2",
"access_key_secret":"SECRET1SECRET0"
}
}
],
"gce":[
{
"name":"GCE1",
"comment":"DDDD",
"id":2,
"credentials":
{
"auth_provider_x509_cert_url":"https:\/\/www.googleapis.com\/oauth2\/v1\/certs",
"auth_uri":"https:\/\/accounts.google.com\/o\/oauth2\/auth",
"client_email":"[email protected]",
"client_id":"10000056887622948111",
"client_x509_cert_url":"https:\/\/www.googleapis.com\/robot\/v1\/metadata\/x509\/1234-compute%40developer.gserviceaccount.com",
"private_key":"-----BEGIN PRIVATE KEY-----\nFDSFSFDSFSDFDSFDSFDS\n-----END PRIVATE KEY-----\n",
"private_key_id":"b0a4df1c54fff4410c33c9bca57bd0fb01679000",
"project_id":"brave-night-121210",
"token_uri":"https:\/\/accounts.google.com\/o\/oauth2\/token",
"type":"service_account"
}
}
]
}
}
getCredentials
POST /v2/cloud
Returns a specific set of stored cloud credentials identified by id and provider.
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
integer | Required | The ID of the stored credentials to retrieve. |
provider |
string | Required | The cloud provider (e.g. aws). |
| Field | Type | Description |
|---|---|---|
data |
object | The stored credential entry. |
data.name |
string | The name assigned to the credential set. |
data.comment |
string | An optional comment for the credential set. |
data.id |
integer | The ID of the credential set. |
data.credentials |
object | The credential values for the provider. |
Response example
{
"reply_received": "2020-01-29T11:01:25.893Z",
"request_created": "2020-01-29T11:01:25.887Z",
"request_id": 10,
"request_processed": "2020-01-29T11:01:25.893Z",
"request_status": "Ok",
"request_user_id": 4,
"data":{
"name":"MyAWS",
"comment":"this is a comment",
"id":1,
"credentials":
{
"access_key_id":"DEADBAADDEADBAAD0x0x0x0x",
"access_key_region":"ap-southeast-2",
"access_key_secret":"SECRET1SECRET0"
}
}
}
addCredentials
POST /v2/cloud
Stores a new set of cloud provider credentials in the controller. Returns the assigned added_id on success.
| Parameter | Type | Required | Description |
|---|---|---|---|
provider |
string | Required | The cloud provider (e.g. aws). |
name |
string | Required | A name to assign to this credential set. |
credentials |
object | Required | The credential values for the provider. |
credentials.access_key_id |
string | Required | The cloud provider access key ID. |
credentials.access_key_secret |
string | Required | The cloud provider access key secret. |
credentials.access_key_region |
string | Required | The cloud provider region. |
comment |
string | Optional | A comment or description for this credential set. |
| Field | Type | Description |
|---|---|---|
added_id |
integer | The ID assigned to the newly stored credential set. |
updateCredentials
POST /v2/cloud
Updates an existing set of cloud provider credentials identified by id. All credential fields are replaced with the supplied values.
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
integer | Required | The ID of the credential set to update. |
provider |
string | Required | The cloud provider (e.g. aws). |
name |
string | Required | The name to assign to this credential set. |
credentials |
object | Required | The updated credential values for the provider. |
credentials.access_key_id |
string | Required | The cloud provider access key ID. |
credentials.access_key_secret |
string | Required | The cloud provider access key secret. |
credentials.access_key_region |
string | Required | The cloud provider region. |
comment |
string | Optional | A comment or description for this credential set. |
removeCredentials
POST /v2/cloud
Removes a stored set of cloud provider credentials identified by id and provider. Clusters or resources that depend on these credentials will no longer be able to access them.
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
integer | Required | The ID of the credential set to remove. |
provider |
string | Required | The cloud provider (e.g. aws). |
Cluster Information and Manipulation
Cluster information and cluster wide operations can be found on the path /v2/clusters. Information about hosts, alarms, license, statistics can also be sent back for convenience.
| Operation | Description |
|---|---|
| getConfig | Retrieve cluster configuration settings. |
| setConfig | Update cluster configuration settings. |
| getClusterInfo | Read information about a single cluster. |
| getAllClusterInfo | Get information about one or more clusters. |
| getAllClusterInfoWithAllPool | Get cluster information aggregated from all controllers in the pool. |
getConfig
POST /v2/clusters
This is the "getConfig" call for clusters. Please note that there is an other "getConfig" call for nodes and these two should not be mixed up. There are some similarities since the controller is itself a node, but this is an entirely different call because it is on a different path.
Here is how a getConfig call should look like:
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The ID of the cluster to get configuration for. |
| Field | Type | Description |
|---|---|---|
configuration |
object | Holds the cluster configuration. |
configuration.values |
array | List of configuration items showing possible settings. |
Response example
{
"configuration": {
"values": [
{
"current_value": "",
"default_value": null,
"description": "An arbitrary identifier string of this controller instance.",
"keys": [ "controller_id" ],
"name": "controller_id",
"sql_keys": [ "CONTROLLER_ID" ]
},
. . .
{
"current_value": null,
"default_value": null,
"description": "Specify a lock file and if present on a node, the node will not recover. It is the responsibilty of the administrator to create/remove the file.",
"keys": [ "node_recovery_lock_file" ],
"name": "node_recovery_lock_file",
"sql_keys": [ "NODE_RECOVERY_LOCK_FILE" ]
}
]
},
"debug_messages": [ "RPC V2 authenticated user is 'pipas'." ],
"reply_received": "2019-09-25T12:21:30.909Z",
"request_created": "2019-09-25T12:21:30.904Z",
"request_id": 3,
"request_processed": "2019-09-25T12:21:30.944Z",
"request_status": "Ok",
"request_user_id": 4
}
As it is shown the "configuration" field holds the cluster configuration and inside it there is a list "values" showing the possible settings. The structure of the data here might be enhanced later, we might want to send back more information.
setConfig
POST /v2/clusters
This is the "setConfig" call for clusters. There is a similar call for nodes, but that has slightly different requests and replies.
Here is how a setConfig request should look like:
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The ID of the cluster to set configuration for. |
configuration |
array | Required | List of configuration items with names and values to change. |
Here the changes are passed in a list with names and values. The names can be either any of the keys or any of the sql_keys for the configuration item as they are returned for the getConfig call. So one can issue a getConfig call, study, find the key to be changed and send back for the setConfig request.
One needs write access on the configuration (same as the write access on the cluster) to change the configuration.
getClusterInfo
POST /v2/clusters
This request is for reading information about one cluster. The cluster can be identified by the cluster ID or the cluster name.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Optional | The numerical ID of the cluster to get. The cluster can also be identified by its name. |
cluster_name |
string | Optional | The name of the cluster to get. The cluster can also be identified by its numerical ID. |
with_hosts |
boolean | Optional | Send also the list of hosts. |
with_sheet_info |
boolean | Optional | Send also the information from the sheet manager. |
with_databases |
boolean | Optional | Send also the databases we found on the cluster. |
with_license_check |
boolean | Optional | Send also the license info. |
getAllClusterInfo
POST /v2/clusters
This request can be used to get information about one or more clusters. The clusters can be identified by their cluster ID passed as a list of integers in the request.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_ids |
array | Optional | An optional list of cluster IDs represented as integers to control which clusters should be detailed in the reply. If this argument is not provided the controller will return information about clusters that the user can see. |
with_hosts |
boolean | Optional | Send also the list of hosts. |
with_containers |
boolean | Optional | Send also the information about the containers/VM-s. |
with_sheet_info |
boolean | Optional | Send also the information from the sheet manager. |
with_databases |
boolean | Optional | Send also the databases we found on the cluster. |
with_license_check |
boolean | Optional | Send also the license info. |
with_tags |
array | Optional | The request may contain this field to limit the list of the returned clusters to those that have at least one of the tags passed here. |
without_tags |
array | Optional | The request may contain this field to limit the list of the returned users to those that has none of the tags passed here. |
| Field | Type | Description |
|---|---|---|
clusters |
array | A list of clusters with all details categorised under CmonClusterInfo objects. |
total |
integer | The total number of clusters managed by the controller. |
Response example
{
"clusters": [
{
"alarm_statistics":
{
"class_name": "CmonAlarmStatistics",
"cluster_id": 1,
"critical": 2,
"warning": 1
},
"class_name": "CmonClusterInfo",
"cluster_auto_recovery": true,
"cluster_id": 1,
"cluster_name": "ft_postgresql_59238",
"cluster_type": "POSTGRESQL_SINGLE",
"configuration_file": "/tmp/cmon_1.cnf",
"group_owner":
{
"class_name": "CmonGroup",
"group_id": 4,
"group_name": "testgroup"
},
"hosts": [
{
"class_name": "CmonPostgreSqlHost",
"clusterid": 1,
"configfile": [ "/etc/postgresql/9.6/main/postgresql.conf" ],
"connected": true,
"container": true,
"data_directory": "/var/lib/postgresql/9.6/main",
"datadir": "/var/lib/postgresql/9.6/main",
"description": "",
"distribution":
{
"codename": "xenial",
"name": "ubuntu",
"release": "16.04",
"type": "debian"
},
"hostId": 1,
"hostname": "192.168.1.177",
"hoststatus": "CmonHostOnline",
"hot_standby": true,
"ip": "192.168.1.177",
"lastseen": 1501216153,
"logfile": "/var/log/postgresql/postgresql-9.6-main.log[0m",
"maintenance_mode_active": false,
"message": "Up and running",
"nodetype": "postgres",
"pid": 5248,
"pidfile": "/var/run/postgresql/9.6-main.pid",
"pingstatus": 0,
"pingtime": 0,
"port": 8089,
"readonly": false,
"received_location": "0/1520838",
"replay_location": "0/1520838",
"role": "master",
"sshfailcount": 0,
"ssl_certs":
{
"server":
{
"ca": "",
"id": 0,
"key": "/etc/ssl/private/ssl-cert-snakeoil.key",
"path": "/etc/ssl/certs/ssl-cert-snakeoil.pem"
}
},
"timestamp": 1501216153,
"unique_id": 1,
"uptime": 220,
"version": "9.6.3",
"wallclock": 1501216175,
"wallclocktimestamp": 1501216110
},
{
"class_name": "CmonHost",
"clusterid": 1,
"configfile": "/tmp/cmon_1.cnf",
"connected": true,
"container": false,
"distribution":
{
"codename": "trusty",
"name": "ubuntu",
"release": "14.04",
"type": "debian"
},
"hostId": 2,
"hostname": "192.168.1.127",
"hoststatus": "CmonHostOnline",
"ip": "192.168.1.127",
"lastseen": 1501216153,
"logfile": "/tmp/cmon_1.log",
"maintenance_mode_active": false,
"message": "Up and running",
"nodetype": "controller",
"pid": 59196,
"pingstatus": 0,
"pingtime": 0,
"port": 9555,
"role": "controller",
"timestamp": 1501216153,
"unique_id": 2,
"uptime": 413,
"version": "1.4.3",
"wallclock": 1501216110,
"wallclocktimestamp": 1501216110
} ],
"info":
{
"cluster.status": 2,
"cluster.statustext": "Cluster started.",
"cmon.domainname": "",
"cmon.hostname": "t7500",
"cmon.running": true,
"cmon.starttime": 1501215924,
"cmon.uptime": 227,
"conf.backup_retention": 31,
"conf.clusterid": 1,
"conf.clustername": "ft_postgresql_59238",
"conf.clustertype": 5,
"conf.configfile": "/tmp/cmon_1.cnf",
"conf.hostname": "192.168.1.127",
"conf.os": "debian",
"conf.statustext": "Configuration loaded.",
"host.1.connected": true,
"host.1.cpu_io_wait_percent": 0,
"host.1.cpu_steal_percent": 0,
"host.1.cpu_usage_percent": 7.92751,
"host.1.cpucores": 16,
"host.1.cpuinfo": [
{
"class_name": "CmonCpuInfo",
"cpucores": 4,
"cpumaxmhz": 2.268e+06,
"cpumhz": 1600,
"cpumodel": "Intel(R) Xeon(R) CPU L5520 @ 2.27GHz",
"cputemp": 54.5,
"hostid": 1,
"physical_cpu_id": 0,
"siblings": 8,
"vendor": "GenuineIntel"
},
{
"class_name": "CmonCpuInfo",
"cpucores": 4,
"cpumaxmhz": 2.268e+06,
"cpumhz": 1600,
"cpumodel": "Intel(R) Xeon(R) CPU L5520 @ 2.27GHz",
"cputemp": 54.5,
"hostid": 1,
"physical_cpu_id": 1,
"siblings": 8,
"vendor": "GenuineIntel"
} ],
"host.1.cpumaxmhz": 2268,
"host.1.cpumhz": 1600,
"host.1.cpumodel": "Intel(R) Xeon(R) CPU L5520 @ 2.27GHz",
"host.1.cputemp": 54.5,
"host.1.devices": [ "/dev/mapper/core1--vg-root" ],
"host.1.free_disk_bytes": 156237512704,
"host.1.hostname": "192.168.1.177",
"host.1.interfaces": [ "eth0" ],
"host.1.ip": "192.168.1.177",
"host.1.membuffer": 0,
"host.1.memcached": 3,
"host.1.memfree": 16450528,
"host.1.memtotal": 16777216,
"host.1.network_interfaces": [
{
"interface_name": "eth0",
"rx_bytes_per_sec": 10438.1,
"tx_bytes_per_sec": 15937.2
} ],
"host.1.pingdelay": -1,
"host.1.pingstatustext": "Creating ICMP socket (to ping '192.168.1.177') failed: Operation not permitted.",
"host.1.port": 8089,
"host.1.rx_bytes_per_second": 10438.1,
"host.1.swapfree": 0,
"host.1.swaptotal": 0,
"host.1.total_disk_bytes": 208033853440,
"host.1.tx_bytes_per_second": 15937.2,
"host.1.uptime": 390,
"host.1.wallclock": 1501216175,
"host.1.wallclocksampled": 1501216110,
"host.2.class_name": "controller",
"host.2.connected": true,
"host.2.cpu_io_wait_percent": 4.14259,
"host.2.cpu_steal_percent": 0,
"host.2.cpu_usage_percent": 178.599,
"host.2.cpucores": 24,
"host.2.cpuinfo": [
{
"class_name": "CmonCpuInfo",
"cpucores": 6,
"cpumaxmhz": 2.661e+06,
"cpumhz": 2660,
"cpumodel": "Intel(R) Xeon(R) CPU X5650 @ 2.67GHz",
"cputemp": 0,
"hostid": 2,
"physical_cpu_id": 0,
"siblings": 12,
"vendor": "GenuineIntel"
},
{
"class_name": "CmonCpuInfo",
"cpucores": 6,
"cpumaxmhz": 2.661e+06,
"cpumhz": 2661,
"cpumodel": "Intel(R) Xeon(R) CPU X5650 @ 2.67GHz",
"cputemp": 0,
"hostid": 2,
"physical_cpu_id": 1,
"siblings": 12,
"vendor": "GenuineIntel"
} ],
"host.2.cpumaxmhz": 2661,
"host.2.cpumhz": 2660,
"host.2.cpumodel": "Intel(R) Xeon(R) CPU X5650 @ 2.67GHz",
"host.2.cputemp": 0,
"host.2.devices": [ "/dev/sda1" ],
"host.2.free_disk_bytes": 1404706975744,
"host.2.hostname": "192.168.1.127",
"host.2.interfaces": [ "eth0" ],
"host.2.ip": "192.168.1.127",
"host.2.membuffer": 232240,
"host.2.memcached": 13097476,
"host.2.memfree": 14108052,
"host.2.memtotal": 49453276,
"host.2.network_interfaces": [
{
"interface_name": "eth0",
"rx_bytes_per_sec": 17268.2,
"tx_bytes_per_sec": 11158.5
} ],
"host.2.pingdelay": -1,
"host.2.pingstatustext": "Creating ICMP socket (to ping '192.168.1.127') failed: Operation not permitted.",
"host.2.port": 9555,
"host.2.rx_bytes_per_second": 17268.2,
"host.2.swapfree": 0,
"host.2.swaptotal": 0,
"host.2.total_disk_bytes": 2125259440128,
"host.2.tx_bytes_per_second": 11158.5,
"host.2.uptime": 2.65439e+06,
"host.2.version": "1.4.3",
"host.2.wallclock": 1501216110,
"host.2.wallclocksampled": 1501216110,
"license.expires": -1,
"license.status": false,
"license.statustext": "No license found.",
"mail.statustext": "Created.",
"netStat.1.eth0.rxBytes": 5238632,
"netStat.1.eth0.txBytes": 33144284,
"netStat.2.eth0.rxBytes": 531337507751,
"netStat.2.eth0.txBytes": 505661940612
},
"job_statistics":
{
"by_state":
{
"ABORTED": 0,
"DEFINED": 0,
"DEQUEUED": 0,
"FAILED": 0,
"FINISHED": 0,
"RUNNING": 0
},
"class_name": "CmonJobStatistics",
"cluster_id": 1
},
"log_file": "/tmp/cmon_1.log",
"maintenance_mode_active": false,
"managed": true,
"node_auto_recovery": true,
"owner":
{
"class_name": "CmonUser",
"email_address": "[email protected]",
"first_name": "Laszlo",
"groups": [
{
"class_name": "CmonGroup",
"group_id": 4,
"group_name": "testgroup"
} ],
"last_login": "2017-07-28T04:29:14.185Z",
"last_name": "Pere",
"title": "",
"user_id": 3,
"user_name": "pipas"
},
"state": "STARTED",
"status_text": "All nodes are operational.",
"vendor": "postgres",
"version": "9.6"
} ],
"reply_received": "2017-07-28T04:29:14.197Z",
"request_created": "2017-07-28T04:29:14.193Z",
"request_id": 3,
"request_processed": "2017-07-28T04:29:14.241Z",
"request_status": "Ok",
"request_user_id": 3,
"total": 1
}
For the "getAllClusterInfo" request the controller is able to send back a lot of information. A full view of the cluster can be implemented using the reply. The following main categories can be found here:
cluster: A list of clusters. All the details are categorised under these cmonclusterinfo objects.hosts: The list of hosts that are part of the cluster. This piece of information is sent if the request had the "with_hosts" property set to true.info: The information that the sheet manager collected about the cluster.alarm_statistics: Shows the number of alarms on the syste. further information can be found in the CmonSimpleObject documentation.job_statistics: Statistical information about the jobs the cluster has. Further information can be found in the CmonJobStatistics page.total: The total number of clusters managed by the controller.
getAllClusterInfoWithAllPool
POST /v2/clusters
This request behaves exactly like getAllClusterInfo but aggregates data from all active controllers in the pool. It applies the same filtering logic, access controls, and generates the same response structure as the normal getAllClusterInfo method.
The difference is that instead of getting data from the local controller only, it retrieves cluster information from all active controllers and presents them in a unified response.
createAccount
POST /v2/clusters
This request can be used to create an account on the cluster. Please note that this is not going to be a Cmon User, this RPC is for creating SQL users.
| Parameter | Type | Required | Description |
|---|---|---|---|
account |
object | Required | A CmonAccount class object that defines the properties of the account that will be created. To get a comprehensive list of the properties the controller supports in the CmonAccount class one can run the following command (or check the cmonaccount section): s9s metatype --list-properties --type=CmonAccount --long |
cluster_id |
integer | Required | The numerical ID of the cluster on which the account will be created. The cluster can also be identified by its name. |
cluster_name |
string | Optional | The name of the cluster on which the new account will be created. The cluster can also be identified by its numerical ID. |
updateAccount
POST /v2/clusters
This request can be used to update an account on the cluster. Please note that this is not going to be a Cmon User, this RPC is for creating SQL users.
| Parameter | Type | Required | Description |
|---|---|---|---|
account |
object | Required | A CmonAccount class object that defines the properties of the account that will be updated. To get a comprehensive list of the properties the controller supports in the CmonAccount class one can run the following command (or check the cmonaccount section): s9s metatype --list-properties --type=CmonAccount --long |
cluster_id |
integer | Required | The numerical ID of the cluster on which the account will be updated. The cluster can also be identified by its name. |
cluster_name |
string | Optional | The name of the cluster on which the account will be updated. The cluster can also be identified by its numerical ID. |
{
"account":
{
"class_name": "CmonAccount",
"grants": "john:ALL;pipas:INSERT",
"host_allow": "1.2.3.4",
"own_database": "laszlo",
"password": "passwd",
"user_name": "laszlo",
"ssl_type": "SSL",
"max_user_connections": 0,
"max_questions": 0,
"max_updates": 0,
"max_connections": 0
},
"cluster_id": 1,
"operation": "updateAccount",
"request_created": "2017-01-27T14:03:09.491Z"
}
getAccounts
POST /v2/clusters
The getAccounts call can be used to get the accounts from the cluster.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The numerical ID of the cluster to get. The cluster can also be identified by its name. |
cluster_name |
string | Optional | The name of the cluster to get. The cluster can also be identified by its numerical ID. |
limit |
integer | Optional | Limits the number of accounts sent back in the reply. |
offset |
integer | Optional | The offset of the first account sent back in the reply. |
| Field | Type | Description |
|---|---|---|
accounts |
array | A list of cmonaccount objects, the accounts found on the cluster. |
total |
integer | The total number of accounts found on the cluster regardless the number of accounts sent back in the reply. |
Response example
{
"accounts": [
{
"class_name": "CmonAccount",
"connections": 1,
"grants": "CREATE USER,CREATE DATABASE,LOGIN,REPLICATION,SUPER;template1:CREATE,TEMPORARY,CONNECT;template0:CREATE,TEMPORARY,CONNECT",
"host_allow": "",
"max_connections": 0,
"password": "",
"user_name": "postgres"
},
. . .
{
"class_name": "CmonAccount",
"grants": "LOGIN;joe:CREATE,TEMPORARY,CONNECT",
"host_allow": "",
"max_connections": 0,
"password": "",
"user_name": "joe"
} ],
"request_created": "2017-08-10T03:03:49.592Z",
"request_id": 3,
"request_processed": "2017-08-10T03:03:49.639Z",
"request_status": "Ok",
"request_user_id": 3,
"total": 5
}
listAccounts
POST /v2/clusters
The listAccounts call can be used to get the accounts from the cluster.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The numerical ID of the cluster to get. The cluster can also be identified by its name. |
cluster_name |
string | Optional | The name of the cluster to get. The cluster can also be identified by its numerical ID. |
limit |
integer | Optional | Limits the number of accounts sent back in the reply. |
offset |
integer | Optional | The offset of the first account sent back in the reply. |
| Field | Type | Description |
|---|---|---|
accounts |
array | A list of cmonaccount objects, the accounts found on the cluster. |
total |
integer | The total number of accounts found on the cluster regardless the number of accounts sent back in the reply. |
Response example
{
"queryResults": [
{
"accounts": [
{
"class_name": "CmonAccount",
"connections": 1,
"grants": "CREATE USER,CREATE DATABASE,LOGIN,REPLICATION,SUPER;template1:CREATE,TEMPORARY,CONNECT;template0:CREATE,TEMPORARY,CONNECT",
"host_allow": "",
"max_connections": 0,
"password": "",
"user_name": "postgres"
},
. . .
{
"class_name": "CmonAccount",
"grants": "LOGIN;joe:CREATE,TEMPORARY,CONNECT",
"host_allow": "",
"max_connections": 0,
"password": "",
"user_name": "joe"
} ],
"hostname": "masterHostName123",
"port": 3306
}
],
"request_created": "2017-08-10T03:03:49.592Z",
"request_id": 3,
"request_processed": "2017-08-10T03:03:49.639Z",
"request_status": "Ok",
"request_user_id": 3,
"total": 5
}
deleteAccount
POST /v2/clusters
This request is for deleting a user account from a cluster.
| Parameter | Type | Required | Description |
|---|---|---|---|
account |
object | Required | The account that should be deleted. To get a comprehensive list of the properties the controller supports in the CmonAccount class one can run the following command (or check the cmonaccount section): s9s metatype --list-properties --type=CmonAccount --long |
cluster_id |
integer | Required | The numerical ID of the cluster from which the account should be removed. The cluster can also be identified by the cluster name. |
cluster_name |
string | Optional | The name of the cluster from which the account will be removed. The cluster can also be identified by its numerical ID. |
grantPrivileges
POST /v2/clusters
The request can be used to grant privileges for a existing user to an existing database.
| Parameter | Type | Required | Description |
|---|---|---|---|
account |
object | Required | The account that will be granted some privileges on some database. To get a comprehensive list of the properties the controller supports in the CmonAccount class one can run the following command (or check the cmonaccount section): s9s metatype --list-properties --type=CmonAccount --long |
cluster_id |
integer | Required | The numerical ID of the cluster on which the privileges will be granted. The cluster can also be identified by name. |
cluster_name |
string | Optional | The name of the cluster on which the privileges will be granted. The cluster can also be identified by the cluster ID. |
privileges |
string | Required | The privileges to grant. This property should be a string in pdl_language format. |
revokePrivileges
POST /v2/clusters
The request can be used to revoke privileges from an existing user to an existing database.
| Parameter | Type | Required | Description |
|---|---|---|---|
account |
object | Required | The account from privileges will be revoked on some database. To get a comprehensive list of the properties the controller supports in the CmonAccount class one can run the following command (or check the cmonaccount section): s9s metatype --list-properties --type=CmonAccount --long |
cluster_id |
integer | Required | The numerical ID of the cluster on which the privileges will be granted. The cluster can also be identified by name. |
cluster_name |
string | Optional | The name of the cluster on which the privileges will be granted. The cluster can also be identified by the cluster ID. |
privileges |
string | Required | The privileges to grant. This property should be a string in pdl_language format. |
revokeAllPrivileges
POST /v2/clusters
The request can be used to revoke all privileges from an existing user.
| Parameter | Type | Required | Description |
|---|---|---|---|
account |
object | Required | The account from all privileges will be revoked. To get a comprehensive list of the properties the controller supports in the CmonAccount class one can run the following command (or check the cmonaccount section): s9s metatype --list-properties --type=CmonAccount --long |
cluster_id |
integer | Required | The numerical ID of the cluster on which the privileges will be granted. The cluster can also be identified by name. |
cluster_name |
string | Optional | The name of the cluster on which the privileges will be granted. The cluster can also be identified by the cluster ID. |
getSqlProcesses
POST /v2/clusters
Returns the list of currently active SQL processes (connections and running queries) across all nodes in a cluster. Useful for monitoring active workloads and identifying long-running or blocking queries.
| Field | Type | Description |
|---|---|---|
processes |
array | List of active SQL process objects across all nodes in the cluster. |
Response example
{
"debug_messages": [ "RPC V2 authenticated user is 'pipas'." ],
"processes": [
{
"blocked_by_trx_id": "",
"client": "",
"command": "Sleep",
"currentTime": 1582871076,
"db": "",
"duration": 139914683312432,
"host": "",
"hostId": 1,
"hostname": "192.168.0.227",
"info": "",
"innodb_status": "",
"innodb_trx_id": "",
"instance": "192.168.0.227:3306",
"lastseen": 139914683312176,
"message": "",
"mysql_trx_id": 1,
"pid": 1,
"query": "",
"reportTs": 1582871076,
"sql": "",
"state": "wsrep aborter idle",
"time": 664,
"user": "system user"
},
{
"blocked_by_trx_id": "",
"client": "",
"command": "Sleep",
"currentTime": 1582871076,
"db": "",
"duration": 139914683312432,
"host": "",
"hostId": 3,
"hostname": "192.168.0.220",
"info": "",
"innodb_status": "",
"innodb_trx_id": "",
"instance": "192.168.0.220:3306",
"lastseen": 139914683312176,
"message": "",
"mysql_trx_id": 5,
"pid": 5,
"query": "",
"reportTs": 1582871076,
"sql": "",
"state": "",
"time": 130,
"user": "system user"
} ],
"request_created": "2020-02-28T06:24:36.355Z",
"request_id": 3,
"request_processed": "2020-02-28T06:24:36.378Z",
"request_status": "Ok",
"request_user_id": 4
}
getTopQueries
POST /v2/clusters
This request can be used to get the top queries, actually the top query patterns (AKA digests).
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The numerical ID of the cluster to query. |
limit |
integer | Optional | Optional number that limits the number of items returned. |
offset |
integer | Optional | Optional number, the offset of the first item returned. |
filterStrings |
array | Optional | Optional list of filters to be applied on the server name and port (the "instance" of the entry) the same way the file name patterns are handled in the UNIX shell. |
| Field | Type | Description |
|---|---|---|
digests |
array | List of CmonStatementDigest objects representing the top query patterns. |
total |
integer | The total number of digests found. |
Response example
{
"debug_messages": [ "RPC V2 authenticated user is 'pipas'." ],
"digests": [
{
"affectedRows": 9020,
"class_name": "CmonStatementDigest",
"count": 9020,
"databaseName": "pipas1_3198",
"dtFirstSeen": "2020-03-25T14:37:24.000Z",
"dtLastSeen": "2020-03-25T14:44:02.000Z",
"instance": "192.168.0.215:6032",
"statementPattern": "INSERT INTO test_table(NAME, VALUE) VALUES(?, ?)",
"waitMillisMax": 610.891,
"waitMillisMin": 8.935,
"waitMillisSum": 324158
},
{
"affectedRows": 9020,
"class_name": "CmonStatementDigest",
"count": 9020,
"databaseName": "pipas1_3198",
"dtFirstSeen": "2020-03-25T14:37:24.000Z",
"dtLastSeen": "2020-03-25T14:44:02.000Z",
"instance": "192.168.0.227:3306",
"statementPattern": "INSERT INTO `test_table` ( NAME , VALUE ) VALUES (...) ",
"waitMillisAvg": 35.7737,
"waitMillisMax": 610.721,
"waitMillisMin": 8.78106,
"waitMillisSum": 322679
} ],
"request_created": "2020-03-26T08:33:01.146Z",
"request_id": 3,
"request_processed": "2020-03-26T08:33:01.202Z",
"request_status": "Ok",
"request_user_id": 4,
"total": 37
}
createDatabase
POST /v2/clusters
This request can be used to create a database on the cluster.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The numerical ID of the cluster on which the new database will be created. The cluster can also be identified by its name. |
cluster_name |
string | Optional | The name of the cluster on which the new database will be created. The cluster can also be identified by its name. |
database |
object | Required | The database to be created. |
| Field | Type | Description |
|---|---|---|
database |
object | The created CmonDataBase object. |
Response example
{
"database":
{
"class_name": "CmonDataBase",
"database_name": "testDatabase"
},
"messages": [ "Database 'testDatabase' created." ],
"reply_received": "2017-08-10T08:16:17.949Z",
"request_created": "2017-08-10T08:16:17.945Z",
"request_id": 3,
"request_processed": "2017-08-10T08:16:18.098Z",
"request_status": "Ok",
"request_user_id": 3
}
ping
POST /v2/clusters
The "ping" request can be used to check the connection to the Cmon Controller or keep it alive. Every ping request will be replied with a simple message that holds some general information about the controller and the connection.
| Field | Type | Description |
|---|---|---|
authenticated |
boolean | Whether the connection is authenticated. |
package_bugreport |
string | Contact address for bug reports. |
package_name |
string | The name of the package. |
package_version |
string | The version of the package. |
rpc_version |
string | The RPC API version. |
Response example
{
"authenticated": true,
"package_bugreport": "[email protected]",
"package_name": "cmon",
"package_version": "1.4.3",
"request_created": "2017-06-22T11:55:39.854Z",
"request_id": 3,
"request_processed": "2017-06-22T11:55:39.900Z",
"request_status": "Ok",
"request_user_id": 12,
"rpc_version": "2.0"
}
availableUpgrades
POST /v2/clusters
This request is for reading a list of available package upgrades for the cluster. The cluster can be identified by the cluster ID or the cluster name.
| Parameter | Type | Required | Description |
|---|---|---|---|
nodes |
array | Optional | List of nodes (hosts) to query available package upgrades on. |
cluster_id |
integer | Required | The numerical ID of the cluster to get. The cluster can also be identified by its name. |
cluster_name |
string | Optional | The name of the cluster to get. The cluster can also be identified by its numerical ID. |
Configuration
The /v2/config path provides access to various configuration files.
| Operation | Description |
|---|---|
| getConfig | Get the configuration of one specific node in a cluster. |
| getConfigs | Obtain all configuration files of a cluster. |
| setConfig | Change individual configuration values for a host. |
| unsetConfig | Unset or comment out individual configuration values for a host. |
| getLdapConfig | Read the LDAP configuration. |
| setLdapConfig | Write the LDAP configuration. |
| listTemplates | List the ClusterControl provided configuration templates. |
getConfig
POST /v2/config
This call is for getting the configuration of one specific node in a cluster.
Access rights: The authenticated user has to have read access on both the host and the cluster to get successful reply on this call.
| Parameter | Type | Required | Description |
|---|---|---|---|
hostname |
string | Required | The hostname of the node to get configuration for. |
| Field | Type | Description |
|---|---|---|
config |
object | Contains the configuration of the host. |
files |
array | One host can have multiple configuration files, so this part contains a list one element for every configuration file. |
values |
array | The parsed version of the configuration. Every item is one configuration value in some configuration file. |
content |
string | The literal content of the configuration file escaped for JSON format. |
path |
string | The full path of the configuration file. |
syntax |
string | The syntax of the configuration file. This can be GenericConfigSyntax, MySqlConfigSyntax, ProxySqlConfigSyntax, HaProxyConfigSyntax, YamlSyntax, UnknownSyntax or MongoConfigSyntax which is the same as YamlSyntax. |
Response example
{
"config":
{
"className": "CmonClusterConfig",
"files": [
{
"filename": "cmon_1.cnf",
"values": [
{
"filepath": "/tmp/cmon_1.cnf",
"linenumber": 1,
"section": "",
"value": "1",
"variablename": "cluster_id"
},
. . .
{
"filepath": "/tmp/cmon_1.cnf",
"linenumber": 29,
"section": "",
"value": "postgres",
"variablename": "vendor"
} ]
} ],
"host":
{
"class_name": "CmonHost",
"hostname": "192.168.1.127",
"port": 9555
}
},
"files": [
{
"content": "cluster_id=1\ncluster_type=postgresql_single\ncmon_db=ft_install_testdb\ncmon_user=root\ncreated_by_job=1\ngroup_owner=4\nhostname=192.168.1.127\ninit_service_name=postgresql\nlogfile=/tmp/cmon_1.log\nmode=controller\nmonitored_mountpoints=/var/lib/postgresql/9.6/main\nmysql_hostname=127.0.0.1\nmysql_password='p'\nmysql_port=3306\nname='ft_postgresql_63564'\nos=debian\nosuser=pipas\nowner=3\npidfile=/var/run\npostgresql_password=passwd12\npostgresql_server_addresses=192.168.1.178:8089\npostgresql_user=postmaster\nrepl_password=\nrepl_user=\nserver_version=9.6\nssh_identity=\nssh_port=22\ntype=postgresql_single\nvendor=postgresql\n",
"filename": "cmon_1.cnf",
"path": "/tmp/cmon_1.cnf",
"syntax": "MySqlConfigSyntax"
} ],
"request_created": "2017-07-28T09:48:30.491Z",
"request_id": 3,
"request_processed": "2017-07-28T09:48:30.541Z",
"request_status": "Ok",
"request_user_id": 3
}
getConfigs
POST /v2/config
A method to obtain all configuration files of a cluster.
Access rights: The authenticated user has to have read access on the cluster to get successful reply on this call.
| Field | Type | Description |
|---|---|---|
configs |
array | The configurations of the nodes, one element per node. |
Response example
{
"configs":
[
{"config": {
"className": "CmonClusterConfig",
"files": [
{
"filename": "cmon_1.cnf",
"values": [
{
"filepath": "/tmp/cmon_1.cnf",
"linenumber": 1,
"section": "",
"value": "1",
"variablename": "cluster_id"
},
. . .
{
"filepath": "/tmp/cmon_1.cnf",
"linenumber": 29,
"section": "",
"value": "postgres",
"variablename": "vendor"
} ]
} ],
"host":
{
"class_name": "CmonHost",
"hostname": "192.168.1.127",
"port": 9555
}
},
"files": [ {
"content": "cluster_id=1\ncluster_type=postgresql_single\ncmon_db=ft_install_testdb\ncmon_user=root\ncreated_by_job=1\ngroup_owner=4\nhostname=192.168.1.127\ninit_service_name=postgresql\nlogfile=/tmp/cmon_1.log\nmode=controller\nmonitored_mountpoints=/var/lib/postgresql/9.6/main\nmysql_hostname=127.0.0.1\nmysql_password='p'\nmysql_port=3306\nname='ft_postgresql_63564'\nos=debian\nosuser=pipas\nowner=3\npidfile=/var/run\npostgresql_password=passwd12\npostgresql_server_addresses=192.168.1.178:8089\npostgresql_user=postmaster\nrepl_password=\nrepl_user=\nserver_version=9.6\nssh_identity=\nssh_port=22\ntype=postgresql_single\nvendor=postgresql\n",
"filename": "cmon_1.cnf",
"path": "/tmp/cmon_1.cnf",
"syntax": "MySqlConfigSyntax"
} ]},
],
"request_created": "2023-02-23T09:48:30.491Z",
"request_id": 3,
"request_processed": "2023-02-23T09:48:30.541Z",
"request_status": "Ok",
"request_user_id": 3
}
setConfig
POST /v2/config
This call is for changing individual configuration values for a host. Multiple values can be changed by sending one request.
Access rights: The authenticated user has to have write access on both the host and the cluster to get successful reply on this call.
| Parameter | Type | Required | Description |
|---|---|---|---|
configuration |
array | Required | A list of values to be changed. |
hostname |
string | Required | The name of the host where the configuration should be changed. |
port |
integer | Optional | If the hostname is not enough to identify the node the sender can provide the port number to identify the node. The port is not mandatory, but might be needed. |
| Field | Type | Description |
|---|---|---|
messages |
array | This call can send multiple messages back. Changing the configuration is a complex step and may result in more than one messages. |
unsetConfig
POST /v2/config
This call is for unsetting, commenting out individual configuration values for a host. Multiple values can be unset by sending one request.
Access rights: The authenticated user has to have write access on both the host and the cluster to get successful reply on this call.
| Parameter | Type | Required | Description |
|---|---|---|---|
configuration |
array | Required | A list of variable names to be changed. |
hostname |
string | Required | The name of the host where the configuration should be changed. |
port |
integer | Optional | If the hostname is not enough to identify the node the sender can provide the port number to identify the node. The port is not mandatory, but might be needed. |
| Field | Type | Description |
|---|---|---|
messages |
array | This call can send multiple messages back. Changing the configuration is a complex step and may result in more than one messages. |
getLdapConfig
POST /v2/config
This call is for reading the LDAP configuration. Access to the LDAP configuration is controlled by the access rights for the "/.runtime/LDAP/configuration" CDT entry, whoever has read access to that CDT entry can get the LDAP configuration through this call.
| Field | Type | Description |
|---|---|---|
effective_privileges |
string | Shows what access privileges the authenticated user has. So with this field the caller can immediately decide if the user has the rights to change the settings or not. |
ldap_configuration |
object | The LDAP configuration. |
Response example
{
"controller_id": "ae03400a-b1d1-42eb-98ad-3196acc1ec23",
"effective_privileges": "rwx",
"reply_received": "2021-01-13T07:22:33.878Z",
"request_created": "2021-01-13T07:22:33.872Z",
"request_id": 2,
"request_processed": "2021-01-13T07:22:33.877Z",
"request_status": "Ok",
"request_user_id": 1,
"debug_messages": [ "RPC V2 authenticated user is 'system'." ],
"ldap_configuration": {
"enabled": false,
"ldapAdminPassword": null,
"ldapAdminUser": null,
"ldapGroupSearchRoot": null,
"ldapServerUri": null,
"ldapUserSearchRoot": null,
"defaults": {
"enabled": false,
"ldapAdminPassword": "",
"ldapAdminUser": "CN=Administrator,CN=Users,DC=ldap,DC=mydomain,DC=com",
"ldapGroupSearchRoot": "CN=Groups,OU=IT,DC=ldap,DC=mydomain,DC=com",
"ldapServerUri": "ldaps://ldap.mydomain.com:686",
"ldapUserSearchRoot": "CN=Users,DC=ldap,DC=mydomain,DC=com",
"groupMappings": [ ],
"ldapSettings": {
"ldapEmailAttributes": "mail,userPrincipalName",
"ldapGroupClassName": "",
"ldapGroupIdAttributes": "dn,uid",
"ldapGroupNameAttribute": "cn",
"ldapGroupSearchRoot": "CN=Groups,OU=IT,DC=ldap,DC=mydomain,DC=com",
"ldapMemberAttributes": "member,memberUid",
"ldapNetworkTimeout": 5,
"ldapProtocolVersion": 3,
"ldapQueryTimeLimit": 5,
"ldapRealnameAttributes": "cn,displayName",
"ldapUserClassName": "objectclass=*",
"ldapUsernameAttributes": "uid,sAMAccountName"
},
"security": {
"caCertFile": "/etc/ssl/certs/ldap-ca.crt",
"certFile": "/etc/ssl/certs/ldap.crt",
"keyFile": "/etc/ssl/certs/ldap.pem"
}
},
"groupMappings": [ ],
"ldapSettings": {
"ldapEmailAttributes": null,
"ldapGroupClassName": null,
"ldapGroupIdAttributes": null,
"ldapGroupNameAttribute": null,
"ldapMemberAttributes": null,
"ldapNetworkTimeout": null,
"ldapProtocolVersion": null,
"ldapQueryTimeLimit": null,
"ldapRealnameAttributes": null,
"ldapUserClassName": null,
"ldapUsernameAttributes": null
},
"security": {
"caCertFile": null,
"certFile": null,
"keyFile": null
}
}
}
setLdapConfig
POST /v2/config
This call is for writing the LDAP configuration. Access to the LDAP configuration is controlled by the access rights for the "/.runtime/LDAP/configuration" CDT entry, whoever has write access to that CDT entry can set the LDAP configuration through this call.
| Parameter | Type | Required | Description |
|---|---|---|---|
ldap_configuration |
object | Required | The LDAP configuration. |
{
"operation": "setLdapConfig",
"request_created": "2021-01-13T07:22:33.966Z",
"request_id": 2,
"ldap_configuration": {
"enabled": true,
"ldapAdminPassword": "p",
"ldapAdminUser": "cn=admin,dc=homelab,dc=local",
"ldapGroupSearchRoot": "dc=homelab,dc=local",
"ldapServerUri": "ldap://ldap.homelab.local:389",
"ldapUserSearchRoot": "dc=homelab,dc=local",
"groupMappings": [ {
"cmonGroupName": "ldapgroup",
"ldapGroupId": "ldapgroup",
"sectionName": "mapping1"
} ],
"ldapSettings": {
"ldapEmailAttributes": "mail",
"ldapGroupClassName": null,
"ldapGroupIdAttributes": null,
"ldapGroupNameAttribute": null,
"ldapMemberAttributes": "memberUid",
"ldapNetworkTimeout": null,
"ldapProtocolVersion": null,
"ldapQueryTimeLimit": null,
"ldapRealnameAttributes": "displayName,cn",
"ldapUserClassName": null,
"ldapUsernameAttributes": "cn"
},
"security": {
"caCertFile": null,
"certFile": null,
"keyFile": null
}
}
}
Response example
{
"controller_id": "ae03400a-b1d1-42eb-98ad-3196acc1ec23",
"reply_received": "2021-01-13T07:22:33.980Z",
"request_created": "2021-01-13T07:22:33.966Z",
"request_id": 2,
"request_processed": "2021-01-13T07:22:33.979Z",
"request_status": "Ok",
"request_user_id": 1,
"debug_messages": [ "RPC V2 authenticated user is 'system'." ]
}
listTemplates
POST /v2/config
This call is to list the ClusterControl provided configuration templates.
| Field | Type | Description |
|---|---|---|
data |
object | Contains the configuration templates for the given cluster type, vendor, and version. |
Response example
{
"controller_id": "ae03400a-b1d1-42eb-98ad-3196acc1ec23",
"reply_received": "2021-01-13T07:22:33.878Z",
"request_created": "2021-01-13T07:22:33.872Z",
"request_id": 2,
"request_processed": "2021-01-13T07:22:33.877Z",
"request_status": "Ok",
"data":
{
"cluster_type": "replication",
"config_templates": [ "my.cnf.gtid_replication" ],
"vendor": "percona",
"version": "5.6",
"requestStatus": "ok",
}
}
setLicense
POST /v2/config
immediately.
Here is how a request should look like:
| Parameter | Type | Required | Description |
|---|---|---|---|
licensedata |
string | Required | The base64-encoded license data string. |
{
"operation": "setLicense",
"request_created": "2021-01-13T07:22:33.872Z",
"request_id": 2,
"licensedata": "ewogICAgImNvbXBhbnkiOiAiU2FudGEgQ2xhdXNlIEluYy4iLAogICAgImVtYWlsX2FkZHJlc3Mi\nOiAic2FudGFAaG9oby5obyIsCiAgICAiZXhwaXJhdGlvbl9kYXRlIjogIjIwMjEtMTItMjRUMDA6\nMDA6MDAuMDAxWiIsCiAgICAibGljZW5zZWRfbm9kZXMiOiA3LAogICAgInR5cGUiOiAiRGVtbyIK\nfQp7czlzLXNpZ25hdHVyZS1zZXBhcmF0b3J9CjBGAiEAmnAo0yCrXOs8s31wPY9axezCSWbBRXbl\nEQT4gQTrN2QCIQD0/L7Ji3OOPQW2DUG3Lgog0jzWcM+8D1I1QEolRpOfrQ=="
}
| Field | Type | Description |
|---|---|---|
data |
object | Object containing the license status and details. |
data.hasLicense |
boolean | Whether a valid license is present. |
data.licenseExpires |
integer | Number of days until the license expires. |
data.licenseStatus |
string | Human-readable license status message. |
data.license |
object | The license object with full details. |
data.license.class_name |
string | Class name of the license object. |
data.license.company |
string | Company name the license is issued to. |
data.license.days_left |
integer | Days remaining on the license. |
data.license.email_address |
string | Email address associated with the license. |
data.license.expiration_date |
string | ISO 8601 expiration date of the license. |
data.license.licensed_nodes |
integer | Number of nodes the license covers. |
data.license.type |
string | License type (e.g., Demo). |
data.license.used_nodes |
integer | Number of nodes currently in use. |
data.license.valid_date |
boolean | Whether the license date is valid. |
Response example
{
"controller_id": "ae03400a-b1d1-42eb-98ad-3196acc1ec23",
"reply_received": "2021-01-13T07:22:33.878Z",
"request_created": "2021-01-13T07:22:33.872Z",
"request_id": 2,
"request_processed": "2021-01-13T07:22:33.877Z",
"request_status": "Ok",
"data":
{
"hasLicense":true,
"licenseExpires":387,
"licenseStatus":"License found.",
"license":{
"class_name":"CmonLicense",
"company":"Santa Clause Inc.",
"days_left":16,
"email_address":"[email protected]",
"expiration_date":"2021-12-24T00:00:00.001Z",
"licensed_nodes":7,
"type":"Demo",
"used_nodes":89,
"valid_date":true
}
}
}
getLicense
POST /v2/config
Returns the current license information registered with the controller, including the license type, expiration date, licensed node count, and current usage.
| Field | Type | Description |
|---|---|---|
data |
object | Object containing the license status and details. |
data.hasLicense |
boolean | Whether a valid license is present. |
data.licenseExpires |
integer | Number of days until the license expires. |
data.licenseStatus |
string | Human-readable license status message. |
data.license |
object | The license object with full details. |
data.license.class_name |
string | Class name of the license object. |
data.license.company |
string | Company name the license is issued to. |
data.license.days_left |
integer | Days remaining on the license. |
data.license.email_address |
string | Email address associated with the license. |
data.license.expiration_date |
string | ISO 8601 expiration date of the license. |
data.license.licensed_nodes |
integer | Number of nodes the license covers. |
data.license.type |
string | License type (e.g., Demo). |
data.license.used_nodes |
integer | Number of nodes currently in use. |
data.license.valid_date |
boolean | Whether the license date is valid. |
Response example
{
"controller_id": "ae03400a-b1d1-42eb-98ad-3196acc1ec23",
"reply_received": "2021-01-13T07:22:33.878Z",
"request_created": "2021-01-13T07:22:33.872Z",
"request_id": 2,
"request_processed": "2021-01-13T07:22:33.877Z",
"request_status": "Ok",
"data":
{
"hasLicense":true,
"licenseExpires":387,
"licenseStatus":"License found.",
"license":{
"class_name":"CmonLicense",
"company":"Santa Clause Inc.",
"days_left":16,
"email_address":"[email protected]",
"expiration_date":"2021-12-24T00:00:00.001Z",
"licensed_nodes":7,
"type":"Demo",
"used_nodes":89,
"valid_date":true
}
}
}
setmailserver
POST /v2/config
Sets the SMTP mail server configuration used by the controller for sending notifications.
| Parameter | Type | Required | Description |
|---|---|---|---|
smtp_server |
object | Required | Object containing SMTP server configuration. |
smtp_server.hostname |
string | Required | Hostname of the SMTP server. |
smtp_server.password |
string | Required | Password for SMTP authentication. |
smtp_server.port |
integer | Required | SMTP server port number. |
smtp_server.sender |
string | Required | Email address used as the sender. |
smtp_server.use_tls |
boolean | Required | Whether to use TLS for the SMTP connection. |
smtp_server.username |
string | Required | Username for SMTP authentication. |
{
"operation": "setmailserver",
"smtp_server":
{
"hostname": "my.smtp.server",
"password": "password",
"port": 587,
"sender": "[email protected]",
"use_tls": false,
"username": "[email protected]"
}
}
getmailserver
POST /v2/config
Returns the current SMTP mail server configuration registered with the controller.
| Field | Type | Description |
|---|---|---|
smtp_server |
object | Object containing the SMTP server configuration. |
smtp_server.hostname |
string | Hostname of the SMTP server. |
smtp_server.password |
string | Password for SMTP authentication. |
smtp_server.port |
integer | SMTP server port number. |
smtp_server.sender |
string | Email address used as the sender. |
smtp_server.use_tls |
boolean | Whether TLS is enabled for the SMTP connection. |
smtp_server.username |
string | Username for SMTP authentication. |
Response example
{
"controller_id": "ae03400a-b1d1-42eb-98ad-3196acc1ec23",
"reply_received": "2022-01-13T07:22:33.878Z",
"request_created": "2022-01-13T07:22:33.872Z",
"request_id": 3,
"request_processed": "2022-01-13T07:22:33.877Z",
"request_status": "Ok",
"smtp_server":
{
"hostname": "my.smtp.server",
"password": "password",
"port": 587,
"sender": "[email protected]",
"use_tls": false,
"username": "[email protected]"
}
}
setContent
POST /v2/config
This call can be used to overwrite a configuration file content in a free way.
| Parameter | Type | Required | Description |
|---|---|---|---|
content |
string | Required | The new content to write to the configuration file. |
cluster_id |
integer | Required | The ID of the cluster. |
hostname |
string | Required | The hostname of the node whose configuration file is being updated. |
filename |
string | Required | The full path to the configuration file to overwrite. |
port |
integer | Required | The port of the node. |
| Field | Type | Description |
|---|---|---|
messages |
array | This call can send multiple messages back. Changing the configuration is a complex step and may result in more than one messages. |
addIntegration
POST /v2/config
This call can be used to add a cmon-events (clustercontrol-notifications package) external integration.
| Parameter | Type | Required | Description |
|---|---|---|---|
integration |
object | Required | Object describing the integration to add. |
integration.name |
string | Required | Name of the integration. |
integration.service_id |
string | Required | Service identifier for the integration (e.g., webhook). |
integration.is_active |
boolean | Required | Whether the integration is active. |
integration.config |
string | Required | JSON-encoded configuration string for the integration. |
updateIntegration
POST /v2/config
This call can be used to update (by id) a cmon-events (clustercontrol-notifications package) external integration.
The other operation is 'updateIntegration' then you must supply an existing 'id' otherwise the request will fail.
| Parameter | Type | Required | Description |
|---|---|---|---|
integration |
object | Required | Object describing the integration to update. |
integration.id |
integer | Required | The ID of the existing integration to update. |
integration.name |
string | Required | Name of the integration. |
integration.service_id |
string | Required | Service identifier for the integration (e.g., webhook). |
integration.is_active |
boolean | Required | Whether the integration is active. |
integration.config |
string | Required | JSON-encoded configuration string for the integration. |
{
"operation": "updateintegration",
"integration": {
"id": 1,
"name": "webhook",
"service_id": "webhook",
"is_active": true,
"config": "{\"clusters\":[-1],\"triggers\":[{\"trigger\":\"ALL\",\"severity\":\"ALL\"}],\"name\":\"webhook\",\"url\":\"https://webhook.site/9ab1ef3e-0d6c-4755-a997-e3bbbe22fa98\"}"
}
}
| Field | Type | Description |
|---|---|---|
integration |
object | The updated integration object. |
integration.id |
integer | The ID of the integration. |
integration.name |
string | Name of the integration. |
integration.service_id |
string | Service identifier for the integration. |
integration.is_active |
boolean | Whether the integration is active. |
integration.config |
string | JSON-encoded configuration string for the integration. |
Response example
{
"controller_id": "7f399ff3-7484-4a93-a47a-a5c0bba42fca",
"is_superuser": true,
"request_processed": "2023-05-05T12:16:31.637Z",
"request_status": "Ok",
"debug_messages":
[
"RPC V2 authenticated user is 'alex'."
],
"integration":
{
"name": "webhook",
"config": "{\"clusters\":[-1],\"triggers\":[{\"trigger\":\"ALL\",\"severity\":\"ALL\"}],\"name\":\"webhook\",\"url\":\"https://webhook.site/9ab1ef3e-0d6c-4755-a997-e3bbbe22fa98\"}",
"id": 1,
"is_active": true,
"service_id": "webhook"
}
}
removeIntegration
POST /v2/config
This call can be used to remove an external integration.
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
integer | Required | The ID of the integration to remove. |
listIntegrations
POST /v2/config
This call can be used to list external integrations, you may use pagination (limit, offset) arguments here.
| Field | Type | Description |
|---|---|---|
total |
integer | Total number of integrations. |
integrations |
array | List of integration objects. |
integrations[].id |
integer | The ID of the integration. |
integrations[].name |
string | Name of the integration. |
integrations[].service_id |
string | Service identifier for the integration. |
integrations[].is_active |
boolean | Whether the integration is active. |
integrations[].config |
string | JSON-encoded configuration string for the integration. |
Response example
{
"controller_id": "7f399ff3-7484-4a93-a47a-a5c0bba42fca",
"is_superuser": true,
"request_processed": "2023-05-05T12:16:31.637Z",
"request_status": "Ok",
"total": 1,
"debug_messages":
[
"RPC V2 authenticated user is 'alex'."
],
"integrations":
[
{
"name": "webhook",
"config": "{\"clusters\":[-1],\"triggers\":[{\"trigger\":\"ALL\",\"severity\":\"ALL\"}],\"name\":\"webhook\",\"url\":\"https://webhook.site/9ab1ef3e-0d6c-4755-a997-e3bbbe22fa98\"}",
"id": 1,
"is_active": false,
"service_id": "webhook"
}
]
}
getcomponentmeta
POST /v2/config
A method to obtain human readable description of e-mail notification components.
| Field | Type | Description |
|---|---|---|
total |
integer | Total number of component metadata entries. |
data |
array | List of component metadata objects. |
data[].alarm_name |
string | Human-readable name for alarms of this component. |
data[].component |
string | Internal component identifier. |
data[].log_name |
string | Human-readable name for logs of this component. |
data[].message_name |
string | Human-readable description of messages for this component. |
Response example
{
"controller_id": "7f399ff3-7484-4a93-a47a-a5c0bba42fca",
"is_superuser": true,
"request_processed": "2023-05-05T12:16:31.637Z",
"request_status": "Ok",
"total": 1,
"debug_messages":
[
"RPC V2 authenticated user is 'alex'."
],
"data":
[
{
"alarm_name": "Network alarms",
"component": "Network",
"log_name": "Network related logs",
"message_name": "Network related messages, e.g host unreachable, SSH issues."
},
{
"alarm_name": "Cmon Internal alarms",
"component": "CmonDatabase",
"log_name": "Cmon database logs",
"message_name": "Internal Cmon database related messages."
}
]
}
getrecipients
POST /v2/config
Obtain the recipients list.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The ID of the cluster to get recipients for. |
| Field | Type | Description |
|---|---|---|
total |
integer | Total number of recipients. |
data |
array | List of recipient email address strings. |
Response example
{
"request_processed": "2023-05-19T15:03:23.080Z",
"request_status": "Ok",
"total": 3,
"data":
[
"[email protected]",
"[email protected]",
"[email protected]"
]
}
setnotificationsettings
POST /v2/config
Sets/updates the notification settings for the specified email.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The ID of the cluster. |
daily_limit |
integer | Required | Maximum number of emails per day. |
digest_hour |
integer | Required | Hour of the day to send digest emails. |
email |
string | Required | The recipient email address to configure. |
settings |
object | Required | Notification settings per component and severity. |
time_zone |
integer | Required | Timezone offset in hours. |
{
"cluster_id": 200,
"daily_limit": 1000,
"digest_hour": 7,
"email": "[email protected]",
"operation": "setnotificationsettings",
"settings":
{
"Cluster":
{
"CRITICAL": "Ignore",
"INFO": "Ignore",
"WARNING": "Ignore"
},
"Network":
{
"CRITICAL": "Digest",
"INFO": "Digest",
"WARNING": "Digest"
}
},
"time_zone": 0
}
| Field | Type | Description |
|---|---|---|
total |
integer | Total number of notification setting entries returned. |
data |
array | List of notification setting objects for the recipient. |
data[].daily_limit |
integer | Maximum number of emails per day. |
data[].digest_hour |
integer | Hour of the day to send digest emails. |
data[].recipient |
string | The recipient email address. |
data[].time_zone |
integer | Timezone offset in hours. |
data[].settings |
object | Notification settings per component and severity. |
Response example
{
"controller_id": "7f399ff3-7484-4a93-a47a-a5c0bba42fca",
"is_superuser": true,
"request_processed": "2023-05-05T12:16:31.637Z",
"request_status": "Ok",
"total": 1,
"data":
[
{
"daily_limit": 1000,
"digest_hour": 7,
"recipient": "[email protected]",
"time_zone": 0,
"settings":
{
"Backup":
{
"CRITICAL": "Digest",
"INFO": "Digest",
"WARNING": "Digest"
},
"Cluster":
{
"CRITICAL": "Ignore",
"INFO": "Ignore",
"WARNING": "Ignore"
},
"ClusterConfiguration":
{
"CRITICAL": "Digest",
"INFO": "Digest",
"WARNING": "Digest"
},
"ClusterRecovery":
{
"CRITICAL": "Deliver",
"INFO": "Digest",
"WARNING": "Digest"
},
"CmonDatabase":
{
"CRITICAL": "Digest",
"INFO": "Digest",
"WARNING": "Digest"
},
"DbHealth":
{
"CRITICAL": "Digest",
"INFO": "Digest",
"WARNING": "Digest"
},
"DbPerformance":
{
"CRITICAL": "Digest",
"INFO": "Digest",
"WARNING": "Digest"
},
"Host":
{
"CRITICAL": "Digest",
"INFO": "Digest",
"WARNING": "Digest"
},
"Mail":
{
"CRITICAL": "Digest",
"INFO": "Digest",
"WARNING": "Digest"
},
"Network":
{
"CRITICAL": "Digest",
"INFO": "Digest",
"WARNING": "Digest"
},
"Node":
{
"CRITICAL": "Deliver",
"INFO": "Digest",
"WARNING": "Digest"
},
"SoftwareInstallation":
{
"CRITICAL": "Digest",
"INFO": "Deliver",
"WARNING": "Digest"
},
"Unknown":
{
"CRITICAL": "Digest",
"INFO": "Digest",
"WARNING": "Digest"
}
}
}
]
}
getnotificationsettings
POST /v2/config
Returns the notification settings of a specified recipient.
| Parameter | Type | Required | Description |
|---|---|---|---|
email |
string | Required | The recipient email address to retrieve settings for. |
cluster_id |
integer | Required | The ID of the cluster. |
{
"operation": "getnotificationsettings",
"email": "[email protected]",
"cluster_id": 101
}
| Field | Type | Description |
|---|---|---|
total |
integer | Total number of notification setting entries returned. |
data |
array | List of notification setting objects for the recipient. |
data[].daily_limit |
integer | Maximum number of emails per day. |
data[].digest_hour |
integer | Hour of the day to send digest emails. |
data[].recipient |
string | The recipient email address. |
data[].time_zone |
integer | Timezone offset in hours. |
data[].settings |
object | Notification settings per component and severity. |
Response example
{
"controller_id": "7f399ff3-7484-4a93-a47a-a5c0bba42fca",
"is_superuser": true,
"request_processed": "2023-05-05T12:16:31.637Z",
"request_status": "Ok",
"total": 1,
"data":
[
{
"daily_limit": 1000,
"digest_hour": 7,
"recipient": "[email protected]",
"time_zone": 0,
"settings":
{
"Backup":
{
"CRITICAL": "Digest",
"INFO": "Digest",
"WARNING": "Digest"
},
"Cluster":
{
"CRITICAL": "Ignore",
"INFO": "Ignore",
"WARNING": "Ignore"
},
"ClusterConfiguration":
{
"CRITICAL": "Digest",
"INFO": "Digest",
"WARNING": "Digest"
},
"ClusterRecovery":
{
"CRITICAL": "Deliver",
"INFO": "Digest",
"WARNING": "Digest"
},
"CmonDatabase":
{
"CRITICAL": "Digest",
"INFO": "Digest",
"WARNING": "Digest"
},
"DbHealth":
{
"CRITICAL": "Digest",
"INFO": "Digest",
"WARNING": "Digest"
},
"DbPerformance":
{
"CRITICAL": "Digest",
"INFO": "Digest",
"WARNING": "Digest"
},
"Host":
{
"CRITICAL": "Digest",
"INFO": "Digest",
"WARNING": "Digest"
},
"Mail":
{
"CRITICAL": "Digest",
"INFO": "Digest",
"WARNING": "Digest"
},
"Network":
{
"CRITICAL": "Digest",
"INFO": "Digest",
"WARNING": "Digest"
},
"Node":
{
"CRITICAL": "Deliver",
"INFO": "Digest",
"WARNING": "Digest"
},
"SoftwareInstallation":
{
"CRITICAL": "Digest",
"INFO": "Deliver",
"WARNING": "Digest"
},
"Unknown":
{
"CRITICAL": "Digest",
"INFO": "Digest",
"WARNING": "Digest"
}
}
}
]
}
removerecipient
POST /v2/config
Removes an e-mail recipient.
| Parameter | Type | Required | Description |
|---|---|---|---|
email |
string | Required | The email address of the recipient to remove. |
cluster_id |
integer | Required | The ID of the cluster. |
{
"operation": "removerecipient",
"email": "[email protected]",
"cluster_id": 101
}
Controllers and HA
The /v2/controller path is for managing controller and operate the Cmon HA subsystem.
| Operation | Description |
|---|---|
| ping | Check if a controller is reachable without locking the HA subsystem. |
| JoinRequest | Internal HA call for a follower to request joining the controller pool. |
| HeartBeat | Internal HA call exchanged between controllers to maintain cluster membership. |
| appendEntries | Internal Raft call to replicate log entries from leader to followers. |
| requestVote | Internal Raft call sent during leader election to request votes. |
ping
POST /v2/controller
This call is created so that the client application can check on a controller even when that controller is not the leader. This call should be as fast as possible and should not do any locking on the Cmon HA subsystem.
| Field | Type | Description |
|---|---|---|
cmon_ha_supported |
boolean | Whether Cmon HA is supported on this controller. |
controller_status |
string | Current status of the controller (e.g. CmonControllerLeader). |
term |
integer | Current Raft term number. |
prev_log_index |
integer | Index of the last log entry. |
prev_log_term |
integer | Term of the last log entry. |
JoinRequest
POST /v2/controller
An internal HA call used by a follower controller to request joining the controller pool managed by the leader. This is part of the CMON HA protocol and is not intended for direct use by external clients.
HeartBeat
POST /v2/controller
An internal HA call exchanged between controllers to maintain cluster membership and detect node failures. The payload includes the current leader, committed log index, and known controller membership. This is part of the CMON HA protocol and is not intended for direct use by external clients.
{
"client_ip_address": "192.168.0.127",
"controller_key": "6a03558f-5d7a-41ed-9af1-9e0ff162bcb8",
"failed_controllers":
{
},
"follower_controllers":
{
"192.168.0.127:10001":
{
"class_name": "CmonControllerHost",
"hostname": "192.168.0.127",
"ip": "192.168.0.127",
"port": 10001
},
"192.168.0.127:20001":
{
"class_name": "CmonControllerHost",
"hostname": "192.168.0.127",
"ip": "192.168.0.127",
"port": 20001
}
},
"committed_index": 6,
"leader_controller":
{
"class_name": "CmonControllerHost",
"hostname": "192.168.0.127",
"ip": "192.168.0.127",
"port": 9556
},
"operation": "heartBeat",
"request_created": "2019-03-19T09:43:58.444Z",
"term": 0
}
| Field | Type | Description |
|---|---|---|
cmon_ha_supported |
boolean | Whether Cmon HA is supported on this controller. |
pid |
integer | Process ID of the Cmon controller. |
wallclock |
integer | Unix timestamp when the response was generated. |
appendEntries
POST /v2/controller
An internal Raft consensus call used to replicate log entries from the leader controller to its followers. Each entry carries a payload instruction — such as saving a configuration file — that the follower applies locally. This is part of the CMON HA replication protocol and is not intended for direct use by external clients.
{
"client_ip_address": "192.168.0.127",
"controller_key": "6a03558f-5d7a-41ed-9af1-9e0ff162bcb8",
"log_entry":
{
"class_name": "CmonHaLogEntry",
"comment": "",
"committed": false,
"executed": false,
"index": 11,
"prev_log_index": 10,
"prev_log_term": 0,
"payload":
{
"files": [
{
"class_name": "CmonFile",
"content": "basedir=/usr\ncdt_path=/\ncluster_id=1\ncmon_db=ft_install_testdb\ncmon_user=root\ncreated_by_job=1\ndb_schema_stats_collection_interval=10800\nenable_is_queries=1\nenable_query_monitor=1\ngalera_version=3.x\ngroup_owner=1\nhostname=192.168.0.127\nlogfile=/tmp/cmon_1.log\nmode=controller\nmonitored_mountpoints=/var/lib/mysql/\nmonitored_mysql_port=3306\nmonitored_mysql_root_password='password'\nmysql_bindir=/usr/bin/\nmysql_hostname=127.0.0.1\nmysql_password='p'\nmysql_port=3306\nmysql_server_addresses=192.168.0.232:3306\nmysql_version=5.6\nname='ft_cmonhabasic_41388'\nos=debian\nowner=1\npidfile=/var/run\nquery_monitor_use_local_settings=false\nssh_identity=\nssh_port=22\nssh_user=pipas\nsudo_opts=sudo -n 2>/dev/null\ntype=galera\nvendor=percona\n",
"full_path": "/tmp/cmon_1.cnf"
} ],
"instruction": "SaveLocalFile"
},
"term": 0
},
"operation": "appendEntries",
"request_created": "2019-03-19T09:48:32.864Z"
}
requestVote
POST /v2/controller
An internal Raft consensus call sent during leader election. A candidate controller sends this to request votes from the other controllers in the pool. This is part of the CMON HA protocol and is not intended for direct use by external clients.
Discovery
The /v2/discovery path provides calls for collecting real-time data about nodes and discovering cluster resources.
| Operation | Description |
|---|---|
| checkClusterName | Check whether a cluster name is acceptable for use when creating a new cluster. |
| getSupportedClusterTypes | Get metadata about all cluster types supported by the controller. |
| getSshCredentials | Get the SSH credentials the controller uses to authenticate on nodes of an existing cluster. |
| checkHosts | Run connectivity and hardware tests against a list of hosts. |
checkClusterName
POST /v2/discovery
This call can be used to check if a specific cluster name is acceptable to be used to create a new cluster.
| Parameter | Type | Required | Description |
|---|---|---|---|
new_cluster_name |
string | Required | The new cluster name the user plans to use to name a new cluster. |
| Field | Type | Description |
|---|---|---|
is_acceptable |
boolean | Shows if the cluster name is acceptable as a name for a new cluster. If the name is not valid for this purpose (e.g. the name already used for some other cluster) this value will be false. |
message |
string | Shows why the name is not acceptable. This string is human readable, it can be shown to the user. |
request_status |
string | Please note that the request status will be "Ok" even if the reply is negative, when the new name is not acceptable. This field shows if the request is processed, it is not the reply. |
getSupportedClusterTypes
POST /v2/discovery
The getSupportedClusterTypes returns some metadata about the cluster types supported by the controller. This is a very important call, using it the GUI can fill up comboboxes, lists and can make sure that the cluster creation will not fail because the user requested some invalid combination. It is also worth mentioning that if the UI uses this call the UI source doesn't need to be changed when we start supporting a new version or vendor.
Here is how the call look like:
And here is the reply. Please note that this call is under construction, we might add new fields if we find some other important information.
Response example
{
"cluster_type_names": [ "galera", "replication", "groupreplication", "myqlcluster", "postgresql", "mongodb" ],
"cluster_type_properties":
{
"galera":
{
"intro_url": "http://galeracluster.com/products/",
"long_name": "Galera Cluster for MySQL",
"short_name": "Galera",
"type_name": "galera",
"vendors": [
{
"name": "mariadb",
"versions": [ "5.5", "10.1", "10.2" ]
},
{
"name": "codership",
"versions": [ "5.5", "5.6" ]
},
{
"name": "percona",
"versions": [ "5.5", "5.6", "5.7" ]
} ]
},
"groupreplication":
{
"intro_url": "http://mysqlhighavailability.com/gr/doc/index.html",
"long_name": "MySQL Group Replication",
"short_name": "Group Replication",
"type_name": "groupreplication",
"vendors": [
{
"name": "oracle",
"versions": [ "5.7" ]
} ]
},
"mongodb":
{
"intro_url": "https://www.mongodb.com/what-is-mongodb",
"long_name": "MongoDB Cluster",
"short_name": "MongoDB",
"type_name": "mongodb",
"vendors": [
{
"name": "10gen",
"versions": [ "3.2", "3.4" ]
},
{
"name": "percona",
"versions": [ "3.2" ]
} ]
},
"myqlcluster":
{
"long_name": "MySQL NDB Cluster",
"nick_name": "ndb",
"short_name": "NDB Cluster",
"type_name": "myqlcluster",
"vendors": [
{
"name": "oracle",
"versions": [ "7.4" ]
} ]
},
"postgresql":
{
"intro_url": "https://www.postgresql.org/about/",
"long_name": "PostgreSQL Cluster",
"short_name": "PostgreSQL",
"type_name": "postgresql",
"vendors": [
{
"name": "postgresql",
"versions": [ "9.4", "9.5", "9.6", "10" ]
} ]
},
"replication":
{
"long_name": "MySQL Replication",
"nick_name": "mysqlreplication",
"short_name": "Replication",
"type_name": "replication",
"vendors": [
{
"name": "mariadb",
"versions": [ "5.5", "10.1", "10.2" ]
},
{
"name": "codership",
"versions": [ "5.5", "5.6" ]
},
{
"name": "percona",
"versions": [ "5.5", "5.6", "5.7" ]
} ]
}
},
"request_created": "2017-08-15T08:37:30.150Z",
"request_id": 3,
"request_processed": "2017-08-15T08:37:30.200Z",
"request_status": "Ok",
"request_user_id": 3,
"total": 6
}
getSshCredentials
POST /v2/discovery
Using the getSshCredentials the caller can get the SSH credentials used when the controller authenticates on the nodes of the cluster. This cluster is made for the UI that creates a new cluster: here the user can check and re-use the SSH credentials used on some existing cluster.
The privilege check provides access if the authenticated user is either the system user or the owner of the existing cluster. No ACLs are implemented and other than the owner can't access the sensitive information of the existing clusters.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Optional | The numerical ID of the cluster to read. The cluster name also can be used to identify the cluster. |
cluster_name |
string | Optional | The name of the cluster to read. The cluster ID can also be used to identify the cluster. |
| Field | Type | Description |
|---|---|---|
cluster_id |
integer | The numerical ID of the cluster is always sent back even if the cluster was identified by its name in the request. |
ssh_credentials |
object | The credentials used to authenticate on the nodes of the cluster. |
Response example
{
"cluster_id": 1,
"request_created": "2017-08-14T08:25:20.298Z",
"request_id": 3,
"request_processed": "2017-08-14T08:25:20.344Z",
"request_status": "Ok",
"request_user_id": 3,
"ssh_credentials":
{
"class_name": "CmonSshCredentials",
"password": "",
"port": 22,
"ssh_keyfile": "./configs/testing_id_rsa",
"timeout": 30,
"tty_for_sudo": true,
"user_name": "pipas"
}
}
checkHosts
POST /v2/discovery
The checkHosts request performs a set of tests on the given hosts and returns various hardware information about the hosts themselves. The call can specify what kind of tests it needs at the given stage, e.g. if the user already provided an ssh password the access to the host through SSH can be checked.
Here is how these checks can be performed using the s9s command line tool:
s9s cluster --check-hosts --nodes="192.168.1.113" --cluster-type=galera --provider-version=5.7 --vendor=codership
| Parameter | Type | Required | Description |
|---|---|---|---|
check_if_already_registered |
boolean | Optional | If true the controller will check if the hosts are already registered for other clusters. If the port is set the code will check if the same host with the same name is already registered in some other cluster. The same port on the same host can't be used twice and the test will check this. If the class_name is set the backend will perform another check — we do not support running two instances of the same daemon on one single host. Supported class names: CmonHost (generic host), CmonMySqlHost, CmonPostgreSqlHost, CmonProxySqlHost, CmonHaProxyHost. |
check_ssh_sudo |
boolean | Optional | This check will see that the host is actually accessible through ssh as superuser. For this test either the SSH credentials or an existing cluster must be specified. |
check_job |
boolean | Optional | When this property is true the caller can send a "job" field with the "create_cluster" job for a preliminary check. The job will not be executed, but some checks will be performed to see if the job with the passed properties is valid. |
cluster_id |
integer | Optional | The cluster can be specified through the numerical ID of the cluster. If the cluster is specified the SSH credentials can be accessed from the cluster configuration, so the user don't need to enter those. |
cluster_name |
string | Optional | Same as cluster_id, but here the cluster can be referenced by the cluster name. |
ssh_credentials |
object | Optional | Fields providing SSH access to the nodes. The SSH credentials can come from the existing cluster and from this field, but this field has precedence. |
Here is an example of the request:
{
"check_if_already_registered": true,
"nodes": [
{
"class_name": "CmonHost",
"hostname": "192.168.1.212",
"port": 8089
} ],
"operation": "checkHosts",
"request_created": "2017-08-11T12:32:58.547Z",
"request_id": 3
}
Here is another request that is slightly different. Note that this request will not check if the host is already registered simply because the "check_if_already_registered" field is not set to true. This request does not identify an existing cluster either, it contains the "ssh_credentials" field so that the controller can gain access to the nodes. Should the cluster be also referenced the "ssh_credentials" have priority over the credentials found in an existing cluster.
{
"check_ssh_sudo": true,
"nodes": [
{
"class_name": "CmonHost",
"hostname": "192.168.1.113",
"port": 8089
} ],
"operation": "checkHosts",
"request_created": "2017-08-14T10:48:50.978Z",
"request_id": 4,
"ssh_credentials":
{
"class_name": "CmonSshCredentials",
"password": "",
"ssh_keyfile": "./configs/testing_id_rsa",
"user_name": "pipas"
}
}
And here is a call that will also check the passed "create_cluster" job:
{
"check_if_already_registered": true,
"check_job": true,
"check_ssh_sudo": true,
"job":
{
"class_name": "CmonJobInstance",
"job_spec":
{
"command": "create_cluster",
"job_data":
{
"cluster_type": "group_replication",
"mysql_version": "",
"nodes": [
{
"class_name": "CmonHost",
"hostname": "192.168.1.113"
} ],
"vendor": ""
}
}
},
"nodes": [
{
"class_name": "CmonHost",
"hostname": "192.168.1.113"
} ],
"operation": "checkHosts",
"request_created": "2017-10-10T07:55:59.653Z",
"request_id": 3
}
| Field | Type | Description |
|---|---|---|
checked_hosts |
array | The detailed list with the hosts checked. Every host has the status showing what was the result of the check on that particular host. |
total |
integer | The total number of hosts checked. |
total_failed |
integer | The number of hosts that failed the checks. This can be used as a quick check, but the details of the failure is in the reply too. |
The error_code field of the status can be one of the following strings:
HostFoundInOtherCluster: The host is already part of some other cluster.SshConnectionFailed: The SSH connection failed.SshAuthenticationFailed: The SSH connected, but the authentication failed.SudoFailed: Failed to gain root access.InvalidRequest: The request is invalid, check could not be performed.JobWouldFail: The job would fail if it is sent seriously.HostIsOk: The host passed all tests.
When the check_ssh_sudo test is performed the reply shows some information about the hosts checked. Please note that these tests are under development, later more information might be added.
The response fields hardware/cpu, hardware/memory, hardware/mounted_partitions, hardware/network_interfaces, software/firewall, and software/os_version provide hardware and software details about the checked hosts.
hardware/cpu: Some information about the CPU(s) found in the host. This can be shown to the user to help recognize the hardware. A total can also be calculated for the cluster so that the user can see what resources the cluster will have.hardware/memory: Information about the memory configuration.hardware/mounted_partitions: Very important piece of information that shows the available storage capacity.hardware/network_interfaces: This actually could show more, like we could show the type of connection.software/firewall: Shows what firewall software is installed.software/os_version: The distribution and its version.
Well, it is clear, we need to send more info, but the basics are there. Takes a lot of work add new things here.
Response example (simple)
{
"checked_hosts": [
{
"host":
{
"class_name": "CmonHost",
"hostname": "192.168.1.112",
"port": 8089
},
"status":
{
"error_code": "HostIsOk"
}
} ],
"request_created": "2017-08-11T13:49:10.052Z",
"request_id": 3,
"request_processed": "2017-08-11T13:49:10.097Z",
"request_status": "Ok",
"request_user_id": 3,
"total": 1,
"total_failed": 0
}
Response example (with hardware/software details)
{
"checked_hosts": [
{
"hardware":
{
"cpu":
{
"class_name": "CmonCpuSet",
"cpus": [
{
"cores": 4,
"cpu_max_ghz": 2.268,
"id": 0,
"model": "Intel(R) Xeon(R) CPU L5520 @ 2.27GHz",
"siblings": 8,
"vendor": "GenuineIntel"
},
{
"cores": 4,
"cpu_max_ghz": 2.268,
"id": 1,
"model": "Intel(R) Xeon(R) CPU L5520 @ 2.27GHz",
"siblings": 8,
"vendor": "GenuineIntel"
} ],
"total_cores": 8,
"total_cpus": 2,
"total_siblings": 16
},
"memory":
{
"class_name": "CmonMemoryInfo",
"memory_available_mb": 16085,
"memory_free_mb": 16085,
"memory_total_mb": 16384,
"swap_free_mb": 0,
"swap_total_mb": 0
},
"mounted_partitions": [
{
"device": "/dev/mapper/core1--vg-root",
"filesystem": "ext4",
"free_gb": 142.631,
"free_mb": 146053,
"mountpoint": "/",
"total_gb": 162.286,
"total_mb": 166180
} ],
"network_interfaces":
{
"eth0": "192.168.1.113"
}
},
"host":
{
"class_name": "CmonHost",
"hostname": "192.168.1.113",
"port": 8089
},
"software":
{
"firewall":
{
"firewalld_installed": false,
"ip_tables_installed": false,
"iptables_installed": false,
"ufw_installed": false
},
"os_version":
{
"class_name": "CmonOsVersion",
"codename": "xenial",
"name": "ubuntu",
"release": "16.04",
"type": "debian"
},
"security":
{
"apparmor_installed": false,
"selinux_installed": false,
"sudo_installed": true
}
},
"status":
{
"error_code": "HostIsOk"
}
} ],
"request_created": "2017-08-16T10:21:19.122Z",
"request_id": 4,
"request_processed": "2017-08-16T10:21:20.571Z",
"request_status": "Ok",
"request_user_id": 3,
"total": 1,
"total_failed": 0
}
Hosts and Containers
The /v2/host path provides calls for managing hosts and containers monitored by the controller.
| Operation | Description |
|---|---|
| startServers | Start (boot) one or more servers. |
| shutDownServers | Shut down one or more servers. |
| registerServers | Register servers with the controller so they can be monitored. |
| unregisterHost | Unregister a single host from the controller. |
| unregisterServers | Unregister multiple servers from the controller. |
| getContainers | Get information about containers managed by the controller. |
| getServers | Get information about servers monitored by the controller. |
startServers
POST /v2/host
This call is for starting up (or booting) servers.
| Parameter | Type | Required | Description |
|---|---|---|---|
servers |
array | Required | A list of server objects to start. Each object should include class_name and hostname. |
shutDownServers
POST /v2/host
Shuts down (powers off) one or more container servers. The servers must be registered with the controller. This is the counterpart to startServers.
registerServers
POST /v2/host
This call can be used to register a container server in the Cmon Controller. This is the fast way, but there is a job called "create_server" that does a very similar registration. The job will actually install software, this call just registers an existing server.
Here is how a request will be sent:
| Parameter | Type | Required | Description |
|---|---|---|---|
servers |
array | Required | A list of server objects to register. Each object should include class_name, cdt_path, and hostname. |
Here is a reply that shows the server was registered, but the server is actually turned off:
| Field | Type | Description |
|---|---|---|
servers |
array | A list of registered server objects with their current state. |
Response example
{
"reply_received": "2017-10-16T11:33:24.501Z",
"request_created": "2017-10-16T11:33:24.496Z",
"request_id": 3,
"request_processed": "2017-10-16T11:33:27.606Z",
"request_status": "Ok",
"request_user_id": 3,
"servers": [
{
"cdt_path": "/",
"class_name": "CmonContainerServer",
"clusterid": 0,
"connected": false,
"hostId": 6,
"hostname": "storage01",
"hoststatus": "CmonHostOffLine",
"ip": "192.168.1.17",
"maintenance_mode_active": false,
"message": "SSH connection failed.",
"owner_group_id": 2,
"owner_group_name": "users",
"owner_user_id": 3,
"owner_user_name": "pipas",
"protocol": "lxc",
"timestamp": 1508153607,
"unique_id": 6
} ]
}
unregisterHost
POST /v2/host
This call will drop the given host from our database entirely. The computer the host represents will not be touched in any way, software will not be uninstalled, service will not be stopped, nada!
So there are multiple fields to identify the host, there is teh hostname, the port, the cluster ID, maybe the cluster name. The backend will use whatever it is provided and find the host. If multiple hosts are found with the given data the request will be rejected.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Optional | The numerical ID of the cluster that will execute the job. The cluster can also be referenced using the cluster name. For RPC v2 identifying the cluster is not mandatory, but it can be usefull if the same host is part of multiple clusters. |
cluster_name |
string | Optional | The name of the cluster that will execute the job. The cluster can also be referenced using the cluster ID. For RPC v2 identifying the cluster is not mandatory, but it can be usefull if the same host is part of multiple clusters. |
dry_run |
boolean | Optional | If this field is provided (with any value at all) the host will not be really unregistered. All the checks will be done, a success will be reported back, only the error message will show that this was just a drill. |
host |
object | Required | The host that shall be unregistered. |
host.class_name |
string | Optional | The class name of the host will not be strictly checked (because the client might not know this), just send "CmonHost" that'll do. |
host.hostname |
string | Required | This is mandatory to identify the host. |
host.port |
integer | Optional | The port of the host. RPC v2 allows the usage of hosts without a port, but for most cases the port will be required. |
unregisterServers
POST /v2/host
This call is for dropping a container server from the scope of the controller. The server will not seize to exist, but the controller will forget everything about it.
| Parameter | Type | Required | Description |
|---|---|---|---|
servers |
array | Required | A list of CmonContainerServer class objects to unregister. In the objects only the class name and the host name has to be provided. |
getContainers
POST /v2/host
Returns the list of containers known by the controller. The RPC v2 call also checks the rights of the authenticated user, if the user has no right to read the container object it will not appear in the list.
| Field | Type | Description |
|---|---|---|
containers |
array | A list of #CmonContainer objects. The following command can be used to print the properties of this class: s9s metatype --list-properties --type=CmonContainer --long |
total |
integer | The total number of containers known by the controller. |
Response example
{
"containers": [
{
"alias": "debian",
"class_name": "CmonContainer",
"hostname": "debian",
"owner_group_id": 4,
"owner_group_name": "testgroup",
"owner_user_id": 3,
"owner_user_name": "pipas",
"parent_server": "storage01",
"status": "STOPPED",
"type": "lxc"
},
. . .
{
"alias": "vnc_server",
"class_name": "CmonContainer",
"hostname": "192.168.1.210",
"ip": "192.168.1.210",
"ipv4_addresses": [ "192.168.1.210" ],
"owner_group_id": 4,
"owner_group_name": "testgroup",
"owner_user_id": 3,
"owner_user_name": "pipas",
"parent_server": "storage01",
"status": "RUNNING",
"template": "ubuntu",
"type": "lxc"
} ],
"request_created": "2017-09-07T05:09:16.895Z",
"request_id": 3,
"request_processed": "2017-09-07T05:09:16.947Z",
"request_status": "Ok",
"request_user_id": 3,
"total": 5
}
getServers
POST /v2/host
Returns the container servers and their properties.
And here is the reply. It is rather complex, but we have a lot of data.
| Field | Type | Description |
|---|---|---|
servers |
array | A list of container server objects with detailed properties including containers, disk devices, distribution info, memory, network interfaces, and processors. |
total |
integer | The total number of servers. |
Response example
{
"request_created": "2017-10-03T08:19:58.769Z",
"request_id": 3,
"request_processed": "2017-10-03T08:19:58.824Z",
"request_status": "Ok",
"request_user_id": 3,
"servers": [
{
"cdt_path": "/",
"class_name": "CmonContainerServer",
"clusterid": 0,
"connected": false,
"containers": [
{
"acl": "user::rwx,user:nobody:r--,group::rw-,other::---",
"alias": "bestw_controller",
"cdt_path": "/core1/containers",
"class_name": "CmonContainer",
"container_id": 1,
"hostname": "192.168.1.182",
"ip": "192.168.1.182",
"ipv4_addresses": [ "192.168.1.182" ],
"owner_group_id": 2,
"owner_group_name": "users",
"owner_user_id": 3,
"owner_user_name": "pipas",
"parent_server": "core1",
"status": "RUNNING",
"type": "lxc",
"version": 25
},
. . .
{
"acl": "user::rwx,group::rw-,other::---",
"alias": "ubuntu",
"cdt_path": "/core1/containers",
"class_name": "CmonContainer",
"container_id": 5,
"hostname": "ubuntu",
"owner_group_id": 2,
"owner_group_name": "users",
"owner_user_id": 3,
"owner_user_name": "pipas",
"parent_server": "core1",
"status": "STOPPED",
"type": "lxc",
"version": 25
} ],
"disk_devices": [
{
"class_name": "CmonDiskDevice",
"device": "/dev/mapper/core1--vg-root",
"filesystem": "ext4",
"free_mb": 141617,
"mountpoint": "/",
"total_mb": 166180
},
. . .
{
"device": "/dev/sdc",
"is_hardware_storage": false,
"model": "LSILOGIC Logical Volume",
"total_mb": 170230,
"volumes": [
{
"description": "Linux filesystem partition",
"device": "/dev/sdc1",
"filesystem": "ext2",
"free_mb": 295,
"mount_point": "/boot",
"total_mb": 487
},
{
"description": "Extended partition",
"device": "/dev/sdc2",
"filesystem": "",
"mount_point": "",
"total_mb": 169741,
"volumes": [
{
"description": "Linux LVM Physical Volume partition",
"device": "/dev/sdc5",
"filesystem": "",
"mount_point": "",
"total_mb": 169741
} ]
} ]
},
. . .
{
"device": "/dev/sda",
"is_hardware_storage": false,
"model": "SCSI Disk",
"total_mb": 15272.1,
"volumes": [
{
"description": "EXT4 volume",
"device": "/dev/sda1",
"filesystem": "ext4",
"mount_point": "",
"total_mb": 15271.1
} ]
} ],
"distribution":
{
"codename": "xenial",
"name": "ubuntu",
"release": "16.04",
"type": "debian"
},
"hostId": 1,
"hostname": "core1",
"hoststatus": "CmonHostOffLine",
"ip": "192.168.1.4",
"last_container_collect": 1506791691,
"last_hw_collect": 1507017024,
"lastseen": 1506791691,
"maintenance_mode_active": false,
"memory":
{
"banks": [
{
"bank": "0",
"name": "DIMM 800 MHz (1.2 ns)",
"size": 4294967296
},
. . .
{
"bank": "7",
"name": "DIMM 800 MHz (1.2 ns)",
"size": 4294967296
} ],
"class_name": "CmonMemoryInfo",
"memory_available_mb": 54091,
"memory_free_mb": 41919,
"memory_total_mb": 64421,
"swap_free_mb": 0,
"swap_total_mb": 0
},
"message": "SSH connection failed.",
"model": "SUN FIRE X4170 SERVER (4583256-1)",
"network_interfaces": [
{
"gbits": 1,
"link": true,
"mac": "00:21:28:76:06:2a",
"model": "82575EB Gigabit Network Connection",
"name": "enp1s0f0"
},
. . .
{
"gbits": 0,
"ip": "192.168.122.1",
"mac": "",
"model": "",
"name": "virbr0"
} ],
"owner_group_id": 2,
"owner_group_name": "users",
"owner_user_id": 3,
"owner_user_name": "pipas",
"processors": [
{
"cores": 4,
"cpu_max_ghz": 1.6,
"id": 5,
"model": "Intel(R) Xeon(R) CPU L5520 @ 2.27GHz",
"siblings": 8,
"vendor": "Intel Corp."
},
{
"cores": 4,
"cpu_max_ghz": 1.6,
"id": 9,
"model": "Intel(R) Xeon(R) CPU L5520 @ 2.27GHz",
"siblings": 8,
"vendor": "Intel Corp."
} ],
"timestamp": 1507017024,
"unique_id": 1,
"version": "2.17"
},
. . .
],
"total": 8
}
Job Information and Manipulation
Creating and manipulating jobs, reading information about jobs is available on the /v2/jobs path.
| Operation | Description |
|---|---|
| createJobInstance | Create and start a new job instance on the controller |
| updateJobInstance | Update an existing non-closed job instance |
| deleteJobInstance | Delete a closed job instance record from the controller |
| killJobInstance | Send a signal to abort a running job |
| cloneJobInstance | Clone an existing job instance to re-execute it |
| getJobInstance | Get information about a single job instance |
| getJobInstances | Get a list of job instances from the controller |
| getJobLog | Read job status and messages from the controller |
createJobInstance
POST /v2/jobs
Arguably the most important call of the whole RPC 2.0 is the "createJobInstance" call where new jobs can be started. Jobs are very powerfull and complex and so this RPC call is very important and very often used.
The request contains a job description that will be created as a new job and then the new job will be described in detail returned in the reply. This way the caller immediately know what properties the controller added to the new job.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Optional | The numerical ID of the cluster that will execute the job. The cluster can also be referenced using the cluster name. |
cluster_name |
string | Optional | The name of the cluster that will execute the job. The cluster can also be referenced using the cluster ID. |
job |
object | Required | The job that will be created. Here the caller can set various properties while other properties will be set by the controller automatically. The most important properties the caller can send are the following: class_name (should always be "CmonJobInstance"), job_spec (specifies what the job will do), recurrence (a crontab string for recurring jobs), scheduled (a date/time for deferred execution), title (human readable title). |
To get a comprehensive list of the properties the controller supports one can run the following command (or check the jobclasses page):
{
"cluster_id": 1,
"job":
{
"class_name": "CmonJobInstance",
"job_spec":
{
"command": "rolling_restart"
},
"title": "Rolling Restart",
},
"operation": "createJobInstance",
"request_created": "2017-06-22T12:46:05.054Z",
"request_id": 3
}
Here is an example that registers a recurring job:
{
"cluster_id": 1,
"job":
{
"class_name": "CmonJobInstance",
"job_spec":
{
"command": "success",
"job_data":
{
}
},
"recurrence": "2 * * * *",
"tags": [ "testRecurringJob" ],
"title": "Simulated Success"
},
"operation": "createJobInstance",
"request_created": "2019-11-06T06:16:23.859Z",
"request_id": 3
}
| Field | Type | Description |
|---|---|---|
job |
object | The newly created job instance with all properties set by the controller. |
Response example
{
"job":
{
"can_be_aborted": false,
"can_be_deleted": true,
"class_name": "CmonJobInstance",
"cluster_id": 1,
"created": "2017-06-22T12:46:05.000Z",
"exit_code": 0,
"group_id": 2,
"group_name": "users",
"job_id": 2,
"job_spec":
{
"command": "rolling_restart"
},
"status": "DEFINED",
"status_text": "Waiting",
"title": "Rolling Restart",
"user_id": 3,
"user_name": "pipas"
},
"request_created": "2017-06-22T12:46:05.054Z",
"request_id": 3,
"request_processed": "2017-06-22T12:46:05.105Z",
"request_status": "Ok",
"request_user_id": 3
}
updateJobInstance
POST /v2/jobs
An RPC 2.0 method call to update an existing (non-closed) job instance.
The request contains the updated job description and status then the updated job will be described in detail returned in the reply. This way the caller immediately know what properties the controller has updated added to the existing job.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Optional | The numerical ID of the cluster that will execute the job. The cluster can also be referenced using the cluster name. |
cluster_name |
string | Optional | The name of the cluster that will execute the job. The cluster can also be referenced using the cluster ID. |
job |
object | Required | The job that will be updated. The most important properties the caller can send are the following: class_name (should always be "CmonJobInstance"), job_spec (specifies what the job will do), status (a new job status, e.g. PAUSED or SCHEDULED), recurrence (a crontab string for recurring jobs), scheduled (a date/time for deferred execution), title (human readable title). |
To get a comprehensive list of the properties the controller supports one can run the following command (or check the jobclasses page):
| Field | Type | Description |
|---|---|---|
job |
object | The updated job instance with all properties as set by the controller. |
Response example
{
"job":
{
"can_be_aborted": false,
"can_be_deleted": true,
"class_name": "CmonJobInstance",
"cluster_id": 1,
"created": "2020-05-05T12:46:05.000Z",
"exit_code": 0,
"group_id": 2,
"group_name": "users",
"job_id": 2,
"job_spec":
{
"command": "rolling_restart"
},
"status": "DEFINED",
"status_text": "Waiting",
"title": "Rolling Restart",
"user_id": 3,
"user_name": "pipas"
},
"request_created": "2020-05-05T12:46:05.054Z",
"request_id": 3,
"request_processed": "2020-05-05T12:46:05.105Z",
"request_status": "Ok",
"request_user_id": 3
}
deleteJobInstance
POST /v2/jobs
Deletes an existing job instance record from the controller. Only closed jobs — those with a status of FINISHED, FAILED, or ABORTED — can be deleted. Use killJobInstance to abort a running job before deleting it.
| Parameter | Type | Required | Description |
|---|---|---|---|
job_id |
integer | Required | The numerical ID of the job instance to delete. |
killJobInstance
POST /v2/jobs
This call was made for killing/aborting jobs running on the controller. To be more precise killing a Cmon job works like killing a UNIX process (it is not a real UNIX process though): we deliver a signal, the job code recognizes the job signal and aborts itself. In short we could say this is not preemptive, jobs that don't want to be aborted will not be aborted.
Here is a request to abort a job:
| Parameter | Type | Required | Description |
|---|---|---|---|
job_id |
integer | Required | The numerical ID of the job that should receive the signal. |
signal |
integer | Required | The signal itself as a single integer number. In the current implementation there is very little difference between the various signals, it is a good practice to send 15 now. |
The reply is just a notification about the signal being delivered. The job will be aborted later (if the job supports aborting at all).
cloneJobInstance
POST /v2/jobs
This call will clone (copy) an existing job instance in order to execute it again. All the properties are going to be inherited from the existing job and the newly created copy will be executed the same way new jobs are always executed.
| Parameter | Type | Required | Description |
|---|---|---|---|
job_id |
integer | Required | The ID of the job that will be cloned. The original job. |
cluster_id |
integer | Optional | If this field is provided the job will be executed by this cluster. If this field is not provided the job will be executed by the same cluster that executed the original job. |
getJobInstance
POST /v2/jobs
This call is very similar to the "getJobInstances" call, but this one returns information about one job.
| Parameter | Type | Required | Description |
|---|---|---|---|
job_id |
integer | Required | The numerical ID of the job that should be returned. |
| Field | Type | Description |
|---|---|---|
job |
object | The job instance itself. |
Response example
{
"job":
{
"can_be_aborted": false,
"can_be_deleted": false,
"class_name": "CmonJobInstance",
"cluster_id": 0,
"created": "2017-06-23T08:29:19.000Z",
"exit_code": 0,
"group_id": 2,
"group_name": "users",
"has_progress": true,
"job_id": 1,
"job_spec":
{
"command": "create_cluster",
"job_data":
{
"cluster_name": "ft_postgresql_63712",
"cluster_type": "postgresql_single",
"enable_uninstall": true,
"hostname": "192.168.1.192",
"port": 8089,
"postgre_password": "passwd12",
"postgre_user": "postmaster",
"ssh_user": "pipas",
"type": "postgresql"
}
},
"progress_percent": 20,
"started": "2017-06-23T08:29:19.000Z",
"status": "RUNNING",
"status_text": "Installing software",
"title": "Setup PostgreSQL Server",
"user_id": 3,
"user_name": "pipas"
},
"request_created": "2017-06-23T08:31:23.490Z",
"request_id": 3,
"request_processed": "2017-06-23T08:31:23.537Z",
"request_status": "Ok",
"request_user_id": 3
}
getJobInstances
POST /v2/jobs
This call can be used to get the job instances from the controller.
If no cluster_id, cluster_ids or cluster_name is sent the controller will send the list of jobs of all the clusters (considering the limit and offset filters of course). The access rights of the authenticated user should also filter the records sent back, but that is unfortunately not yet implemented.
| Parameter | Type | Required | Description |
|---|---|---|---|
ascending |
boolean | Optional | Normally the records will be sent in descending order of time, the newest first. If this boolean is true the order will be descending. |
cluster_id |
integer | Optional | The ID of the cluster from which the jobs will be received. The cluster name can also be used to identify the cluster, but neither of them are mandatory. It is possible to receive a mixed job list with multiple clusters. |
cluster_ids |
array | Optional | A list of integers, the IDs of the clusters from which we will get the jobs. No cluster ID or cluster name is mandatory, this call works without any identification of the clusters. |
cluster_name |
string | Optional | The name of the cluster from which the job list will be received. The cluster ID can also be used to identify the cluster, but neither of them are mandatory. |
show_defined |
boolean | Optional | Turn on state filtering and add jobs in defined state. |
show_running |
boolean | Optional | Turn on state filtering and add jobs that are running. |
show_scheduled |
boolean | Optional | Turn on state filtering and add jobs that are scheduled. |
show_aborted |
boolean | Optional | Turn on state filtering and add jobs that are aborted. |
show_finished |
boolean | Optional | Turn on state filtering and add jobs that are finished. |
show_failed |
boolean | Optional | Turn on state filtering and add jobs that are failed. |
tags |
array | Optional | A list of short strings (tags) to filter the job list. If the list is empty no tags will be considered. |
limit |
integer | Optional | Limits the number of records the same way the SQL LIMIT statement does. |
offset |
integer | Optional | The offset of the first record returned. This works the same way the SQL OFFSET statement works. |
| Field | Type | Description |
|---|---|---|
jobs |
array | The list of job instances found. The elements in the list are CmonJobInstance class objects. To get a comprehensive list of the properties the controller supports in the CmonJobInstance class please run: s9s metatype --list-properties --type=CmonJobInstance --long (or check the jobclasses page). |
total |
integer | The total number of records found in the database. The caller can implement a pager using this "total", the "limit" and the "offset" properties. |
Response example
{
"jobs": [
{
"can_be_aborted": false,
"can_be_deleted": true,
"class_name": "CmonJobInstance",
"cluster_id": 1,
"created": "2017-06-23T01:00:00.000Z",
"ended": "2017-06-23T01:00:00.000Z",
"exit_code": 0,
"group_id": 1,
"group_name": "admins",
"ip_address": "127.0.0.1",
"job_id": 2,
"job_spec": "Removing Old Backups",
"started": "2017-06-23T01:00:00.000Z",
"status": "FINISHED",
"status_text": "Command ok",
"title": "Removing Old Backups",
"user_id": 0,
"user_name": "system"
},
{
"can_be_aborted": false,
"can_be_deleted": true,
"class_name": "CmonJobInstance",
"cluster_id": 0,
"created": "2017-06-22T12:56:33.000Z",
"ended": "2017-06-22T12:58:18.000Z",
"exit_code": 0,
"group_id": 2,
"group_name": "users",
"has_progress": true,
"job_id": 1,
"job_spec":
{
"command": "create_cluster",
"job_data":
{
"cluster_name": "ft_postgresql_4357",
"cluster_type": "postgresql_single",
"enable_uninstall": true,
"hostname": "192.168.1.191",
"port": 8089,
"postgre_password": "passwd12",
"postgre_user": "postmaster",
"ssh_user": "pipas",
"type": "postgresql"
}
},
"progress_percent": 100,
"started": "2017-06-22T12:56:33.000Z",
"status": "FINISHED",
"status_text": "Job finished.",
"title": "Setup PostgreSQL Server",
"user_id": 3,
"user_name": "pipas"
} ],
"request_created": "2017-06-23T05:25:17.891Z",
"request_id": 3,
"request_processed": "2017-06-23T05:25:17.939Z",
"request_status": "Ok",
"request_user_id": 3,
"total": 2
}
getJobLog
POST /v2/jobs
This RPC call is for reading the job status and job messages from the controller. The reply will have the job and the job message in it, so the caller can show the job together with all the messages.
| Parameter | Type | Required | Description |
|---|---|---|---|
job_id |
integer | Required | The numerical ID of the job to return. |
ascending |
boolean | Optional | Normally the job messages returned so that the first is the newest. When this property is set to true in the request the first message will be the oldest, the last will be the newest. |
limit |
integer | Optional | Setting the limit for the log messages sent back. |
log_level |
string | Optional | Controls the severity of the messages that will be sent back. Valid values are "DEBUG", "SUCCESS", "WARNING" or "FAILED" (or as an alternative "JOB_DEBUG", "JOB_SUCCESS", "JOB_WARNING" or "JOB_FAILED"). The "DEBUG" will send back every message, "SUCCESS" will not send debug messages, "WARNING" will send warning and failure messages while "FAILURE" will send only failure messages. |
offset |
integer | Optional | Setting the offset of the first log message to be sent back. |
| Field | Type | Description |
|---|---|---|
job |
object | The info about the job instance as it is described in the jobclasses page. |
messages |
array | The job messages of the given job. This is a list of cmonjobmessage objects. |
Response example
{
"job":
{
"can_be_aborted": false,
"can_be_deleted": true,
"class_name": "CmonJobInstance",
"cluster_id": 0,
"created": "2017-06-23T08:29:19.000Z",
"ended": "2017-06-23T08:32:31.000Z",
"exit_code": 0,
"group_id": 2,
"group_name": "users",
"has_progress": true,
"job_id": 1,
"job_spec":
{
"command": "create_cluster",
"job_data":
{
"cluster_name": "ft_postgresql_63712",
"cluster_type": "postgresql_single",
"enable_uninstall": true,
"hostname": "192.168.1.192",
"port": 8089,
"postgre_password": "passwd12",
"postgre_user": "postmaster",
"ssh_user": "pipas",
"type": "postgresql"
}
},
"progress_percent": 100,
"started": "2017-06-23T08:29:19.000Z",
"status": "FINISHED",
"status_text": "Job finished.",
"title": "Setup PostgreSQL Server",
"user_id": 3,
"user_name": "pipas"
},
"messages": [
{
"class_name": "CmonJobMessage",
"created": "2017-06-23T08:29:19.000Z",
"file_name": "CmonCommandHandlerWorker.cpp",
"job_id": 1,
"line_number": 2820,
"message_id": 1,
"message_status": "JOB_SUCCESS",
"message_text": "Started create cluster job."
},
. . .
{
"class_name": "CmonJobMessage",
"created": "2017-06-23T08:32:31.000Z",
"file_name": "CmonCommandHandlerWorker.cpp",
"job_id": 1,
"line_number": 945,
"message_id": 79,
"message_status": "JOB_WARNING",
"message_text": "Try Settings -> Cluster Registrations and press 'Synchronize Clusters'."
} ],
"reply_received": "2017-06-23T08:38:01.052Z",
"request_created": "2017-06-23T08:38:01.046Z",
"request_id": 3,
"request_processed": "2017-06-23T08:38:01.102Z",
"request_status": "Ok",
"request_user_id": 3
}
Log Related Calls
The /v2/log provides calls to access the log handled by the Cmon controller. This is not for the job messages, this is about the logs that are stored in ASCII files.
| Operation | Description |
|---|---|
| getLogEntries | Get log messages from the controller. |
| getLogEntry | Retrieve one log message by its message ID. |
| getLogStatistics | Get statistical information about the log subsystem. |
| listCollectedLogs | List logs collected from all hosts stored in the local file system. |
| getCollectedLog | Retrieve the details of a selected collected log file. |
getLogEntries
POST /v2/log
This call can be used to get the log messages from the controller.
| Parameter | Type | Required | Description |
|---|---|---|---|
ascending |
boolean | Optional | Boolean value controlling the order of the log messages. |
cluster_name |
string | Optional | Identifies the cluster from which the log entries will be returned. The cluster ID can also be used to identify the cluster. |
cluster_id |
integer | Optional | Identifies the cluster from which the log entries will be returned. The cluster name can also be used. |
component |
string | Optional | Identifies the component that sent the log message. Currently this string can be 'Network', 'CmonDatabase', 'Mail', 'Cluster', 'ClusterConfiguration', 'ClusterRecovery', 'Node', 'Host', 'DbHealth', 'DbPerformance', 'SoftwareInstallation', 'Backup' or 'Unknown'. |
created_before |
string | Optional | If this date&time string is provided it will filter the messages by their creation time. |
created_after |
string | Optional | If this date&time string is provided it fill filter the messages by their creation time. |
limit |
integer | Optional | If this provided it limits the number of log entries sent back. |
offset |
integer | Optional | The index of the first item. If this value is provided together with the limit they can be used to implement a pager. |
severity |
string | Optional | This string can be one of the "LOG_EMERG", "LOG_ALERT", "LOG_CRIT", "LOG_ERR", "LOG_WARNING", "LOG_NOTICE", "LOG_INFO", "LOG_DEBUG" to filter the messages by their severity. |
| Field | Type | Description |
|---|---|---|
log_entries |
array | A list that holds the log entries returned as result. The log entries returned as CmonLogMessage objects. |
log_entry_counts |
object | A simple statistics showing how many messages are in the reply with various properties. |
total |
integer | The total number of records with the given filters. This with the limit and offset request parameters can be used to implement a pager. |
Response example
{
"log_entries": [
{
"class_name": "CmonLogMessage",
"component": "ClusterConfiguration",
"created": "2017-07-26T08:35:40.704Z",
"log_class": "LogMessage",
"log_id": 110,
"log_origins":
{
"sender_binary": "cmon",
"sender_file": "../../src/cmonhostmanager.cpp",
"sender_line": 594,
"sender_pid": 40818,
"tv_nsec": 704637455,
"tv_sec": 1501058140
},
"log_specifics":
{
"cluster_id": 1,
"message_text": "Registering CmonPostgreSqlHost: 192.168.1.167:8089"
},
"severity": "LOG_DEBUG"
},
. . .
{
"class_name": "CmonLogMessage",
"created": "2017-07-26T08:38:11.697Z",
"log_class": "LogMessage",
"log_id": 351,
"log_origins":
{
"sender_binary": "cmon",
"sender_file": "../../src/cmonalarmdb.cpp",
"sender_line": 1467,
"sender_pid": 40818,
"tv_nsec": 697060177,
"tv_sec": 1501058291
},
"log_specifics":
{
"cluster_id": 1,
"message_text": "hostId: 1, nodeId: 0, alarm: Host is not responding"
},
"severity": "LOG_DEBUG"
} ],
"log_entry_counts":
{
"component":
{
"Cluster": 1,
"ClusterConfiguration": 2,
"Node": 3,
"Unknown": 194
},
"hostname":
{
"": 199,
"192.168.1.167": 1
},
"sender_binary":
{
"cmon": 200
},
"severity":
{
"LOG_CRIT": 2,
"LOG_DEBUG": 192,
"LOG_ERR": 1,
"LOG_INFO": 2,
"LOG_WARNING": 3
}
},
"reply_received": "2017-07-26T08:39:53.936Z",
"request_created": "2017-07-26T08:39:53.931Z",
"request_id": 3,
"request_processed": "2017-07-26T08:39:54.019Z",
"request_status": "Ok",
"request_user_id": 3,
"total": 258
}
getLogEntry
POST /v2/log
This call is made for retrieving one message by its message ID.
Here is how a request looks like:
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The cluster ID. Use -1 for controller-level scope. |
message_id |
integer | Required | The ID of the log message to retrieve. |
| Field | Type | Description |
|---|---|---|
log_entry |
object | The log entry returned as a CmonLogMessage object. |
Response example
{
"debug_messages": [ "RPC V2 authenticated user is 'pipas'." ],
"log_entry":
{
"class_name": "CmonLogMessage",
"created": "2019-08-13T04:00:38.375Z",
"log_class": "JobStarted",
"log_id": 32,
"log_origins":
{
"sender_binary": "cmon",
"sender_file": "CmonCommandHandlerWorker.cpp",
"sender_line": 332,
"sender_pid": 49080,
"tv_nsec": 375158422,
"tv_sec": 1565668838
},
"log_specifics":
{
"cluster_id": 0,
"message_text": "Simulated Failure",
"reason": "Simulated Failure"
},
"severity": "LOG_INFO"
},
"request_created": "2019-08-13T05:22:18.882Z",
"request_id": 3,
"request_processed": "2019-08-13T05:22:18.891Z",
"request_status": "Ok",
"request_user_id": 4
}
getLogStatistics
POST /v2/log
This call can be used to get some statistical information about the subsystem that handles log messages. This is mostly for debugging purposes, but it also can be used to get some information that is shown to the end-user.
| Field | Type | Description |
|---|---|---|
log_statistics |
object | Statistical information about the log subsystem, including per-cluster log statistics, entry counts, and writer thread status. |
Response example
{
"log_statistics":
{
"cluster_log_statistics": [
{
"cluster_id": -1,
"disabled": false,
"entries_received": 3,
"format_string": "%C : (%S) %M",
"last_error_message": "",
"lines_written": 0,
"log_file_name": "",
"max_log_file_size": 5242880,
"messages_per_sec": 0.05,
"syslog_enabled": false,
"write_cycle_counter": 1
},
{
"cluster_id": 0,
"disabled": false,
"entries_received": 93,
"format_string": "%C : (%S) %M",
"last_error_message": "Success.",
"lines_written": 93,
"log_file_name": "./cmon-ft-install.log",
"max_log_file_size": 5242880,
"messages_per_sec": 0.05,
"syslog_enabled": false,
"write_cycle_counter": 3
},
{
"cluster_id": 1,
"disabled": false,
"entries_received": 218,
"format_string": "%C : (%S) %M",
"last_error_message": "Success.",
"lines_written": 218,
"log_file_name": "/tmp/cmon_1.log",
"max_log_file_size": 5242880,
"messages_per_sec": 0.85,
"syslog_enabled": false,
"write_cycle_counter": 11
} ],
"current_time": "2017-07-26T11:01:08.884Z",
"entries_statistics":
{
"entries_received": 319,
"entries_written_to_cmondb": 314
},
"has_cmondb": true,
"last_error_message": "Success.",
"last_flush_time": "2017-07-26T11:00:59.543Z",
"log_debug_enabled": false,
"writer_thread_running": true,
"writer_thread_started": "2017-07-26T10:55:29.410Z"
},
"request_created": "2017-07-26T11:01:08.840Z",
"request_id": 3,
"request_processed": "2017-07-26T11:01:08.884Z",
"request_status": "Ok",
"request_user_id": 3
}
listCollectedLogs
POST /v2/log
This call retrieves logs from all hosts then store in the local file system. The default folder is /var/lib/cmon/host_logs. Each subfolder represents the cluster which contains some nodes. Nodes/hosts are named using the format: hostname_port.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The ID of the cluster whose collected logs to list. |
| Field | Type | Description |
|---|---|---|
files |
array | A list of collected log file objects, each containing metadata about a log file stored on the local file system. |
Response example
{
"files": [
{
"created": "1662022801",
"filename": "postgresql-2022-09-01_064920.log",
"hostname": "10.0.8.11",
"length": "2030",
"path": "/var/lib/cmon/host_logs/10/10.0.8.11_5432/postgresql-2022-09-01_064920.log"
},
{
"created": "1663655401",
"filename": "prometheus.log",
"hostname": "178.128.85.233",
"length": "313625",
"path": "/var/lib/cmon/host_logs/10/178.128.85.233_9090/prometheus.log"
},
{
"created": "1663655400",
"filename": "agent_internal_logs.log",
"hostname": "10.0.8.11",
"length": "3568",
"path": "/var/lib/cmon/host_logs/10/10.0.8.11_4433/agent_internal_logs.log"
},
{
"created": "1663632001",
"filename": "cmnd.log",
"hostname": "10.0.8.11",
"length": "105914",
"path": "/var/lib/cmon/host_logs/10/10.0.8.11_4433/cmnd.log"
}
]
}
getCollectedLog
POST /v2/log
This call retrieves the details of a selected log from the UI. Logs are stored in the local file system and 'read' when user clicks on the particular log.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The ID of the cluster the log belongs to. |
filename |
string | Required | The filename of the log to retrieve. |
hostname |
string | Required | The hostname of the node whose log is being retrieved. |
| Field | Type | Description |
|---|---|---|
data |
object | An object containing the content and metadata of the retrieved log file. |
Response example
{
"data": {
"content": "2022-06-02 05:16:44.319 UTC [499] LOG: starting PostgreSQL 14.2 (Ubuntu 14.2-1.pgdg20.04+1+b1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0, 64-bit\r\n2022-06-02 05:16:44.319 UTC [499] LOG: listening on IPv4 address \"0.0.0.0\", port 5432\r\n2022-06-02 05:16:44.319 UTC [499] LOG: listening on IPv6 address \"::\", port 5432\r\n2022-06-02 05:16:44.339 UTC [499] LOG: listening on Unix socket \"/var/run/postgresql/.s.PGSQL.5432\"\r\n2022-06-02 05:16:44.451 UTC [508] LOG: database system was shut down at 2022-06-02 05:14:41 UTC\r\n2022-06-02 05:16:44.653 UTC [499] LOG: database system is ready to accept connections\r\n",
"created": "1661841000",
"filename": "postgresql-2022-06-02_051644.log",
"hostname": "10.0.8.11",
"length": "642"
}
}
PostgreSQL Logical Replication
The /v2/logical_replication is for managing logical replication clusters.
| Operation | Description |
|---|---|
| createPublication | Create a publication for logical replication. |
| dropPublication | Remove an existing publication from logical replication. |
| modifyPublication | Modify an existing publication in logical replication. |
| getPublications | Retrieve list of all publications configured for logical replication on the specified host. |
| createSubscription | Create a subscription for logical replication. |
| dropSubscription | Remove an existing subscription from logical replication. |
| modifySubscription | Modify an existing subscription in logical replication. |
| setSubscriptionState | Set the state (enabled/disabled) of a subscription. |
| getSubscriptions | Retrieve list of all subscriptions configured for logical replication on the specified host. |
createPublication
POST /v2/logical_replication
This call is for creating a publication for logical replication.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The logical replication cluster ID. |
subcluster_id |
integer | Optional | The sub-cluster ID to create the publication on. |
subcluster_name |
string | Optional | The sub-cluster name to create the publication on. |
pub_name |
string | Required | The name of the new publication. |
{pub_db_name\|db_name} |
string | Required | The database to create the publication on. |
include_all_tables |
boolean | Optional | Whether to replicate changes for all tables in the database (including future tables). |
db_tables |
array | Optional | List of specific tables to include in the publication. |
Remarks: Either
subcluster_idorsubcluster_namemust be provided. Eitherinclude_all_tablesmust betrueordb_tablesmust contain at least one table. The user must have the necessary privileges to manage replication.
dropPublication
POST /v2/logical_replication
Removes an existing publication from logical replication.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The logical replication cluster ID. |
subcluster_id |
integer | Optional | The sub-cluster ID containing the publication. |
subcluster_name |
string | Optional | The sub-cluster name containing the publication. |
pub_name |
string | Required | The name of the publication to drop. |
{pub_db_name\|db_name} |
string | Required | The database containing the publication. |
Remarks: Either
subcluster_idorsubcluster_namemust be provided. The user must have the necessary privileges to manage replication.
modifyPublication
POST /v2/logical_replication
Modifies an existing publication in logical replication.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The logical replication cluster ID. |
subcluster_id |
integer | Required | The sub-cluster ID containing the publication. |
pub_name |
string | Required | The current name of the publication. |
{pub_db_name\|db_name} |
string | Required | The database containing the publication. |
new_pub_name |
string | Optional | Optional new name for the publication. |
include_all_tables |
boolean | Optional | Whether to replicate all tables (including future ones). |
db_tables |
array | Optional | List of specific tables to include in the publication. |
getPublications
POST /v2/logical_replication
Retrieves list of all publications configured for logical replication on the specified host.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The logical replication cluster ID. |
subcluster_id |
integer | Optional | The sub-cluster ID to query publications from. |
subcluster_name |
string | Optional | The sub-cluster name to query publications from. |
Remarks: Either
subcluster_idorsubcluster_namemust be provided.
| Field | Type | Description |
|---|---|---|
publications |
array | List of publication objects. |
publications[].publication_name |
string | The name of the publication. |
publications[].database |
string | The database containing the publication. |
publications[].all_tables |
boolean | Whether the publication includes all tables. |
publications[].tables |
array | List of specific tables included in the publication. |
createSubscription
POST /v2/logical_replication
Creates a subscription for logical replication. A subscription represents a replication connection to the publisher.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The logical replication cluster ID. |
subcluster_id |
integer | Optional | The sub-cluster ID to create the subscription on. |
subcluster_name |
string | Optional | The sub-cluster name to create the subscription on. |
sub_name |
string | Required | The name of the new subscription. |
pub_name |
string | Required | The name of the publication to subscribe to. |
pub_db_name |
string | Optional | The database name of the publication. |
pub_origin |
string | Optional | Specifies whether to request changes with no origin ("none") or all changes regardless of origin ("any"). |
sub_db_name |
string | Required | The database to create the subscription in (preferred field name). |
db_name |
string | Optional | Deprecated: use sub_db_name instead. The database to create the subscription in. |
copy_data |
boolean | Optional | Specifies whether to copy pre-existing data in the publications when replication starts. |
Remarks: Either
subcluster_idorsubcluster_namemust be provided. The subscription name must be distinct from existing subscriptions in the database. Thepub_db_nameis optional and can be ignored, yet with multiple publications having the same name an error will be reported. In this case, it must be provided. The default value forpub_originis"any", and forcopy_dataistrue. Whencopy_data=trueandorigin=none, initial sync copies data directly from publisher, which may include data from upstream sources. The user must have the necessary privileges to manage replication.
dropSubscription
POST /v2/logical_replication
Removes an existing subscription from logical replication.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The logical replication cluster ID. |
subcluster_id |
integer | Optional | The sub-cluster ID containing the subscription. |
subcluster_name |
string | Optional | The sub-cluster name containing the subscription. |
sub_name |
string | Required | The name of the subscription to drop. |
{sub_db_name\|db_name} |
string | Required | The database containing the subscription. |
Remarks: Either
subcluster_idorsubcluster_namemust be provided. The user must have the necessary privileges to manage replication.
modifySubscription
POST /v2/logical_replication
Modifies an existing subscription in logical replication.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The logical replication cluster ID. |
subcluster_id |
integer | Required | The sub-cluster ID containing the subscription. |
sub_name |
string | Required | The current name of the subscription. |
sub_db_name |
string | Required | The database containing the subscription (preferred field name). |
db_name |
string | Optional | Deprecated: use sub_db_name instead. The database containing the subscription. |
new_sub_name |
string | Optional | Optional new name for the subscription. |
pub_origin |
string | Optional | Optional new publication origin setting ('any' or 'none') for the subscription. |
enabled |
boolean | Optional | Optional flag to enable/disable the subscription. |
setSubscriptionState
POST /v2/logical_replication
Sets the state (enabled/disabled) of a subscription.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The logical replication cluster ID. |
subcluster_id |
integer | Required | The sub-cluster ID containing the subscription. |
sub_name |
string | Required | The name of the subscription to modify. |
{sub_db_name\|db_name} |
string | Required | The database containing the subscription. |
enabled |
boolean | Required | Whether to enable (true) or disable (false) the subscription. |
Remarks: The user must have the necessary privileges to manage replication.
getSubscriptions
POST /v2/logical_replication
Retrieves list of all subscriptions configured for logical replication on the specified host.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The logical replication cluster ID. |
subcluster_id |
integer | Optional | The sub-cluster ID to query subscriptions from. |
subcluster_name |
string | Optional | The sub-cluster name to query subscriptions from. |
Remarks: Either
subcluster_idorsubcluster_namemust be provided.
| Field | Type | Description |
|---|---|---|
subscriptions |
array | List of subscription objects. |
subscriptions[].subscription_name |
string | The name of the subscription. |
subscriptions[].database |
string | The database containing the subscription. |
subscriptions[].publication_name |
string | The name of the publication being subscribed to. |
subscriptions[].publication_database |
string | The database of the publication. |
subscriptions[].publication_origin |
string | The publication origin setting ('any' or 'none'). |
subscriptions[].enabled |
boolean | Whether the subscription is enabled. |
Response example
{
"request_status": "Ok",
"subscriptions": [
{
"subscription_name": "sub1",
"database": "postgres",
"publication_name": "pub1",
"publication_database": "mydb",
"publication_origin": "any",
"enabled": true
},
{
"subscription_name": "sub2",
"database": "mydb",
"publication_name": "pub2",
"publication_database": "postgres",
"publication_origin": "none",
"enabled": false
}
]
}
Maintenance
The "v2/maintenance" is for creating, deleting and reading maintenance periods.
| Operation | Description |
|---|---|
| addMaintenance | Add a new maintenance period for a cluster or host. |
| removeMaintenance | Delete a maintenance period before it expires. |
| getMaintenance | Retrieve maintenance periods for clusters and/or hosts. |
| getCurrentMaintenance | Get the currently active maintenance period for a cluster or host. |
| getNextMaintenance | Get the next upcoming maintenance period for a cluster or host. |
addMaintenance
POST /v2/maintenance
The addMaintenance call is for adding new maintenance periods for clusters and hosts. A maintenance period is either belong to an entire cluster, in which case the cluster must be identified or it belongs to a host, so that the host name must be provided.
| Parameter | Type | Required | Description |
|---|---|---|---|
deadline |
string | Required | Marks the end of the maintenance period. At this time the maintenance period will automatically expire. |
cluster_id |
integer | Optional | The numerical ID of the cluster if this is a cluster maintenance period. |
hostname |
string | Optional | The name of the host if this is a host maintenance. |
initiate |
string | Required | The start of the maintenance period. |
reason |
string | Required | A human readable string which the users will see. |
| Field | Type | Description |
|---|---|---|
UUID |
string | A unique string which can be used to identify the maintenance period. |
removeMaintenance
POST /v2/maintenance
This RPC call can be used to delete maintenance periods before their time. Deleting a maintenance period will make them expire immediately.
| Parameter | Type | Required | Description |
|---|---|---|---|
UUID |
string | Required | Indentifies which maintenance period is going to be deleted. |
getMaintenance
POST /v2/maintenance
This call either sends back cluster maintenance periods when it received a cluster ID or host maintenance periods when it received one or more hostnames. When no cluster ID provided and no host names are sent either, both cluster maintenance and host maintenance periods are sent back.
The idea behind this call is that when the UI shows a host, it gets the maintenance periods of that host to show the details, when it shows a cluster it gets the maintenance periods of that cluster to show the details. If however the UI needs to know what nodes are in a cluster, that's an other call, that's not a "getMaintenance" call at all.
Here is an example of an s9s run. It shows two maintenance records, one for a host and one for a cluster:
$ s9s maintenance --list --long
ST UUID OWNER GROUP START END HOST/CLUSTER * REASON
-h 1da4955 pipas testgroup 2019-11-10 13:05:40 2019-11-10 15:05:40 192.168.0.58 testMaintenanceJob4
Ac 2358876 pipas testgroup 13:05:37 14:05:37 ft_maintenance_36279 testMaintenanceJob1
-c d89319c pipas testgroup 2019-11-09 13:05:39 2019-11-09 15:05:39 ft_maintenance_36279 testMaintenanceJob3
Total: 2
But the two records has three maintenance periods in it, because the same cluster has two maintenance periods. Now these looks like this in a reply:
Response example
{
"debug_messages": [ "RPC V2 authenticated user is 'pipas'." ],
"maintenance_records": [
{
"class_name": "CmonMaintenanceInfo",
"hostname": "192.168.0.58",
"is_active": false,
"maintenance_periods": [ {
"UUID": "1da49552-dd68-4604-ab16-a340c312cd9c",
"deadline": "2019-11-10T14:05:40.000Z",
"groupid": 4,
"groupname": "testgroup",
"initiate": "2019-11-10T12:05:40.000Z",
"is_active": false,
"reason": "testMaintenanceJob4",
"userid": 4,
"username": "pipas"
} ]
},
{
"class_name": "CmonMaintenanceInfo",
"cluster": {
"acl": "user::rwx,group::rwx,other::---",
"alarm_statistics": {
"class_name": "CmonAlarmStatistics"
},
"cdt_path": "/",
"class_name": "CmonClusterInfo",
"cluster_auto_recovery": true,
"cluster_id": 1,
"cluster_name": "ft_maintenance_36279",
"cluster_type": "POSTGRESQL_SINGLE",
"configuration_file": "/tmp/cmon_1.cnf",
"effective_privileges": "",
"group_owner": {
"acl": "user::rwx,group::rwx,other::---",
"cdt_path": "/groups",
"class_name": "CmonGroup",
"created": "2019-11-08T12:02:37.983Z",
"group_id": 4,
"group_name": "testgroup",
"owner_group_id": 1,
"owner_group_name": "admins",
"owner_user_id": 1,
"owner_user_name": "system"
},
"job_statistics": {
"class_name": "CmonJobStatistics"
},
"log_file": "/tmp/cmon_1.log",
"maintenance_mode_active": true,
"managed": true,
"node_auto_recovery": true,
"owner": {
"acl": "user::rwx,group::r--,other::r--",
"cdt_path": "/",
"class_name": "CmonUser",
"created": "2019-11-08T12:02:37.995Z",
"disabled": false,
"email_address": "[email protected]",
"first_name": "Laszlo",
"groups": [ {
"acl": "user::rwx,group::rwx,other::---",
"cdt_path": "/groups",
"class_name": "CmonGroup",
"created": "2019-11-08T12:02:37.983Z",
"group_id": 4,
"group_name": "testgroup",
"owner_group_id": 1,
"owner_group_name": "admins",
"owner_user_id": 1,
"owner_user_name": "system"
} ],
"last_failed_login": "",
"last_login": "2019-11-08T12:24:56.456Z",
"last_name": "Pere",
"n_failed_logins": 0,
"origin": "CmonDb",
"owner_group_id": 1,
"owner_group_name": "admins",
"owner_user_id": 4,
"owner_user_name": "pipas",
"suspended": false,
"timezone": {
"abbreviation": "CET",
"class_name": "CmonTimeZone",
"name": "Central European Time",
"offset": -3600,
"has_dst_rules": true
},
"user_id": 4,
"user_name": "pipas"
},
"state": "STARTED",
"status_text": "All nodes are operational.",
"vendor": "postgres",
"version": "9.6"
},
"cluster_id": 1,
"is_active": true,
"maintenance_periods": [
{
"UUID": "2358876c-8eec-42c8-b149-69e722044b3f",
"deadline": "2019-11-08T13:05:37.178Z",
"groupid": 4,
"groupname": "testgroup",
"initiate": "2019-11-08T12:05:37.178Z",
"is_active": true,
"reason": "testMaintenanceJob1",
"userid": 4,
"username": "pipas"
},
{
"UUID": "d89319c9-3e7c-462e-9f54-4052682d2daa",
"deadline": "2019-11-09T14:05:39.000Z",
"groupid": 4,
"groupname": "testgroup",
"initiate": "2019-11-09T12:05:39.000Z",
"is_active": false,
"reason": "testMaintenanceJob3",
"userid": 4,
"username": "pipas"
}
]
}
],
"reply_received": "2019-11-08T12:24:56.475Z",
"request_created": "2019-11-08T12:24:56.464Z",
"request_id": 3,
"request_processed": "2019-11-08T12:24:56.475Z",
"request_status": "Ok",
"request_user_id": 4,
"total": 2
}
getCurrentMaintenance
POST /v2/maintenance
This RPC call was made so that the client program has a quick and easy way to get information about the active maintanence for a cluster or a host.
If this call finds a host maintenance that is active it will return that, if it finds a cluster maintenance that will be returned.
Here is a call to search for a cluster wide maintenance (no host maintenance is returned ever).
{
"cluster_id": 1,
"operation": "getCurrentMaintenance",
"request_created": "2019-11-11T15:07:37.539Z",
"request_id": 3
}
Here is a call that returns either the cluster maintenance or the host maintenance or no maintenance if neither of those found:
Response example
{
"debug_messages": [ "RPC V2 authenticated user is 'pipas'." ],
"found_maintenance": true,
"maintenance_period": {
"UUID": "9dec403d-0940-4603-b93f-3c58fa773ce1",
"class_name": "CmonMaintenanceDate",
"deadline": "2019-11-11T16:07:12.969Z",
"groupid": 4,
"groupname": "testgroup",
"initiate": "2019-11-11T15:07:12.969Z",
"reason": "testMaintenanceJob1",
"userid": 4,
"username": "pipas"
},
"reply_received": "2019-11-11T15:07:37.546Z",
"request_created": "2019-11-11T15:07:37.539Z",
"request_id": 3,
"request_processed": "2019-11-11T15:07:37.546Z",
"request_status": "Ok",
"request_user_id": 4,
"ui_string": "Cluster 1 is under maintenance: testMaintenanceJob1"
}
getNextMaintenance
POST /v2/maintenance
This RPC call was made so that the client program has a quick and easy way to get information about the next coming maintenance periods.
If this call finds a host maintenance that is active it will return that, if it finds a cluster maintenance that will be returned.
Here is a call to search for a cluster wide maintenance (no host maintenance is returned ever).
{
"cluster_id": 1,
"operation": "getNextMaintenance",
"request_created": "2019-11-12T08:07:29.966Z",
"request_id": 3
}
Here is a call that returns either the cluster maintenance or the host maintenance or no maintenance if neither of those found:
Response example
{
"debug_messages": [ "RPC V2 authenticated user is 'pipas'." ],
"found_maintenance": true,
"maintenance_period": {
"UUID": "8a812d58-18a2-4d55-9702-2e5e05de1a41",
"class_name": "CmonMaintenanceDate",
"deadline": "2019-11-13T09:07:15.000Z",
"groupid": 4,
"groupname": "testgroup",
"initiate": "2019-11-13T08:07:15.000Z",
"reason": "testMaintenanceJob1",
"userid": 4,
"username": "pipas"
},
"reply_received": "2019-11-12T08:07:29.973Z",
"request_created": "2019-11-12T08:07:29.966Z",
"request_id": 3,
"request_processed": "2019-11-12T08:07:29.973Z",
"request_status": "Ok",
"request_user_id": 4,
"ui_string": "Cluster 1 maintenance starts Nov 13 08:07:15: testMaintenanceJob1"
}
Mysql databaseperformance
| Operation | Description |
|---|---|
| noPrimaryKeys | Returns a list of tables that do not have primary keys. |
| myIsamTables | Returns a list of tables that are using MyISAM engine. |
| redundantIndexes | Returns a list of tables that have redundant indexes. |
noPrimaryKeys
POST /v2/performance
An RPC call that returns a list of tables that do not have primary keys.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The ID of the cluster. |
| Field | Type | Description |
|---|---|---|
total |
integer | Total number of tables without primary keys. |
data |
array | List of tables without primary keys. |
data[].database |
string | Database name. |
data[].engine |
string | Storage engine used by the table. |
data[].table |
string | Table name. |
Response example
{
"controller_id": "5bfb8a65-8bbf-4762-9c48-e6603377b26e",
"request_processed": "2024-08-01T12:16:59.926Z",
"request_status": "Ok",
"request_user_id": 4,
"total": 2,
"data":
[
{
"database": "mysql",
"engine": "myEngine",
"table": "AAA"
},
{
"database": "mysql",
"engine": "myEngine",
"table": "BBB"
}
],
"debug_messages":
[
"RPC V2 authenticated user is 'Adam'."
]
}
myIsamTables
POST /v2/performance
An RPC call that returns a list of tables that are using MyISAM engine.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The ID of the cluster. |
| Field | Type | Description |
|---|---|---|
total |
integer | Total number of MyISAM tables. |
data |
array | List of MyISAM tables. |
data[].database |
string | Database name. |
data[].engine |
string | Storage engine used by the table. |
data[].table |
string | Table name. |
Response example
{
"controller_id": "5bfb8a65-8bbf-4762-9c48-e6603377b26e",
"request_processed": "2024-08-01T12:16:59.926Z",
"request_status": "Ok",
"request_user_id": 4,
"total": 1,
"data":
[
{
"database": "mysql",
"engine": "myIsam",
"table": "BBB"
}
],
"debug_messages":
[
"RPC V2 authenticated user is 'Adam'."
]
}
redundantIndexes
POST /v2/performance
An RPC call that returns a list of tables that have redundant indexes.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The ID of the cluster. |
| Field | Type | Description |
|---|---|---|
total |
integer | Total number of tables with redundant indexes. |
data |
array | List of tables with redundant indexes. |
data[].advise |
string | Advisory note about the redundant index. |
data[].database |
string | Database name. |
data[].index |
string | Index identifier. |
data[].indexColumns |
string | Columns in the index. |
data[].redidxColumns |
string | Columns in the redundant index. |
data[].redundantIndex |
string | Name of the redundant index. |
data[].table |
string | Table name. |
Response example
{
"controller_id": "5bfb8a65-8bbf-4762-9c48-e6603377b26e",
"request_processed": "2024-08-01T12:16:59.926Z",
"request_status": "Ok",
"request_user_id": 4,
"total": 1,
"data":
[
{
"advise": "Do not touch",
"database": "myXdb",
"index": "66",
"indexColumns": "88",
"redidxColumns": "55",
"redundantIndex": "111",
"table": "myTable"
}
],
"debug_messages":
[
"RPC V2 authenticated user is 'Adam'."
]
}
Reports
The /v2/reports provides access to reports generated by the Cmon controller.
| Operation | Description |
|---|---|
| Download report | Download a generated report file by basename and cluster ID. |
| generateReport | Generate a named report for a cluster and return its content inline. |
| getReport | Retrieve a specific report by ID. |
| getReportTemplates | Return report templates describing available report types. |
| deleteReport | Delete an existing report from the controller. |
| getReports | Get existing reports from the controller. |
| listErrorReports | List generated error reports. |
| removeErrorReport | Remove a specific error report. |
| downloadErrorReport | Download a specific error report as a tar.gz file. |
| addSchedule | Schedule an operational report. |
| removeSchedule | Remove an operational report schedule. |
| listSchedules | List currently active operational report schedules. |
Download report
POST /v2/reports
Pass the basename of the report after path /v2/reports/, and you must specify the cluster-id as well via the ?cluster_id= query argument.
<!DOCTYPE html>
<html><body>
...
<p class="text"><br/><b>How do you like this report?</b><br/>What else do you like to see or not see? We'd <a href="mailto:[email protected]?subject=Operation Reports Feedback">appreciate your feedback</a>. Thanks!<br/></p>
</body>
</html>
generateReport
POST /v2/reports
Generates a named report for a cluster and returns its content inline. The report_type field specifies which report to generate, and text_format controls the output format (AnsiTerminal, Html, etc.). The generated report content is returned in report.content and report.document.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The ID of the cluster to generate the report for. |
report |
object | Required | A CmonReport class object specifying the report configuration. |
report.class_name |
string | Required | Must be CmonReport. |
report.recipients |
string | Optional | Email recipients for the report. |
report.report_type |
string | Required | The type of report to generate. |
report.text_format |
string | Required | The output format (e.g., AnsiTerminal, Html). |
{
"cluster_id": 1,
"operation": "generateReport",
"report":
{
"class_name": "CmonReport",
"recipients": "[email protected]",
"report_type": "testreport",
"text_format": "AnsiTerminal"
},
"request_created": "2017-08-04T11:06:32.148Z",
"request_id": 3
}
| Field | Type | Description |
|---|---|---|
report |
object | The report that has been created as a CmonReport class object. |
report.class_name |
string | The class name, CmonReport. |
report.content |
string | The rendered text content of the report. |
report.created |
string | Timestamp when the report was created. |
report.document |
object | The structured document representation of the report. |
report.owner |
string | The owner of the report. |
report.path |
string | The file path where the report was saved. |
report.recipients |
string | Email recipients for the report. |
report.report_id |
integer | The unique ID of the generated report. |
report.report_type |
string | The type of the report. |
report.text_format |
string | The output format used. |
report.title |
string | The title of the report. |
To get a comprehensive list of the properties the controller supports in the CmonReport class one can run the following command:
Response example
{
"report":
{
"class_name": "CmonReport",
"content": " Simple Test Report\n\n This report was created to test the report subsystem. The document was\n created in the CmonReporter::buildTestReport() method.\n\n",
"created": "2017-08-04T11:06:32.000Z",
"document":
{
"className": "CmonDocument",
"elements": [
{
"className": "CmonTitle",
"text": "Simple Test Report",
"titleLevel": 1
},
{
"className": "CmonParagraph",
"text": "This report was created to test the report subsystem. The document was created in the CmonReporter::buildTestReport() method."
} ]
},
"owner": "pipas",
"path": "/home/pipas/s9s_tmp/1/postgresql_single/cmon-reports/testreport_2017-08-04_130632.html",
"recipients": "[email protected]",
"report_id": 1,
"report_type": "testreport",
"text_format": "AnsiTerminal",
"title": "Simple Test Report"
},
"request_created": "2017-08-04T11:06:32.148Z",
"request_id": 3,
"request_processed": "2017-08-04T11:06:32.200Z",
"request_status": "Ok",
"request_user_id": 3
}
getReport
POST /v2/reports
The request format for this call has recently been changed. Instead of passing just a single ID we need to pass a CmonReport class object.
| Parameter | Type | Required | Description |
|---|---|---|---|
report |
object | Required | A CmonReport class object identifying the report to retrieve. |
report.class_name |
string | Required | Must be CmonReport. |
report.report_id |
integer | Required | The ID of the report to retrieve. |
report.text_format |
string | Optional | The output format (e.g., AnsiTerminal). |
getReportTemplates
POST /v2/reports
This call is to return the report templates describing what kind of reports are available for the user when generating reports. Report templates are just simple CmonReport objects with a few properties set to reflect the properties that the report will have when a report with the same report type is used.
So template name is just an other way of saying report_type.
| Field | Type | Description |
|---|---|---|
reports |
array | List of report template objects. |
reports[].class_name |
string | The class name, CmonReport. |
reports[].report_type |
string | The report type identifier (template name). |
reports[].title |
string | The human-readable title of the report template. |
Response example
{
"reports": [
{
"class_name": "CmonReport",
"report_type": "default",
"title": "System Report"
},
. . .
{
"class_name": "CmonReport",
"report_type": "capacity",
"title": "Database Growth Report"
} ],
"request_created": "2019-07-31T06:45:30.083Z",
"request_id": 3,
"request_processed": "2019-07-31T06:45:30.089Z",
"request_status": "Ok",
"request_user_id": 4
}
deleteReport
POST /v2/reports
A call to delete an existing report from the controller.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The ID of the cluster the report belongs to. |
report |
object | Required | A CmonReport class object identifying the report to delete. |
report.class_name |
string | Required | Must be CmonReport. |
report.report_id |
integer | Required | The ID of the report to delete. |
getReports
POST /v2/reports
A call to get existing reports from the controller.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The ID of the cluster to retrieve reports for. |
| Field | Type | Description |
|---|---|---|
reports |
array | List of report info objects. |
reports[].class_name |
string | The class name, CmonReportInfo. |
reports[].cluster_id |
integer | The cluster ID the report belongs to. |
reports[].created |
string | Timestamp when the report was created. |
reports[].name |
string | The filename of the report. |
reports[].owner |
string | The owner of the report. |
reports[].path |
string | The full file path of the report. |
reports[].recipients |
string | Email recipients for the report. |
reports[].report_id |
integer | The unique ID of the report. |
reports[].report_type |
string | The type of the report. |
total |
integer | Total number of reports returned. |
Response example
{
"reports": [
{
"class_name": "CmonReportInfo",
"cluster_id": 1,
"created": "2017-08-02T13:01:44.000Z",
"name": "availability_2017-08-02_143459.html",
"owner": "pipas",
"path": "/home/pipas/s9s_tmp/1/postgresql_single/cmon-reports/availability_2017-08-02_143459.html",
"recipients": "",
"report_id": 1,
"report_type": "availability"
} ],
"request_created": "2017-08-02T12:34:59.892Z",
"request_id": 4,
"request_processed": "2017-08-02T12:34:59.936Z",
"request_status": "Ok",
"request_user_id": 3,
"total": 1
}
listErrorReports
POST /v2/reports
A call to list the generated error reports.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The ID of the cluster to list error reports for. |
| Field | Type | Description |
|---|---|---|
is_superuser |
boolean | Whether the authenticated user is a superuser. |
total |
integer | Total number of error reports. |
data |
array | List of error report objects. |
data[].created |
string | Timestamp when the error report was created. |
data[].id |
integer | The unique ID of the error report. |
data[].path |
string | The file path of the error report archive. |
data[].size |
string | The size of the error report file. |
data[].www |
boolean | Whether the report is accessible via the web. |
Response example
{
"controller_id": "7f399ff3-7484-4a93-a47a-a5c0bba42fca",
"is_superuser": true,
"request_processed": "2022-09-26T08:21:43.405Z",
"request_status": "Ok",
"total": 1,
"data":
[
{
"created": "2022-09-26T08:21:18.000Z",
"id": 13,
"path": "/home/cmon_user/s9s_tmp/error-report-2022-09-26_082116-cluster90.tar.gz",
"size": "7.63 MiB",
"www": false
}
]
}
removeErrorReport
POST /v2/reports
A call to list the generated error reports.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The ID of the cluster the error report belongs to. |
id |
integer | Required | The ID of the error report to remove. |
downloadErrorReport
POST /v2/reports
A method to download a specific error report. Please NOTE this method will return the generated .tar.gz file directly (so don't expect a JSON reply).
The return value is an application/octet-stream of the tar.gz file directly. Or in case of error a normal JSON RPC reply including the error reason.
addSchedule
POST /v2/reports
A call to schedule an operational report.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The ID of the cluster to schedule the report for. |
name |
string | Required | The name/type of the report to schedule. |
schedule |
string | Required | The cron expression defining the schedule. |
recipients |
string | Optional | Email recipients for the scheduled report. |
{
"cluster_id": 90,
"operation": "addSchedule",
"name": "default",
"schedule": "*0 10 * * *",
"recipients": "[email protected]"
}
| Field | Type | Description |
|---|---|---|
is_superuser |
boolean | Whether the authenticated user is a superuser. |
id |
integer | The ID of the newly created schedule. |
removeSchedule
POST /v2/reports
A call to remove an operational report schedule.
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
integer | Required | The ID of the schedule to remove. |
listSchedules
POST /v2/reports
Lists the currently active operational reports schedules.
| Field | Type | Description |
|---|---|---|
is_superuser |
boolean | Whether the authenticated user is a superuser. |
total |
integer | Total number of schedules. |
data |
array | List of schedule objects. |
data[].arguments |
string | Arguments passed to the scheduled report. |
data[].command |
string | The report command/type to run. |
data[].id |
integer | The unique ID of the schedule. |
data[].recipients |
string | Email recipients for the scheduled report. |
data[].schedule |
string | The cron expression for the schedule. |
user |
object | The authenticated user object. |
Response example
{
"controller_id": "7f399ff3-7484-4a93-a47a-a5c0bba42fca",
"is_superuser": true,
"request_processed": "2023-01-26T14:16:16.603Z",
"request_status": "Ok",
"total": 2,
"data":
[
{
"arguments": "days=7",
"command": "default",
"id": 1,
"recipients": "",
"schedule": "1 6 * * *"
},
{
"arguments": "days=7",
"command": "upgrade",
"id": 2,
"recipients": "[email protected]",
"schedule": "1 22 10 * *"
}
],
"debug_messages":
[
"RPC V2 authenticated user is 'alex'."
],
"user":
{
"class_name": "CmonUser",
"cdt_path": "/",
"owner_user_id": 68,
"owner_user_name": "alex",
"owner_group_id": 1,
"owner_group_name": "admins",
"acl": "user::rwx,group::r--,other::r--",
"created": "2022-12-16T15:21:36.542Z",
"disabled": false,
"distinguished_name": "uid=alex,ou=People,dc=severalnines,dc=org",
"email_address": "[email protected]",
"first_name": "alex",
"last_failed_login": "",
"last_login": "2023-01-26T14:16:16.601Z",
"n_failed_logins": 0,
"origin": "LDAP",
"suspended": false,
"user_id": 68,
"user_name": "alex",
"groups":
[
{
"class_name": "CmonGroup",
"cdt_path": "/groups",
"owner_user_id": 1,
"owner_user_name": "system",
"owner_group_id": 1,
"owner_group_name": "admins",
"acl": "user::rwx,group::rwx,other::---",
"created": "2022-02-23T11:01:14.628Z",
"group_id": 1,
"group_name": "admins"
}
],
"timezone":
{
"class_name": "CmonTimeZone",
"name": "Central European Time",
"abbreviation": "CET",
"offset": -3600,
"has_dst_rules": false
}
}
}
Repositories
The /v2/repositories path provides calls to create and manage local software repositories and get information about supported software.
| Operation | Description |
|---|---|
| getRepositories | Returns available local repositories. |
| deleteRepository | Removes a software repository registration and deletes the repository directory from disk. |
| getRepositorySetup | Prints out the generated repository filename and contents for manual use. |
| getSupportedSetups | Returns what possible setups can be used to create/install a new node. |
getRepositories
POST /v2/repositories
Returns available local repositories.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The cluster ID. |
cluster_type |
string | Optional | Filter by cluster-type (galera, mongodb, postgresql, ...). |
vendor |
string | Optional | Filter by vendor (percona, mariadb, ...). |
db_version |
string | Optional | Filter by database (major.minor) version (5.6, 10.1, ...). |
| Field | Type | Description |
|---|---|---|
repositories |
array | List of repository objects. |
total |
integer | Total number of repositories returned. |
Response example
{
"repositories": [
{
"class_name": "CmonRepository",
"cluster_type": "galera",
"db_version": "5.6",
"modified": "2017-08-01T08:25:29.000Z",
"name": "percona-5.6-apt-precise",
"os":
{
"distribution/codename": "unknown",
"distribution/name": "unknown",
"distribution/release": "unknown",
"distribution/type": "debian"
},
"path": "/var/tmp/unammed-cmon-repo",
"used_by_cluster": "",
"vendor": "percona"
} ],
"request_created": "2017-08-01T08:25:35.414Z",
"request_id": 4,
"request_processed": "2017-08-01T08:25:35.462Z",
"request_status": "Ok",
"request_user_id": 3,
"total": 1
}
deleteRepository
POST /v2/repositories
Removes a software repository registration from the controller and deletes the repository directory from disk. This operation is irreversible.
getRepositorySetup
POST /v2/repositories
Prints out the (semi-)generated repository filename and contents to use the repository manually. You have to substitute the CMON-HOSTNAME string with the controllers IP address before u use it.
getSupportedSetups
POST /v2/repositories
This call will return what possible setups can be used to create/install a new node.
The request does not need a cluster ID or cluster name, the only field that is needed is the "operation" field:
| Field | Type | Description |
|---|---|---|
supported_setups |
array | List of supported setup objects, each with cluster_type, db_version, os_version, and vendor. |
total |
integer | Total number of supported setups returned. |
Response example
{
"request_created": "2017-07-31T09:57:07.145Z",
"request_id": 3,
"request_processed": "2017-07-31T09:57:07.188Z",
"request_status": "Ok",
"request_user_id": 3,
"supported_setups": [
{
"cluster_type": "mongodb",
"db_version": "3.2",
"os_version": "5",
"vendor": "10gen"
},
. . .
{
"cluster_type": "replication",
"db_version": "5.7",
"os_version": "xenial",
"vendor": "oracle"
} ],
"total": 206
}
Cmon Events
The /v2/events path holds proxied requests to cmon-events.
| Operation | Description |
|---|---|
| test | Proxies to the /test endpoint in cmon-events. |
| getSpreadsheetNames | Returns the list of spreadsheet names available for a cluster. |
| getSpreadsheet | Returns the contents of a named spreadsheet for a cluster. |
test
POST /v2/events
This request proxies to the /test endpoint in cmon-events.
getSpreadsheetNames
POST /v2/events
Returns the list of spreadsheet names available for a cluster. Spreadsheets are used for capacity planning and other analytical reports. Use the names returned here with getSpreadsheet to retrieve the actual data.
getSpreadsheet
POST /v2/events
Returns the contents of a named spreadsheet for a cluster. Use getSpreadsheetNames first to discover the spreadsheet names available for a given cluster.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The ID of the cluster. |
spreadsheet_name |
string | Required | The name of the spreadsheet to retrieve. |
Statistical Data Calls
The /v2/stat provides calls to access various statistical information about the cluster.
| Operation | Description |
|---|---|
| getInfo | Get data collected by the sheet manager from the system. |
| statByName | Return time-series statistics samples for a named metric across all nodes in a cluster. |
| getCpuPhysicalInfo | Return physical CPU hardware information for each node in a cluster. |
getInfo
POST /v2/stat
This call is for getting the data that the sheet manager collected from the system.
Response example
{
"collected_info": [
{
"cluster_id": 1,
"info":
{
"cluster.status": 2,
"cluster.statustext": "Cluster started.",
"cmon.domainname": "",
"cmon.hostname": "t7500",
"cmon.running": true,
"cmon.starttime": 1501144642,
"cmon.uptime": 15636,
"conf.backup_retention": 31,
"conf.clusterid": 1,
"conf.clustername": "ft_postgresql_48154",
"conf.clustertype": 5,
"conf.configfile": "/tmp/cmon_1.cnf",
"conf.hostname": "192.168.1.127",
"conf.os": "debian",
"conf.statustext": "Configuration loaded.",
"host.1.connected": true,
"host.1.cpu_io_wait_percent": 0.353357,
"host.1.cpu_steal_percent": 0,
"host.1.cpu_usage_percent": 15.5331,
"host.1.cpucores": 16,
"host.1.cpuinfo": [
{
"class_name": "CmonCpuInfo",
"cpucores": 4,
"cpumaxmhz": 2.268e+06,
"cpumhz": 1600,
"cpumodel": "Intel(R) Xeon(R) CPU L5520 @ 2.27GHz",
"cputemp": 55.5,
"hostid": 1,
"physical_cpu_id": 0,
"siblings": 8,
"vendor": "GenuineIntel"
},
{
"class_name": "CmonCpuInfo",
"cpucores": 4,
"cpumaxmhz": 2.268e+06,
"cpumhz": 1733,
"cpumodel": "Intel(R) Xeon(R) CPU L5520 @ 2.27GHz",
"cputemp": 55.5,
"hostid": 1,
"physical_cpu_id": 1,
"siblings": 8,
"vendor": "GenuineIntel"
} ],
"host.1.cpumaxmhz": 2268,
"host.1.cpumhz": 1733,
"host.1.cpumodel": "Intel(R) Xeon(R) CPU L5520 @ 2.27GHz",
"host.1.cputemp": 55.5,
"host.1.devices": [ "/dev/mapper/core1--vg-root" ],
"host.1.free_disk_bytes": 155814936576,
"host.1.hostname": "192.168.1.174",
"host.1.interfaces": [ "eth0" ],
"host.1.ip": "192.168.1.174",
"host.1.membuffer": 0,
"host.1.memcached": 1,
"host.1.memfree": 16031900,
"host.1.memtotal": 16777216,
"host.1.network_interfaces": [
{
"interface_name": "eth0",
"rx_bytes_per_sec": 11775.8,
"tx_bytes_per_sec": 17652.3
} ],
"host.1.pingdelay": -1,
"host.1.pingstatustext": "Creating ICMP socket (to ping '192.168.1.174') failed: Operation not permitted.",
"host.1.port": 8089,
"host.1.rx_bytes_per_second": 11775.8,
"host.1.swapfree": 0,
"host.1.swaptotal": 0,
"host.1.total_disk_bytes": 208033853440,
"host.1.tx_bytes_per_second": 17652.3,
"host.1.uptime": 15779,
"host.1.wallclock": 1501160299,
"host.1.wallclocksampled": 1501160235,
"host.2.class_name": "controller",
"host.2.connected": true,
"host.2.cpu_io_wait_percent": 2.89087,
"host.2.cpu_steal_percent": 0,
"host.2.cpu_usage_percent": 204.378,
"host.2.cpucores": 24,
"host.2.cpuinfo": [
{
"class_name": "CmonCpuInfo",
"cpucores": 6,
"cpumaxmhz": 2.661e+06,
"cpumhz": 1596,
"cpumodel": "Intel(R) Xeon(R) CPU X5650 @ 2.67GHz",
"cputemp": 0,
"hostid": 2,
"physical_cpu_id": 0,
"siblings": 12,
"vendor": "GenuineIntel"
},
{
"class_name": "CmonCpuInfo",
"cpucores": 6,
"cpumaxmhz": 2.661e+06,
"cpumhz": 1596,
"cpumodel": "Intel(R) Xeon(R) CPU X5650 @ 2.67GHz",
"cputemp": 0,
"hostid": 2,
"physical_cpu_id": 1,
"siblings": 12,
"vendor": "GenuineIntel"
} ],
"host.2.cpumaxmhz": 2661,
"host.2.cpumhz": 1596,
"host.2.cpumodel": "Intel(R) Xeon(R) CPU X5650 @ 2.67GHz",
"host.2.cputemp": 0,
"host.2.devices": [ "/dev/sda1" ],
"host.2.free_disk_bytes": 1409452683264,
"host.2.hostname": "192.168.1.127",
"host.2.interfaces": [ "eth0" ],
"host.2.ip": "192.168.1.127",
"host.2.membuffer": 318624,
"host.2.memcached": 19415480,
"host.2.memfree": 9243460,
"host.2.memtotal": 49453276,
"host.2.network_interfaces": [
{
"interface_name": "eth0",
"rx_bytes_per_sec": 29150.4,
"tx_bytes_per_sec": 18520.8
} ],
"host.2.pingdelay": -1,
"host.2.pingstatustext": "Creating ICMP socket (to ping '192.168.1.127') failed: Operation not permitted.",
"host.2.port": 9555,
"host.2.rx_bytes_per_second": 29150.4,
"host.2.swapfree": 0,
"host.2.swaptotal": 0,
"host.2.total_disk_bytes": 2125259440128,
"host.2.tx_bytes_per_second": 18520.8,
"host.2.uptime": 2.59852e+06,
"host.2.version": "1.4.3",
"host.2.wallclock": 1501160235,
"host.2.wallclocksampled": 1501160235,
"license.expires": -1,
"license.status": false,
"license.statustext": "No license found.",
"mail.statustext": "Created.",
"netStat.1.eth0.rxBytes": 287358005,
"netStat.1.eth0.txBytes": 205682361,
"netStat.2.eth0.rxBytes": 531084878595,
"netStat.2.eth0.txBytes": 503628558465
}
} ],
"request_created": "2017-07-27T12:58:00.283Z",
"request_id": 3,
"request_processed": "2017-07-27T12:58:00.328Z",
"request_status": "Ok",
"request_user_id": 3
}
statByName
POST /v2/stat
Returns time-series statistics samples for a named metric across all nodes in a cluster. Common metric names include cpustat, memstat, and diskstat.
Filter results to a specific time window using start_datetime and end_datetime. Set with_hosts to true to include host metadata alongside each sample, and calculate_per_sec to true to normalise counter-type values to per-second rates.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The ID of the cluster. |
name |
string | Required | The metric name to retrieve (e.g. cpustat, memstat, diskstat). |
start_datetime |
string | Optional | Start of the time window to filter results. |
end_datetime |
string | Optional | End of the time window to filter results. |
with_hosts |
boolean | Optional | Set to true to include host metadata alongside each sample. |
calculate_per_sec |
boolean | Optional | Set to true to normalise counter-type values to per-second rates. |
| Field | Type | Description |
|---|---|---|
data |
array | Array of time-series stat sample objects for the requested metric. |
hosts |
array | Array of host objects with metadata for each node (present when with_hosts is true). |
total |
integer | Total number of samples returned. |
Response example
{
"data": [
{
"busy": 0.00555556,
"cpuid": 0,
"cpumhz": 1600,
"cpumodelname": "Intel(R) Xeon(R) CPU L5520 @ 2.27GHz",
"cpuphysicalid": 0,
"cputemp": 55.5,
"created": 1501161605,
"hostid": 1,
"idle": 0.994444,
"interval": 5473,
"iowait": 0,
"loadavg1": 0.14,
"loadavg15": 0.09,
"loadavg5": 0.11,
"sampleends": 1501161608,
"samplekey": "CmonCpuStats-1-0",
"steal": 0,
"sys": 0.0037037,
"uptime": 17107,
"user": 0.00185185
},
. . .
{
"busy": 0.0980228,
"cpuid": 23,
"cpumhz": 1596,
"cpumodelname": "Intel(R) Xeon(R) CPU X5650 @ 2.67GHz",
"cpuphysicalid": 0,
"cputemp": 0,
"created": 1501161658,
"hostid": 2,
"idle": 0.901977,
"interval": 5379,
"iowait": 0,
"loadavg1": 2.35,
"loadavg15": 2.23,
"loadavg5": 2.33,
"sampleends": 1501161661,
"samplekey": "CmonCpuStats-2-23",
"steal": 0,
"sys": 0.0247148,
"uptime": 2.5999e+06,
"user": 0.073308
} ],
"hosts": [
{
"class_name": "CmonPostgreSqlHost",
"clusterid": 1,
"configfile": [ "/etc/postgresql/9.6/main/postgresql.conf" ],
"connected": true,
"data_directory": "/var/lib/postgresql/9.6/main",
"datadir": "/var/lib/postgresql/9.6/main",
"description": "",
"distribution":
{
"codename": "xenial",
"name": "ubuntu",
"release": "16.04",
"type": "debian"
},
"hostId": 1,
"hostname": "192.168.1.174",
"hoststatus": "CmonHostOnline",
"hot_standby": true,
"ip": "192.168.1.174",
"lastseen": 1501162240,
"logfile": "/var/log/postgresql/postgresql-9.6-main.log[0m",
"maintenance_mode_active": false,
"message": "Up and running",
"nodetype": "postgres",
"pid": 5247,
"pidfile": "/var/run/postgresql/9.6-main.pid",
"pingstatus": 0,
"pingtime": 0,
"port": 8089,
"readonly": false,
"received_location": "0/1523B10",
"replay_location": "0/1523B10",
"role": "master",
"sshfailcount": 0,
"ssl_certs":
{
"server":
{
"ca": "",
"id": 0,
"key": "/etc/ssl/private/ssl-cert-snakeoil.key",
"path": "/etc/ssl/certs/ssl-cert-snakeoil.pem"
}
},
"timestamp": 1501162240,
"unique_id": 1,
"uptime": 17592,
"version": "9.6.3",
"wallclock": 1501162260,
"wallclocktimestamp": 1501162197
},
{
"class_name": "CmonHost",
"clusterid": 1,
"configfile": "/tmp/cmon_1.cnf",
"connected": true,
"distribution":
{
"codename": "trusty",
"name": "ubuntu",
"release": "14.04",
"type": "debian"
},
"hostId": 2,
"hostname": "192.168.1.127",
"hoststatus": "CmonHostOnline",
"ip": "192.168.1.127",
"lastseen": 1501162240,
"logfile": "/tmp/cmon_1.log",
"maintenance_mode_active": false,
"message": "Up and running",
"nodetype": "controller",
"pid": 48111,
"pingstatus": 0,
"pingtime": 0,
"port": 9555,
"role": "controller",
"timestamp": 1501162240,
"unique_id": 2,
"uptime": 17759,
"version": "1.4.3",
"wallclock": 1501162197,
"wallclocktimestamp": 1501162197
} ],
"reply_received": "2017-07-27T13:30:41.871Z",
"request_created": "2017-07-27T13:30:41.866Z",
"request_id": 3,
"request_processed": "2017-07-27T13:30:41.929Z",
"request_status": "Ok",
"request_user_id": 3,
"total": 384
}
getCpuPhysicalInfo
POST /v2/stat
Returns physical CPU hardware information for each node in a cluster. Each entry in the data array represents one physical CPU socket on one host, and includes the CPU model name, core count, clock speed, socket topology, and temperature reading.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The ID of the cluster. |
| Field | Type | Description |
|---|---|---|
data |
array | Array of physical CPU info objects, one per CPU socket per host. |
total |
integer | Total number of CPU socket entries returned. |
Response example
{
"data": [
{
"class_name": "CmonCpuInfo",
"cpucores": 4,
"cpumaxmhz": 2.268e+06,
"cpumhz": 1600,
"cpumodel": "Intel(R) Xeon(R) CPU L5520 @ 2.27GHz",
"cputemp": 55.5,
"hostid": 1,
"physical_cpu_id": 0,
"siblings": 8,
"vendor": "GenuineIntel"
},
{
"class_name": "CmonCpuInfo",
"cpucores": 4,
"cpumaxmhz": 2.268e+06,
"cpumhz": 1600,
"cpumodel": "Intel(R) Xeon(R) CPU L5520 @ 2.27GHz",
"cputemp": 55.5,
"hostid": 1,
"physical_cpu_id": 1,
"siblings": 8,
"vendor": "GenuineIntel"
} ],
"request_created": "2017-07-27T13:43:47.802Z",
"request_id": 3,
"request_processed": "2017-07-27T13:43:47.848Z",
"request_status": "Ok",
"request_user_id": 3,
"total": 2
}
The caller should specify the hostname and cluster id where cmonagent is deployed; Along with limit (maximum number of data to retrieve), origin e.g. "timeline", and begin and end date - range of queries to retrieve.
Example:
curl -k 'https://127.0.0.1:9501/v2/stat' -XPOST -d '{"hostname": "10.10.10.10", "cluster_id": 123, "operation": "gettopqueries", "limit": 10, "begin": "2021-06-01T09:48:31.970Z", "end" : "2021-06-07T09:48:31.970Z", "origin" : "timeline"}' -b cookies.jar
{"hostname": "10.10.10.10", "cluster_id": 123, "operation": "getTopQueries", "limit": 10, "begin": "2021-06-01T09:48:31.970Z", "end" : "2021-06-07T09:48:31.970Z", "origin" : "timeline"}
getTopQueries
POST /v2/stat
Returns top query statistics for a host over a time range.
| Parameter | Type | Required | Description |
|---|---|---|---|
hostname |
string | Required | The database host to query. |
requestType |
string | Required | Request type, e.g. RequestRead. |
requestData |
object | Required | Read parameters object. |
requestData.begin |
string | Required | Start of the time range (ISO 8601). |
requestData.end |
string | Required | End of the time range (ISO 8601). |
requestData.limit |
integer | Required | Maximum number of results to return. |
requestData.mimeType |
string | Required | Response MIME type, e.g. application/json. |
requestData.objectName |
string | Required | Object path, e.g. /topQueryMonitor. |
requestData.origin |
string | Required | Query origin, e.g. timeline. |
{
"operation": "getTopQueries",
"hostname": "dbhost1",
"className": "CmnRequest",
"requestCreated": "2021-06-07T09:41:43.636Z",
"requestType": "RequestRead",
"requestData":
{
"begin": "021-06-01T09:48:31.970Z",
"className": "CmnReadParam",
"end": "021-06-07T09:48:31.970Z",
"limit": 10,
"mimeType": "application/json",
"objectName": "/topQueryMonitor",
"origin": "timeline"
}
}
| Field | Type | Description |
|---|---|---|
result |
object | Result container. |
result.readParam |
object | Echo of the read parameters used. |
result.resultData |
object | SQL result object. |
result.resultData.columnNames |
array | List of column names in the result set. |
result.resultData.records |
array | Array of result rows, each matching the column order. |
result.resultData.created |
string | Timestamp when the result was created. |
result.resultData.databaseName |
string | Database connection name used. |
result.resultData.sqlServerName |
string | SQL server name. |
Response example
{
"className": "CmnReply",
"requestCreated": "2021-06-07T09:51:44.255Z",
"requestProcessed": "2021-06-07T09:51:44.243+00:00",
"requestReceived": "2021-06-07T09:51:44.232+00:00",
"requestStatus": "OK",
"result":
{
"className": "CmnReadResult",
"readParam":
{
"begin": "2021-06-01T09:48:31.970Z",
"className": "CmnReadParam",
"end": "2021-06-07T09:48:31.970Z",
"limit": 1,
"mimeType": "application/json",
"objectName": "/topQueryMonitor",
"origin": "timeline"
},
"resultData":
{
"className": "CmnSqlResult",
"created": "2021-06-07T09:51:44.233+00:00",
"databaseName": ".storageConnection",
"sqlServerName": "localhost",
"columnNames":
[
"created",
"server",
"schema",
"count",
"sumTime",
"sumIoTime",
"shrdBlcks",
"localBlcks",
"tempBlcks"
],
"records":
[
[
"2021-06-07T09:41:12.915Z",
"127.0.0.1",
"sbtest",
1,
773514,
0,
0,
0,
0
]
]
}
}
}
Returns historical database size statistics for a cluster, which returns the growth trend of a database in order to assist with capacity planning.
getDbGrowth
POST /v2/stat
Returns historical database size statistics for a cluster, allowing you to track data growth over time. Results include per-host datadir size samples with timestamps and an optional per-database breakdown. Filter the time window using startdate and enddate, or request a specific day with dayofyear and year.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The ID of the cluster. |
startdate |
string | Optional | Start of the time window to filter results. |
enddate |
string | Optional | End of the time window to filter results. |
dayofyear |
integer | Optional | Specific day of year to request data for. |
year |
integer | Optional | Year corresponding to dayofyear. |
include_tables |
boolean | Optional | Whether to include per-table breakdown. |
db |
string | Optional | Filter results to a specific database name. |
| Field | Type | Description |
|---|---|---|
total |
integer | Total number of records returned. |
data |
array | List of database growth data objects. |
data[].created |
string | Timestamp of the sample. |
data[].database_count |
integer | Number of databases on the host. |
data[].datadir |
string | Path to the data directory. |
data[].free_datadir_size |
integer | Free space in the data directory in bytes. |
data[].hostname |
string | Hostname of the database node. |
data[].port |
integer | Port of the database node. |
data[].total_datadir_size |
integer | Total size of the data directory in bytes. |
data[].year |
integer | Year of the sample. |
data[].yearday |
integer | Day of year of the sample. |
data[].dbs |
array | Per-database breakdown (if requested). |
Response example
{
"controller_id": "a19271f7-3dd7-4f6b-89a4-7b84b6fb0bf2",
"request_processed": "2021-09-27T18:44:32.327Z",
"request_status": "Ok",
"request_user_id": 3,
"total": 1,
"data":
[
{
"class_name": "CmonDbStats",
"created": "Sep 18 15:13:36",
"database_count": 0,
"datadir": "/var/lib/mysql/",
"free_datadir_size": 406810349568,
"hostname": "10.63.228.75",
"port": 3306,
"total_datadir_size": 458595631104,
"year": 2021,
"yearday": 261,
"dbs": []
}
],
"debug_messages":
[
"RPC V2 authenticated user is 'admin'."
]
}
prometheus
POST /v2/stat
The following URL path (/v2/stat/prometheus) will be proxied to the prometheus daemon, you have to pass additional URI paths like /query.
Mandatory argument: cluster_id or cluster_name to identify the cluster.
The caller could specify/select here a Prometheus monitor instance to be used for processing the query, if not specified the code will takes the first Online CmonPrometheusHost instance to process the query.
Note
Only the following arguments will be sent to Prometheus: "query", "time", "timeout", "start", "end", "step", "match[]"
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The ID of the cluster (or use cluster_name). |
cluster_name |
string | Optional | The name of the cluster (alternative to cluster_id). |
queries |
array | Optional | Array of query objects with query and step fields. |
start |
integer | Optional | Start of the time range (Unix epoch). |
end |
integer | Optional | End of the time range (Unix epoch). |
step |
integer | Optional | Step interval in seconds. |
returnfrom |
integer | Optional | Offset for result pagination. |
| Field | Type | Description |
|---|---|---|
total |
integer | Total number of results returned. |
data |
array | Array of Prometheus response objects. |
Response example
{
"controller_id": "7f399ff3-7484-4a93-a47a-a5c0bba42fca",
"request_processed": "2021-05-27T09:51:45.311Z",
"request_status": "Ok",
"request_user_id": 6,
"total": 1,
"data":
[
{"status":"success","data":{"resultType":"vector","result":[{"metric":{"__name__":"mysql_global_status_wsrep_cert_deps_distance","instance":"10.117.12.165:9104","job":"mysqld","monitors":"10.117.12.165:3306"},"value":[1622109105.311,"0"]}]}}
],
"debug_messages":
[
"RPC V2 authenticated user is 'kedz'."
]
}
qm_topqueries
POST /v2/stat
Returns the top queries captured by the Query Monitor for a cluster, ranked by total execution time. Supports filtering by username and db_name, and pagination via limit and offset. Pass -1 for limit or offset to return all results without pagination.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The ID of the cluster. |
limit |
integer | Required | Maximum number of results; pass -1 for all. |
offset |
integer | Required | Pagination offset; pass -1 for all. |
username |
string | Optional | Filter results to a specific database user. |
db_name |
string | Optional | Filter results to a specific database name. |
| Field | Type | Description |
|---|---|---|
total |
integer | Total number of query records returned. |
available_databases |
array | List of database names available for filtering. |
available_users |
array | List of usernames available for filtering. |
data |
object | Container for query results. |
data.total_query_exec_time_us |
integer | Total execution time in microseconds across all queries. |
data.queries |
array | List of top query records. |
Response example
{
"controller_id": "7f399ff3-7484-4a93-a47a-a5c0bba42fca",
"is_superuser": true,
"request_processed": "2022-12-05T14:48:48.548Z",
"request_status": "Ok",
"total": 2,
"available_databases": ["aaa", "bbb"],
"available_users": ["root", "admin"],
"controllers": {},
"data": {
"total_query_exec_time_us": 3587694,
"queries": [
{
"class_name": "CmonQueryMonRecord",
"avg_query_time": 620268,
"canonical": "COMMIT",
"command": "",
"count": 3,
"db": "dcps",
"host": "localhost",
"host_id": 1101,
"hostid": 1101,
"info": "COMMIT",
"last_seen": 1634133907,
"lock_time": 0,
"max_query_time": 685060,
"min_query_time": 0,
"query_id": 10201897797591768868,
"query_time": 685060,
"rows_examined": 0,
"rows_sent": 0,
"state": "",
"stddev": 48187,
"sum_created_tmp_disk_tables": 0,
"sum_created_tmp_tables": 0,
"sum_lock_time": 0,
"sum_no_good_index_used": 0,
"sum_no_index_used": 0,
"sum_query_time": 1860804,
"sum_rows_examined": 0,
"sum_rows_sent": 0,
"user": "cmon[cmon]",
"variance": 2322006804
},
{
"class_name": "CmonQueryMonRecord",
"avg_query_time": 575630,
"canonical": "UPDATE `dcps`.`cake_sessions` SET `id` = ?, `data` = ?, `expires` = ? ",
"command": "",
"count": 3,
"db": "dcps",
"host": "localhost",
"host_id": 1101,
"hostid": 1101,
"info": "UPDATE `dcps`.`cake_sessions` SET `id` = 'mqivh99fpnav209eomfouo4mi1', `data`",
"last_seen": 1634133910,
"lock_time": 160,
"max_query_time": 602311,
"min_query_time": 0,
"query_id": 9449288033917105119,
"query_time": 602311,
"rows_examined": 1,
"rows_sent": 0,
"state": "",
"stddev": 10766,
"sum_created_tmp_disk_tables": 0,
"sum_created_tmp_tables": 0,
"sum_lock_time": 160,
"sum_no_good_index_used": 0,
"sum_no_index_used": 0,
"sum_query_time": 1726890,
"sum_rows_examined": 2,
"sum_rows_sent": 0,
"user": "cmon[cmon]",
"variance": 115915538
}
]
}
}
qm_queryoutliers
POST /v2/stat
Returns individual query executions that exceeded the outlier threshold configured in the Query Monitor. Filter results by time range using starttime and endttime (Unix epoch timestamps), and paginate using limit and offset.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The ID of the cluster. |
starttime |
integer | Optional | Start of the time range (Unix epoch timestamp). |
endttime |
integer | Optional | End of the time range (Unix epoch timestamp). |
limit |
integer | Required | Maximum number of results; pass -1 for all. |
offset |
integer | Required | Pagination offset; pass -1 for all. |
| Field | Type | Description |
|---|---|---|
total |
integer | Total number of outlier query records returned. |
data |
object | Container for query results. |
data.queries |
array | List of outlier query records. |
qm_purge
POST /v2/stat
Purges all slow-query data collected by the Query Monitor for a cluster. This clears the accumulated query history. Use with caution — the data cannot be recovered after purging.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The ID of the cluster whose query monitor data should be purged. |
qm_killprocess
POST /v2/stat
Terminates a specific database backend process identified by its pid on the node given by host_port.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The ID of the cluster. |
pid |
integer | Required | Process ID of the database backend process to terminate. |
host_port |
array | Required | Array containing the host:port string of the target node. |
qm_processes
POST /v2/stat
Returns the list of currently active database backend processes for a cluster as seen by the Query Monitor. Supports pagination via limit and offset.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The ID of the cluster. |
limit |
integer | Required | Maximum number of results to return. |
offset |
integer | Required | Pagination offset. |
| Field | Type | Description |
|---|---|---|
total |
integer | Total number of active processes. |
data |
array | List of database backend process objects. |
data[].appName |
string | Application name connected to the backend. |
data[].backendPid |
integer | Backend process ID. |
data[].backendStart |
string | Timestamp when the backend started. |
data[].client |
string | Client address and port. |
data[].databaseName |
string | Name of the database the backend is connected to. |
data[].elapsedTime |
string | Elapsed time since the current query started. |
data[].hostId |
integer | Internal host ID of the node. |
data[].hostname |
string | Hostname of the node. |
data[].node |
string | Node address in host:port format. |
data[].port |
integer | Port of the node. |
data[].query |
string | Currently executing query text. |
data[].queryStart |
string | Timestamp when the current query started. |
data[].reportTs |
integer | Unix timestamp of the report. |
data[].state |
string | Backend state. |
data[].userName |
string | Database user name. |
data[].waiting |
string | Lock or wait condition the backend is waiting on. |
data[].xactStart |
string | Timestamp when the current transaction started. |
Response example
{
"controller_id": "7f399ff3-7484-4a93-a47a-a5c0bba42fca",
"is_superuser": true,
"request_processed": "2022-12-05T14:37:36.259Z",
"request_status": "Ok",
"total": 6,
"controllers": { },
"data":
[
{
"class_name": "CmonPostgreSqlDbProcess",
"appName": "",
"backendPid": 440,
"backendStart": "2022-11-17 15:22:04.460071+01",
"client": "localhost:0",
"databaseName": "",
"elapsedTime": "",
"hostId": 7006,
"hostname": "10.228.47.220",
"node": "10.228.47.220:5432",
"port": 5432,
"query": "",
"queryStart": "",
"reportTs": 1670251052,
"state": "",
"userName": "postgres",
"waiting": "LogicalLauncherMain",
"xactStart": ""
}
]
}
gettxdeadlock
POST /v2/stat
Returns recent transaction deadlock events detected across the cluster nodes. Each entry describes the SQL statement involved, the host and instance where the deadlock occurred, and the IDs of the conflicting transactions.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The ID of the cluster. |
limit |
integer | Required | Maximum number of results to return. |
offset |
integer | Required | Pagination offset. |
| Field | Type | Description |
|---|---|---|
total |
integer | Total number of deadlock records returned. |
data |
array | List of deadlock event objects. |
data[].blocked_by_trx_id |
string | Transaction ID that blocked this transaction. |
data[].db |
string | Database name where the deadlock occurred. |
data[].duration |
string | Duration of the transaction in seconds. |
data[].host |
string | Host where the deadlock was detected. |
data[].hostId |
integer | Internal host ID of the node. |
data[].info |
string | SQL statement involved in the deadlock. |
data[].innodb_trx_id |
string | InnoDB transaction ID. |
data[].instance |
string | Node instance in host:port format. |
data[].internal_trx_id |
string | Internal transaction ID. |
data[].lastseen |
integer | Unix timestamp when the deadlock was last seen. |
data[].message |
string | Deadlock message. |
data[].mysql_trx_id |
string | MySQL transaction ID. |
data[].port |
integer | Port of the node. |
data[].sql |
string | SQL statement that caused the deadlock. |
data[].state |
string | Transaction state at the time of the deadlock. |
data[].user |
string | Database user that executed the statement. |
Response example
{
"controller_id": "7f399ff3-7484-4a93-a47a-a5c0bba42fca",
"is_superuser": true,
"request_processed": "2022-12-05T14:37:36.259Z",
"request_status": "Ok",
"total": 6,
"controllers": { },
"data": [
{
"blocked_by_trx_id": "",
"db": "classicmodels",
"duration": "45",
"host": "localhost",
"hostId": 2,
"info": "DELETE FROM t WHERE i = 1",
"innodb_trx_id": "",
"instance": "10.0.8.12:3306",
"internal_trx_id": "",
"lastseen": 1696620029,
"message": "DELETE FROM t WHERE i = 1",
"mysql_trx_id": "23",
"port": 3306,
"sql": "DELETE FROM t WHERE i = 1",
"state": "updating",
"user": "root"
}
]
}
nodevariables
POST /v2/stat
Returns the current runtime variables for each node in a cluster (equivalent to SHOW VARIABLES for MySQL/MariaDB nodes). Nodes that have not yet reported their variables appear in the list with a null report_ts.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The ID of the cluster. |
| Field | Type | Description |
|---|---|---|
total |
integer | Total number of node entries returned. |
data |
array | List of per-node variable objects. |
data[].hostId |
integer | Internal host ID of the node. |
data[].hostname |
string | Hostname of the node. |
data[].port |
integer | Port of the node. |
data[].report_ts |
integer | Unix timestamp of the last variable report, or null if not yet reported. |
data[].unique_id |
integer | Unique identifier for the node entry. |
data[].variables |
object | Key-value map of runtime variable names and their current values (present when variables have been reported). |
Response example
{
"controller_id": "42e4370a-cae2-4b51-aa29-63d7fbfeacb2",
"request_processed": "2023-10-16T15:56:58.857Z",
"request_status": "Ok",
"request_user_id": 5,
"total": 14,
"data":
[
{
"hostId": 2611,
"hostname": "10.238.5.169",
"port": 27017,
"report_ts": null,
"unique_id": 1251
},
{
"hostId": 2612,
"hostname": "10.238.5.25",
"port": 27017,
"report_ts": null,
"unique_id": 1252
},
{
"hostId": 2613,
"hostname": "10.238.5.5",
"port": 27017,
"report_ts": null,
"unique_id": 1253
},
{
"hostId": 2675,
"hostname": "10.238.5.17",
"port": 3306,
"report_ts": 1697471809,
"unique_id": 1275,
"variables":
{
"allow_suspicious_udfs": "OFF",
"alter_algorithm": "DEFAULT",
"analyze_sample_percentage": "100.000000",
".......": "........",
".......": "........",
"wsrep_trx_fragment_size": "0",
"wsrep_trx_fragment_unit": "bytes"
}
},
{
"hostId": 2676,
"hostname": "10.238.5.112",
"port": 3306,
"report_ts": 1697471809,
"unique_id": 1276,
"variables":
{
"allow_suspicious_udfs": "OFF",
"alter_algorithm": "DEFAULT",
"analyze_sample_percentage": "100.000000",
".......": "........",
".......": "........",
"wsrep_trx_fragment_size": "0",
"wsrep_trx_fragment_unit": "bytes"
}
},
{
"hostId": 2677,
"hostname": "10.238.5.23",
"port": 3306,
"report_ts": 1697471809,
"unique_id": 1277,
"variables":
{
"allow_suspicious_udfs": "OFF",
"alter_algorithm": "DEFAULT",
"analyze_sample_percentage": "100.000000",
".......": "........",
".......": "........",
"wsrep_trx_fragment_size": "0",
"wsrep_trx_fragment_unit": "bytes"
}
}
],
"debug_messages":
[
"RPC V2 authenticated user is 's9s'."
]
}
getdbstatus
POST /v2/stat
Returns the current runtime status variables for each node in a cluster (equivalent to SHOW STATUS for MySQL/MariaDB nodes). Useful for monitoring engine-level counters, replication state, and cache hit rates.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_id |
integer | Required | The ID of the cluster. |
| Field | Type | Description |
|---|---|---|
total |
integer | Total number of node entries returned. |
data |
array | List of per-node status objects. |
data[].hostId |
integer | Internal host ID of the node. |
data[].hostname |
string | Hostname of the node. |
data[].statuses |
object | Key-value map of status variable names and their current values, plus a report_ts timestamp field. |
Response example
{
"controller_id": "42e4370a-cae2-4b51-aa29-63d7fbfeacb2",
"request_processed": "2023-10-16T15:57:20.493Z",
"request_status": "Ok",
"request_user_id": 5,
"total": 3,
"data":
[
{
"hostId": 2675,
"hostname": "10.238.5.17",
"statuses":
{
"class_name": "CmonSqlVariables",
"ACL_DATABASE_GRANTS": "2",
".......": "........",
".......": "........",
"WSREP_LOCAL_INDEX": "18446744073709551615",
"report_ts": 1697471840
}
},
{
"hostId": 2676,
"hostname": "10.238.5.112",
"statuses":
{
"class_name": "CmonSqlVariables",
"ACL_DATABASE_GRANTS": "2",
".......": "........",
".......": "........",
"WSREP_LOCAL_INDEX": "18446744073709551615",
"report_ts": 1697471840
}
},
{
"hostId": 2677,
"hostname": "10.238.5.23",
"statuses":
{
"class_name": "CmonSqlVariables",
"ACL_DATABASE_GRANTS": "2",
".......": "........",
".......": "........",
"WSREP_LOCAL_INDEX": "18446744073709551615",
"report_ts": 1697471840
}
}
],
"debug_messages":
[
"RPC V2 authenticated user is 's9s'."
]
}
CMON Directory Tree
The /v2/tree path is for managing objects in the CMON Directory Tree.
| Operation | Description |
|---|---|
| getTree | Get the CDT (CMON Directory Tree) or a sub-tree. |
| move | Move an object into a new location in the tree. |
| rename | Change the name of a CDT entry. |
| getAcl | Get the ACL of an object from the CMON Directory Tree. |
| cat | Read the content of a CDT file. |
| getObject | Get an object using its full path as a reference. |
| addAcl | Add an ACL entry to an object. |
| removeAcl | Remove an ACL entry from the ACL of an object. |
| checkAccess | Check if the authenticated user has access to a given object. |
| chown | Change the ownership of object(s). |
| mkdir | Create folders in the CMON Directory Tree. |
| rmdir | Remove empty folders from the CMON Directory Tree. |
| mkfile | Create a file type CDT entry. |
| setContent | Change the content string of a CDT entry. |
| delete | Delete an object from the tree. |
getTree
POST /v2/imperative
This call can be used to get the CDT (CMON Directory Tree).
| Parameter | Type | Required | Description |
|---|---|---|---|
path |
string | Optional | The path of the sub-tree to get. This is not mandatory, if it is not provided the entire tree will be returned (or at least the part that the user allowed to see). |
| Field | Type | Description |
|---|---|---|
cdt |
object | The CMON Directory Tree organized into a tree of objects. This is either the root node of the tree or the node representing the path that was requested. |
Response example
{
"cdt":
{
"item_acl": "user::rwx,group::rw-,other::---",
"item_name": "galera_001",
"item_path": "/",
"item_type": "Cluster",
"object_id": 1,
"owner_group_id": 2,
"owner_group_name": "users",
"owner_user_id": 3,
"owner_user_name": "pipas",
"sub_items": [
{
"item_acl": "user::rwx,group::rw-,other::---",
"item_name": "192.168.1.212:3306",
"item_path": "/galera_001",
"item_type": "Node",
"object_id": 2,
"owner_group_id": 1,
"owner_group_name": "admins",
"owner_user_id": 1,
"owner_user_name": "system"
},
{
"item_acl": "user::rwx,group::rw-,other::---",
"item_name": "192.168.1.127:9555",
"item_path": "/galera_001",
"item_spec": "controller",
"item_type": "Node",
"object_id": 3,
"owner_group_id": 1,
"owner_group_name": "admins",
"owner_user_id": 1,
"owner_user_name": "system"
} ]
},
"request_created": "2017-10-03T07:12:13.682Z",
"request_id": 3,
"request_processed": "2017-10-03T07:12:13.750Z",
"request_status": "Ok",
"request_user_id": 3
}
move
POST /v2/imperative
This call can be used to move an object into a new location in the tree.
| Parameter | Type | Required | Description |
|---|---|---|---|
source_path |
string | Required | The full path of the object to move. |
target_path |
string | Required | The new location where the object will be moved. |
rename
POST /v2/imperative
Changes the name of a CDT entry.
So for example if one wants to change the name of a user group one needs to get the group. Then the "cdt_path" and the "group_name" property of the group has to be accessed to build the path of the group object and the "rename" request has to be sent.
getAcl
POST /v2/imperative
This call can be used to get the ACL of an object from the CMON Directory Tree.
| Parameter | Type | Required | Description |
|---|---|---|---|
path |
string | Required | The full path of the object. |
| Field | Type | Description |
|---|---|---|
acl |
string | The ACL for the requested object in string format. |
object_name |
string | The name of the object. |
object_path |
string | The path in the CDT where the object can be found. |
owner_group_name |
string | The group name of the group owner for the object. |
owner_user_name |
string | The user name of the owner of the group. |
Response example
{
"acl": "user::rwx,group::rw-,other::---",
"object_name": "bestw_controller",
"object_path": "/core1/containers",
"owner_group_name": "users",
"owner_user_name": "pipas",
"request_created": "2017-10-03T06:39:59.289Z",
"request_id": 3,
"request_processed": "2017-10-03T06:40:02.358Z",
"request_status": "Ok",
"request_user_id": 3
}
cat
POST /v2/imperative
This call reads the content of a CDT file.
getObject
POST /v2/imperative
This call can be used to get the object using its full path as a reference.
Response example
{
"object":
{
"acl": "user::r--,group::---,other::---",
"cdt_path": "/.runtime",
"class_name": "CmonCdtEntry",
"content": " cluster_manager_instance : 0x7fad58001380\n\n",
"dirty": false,
"major_device_number": 10,
"minor_device_number": 1,
"name": "cluster_manager",
"owner_group_id": 1,
"owner_group_name": "admins",
"owner_user_id": 1,
"owner_user_name": "system",
"type": "CmonCdtFile"
},
"reply_received": "2018-11-29T09:09:22.841Z",
"request_created": "2018-11-29T09:09:22.836Z",
"request_id": 2,
"request_processed": "2018-11-29T09:09:22.864Z",
"request_status": "Ok",
"request_user_id": 1
}
addAcl
POST /v2/imperative
This call can be used to add an ACL entry to an object. Please note that if the given entry is already added to the ACL it will be overwritten. This is the intuitive thing to do.
| Parameter | Type | Required | Description |
|---|---|---|---|
acl |
string | Required | The ACL to add. This should be the text format of one ACL entry. |
path |
string | Required | The full path of the object to change. |
| Field | Type | Description |
|---|---|---|
acl |
string | The ACL of the object after the change. |
object_name |
string | The name of the object. |
object_path |
string | The path in the CDT where the object can be found. |
owner_group_name |
string | The group name of the group owner for the object. |
owner_user_name |
string | The user name of the owner of the group. |
Response example
{
"acl": "user::rwx,user:nobody:r--,group::rw-,other::---",
"object_name": "bestw_controller",
"object_path": "/core1/containers",
"owner_group_name": "users",
"owner_user_name": "pipas",
"request_created": "2017-10-03T06:46:42.233Z",
"request_id": 3,
"request_processed": "2017-10-03T06:46:42.322Z",
"request_status": "Ok",
"request_user_id": 3
}
removeAcl
POST /v2/imperative
This call can be used to remove an ACL entry from the ACL of an object. Currently only one single ACL entry can be removed at a a time.
Please note that certain ACL entries are mandatory and can not be removed only changed. If the call tries to remove such a mandatory entry an error will be reported.
Here is a reply notifying the caller about the successful removal of the entry.
Response example
{
"acl": "user::rwx,group::rwx,other::rwx",
"object_name": "",
"object_path": "/",
"owner_group_name": "admins",
"owner_user_name": "system",
"request_created": "2017-10-04T15:07:50.427Z",
"request_id": 3,
"request_processed": "2017-10-04T15:07:50.504Z",
"request_status": "Ok",
"request_user_id": 3
}
checkAccess
POST /v2/imperative
This RPC call can be used to check if the authenticated user has access to the given object.
The reply will simply be an "Ok" reply if the user has the access or an "AccessDenied" if the the user is not provided with the given access right(s). Other errors also might be possible, for example the request might be mallformad of the object might be missing.
chown
POST /v2/imperative
Changes the ownership of object(s).
| Parameter | Type | Required | Description |
|---|---|---|---|
owner_group_name |
string | Required | The group name of the new group owner. One of the owner_user_name and owner_group_name is mandatory. |
owner_user_name |
string | Required | The username of the new owner. One of the owner_user_name and owner_group_name is mandatory. |
path |
string | Required | The full path of the object to change. |
recursive |
boolean | Optional | If this propertyis true all the subitems of the tree will be changed too. If any of the changes fail with access denied no change will be done on any of the tree items. |
The reply to a successful chown request looks like this.
Response example
{
"acl": "user::rwx,group::rwx,other::rwx",
"object_name": "containers",
"object_path": "/core2/",
"owner_group_name": "users",
"owner_user_name": "pipas",
"request_created": "2017-10-05T07:51:05.133Z",
"request_id": 3,
"request_processed": "2017-10-05T07:51:05.208Z",
"request_status": "Ok",
"request_user_id": 3
}
mkdir
POST /v2/imperative
This call is for creating folders in the CMON Directory Tree.
| Parameter | Type | Required | Description |
|---|---|---|---|
path |
string | Required | The full path of the folder to create. |
rmdir
POST /v2/imperative
This call is for removing empty folders. This call will be returning with an error if the object at the given path is not an empty folder. To remove objects other than a folder please consider using the delete call. The delete call is also able to remove empty folders.
| Parameter | Type | Required | Description |
|---|---|---|---|
path |
string | Required | The full path of the folder to remove. |
mkfile
POST /v2/imperative
This call can be used to create a file type CDT entry.
setContent
POST /v2/imperative
This call can be used to change the content string of a CDT entry. Currently only the file type CDT entries can have contents handled in this call.
delete
POST /v2/imperative
This call is for deleting object from the tree. Once an object is deleted, it is deleted for good. If for example one performs a delete operation on a container it is deleted from the server. It is gone, it is nonexisting, it is a late container.
| Parameter | Type | Required | Description |
|---|---|---|---|
path |
string | Required | The full path of the object to delete. |
User Database manipulation
The /v2/users path is to manipulate Cmon Users, users that are maintained by the Cmon controller. These users are used while setting up encrypted communication for the RPC v2 interface, so without this interface it is not possible to use the RPC v2 itself.
| Operation | Description |
|---|---|
| createUser | Create a new Cmon user account. |
| whoAmI | Return information about the currently authenticated user. |
| getUsers | Read the user database managed by the controller. |
| setUser | Modify certain properties of an existing Cmon user. |
| disable | Set the disabled flag for a user to prevent login. |
| deleteUser | Permanently delete an existing Cmon user. |
| enable | Clear the disabled flag so a user can log in again. |
| changePassword | Change the password of an existing user. |
| getKeys | Return the public keys registered for a user. |
| addKey | Add a new public key for a user. |
| deleteKey | Delete a public key by its name. |
createUser
POST /v2/users
The createUser RPC call can be used to create a new Cmon User.
In the call both the user's password and public kay can be specified so that the user can log in after the account is created.
| Parameter | Type | Required | Description |
|---|---|---|---|
create_group |
boolean | Optional | If the groups of the user does not exist the controller will try to create the group on the fly. If the group could be created the user will be added to the group, if not the request will be failed. |
new_password |
string | Optional | The plain text password that the user can actually use to log in. This is not mandatory, if the new password is not provided no password will be set and the user won't be able to log in with a password until a valid password is set. Please note that the new_password is not a property of the cmonuser. The plain password will not be stored, only the encoded version of the password is a property of the CmonUser object, but even that is a hidden property, not seen from outside of the controller code. |
user |
object | Required | The user object to create. |
user.class_name |
string | Required | Must be "CmonUser". |
user.groups |
array | Optional | The user groups the user belongs to. This is not a mandatory argument, if the create_group is set to true, but no group is provided the controller will try to create a group that has the same name as the user and add the new user to this new group. It is important to note that every user must belong to at least one group the so called "primary group". If the user belongs to multiple groups the first group is the primary group. Theoretically this call can accept multiple groups, but this feature is not yet implemented. |
user.public_keys |
array | Optional | Zero or more keys the user can use to log in. This is not a mandatory argument, if no key is provided the user will not able to log in with a key, but might still be able to use the system with a password. The public_keys is actually a property of the cmonuser, but it is a hidden property, not readable only using special calls like the getKeys call. |
user.public_keys[].key |
string | Optional | The actual public key string. |
user.public_keys[].name |
string | Optional | The name of the key. The name is just a human readable string the user provided as a reminder. |
user.user_name |
string | Required | The username for the new user. |
{
"create_group": true,
"new_password": "p",
"operation": "createUser",
"user":
{
"class_name": "CmonUser",
"groups": [
{
"class_name": "CmonGroup",
"group_name": "testgroup"
} ],
"public_keys": [
{
"key": "-----BEGIN RSA PUBLIC KEY-----\nMIIBCgKCAQEAxupGXCUCtoytVYBD1NKeAB+oWauxJzGYvunMGnVIqhjF/o8gokNf\nV0mcad022SJ/Mng/PICKKrUtdQoQ+blCTRpOJw44nA/NIfp8mWkeCNB9BjaXtMQz\nxRHMo3Cw6mpPbxgzpTLvpiVyn7i3RK+k97oSk3VDlWOGjmchaBrGqVD77BuzbUQW\nZRkkgHF70b7/8pOESWgo7YGlTE/qbQ1VddGaIatnpm/9cyAj3TJRR3OaUm56d8sm\n48b0IGQkESxjtdHuLcDSo5/Fp0DhAFkabWMRU8d3pBEIxpcOWOGjps50Au4y/46S\np9x0vnW6lLEAVHfWoRqqN2S21yJZAHYDFwIDAQAB\n-----END RSA PUBLIC KEY-----\n",
"name": "No Name"
} ],
"user_name": "pipas"
}
}
| Field | Type | Description |
|---|---|---|
user |
object | All the details of the user that has been created. |
user.user_id |
integer | The user ID of the user that just has been created. The only inmutable property of the user that can not be ever changed. |
Please note that there is no password or public key in the reply. We handle those as a secret.
Here is an example showing a stored user with the internal properties that are not visible from the outside (but might be set like the "password_encrypted"), for example:
{
"class_name": "CmonUser",
"email_address": "[email protected]",
"first_name": "Laszlo",
"groups": [
{
"class_name": "CmonGroup",
"group_id": 4,
"group_name": "testgroup"
} ],
"last_login": "2017-09-06T08:45:55.588Z",
"last_name": "Pere",
"password_encrypted": "3babe525f514e13a421b1e2870824d8d3e08531c5db461b088aa8c4298a1eca8",
"password_format": "sha256",
"password_salt": "7cc254f8-1be8-e78d-765a-2e63339fc99a",
"public_keys": [
{
"key": "-----BEGIN RSA PUBLIC KEY-----\nMIIBCgKCAQEAxupGXCUCtoytVYBD1NKeAB+oWauxJzGYvunMGnVIqhjF/o8gokNf\nV0mcad022SJ/Mng/PICKKrUtdQoQ+blCTRpOJw44nA/NIfp8mWkeCNB9BjaXtMQz\nxRHMo3Cw6mpPbxgzpTLvpiVyn7i3RK+k97oSk3VDlWOGjmchaBrGqVD77BuzbUQW\nZRkkgHF70b7/8pOESWgo7YGlTE/qbQ1VddGaIatnpm/9cyAj3TJRR3OaUm56d8sm\n48b0IGQkESxjtdHuLcDSo5/Fp0DhAFkabWMRU8d3pBEIxpcOWOGjps50Au4y/46S\np9x0vnW6lLEAVHfWoRqqN2S21yJZAHYDFwIDAQAB\n-----END RSA PUBLIC KEY-----\n",
"name": "No Name"
} ],
"user_id": 3,
"user_name": "pipas"
}
It is also important to know what the backend checks to see if the authenticated user actually has the proper privileges to create the new user in the given situation.
-
The controller checks if the
/.runtime/user_managerentry exists and the authenticated user has execute access on it. If not the request will be rejected. -
The backend checks if a user with the same name already exists. If so the creation of the user with the same name will be denied.
-
The controller checks if the passed new user has a group set. If so and the group does not exist the controller checks if the request asks for a new group to be created. If so the controller tries to create a new group.
-
Then the controller checks if the authenticated user has write access on the group. If the group was just created the authenticated user will be able to write it, but if it is pre-existing the authenticated user might not have write access to it. If this happens the request will be rejected.
-
Then the controller checks if there is already an object (not a cmon user) at the same path and name. If so the request will be rejected.
-
Then the new user is saved and an OK reply is sent.
Response example
{
"request_created": "2017-07-04T12:49:50.896Z",
"request_id": 2,
"request_processed": "2017-07-04T12:49:50.954Z",
"request_status": "Ok",
"request_user_id": 1,
"user":
{
"class_name": "CmonUser",
"email_address": "[email protected]",
"groups": [
{
"class_name": "CmonGroup",
"group_id": 6,
"group_name": "testgroup"
} ],
"user_id": 11,
"user_name": "rpc_user"
}
}
whoAmI
POST /v2/users
This call returns information about the authenticated user. The client application can send this call periodically to update the information about the user and the privileges the user has.
| Parameter | Type | Required | Description |
|---|---|---|---|
with_extended_privileges |
boolean | Optional | If the request has this field set to true the reply will contain some extra information about the user's rigts. |
| Field | Type | Description |
|---|---|---|
user |
object | The user object with all details about the authenticated user. |
user_extended_privileges |
object | Convenience check that returns information about the effective privileges of several CDT entries. These privileges are not the property of the user but are controlled by the access rights of other CDT entries on the controller. |
user_extended_privileges.can_create_clusters |
boolean | Whether the user can create clusters. |
user_extended_privileges.can_execute_jobs |
boolean | Whether the user can execute jobs. |
The list of the extended privileges are under construction, the caller may expect more than shown in this example.
Response example
{
"request_created": "2018-12-07T08:51:14.324Z",
"request_id": 3,
"request_processed": "2018-12-07T08:51:14.332Z",
"request_status": "Ok",
"request_user_id": 4,
"user":
{
"acl": "user::rwx,group::r--,other::r--",
"cdt_path": "/",
"class_name": "CmonUser",
"created": "2018-12-07T07:22:49.165Z",
"disabled": false,
"email_address": "[email protected]",
"first_name": "Laszlo",
"groups": [
{
"acl": "user::rwx,group::rw-,other::---",
"cdt_path": "/groups",
"class_name": "CmonGroup",
"created": "2018-12-07T07:22:49.153Z",
"group_id": 4,
"group_name": "testgroup",
"owner_group_id": 1,
"owner_group_name": "admins",
"owner_user_id": 1,
"owner_user_name": "system"
} ],
"last_failed_login": "",
"last_login": "2018-12-07T08:51:14.317Z",
"last_name": "Pere",
"n_failed_logins": 0,
"owner_group_id": 1,
"owner_group_name": "admins",
"owner_user_id": 4,
"owner_user_name": "pipas",
"suspended": false,
"timezone":
{
"class_name": "CmonTimeZone",
"name": "CET",
"offset": -3600,
"has_dst_rules": true
},
"user_id": 4,
"user_name": "pipas"
},
"user_extended_privileges":
{
"can_create_clusters": true,
"can_execute_jobs": true,
"class_name": "CmonExtendedPrivileges"
}
}
getUsers
POST /v2/users
A call to read the user database.
| Parameter | Type | Required | Description |
|---|---|---|---|
with_tags |
array | Optional | The request may contain this field to limit the list of the returned users to those that have at least one of the tags passed here. |
without_tags |
array | Optional | The request may contain this field to limit the list of the returned users to those that has none of the tags passed here. |
| Field | Type | Description |
|---|---|---|
total |
integer | The total number of users managed by the controller. |
users |
array | A list of CmonUser class objects. To get more information about the user objects please check the cmonuser and cmongroup sections. |
Response example
{
"request_created": "2020-05-13T06:16:11.197Z",
"request_id": 3,
"request_processed": "2020-05-13T06:16:11.216Z",
"request_status": "Ok",
"request_user_id": 4,
"total": 16,
"debug_messages":
[
"RPC V2 authenticated user is 'pipas'."
],
"users":
[
{
"class_name": "CmonUser",
"cdt_path": "/",
"owner_user_id": 4,
"owner_user_name": "pipas",
"owner_group_id": 1,
"owner_group_name": "admins",
"acl": "user::rwx,group::r--,other::r--",
"tags":
[
"testUser"
],
"created": "2020-05-13T06:08:24.564Z",
"disabled": false,
"email_address": "[email protected]",
"first_name": "Laszlo",
"last_failed_login": "",
"last_login": "2020-05-13T06:16:11.186Z",
"last_name": "Pere",
"n_failed_logins": 0,
"origin": "CmonDb",
"suspended": false,
"user_id": 4,
"user_name": "pipas",
"groups":
[
{
"class_name": "CmonGroup",
"cdt_path": "/groups",
"owner_user_id": 1,
"owner_user_name": "system",
"owner_group_id": 1,
"owner_group_name": "admins",
"acl": "user::rwx,group::rwx,other::---",
"created": "2020-05-13T06:08:13.521Z",
"group_id": 1,
"group_name": "admins"
}
],
"timezone":
{
"class_name": "CmonTimeZone",
"name": "Central European Time",
"abbreviation": "CET",
"offset": -3600,
"has_dst_rules": true
}
}
]
}
setUser
POST /v2/users
The setUser call can be used to modify certain properties of existing Cmon users.
Here is an example showing how to modify the email address of a user.
The reply to this request will contain the request status and, if an error occurred, the error string. If the request was successfully processed the controller will send back the user object with all of its properties after the change.
| Parameter | Type | Required | Description |
|---|---|---|---|
user |
object | Required | Identifies the user and the properties to change. The "class_name" of this map should be "CmonUser" and the "user_name" should identify an existing user. Any other fields are properties the caller wants to change. Please check out the cmonuser section to see what properties can be changed. |
{
"operation": "setUser",
"request_created": "2017-06-26T07:25:16.198Z",
"request_id": 3,
"user":
{
"class_name": "CmonUser",
"email_address": "[email protected]",
"user_name": "system"
}
}
| Field | Type | Description |
|---|---|---|
user |
object | Shows the properties of the user after the change. |
Response example
{
"request_created": "2017-06-26T07:37:51.522Z",
"request_id": 3,
"request_processed": "2017-06-26T07:37:51.575Z",
"request_status": "Ok",
"request_user_id": 3,
"user":
{
"class_name": "CmonUser",
"email_address": "[email protected]",
"first_name": "System",
"groups": [
{
"class_name": "CmonGroup",
"group_id": 1,
"group_name": "admins"
} ],
"last_name": "User",
"user_id": 1,
"user_name": "system"
}
}
disable
POST /v2/users
This call will set the "disabled" flag for the user and so prevent the user from logging in.
| Parameter | Type | Required | Description |
|---|---|---|---|
user |
object | Required | Identifies the user to disable. Must include class_name of "CmonUser" and user_name. |
The reply contains the user object with the "disabled" flag set to true.
Response example
{
"request_created": "2017-10-30T08:25:15.685Z",
"request_id": 3,
"request_processed": "2017-10-30T08:25:16.535Z",
"request_status": "Ok",
"request_user_id": 4,
"user":
{
"cdt_path": "/",
"class_name": "CmonUser",
"created": "2017-10-27T12:34:47.333Z",
"disabled": true,
"first_name": "Default",
"groups": [
{
"cdt_path": "/groups",
"class_name": "CmonGroup",
"group_id": 3,
"group_name": "nobody"
} ],
"last_failed_login": "",
"last_name": "User",
"n_failed_logins": 0,
"owner_group_id": 1,
"owner_group_name": "admins",
"owner_user_id": 2,
"owner_user_name": "nobody",
"suspended": false,
"user_id": 2,
"user_name": "nobody"
}
}
deleteUser
POST /v2/users
Permanently deletes an existing CMON user. The user to delete is identified by user_name inside the user object. All associated SSH keys, group memberships, and preferences for that user are also removed.
enable
POST /v2/users
This call will clear the "disabled" flag for the user so the user will be able to log in. The "suspended" flag will also be cleared, the failed login counter set to 0 and the date&time of the last failed login gets deleted, so users who are suspended for failed login attempts will also be able to log in.
| Parameter | Type | Required | Description |
|---|---|---|---|
user |
object | Required | Identifies the user to enable. Must include class_name of "CmonUser" and user_name. |
Response example
{
"request_created": "2017-10-30T08:28:29.852Z",
"request_id": 3,
"request_processed": "2017-10-30T08:28:29.912Z",
"request_status": "Ok",
"request_user_id": 4,
"user":
{
"cdt_path": "/",
"class_name": "CmonUser",
"created": "2017-10-27T12:34:47.333Z",
"disabled": false,
"first_name": "Default",
"groups": [
{
"cdt_path": "/groups",
"class_name": "CmonGroup",
"group_id": 3,
"group_name": "nobody"
} ],
"last_failed_login": "",
"last_name": "User",
"n_failed_logins": 0,
"owner_group_id": 1,
"owner_group_name": "admins",
"owner_user_id": 2,
"owner_user_name": "nobody",
"suspended": false,
"user_id": 2,
"user_name": "nobody"
}
}
changePassword
POST /v2/users
This call is of course for changing the password of an existing user.
| Parameter | Type | Required | Description |
|---|---|---|---|
new_password |
string | Required | The new password in plain string format. |
old_password |
string | Optional | The current password in plain format. The user's old password that will be checked using the usually password authentication algorithms. Please note that a superuser can change the passwords for any user without providing the old password, but if the old password is sent it will be checked even if the user that sent it is a superuser. |
user |
object | Required | Identifies the user that should have the new password. |
getKeys
POST /v2/users
A call to return the public keys of a user.
| Parameter | Type | Required | Description |
|---|---|---|---|
user |
object | Required | This identifies the user whose public keys will be returned. Only the class name and the user name needed here. Please note that the controller handles the public keys securely, normal users can not read the public keys of other users. Users can always read their own keys of course. |
| Field | Type | Description |
|---|---|---|
public_keys |
array | Contains the public keys of the user. |
public_keys[].key |
string | The actual key string. |
public_keys[].name |
string | The human readable name of the key, a reminder that the user set when adding the key. |
total |
integer | Shows how many keys has been found. |
user |
object | The user that has these keys. This field is sent back for convenience. |
Response example
{
"public_keys": [
{
"key": "-----BEGIN RSA PUBLIC KEY-----\nMIIBCgKCAQEAxupGXCUCtoytVYBD1NKeAB+oWauxJzGYvunMGnVIqhjF/o8gokNf\nV0mcad022SJ/Mng/PICKKrUtdQoQ+blCTRpOJw44nA/NIfp8mWkeCNB9BjaXtMQz\nxRHMo3Cw6mpPbxgzpTLvpiVyn7i3RK+k97oSk3VDlWOGjmchaBrGqVD77BuzbUQW\nZRkkgHF70b7/8pOESWgo7YGlTE/qbQ1VddGaIatnpm/9cyAj3TJRR3OaUm56d8sm\n48b0IGQkESxjtdHuLcDSo5/Fp0DhAFkabWMRU8d3pBEIxpcOWOGjps50Au4y/46S\np9x0vnW6lLEAVHfWoRqqN2S21yJZAHYDFwIDAQAB\n-----END RSA PUBLIC KEY-----\n",
"name": "Unnamed key"
} ],
"request_created": "2017-07-05T09:23:04.988Z",
"request_id": 2,
"request_processed": "2017-07-05T09:23:05.034Z",
"request_status": "Ok",
"request_user_id": 1,
"total": 1,
"user":
{
"class_name": "CmonUser",
"email_address": "[email protected]",
"first_name": "Laszlo",
"groups": [
{
"class_name": "CmonGroup",
"group_id": 4,
"group_name": "testgroup"
} ],
"last_login": "2017-07-05T09:22:55.587Z",
"last_name": "Pere",
"title": "",
"user_id": 3,
"user_name": "pipas"
}
}
addKey
POST /v2/users
A call to add/register a new public key for a user.
| Parameter | Type | Required | Description |
|---|---|---|---|
public_key |
object | Required | The public key to add. |
user |
object | Required | The user to whom the key will be added. Only the class name and the user name has to be specified here. |
{
"operation": "addKey",
"public_key":
{
"key": "-----BEGIN RSA PUBLIC KEY-----\nMIIBCgKCAQEAr6KS5KsnwVuoOzFGJsF2oPhUokBEEdrcGfVPX5XbdlIn0E/Gn44i\nx4HBt0rDKNe//tbDPBPItqYyBJInKwwaSmT5u68WiD9XKd4faDUImogmV/eVEod2\nMHkcvkg6a9zYDnSVj8QsCJgN865HEsEPgmShw3Kuqhy3c4h33pbvjbzIuX8d6svt\ncGLhMpL9Lia3WEf8ef2yd78rUY6KqNMcUdOyUJU1p0bsLLjXxOcCAArcBk1LbRVL\n0g3uBEYGzuCrx+JARPWu+Oih+z/ad4HC8hXZXW2ESXO769P1rOoWX4CRu/AkamN6\nQNfAM7WOdTgUrv3YXXBOu5oF0aAmEUIUcQIDAQAB\n-----END RSA PUBLIC KEY-----\n",
"name": ""
},
"request_created": "2017-07-05T11:55:57.885Z",
"request_id": 3,
"user":
{
"class_name": "CmonUser",
"user_name": "pipas"
}
}
deleteKey
POST /v2/users
This call can be used to delete a public key by its name. The call looks very similar to the "addKey" call.
| Parameter | Type | Required | Description |
|---|---|---|---|
public_key |
object | Required | Identifies the key to delete by its name. |
public_key.name |
string | Required | The name of the key to delete. |
user |
object | Required | The user from whom the key will be deleted. Only the class name and the user name has to be specified here. |
createGroup
POST /v2/users
Creates a new CMON user group. Groups are used to organise users and manage access control collectively. The group is identified by group_name inside the group object.
| Parameter | Type | Required | Description |
|---|---|---|---|
group |
object | Required | The group object to create. |
group.class_name |
string | Required | Must be CmonGroup. |
group.group_name |
string | Required | The name of the group to create. |
deleteGroup
POST /v2/users
This call is for deleting an existing Cmon Group. Groups can only be deleted if they are empty (no Cmon User is assigned to them) and the authenticateduser has a write access to the actual group itself.
Currently only the group name is used to identify the group that will be deleted.
| Parameter | Type | Required | Description |
|---|---|---|---|
group |
object | Required | The group to delete. |
group.class_name |
string | Required | Must be CmonGroup. |
group.group_name |
string | Required | The name of the group to delete. |
getGroups
POST /v2/users
A call to read the user database. In its basic form the RPC call looks like this:
| Field | Type | Description |
|---|---|---|
groups |
array | The list of user groups the controller has. |
total |
integer | The total number of groups the controller has. |
Response example
{
"groups": [
{
"class_name": "CmonGroup",
"group_id": 1,
"group_name": "admins"
},
{
"class_name": "CmonGroup",
"group_id": 2,
"group_name": "users"
},
. . .
{
"class_name": "CmonGroup",
"group_id": 6,
"group_name": "rpc_group"
} ],
"reply_received": "2017-07-24T08:53:33.498Z",
"request_created": "2017-07-24T08:53:33.493Z",
"request_id": 3,
"request_processed": "2017-07-24T08:53:33.538Z",
"request_status": "Ok",
"request_user_id": 3,
"total": 6
}
addToGroup
POST /v2/users
Adds the user to a new group or moves the user from the current primary group to a new group.
| Parameter | Type | Required | Description |
|---|---|---|---|
group_name |
string | Required | The name of the group to add the user to. |
replace_primary_group |
boolean | Required | If true, the user is moved from their current primary group to the new group. |
user |
object | Required | The user to add to the group. |
user.class_name |
string | Required | Must be CmonUser. |
user.user_name |
string | Required | The name of the user to add. |
| Field | Type | Description |
|---|---|---|
user |
object | All the details of the user that was updated. |
Response example
{
"request_created": "2018-01-12T11:07:48.963Z",
"request_id": 2,
"request_processed": "2018-01-12T11:07:48.984Z",
"request_status": "Ok",
"request_user_id": 1,
"user":
{
"cdt_path": "/",
"class_name": "CmonUser",
"created": "2018-01-12T07:26:13.677Z",
"disabled": false,
"email_address": "[email protected]",
"first_name": "Laszlo",
"groups": [
{
"cdt_path": "/groups",
"class_name": "CmonGroup",
"group_id": 1,
"group_name": "admins"
} ],
"last_failed_login": "",
"last_login": "2018-01-12T10:54:53.222Z",
"last_name": "Pere",
"n_failed_logins": 0,
"owner_group_id": 1,
"owner_group_name": "admins",
"owner_user_id": 3,
"owner_user_name": "pipas",
"suspended": false,
"user_id": 3,
"user_name": "pipas"
}
}
removeFromGroup
POST /v2/users
Removes the user from a group if it is indeed the member of that group. Here is how the rquest should look like:
| Parameter | Type | Required | Description |
|---|---|---|---|
group_name |
string | Required | The name of the group to remove the user from. |
user |
object | Required | The user to remove from the group. |
user.class_name |
string | Required | Must be CmonUser. |
user.user_name |
string | Required | The name of the user to remove. |
| Field | Type | Description |
|---|---|---|
user |
object | All the details of the user after the group removal. |
Response example
{
"request_created": "2018-10-08T06:03:36.983Z",
"request_id": 3,
"request_processed": "2018-10-08T06:03:37.006Z",
"request_status": "Ok",
"request_user_id": 4,
"user":
{
"acl": "user::rwx,user:pipas:rwx,group::r--,other::r--",
"cdt_path": "/",
"class_name": "CmonUser",
"created": "2018-10-05T14:09:14.660Z",
"disabled": false,
"email_address": "[email protected]",
"first_name": "Benjamin",
"groups": [
{
"cdt_path": "/groups",
"class_name": "CmonGroup",
"group_id": 5,
"group_name": "ds9",
"owner_group_id": 1,
"owner_group_name": "admins",
"owner_user_id": 1,
"owner_user_name": "system"
} ],
"last_failed_login": "",
"last_login": "2018-10-05T14:09:18.111Z",
"last_name": "Sisko",
"n_failed_logins": 0,
"owner_group_id": 1,
"owner_group_name": "admins",
"owner_user_id": 5,
"owner_user_name": "sisko",
"suspended": false,
"title": "Captain",
"user_id": 5,
"user_name": "sisko"
}
}
canCreateUser
POST /v2/users
This call can be used to find out if the currently authenticated user is allowed to create a new user. For the user creation the authenticated user must be the superuser or has write access to a user group and a folder.
Please note that the request will be successfull (the request_status will be "Ok") even if the user can not possibly create a new cmon user.
| Field | Type | Description |
|---|---|---|
can_create_user |
boolean | True if the authenticated user has a chance to create a new user. |
folders_available_for_write |
array | The folders that are writable and so can hold a new user. The full path of the folders are enumerated in a list. |
groups_available_for_write |
array | The names of the groups that are writable for the user and so can hold the new user. |
Response example
{
"can_create_user": true,
"folders_available_for_write": [ "/", "/core1/containers" ],
"groups_available_for_write": [ "admins", "users", "nobody" ],
"request_created": "2017-10-19T08:02:53.276Z",
"request_id": 3,
"request_processed": "2017-10-19T08:02:56.341Z",
"request_status": "Ok",
"request_user_id": 4
}
canCreateGroup
POST /v2/users
This call is to decide if the authenticated user is allowed to create user groups.
| Field | Type | Description |
|---|---|---|
can_create_group |
boolean | True if the user is allowed to create cmon user groups. |
folders_available_for_write |
array | The list of folders the user has write access. |
updateUser
POST /v2/users
The updateUser RPC call can be used to update the current logged in user.
In the call you may define a new password as well in the new_password field.
In the call both the user's password and public kay can be specified so that the user can log in after the account is created.
| Parameter | Type | Required | Description |
|---|---|---|---|
new_password |
string | Optional | A new password to set for the user. |
user |
object | Required | The user object with updated fields. |
user.class_name |
string | Required | Must be CmonUser. |
user.user_id |
integer | Required | The ID of the user to update. |
user.first_name |
string | Optional | The user's first name. |
user.last_name |
string | Optional | The user's last name. |
user.email_address |
string | Optional | The user's email address. |
user.user_name |
string | Optional | The user's new username. |
{
"new_password": "p",
"operation": "updateUser",
"user":
{
"class_name": "CmonUser",
"user_id": 1234,
"first_name": "Firstname",
"last_name": "Lastname",
"email_address": "[email protected]",
"user_name": "newusername"
}
}
| Field | Type | Description |
|---|---|---|
user |
object | All the details of the user that has been updated. |
user.user_id |
integer | The user ID of the user that just has been created. The only inmutable property of the user that can not be ever changed. |
Please note that there is no password or public key in the reply. We handle those as a secret.
Response example
{
"request_created": "2017-07-04T12:49:50.896Z",
"request_id": 2,
"request_processed": "2017-07-04T12:49:50.954Z",
"request_status": "Ok",
"request_user_id": 1,
"user":
{
"class_name": "CmonUser",
"email_address": "[email protected]",
"groups": [
{
"class_name": "CmonGroup",
"group_id": 6,
"group_name": "testgroup"
} ],
"user_id": 11,
"user_name": "rpc_user"
}
}
setUserPreferences
POST /v2/users
A call to set the user's preferences.
Possible RPC request command:
To add new preferences:
$ s9s user --cmon-user=s9s --password=***** --preferences --preferences-to-set="key1=value1;key2=value2;key3=value3"
To update existing preferences:
$ s9s user --cmon-user=s9s --password=***** --preferences --preferences-to-set="key2=QWERTY;key3=UIOP"
| Parameter | Type | Required | Description |
|---|---|---|---|
user |
object | Required | The ClusterControl user's data in the request to set his/her properties. |
user.user_name |
string | Required | Must be a name of a valid logged in user. |
user.preferences |
object | Required | The list of one or more user's preferences to store to the DB. |
| Field | Type | Description |
|---|---|---|
user |
object | The ClusterControl user's data, including his/her actual properties. |
user.preferences |
object | The list of all user's preferences stored in the databaseafter the request is completed. |
Response example
{
"controller_id": "b195b016-ed96-49e4-a646-596b52d9d8f3",
"reply_received": "2023-01-25T14:57:37.168Z",
"request_created": "2023-01-25T14:57:37.155Z",
"request_id": 2,
"request_processed": "2023-01-25T14:57:37.167Z",
"request_status": "Ok",
"request_user_id": 3,
"debug_messages": [ "RPC V2 authenticated user is 'admin'." ],
"user": {
"class_name": "CmonUser",
"user_id": 3,
"user_name": "s9s",
"preferences": {
"param11": "val11",
"param12": "val12",
"param7": "val7"
}
}
}
getUserPreferences
POST /v2/users
A call to get the user's preferences from DB.
Possible RPC request command with s9s tools:
| Parameter | Type | Required | Description |
|---|---|---|---|
user |
object | Required | The ClusterControl user's data in the request to get his/her properties. |
user.user_name |
string | Required | Must be a name of a valid logged in user. |
| Field | Type | Description |
|---|---|---|
user |
object | The ClusterControl user's data, including his/her actual properties. |
user.preferences |
object | The list of all user's preferences stored in the databaseafter the request is completed. |
Response example
{
"controller_id": "b195b016-ed96-49e4-a646-596b52d9d8f3",
"reply_received": "2023-01-25T13:55:07.073Z",
"request_created": "2023-01-25T13:55:07.068Z",
"request_id": 2,
"request_processed": "2023-01-25T13:55:07.072Z",
"request_status": "Ok",
"request_user_id": 3,
"debug_messages": [ "RPC V2 authenticated user is 'admin'." ],
"user": {
"class_name": "CmonUser",
"user_id": 3,
"user_name": "s9s",
"preferences": {
"pref01": "value01",
"pref02": "value02",
"pref03": "value03"
}
}
}
deleteUserPreferences
POST /v2/users
A call to read the user's preferences.
Possible RPC request command:
| Parameter | Type | Required | Description |
|---|---|---|---|
user |
object | Required | The ClusterControl user's data in the request to set his/her properties. |
user.user_name |
string | Required | Must be a name of a valid logged in user. |
user.preferences |
object | Required | The list of one or more user's preferences to delete from the DB. |
| Field | Type | Description |
|---|---|---|
user |
object | The ClusterControl user's data, including his/her actual properties. |
user.preferences |
object | The list of all user's preferences from the databaseafter the request is completed. |
Response example
{
"controller_id": "b195b016-ed96-49e4-a646-596b52d9d8f3",
"reply_received": "2023-01-25T14:57:46.284Z",
"request_created": "2023-01-25T14:57:46.274Z",
"request_id": 2,
"request_processed": "2023-01-25T14:57:46.283Z",
"request_status": "Ok",
"request_user_id": 3,
"debug_messages": [ "RPC V2 authenticated user is 'admin'." ],
"user": {
"class_name": "CmonUser",
"user_id": 3,
"user_name": "s9s",
"preferences": {
"param11": "val11",
"param12": "val12"
}
}
}
getDbVersions
POST /v2/dbversions
Lists the available 1-2 or 3 digits database versions supported by ClusterControl for a given cluster type and vendor. Returned values can be used as values on "provider_version" field on the cluster creation jobs.
| Parameter | Type | Required | Description |
|---|---|---|---|
cluster_type |
string | Required | The cluster type to query versions for |
vendor |
string | Required | The vendor to query versions for |
patch_number |
boolean | Optional | If true, returns 3-digit versions. Default is false |
use_vendor_api |
boolean | Optional | If true, queries the vendor's API for versions. Default is false |
Step 1 - Get 1-2 digit versions
{
"cluster_type": "galera",
"operation": "getDbVersions",
"request_created": "2024-01-04T17:59:22.892Z",
"request_id": 2,
"vendor": "mariadb"
}
Step 2 - Get 3-digit versions with patch_number
{
"cluster_type": "galera",
"operation": "getDbVersions",
"patch_number": true,
"request_created": "2024-01-04T18:06:00.767Z",
"request_id": 2,
"vendor": "percona"
}
Step 3 - Get 3-digit versions via vendor API
| Field | Type | Description |
|---|---|---|
db_versions |
array | Possible values on provider_version field on deployment jobs |
cluster_type |
string | The cluster type queried |
vendor |
string | The vendor queried |
use_vendor_api |
boolean | Indicates whether the vendor's API was used as the source of versions |
The controller replies with supported 1-2 digit versions for the specified cluster_type and vendor:
Response example
{
"authenticated": true,
"cluster_type": "GALERA",
"controller_id": "449bf7e9-a274-41db-bec6-85c915e619c5",
"reply_received": "2024-01-04T17:59:22.895Z",
"request_created": "2024-01-04T17:59:22.892Z",
"request_id": 2,
"request_processed": "2024-01-04T17:59:22.894Z",
"request_status": "Ok",
"request_user_id": 6,
"rpc_version": "2.0",
"vendor": "mariadb",
"db_versions": [
"10.4",
"10.5",
"10.6",
"10.7",
"10.8",
"10.9",
"10.10",
"10.11"
],
}
It is also possible to specify the patch_number option on some clusters (for example: "galera"). The default value for this option is false. The controller then replies with supported 3-digit versions only for the specified cluster_type and vendor:
Response example (patch_number=true)
{
"authenticated": true,
"cluster_type": "GALERA",
"controller_id": "449bf7e9-a274-41db-bec6-85c915e619c5",
"reply_received": "2024-01-04T18:06:00.771Z",
"request_created": "2024-01-04T18:06:00.767Z",
"request_id": 2,
"request_processed": "2024-01-04T18:06:00.771Z",
"request_status": "Ok",
"request_user_id": 6,
"rpc_version": "2.0",
"use_vendor_api": false,
"vendor": "percona",
"db_versions": [
"8.0.21",
"8.0.22",
"8.0.23",
"8.0.25",
"8.0.26",
"8.0.27",
"8.0.28",
"8.0.29",
"8.0.30",
"8.0.31",
"8.0.32",
"8.0.33",
"8.0.34"
],
}
The source of the versions can be the stored values of ClusterControl or the vendor's API. The use_vendor_api option can be used to specify the source of the versions (default value is false). The controller then queries the vendor's API to reply with supported 3-digit versions only for the specified cluster_type and vendor:
Response example (use_vendor_api=true)
{
"authenticated": true,
"cluster_type": "GALERA",
"controller_id": "449bf7e9-a274-41db-bec6-85c915e619c5",
"reply_received": "2024-01-04T18:06:00.771Z",
"request_created": "2024-01-04T18:06:00.767Z",
"request_id": 2,
"request_processed": "2024-01-04T18:06:00.771Z",
"request_status": "Ok",
"request_user_id": 6,
"rpc_version": "2.0",
"use_vendor_api": false,
"vendor": "percona",
"db_versions": [
"8.0.21",
"8.0.22",
"8.0.23",
"8.0.25",
"8.0.26",
"8.0.27",
"8.0.28",
"8.0.29",
"8.0.30",
"8.0.31",
"8.0.32",
"8.0.33",
"8.0.34"
],
}
getClusterTypes
POST /v2/dbversions
Gets the list of supported clusters types. Returned values can be used as an argument to the cluster_type option (upper or lower case).
| Field | Type | Description |
|---|---|---|
cluster_types |
array | Possible cluster types supported |
The controller replies with supported cluster types:
Response example
{
"authenticated": true,
"controller_id": "449bf7e9-a274-41db-bec6-85c915e619c5",
"reply_received": "2024-01-04T17:43:14.779Z",
"request_created": "2024-01-04T17:43:14.776Z",
"request_id": 2,
"request_processed": "2024-01-04T17:43:14.779Z",
"request_status": "Ok",
"request_user_id": 6,
"rpc_version": "2.0",
"cluster_types": [
"MYSQLCLUSTER",
"REPLICATION",
"MYSQL_SINGLE",
"MONGODB",
"POSTGRESQL_SINGLE",
"GROUP_REPL",
"REDIS",
"MSSQL_SINGLE",
"MSSQL_AO_ASYNC",
"MSSQL_AO_SYNC",
"ELASTIC",
"GALERA"
],
}
getVendors
POST /v2/dbversions
Gets the list of supported vendors on all supported clusters. If no version is retrieved for a specific cluster type-vendor, it means that it is not supported.
| Field | Type | Description |
|---|---|---|
vendors |
array | Possible vendor values on vendor field |
The controller replies with supported vendors on all cluster types:
Response example
{
"authenticated": true,
"controller_id": "449bf7e9-a274-41db-bec6-85c915e619c5",
"reply_received": "2024-01-04T17:49:46.016Z",
"request_created": "2024-01-04T17:49:46.012Z",
"request_id": 2,
"request_processed": "2024-01-04T17:49:46.015Z",
"request_status": "Ok",
"request_user_id": 6,
"rpc_version": "2.0",
"debug_messages": [ "RPC V2 authenticated user is 'ccalvaro'." ],
"vendors": [
"percona",
"mariadb",
"oracle",
"codership",
"10gen",
"mongodbenterprise",
"microsoft",
"elasticsearch",
"redis",
"postgresql",
"enterprisedb"
]
}
Controllers manipulation on database
The /v2/poolcontrollers path is to retrieve controllers managed by the system.
| Operation | Description |
|---|---|
| listPoolControllers | Retrieve controllers from the DB, optionally filtered by ID or status. |
| startController | Start a controller in the pool remotely via SSH. |
| stopController | Stop a controller in the pool remotely via SSH. |
| setPoolMode | Change the pool mode state on the controller. |
listPoolControllers
POST /v2/poolcontrollers
The getControllers RPC call can be used to retrieve controllers from the DB. By default, only controllers that are not in 'stopped' status are returned.
| Parameter | Type | Required | Description |
|---|---|---|---|
controller_id |
integer | Optional | If provided and non-zero, only the controller with this id is returned. |
all_controllers |
boolean | Optional | If set to true, all controllers including stopped ones are returned. |
| Field | Type | Description |
|---|---|---|
controllers |
array | List of controller objects. |
total |
integer | Total number of controllers returned. |
Response example
{
"controllers": [ {
"controller_id": 1,
"hostname": "controller1",
"port": 3306,
"status": "active",
"properties": "full_controller",
"report_ts": "2025-06-28 15:54:00",
"clusters": [ 1, 2, 3 ]
}, {
"controller_id": 2,
"hostname": "controller2",
"port": 3306,
"status": "stopped",
"properties": "full_controller",
"report_ts": "2025-06-28 15:54:00",
"clusters": [ 4, 5, 6 ]
} ],
"total": 2
}
startController
POST /v2/poolcontrollers
Starts a controller in the pool remotely via SSH. This operation is only allowed when the controller is in pool mode and requires superuser privileges.
| Parameter | Type | Required | Description |
|---|---|---|---|
controller_id |
integer | Required | The ID of the controller to start. |
| Field | Type | Description |
|---|---|---|
controller |
object | The controller object reflecting the updated state. |
message |
string | Status message for the start operation. |
stopController
POST /v2/poolcontrollers
Stops a controller in the pool remotely via SSH. This operation is only allowed when the controller is in pool mode and requires superuser privileges. Cannot be used to stop the local controller.
| Parameter | Type | Required | Description |
|---|---|---|---|
controller_id |
integer | Required | The ID of the controller to stop. |
| Field | Type | Description |
|---|---|---|
controller |
object | The controller object reflecting the updated state. |
message |
string | Status message for the stop operation. |
setPoolMode
POST /v2/poolcontrollers
Changes the pool mode state on the controller. When the state changes, the controller will restart automatically. This operation is only allowed on the main controller and requires superuser privileges.
| Parameter | Type | Required | Description |
|---|---|---|---|
pool_mode |
boolean | Optional | Whether to enable or disable pool mode. Defaults to true. |
conf_storage |
string | Optional | Storage type for pool configuration. Valid values: "nfs" or "k8s". Defaults to "nfs". |
| Field | Type | Description |
|---|---|---|
pool_mode |
boolean | The resulting pool mode state. |
conf_storage |
string | The resulting storage type for pool configuration. |
controller |
object | The controller object reflecting the updated state. |
Watchlists manipulation on database
The /v2/watchlists path is to manipulate whatchlists to visualize clusters according to user configuration.
| Operation | Description |
|---|---|
| createWatchlist | Create a new watchlist. |
| updateWatchlist | Update an existing watchlist. |
| listWatchlists | List watchlists stored on the controller database. |
| deleteWatchlist | Delete an existing watchlist. |
createWatchlist
POST /v2/watchlists
The createWatchlist RPC call can be used to create a new Watchlist.
Here are the most important elements of the request:
| Parameter | Type | Required | Description |
|---|---|---|---|
watchlist_name |
string | Required | Name given by the user to identify watchlist. |
topics |
string | Required | Themes for the different information types to be visualized. |
clusters |
string | Required | List of clusters IDs to be visualized on watchlist. |
page_by |
string | Required | Pagination to be used on watchlist. Initially only 'cluster' or 'topic' are supported. |
grid |
string | Required | The grid layout to be used on watchlist. |
owner_id |
integer | Required | User ID of the owner (creator) of the watchlist. |
updateWatchlist
POST /v2/watchlists
The updateWatchlist RPC call can be used to update an existing watchlist.
Here are the most important elements of the request:
| Parameter | Type | Required | Description |
|---|---|---|---|
watchlist_id |
integer | Required | The internal ID of the watchlist once it has been persisted. |
watchlist_name |
string | Required | Name given by the user to identify watchlist. |
topics |
string | Required | Themes for the different information types to be visualized. |
clusters |
string | Required | List of clusters IDs to be visualized on watchlist. |
page_by |
string | Required | Pagination to be used on watchlist. Initially only 'cluster' or 'topic' are supported. |
grid |
string | Required | The grid layout to be used on watchlist. Initially only '2x2' | '2x3' | '3x2' | '3x3' are allowed. |
owner_id |
integer | Required | User ID of the owner (creator) of the watchlist. |
listWatchlists
POST /v2/watchlists
A call to read the watchlists on controller database.
| Parameter | Type | Required | Description |
|---|---|---|---|
watchlist_id |
integer | Optional | Limit the list of returned watchlists to those that have this id. Use '0' to get all watchlists. |
watchlist_name |
string | Optional | Limit the list of returned watchlists to those that have this name. |
| Field | Type | Description |
|---|---|---|
total |
integer | The total number of watchlists stored on controller db. |
watchlists |
array | A list of watchlists class objects. To get more information about the user objects please check the watchlists sections. |
Response example
{
"controller_id": "3d797309-1bfe-4b6d-be07-e65d65f3b411",
"reply_received": "2025-04-01T08:35:23.397Z",
"request_created": "2025-04-01T08:35:17.696Z",
"request_id": 2,
"request_processed": "2025-04-01T08:35:23.396Z",
"request_status": "Ok",
"request_user_id": 7,
"total": 2,
"debug_messages": [ "RPC V2 authenticated user is 'ccalvaro2'." ],
"watchlists": [
{
"name": "dbWatchlist",
"id": 1,
"owner_id": 3,
"page_by": "cluster",
"properties": "empty",
"clusters": [
"12",
"13",
"14"
],
"grid": [ "2x2" ],
"topics": [
"topic1",
"topic3"
]
},
{
"name": "w1",
"id": 2,
"owner_id": 0,
"page_by": "cluster",
"properties": "",
"clusters": [ "1" ],
"grid": [ ],
"topics": [ "t1" ]
}
]
}
deleteWatchlist
POST /v2/watchlists
This call can be used to delete an existing watchlist.