Hosting API documentation¶
Welcome to the documentation of scaledo-hosting API.
Server¶
Server CRUD
Resource |
Operation |
Description |
|---|---|---|
Server |
List servers |
|
Show one server |
||
Create new server |
||
Update server. |
||
Delete server |
||
Evacuate server |
||
List storages on server |
||
Upstream createEnabled php-version |
||
CDB; MCDB; Logs |
||
Send data of a specific type |
- GET /v2/server¶
Server List.
- Status Codes:
200 OK – no error
Example request:
GET /server HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "items":[{ "createEnabled": true, "group": "local", "hostname": "web-1", "id": 2, "nfsMountpoint": "/nfsmnt/web-1", "rack": "r0", }] }
- GET /v2/server/(hostname)¶
Server List.
- Status Codes:
200 OK – no error
404 Not Found – Not found
Example request:
GET /server/web-1 HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "item":{ "createEnabled": true, "group": "local", "hostname": "web-1", "id": 2, "nfsMountpoint": "/nfsmnt/web-1", "rack": "r0", "upstreams": [ { "createEnabled": true, "id": 1, "identString": "local-php56-1", "name": "Apache 2.4 PHP 5.6", "protected": false, "type": "hosting", "upstream": "apache24-php56" }, { "createEnabled": true, "id": 2, "identString": "local-php71-1", "name": "Apache 2.4 PHP 7.1", "protected": false, "type": "hosting", "upstream": "apache24-php71" }, { "createEnabled": true, "id": 3, "identString": "local-php73-1", "name": "Apache 2.4 PHP 7.3", "protected": false, "type": "hosting", "upstream": "apache24-php73" } ] } }
Example response - Not found:
HTTP/1.1 404 OK Content-Type: application/json { "error": "Server not found" }
- POST /v2/server¶
Server create.
Example request:
POST /server HTTP/1.1 Content-Type: application/json Accept: application/json { "createEnabled": true, "group": "local", "hostname": "web-1", "id": 2, "nfsMountpoint": "/nfsmnt/web-1", "rack": "r0", "serverUpstreams":[ { "php_container": "php56", "php_version": "5.6", "apache_version": "2.4", "upstream_type": "hosting" }, { "php_container": "php71", "php_version": "7.1", "apache_version": "2.4", "upstream_type": "hosting" }, { "php_container": "php73", "php_version": "7.3", "apache_version": "2.4", "upstream_type": "hosting" }] }
Example request - new ident string:
POST /server HTTP/1.1 Content-Type: application/json Accept: application/json { "createEnabled": true, "group": "local", "hostname": "web-1", "id": 2, "nfsMountpoint": "/nfsmnt/web-1", "rack": "r1", "newIdentString": true, "unit": "u1", "serverUpstreams":[ { "php_container": "php56", "php_version": "5.6", "apache_version": "2.4", "upstream_type": "hosting" }, { "php_container": "php71", "php_version": "7.1", "apache_version": "2.4", "upstream_type": "hosting" }, { "php_container": "php73", "php_version": "7.3", "apache_version": "2.4", "upstream_type": "hosting" }] }
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "item":{ "createEnabled": true, "group": "local", "hostname": "web-1", "id": 2, "nfsMountpoint": "/nfsmnt/web-1", "rack": "r0", "upstreams": [ { "createEnabled": true, "id": 1, "identString": "local-php56-1", "name": "Apache 2.4 PHP 5.6", "protected": false, "type": "hosting", "upstream": "apache24-php56" }, { "createEnabled": true, "id": 2, "identString": "local-php71-1", "name": "Apache 2.4 PHP 7.1", "protected": false, "type": "hosting", "upstream": "apache24-php71" }, { "createEnabled": true, "id": 3, "identString": "local-php73-1", "name": "Apache 2.4 PHP 7.3", "protected": false, "type": "hosting", "upstream": "apache24-php73" } ] } }
Example response - error:
HTTP/1.1 200 OK Content-Type: application/json { "status": "error", "error": {"hostname": ["Unable to find server ident number"]} }
- PUT /v2/server/(hostname)¶
Server update.
- Status Codes:
200 OK – no error
200 OK – error
404 Not Found – Not found
Example request:
PUT /server HTTP/1.1 Content-Type: application/json Accept: application/json { "createEnabled": true, "hostname": "web-1", "rack": "r1", "serverUpstreams":{"containers":[ { "php_container": "php74", "php_version": "7.4", "apache_version": "2.4", "upstream_type": "hosting" }]} }
Example request - new ident string:
PUT /server HTTP/1.1 Content-Type: application/json Accept: application/json { "createEnabled": true, "hostname": "web-1", "rack": "r1", "newIdentString": true, "unit": "u1", "serverUpstreams":{"containers":[ { "php_container": "php74", "php_version": "7.4", "apache_version": "2.4", "upstream_type": "hosting" }]} }
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "item":{ "createEnabled": true, "group": "local", "hostname": "web-1", "id": 2, "nfsMountpoint": "/nfsmnt/web-1", "rack": "r1", "upstreams": [ { "createEnabled": true, "id": 1, "identString": "local-php56-1", "name": "Apache 2.4 PHP 5.6", "protected": false, "type": "hosting", "upstream": "apache24-php56" }, { "createEnabled": true, "id": 2, "identString": "local-php71-1", "name": "Apache 2.4 PHP 7.1", "protected": false, "type": "hosting", "upstream": "apache24-php71" }, { "createEnabled": true, "id": 3, "identString": "local-php73-1", "name": "Apache 2.4 PHP 7.3", "protected": false, "type": "hosting", "upstream": "apache24-php73" }, { "createEnabled": true, "id": 4, "identString": "local-php74-1", "name": "Apache 2.4 PHP 7.4", "protected": false, "type": "hosting", "upstream": "apache24-php74" } ] } }
Example response - error:
HTTP/1.1 200 OK Content-Type: application/json { "status": "error", "error": {"hostname": ["Unable to find server ident number"]} }
Example response - Not found:
HTTP/1.1 404 OK Content-Type: application/json { "error": "Server not found" }
- DELETE /v2/server/(hostname)¶
Server delete.
- Status Codes:
200 OK – no error
404 Not Found – Not found
Example request:
DELETE /server HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "item":{ "createEnabled": true, "group": "local", "hostname": "web-1", "id": 2, "nfsMountpoint": "/nfsmnt/web-1", "rack": "r0", "upstreams": [ { "createEnabled": true, "id": 1, "identString": "local-php56-1", "name": "Apache 2.4 PHP 5.6", "protected": false, "type": "hosting", "upstream": "apache24-php56" }, { "createEnabled": true, "id": 2, "identString": "local-php71-1", "name": "Apache 2.4 PHP 7.1", "protected": false, "type": "hosting", "upstream": "apache24-php71" }, { "createEnabled": true, "id": 3, "identString": "local-php73-1", "name": "Apache 2.4 PHP 7.3", "protected": false, "type": "hosting", "upstream": "apache24-php73" } ] } }
Example response - Not found:
HTTP/1.1 404 OK Content-Type: application/json { "error": "Server not found" }
- PUT /v2/server/evacuate¶
Evacuate source server to target server. Updates all storages in database from source server and send cdb / mcdb updates. We create many small updates so that cdb queue is not blocked by big cdb / mcdb update.
This method doesn’t migrate / delete any data and should be called only after data is on target server.
We rely on proper validations during the data migration process - for example, making sure that all upstreams used on the source server are available on the target, too. That’s why here, we do our best to go through with the operation and only log errors. This is the last step of an evacuation process, and we don’t want to leave hundreds of websites dysfunctional.
- Status Codes:
200 OK – no error
404 Not Found – Not found
- Request JSON Object:
sourceServer (str) – Source server hostname
targetServer (str) – Target server hostname
async (bool) – If
true(default), return a Task ID immediately and perform the evacuation in the background. Otherwise, wait for the process to complete.
Example request:
PUT /v2/server/evacuate HTTP/1.1 Content-Type: application/json Accept: application/json { "sourceServer": "r1-u19-web", "targetServer": "r1-u20-web", "async": false }
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success" "items":[ "848fd3e9-feea-4dfe-b2a7-c92b74fd59d8", "5975a26f-0349-46af-9334-4b5231b881a0", "d772f3b3-ab4c-41de-aefa-88719c12d452" ], "tasks": { "mcdb": "e2119676-340b-4388-8f06-9351d572a72f", "ftp": "a45abf5f-a8dc-4303-ab3e-d24d16c07a0e", "crontab_source": "5815dd49-264b-4cdf-9c33-e7721de581ea", "crontab_target": "a08422f4-4222-4423-a704-86c2c7fb5c94", "shell": "1e8121cf-6463-476e-9a12-344a34fcbca2" }, "warnings": { "domain-1.com": "message which should be logged and operator should handle it" }, "upstream_errors": { "r1-u18-php85-fpm9": "Error message", "r1-u18-php83": "Upstream not found on target server" } }
- GET /v2/server/(server)/storage¶
List all storages on server
- Status Codes:
200 OK – no error
404 Not Found – Not found
Example request:
GET /web-1/storage HTTP/1.1 Content-Type: application/json
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json
- {
- “items”: [
- [
“e3b0a1af-fcff-4cc5-b7db-79aa7991470b”, “mrena.sk”, 130900
], [
“625eb1d4-6b66-4d89-9101-5bf200f18b99”, “halka.sk”, 71360
],
], “status”: “success”
}
- PUT /v2/server/upstream/(php_version)¶
Update a rack/all rack upstream value ‘createEnabled’ for specific PHP-version. If no rack is specified, request will apply to ALL rack.
- Status Codes:
200 OK – no error
400 Bad Request – validation error
404 Not Found – Not found
Example request:
PUT /v2/server/upstream/php-version HTTP/1.1 Content-Type: application/json Accept: application/json { "rack": "r101", "createEnabled": True, }
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "r101": [ { "id": 2024, "name": "Apache 2.4 PHP 7.4", "upstream": "apache24-php74", "createEnabled": true, "protected": false, "type": "hosting", "identString": "r101-u24-php74", "defaultUpstreamFlag": false }, ] }
- GET /v2/server/get-full-cdb-export/(rack)/(log_type)¶
Get the latest FULL cdb/mcdb log from specified rack.
- Parameters:
rack – rack
log_type – type of log (cdb/mcdb)
Example request:
GET /v2/server/get-full-cdb-export/r101 HTTP/1.1 Content-Type: application/json Accept: application/json { "log_type": "cdb", "uuid": "79acb3b4-6ce9-4bd9-aed6-678083280ebd" }
- POST /v2/server/data-send-of¶
Send data of a specific type to a server.
- Status Codes:
200 OK – no error
400 Bad Request – validation error or unsupported data type
Example request:
POST /v2/server/data-send-of HTTP/1.1 Content-Type: application/json Accept: application/json { "hostname": "web-1", "dataType": "cdb" }
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "task_id": "some-task-id" }
Example response - error:
HTTP/1.1 400 Bad Request Content-Type: application/json { "error": "Unsupported data type" }
Storage¶
Manipulating hosting Storages
Resource |
Operation |
Description |
|---|---|---|
Storage |
list all Storage objects |
|
list all Rack Storages objects |
||
show info |
||
insert default vhost/services |
||
create storage |
||
update storage |
||
delete storage |
||
restore storage |
||
enable files for storage |
||
set quota |
||
set multiple quotas |
||
get storage by domain |
||
cleanup mcdb |
||
public ip by domain |
||
get rack by domain |
||
check quarantine status |
||
enable quarantine |
||
clear quarantine |
||
check CMS Admin GeoIP protection status |
||
update CMS Admin GeoIP protection status |
||
check quarantine status |
||
get uid locations |
||
set PHP backend |
||
change PHP container |
||
Web sender whitelist |
list rules |
|
add rule |
||
DELETE /v2/storage/(uuid)/whitelist-web-sender/(int:rule_id) |
delete rule |
- GET /v2/storage¶
Lists all existing Storages.
Example request
GET /v2/storage HTTP/1.1 Content-Type: application/json Accept: application/json
Example response
HTTP/1.1 200 OK Content-Type: application/json { "items": [ { "id": 55363, "createTime": 1411978388, "updateTime": 1411978388, "uuid": "816e9892-c580-11e8-b389-fba089f55f59", "domain": "asdf.sk", "uid": 1005, "gid": 1005, "limitBytes": 0, "disabled": false, "deleted": false, "disabledChangeTime": null, "deletedChangeTime": null, "rootPath": "/data/a/s/asdf.sk", "storagePool": { "id": 1, }, "server": { "id": 3, "host": "web-1", "group": "it13", }, "filesEnabled": true, "scheduledToDelete": null, }, ], "pager": { "items": 1, "page": 1, "pagesize": null } }
- Query Parameters:
pagesize – limit number of records shown at once
page – page index
- GET /v2/storage/by-rack/(rack)¶
Lists all existing Storages for specific rack.
Example request
GET /v2/storage/by-rack/r101 HTTP/1.1 Content-Type: application/json Accept: application/json
Example response
HTTP/1.1 200 OK Content-Type: application/json { "items": [ { "id": 2119952, "createTime": 1691966925, "updateTime": 1691966927, "uuid": "3327df65-eb87-423c-b77b-e72f476f5090", "domain": "deduco.se", "uid": 3619952, "gid": 3619952, "limitBytes": 107374182400, "disabled": false, "deleted": false, "disabledChangeTime": null, "deletedChangeTime": null, "rootPath": "/data/3/3/3327df65-eb87-423c-b77b-e72f476f5090", "storagePool": { "id": 7, "mountpoint": "/data" }, "server": { "id": 445, "rack": "r101", "group": "local", "hostname": "r101-u22-web", "createEnabled": true, "nfsMountpoint": "/nfsmnt/r101-u22-web" }, "filesEnabled": true, "scheduledToDelete": null, "quarantine": null, "cmsProtection": true, "business": false, "sysTempDir": ".tmp", "uploadTmpDir": ".tmp/upload" } ], "pager": { "page": 1, "pagesize": null, "items": 118418 } } :query pagesize: limit number of records shown at once :query page: page index
- GET /v2/storage/(uuid)¶
Get Storage information by its uuid identifier.
Example request
GET /v2/storage/816e9892-c580-11e8-b389-fba089f55f59 HTTP/1.1 Content-Type: application/json Accept: application/json
Example response
HTTP/1.1 200 OK Content-Type: application/json { "id": 55363, "createTime": 1411978388, "updateTime": 1411978388, "uuid": "816e9892-c580-11e8-b389-fba089f55f59" "domain": "asdf.sk", "uid": 1005, "gid": 1005, "limitBytes": 0, "disabled": false, "deleted": false, "disabledChangeTime": null, "deletedChangeTime": null, "rootPath": "/data/a/s/asdf.sk", "storagePool": { "id": 1, }, "server": { "id": 3, "host": "web-1", "group": "it13", }, "filesEnabled": true, "scheduledToDelete": null "ddosProtection": HIGH }
- POST /v2/storage/(uuid)/defaults¶
Sets up default Services and Virtualhost on a new Storage.
- Request JSON Object:
indexTemplate (string) – Default template file name if we don’t provide
language(in that case, it’s used to assemble the file name dynamically together withentity).language (string) – Two-letter country code, used to select the correct index template file
entity (string) – Company name abbreviation, used to select the correct index template file (default ws)
Example request:
POST /v2/storage/816e9892-c580-11e8-b389-fba089f55f59/defaults HTTP/1.1 Content-Type: application/json Accept: application/json { "entity": "sk-ws" }
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "item": { "id": 55363, "createTime": 1411978388, "updateTime": 1411978388, "uuid": "816e9892-c580-11e8-b389-fba089f55f59" "domain": "asdf.sk", "uid": 1005, "gid": 1005, "limitBytes": 0, "disabled": false, "deleted": false, "disabledChangeTime": null, "deletedChangeTime": null, "rootPath": "/data/a/s/asdf.sk", "storagePool": { "id": 1, }, "server": { "id": 3, "host": "web-1", "group": "it13", }, "filesEnabled": true, "scheduledToDelete": null, }, "error": null }
Example response - Storage already has children:
HTTP/1.1 200 OK Content-Type: application/json { "status": "error", "items": { "virtualhosts": [] }, "error": "Cannot setup defaults on non-empty Storage." }
- POST /v2/storage/(uuid)¶
Creates a Storage identified by a unique identifier uuid. Domain is a required request parameter and specifies a domain with which the Storage will be associated until it is deleted. A Domain cannot be shared by two or more Storage objects, and a Storage cannot be updated to use a new domain; it can only be deleted and created anew.
- Request JSON Object:
domain (string) – domain associated with this Storage
filesEnabled (bool) – if false, only redirects are supported
limitBytes (int) – Storage quota
location (string) – location of storage (sk, hu, …) - if not specified any location is chosen
business (bool) – mark storage as business (false by default)
premium (bool) – create storage in premium rack (false by default)
skipLetsEncryptCertificate (bool) – skip generating new Lets Encrypt certificates (false by default)
- Response JSON Object:
status (string) – operation status
item (obj) – JSON representation of created Storage model
error (string) – error message (if any)
- Status Codes:
200 OK – no error
200 OK – validation error
404 Not Found – storage not found, ip not found, domain not found
500 Internal Server Error – internal error, failed api call
Example request:
POST /v2/storage/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a HTTP/1.1 Content-Type: application/json Accept: application/json { "domain": "nahodnadomenatest.sk", "filesEnabled": true, "limitBytes": 1024, "location": "sk" }
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "item": { "id": 94336, "createTime": 1560853445, "updateTime": 1569575907, "uuid": "fc4b1231-4310-4d03-b0a8-aa03b4b37b4a", "domain": "nahodnadomenatest.sk", "uid": 1074174, "gid": 1074174, "limitBytes": 10642040832, "disabled": false, "deleted": false, "disabledChangeTime": 1560846245, "deletedChangeTime": null, "rootPath": "/nfsmnt/hosting2_1/f/c/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a", "storagePool": { "mountpoint": "/nfsmnt/hosting2_1", "id": 3 }, "server": { "id": 223, "rack": "r0", "group": "local", "hostname": "web-100", "createEnabled": true, "nfsMountpoint": "/nfsmnt/web-100" }, "filesEnabled": true, "scheduledToDelete": null, "quarantine": null, "cmsProtection": true }, "status": "success", "error": null, "async_tasks": { "set_mcdb": "72896007-624e-405f-a37b-6efda1011986" } }
Example response - validation error:
HTTP/1.1 200 OK Content-Type: application/json { "error": { "domain": ["Domain name already used."] }, "status": "error" }
Example response - Not Found:
HTTP/1.1 404 Not Found Content-Type: application/json { "error": "No available location found", "status": "error" }
Example response - Internal Server Error:
HTTP/1.1 500 Internal Server Error Content-Type: application/json { "error": "Could not get available locations", "status": "error" }
- PUT /v2/storage/(uuid)¶
Update Storage.
- Request JSON Object:
limitBytes (int) – Storage quota
disabled (bool) – (un)mark storage as disabled
scheduledToDelete (int) – specify date (UNIX) on which the storage files will be deleted unless it’s restored in the meantime.
deleted (bool) – do not update directly; use delete/restore endpoint
serverId (int) – update server id
business (bool) – mark storage as business
ddosProtection (str) – change ddos protection. Options: “DISABLED”, “LOW”, “HIGH”
- Response JSON Object:
status (string) – operation status
item (obj) – JSON representation of updated Storage model
error (string) – error message (if any)
- DELETE /v2/storage/(uuid)¶
Delete a Storage. Immediately marks the Storage as deleted and begins the process of deleting hosting files from the web server.
The safer approach is to update the Storage with disabled`=1 and set `scheduledToDelete.
- Response JSON Object:
status (string) – operation status
item (obj) – JSON representation of updated Storage model
error (string) – error message (if any)
- PUT /v2/storage/(uuid)/restore¶
Restore Storage that was marked as deleted. Clears deleted/disabled flags and resets scheduled deletion time, if set.
Creates folder structure on the hosting server, however it does not perform restore from backup.
Example request:
PUT /v2/storage/625eb1d4-6b66-4d89-9101-5bf200f18b99/restore HTTP/1.1 Content-Type: application/json Accept: application/json { "restoreData": true }
- Response JSON Object:
status (string) – operation status
item (obj) – JSON representation of updated Storage model
error (string) – error message (if any)
- PUT /v2/storage/(uuid)/enable-files¶
Enable files for storage. Create storage on server, set storage limit (limitBytes), set correct dns settings and nginx configuration.
Return success if files are already enabled for storage.
Note: This method does not create default Virtualhost nor any services.
- Request JSON Object:
location (string) – location of storage (sk, hu, …)
- Response JSON Object:
status (string) – operation status
item (obj) – JSON representation of Storage model
error (string) – error message (if any)
async_tasks (obj) – async celery tasks - key is task name, value is task id
- Status Codes:
200 OK – no error
400 Bad Request – validation error
404 Not Found – storage not found
500 Internal Server Error – internal error, failed api call
Example request:
PUT /v2/storage/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a/enable-files HTTP/1.1 Content-Type: application/json Accept: application/json { "location": "sk" }
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "item": { "id": 94336, "createTime": 1560853445, "updateTime": 1569575907, "uuid": "fc4b1231-4310-4d03-b0a8-aa03b4b37b4a", "domain": "nahodnadomenatest.sk", "uid": 1074174, "gid": 1074174, "limitBytes": 10642040832, "disabled": false, "deleted": false, "disabledChangeTime": 1560846245, "deletedChangeTime": null, "rootPath": "/nfsmnt/hosting2_1/f/c/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a", "storagePool": { "mountpoint": "/nfsmnt/hosting2_1", "id": 3 }, "server": { "id": 223, "rack": "r0", "group": "local", "hostname": "web-100", "createEnabled": true, "nfsMountpoint": "/nfsmnt/web-100" }, "filesEnabled": true, "scheduledToDelete": null, "quarantine": null, "cmsProtection": true }, "status": "success", "async_tasks": { "set_mcdb": "72896007-624e-405f-a37b-6efda1011986" } }
Example response - validation error:
HTTP/1.1 400 OK Content-Type: application/json { "error": { "location": ["This field is required."] }, "status": "error" }
Example response - validation error - storage:
HTTP/1.1 400 OK Content-Type: application/json { "error": { "storage": ["Storage cannot have virtualhosts"] }, "status": "error" }
Example response - Not Found:
HTTP/1.1 404 Not Found Content-Type: application/json { "error": "Storage does not exist", "status": "error" }
Example response - Internal Server Error:
HTTP/1.1 500 Internal Server Error Content-Type: application/json { "error": "Could not get available locations", "status": "error" }
- PUT /v2/storage/(uuid)/set_limit_queued¶
- PUT /v2/storage/(uuid)/set_limit¶
Update filesystem quota for a
Storage.- Parameters:
uuid – Storage UUID
- Request JSON Object:
limit (int) – New storage quota in KiB
- Status Codes:
200 OK – Success
500 Internal Server Error – Validation error
Example request - set quota to 200 MiB:
PUT /v2/storage/a6d80ff7-2603-45c5-b83b-83d8d15d4d35/set_limit HTTP/1.1 Content-Type: application/json Accept: application/json { "limit": 204800 }
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "error": null, "async_tasks": { "set_limit": ["63bf9ac6-c6da-45c1-a2ca-433f757939b2"] }, "item": { "limit": 204800, "limitBytes": 209715200, "uuid": "a6d80ff7-2603-45c5-b83b-83d8d15d4d35", "uid": 10247710 } }
- PUT /v2/storage/quota_multiset¶
Batch update of quotas for multiple Storages. Expects a dictionary in which keys are Storage UUIDs (str) and values new quota values (int) specified in kB.
Only integer quota values are supported.
- Status Codes:
200 OK – success
400 Bad Request – no data or non-integer quota values
Example request:
POST /v2/storage/quota_multiset HTTP/1.1 Content-Type: application/json Accept: application/json { "720a57b7-b1e8-4b54-b25d-ce18651df3fb": 45612345, "3fb63c3c-0d07-4b20-bb43-56467b2cb20a": 12345, "not-a-uuid.com": 12345 }
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "async_tasks": { "quota_multiset": ["a4c87582-ac0c-11ea-b89a-97352964f0cc"] }, "malformed_entries": { "not-a-uid.com": 12345 } }
Example response - no valid data submitted:
HTTP/1.1 400 Bad Request Content-Type: application/json { "status": "No (valid) data was supplied", "async_tasks": { "quota_multiset": [] }, "malformed_entries": { "not-a-uid.com": 12345 } }
- GET /v2/storage/by-domain/(domain)¶
Get storage by domain. Prefer non deleted and non disabled storage if exists.
- Status Codes:
200 OK – no error
404 Not Found – storage not found
- Query Parameters:
full-dump – Get full dump of storage with virtualhosts and services, optional
Example request
GET /v2/storage/by-domain/nahodnadomenatest.sk HTTP/1.1 Content-Type: application/json Accept: application/json
Example request - full dump request
GET /v2/storage/by-domain/nahodnadomenatest.sk?full-dump=1 HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success
HTTP/1.1 200 OK Content-Type: application/json { "id": 94336, "createTime": 1560853445, "updateTime": 1569575907, "uuid": "fc4b1231-4310-4d03-b0a8-aa03b4b37b4a", "domain": "nahodnadomenatest.sk", "uid": 1074174, "gid": 1074174, "limitBytes": 10642040832, "disabled": false, "deleted": false, "disabledChangeTime": 1560846245, "deletedChangeTime": null, "rootPath": "/nfsmnt/hosting2_1/f/c/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a", "storagePool": { "id": 3, "mountpoint": "/nfsmnt/hosting2_1" }, "server": { "id": 223, "rack": "r0", "group": "local", "hostname": "web-100", "createEnabled": true, "nfsMountpoint": "/nfsmnt/web-100" }, "filesEnabled": true, "scheduledToDelete": null, "quarantine": null, "cmsProtection": true }
Example response - not found
HTTP/1.1 404 Not Found Content-Type: application/json { "error": "Storage does not exist" }
- DELETE /v2/storage/by-domain/(domain)/mcdb/(rack)¶
Cleanup mcdb for domain in rack. We have nginx fallback in every rack if mcdb data is not found request can be routed to correct rack so we need to delete mcdb data after certain operations (for example after migration).
- Status Codes:
200 OK – no error
Example request
DELETE /v2/storage/by-domain/nahodnadomenatest.sk/mcdb/r1 HTTP/1.1 Content-Type: application/json Accept: application/json
Example response
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "async_tasks": [ "3d805bc3-40b9-4d33-9386-5fd96e407280" ] }
- GET /v2/storage/by-domain/(domain)/public-ip¶
Get public ip on which is domain accessible. Public ip is obtained from scaledo-dns according to rack of storage.
- Status Codes:
200 OK – no error
404 Not Found – storage not found, ip not found, storage does not have a server
500 Internal Server Error – internal error, failed api call
Example request
GET /v2/storage/by-domain/nahodnadomenatest.sk/public-ip HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success
HTTP/1.1 200 OK Content-Type: application/json "37.9.175.24"
Example response - not found
HTTP/1.1 404 Not Found Content-Type: application/json { "error": "Storage does not exist" }
Example response - internal error
HTTP/1.1 500 Internal Server Error Content-Type: application/json { "error": "Could not get public ip" }
- GET /v2/storage/by-domain/(domain)/rack¶
Get rack for domain. If domain is normal storage the rack of the assigned server is returned. If domain is masked redirect than rack of the target storage is returned. If rack cannot be determined than default rack is returned and storage_exists flag is set to False.
- Response JSON Object:
rack (string) – rack for the domain
storage_exists (bool) – if storage exists on server.
- Status Codes:
200 OK – no error
Example request
GET /v2/storage/by-domain/nahodnadomenatest.sk/rack HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success
HTTP/1.1 200 OK Content-Type: application/json { "rack": "r0", "storage_exists": true }
- POST /v2/storage/(uuid)/push-config¶
Forces Nginx, Apache and PHP-FPM configuration update.
- PUT /v2/storage/(uuid)/push-config¶
Forces Nginx, Apache and PHP-FPM configuration update.
- GET /v2/storage/(uuid)/quarantine¶
Check quarantine status.
Example request
GET /v2/816e9892-c580-11e8-b389-fba089f55f59/quarantine HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - quarantine inactive
HTTP/1.1 200 OK Content-Type: application/json { "countries": [], "status": "inactive" }
Example response - quarantine active
HTTP/1.1 200 OK Content-Type: application/json { "countries": [ "SK", "CZ", "HU" ], "status": "active" }
- POST /v2/storage/(uuid)/quarantine¶
Restrict access to a website by supplying a list of whitelisted country codes. Attempts to access the website from a non-whitelisted country will result in a 403 HTTP error code.
Example request
PUT /v2/816e9892-c580-11e8-b389-fba089f55f59/quarantine HTTP/1.1 Content-Type: application/json Accept: application/json { "countries": ["SK"] }
Example response
HTTP/1.1 200 OK Content-Type: application/json { "async_tasks": { "mcdb": "3d805bc3-40b9-4d33-9386-5fd96e407280" }, "countries": [ "SK" ], "status": "success" }
- PUT /v2/storage/(uuid)/quarantine¶
Restrict access to a website by supplying a list of whitelisted country codes. Attempts to access the website from a non-whitelisted country will result in a 403 HTTP error code.
Example request
PUT /v2/816e9892-c580-11e8-b389-fba089f55f59/quarantine HTTP/1.1 Content-Type: application/json Accept: application/json { "countries": ["SK"] }
Example response
HTTP/1.1 200 OK Content-Type: application/json { "async_tasks": { "mcdb": "3d805bc3-40b9-4d33-9386-5fd96e407280" }, "countries": [ "SK" ], "status": "success" }
- DELETE /v2/storage/(uuid)/quarantine¶
Clear quarantine.
Example request
DELETE /v2/816e9892-c580-11e8-b389-fba089f55f59/quarantine HTTP/1.1 Content-Type: application/json Accept: application/json
Example response
HTTP/1.1 200 OK Content-Type: application/json { "async_tasks": { "mcdb": "3d805bc3-40b9-4d33-9386-5fd96e407280" }, "countries": [], "status": "success" }
- GET /v2/storage/(uuid)/whitelist-web-sender¶
List email addresses for the given
Storagethat are allowed to be used as the “envelope sender” or as theFrom:header value when sending messages from the website (e.g. using PHPmail()).- The
addressfield can have three formats: Allow sending from a specific email address (e.g.
info@example.com)Allow sending from any email address in a domain (e.g.
@example.com)Allow sending from any email address at all (
@). This value is not allowed for new entries and was only used during migration of records from the Email API.
- Status Codes:
200 OK – Success
404 Not Found – Storage not found, not active or files are disabled.
Example request
GET /v2/816e9892-c580-11e8-b389-fba089f55f59/whitelist-web-sender HTTP/1.1 Content-Type: application/json Accept: application/json
Example response
HTTP/1.1 200 OK Content-Type: application/json { "items": [ { "id": 1, "address": "info@example.com", "note": "Customer request, see LA ticket BVF-UDJ-234" }, { "id": 2, "address": "@my-eshop.com", "note": null } ] }
- The
- POST /v2/storage/(uuid)/whitelist-web-sender¶
Add a new email address that can be used as the “envelope sender” or as the
From:header value when sending messages from the website (e.g. using PHPmail()).Normally, we only allow using email addresses that exist in our system, either as a regular mailbox or as an alias to a mailbox.
- Request JSON Object:
address (string) – The email address to allow. This can actually have two forms; the exact address (
info@example.com) or a domain-wide pattern (@example.com).note (string) – An optional note to add to the entry, e.g. a reference to the customer request ticket or a short reason description.
- Status Codes:
201 Created – Rule added successfully.
400 Bad Request – Validation error.
404 Not Found – Storage not found, not active or files are disabled.
409 Conflict – Rule already exists.
Example request
POST /v2/816e9892-c580-11e8-b389-fba089f55f59/whitelist-web-sender HTTP/1.1 Content-Type: application/json Accept: application/json { "address": "info@example.com", "note": "Customer request, see LA ticket BVF-UDJ-234" }
Example response
HTTP/1.1 201 Created Content-Type: application/json { "status": "success", "item": { "id": 1, "address": "info@example.com", "note": "Customer request, see LA ticket BVF-UDJ-234" } }
- DELETE /v2/storage/(uuid)/whitelist-web-sender/(int: rule_id)¶
Delete a whitelisted email address identified by its ID.
- Parameters:
rule_id (int) – The ID of the rule to delete.
- Status Codes:
200 OK – Rule deleted successfully.
404 Not Found – Storage not found, not active or files are disabled; or rule not found.
Example request
DELETE /v2/816e9892-c580-11e8-b389-fba089f55f59/whitelist-web-sender/213 HTTP/1.1 Content-Type: application/json Accept: application/json
Example response
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "item": { "id": 213, "address": "info@example.com", "note": "Customer request, see LA ticket BVF-UDJ-234" } }
Example response - rule not found
HTTP/1.1 404 Not Found Content-Type: application/json { "error": "Rule not found" }
- GET /v2/storage/(uuid)/cms-geoip¶
Check status of GeoIP protection for standard CMS administration endpoints; access to these is by default allowed only for browsers from SK, CZ, AT, and HU.
- POST /v2/storage/(uuid)/cms-geoip¶
Enable (DELETE) or disable (POST) GeoIP protection for standard CMS administration endpoints; access to these is by default allowed only for browsers from SK, CZ, AT, and HU.
Note: API endpoint name /cms-geoip may be confusing, since POSTing to it disables GeoIP protection, and DELETEing it re-enables GeoIP protection.
- DELETE /v2/storage/(uuid)/cms-geoip¶
Enable (DELETE) or disable (POST) GeoIP protection for standard CMS administration endpoints; access to these is by default allowed only for browsers from SK, CZ, AT, and HU.
Note: API endpoint name /cms-geoip may be confusing, since POSTing to it disables GeoIP protection, and DELETEing it re-enables GeoIP protection.
- GET /v2/storage/search-info¶
Generate a dictionary mapping domains to uid and uuid. Includes disabled, but not deleted storages. Used as a data source for elastic-powered search in FE.
Example request
GET /v2/storage/search-info HTTP/1.1 Accept: application/json
Example response (snip)
HTTP/1.1 200 OK Content-Type: application/json { "zlesapocujem.sk": [ 166987, "203160c5-c27f-4e1c-851d-a2fccbee97e7" ], "znarodnenie.sk": [ 164585, "0fcbca4d-add7-41b2-a187-a3b405e2653c" ] }
- GET /v2/storage/user-location¶
Return a dictionary of server names to lists of numerical uid`s whose `Storage is currently located on that server. Used in scaledo-rrhad web size measurements to determine which size usage measurement is correct if an uid has files on multiple servers.
- We’re using the server-name-to-list-of-uids data structure because of two reasons:
It’s more compact (about half the size) than an uid-to-server-name dictionary
JSON has a limitation that dictionary keys can only be strings, so we’d have to keep this in mind and do type conversions on the client side
- Query Parameters:
server – Only return uids located on the specified server
Example request
GET /v2/storage/user-location HTTP/1.1 Accept: application/json
Example response
HTTP/1.1 200 OK Content-Type: application/json { "web-1": [12345, 24231], "r1-u18-web": [299532, 3948183, 21245] }
- PUT /v2/storage/(uuid)/deploy-ddos-protection¶
Deploy DDoS protection settings.
Example request
PUT /v2/storage/2c40948e-1e84-11ef-b996-8b73c528699e/deploy-ddos-protection HTTP/1.1 Content-Type: application/json Accept: application/json
Example response
HTTP/1.1 200 OK Content-Type: application/json { "async_tasks": { "set_ddos_protection": "45f0318f-32eb-4c58-af40-fffd213e96ce" } }
- PUT /v2/storage/(uuid)/php-backend¶
Change the PHP backend on all Services under this Storage to PHP-FPM or to mod_php. All masked redirects pointed to this Storage (defined under other Storages) are also switched.
If any single Service fails validations, roll back to the original state. Validations may include presence of given PHP version on the current server and so on.
- Request JSON Object:
php_backend (string) – New PHP backend for all PHP services. Valid values are
mod_phpandphp_fpm.
- Status Codes:
200 OK – Success
400 Bad Request – Validation error
409 Conflict – Service conflict, e.g. a PHP version is unavailable for desired backend
500 Internal Server Error – Failed to set new upstream on a Service
Example request
PUT /v2/storage/2c40948e-1e84-11ef-b996-8b73c528699e/php-backend HTTP/1.1 Content-Type: application/json Accept: application/json { "php_backend": "php_fpm" }
Example response
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "service_upstreams": { "domain-1.com": "apache24-php85-fpm", "php83.domain-1.com": "apache24-php83-fpm", "masked-sub-php101.domain-2.com": "apache24-php101-fpm", "masked-sub-php83.domain-2.com": "apache24-php83-fpm", }, "async_tasks": { "mcdb": ["efb353f9-e081-401f-ad1f-a02b9f0aecf4", "aa1f78ce-f9b7-427a-bd8c-5b325b073181"], "fpm_config": ["608f9711-f96d-43a3-a24d-c3c578f312af", "c6458e9a-c845-4133-818f-c212206354aa"], "sync_user_ini_files": ["de58a0a9-e086-496a-8df2-600e492dad6b"] } }
Example response - PHP version unavailable
HTTP/1.1 409 Conflict Content-Type: application/json { "status": "error", "error": "Some hosting or masked redirect services currently use a PHP version that's not available as PHP-FPM on the server", "detail": { "unsupported_php_versions": ["php83", "php84"] } }
- PUT /v2/storage/(uuid)/php-container¶
Direct all Services under the Storage to another PHP container on the same web server. No data migration takes place during this operation. The backend type is also left unchanged, so only PHP-FPM services are affected.
This operation is best-effort - if the new container doesn’t provide a PHP version used by one of the Services, we skip that Service.
- Request JSON Object:
container_id (int) – New PHP-FPM container ID where services should point to.
force (bool) – If
true, only log an error for services whose PHP version is not available in the target container or if they’re still usingmod_php. Iffalse(default), return an error if at least one service is not changeable to the target upstream, and don’t change anything.
- Response JSON Object:
service_upstream_idents – Map of Service subdomains to the ``identString``s of their upstream. This value encodes rack and server ID, PHP version, PHP backend and container ID where applicable.
errors – Map of Service subdomains to detailed error messages if, for some reason, we were unable to set the new container ID for that Service.
- Status Codes:
200 OK – Success, either full or partial (see response body)
400 Bad Request – Validation error
409 Conflict – PHP version for some services is not available in the new container
Example request
PUT /v2/storage/2c40948e-1e84-11ef-b996-8b73c528699e/php-container HTTP/1.1 Content-Type: application/json Accept: application/json { "container_id": 17, "force": true }
Example response
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "service_upstream_idents": { "domain-1.com": "r1-u18-php85-fpm17", "blog.domain-1.com": "r1-u18-php85-fpm8", "php83.domain-1.com": "r1-u18-php83", "masked-sub-php101.domain-2.com": "r1-u18-php101-fpm17", }, "errors": { "blog.domain-1.com": "PHP version php56 not available in the target container", "php83.domain-1.com": "Service ID 45663 is not PHP-FPM" }, "async_tasks": { "mcdb": ["efb353f9-e081-401f-ad1f-a02b9f0aecf4", "aa1f78ce-f9b7-427a-bd8c-5b325b073181"], "fpm_config": ["608f9711-f96d-43a3-a24d-c3c578f312af", "c6458e9a-c845-4133-818f-c212206354aa"], "sync_user_ini_files": ["de58a0a9-e086-496a-8df2-600e492dad6b"] } }
Example response - unable to change some upstreams
HTTP/1.1 409 Conflict Content-Type: application/json { "status": "error", "errors": { "blog.domain-1.com": "PHP version php56 not available in the target container", "php83.domain-1.com": "Service ID 45663 is not PHP-FPM" } }
Services¶
Configure Nginx services
Resource |
Operation |
Description |
|---|---|---|
Service |
list services |
|
show service |
||
create service |
||
update services upstream |
||
update service |
||
delete service |
||
update default upstream |
||
list available upstreams |
||
Storage |
list available upstreams |
|
show upstream details |
- GET /v2/storage/(uuid)/service¶
List Services in a specific Storage.
- Request JSON Object:
filter (ServiceFilter) – Filter results based on various criteria.
- Query Parameters:
page (int) – Page offset number (default is 1).
pagesize (int) – Page size; return all results if omitted.
sort (string) – Sort results by this attribute.
reverse (bool) – Set to
trueto reverse sort order.
- Response JSON Object:
items (list) – List of
Serviceobjects.pager (object) – Pagination properties.
filter_errors (object) – In case the filters didn’t pass validation, return the complete result set and include the errors in this field.
ServiceFilterobject format:- Request JSON Object:
typeIn (list[string]) – Filter services whose
typeattribute matches one of these values.redirCodeIn (list[string]) – Filter services whose redirect response code (
redirCodeattribute) matches one of these values.subLike (string) – Filter services whose
subattribute contains the value.pathLike (string) – Filter services whose
pathattribute contains the value.redirTargetLike (string) – Filter services whose redirect target (
redirTargetattribute) contains the value.
- Status Codes:
200 OK – success
Example request:
GET /v2/storage/13e43429-77c1-4e2d-a0d5-37a1ace49472/service?sort=sub HTTP/1.1 Accept: application/json Content-Type: application/json { "filter": { "redirCodeIn": ["301"], "redirTargetLike": "shop", "typeIn": ["redirect"] } }
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "filter_errors": null, "items": [ { "cache": true, "default": false, "https_upgrade": false, "upgrade_insecure_requests": false, "id": 2755875, "path": "", "redirCode": "301", "redirCopyPath": false, "redirTarget": "https://gcutzbarbershop.hu/barbershop-budapest", "sub": "balint", "type": "redirect", "upstream": null, "upstreamName": null, "virtualhost": null }, { "cache": true, "default": false, "https_upgrade": false, "upgrade_insecure_requests": false, "id": 2755899, "path": "", "redirCode": "301", "redirCopyPath": false, "redirTarget": "https://gcutzbarbershop.hu/a-legjobb-barber-shop-budapesten", "sub": "dave", "type": "redirect", "upstream": null, "upstreamName": null, "virtualhost": null }, { "cache": true, "default": false, "https_upgrade": false, "upgrade_insecure_requests": false, "id": 2755908, "path": "", "redirCode": "301", "redirCopyPath": false, "redirTarget": "https://gcutzbarbershop.hu/barbershop-budapest-7-kerulet", "sub": "geri", "type": "redirect", "upstream": null, "upstreamName": null, "virtualhost": null } ], "pager": { "items": 3, "page": 1, "pagesize": null } }
- GET /v2/storage/(uuid)/service/(service_id)¶
Show details of an existing Service record.
Example request:
GET /v2/<UUID>/service/<svc_id> HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "id": 1, "default": 0, "sub": "blog", "path": "", "type": "hosting", "upstream": { "id": 21, "upstream": "apache24-php72", }, "virtualhost": { "id": 39, }, "redirTarget": "", "redirCopyPath": "", "cache": 0 }
- POST /v2/storage/(uuid)/service¶
Creates a Service record. These are used to generate configuration for our Nginx load-balancers.
When creating a type: masked Service record, this method also creates a Virtualhost record, that copies the default Virtualhost model on Storage specified by redirTarget. In this case, this method also accepts all JSON parameters accepted by create/update Virtualhost methods, and passes the parameters to them.
- Request JSON Object:
sub (string) – subdomain
path (string) – URI path (example.com/this-right-here)
type (string) – hosting, masked, redirect or upstream
upstreamName (string) – ServerUpstream name (ex.: roundcube, apache24-php56) Only for type: hosting and type: upstream
prefer_fpm (bool) – In case of “masked” and “hosting” upstream types, swap the requested upstream for a PHP-FPM equivalent if available. The PHP version remains unchanged. Default:
False.redirTarget (string) – URL (type: redirect) or target domain (type: masked)
redirCopyPath (string) – copy URI when redirecting (only for type: redirect)
disabled (bool) – mark Service as disabled (configuration does not propagate)
cache (bool) – enable Nginx HTTP cache
https_upgrade (bool) – upgrade insecure requests to HTTPS (default: False)
upgrade_insecure_requests (bool) – add Content-Security-Policy upgrade-insecure-requests header when redirecting to HTTPS - NOTE: this flag has no effect unless https_upgrade is set to True (default: False)
skip_dns (bool) – Skip DNS updates.
- Status Codes:
200 OK – no error, validation error
404 Not Found – storage not found, redirect target not found
500 Internal Server Error – internal error
Example request:
POST /v2/<UUID>/service/<svc_id> HTTP/1.1 Content-Type: application/json Accept: application/json { "sub": "blog", "upstreamName": "apache24-php84", "prefer_fpm": true }
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "item": { "id": 1, "default": false, "sub": "blog", "path": "", "type": "hosting", "upstream": { "id": 21, "upstream": "apache24-php84-fpm" }, "virtualhost": { "id": 39 }, "redirTarget": "", "redirCopyPath": "", "cache": false, "https_upgrade": false, "upgrade_insecure_requests": false }, "error": null }
Example response - validation error:
HTTP/1.1 200 OK Content-Type: application/json { "status": "error", "error": { "sub": [ "A service with this sub and path combination already exists." ] } }
- PUT /v2/storage/(uuid)/update-upstreams¶
Update upstream for hosting and masked services under storage according to storage.server.
- Status Codes:
200 OK – no error, validation error
404 Not Found – storage not found, redirect target not found
500 Internal Server Error – internal error
Example request:
PUT /v2/storage/<UUID>/update-upstreams HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "items": [ { "cache": true, "default": true, "https_upgrade": false, "upgrade_insecure_requests": false, "id": 433285, "path": "", "redirCode": null, "redirCopyPath": false, "redirTarget": "", "storage": { "cmsProtection": true, "createTime": 1560853445, "deleted": false, "deletedChangeTime": null, "disabled": false, "disabledChangeTime": 1560846245, "domain": "nahodnadomenatest.sk", "filesEnabled": true, "gid": 1074174, "id": 94336, "limitBytes": 10641645568, "quarantine": null, "rootPath": "/nfsmnt/hosting2_1/f/c/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a", "scheduledToDelete": null, "server": { "createEnabled": true, "group": "local", "hostname": "web-92", "id": 183, "nfsMountpoint": "/nfsmnt/web-92", "rack": "r0" }, "storagePool": { "id": 3, "mountpoint": "/nfsmnt/hosting2_1" }, "uid": 1074174, "updateTime": 1567745694, "uuid": "fc4b1231-4310-4d03-b0a8-aa03b4b37b4a" }] "error": null }
Example response - internal error:
HTTP/1.1 500 OK Content-Type: application/json { "status": "success", "error": "Unknown upstream" }
- PUT /v2/storage/(uuid)/service/(service_id)¶
Update a Service record.
- Request JSON Object:
sub (string) – subdomain
path (string) – URI path (example.com/this-right-here)
type (string) – hosting, masked, redirect or upstream
upstreamName (string) – ServerUpstream name (ex.: roundcube, apache24-php56) Only for type: hosting and type: upstream
prefer_fpm (bool) – In case of “masked” and “hosting” upstream types, swap the requested upstream for a PHP-FPM equivalent if available. The PHP version remains unchanged. Default:
False.redirTarget (string) – URL (type: redirect) or target domain (type: masked)
redirCopyPath (string) – copy URI when redirecting (only for type: redirect)
disabled (bool) – mark Service as disabled (configuration does not propagate)
cache (bool) – enable Nginx HTTP cache
https_upgrade (bool) – upgrade insecure requests to HTTPS (default: False)
upgrade_insecure_requests (bool) – add Content-Security-Policy upgrade-insecure-requests header when redirecting to HTTPS - NOTE: this flag has no effect unless https_upgrade is set to True (default: False)
skip_dns (bool) – Skip DNS updates. Useful for batch service updates.
- Status Codes:
200 OK – no error, validation error
404 Not Found – storage not found, redirect target not found
500 Internal Server Error – internal error
Example request:
PUT /v2/<UUID>/service/<svc_id> HTTP/1.1 Content-Type: application/json Accept: application/json { "upstream": "roundcube", "sub": "mail", "type": "upstream", "https_upgrade": true }
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "item": { "id": 1, "default": false, "sub": "mail", "path": "", "type": "hosting", "upstream": { "id": 1, "upstream": "roundcube", }, "virtualhost": { "id": 39, }, "redirTarget": "", "redirCopyPath": "", "cache": false, "https_upgrade": true, "upgrade_insecure_requests": false }, "error": null }
- DELETE /v2/storage/(uuid)/service/(service_id)¶
Removes a Service record permanently. If you want to disable the indicated Service temporarily, use the PUT endpoint to set the flag instead.
- Status Codes:
200 OK – no error
404 Not Found – service not found
Example request:
DELETE /v2/<UUID>/service/<svc_id> HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "item": { "id": 1, "default": 0, "sub": "blog", "path": "", "type": "hosting", "upstream": { "id": 21, "upstream": "apache24-php72", }, "virtualhost": { "id": 39, }, "redirTarget": "", "redirCopyPath": "", "cache": 0 }, "error": null }
- GET /v2/storage/upstream¶
Lists all ServerUpstream records.
- GET /v2/storage/upstream/active¶
Lists all active ServerUpstream records.
- GET /v2/storage/(uuid)/available-upstreams¶
List upstreams available to Services on this Storage.
In case of PHP-FPM upstreams, multiple entries with the same upstream name can appear in the output. When selecting an upstream for subsequent operations (e.g. which upstream to use for a new
Service), just provide its name and the Hosting API will choose the most suitable instance.When ‘protected’ is set to true, denotes that said upstream is immutable/read-only, i.e. its contents cannot be changed by the user. Only Service of type hosting or masked should be able to use unprotected upstreams.
- Response JSON Object:
createEnabledOnly (bool) – filter between createEnabled upstreams and all upstreams (optional).
By default, only createEnabled upstreams are listed.
Example request:
GET /v2/storage/<uuid>/available-upstreams HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "items": [ { "createEnabled": true, "id": 694, "identString": "r7-u40-php83", "name": "Apache 2.4 PHP 8.3", "protected": false, "type": "hosting", "upstream": "apache24-php83" }, { "createEnabled": true, "id": 695, "identString": "r7-u40-php84", "name": "Apache 2.4 PHP 8.4", "protected": false, "type": "hosting", "upstream": "apache24-php84" }, { "createEnabled": true, "id": 696, "identString": "r7-u40-php85-fpm8", "name": "Apache 2.4 PHP 8.5", "protected": false, "type": "hosting", "upstream": "apache24-php85-fpm" }, { "createEnabled": true, "id": 697, "identString": "r7-u40-php85-fpm11", "name": "Apache 2.4 PHP 8.5", "protected": false, "type": "hosting", "upstream": "apache24-php85-fpm" } { "createEnabled": true, "id": 1391, "identString": "roundcube", "name": "Webmail - Roundcube", "protected": true, "type": "email", "upstream": "roundcube" } ], "pager": { "items": 3, "page": 1, "pagesize": null } }
- GET /v2/storage/(uuid)/upstream/(upstream_name)¶
WARNING: This API endpoint is deprecated in favor of GET /v2/storage/<uuid>/upstreams/<upstream_name> which returns a list of upstreams. As of
SE1OPQ1-1884, upstream name is no longer a unique identifier and multiple upstreams with the same name may exist on a single web server.- Parameters:
upstream_name – Upstream name, e.g. apache24-php84.
- GET /v2/storage/(uuid)/upstreams/(upstream_name)¶
Get detailed information about upstreams with the requested name, which are available to this Storage. There can be multiple upstreams, especially for the PHP-FPM backend.
Generally, the caller does not need to be concerned about which one to use - it’s only necessary to provide upstream name in other requests (e.g. apache24-php85-fpm) and the Hosting API will make the right choice.
- Parameters:
upstream_name – Upstream name, e.g. apache24-php84.
- Response JSON Object:
createEnabledOnly (bool) – filter between createEnabled upstreams and all upstreams (optional).
By default, only createEnable upstreams are listed.
- Status Codes:
200 OK – OK
404 Not Found – No upstreams with that name available for this Storage
Example request:
GET /v2/storage/49640220-d93f-48dd-8071-0b57178223aa/upstreams/apache24-php85-fpm HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "items": [ { "createEnabled": true, "id": 696, "identString": "r7-u40-php85-fpm8", "name": "Apache 2.4 PHP 8.5", "protected": false, "type": "hosting", "upstream": "apache24-php85-fpm" }, { "createEnabled": true, "id": 697, "identString": "r7-u40-php85-fpm11", "name": "Apache 2.4 PHP 8.5", "protected": false, "type": "hosting", "upstream": "apache24-php85-fpm" } ] }
- PUT /v2/storage/default-upstream¶
Update current default upstream.
- Request JSON Object:
defaultUpstream (string) – default upstream
- GET /v2/storage/service/upstream/check-multiple¶
List upstreams for all services and crons under multiple storages by uuid.
- Response JSON Object:
list[str] – list of uuids.
Example request:
GET /service/upstream/check-multiple HTTP/1.1 Content-Type: application/json Accept: application/json ["961c2e55-1413-4938-98de-d3fee5114805", "8f518fbd-02ef-473a-a42d-9b79d284a22a"]
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "items": { "8f518fbd-02ef-473a-a42d-9b79d284a22a": { "crons": [ { "id": 1, "phpVersion": "php73", "target": "domain1.sk/web/get4.php" } ], "upstreams": [ { "serviceId": 1, "name": "domain1.sk", "phpVersion": "php74", "isModPhp": true, "isPhpFpm": false, "subdomain": "", "type": "hosting" } ] }, "961c2e55-1413-4938-98de-d3fee5114805": { "crons": [ { "id": 2, "phpVersion": "php80", "target": "domain2.sk/sub/api/cron.php" } ], "upstreams": [ { "serviceId": 2, "name": "domain2.sk", "phpVersion": "php71", "isModPhp": true, "isPhpFpm": false, "subdomain": "", "type": "hosting" }, { "serviceId": 3, "name": "domain2.sk", "phpVersion": "php72", "isModPhp": true, "isPhpFpm": false, "subdomain": "sub", "type": "hosting" } ] } }, "status": "success" }
Virtualhosts¶
Manipulate Apache virtualhosts
Resource |
Operation |
Description |
|---|---|---|
Virtualhost |
list assigned virtualhosts |
|
list virtualhosts |
||
list masked virtualhosts |
||
show virtualhost |
||
create virtualhost |
||
update virtualhost |
- GET /v2/storage/virtualhost/assigned/(fqdn)¶
List of Virtualhost records assigned to specified subdomain. We only list Virtualhost containing specified subdomain, from non deleted, non disabled storage.
Example request:
GET /v2/storage/virtualhost/assigned/non-existing.example.com HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - error:
HTTP/1.1 404 OK Content-Type: application/json { "error": "No vhost assigned for non-existing.example.com" }
- GET /v2/storage/(uuid)/virtualhost¶
List of Virtualhost records under this Storage.
- GET /v2/storage/(uuid)/masked-virtualhost¶
List of Virtualhost records by masked storage id.
- Query Parameters:
exclude_disabled – Excludes all disabled storage
Example request
GET /v2/storage/12345678-1234-1234-1234-123456789012/masked-virtualhost HTTP/1.1 Content-Type: application/json Accept: application/json
Example request - full dump request
GET /v2/storage/12345678-1234-1234-1234-123456789012/masked-virtualhost?exclude_disabled=0 HTTP/1.1 Content-Type: application/json Accept: application/json
- GET /v2/storage/(uuid)/virtualhost/(vhost_id)¶
Show details of an existing Virtualhost record.
Example request:
GET /v2/<UUID>/virtualhost/<vhost_id> HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "createTime": 1500292181, "default": true, "id": 892, "keepAliveOff": false, "logsOnStorage": "halka.sk/logs", "nonExistSubDomainsToWeb": false, "phpDefaultMysql": "mariadb55", "phpMaxExecutionTime": 30, "phpMemoryLimit": 64, "phpOpenBaseDir": false, "phpOpenBaseDirAll": false, "phpOpenBaseDirStorage": false, "phpOpenBaseWebInWeb": false, "phpPostMaxSize": 48, "phpRegisterGlobalsOff": false, "phpSafeModeOff": false, "phpUploadMaxFilesize": 48, "storage": { "createTime": 1486658172, "deleted": false, "deletedChangeTime": null, "disabled": false, "disabledChangeTime": null, "filesEnabled": true, "gid": 71360, "id": 757, "limitBytes": 13765221376, "rootPath": "/nfsmnt/hosting2_1/6/2/625eb1d4-6b66-4d89-9101-5bf200f18b99", "scheduledToDelete": null, "server": { "group": "local", "host": "web-1", "id": 79 }, "storagePool": { "id": 2, "mountpoint": "/nfsmnt/hosting2_1" }, "uid": 71360, "updateTime": 1539929920, "uuid": "625eb1d4-6b66-4d89-9101-5bf200f18b99" }, "sub": "", "subOnStorage": "halka.sk/sub", "webOnStorage": "halka.sk/web" }
- POST /v2/storage/(uuid)/virtualhost¶
Creates a Virtualhost record. This record is used to generate virtualhost configuration for our Apache webservers.
If redirTarget or maskedStorageId is specified, the configuration of the default Virtualhost on target Storage is used instead of default values to pre-populate this record’s configuration.
- Request JSON Object:
sub (string) – Subdomain name (leave empty for main domain)
webOnStorage (string) – relative path to webroot (domain.tld/web)
subOnStorage (string) – relative path to subdomains root (domain.tld/sub)
logsOnStorage (string) – relative path to log directory (domain.tld/logs)
nonExistSubDomainsToWeb (bool)
keepAliveOff (bool) – unset keep-alive flag
phpSafeModeOff (bool) – unset PHP safe_mode
phpRegisterGlobalsOff (bool) – unset PHP register_globals
phpOpenBaseDir (bool) – PHP open_basedir directive
phpOpenBaseDirAll (bool) – PHP open_basedir directive
phpOpenBaseWebInWeb (bool) – PHP open_basedir directive
phpOpenBaseDirStorage (bool) – PHP open_basedir directive
phpDefaultMysql (string) – one of mysql50, mysql51, mysql57, mysql80, mariadb55, mariadb101, mariadb103, mariadb105
phpMaxExecutionTime (int) – default 30 (s)
phpMemoryLimit (int) – default 128 (M)
phpUploadMaxFilesize (int) – default 48 (M)
phpPostMaxSize (int) – default 48 (M)
redirTarget (string) – domain name
maskedStorageId (int) – id of a masked Storage
entity (string) – Company name abbreviation, used to select the correct index template file (default sk-ws)
Example request:
POST /v2/<UUID>/virtualhost HTTP/1.1 Content-Type: application/json Accept: application/json { "sub": "blog", "phpMemoryLimit": 256, "webOnStorage": "halka.sk/sub/blog", "entity": "sk-ws" }
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "item": { "createTime": 1500292181, "id": 892, "default": false, "keepAliveOff": false, "logsOnStorage": "halka.sk/logs", "nonExistSubDomainsToWeb": false, "phpDefaultMysql": "mariadb55", "phpMaxExecutionTime": 30, "phpMemoryLimit": 64, "phpOpenBaseDir": false, "phpOpenBaseDirAll": false, "phpOpenBaseDirStorage": false, "phpOpenBaseWebInWeb": false, "phpPostMaxSize": 48, "phpRegisterGlobalsOff": false, "phpSafeModeOff": false, "phpUploadMaxFilesize": 48, "storage": { "createTime": 1486658172, "deleted": false, "deletedChangeTime": null, "disabled": false, "disabledChangeTime": null, "filesEnabled": true, "gid": 71360, "id": 757, "limitBytes": 13765221376, "rootPath": "/nfsmnt/hosting2_1/6/2/625eb1d4-6b66-4d89-9101-5bf200f18b99", "scheduledToDelete": null, "server": { "group": "local", "host": "web-1", "id": 79 }, "storagePool": { "id": 2, "mountpoint": "/nfsmnt/hosting2_1" }, "uid": 71360, "updateTime": 1539929920, "uuid": "625eb1d4-6b66-4d89-9101-5bf200f18b99" }, "sub": "blog", "subOnStorage": "", "webOnStorage": "halka.sk/sub/blog" } }
- PUT /v2/storage/(uuid)/virtualhost/(vhost_id)¶
Update an existing Virtualhost record.
- Request JSON Object:
webOnStorage (string) – relative path to webroot (domain.tld/web)
subOnStorage (string) – relative path to subdomains root (domain.tld/sub)
logsOnStorage (string) – relative path to log directory (domain.tld/logs)
nonExistSubDomainsToWeb (bool)
keepAliveOff (bool) – unset keep-alive flag
phpSafeModeOff (bool) – unset PHP safe_mode
phpRegisterGlobalsOff (bool) – unset PHP register_globals
phpOpenBaseDir (bool) – PHP open_basedir directive
phpOpenBaseDirAll (bool) – PHP open_basedir directive
phpOpenBaseWebInWeb (bool) – PHP open_basedir directive
phpOpenBaseDirStorage (bool) – PHP open_basedir directive
phpDefaultMysql (string) – one of mysql50, mysql51, mysql57, mysql80, mariadb55, mariadb101, mariadb103, mariadb105
phpMaxExecutionTime (int) – default 30 (s)
phpMemoryLimit (int) – default 128 (M)
phpUploadMaxFilesize (int) – default 48 (M)
phpPostMaxSize (int) – default 48 (M)
redirTarget (string) – UUID of a masked Storage
maskedStorageId (int) – id of a masked Storage
- DELETE /v2/storage/(uuid)/virtualhost/(vhost_id)¶
Removes a Virtualhost record. The associated database record will be removed permanently without the possibility of a later recovery, but hosting data will remain unaffected. The attempt will fail if there is at least a single Service pointing to the Virtualhost. Default Virtualhost cannot be deleted.
Example request:
DELETE /v1/<UUID>/virtualhost/<vhost_id> HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "item": { "createTime": 1500292181, "default": true, "id": 892, "keepAliveOff": false, "logsOnStorage": "halka.sk/logs", "nonExistSubDomainsToWeb": false, "phpDefaultMysql": "mariadb55", "phpMaxExecutionTime": 30, "phpMemoryLimit": 64, "phpOpenBaseDir": false, "phpOpenBaseDirAll": false, "phpOpenBaseDirStorage": false, "phpOpenBaseWebInWeb": false, "phpPostMaxSize": 48, "phpRegisterGlobalsOff": false, "phpSafeModeOff": false, "phpUploadMaxFilesize": 48, "storage": { "createTime": 1486658172, "deleted": false, "deletedChangeTime": null, "disabled": false, "disabledChangeTime": null, "filesEnabled": true, "gid": 71360, "id": 757, "limitBytes": 13765221376, "rootPath": "/nfsmnt/hosting2_1/6/2/625eb1d4-6b66-4d89-9101-5bf200f18b99", "scheduledToDelete": null, "server": { "group": "local", "host": "web-1", "id": 79 }, "storagePool": { "id": 2, "mountpoint": "/nfsmnt/hosting2_1" }, "uid": 71360, "updateTime": 1539929920, "uuid": "625eb1d4-6b66-4d89-9101-5bf200f18b99" }, "sub": "", "subOnStorage": "halka.sk/sub", "webOnStorage": "halka.sk/web" }, "error": null }
Example response - Attempt to delete default Virtualhost:
HTTP/1.1 200 OK Content-Type: application/json { "status": "error", "error": "Cannot delete default Virtualhost." }
- POST /v2/storage/virtualhost/check-multiple¶
Get a list of Virtualhost records on Storages specified by a list of UUIDs.
Example request:
GET /v2/storage/virtualhost/check-multiple HTTP/1.1 Content-Type: application/json Accept: application/json ["625eb1d4-6b66-4d89-9101-5bf200f18b99"]
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "items": [ { "createTime": 1371758257, "id": 862, "keepAliveOff": true, "logsOnStorage": "halka.sk/logs", "nonExistSubDomainsToWeb": true, "phpDefaultMysql": "mariadb101", "phpMaxExecutionTime": 60, "phpMemoryLimit": 128, "phpOpenBaseDir": false, "phpOpenBaseDirAll": false, "phpOpenBaseDirStorage": false, "phpOpenBaseWebInWeb": false, "phpPostMaxSize": 96, "phpRegisterGlobalsOff": true, "phpSafeModeOff": true, "phpUploadMaxFilesize": 96, "sub": "", "default": true, "subOnStorage": "halka.sk/sub", "webOnStorage": "halka.sk/web" }, ], "pager": { "items": 1, "page": 1, "pagesize": null } }
- GET /v2/storage/virtualhost/check-multiple¶
Get a list of Virtualhost records on Storages specified by a list of UUIDs.
Example request:
GET /v2/storage/virtualhost/check-multiple HTTP/1.1 Content-Type: application/json Accept: application/json ["625eb1d4-6b66-4d89-9101-5bf200f18b99"]
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "items": [ { "createTime": 1371758257, "id": 862, "keepAliveOff": true, "logsOnStorage": "halka.sk/logs", "nonExistSubDomainsToWeb": true, "phpDefaultMysql": "mariadb101", "phpMaxExecutionTime": 60, "phpMemoryLimit": 128, "phpOpenBaseDir": false, "phpOpenBaseDirAll": false, "phpOpenBaseDirStorage": false, "phpOpenBaseWebInWeb": false, "phpPostMaxSize": 96, "phpRegisterGlobalsOff": true, "phpSafeModeOff": true, "phpUploadMaxFilesize": 96, "sub": "", "default": true, "subOnStorage": "halka.sk/sub", "webOnStorage": "halka.sk/web" }, ], "pager": { "items": 1, "page": 1, "pagesize": null } }
SSL¶
Add and manipulate SSL certificates
Resource |
Operation |
Description |
|---|---|---|
CSR |
generate CSR |
|
SSL |
list certificates |
|
public ip by domain |
||
get certificate by id |
||
get certificate by name |
||
install new certificate |
||
update an existing certificate |
||
delete certificate |
- GET /v2/storage/(uuid)/ssl¶
List SSL certificates.
Example request:
GET /v2/storage/d0a12334-c5a3-11e9-822c-c381a7805210/ssl HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "items": [ { "activeCount": 2, "activeDomains": "*.example.com,example.com", "activeServiceIds": [ 2017537 ], "activeSubdomains": [ "*.example.com", "example.com" ], "altNames": "*.example.com,example.com", "cert": "-----BEGIN CERTIFICATE----- ...", "chain": "-----BEGIN CERTIFICATE----- ...", "expireDate": 1574321006, "id": 179227, "key": "-----BEGIN RSA PRIVATE KEY----- ...", "subject": "CN=*.example.com" } ], "pager": { "items": 1, "page": 1, "pagesize": null } }
- GET /v2/storage/by-domain/(domain)/ssl¶
Get ssl cert for host (domain or subdomain). Returns pem format.
- Status Codes:
200 OK – no error
404 Not Found – storage not found, ip not found, domain not found
Example request
GET /v2/storage/by-domain/nahodnadomenatest.sk/ssl HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success
HTTP/1.1 200 OK Content-Type: application/json "-----BEGIN PRIVATE KEY----- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDX05H6+/6xK7TE 465yBfclc1M2n/XRiyIxbYLqsoqyQqgvwrjeeOz+er4wloLWvF7OQ8nrp2SW/dwq qNSsOFgmBDoSukFzgugd20/z+MCcMkeWRQlJMVaXuWKVSBTdZLFVpif1VQDvCYHx lUSxasRGDunjd4sPQs90bzCm/Y8cVbXqIb/6OGIPqRc0JCm8SVNqeBwPe0iWxjOK +dlEwV8lJhIzw6VLTHrMA/8ku0sCHcQcIsB8igymNPrGfau+zkSgOHgiRXj/0awn pdmjRpHy6FCbZy0kdkJbSHZu1SyKuJSDNq2GV4sNjVetY9qIMSe6BW+i9+QMNrg0 tv0e0ku7AgMBAAECggEBAIpWYzCDy0mWoSS+Z3dQmYyYshLGTxMD4mPaNNrom/wM u675WfPHgOjQlg2gu7aWQRJm4ws4XUJm73MsijzlVKLxfKO6XO+ETfGtPD8+B39W vwnzsDMI+97+hdD3xd/uhbhHaz9WP+X3qyHFMqWhsLLTJlmVqz2Z7k1MY9v1lIBs xntHG4i66NTxRcD78+KtRhSLjePpcjIvQxA94VFZoukQ7TRSM7PPzQo6XI7CMGZi BMQFewOQ4v9O6MspgzUM3xC5bpvD8orYY4NhL0JZzKfJSI5Gvn4JxeGORKm4QNyg aKQ8SlDLAuJ6R35p08pcX3p4cPEwIoQxRD/4EeQVnIECgYEA6+h4HoFlDOrW+sBh kSy9KP2owQfCiE5DVdg9K+YNHFuQlYSCe13XMFx/N457nr0q4LAyge+QE5Q97nZT 0CTgu2AbCGgj0ovlXfgTDS30DVL5yxvcmh2exfLhhVqm7HP3LtKwSpXn7csoa9Md GrLjpPvrgORw+X4awSEVeO3vHXsCgYEA6jVCQW8iDFloO2KIl4h3DouKDjc67dur 86WBviCta+zdSAwaiEjKCbVt3E549rgNzK8Ql54SRGTBb8U5vkKgrmKQBilol1cl hZodTePlQsRZ5kug/xKQvqZnYRD7UUA+R0T0zFm3wOnmJkL0chT8hPx4Ve8SuDDC Xwx8jkallsECgYBiFCl0jVlk0HIGmFs4D0CpvSQe9Mn0/4zRMPDlwmRrCMqIzyms fqxLp/kgMPXGXmFoPvkQunfNHBHPhZR88ggY/vDeQuW50H3Q3qWVEijoLTo7Ll8+ F9h99ee7GKBTqDb5WZD/wWlGnPM2OPRduEgavL4BvXgW0k3vQ4D44PtL5wKBgFIV cnAue/dqCm7tvMOnL1roqu0KjFu65swQ0KULHNy7el56532mTTET5joVQq3tmeCH 5r/Mxcg0q9r5e6BkB562qpWOQ7ru7xahCe43li1NVdix3u4m2pYHCipp4jr60hj2 YPmR5CX3lBMK2lN1aX9OYPp1PNFTPXxEiw7uUbDBAoGBANWjc5EiQnDpWyLyX7Gs WjOkkZZgn/06zbhh25Bo0bFHaHOIqEjKs263AEOm3kpBDPNKTx5AREOwvY3D6Lxj jPO4HDt891zoHhfvxoI0hqbETZWB2wuoZAKWEz7GK2wd2otv4hrRpAwr7EjpyBd4 YDQLO3F48GP5q2CJaX9OSKBP -----END PRIVATE KEY----- -----BEGIN CERTIFICATE----- MIIDUTCCAjmgAwIBAgIUQC5j3NFS1rnJHPqFQ4L0Z6N1AhQwDQYJKoZIhvcNAQEL BQAwODE2MDQGA1UEAwwtbmFob2RuYWRvbWVuYXRlc3Quc2ssd3d3Lm5haG9kbmFk b21lbmF0ZXN0LnNrMB4XDTE5MDkyNzEyMzkyMFoXDTIwMDkyNjEyMzkyMFowODE2 MDQGA1UEAwwtbmFob2RuYWRvbWVuYXRlc3Quc2ssd3d3Lm5haG9kbmFkb21lbmF0 ZXN0LnNrMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA19OR+vv+sSu0 xOOucgX3JXNTNp/10YsiMW2C6rKKskKoL8K43njs/nq+MJaC1rxezkPJ66dklv3c KqjUrDhYJgQ6ErpBc4LoHdtP8/jAnDJHlkUJSTFWl7lilUgU3WSxVaYn9VUA7wmB 8ZVEsWrERg7p43eLD0LPdG8wpv2PHFW16iG/+jhiD6kXNCQpvElTangcD3tIlsYz ivnZRMFfJSYSM8OlS0x6zAP/JLtLAh3EHCLAfIoMpjT6xn2rvs5EoDh4IkV4/9Gs J6XZo0aR8uhQm2ctJHZCW0h2btUsiriUgzathleLDY1XrWPaiDEnugVvovfkDDa4 NLb9HtJLuwIDAQABo1MwUTAdBgNVHQ4EFgQUisTox6jIrWXF6gpfEI2d/2XOcCEw HwYDVR0jBBgwFoAUisTox6jIrWXF6gpfEI2d/2XOcCEwDwYDVR0TAQH/BAUwAwEB /zANBgkqhkiG9w0BAQsFAAOCAQEA01u4sI3iUWbkbw27OmT78stHDCJGIxW4rQpW 8OKJXdFBxD2Z5UvEpoGk+L5H9f+NimX5LUd594n6rX9qOcN6qD0U6hv0f2Jt9AX/ sRzLwBGGLXBZN5coe8gJidt6nXAOdgh405TLqDEJQQJaXcGLAioq9TbLTmdzV+7O 081G+MNoaBF3LPavJOxXuF6fZ3C/+c9CGE7Pd0VwIJeOkjwcWGKYfcmCZfjj6+ze CfHGMAXP184tXY5a6MCHsdONvDSvutohY1xe23R2ErYmhKbIj5/GVpg4Mq69MAiX QSiNlgVi73xmijzT6R+vfPsg93llz3LKEkBsg7jvrt8Gfe2i3Q== -----END CERTIFICATE-----"
Example response - not found
HTTP/1.1 404 NOT FOUND Content-Type: application/json { "error": "SSL for domain not found" }
- GET /v2/storage/(uuid)/ssl/(ssl_id)¶
Get SSL certificate by id.
Example request:
GET /v2/storage/d0a12334-c5a3-11e9-822c-c381a7805210/ssl/179227 HTTP/1.1 Content-Type: application/json Accept: application/json
Example response:
HTTP/1.1 200 OK Content-Type: application/json { "activeCount": 2, "activeDomains": "*.example.com,example.com", "activeServiceIds": [ 2017537 ], "activeSubdomains": [ "*.example.com", "example.com" ], "altNames": "*.example.com,example.com", "cert": "-----BEGIN CERTIFICATE----- ...", "chain": "-----BEGIN CERTIFICATE----- ...", "expireDate": 1574321006, "id": 179227, "key": "-----BEGIN RSA PRIVATE KEY----- ...", "subject": "CN=*.example.com" }
- GET /v2/storage/(uuid)/ssl/dns/(name)¶
Get SSL certificate(s) by DNS identifier.
Example request:
GET /v2/storage/d0a12334-c5a3-11e9-822c-c381a7805210/ssl/dns/*.example.com HTTP/1.1 Content-Type: application/json Accept: application/json
Example response:
HTTP/1.1 200 OK Content-Type: application/json { "items": [ { "activeCount": 2, "activeDomains": "*.example.com,example.com", "activeServiceIds": [ 2017537 ], "activeSubdomains": [ "*.example.com", "example.com" ], "altNames": "*.example.com,example.com", "cert": "-----BEGIN CERTIFICATE----- ...", "chain": "-----BEGIN CERTIFICATE----- ...", "expireDate": 1574321006, "id": 179227, "key": "-----BEGIN RSA PRIVATE KEY----- ...", "subject": "CN=*.example.com" } ], "pager": { "items": 1, "page": 1, "pagesize": null } }
- POST /v2/storage/(uuid)/ssl¶
Insert a new SSL certificate. Optionally specify which FQDNs should use this certificate by passing them in the domains parameter.
- Request JSON Object:
key (string) – SSL certificate key
cert (string) – SSL certificate
chain (string) – CA intermediate certificate chain
domains[string] (list) – list of FQDNs that should use this cert
activeServiceIds[int] (list) – list of service IDs that should use this cert
Key, cert and chain should pe posted as one-liners. Using activeServiceIds is not recommended and only here for convenience. It will get a list of subdomains from indicated services and proceed as if a list of domains was passed; there is no FK relation.
- Status Codes:
200 OK – no error
404 Not Found – Storage not found
500 Internal Server Error – validation error
Example request:
POST /v1/<UUID>/ssl HTTP/1.1 Content-Type: application/json Accept: application/json { "cert": "-----BEGIN CERTIFICATE----- ...", "key": "-----BEGIN PRIVATE KEY----- ...", "chain": "-----BEGIN CERTIFICATE----- ...", "domains": ["nicereply.com", "*.nicereply.com"] }
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "async_tasks": { "set_mcdb": "69eb2d28-c4af-11e9-91cb-9ffaf0077f08" }, "item": { "id": 1, "key": "-----BEGIN PRIVATE KEY----- ...", "cert": "-----BEGIN CERTIFICATE----- ...", "chain": "-----BEGIN CERTIFICATE----- ...", "subject": "OU=Domain Control Validated, OU=Provided by DOMENY.PL sp. z o.o.", "altNames": "nicereply.com,*.nicereply.com", "expireDate": 1534431694, "activeCount": 1, "activeDomains": "nicereply.com,*.nicereply.com", "activeSubdomains": ["nicereply.com", "*.nicereply.com"], "activeServiceIds": [] } }
Example response - Storage not found:
HTTP/1.1 404 Not Found Content-Type: application/json { "status": "error", "error": "Storage does not exist" }
- PUT /v2/storage/(uuid)/ssl/(ssl_id)¶
Update an existing SSL certificate.
- Request JSON Object:
key (string) – SSL certificate key
cert (string) – SSL certificate
chain (string) – CA intermediate certificate chain
domains[string] (list) – list of FQDNs that should use this cert
activeServiceIds[int] (list) – list of service IDs that should use this certificate
- DELETE /v2/storage/(uuid)/ssl/(ssl_id)¶
Delete an SSL certificate along with active configurations.
DELETE /v2/storage/a17fb16a-c5a3-11e9-a37e-f78545774a41/ssl/1234 HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "item": { "altNames": "example.com", "cert": "-----BEGIN CERTIFICATE----- ...", "chain": "-----BEGIN CERTIFICATE----- ...", "createDate": 1536953064.0, "csr": "-----BEGIN CERTIFICATE REQUEST----- ...", "domain": "example.com", "expireDate": 1536283780.0, "id": 1234, "key": "-----BEGIN RSA PRIVATE KEY----- ...", "renewalDate": 1538518570.0, "renewalError": null, "revoked": true, "subject": "CN=example.com" } }
- POST /v2/storage/(uuid)/service/(service_id)/ssl¶
Sets SSL certificate that will be used by this service (or more precisely, the FQDN that is associated with this service).
Pass either storageSSLId to use an existing certificate, key, cert and chain to create a new certificate, or both to update an existing certificate (useful when doing a renewal).
Note for the latter: since more services may share the same subdomain, and many services may use a single SSL certificate, updating an existing certificate here will also effectively update it for all other services that were using it. If this behavior is undesirable, simply omit storageSSLId.
- Request JSON Object:
storageSSLId (int) – ID of an existing SSL certificate
key (string) – SSL certificate key
cert (string) – SSL certificate
chain (string) – CA intermediate certificate chain
Example request:
POST /v1/<UUID>/service/1/ssl HTTP/1.1 Content-Type: application/json Accept: application/json { "cert": "-----BEGIN CERTIFICATE----- ...", "key": "-----BEGIN PRIVATE KEY----- ...", "chain": "-----BEGIN CERTIFICATE----- ..." }
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "item": { "id": 1, "storageSSL": { "id": 1, "key": "-----BEGIN PRIVATE KEY----- ...", "cert": "-----BEGIN CERTIFICATE----- ...", "chain": "-----BEGIN CERTIFICATE----- ...", "subject": "OU=Domain Control Validated, OU=Provided by DOMENY.PL sp. z o.o.", "altNames": "nicereply.com,*.nicereply.com", "expireDate": 1534431694, "activeCount": 1, "activeDomains": "nicereply.com,*.nicereply.com", "activeSubdomains": ["nicereply.com", "*.nicereply.com"], "activeServiceIds": [1] }, "sub": "" } }
- PUT /v2/storage/(uuid)/service/(service_id)/ssl¶
Sets SSL certificate that will be used by this service (or more precisely, the FQDN that is associated with this service).
Pass either storageSSLId to use an existing certificate, key, cert and chain to create a new certificate, or both to update an existing certificate (useful when doing a renewal).
Note for the latter: since more services may share the same subdomain, and many services may use a single SSL certificate, updating an existing certificate here will also effectively update it for all other services that were using it. If this behavior is undesirable, simply omit storageSSLId.
- Request JSON Object:
storageSSLId (int) – ID of an existing SSL certificate
key (string) – SSL certificate key
cert (string) – SSL certificate
chain (string) – CA intermediate certificate chain
Example request:
POST /v1/<UUID>/service/1/ssl HTTP/1.1 Content-Type: application/json Accept: application/json { "cert": "-----BEGIN CERTIFICATE----- ...", "key": "-----BEGIN PRIVATE KEY----- ...", "chain": "-----BEGIN CERTIFICATE----- ..." }
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "item": { "id": 1, "storageSSL": { "id": 1, "key": "-----BEGIN PRIVATE KEY----- ...", "cert": "-----BEGIN CERTIFICATE----- ...", "chain": "-----BEGIN CERTIFICATE----- ...", "subject": "OU=Domain Control Validated, OU=Provided by DOMENY.PL sp. z o.o.", "altNames": "nicereply.com,*.nicereply.com", "expireDate": 1534431694, "activeCount": 1, "activeDomains": "nicereply.com,*.nicereply.com", "activeSubdomains": ["nicereply.com", "*.nicereply.com"], "activeServiceIds": [1] }, "sub": "" } }
- POST /v2/storage/csr¶
Provision a new CSR.
A new RSA private key is generated for each request.
- <json string domain:
desired Common Name of the certificate
- <json string organization:
Organization Name (optional, default: “Websupport, s.r.o.”)
- <json string organization_unit:
Organizational Unit Name (optional, default: “IT”)
- <json string city:
Location (optional, default: “Bratislava”)
- <json string state:
State or Province Name (optional, default: “Slovakia”)
- <json string country:
Country Name (optional, default: “SK”)
Example request:
POST /v2/storage/csr HTTP/1.1 Content-Type: application/json Accept: application/json { "domain": "example.com" }
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "item": { "id": 12345, "createTime": 1607152713, "domain": "example.com", "csr": "-----BEGIN CERTIFICATE REQUEST-----
- MIIEyzCCAr …”,
“rsa_key”: “—–BEGIN RSA PRIVATE KEY—–
- MIIJKQIBAA …”,
}
}
LetsEncrypt¶
Issue and revoke free SSL certificates using LetsEncrypt API
Resource |
Operation |
Description |
|---|---|---|
LetsEncrypt |
list domain certificates |
|
get certificate |
||
get ARI information |
||
delete certificate |
||
renew certificate |
||
issue a new certificate |
||
issue a new certificate for domain with active Storage. |
||
revoke certificate |
- GET /.well-known/acme-challenge/ping¶
Returns “pong”.
Used to check whether the Nginx passthrough for http-01 challenges is set up correctly. If a request to http://<domain>/.well-known/acme-challenge/ping returns “pong”, we’re able to issue non-wildcard certificates for it.
- GET /.well-known/acme-challenge/(token)¶
- GET /v2/letsencrypt/challenge/(token)¶
Returns an encoded response to a LetsEncrypt http-01 challenge.
Used for issuing non-wildcard certificates using LetsEncrypt.
- GET /v2/letsencrypt/account¶
List known LetsEncrypt accounts.
- GET /v2/letsencrypt/account/(int: account_id)¶
Show LetsEncrypt account details.
- PUT /v2/letsencrypt/account/(int: account_id)/enable¶
Enable a LetsEncrypt account.
- DELETE /v2/letsencrypt/account/(int: account_id)¶
Disable a LetsEncrypt account.
- PUT /v2/letsencrypt/account/(int: account_id)/disable¶
Disable a LetsEncrypt account.
- POST /v2/letsencrypt/account¶
- POST /v2/letsencrypt/new-account¶
Create a new LetsEncrypt account.
Generates a new private key, requests a new account via LetsEncrypt API, and stores both the key and account url (“kid”) to database.
https://tools.ietf.org/html/draft-ietf-acme-acme#section-7.3
Example request:
POST /v2/letsencrypt/account HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "message": "Registered", "kid": "https://acme-v02.api.letsencrypt.org/acme/acct/12345678" "item": { "id": 1, "kid": "https://acme-v02.api.letsencrypt.org/acme/acct/12345678", "active": True, "comment": None, "createTime": 1234567890, "updateTime": 1234567890 } }
- GET /v2/letsencrypt/(domain)¶
List LetsEncrypt certificates issued for
domain.GET /v2/letsencrypt/example.com HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "items": [ { "altNames": "test.example.com", "cert": "-----BEGIN CERTIFICATE----- ...", "chain": "-----BEGIN CERTIFICATE----- ...", "createDate": 1536953064.0, "csr": "-----BEGIN CERTIFICATE REQUEST----- ...", "domain": "example.com", "expireDate": 1536283780.0, "id": 54727, "key": "-----BEGIN RSA PRIVATE KEY----- ...", "renewalDate": 1538518570.0, "renewalError": "http-01: NXDOMAIN looking up A for test.example.com", "revoked": false, "subject": "CN=test.example.com" }, { "altNames": "example.com,www.example.com", "cert": "-----BEGIN CERTIFICATE----- ...", "chain": "-----BEGIN CERTIFICATE----- ...", "createDate": 1546953064.0, "csr": "-----BEGIN CERTIFICATE REQUEST----- ...", "domain": "example.com", "expireDate": 1566283780.0, "id": 54728, "key": "-----BEGIN RSA PRIVATE KEY----- ...", "renewalDate": 1558518570.0, "renewalError": null, "revoked": false, "subject": "CN=www.example.com" } ], "pager": { "items": 2, "page": 1, "pagesize": null } }
- GET /v2/letsencrypt/(domain)/(ssl_id)¶
Get a LetsEncrypt certificate by domain and id.
GET /v2/letsencrypt/example.com/54728 HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "altNames": "example.com,www.example.com", "cert": "-----BEGIN CERTIFICATE----- ...", "chain": "-----BEGIN CERTIFICATE----- ...", "createDate": 1546953064.0, "csr": "-----BEGIN CERTIFICATE REQUEST----- ...", "domain": "example.com", "expireDate": 1566283780.0, "id": 54728, "key": "-----BEGIN RSA PRIVATE KEY----- ...", "renewalDate": 1558518570.0, "renewalError": null, "revoked": false, "subject": "CN=www.example.com" }
- GET /v2/letsencrypt/(domain)/(ssl_id)/ari-info¶
Get ARI information for a certificate by domain and id.
Displays ARI certificate ID and ideal renewal window - both one that’s requested from ACME API directly, and one we calculate by ourselves. These don’t always line up completely.
GET /v2/letsencrypt/example.com/54728/ari HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "ari_id": "56ufDywzoFPTXk94yLKEDjvWkjM.BhQl0s4X-V6_3yZYTelHzyQ6", "ari_url": "https://acme-v02.api.letsencrypt.org/acme/renewal-info/56ufDywzoFPTXk94yLKEDj...", "ari_response": { "suggestedWindow": { "start": "2025-11-16T19:08:00Z", "end": "2025-11-18T14:18:49Z" } }, "calculated_renewal_window": { "start": "2025-11-16T19:08:00+00:00", "end": "2025-11-18T14:18:49+00:00", } }
- DELETE /v2/letsencrypt/(domain)/(ssl_id)¶
Delete a LetsEncrypt certificate. For revoking the certificate first, see
/v2/letsencrypt/revoke/<ssl_id>.This method does not deactivate certificates that are set up via
/v2/storage/<UUID>/ssl, as they use a different certificate store.GET /v2/letsencrypt/example.com/54728 HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "item": { "altNames": "example.com,www.example.com", "cert": "-----BEGIN CERTIFICATE----- ...", "chain": "-----BEGIN CERTIFICATE----- ...", "createDate": 1546953064.0, "csr": "-----BEGIN CERTIFICATE REQUEST----- ...", "domain": "example.com", "expireDate": 1566283780.0, "id": 54728, "key": "-----BEGIN RSA PRIVATE KEY----- ...", "renewalDate": 1558518570.0, "renewalError": null, "revoked": false, "subject": "CN=www.example.com" } }
- PUT /v2/letsencrypt/(domain)/(ssl_id)¶
- PUT /v2/letsencrypt/renew/(ssl_id)¶
Renew a LetsEncrypt certificate.
Will attempt to match configured active certificates in other certificate stores and update them on successful renewal.
PUT /v2/letsencrypt/example.com/54728 HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "item": { "altNames": "example.com,www.example.com", "cert": "-----BEGIN CERTIFICATE----- ...", "chain": "-----BEGIN CERTIFICATE----- ...", "createDate": 1546953064.0, "csr": "-----BEGIN CERTIFICATE REQUEST----- ...", "domain": "example.com", "expireDate": 1566283780.0, "id": 54728, "key": "-----BEGIN RSA PRIVATE KEY----- ...", "renewalDate": 1558518570.0, "renewalError": null, "revoked": false, "subject": "CN=www.example.com" }, "async_tasks": { "set_mcdb": "ba27dfa6-c582-11e9-81d0-93ca4401da60" } }
- POST /v2/letsencrypt/(domain)¶
Request a new certificate from LetsEncrypt.
Uses
DNS-01challenge for wildcard certificates andHTTP-01for all others. This means the domain has to either use our nameservers (wildcard certificates) or point theArecord to our webservers (for regular certificates).Example request - single certificate:
POST /v2/letsencrypt/example.com HTTP/1.1 Content-Type: application/json Accept: application/json { "subdomains": ["", "www"] }
Example request - wildcard certificate:
POST /v2/letsencrypt/example.com HTTP/1.1 Content-Type: application/json Accept: application/json { "subdomains": ["*"] }
Example request - mixed certificate:
POST /v2/letsencrypt/example.com HTTP/1.1 Content-Type: application/json Accept: application/json { "subdomains": ["", "*"] }
Example request - wildcard certificate for 3rd level domain:
POST /v2/letsencrypt/example.com HTTP/1.1 Content-Type: application/json Accept: application/json { "subdomains": ["*.subdomain"] }
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "item": { "id": 1, "domain": "example.com", "csr": "---BEGIN CERTIFICATE REQUEST--- ...", "key": "---BEGIN RSA PRIVATE KEY--- ...", "cert": "---BEGIN CERTIFICATE--- ...", "chain": "---BEGIN CERTIFICATE--- ...", "subject": "CN=example.com", "altNames": "example.com,www.example.com", "revoked": false, "createDate": 1515582789.0, "expireDate": 1565905305.0, "renewalDate": 1515582789.0, "renewalError": null } }
Example response - error:
HTTP/1.1 200 OK Content-Type: application/json { "status": "error", "error": { "domain": ["http-01: NXDOMAIN looking for example.com"] } }
- POST /v2/letsencrypt/(domain)/async¶
Request a new certificate from LetsEncrypt for domain with active Storage.
Uses
DNS-01challenge for wildcard certificates andHTTP-01for all others. This means the domain has to either use our nameservers (wildcard certificates) or point theArecord to our webservers (for regular certificates).- Request JSON Object:
subdomains (list[str]) – List of subdomains to issue the certificate for.
delay (int) – Time in seconds to wait before issuing the certificate.
Example request - single certificate:
POST /v2/letsencrypt/example.com HTTP/1.1 Content-Type: application/json Accept: application/json { "subdomains": ["", "www"], "delay": 600 }
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "task_id": "45f0318f-32lb-4x58-af40-fafd213e95ce" }
- PUT /v2/letsencrypt/revoke/(ssl_id)¶
Revoke a LetsEncrypt certificate via ACME API. Does not attempt to revoke already expired certificates, but will simply mark them as evoked.
PUT /v2/letsencrypt/revoke/1234 HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "item": { "altNames": "example.com", "cert": "-----BEGIN CERTIFICATE----- ...", "chain": "-----BEGIN CERTIFICATE----- ...", "createDate": 1536953064.0, "csr": "-----BEGIN CERTIFICATE REQUEST----- ...", "domain": "example.com", "expireDate": 1536283780.0, "id": 1234, "key": "-----BEGIN RSA PRIVATE KEY----- ...", "renewalDate": 1538518570.0, "renewalError": null, "revoked": true, "subject": "CN=example.com" } }
FTP¶
Add, remove and configure FTP accounts
Resource |
Operation |
Description |
|---|---|---|
FTP |
list FTP accounts for Storage |
|
list FTP accounts for multiple Storages |
||
get FTP account by id |
||
create FTP account |
||
update an FTP account by id |
||
delete an FTP account by id |
||
check login for duplicates |
||
Temporary FTP |
get temporary FTP account details |
|
create temporary FTP account |
||
delete temporary FTP account |
- GET /v2/storage/(uuid)/ftp¶
List of all FTP accounts under Storage specified by UUID.
Example request:
GET /v2/<UUID>/ftp HTTP/1.1 Content-Type: application/json Accept: application/json
Example response:
HTTP/1.1 200 OK Content-Type: application/json { "items": [ { "countries": [ "SK", "CZ", "HU" ], "countryCheck": true, "createTime": 1489736457, "dir": "", "disabled": false, "ftpEnabled": true, "id": 2, "ipCheck": false, "ips": [], "ips_v6": [], "login": "example.com", "note": "", "password": "{sha256}qEg6b/jphztLRYC3wd0fo+YmIGqWRpIJ1veWfCl86wY=", "sshEnabled": true, "storage": { "id": 55363, "createTime": 1411978388, "updateTime": 1411978388, "uuid": "816e9892-c580-11e8-b389-fba089f55f59" "domain": "example.com", "uid": 1005, "gid": 1005, "limitBytes": 0, "disabled": false, "deleted": false, "disabledChangeTime": null, "deletedChangeTime": null, "rootPath": "/data/e/x/example.com", "storagePool": { "id": 1, }, "server": { "id": 3, "host": "web-1", "group": "it13", }, "filesEnabled": true, "scheduledToDelete": null }, "temporary": false } ], "pager": { "items": 1, "page": 1, "pagesize": null } }
- POST /v2/storage/ftp/check-multiple¶
List FTP accounts for Storages specified in the POST request.
- Request JSON Object:
data (obj) – list of UUIDs
- Query Parameters:
draw – draw parameter
page – page offset number (default is 1)
pagesize – page size; return all results if omitted
search – filter results by searching in all columns
search.column_name – filter results by specified column
sort[column_name] – sort by column, set to “desc” or “reverse” for reverse sort
sort.column_name – same as above
sort – sort by column name
reverse – flags previous sort key as reverse, accepts “true”/”false” (default “false”)
- Response JSON Object:
recordsTotal – total record count before filtering
recordsFiltered – total record count after filtering (using
search*query parameters)pager.page – current page
pager.pagesize – page size
pager.items – number of records displayed on current page
Filtering results
Results may be filtered by passing either
search=substringorsearch.<column name>=substringin the query string.Only top-level objects are searched, filtering in nested object contents is not supported.
Sorting results
Chaining sort expressions is supported, order in which they appear in the query string is taken into consideration.
sort[name]=descis the same assort.name=descis the same assort=name&reverse=true.Paging
Use
pagesizequery parameter to specify page size, andpageto specify page number. Negative values are not supported.Example request
GET /v2/storage/ftp/check-multiple?draw=123&search.login=test&sort.login=desc HTTP/1.1 Content-Type: application/json Accept: application/json ["625eb1d4-6b66-4d89-9101-5bf200f18b99"]
Example response
HTTP/1.1 200 OK Content-Type: application/json { "draw": 123, "items": [ { "id": 1, "login": "testing", "comment": "fields omitted for brevity" "storage": { "id": 12345, "uuid": "625eb1d4-6b66-4d89-9101-5bf200f18b99", "domain": "example.com" } } ], "pager": { "items": 2, "page": 1, "pagesize": 2 }, "recordsFiltered": 2, "recordsTotal": 3 }
- GET /v2/storage/ftp/check-multiple¶
List FTP accounts for Storages specified in the POST request.
- Request JSON Object:
data (obj) – list of UUIDs
- Query Parameters:
draw – draw parameter
page – page offset number (default is 1)
pagesize – page size; return all results if omitted
search – filter results by searching in all columns
search.column_name – filter results by specified column
sort[column_name] – sort by column, set to “desc” or “reverse” for reverse sort
sort.column_name – same as above
sort – sort by column name
reverse – flags previous sort key as reverse, accepts “true”/”false” (default “false”)
- Response JSON Object:
recordsTotal – total record count before filtering
recordsFiltered – total record count after filtering (using
search*query parameters)pager.page – current page
pager.pagesize – page size
pager.items – number of records displayed on current page
Filtering results
Results may be filtered by passing either
search=substringorsearch.<column name>=substringin the query string.Only top-level objects are searched, filtering in nested object contents is not supported.
Sorting results
Chaining sort expressions is supported, order in which they appear in the query string is taken into consideration.
sort[name]=descis the same assort.name=descis the same assort=name&reverse=true.Paging
Use
pagesizequery parameter to specify page size, andpageto specify page number. Negative values are not supported.Example request
GET /v2/storage/ftp/check-multiple?draw=123&search.login=test&sort.login=desc HTTP/1.1 Content-Type: application/json Accept: application/json ["625eb1d4-6b66-4d89-9101-5bf200f18b99"]
Example response
HTTP/1.1 200 OK Content-Type: application/json { "draw": 123, "items": [ { "id": 1, "login": "testing", "comment": "fields omitted for brevity" "storage": { "id": 12345, "uuid": "625eb1d4-6b66-4d89-9101-5bf200f18b99", "domain": "example.com" } } ], "pager": { "items": 2, "page": 1, "pagesize": 2 }, "recordsFiltered": 2, "recordsTotal": 3 }
- GET /v2/storage/(uuid)/ftp/(ftp_id)¶
Get FTP account details by its ID
- POST /v2/storage/(uuid)/ftp¶
Create an FTP account.
Required parameters:
- Request JSON Object:
login (string) – desired FTP login
password (string) – FTP password in plaintext
dir (string) – relative directory
Optional parameters:
- Request JSON Object:
note (string) – text comment
ipCheck (bool) – enable login restriction by IP address/range
countryCheck (bool) – enable login restriction by country
ips (obj) – list of allowed IPs and/or ranges (CIDR format)
countries (obj) – list of ISO allowed country codes
disabled (bool)
ftpEnabled (bool) – enable/disable FTP access
sshEnabled (bool) – enable/disable SFTP access
Example request:
POST /v2/<UUID>/ftp HTTP/1.1 Content-Type: application/json Accept: application/json { "login": "test.example.com", "password": "the stronkest password", "dir": "", "ipCheck": true, "ips": [ "192.168.0.0/16" ], "ips_v6": [ 2a01::1/64" ], "countryCheck": true, "countries": [ "SK", "CZ", "HU" ] }
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "item": { "id": 2, "login": "test.example.com", "password": "the stronkest password", "dir": "", "ipCheck": true, "ips": [ "192.168.0.0/16" ], "ips_v6": [ 2a01::1/64" ], "countryCheck": true, "countries": [ "SK", "CZ", "HU" ] } }
- PUT /v2/storage/(uuid)/ftp¶
Update all FTP accounts data on ingress servers.
Example request:
PUT /v2/<UUID>/ftp HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "items": [{ "id": 2, "login": "test.example.com", "password": "the stronkest password", "dir": "", "ipCheck": true, "ips": [ "192.168.0.0/16" ], "countryCheck": true, "countries": [ "SK", "CZ", "HU" ] }] "async_tasks": ["625eb1d4-6b66-4d89-9101-5bf200f18b99"] }
- PUT /v2/storage/(uuid)/ftp/(ftp_id)¶
Update an FTP account.
Required parameters:
- Request JSON Object:
login (string) – desired FTP login
password (string) – FTP password in plaintext
dir (string) – relative directory
Example request:
PUT /v2/<UUID>/ftp/2 HTTP/1.1 Content-Type: application/json Accept: application/json { "login": "test.example.com", "password": "the stronkest password", "dir": "", "disabled": true }
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "item": { "id": 2, "login": "test.example.com", "password": "the stronkest password", "dir": "", "ipCheck": true, "ips": [ "192.168.0.0/16" ], "ips_v6": [ 2a01::1/64" ], "countryCheck": true, "countries": [ "SK", "CZ", "HU" ] } }
- DELETE /v2/storage/(uuid)/ftp/(ftp_id)¶
Hard delete an FTP account.
- GET /v2/storage/ftp/check-duplicity/(login)¶
Check for duplicate login before attempting to create FTP account.
Example request:
GET /v2/check-duplicity/test.example.com HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - login is present:
HTTP/1.1 200 OK Content-Type: application/json true
- GET /v2/storage/(uuid)/temporary-ftp¶
Get temporary FTP account if present.
Example request:
GET /v2/storage/<UUID>/temporary-ftp HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - temp FTP account not present:
HTTP/1.1 200 OK Content-Type: application/json { "login": "", "message": "No active account exists", "password": "", "status": "error" }
Example response - temp FTP account present:
HTTP/1.1 200 OK Content-Type: application/json { "login": "8cb1a8bahelpdesk.halka.sk", "password": "d2dd1472", "status": "success", "storage": { "createEnabled": true, "group": "local", "host": "ftp.websupport.sk", "hostname": "web-1", "id": 79, "nfsMountpoint": "/nfsmnt/web-1" } }
- POST /v2/storage/(uuid)/temporary-ftp¶
Create a temporary FTP account. This account has a lifetime of one hour after which it’ll be disabled if not deleted explicitly.
Example request:
POST /v2/storage/<UUID>/temporary-ftp HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "login": "8cb1a8bahelpdesk.halka.sk", "password": "d2dd1472", "status": "success", "storage": { "createEnabled": true, "group": "local", "hostname": "web-1", "id": 79, "nfsMountpoint": "/nfsmnt/web-1" } }
Example response - temp FTP account already present:
HTTP/1.1 500 Internal Server Error Content-Type: application/json { "error": "Temporary FTP is already active" }
- DELETE /v2/storage/(uuid)/temporary-ftp¶
Deactivate the temporary FTP account.
Example request:
DELETE /v2/storage/<UUID>/temporary-ftp HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "message": "Deleted temporary account 8cb1a8bahelpdesk.halka.sk", "status": "success" }
Example response - no account present:
HTTP/1.1 200 OK Content-Type: application/json { "message": "No active account found for halka.sk", "status": "error" }
Restore¶
Restoring contents of FTP from backup
Resource |
Operation |
Description |
|---|---|---|
Restore |
show restore info |
|
list snapshots |
||
browse snapshot filesystem |
||
browse current filesystem |
||
create folder |
||
list jobs |
||
show job |
||
restore from snapshot |
- GET /v2/restore/(domain_or_uuid)/info¶
List hosting backup info.
This is one of the few endpoints where domain is still accepted (and widely used) instead of just UUID. Currently it’s only used when rendering “edit service” view in helpdesk app.
Example request:
POST /v2/restore/625eb1d4-6b66-4d89-9101-5bf200f18b99/info HTTP/1.1 Content-Type: application/json Accept: application/json
Equivalent request using domain (deprecated):
POST /v2/restore/example.com/info HTTP/1.1 Content-Type: application/json Accept: application/json
Example response:
HTTP/1.1 200 OK Content-Type: application/json { "arch": "local", "backup_path": [ "web-94", "/data/.zfs/snapshot/2019-05-22-23:00:04/6/2/625eb1d4-6b66-4d89-9101-5bf200f18b99" ], "host": "web-94", "path": "/nfsmnt/hosting1_2/6/2/625eb1d4-6b66-4d89-9101-5bf200f18b99" }
- GET /v2/restore/(uuid)/backups¶
List available snapshots for hosting storage.
Example request:
POST /v2/restore/625eb1d4-6b66-4d89-9101-5bf200f18b99/backups HTTP/1.1 Content-Type: application/json Accept: application/json
Example response:
HTTP/1.1 200 OK Content-Type: application/json { "items": { "2023-03-10-18:30:27": "", "2023-03-11-18:30:32": "", "2023-03-12-18:30:25": "", "2023-03-13-18:30:20": "", "2023-03-14-18:30:34": "", "2023-03-15-18:30:20": "", "2023-03-16-18:30:34": "", "2023-03-17-18:30:27": "", "2023-03-18-18:30:20": "", "2023-03-19-18:30:15": "", "2023-03-20-18:30:23": "", "2023-03-21-18:30:33": "", "2023-03-22-18:30:16": "", "2023-03-23-18:30:22": "" } }
- GET /v2/restore/(uuid)/backups/(snapshot)¶
Browse filesystem of a particular snapshot.
- Request JSON Object:
dir (string) – (optional) relative path
Example request:
GET /v2/restore/625eb1d4-6b66-4d89-9101-5bf200f18b99/backups/2023-03-23-18:30:22 HTTP/1.1 Content-Type: application/json Accept: application/json { "dir": ".tmp" }
Example response:
HTTP/1.1 200 OK Content-Type: application/json { "items": { "upload": { "atime": 1676899264.46657, "ctime": 1677505795.9872718, "gid": 2024955, "mode": { "is_blk": false, "is_chr": false, "is_dir": true, "is_fifo": false, "is_lnk": false, "is_reg": false, "is_sock": false, "perm": "0o770" }, "mtime": 1676899264.46657, "size": 0, "uid": 0 } } }
- GET /v2/restore/(uuid)/current¶
Browse current filesystem for hosting.
- Request JSON Object:
dir (string) – (optional) relative path
Example request:
GET /v2/restore/625eb1d4-6b66-4d89-9101-5bf200f18b99/current HTTP/1.1 Content-Type: application/json Accept: application/json { "dir": ".tmp" }
Example response:
HTTP/1.1 200 OK Content-Type: application/json { "items": { "upload": { "atime": 1676899264.46657, "ctime": 1677505795.9872718, "gid": 2024955, "mode": { "is_blk": false, "is_chr": false, "is_dir": true, "is_fifo": false, "is_lnk": false, "is_reg": false, "is_sock": false, "perm": "0o770" }, "mtime": 1676899264.46657, "size": 0, "uid": 0 } } }
- POST /v2/restore/(uuid)/mkdir¶
Create a new folder.
- Request JSON Object:
dir (string) – (optional) relative path
name (string) – name of the folder to create
POST /v2/restore/625eb1d4-6b66-4d89-9101-5bf200f18b99 HTTP/1.1 Content-Type: application/json Accept: application/json { "dir": "example/com/www", "name": "new_folder" }
Example response:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success" }
- GET /v2/restore/(uuid)¶
List previous restore jobs
Example request:
GET /v2/restore/625eb1d4-6b66-4d89-9101-5bf200f18b99 HTTP/1.1 Content-Type: application/json Accept: application/json { "restoreDomainDataUuid": "880b994d-7231-4b21-89d0-71bcbd93f7b6" }
Example response:
HTTP/1.1 200 OK Content-Type: application/json { "items": [ { "createTime": 1490021820, "domain": "example.com", "finishTime": 1490021822, "id": 20932, "message": "", "sourceDir": ".../snapshot/2017-02-28-22:35:09/6/2/625eb1d4-...-f18b99/example.com", "sourceServer": "backup5", "startTime": 1490021820, "status": "DONE", "targetDir": "/data/6/2/625eb1d4-6b66-4d89-9101-5bf200f18b99/test", "targetServer": "web-64", "restoreDomainDataUuid": "880b994d-7231-4b21-89d0-71bcbd93f7b6" } ], "pager": { "items": 0, "page": 1, "pagesize": null } }
- GET /v2/restore/(uuid)/(int: restore_id)¶
Show restore job by id.
Example request:
GET /v2/restore/625eb1d4-6b66-4d89-9101-5bf200f18b99/20932 HTTP/1.1 Content-Type: application/json Accept: application/json
Example response:
HTTP/1.1 200 OK Content-Type: application/json { "createTime": 1490021820, "domain": "example.com", "finishTime": 1490021822, "id": 20932, "message": "", "sourceDir": ".../snapshot/2017-02-28-22:35:09/6/2/625eb1d4-...-f18b99/example.com", "sourceServer": "backup5", "startTime": 1490021820, "status": "DONE", "targetDir": "/data/6/2/625eb1d4-6b66-4d89-9101-5bf200f18b99/test", "targetServer": "web-64" }
- POST /v2/restore/(uuid)¶
Restore folder or file from snapshot.
Note: this endpoint no longer accepts domain names, only Storage UUIDs. No requests containing domains were recorded since well before the start of 2023.
When restoring a folder, both
sourceDirandtargetDirneed to be specified. The current contents oftargetDirwill be moved prior to restore, unlessskip_backupis set.When
sourceFileis specified, a single file in this path will be restored in-place. All other arguments (exceptdateandskip_backup) are ignored.- Request JSON Object:
date (string) – snapshot date (name of the snapshot)
sourceFile (string) – relative path to file (restore single file in-place)
sourceDir (string) – relative path to directory to be restored
targetDir (string) – relative path where to restore contents of
sourceDirskip_backup (bool) – do not move existing target to a new location before restore (defaults to
false)
- Status Codes:
200 OK – no error
400 Bad Request – validation error
404 Not Found – storage, domain, snapshot or folder not found
500 Internal Server Error – files disabled, restore already running, internal error
Example request - restore folder:
GET /v2/restore/625eb1d4-6b66-4d89-9101-5bf200f18b99/20932 HTTP/1.1 Content-Type: application/json Accept: application/json { "date": "2017-02-28-22:35:09", "sourceDir": "example.com", "targetDir": "test", "skip_backup": false }
Example request - restore file:
GET /v2/restore/625eb1d4-6b66-4d89-9101-5bf200f18b99/20932 HTTP/1.1 Content-Type: application/json Accept: application/json { "date": "2017-02-28-22:35:09", "sourceFile": "example.com/info.php", "skip_backup": false }
Example response:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", item = { "createTime": 1490021820, "domain": "example.com", "finishTime": 1490021822, "id": 20932, "message": "", "sourceDir": ".../snapshot/2017-02-28-22:35:09/6/2/625eb1d4-...-5bf18b99/example.com", "sourceServer": "backup5", "startTime": 1490021820, "status": "QUEUED", "targetDir": "/data/6/2/625eb1d4-6b66-4d89-9101-5bf200f18b99/test", "targetServer": "web-64" }, "task_id": "b6128f94-ccac-11ed-8e19-c7670bae6ed6" }
Cron¶
Manipulating scheduled tasks
Resource |
Operation |
Description |
|---|---|---|
Crontab |
refrest crontabs |
- PUT /v2/storage/refresh-crontabs¶
Refresh crontabs for servers.
Example request:
PUT /v2/storage/refresh-crontabs HTTP/1.1 Content-Type: application/json Accept: application/json { "servers" : [1, 2, 3, "web-100"] }
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "task_ids": [ "ff130a62-7bd0-49df-8a68-11ed9c769287", "8b48e036-2a08-4881-bb72-74acb7046ca9", "cc0f1baf-d625-49e5-8a79-94cb0bea7081", "f0f301b2-1bb1-4e25-9c01-e91417c2ad54" ] "error": null }
Htaccess¶
Manipulating .htaccess files
Logs¶
Accessing Apache access/error logs
Resource |
Operation |
Description |
|---|---|---|
Logs |
list of log files |
|
GET /v2/storage/(uuid)/virtualhost/(vhost_id)/logs/(file_name) |
Get logs file content |
|
Get compressed log files |
- GET /v2/storage/(uuid)/virtualhost/(vhost_id)/logs¶
List of all available log files
Example request:
GET /v2/<uuid>/virtualhost/<vhost_id>/logs HTTP/1.1 Accept: application/json
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "items": { "access_log": { "atime": 1576502426.2307496, "ctime": 1576483631.9866045, "gid": 0, "mode": 33188, "mtime": 1576483631.9866045, "size": 495, "uid": 0 }, "access_log-2019-12-14.gz": { "atime": 1576360684.315062, "ctime": 1576364463.3059802, "gid": 0, "mode": 33188, "mtime": 1576355575.321021, "size": 262, "uid": 0 }, "access_log-2019-12-15.gz": { "atime": 1576441146.5722764, "ctime": 1576450862.7608495, "gid": 0, "mode": 33188, "mtime": 1576434504.187748, "size": 243, "uid": 0 } } }
- GET /v2/storage/(uuid)/virtualhost/(vhost_id)/logs/(file_name)¶
Get logs file content
Example request
GET /v2/<uuid>/virtualhost/<vhost_id>/logs/<file_name> HTTP/1.1 Accept: */*
Example response
HTTP/1.1 200 OK Content-Type: application/octet-stream domain.sk 185.110.144.25 - - [17/Dec/2019:07:43:13 +0100] "GET / HTTP/1.1" 200 55 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Safari/605.1.15" 0.003 MISS 10.10.153.26:80 0.004 domain.sk 185.110.144.25 - - [17/Dec/2019:07:43:13 +0100] "GET /favicon.ico HTTP/1.1" 404 194 "http://domain.sk/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Safari/605.1.15" 0.001 MISS 10.10.153.26:80 0.000
Example request
GET /v2/<uuid>/virtualhost/<vhost_id>/logs/<file_name>?format=parsed HTTP/1.1 Accept: */*
Example response
HTTP/1.1 200 OK Content-Type: application/json { "items": [ { "body_bytes_sent": "55", "http_host": "domain.sk", "http_referer": "-", "http_user_agent": "Mozilla/5.0 (Macintosh)", "method": "GET", "raw": "domain.sk 185.110.144.25", "remote_addr": "185.110.144.25", "request_time": "0.003", "request_uri": "/", "server_protocol": "HTTP/1.1", "status": "200", "time_local": "2019-12-17T07:43:13", "upstream_addr": "10.10.153.26:80", "upstream_cache_status": "MISS", "upstream_response_time": "0.004" } ], "not_parsed": "" }
- Query Parameters:
format – (parsed / raw) type of response
start – Start cursor position of reading log file
length – Length of reading log file
tail – Read log file from end
- GET /v2/storage/(uuid)/virtualhost/(vhost_id)/logs/archive¶
Get compressed log files
Example request
GET /v2/<uuid>/virtualhost/<vhost_id>/logs/archive?name=access_log&name=error_log HTTP/1.1 Accept: */*
Example response - success
HTTP/1.1 200 OK Connection: keep-alive Content-Length: 440 Content-Type: application/octet-stream X-Sentry-Id: None +-----------------------------------------+ | NOTE: binary data not shown in terminal | +-----------------------------------------+
Example response - success (large file)
HTTP/1.1 201 CREATED Connection: keep-alive Content-Length: 440 Content-Type: application/json X-Sentry-Id: None { "message": "Archive file is larger than 100MB.Please download this file via FTP" }
Example response - error
HTTP/1.1 200 OK Connection: keep-alive Content-Length: 35 Content-Type: application/json Date: Thu, 19 Dec 2019 13:41:35 GMT Server: nginx/1.17.3 X-Sentry-Id: None { "error": "No files specified" }
- Query Parameters:
name – Name of file
Scanner¶
Run a alware scan on hosting
CMS Installer¶
One-click CMS installer
Resource |
Operation |
Description |
|---|---|---|
CMS |
check installation folder |
|
PUT /v2/storage/(uuid)/service/(service_id)/cms-install-check |
||
install CMS |
||
install CMS under a specific Service |
||
list available CMS installers and configurations |
- PUT /v2/storage/(uuid)/cms-install-check¶
Check whether CMS can be installed to a folder.
Runs the same validations that are run during a normal CMS installation. Accepts a subset of arguments of the CMS installation endpoint.
- Request JSON Object:
directory (string) – URI path
subDomain (string) – subdomain name
- PUT /v2/storage/(uuid)/service/(service_id)/cms-install-check¶
Check whether CMS can be installed to a folder used by specified Service’s Virtualhost.
Accepts a subset of arguments of the CMS installation endpoint.
- Request JSON Object:
directory (string) – URI path
subDomain (string) – subdomain name
- PUT /v2/storage/(uuid)/install/(cms)¶
Install a CMS under a matching virtualhost/service. If we find a service that matches the
subDomain/directory(path) specified, we update the Service PHP upstream to the one recommended by/v2/cms-settingsendpoint.If no matching Service is found, a new one is created.
The exception to these rules is if no subdomain or path (directory) is specified (or if subdomain equals to ‘www’) - in this case we don’t touch the default Service as updating its PHP upstream might break other websites running under it.
We expect the database specified in the request body to already exist (it doesn’t need to be immediately available, as the RPC process will wait until it becomes live - it just won’t be created by calling this endpoint and has to be created explicitly).
By default, the installation is executed synchronously; but as the installer can sometimes take well over a minute, the response can be returned almost immediately and the installer task executed in the background - to do this, include
"async": Truein request parameters.Asynchronous tasks are listed in the response body under
async_tasks. This endpoint can trigger up to two asynchronous tasks:set_mcdbhandles Nginx configuration update if Service PHP version was updatedinstall_cmshandles CMS installation itself if executed usingasync=True
To check the status of an async task, make a GET request to
/v2/queue/<task_id>(see below)- Request JSON Object:
async (bool)
adminEmail (string)
adminLogin (string)
adminPassword (string)
dbHost (string)
dbName (string)
dbUser (string)
dbPw (string)
siteDomain (string)
siteTitle (string)
siteLanguage (string)
ssl (bool) – whether to enable redirect to HTTPS
overwrite (bool) – optional, default:
false. Overwrite contents of the installation directory.disableWpMail (bool) – (optional) Disable built-in
wp_mail()function (ignored for non-WordPress installations). This is a persistent configuration change and needs to be turned off manually.
Example request:
PUT /v2/storage/8340327c-a188-11e9-8480-ab9f87f07045/install/prestashop HTTP/1.1 Content-Type: application/json Accept: application/json { "async": true, "adminEmail": "info@example.com", "adminLogin": "administrator", "adminPassword": "******", "dbHost": "mariadb101.websupport.sk:3312", "dbName": "4p7j0oducq8t", "dbPw": "*********", "dbUser": "4p7j0oducq8t", "siteDomain": "example.com", "subDomain": "www", "siteTitle": "Example Site", "siteLanguage": "sk", "directory": "", "archive_url": "http://m.websupport.sk/prestashop-1.7.5.2.tar.gz", "ssl": true, "overwrite": false, "update_default_service": false, "disableWpMail": false }
Example response:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "item": { "host": "web-96", "path": "/data/2/d/2d62414c-a22d-11e9-8d32-1f869af45ef2/example.com/web" "uid": 123456 "config": { "adminEmail": "info@example.com", "adminLogin": "administrator", "adminPassword": "******", "dbHost": "mariadb101.websupport.sk:3312", "dbName": "4p7j0oducq8t", "dbPw": "*********", "dbUser": "4p7j0oducq8t", "siteDomain": "www.example.com", "siteTitle": "Example Site", "siteLanguage": "sk", "directory": "", "ssl": true, "overwrite": false }, }, "async_tasks": { "install_cms": "f72ead9f-9195-458e-ba04-5918e38fe6e3", "set_mcdb": "6cafcc46-a7b6-11e9-a8ec-0b4e0e935bce" } }
Polling async task status::
GET /v2/queue/f72ead9f-9195-458e-ba04-5918e38fe6e3 HTTP/1.1
Async task not started:
HTTP/1.1 200 OK Content-Type: application/json { "id": "f72ead9f-9195-458e-ba04-5918e38fe6e3", "result": null, "state": "PENDING", "successful": false }
Async task started:
HTTP/1.1 200 OK Content-Type: application/json { "id": "f72ead9f-9195-458e-ba04-5918e38fe6e3", "result": null, "state": "STARTED", "successful": false }
Async task finished successfully:
HTTP/1.1 200 OK Content-Type: application/json { "id": "f72ead9f-9195-458e-ba04-5918e38fe6e3", "result": true, "state": "SUCCESS", "successful": true }
Async task failed:
HTTP/1.1 200 OK Content-Type: application/json { "id": "f72ead9f-9195-458e-ba04-5918e38fe6e3", "result": null, "state": "FAILURE", "successful": false }
- PUT /v2/storage/(uuid)/service/(service_id)/install/(cms)¶
Install a CMS under the specified service. Updates the PHP upstream if it’s not a default Service.
- Request JSON Object:
async (bool)
adminEmail (string)
adminLogin (string)
adminPassword (string)
dbHost (string)
dbName (string)
dbUser (string)
dbPw (string)
siteDomain (string)
siteTitle (string)
siteLanguage (string)
ssl (bool) – whether to enable redirect to HTTPS
overwrite (bool) – optional, default:
false. Overwrite contents of the installation directory.disableWpMail (bool) – (optional) Disable built-in
wp_mail()function (ignored for non-WordPress installations). This is a persistent configuration change and needs to be turned off manually.
Otherwise, it behaves the same as
/v2/storage/<uuid>/install/<cms>.Example request:
POST /v2/storage/8340327c-a188-11e9-8480-ab9f87f07045/service/1/install/prestashop HTTP/1.1 Content-Type: application/json Accept: application/json { "adminEmail": "info@example.com", "adminLogin": "administrator", "adminPassword": "******", "dbHost": "mariadb101.websupport.sk:3312", "dbName": "4p7j0oducq8t", "dbPw": "*********", "dbUser": "4p7j0oducq8t", "siteDomain": "example.com", "subDomain": "www", "siteTitle": "Example Site", "siteLanguage": "sk", "directory": "", "archive_url": "http://m.websupport.sk/prestashop-1.7.5.2.tar.gz", "ssl": true, "overwrite": false, "update_default_service": false, "disableWpMail": false }
Example response:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "item": { "host": "web-96", "path": "/data/2/d/2d62414c-a22d-11e9-8d32-1f869af45ef2/example.com/web" "uid": 123456 "config": { "adminEmail": "info@example.com", "adminLogin": "administrator", "adminPassword": "******", "dbHost": "mariadb101.websupport.sk:3312", "dbName": "4p7j0oducq8t", "dbPw": "*********", "dbUser": "4p7j0oducq8t", "siteDomain": "www.example.com", "siteTitle": "Example Site", "siteLanguage": "sk", "directory": "", "overwrite": false } } }
- GET /v2/cms-settings¶
List known CMS types.
Example request:
GET /v2/cms-settings HTTP/1.1 Content-Type: application/json Accept: application/json
Example response:
HTTP/1.1 200 OK Content-Type: application/json { "items": [ { "archive": "http://m.websupport.sk/wordpress-5.2.2.tar.gz", "createEnabled": true, "databaseType": "mariadb101", "id": 1, "languages": [ "sk_SK", "cs_CZ", "hu_HU", "en_US" ], "name": "wordpress", "upstream": "apache24-php73", "version": "5.2.2" }, ] }
Shell¶
Start/stop shell container instances
Resource |
Operation |
Description |
|---|---|---|
Shell |
activate shell access |
|
stop console |
||
- GET /v2/storage/(uuid)/shell¶
Look for an active shell container for this domain.
- GET /v2/storage/(uuid)/shell/last-activated¶
Look for last shell container for given domain.
- GET /v2/storage/(uuid)/shell/ssh-keys¶
Get all ssh keys from authorizes_keys file for this domain.
- PUT /v2/storage/(uuid)/shell/ssh-keys¶
Add all ssh keys to authorizes_keys file for this domain.
- POST /v2/storage/(uuid)/shell¶
Create a shell container, providing shell access via a web interface and the SSH protocol. Note that if activating premium shell, active shell will be terminated.
Only available for
Storageobjects withfilesEnabled==1.- Request JSON Object:
premium (bool) – Create ‘premium’ container (SSL, sshd, no expiration timeout). Default False.
last_password (bool) – Reuse password from last active shell for this account. Default False.
country (string) – Two-letter country code representing the domain’s market. If specified, we’ll try to return a web shell URL for the given country, otherwise we fall back to the first shell URL for the given rack.
Example request:
POST /v2/storage/b3f34e3a-6cb7-4494-ad0e-cb316bb4539f/shell HTTP/1.1 Content-Type: application/json Accept: application/json { "country": "SK", "premium": true }
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "item": { "country": "SK", "createTime": 1642592792, "deleteTime": null, "host": "shellserver-2", "id": 322308, "login": "uid71083", "message": null, "password": "d9b716f0fe", "port": 20219, "premium": true, "rootdir": "/nfsmnt/web-101/b/3/b3f34e3a-6cb7-4494-ad0e-cb316bb4539f", "ssh_port": 25219, "status": "ACTIVE", "url": "https://shellserver-2.websupport.sk:20219", "storageId": 3120932 }, "status": "success" }
- DELETE /v2/storage/(uuid)/shell¶
Stop a shell container under Storage specified by uuid.
- Status Codes:
200 OK – no error
404 Not Found – storage not found, shell not found
- DELETE /v2/shell/(domain)¶
Stop a shell container under Storage specified by domain.
This endpoint is called from FRM at the moment of Premium Shell service expiry.
- Status Codes:
200 OK – no error
404 Not Found – storage not found, shell not found
500 Internal Server Error – multiple active storage records found
- POST /v2/shell/(rack)/ensure-socat-services¶
Make sure that all socat redirects on ing servers are configured and running. Useful after ing server reinstall
GitHookEvent¶
Manage git hooks.
Resource |
Operation |
Description |
|---|---|---|
GitHook |
List git hooks. |
|
Show git hook. |
||
Create a new git hook. |
||
Update a git hook. |
||
Test a git hook. |
||
Delete a git hook. |
||
Listener for git hook. |
||
All git hook logs for storage. |
||
Git hook logs. |
- GET /v2/storage/(uuid)/githook/push¶
List ‘push’ githooks for a storage.
- Status Codes:
200 OK – no error
404 Not Found – storage not found
Example request
GET /v2/storage/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a/githook/push HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success
HTTP/1.1 200 OK Content-Type: application/json { "items": [{ "branch": "master", "clone_url": "git@github.com:johnybx/test-webhook.git", "http_password": null, "http_user": null, "id": 1, "reset_before_pull": false, "listener_password": null, "listener_user": null, "path": "nahodnadomenatest.sk/web/", "project_name": "johnybx/test-webhook", "protocol": "SSH", "secret_token": null, "ssh_fingerprint": null, "ssh_public_key": null, "status": "ACTIVE", "storageId": 94336 }], "status": "success" }
- GET /v2/storage/(uuid)/githook/push/(hook_id)¶
Show the details of a single git hook.
- Status Codes:
200 OK – no error
404 Not Found – storage not found
Example request
GET /v2/storage/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a/githook/push/1 HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success
HTTP/1.1 200 OK Content-Type: application/json { "item": { "branch": "master", "clone_url": "git@github.com:johnybx/test-webhook.git", "http_password": null, "http_user": null, "id": 1, "reset_before_pull": false, "listener_password": null, "listener_user": null, "path": "nahodnadomenatest.sk/web/", "project_name": "johnybx/test-webhook", "protocol": "SSH", "secret_token": null, "ssh_fingerprint": null, "ssh_public_key": null, "status": "ACTIVE", "storageId": 94336 }, "status": "success" }
- POST /v2/storage/(uuid)/githook/push¶
Create a new hook.
- Status Codes:
200 OK – no error
404 Not Found – storage not found
409 Conflict – duplicate hook exists
500 Internal Server Error – error validating target folder
- Request JSON Object:
project_url (string) – clone url of project
branch (string) – branch which should be pulled
path (string) – path where git repository should be pulled to
reset_before_pull (bool) – git reset repository before pulling, optional
keypairId (int) – id of ssh key pair, optional
http_user (string) – user for basic authentication to git repository, optional
http_password (string) – password for basic authentication to git repository, optional
secret_token (string) – secret tocket to authorize push event (supported only for github and giltab), optional
listener_user (string) – user for basic authentication for listener endpoint, optional
listener_password (string) – password for basic authentication for listener endpoint, optional
build_command (string) – command to run after git pull in order to build the application, optional ( nothing is run if not specified )
Example request
POST /v2/storage/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a/githook/push HTTP/1.1 Content-Type: application/json Accept: application/json { "project_url": "git@github.com:johnybx/test-webhook.git", "branch": "master", "path": "nahodnadomenatest.sk/web/", "reset_before_pull": false }
Example response - success
HTTP/1.1 200 OK Content-Type: application/json { "item": { "branch": "master", "clone_url": "git@github.com:johnybx/test-webhook.git", "http_password": null, "http_user": null, "id": 1, "reset_before_pull": false, "listener_password": null, "listener_user": null, "path": "nahodnadomenatest.sk/web/", "project_name": "johnybx/test-webhook", "protocol": "SSH", "secret_token": null, "ssh_fingerprint": null, "ssh_public_key": null, "status": "ACTIVE", "storageId": 94336 "build_command": "composer install" }, "status": "success" }
- PUT /v2/storage/(uuid)/githook/push/(hook_id)¶
- Update hook settings. You can change:
hook status
clone path
branch
http username and password
secret token
listener username and password
- Status Codes:
200 OK – no error
404 Not Found – storage not found, githook not found
- Request JSON Object:
branch (string) – branch which should be pulled, optional
path (string) – path where git repository should be pulled to, optional
reset_before_pull (bool) – git reset repository before pulling, optional
keypairId (int) – id of ssh key pair, optional
http_user (string) – user for basic authentication to git repository, optional
http_password (string) – password for basic authentication to git repository, optional
secret_token (string) – secret tocket to authorize push event (supported only for github and giltab), optional
listener_user (string) – user for basic authentication for listener endpoint, optional
listener_password (string) – password for basic authentication for listener endpoint, optional
build_command (string) – command to run after git pull in order to build the application, optional ( nothing is run if not specified )
Example request
PUT /v2/storage/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a/githook/push/1 HTTP/1.1 Content-Type: application/json Accept: application/json { "branch": "staging", "path": "nahodnadomenatest.sk/sub/staging", "reset_before_pull": true }
Example response - success
HTTP/1.1 200 OK Content-Type: application/json { "item": { "branch": "staging", "clone_url": "git@github.com:johnybx/test-webhook.git", "http_password": null, "http_user": null, "id": 1, "reset_before_pull": true, "listener_password": null, "listener_user": null, "path": "nahodnadomenatest.sk/sub/staging", "project_name": "johnybx/test-webhook", "protocol": "SSH", "secret_token": null, "ssh_fingerprint": null, "ssh_public_key": null, "status": "ACTIVE", "storageId": 94336 }, "status": "success" }
- PUT /v2/storage/(uuid)/githook/push/(hook_id)/test¶
Test if storage git hook is correctly configured. This endpoint try to pull latest data from git and returns error message in case of fail.
- Status Codes:
200 OK – no error
404 Not Found – storage not found, git hook not found
500 Internal Server Error – git hook failed
Example request
PUT /v2/storage/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a/githook/push/1/test HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success
HTTP/1.1 200 OK Content-Type: application/json { "status": "success" }
Example response - git hook fail
HTTP/1.1 500 Internal error Content-Type: application/json { "status": "error", "error": "git@github.com: Permission denied (publickey)" }
- DELETE /v2/storage/(uuid)/githook/push/(hook_id)¶
Delete git hook.
- Status Codes:
200 OK – no error
404 Not Found – storage not found, githook not found
Example request
DELETE /v2/storage/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a/githook/push HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success
HTTP/1.1 200 OK Content-Type: application/json { "item": { "branch": "staging", "clone_url": "git@github.com:johnybx/test-webhook.git", "http_password": null, "http_user": null, "id": 1, "reset_before_pull": true, "listener_password": null, "listener_user": null, "path": "nahodnadomenatest.sk/sub/staging", "project_name": "johnybx/test-webhook", "protocol": "SSH", "secret_token": null, "ssh_fingerprint": null, "ssh_public_key": null, "status": "ACTIVE", "storageId": 94336 }, "status": "success" }
- POST /v2/storage/githook/listener¶
Listener for git hooks from github, gitlab or bitbucket.
- Status Codes:
200 OK – no error
400 Bad Request – Bad event type
403 Forbidden – Forbidden
404 Not Found – storage not found, githook not found
Example request
POST /v2/storage/githook/listener HTTP/1.1 Content-Type: application/json Accept: application/json { "data": "payload from github, gitlab or bitbucket" }
Example response - success
HTTP/1.1 200 OK Content-Type: application/json { "task_id": "7941f72d-d121-4c43-8bce-2d0f58b663a1", "status": "success" }
- GET /v2/storage/(uuid)/githook/push/logs¶
Get logs for all git hooks connected to specified storage.
- Status Codes:
200 OK – no error
404 Not Found – storage not found
Example request
GET /v2/storage/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a/githook/push/logs HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "items": [ { "branch": "master", "clone_url": "https://gitlab.com/gituser/test-ws-githook", "error": null, "path": "testdomain.com/web", "project_name": "gituser/test-ws-githook", "status_code": 200, "utc_datetime": "Tue, 23 Feb 2021 17:21:57 GMT" }, { "branch": "master", "clone_url": "https://gitlab.com/gituser/test-ws-githook", "error": "Access denied to URL", "path": "testdomain.com/web", "project_name": "gituser/test-ws-githook", "status_code": 403, "utc_datetime": "Tue, 23 Feb 2021 17:22:08 GMT" }, { "branch": "master", "clone_url": "https://gitlab.com/gituser/test-ws-githook", "error": null, "path": "testdomain.com/web", "project_name": "gituser/test-ws-githook", "status_code": 200, "utc_datetime": "Tue, 23 Feb 2021 17:22:19 GMT" } ] }
- GET /v2/storage/(uuid)/githook/push/(hook_id)/logs¶
Get logs for specified git hook.
- Status Codes:
200 OK – no error
404 Not Found – storage not found, githook not found
Example request
GET /v2/storage/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a/githook/push/41413/logs HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "items": [ { "branch": "master", "clone_url": "https://gitlab.com/gituser/test-ws-githook", "error": null, "path": "testdomain.com/web", "project_name": "gituser/test-ws-githook", "status_code": 200, "utc_datetime": "Tue, 23 Feb 2021 17:21:57 GMT" }, { "branch": "master", "clone_url": "https://gitlab.com/gituser/test-ws-githook", "error": "Access denied to URL", "path": "testdomain.com/web", "project_name": "gituser/test-ws-githook", "status_code": 403, "utc_datetime": "Tue, 23 Feb 2021 17:22:08 GMT" }, { "branch": "master", "clone_url": "https://gitlab.com/gituser/test-ws-githook", "error": null, "path": "testdomain.com/web", "project_name": "gituser/test-ws-githook", "status_code": 200, "utc_datetime": "Tue, 23 Feb 2021 17:22:19 GMT" } ] }
SSHKeys¶
Manage ssh keys.
Resource |
Operation |
Description |
|---|---|---|
SshKeys |
List ssh keys. |
|
Show ssh key. |
||
Add ssh key. |
||
Update ssh key. |
||
Delete ssh key. |
- GET /v2/storage/(uuid)/ssh-keys¶
List ssh keys.
- Status Codes:
200 OK – no error
404 Not Found – storage not found
Example request
GET /v2/storage/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a/ssh-keys HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success
HTTP/1.1 200 OK Content-Type: application/json { "items": [{ "comment": null, "createTime": 1595510348, "fingerprint": "a8:ad:36:65:1e:4d:f7:e7:aa:9c:25:3b:f3:5c:c9:4a", "id": 1, "private_key": "-----BEGIN RSA PRIVATE KEY----- MIIJKAIBAAKCAgEAzXdOPb5GNXENQiYT91Mzo3tSZqvkcRVsjSkup9R7V5uoL1ht pvxv5KmdTejOq8ZwbEVChw5xkRSzNbvUBlQepi4vE2YmzVD8S8IJuzzfKJurQ4JK QUlC1oOZmE8aUjyoQ/6vJ8AEyH+lItQx1VdktpUDa91lYk84SH07sza/GUtXqMG7 del8kzxT3Wdf33K+CULmkD7Xx/CuyED5V22i2U5ZhPrR4EK/L13RcB40QajzUsw3 xkIh1wjZoKJPSs9/p2dFv2xOxXzm0fPKq/qfd9zRwbRUpvO+PikdcpKrzrN8DgHl wSEiWWnMzBywc/4wjlfeaSo3srNo7Q+0q3GCWp8ulXoH+1ZzV9VisJqKVbpW2zI7 3zB14GQuEc/qVrFX2qFZ50AWHoH/595vf42/f9KeooGnQpYTBWUOt5/kmpIHgaNy WQHxrNlPXQu4RHSLWa99tijW21i7pyb/ftupyX6K7puzA1plua0ypgXyg1iMXuiv TEyCpVFNs4vPvE+QneLA0TwEHiE0BspYusFcljyaeMi1ETKvsxN4bs9ZNm0S7imQ weQJJ9mBDBqnIPUJAmlc0s/Kep2vR/FFho0nOQXF3id+S2BQjqqbo5zPMPe0WYBh A4UhR3ITXdkToEiLBZw2bSnmMQDW6iYAz8zkiVkZlMGcdjvCAl4aePPxf7kCAwEA AQKCAgBAxeZMD7KJgXjZDDEKLNggJy4MgQ8U2VitzbhQH2u87CzitCFpXbaWoyQc nhKdU4M4lsMI2bRStPBkNbD7R8Sbxf6AQplj666F4Yd42BFP93dP4oCvQT3Ja5Zd zj4xg77WJLGqOd4oKRlxt+x34cO1zZdVB2hBTFElhRlvf4hSHI7nfB+xZeiocAHO UBsI0d74A3e1LKKQ/R7UsasJdV473HfbNMk6RkCIWa6/hj4aHv2Kcif5H/sUE82r 1s9hebW4HBYAaVAR8TTBJnaTrgBc5KfZxZRUR44HgaWva26vTKUEs3NvZZczEegG xtqXzqAXF7tdcvo5I1cmOOfPjoq1nu+63K0r76DXDTyLpRMtsBPRn/LRxW+Gw5kb X5v9ugehBbVPErVhxbtdtBapcmnn3rqAGfAM/EhLPPD7dT0ZmJGmO7EwMlAFgYEO vjjV8u26GKiDb6fMemmb3tPJ62tMDQiGT2yR7C0CTfjMPr6S0KUCMFhYylFr4M/s MRVKsdDqkeP3vdknhiqZ3LJaOfFYtpxtti0JnwMsqRnMh5mUcySkxqu2eo9Qx/J0 w9jZOMQf8Dg7vmUzldrxQfavzgsUgPD08xdyDbsyPyb59p7swWpxh2r9CmwoH/c6 jsLKepTqxEmMHT4gH+/wI41zk6jqg3jpk0lLS4NBHkq0d22r4wKCAQEA1R05ib/Z eXuA6uc9kLAD5rNkn8lG9eYNTYFSrP26GokcvN+p+B2b6KOJLYcIZOp9bEnlD/Ng F6GeQF3B+T7VARno6HqICL1d/cf5tpKsndIqwNl/p87BTs6eaZUI7cFZz0w5uV4K 1nkEsrWIZv6dUAd+W+Px0NVa6N5/4XPNreKAj9SYmAtOdEP6JvvTKBgQaPG9sZ02 kzYUwcpAWHG3N/kCcLPwVkav4MX1ZUe5jECD1bEaOAYjqIsXndP5meH3VUefPLyl aiGJj3Iq7uXYYeHf+vA1h76RJgd2F4Y12g4D4fBg53W17OfBBZxVxPktdOqzE9jj Roz8n75Zc8FxgwKCAQEA9tAUqvxfoj0QjP+pHdqO2SPUTIVYa1De46augvE0We1d bqMOr3Ji4JGp2qqtpz0Tfb0kCNTQcU4mnYec3KuyU8uK/0LIMDkTFYLDYFp00bDG nyjLEUt015MpAzR9T8lOBVdo2UA+LF9EKq50Ak3qvTQr+XxnYUA8ofehb3jZTKpf uoP4PEZPoAZiJ9x4B0DvBnDmbPuq3kMCk2U90WL+zhhtv0mO7md4/ZddCO23sayG oGgJbC7Z5x1Y//lB5w+SqbpvdqsbjeZPoE+KamIQm+2pKMz3x2JSOjyOtbJAJ+Fy yoUvt+hG0A6CJ42hj/hqrMjpMpBcpSsNa0tON/QxEwKCAQEApg6hmN4unORJLcCF Tkp4n7jE/WSesFhToULVowoJi0evZtR44mZf58QVza3cMpYsqMZjgCxJgeBjKRBl Zss4uiTwQMXJXdYAeRDrWQGtE0SCH8baG22VXszMzsRcMrZoPojMqc3HcBrYOFAP OwHGnmdYZE2XTPwSXEWTK59KcuV8+5XSWRbmSN32+41ZmXI2xy8melFgBxEq1127 Ca+B7lFPP3ZWHUPzI5fcgNCEme5jS402OtU9z8Sh4E8dvHRAfujSAUeVNL9xKp7x KTlbg9m25xdo/p7VBublc6sWJxSondLqDzC/Uxu6YZ7RjiwC6Yk/hIWJgp208twl Y3cl9QKCAQBHItgiJBVIRINlsDZFFX5AlXQWDgTbAXcMdDkuImktVh2syrBr3vMi uLkU/kaIwjDA9+fP586gKZ81niWW8KG4Rx0rz0q1o22dsI+xUMEEwwesTeyhcncd vxt+Af3wJhwnq/bbTwncbiTOjHOBSoXSvJvED5gYTpRrNl1ALLusvhpTPsAoVzeR 7uURihjKNmvuFlJDrRGld/jhFLgJhpfcPOw8yu24Rvh3Vs4IycM9IXW3++RjWumR FENXm7bj6vghlUuVD2IktvHSSbqiSNtypcAws0rjG7KJeHTFZ7fYBsG4H0UOo5Lt WpEm50penYHZhRq5aSRaspruhsjnlakjAoIBAHgUAfT81RhLZisgldiYlDf9tfCk vYN9YB/dMoniWzFvZCRGvVjQkPTufhplFrFWpFdavMOFpVVMzKQL/VqZEQin3SGn BA35HU6t1bqOfKD1c4COyz4qo+rF8+OEuTEs00KvrRVMCaRcQ8i8Ah2k2v/P6I/2 EsrZLSqYNQnSVVTl59gfP3+vo7qmDT4Q8ZdHGO045XZ+KJ1ZDdWLBxs9i17zfOlT LuCv5x1DCrv7BnCca1dtxC6s9j9s+qUHyXmTbjXUFA8qgdMqZulXFfycoh3MdcOp Ha20O2Wp5BFergG9nec4cfI3CsrjmcVgjHuFTuvyLLwAj1s4paEt/fqRNB4= -----END RSA PRIVATE KEY-----", "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDNd049vkY1cQ1CJhP3UzOje1Jmq+RxFWyNKS6n1HtXm6gvWG2m/G/kqZ1N6M6rxnBsRUKHDnGRFLM1u9QGVB6mLi8TZibNUPxLwgm7PN8om6tDgkpBSULWg5mYTxpSPKhD/q8nwATIf6Ui1DHVV2S2lQNr3WViTzhIfTuzNr8ZS1eowbt16XyTPFPdZ1/fcr4JQuaQPtfH8K7IQPlXbaLZTlmE+tHgQr8vXdFwHjRBqPNSzDfGQiHXCNmgok9Kz3+nZ0W/bE7FfObR88qr+p933NHBtFSm874+KR1ykqvOs3wOAeXBISJZaczMHLBz/jCOV95pKjeys2jtD7SrcYJany6Vegf7VnNX1WKwmopVulbbMjvfMHXgZC4Rz+pWsVfaoVnnQBYegf/n3m9/jb9/0p6igadClhMFZQ63n+SakgeBo3JZAfGs2U9dC7hEdItZr322KNbbWLunJv9+26nJforum7MDWmW5rTKmBfKDWIxe6K9MTIKlUU2zi8+8T5Cd4sDRPAQeITQGyli6wVyWPJp4yLURMq+zE3huz1k2bRLuKZDB5Akn2YEMGqcg9QkCaVzSz8p6na9H8UWGjSc5BcXeJ35LYFCOqpujnM8w97RZgGEDhSFHchNd2ROgSIsFnDZtKeYxANbqJgDPzOSJWRmUwZx2O8ICXhp48/F/uQ==", "storageId": 94336 }] }
- GET /v2/storage/(uuid)/ssh-keys/(int: key_id)¶
Show ssh key.
- Status Codes:
200 OK – no error
404 Not Found – storage not found, key not found
Example request
GET /v2/storage/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a/ssh-keys/1 HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success
HTTP/1.1 200 OK Content-Type: application/json { "item": { "comment": null, "createTime": 1595510348, "fingerprint": "a8:ad:36:65:1e:4d:f7:e7:aa:9c:25:3b:f3:5c:c9:4a", "id": 1, "private_key": "-----BEGIN RSA PRIVATE KEY----- MIIJKAIBAAKCAgEAzXdOPb5GNXENQiYT91Mzo3tSZqvkcRVsjSkup9R7V5uoL1ht pvxv5KmdTejOq8ZwbEVChw5xkRSzNbvUBlQepi4vE2YmzVD8S8IJuzzfKJurQ4JK ..... LuCv5x1DCrv7BnCca1dtxC6s9j9s+qUHyXmTbjXUFA8qgdMqZulXFfycoh3MdcOp Ha20O2Wp5BFergG9nec4cfI3CsrjmcVgjHuFTuvyLLwAj1s4paEt/fqRNB4= -----END RSA PRIVATE KEY-----", "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAA......2O8ICXhp48/F/uQ==", "storageId": 94336 }, "status": "success" }
- POST /v2/storage/(uuid)/ssh-keys¶
Add ssh key. If not private key is send in request than new ssh key will be automatically generated.
- Status Codes:
200 OK – no error
404 Not Found – storage not found, key not found
Example request
POST /v2/storage/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a/ssh-keys HTTP/1.1 Content-Type: application/json Accept: application/json { "comment": "My ssh key", "private_key": "-----BEGIN RSA PRIVATE KEY----- MIIJKAIBAAKCAgEAzXdOPb5GNXENQiYT91Mzo3tSZqvkcRVsjSkup9R7V5uoL1ht pvxv5KmdTejOq8ZwbEVChw5xkRSzNbvUBlQepi4vE2YmzVD8S8IJuzzfKJurQ4JK ..... LuCv5x1DCrv7BnCca1dtxC6s9j9s+qUHyXmTbjXUFA8qgdMqZulXFfycoh3MdcOp Ha20O2Wp5BFergG9nec4cfI3CsrjmcVgjHuFTuvyLLwAj1s4paEt/fqRNB4= -----END RSA PRIVATE KEY-----", }
Example response - success
HTTP/1.1 200 OK Content-Type: application/json { "item": { "comment": "My ssh key", "createTime": 1595510348, "fingerprint": "a8:ad:36:65:1e:4d:f7:e7:aa:9c:25:3b:f3:5c:c9:4a", "id": 1, "private_key": "-----BEGIN RSA PRIVATE KEY----- MIIJKAIBAAKCAgEAzXdOPb5GNXENQiYT91Mzo3tSZqvkcRVsjSkup9R7V5uoL1ht pvxv5KmdTejOq8ZwbEVChw5xkRSzNbvUBlQepi4vE2YmzVD8S8IJuzzfKJurQ4JK ..... LuCv5x1DCrv7BnCca1dtxC6s9j9s+qUHyXmTbjXUFA8qgdMqZulXFfycoh3MdcOp Ha20O2Wp5BFergG9nec4cfI3CsrjmcVgjHuFTuvyLLwAj1s4paEt/fqRNB4= -----END RSA PRIVATE KEY-----", "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAA......2O8ICXhp48/F/uQ==", "storageId": 94336 }, "status": "success" }
- PUT /v2/storage/(uuid)/ssh-keys/(int: key_id)¶
Update ssh key.
- Status Codes:
200 OK – no error
404 Not Found – storage not found, key not found
Example request
PUT /v2/storage/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a/ssh-keys/1 HTTP/1.1 Content-Type: application/json Accept: application/json { "comment": "My ssh key" }
Example response - success
HTTP/1.1 200 OK Content-Type: application/json { "item": { "comment": "My ssh key", "createTime": 1595510348, "fingerprint": "a8:ad:36:65:1e:4d:f7:e7:aa:9c:25:3b:f3:5c:c9:4a", "id": 1, "private_key": "-----BEGIN RSA PRIVATE KEY----- MIIJKAIBAAKCAgEAzXdOPb5GNXENQiYT91Mzo3tSZqvkcRVsjSkup9R7V5uoL1ht pvxv5KmdTejOq8ZwbEVChw5xkRSzNbvUBlQepi4vE2YmzVD8S8IJuzzfKJurQ4JK ..... LuCv5x1DCrv7BnCca1dtxC6s9j9s+qUHyXmTbjXUFA8qgdMqZulXFfycoh3MdcOp Ha20O2Wp5BFergG9nec4cfI3CsrjmcVgjHuFTuvyLLwAj1s4paEt/fqRNB4= -----END RSA PRIVATE KEY-----", "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAA......2O8ICXhp48/F/uQ==", "storageId": 94336 }, "status": "success" }
- DELETE /v2/storage/(uuid)/ssh-keys/(int: key_id)¶
Delete ssh key.
- Status Codes:
200 OK – no error
404 Not Found – storage not found, key not found
Example request
DELETE /v2/storage/fc4b1231-4310-4d03-b0a8-aa03b4b37b4a/ssh-keys/1 HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success
HTTP/1.1 200 OK Content-Type: application/json { "item": { "comment": null, "createTime": 1595510348, "fingerprint": "a8:ad:36:65:1e:4d:f7:e7:aa:9c:25:3b:f3:5c:c9:4a", "id": 1, "private_key": "-----BEGIN RSA PRIVATE KEY----- MIIJKAIBAAKCAgEAzXdOPb5GNXENQiYT91Mzo3tSZqvkcRVsjSkup9R7V5uoL1ht pvxv5KmdTejOq8ZwbEVChw5xkRSzNbvUBlQepi4vE2YmzVD8S8IJuzzfKJurQ4JK ..... LuCv5x1DCrv7BnCca1dtxC6s9j9s+qUHyXmTbjXUFA8qgdMqZulXFfycoh3MdcOp Ha20O2Wp5BFergG9nec4cfI3CsrjmcVgjHuFTuvyLLwAj1s4paEt/fqRNB4= -----END RSA PRIVATE KEY-----", "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAA......2O8ICXhp48/F/uQ==", "storageId": 94336 }, "status": "success" }
IptablesRule¶
Manage iptables rules.
Resource |
Operation |
Description |
|---|---|---|
Iptables |
List iptables rules |
|
Show one iptables rule |
||
Create new iptables rule |
||
Update iptables rule |
||
Delete iptables rule |
||
Export rules by rack |
- GET /v2/storage/(uuid)/iptables¶
List iptables rules under storage.
- Status Codes:
200 OK – no error
Example request:
GET /storage/3ed95099-0795-4276-bfa8-4f9c24281807/iptables HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "items": [ { "chain": "hosting_allowlist", "comment": "This rule is added based on client request", "deleted": false, "destination": "37.9.175.0/24,37.9.169.5", "id": 1, "port": 10000, "protocol": "tcp", "storageId": 94336, "jump_target": "ACCEPT" } ] }
- GET /v2/storage/(uuid)/iptables/(rule_id)¶
Show iptables rule under storage
- Status Codes:
200 OK – no error
404 Not Found – Not found
Example request:
GET /storage/3ed95099-0795-4276-bfa8-4f9c24281807/iptables/1 HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "item": { "chain": "hosting_allowlist", "comment": "This rule is added based on client request", "deleted": false, "destination": "37.9.175.0/24,37.9.169.5", "id": 1, "port": 10000, "protocol": "tcp", "storageId": 94336, "jump_target": "ACCEPT" } }
Example response - Not found:
HTTP/1.1 404 OK Content-Type: application/json { "error": "Iptables rule not found" }
- POST /v2/storage/(uuid)/iptables¶
Create new iptables rule under storage
- Status Codes:
201 Created – Created
400 Bad Request – validation error
404 Not Found – Not found
- Request JSON Object:
port (int) – port which should be allowed
destination (str) – ipaddress or ip range. Multiple ipaddresses or ip ranges can be specified devided by comma
protocol (str) – tcp or udp
comment (str) – most often reason for existence of rule
jump_target (str) – iptables jump target ACCEPT (default) or DROP, optional
Example request:
POST /storage/3ed95099-0795-4276-bfa8-4f9c24281807/iptables HTTP/1.1 Content-Type: application/json Accept: application/json { "port": 10000, "destination": "37.9.175.0/24,37.9.169.5", "protocol": "tcp", "comment": "This rule is added based on client request", "jump_target": "ACCEPT" }
Example response - success:
HTTP/1.1 201 Created Content-Type: application/json { "item": { "chain": "hosting_allowlist", "comment": "This rule is added based on client request", "deleted": false, "destination": "37.9.175.0/24,37.9.169.5", "id": 1, "port": 10000, "protocol": "tcp", "storageId": 94336, "jump_target": "ACCEPT" } }
Example response - Not found:
HTTP/1.1 404 OK Content-Type: application/json { "error": "Iptables rule not found" }
- PUT /v2/storage/(uuid)/iptables/(rule_id)¶
Update iptables rule under storage
- Status Codes:
200 OK – no error
400 Bad Request – validation error
404 Not Found – Not found
- Request JSON Object:
port (int) – port which should be allowed, optional
destination (str) – ipaddress or ip range. Multiple ipaddresses or ip ranges can be specified devided by comma, optional
protocol (str) – tcp or udp, optional
comment (str) – most often reason for existence of rule, optional
jump_target (str) – iptables jump target ACCEPT or DROP, optional
Example request:
PUT /storage/3ed95099-0795-4276-bfa8-4f9c24281807/iptables/1 HTTP/1.1 Content-Type: application/json Accept: application/json { "port": 10001, "destination": "37.9.175.0/24", "protocol": "udp", "comment": "This rule is added based on client request", "jump_target": "ACCEPT", "deleted": false }
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "item": { "chain": "hosting_allowlist", "comment": "This rule is added based on client request", "deleted": false, "destination": "37.9.175.0/24", "id": 1, "port": 10001, "protocol": "udp", "storageId": 94336, "jump_target": "ACCEPT" } }
Example response - Not found:
HTTP/1.1 404 OK Content-Type: application/json { "error": "Iptables rule not found" }
- DELETE /v2/storage/(uuid)/iptables/(rule_id)¶
Delete iptables rule under storage
- Status Codes:
200 OK – no error
404 Not Found – Not found
Example request:
DELETE /storage/3ed95099-0795-4276-bfa8-4f9c24281807/iptables/1 HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "item": { "chain": "hosting_allowlist", "comment": "This rule is added based on client request", "deleted": true, "destination": "37.9.175.0/24", "id": 1, "port": 10001, "protocol": "udp", "storageId": 94336, "jump_target": "ACCEPT" } }
Example response - Not found:
HTTP/1.1 404 OK Content-Type: application/json { "error": "Iptables rule not found" }
- PUT /v2/storage/(uuid)/iptables/export/(rack)¶
Export iptables rules by rack
- Status Codes:
200 OK – no error
404 Not Found – Not found
Example request:
PUT /storage/3ed95099-0795-4276-bfa8-4f9c24281807/iptables/export/r1 HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "task_id": "bfcfc866-b633-447f-b2fa-81658c9b2599" }
Example response - Not found:
HTTP/1.1 404 OK Content-Type: application/json { "status": "error", "error": "Rack: r13 not found" }
Nginx waf allowlist¶
Manage nginx waf allowlist rules.
Resource |
Operation |
Description |
|---|---|---|
Nginx waf allowlist |
List nginx waf allowlist rules |
|
Show one nginx waf allowlist rule |
||
Create new nginx waf allowlist rule |
||
Update nginx waf allowlist rule |
||
Deploy nginx waf allowlist rules |
||
Delete nginx waf allowlist rule |
- GET /v2/storage/(uuid)/nginx-waf¶
List nginx waf allowlist rules.
- Status Codes:
200 OK – no error
Example request:
GET /v2/storage/720a57b7-b1e8-4b54-b25d-ce18651df3fb/nginx-waf HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "items": [ { "comment": "some nginx waf rule", "id": 1, "storageId": 1, "domain": "some\.domain\.sk$", } ] }
- GET /v2/storage/(uuid)/nginx-waf/(int: rule_id)¶
Show nginx waf allowlist rule
- Status Codes:
200 OK – no error
404 Not Found – Not found
Example request:
GET /v2/storage/720a57b7-b1e8-4b54-b25d-ce18651df3fb/nginx-waf/1 HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "item": { "comment": "some nginx waf rule", "id": 1, "storageId": 1, "domain": "some\.domain\.sk$", } }
Example response - Not found:
HTTP/1.1 404 OK Content-Type: application/json { "status": "error", "error": "Nginx waf allowlist rule not found" }
- POST /v2/storage/(uuid)/nginx-waf¶
Create new nginx waf allowlist rule
- Status Codes:
201 Created – Created
400 Bad Request – validation error
404 Not Found – Not found
- Request JSON Object:
domain (str) – nginx waf rule to be allowed
comment (str) – why the rule exists
Example request:
POST /v2/storage/720a57b7-b1e8-4b54-b25d-ce18651df3fb/nginx-waf HTTP/1.1 Content-Type: application/json Accept: application/json { "domain": "some\.domain\.sk$", "comment": "some nginx waf rule", }
Example response - success:
HTTP/1.1 201 Created Content-Type: application/json { "status": "success", "item": { "comment": "some nginx waf rule", "id": 1, "storageId": 1, "domain": "some\.domain\.sk$", } }
Example response - Not found:
HTTP/1.1 404 OK Content-Type: application/json { "status": "error", "error": "Nginx waf allowlist rule not found" }
- PUT /v2/storage/(uuid)/nginx-waf/(int: rule_id)¶
Update nginx waf allowlist rule
- Status Codes:
200 OK – no error
400 Bad Request – validation error
404 Not Found – Not found
- Request JSON Object:
domain (str) – nginx waf rule to be allowed, optional
comment (str) – why the rule exists, optional
Example request:
PUT /v2/storage/720a57b7-b1e8-4b54-b25d-ce18651df3fb/nginx-waf/1 HTTP/1.1 Content-Type: application/json Accept: application/json { "domain": "some\.domain\.sk$" }
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "item": { "comment": "some nginx waf rule", "id": 1, "storageId": 1, "domain": "some\.domain\.sk$", } }
Example response - Not found:
HTTP/1.1 404 OK Content-Type: application/json { "status": "error", "error": "Nginx waf allowlist rule not found" }
- PUT /v2/storage/nginx-waf/deploy/(rack)/(server)¶
Deploy nginx waf allowlist rules to server
- Status Codes:
200 OK – no error
404 Not Found – Not found
Example request:
PUT /v2/storage/nginx-waf/deploy/in-1 HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "result": { "some": "result" } }
- DELETE /v2/storage/(uuid)/nginx-waf/(int: rule_id)¶
Delete nginx waf allowlist rule
- Status Codes:
200 OK – no error
404 Not Found – Not found
Example request:
DELETE /v2/storage/720a57b7-b1e8-4b54-b25d-ce18651df3fb/nginx-waf/1 HTTP/1.1 Content-Type: application/json Accept: application/json
Example response - success:
HTTP/1.1 200 OK Content-Type: application/json { "status": "success", "item": { "comment": "some nginx waf rule", "id": 1, "storageId": 1, "domain": "some\.domain\.sk$", } }
Example response - Not found:
HTTP/1.1 404 OK Content-Type: application/json { "status": "error", "error": "Nginx waf allowlist rule not found" }