API Reference¶
Pod Management¶
-
GET
/api/pod/
¶ List all pods
Example response:
HTTP/1.1 200 OK Content-Type: application/json [ { "name": "eru", "desc": "eru test pod", "__class__": "Pod" } ]
-
GET
/api/pod/
(name)/networks
¶ List networks under a pod
Example response:
HTTP/1.1 200 OK Content-Type: application/json [ {"name": "host", "subnets": [], "__class__": "Network"}, {"name": "bridge", "subnets": ["172.17.0.0/16"], "__class__": "Network"} ]
-
GET
/api/pod/
(name)/nodes
¶ List nodes under a pod
Example response:
HTTP/1.1 200 OK Content-Type: application/json [ { "name": "c1-eru-2.ricebook.link", "endpoint": "tcp://xxx.xxx.xxx.xxx:2376", "podname": "eru", "cpu": {"0": 75}, "memory": 855085056, "info": "{\"ID\":\"UUWL:QZS7:MPQY:KMYY:T5Q4:GCBY:JBRA:Q55K:NUKW:O2N2:4BEX:UTFK\",\"Containers\":7,\"ContainersRunning\":6,\"ContainersPaused\":0,\"ContainersStopped\":1,\"Images\":9,\"Driver\":\"overlay\",\"DriverStatus\":[[\"Backing Filesystem\",\"xfs\"],[\"Supports d_type\",\"false\"]],\"SystemStatus\":null,\"Plugins\":{\"Volume\":[\"local\"],\"Network\":[\"bridge\",\"host\",\"macvlan\",\"null\",\"overlay\"],\"Authorization\":null},\"MemoryLimit\":true,\"SwapLimit\":true,\"KernelMemory\":true,\"CpuCfsPeriod\":true,\"CpuCfsQuota\":true,\"CPUShares\":true,\"CPUSet\":true,\"IPv4Forwarding\":true,\"BridgeNfIptables\":true,\"BridgeNfIp6tables\":true,\"Debug\":false,\"NFd\":57,\"OomKillDisable\":true,\"NGoroutines\":72,\"SystemTime\":\"2018-03-20T16:10:51.806831123+08:00\",\"LoggingDriver\":\"json-file\",\"CgroupDriver\":\"cgroupfs\",\"NEventsListener\":1,\"KernelVersion\":\"3.10.0-693.5.2.el7.x86_64\",\"OperatingSystem\":\"CentOS Linux 7 (Core)\",\"OSType\":\"linux\",\"Architecture\":\"x86_64\",\"IndexServerAddress\":\"https://index.docker.io/v1/\",\"RegistryConfig\":{\"InsecureRegistryCIDRs\":[\"127.0.0.0/8\"],\"IndexConfigs\":{\"docker.io\":{\"Name\":\"docker.io\",\"Mirrors\":[\"https://registry.docker-cn.com/\"],\"Secure\":true,\"Official\":true}},\"Mirrors\":[\"https://registry.docker-cn.com/\"]},\"NCPU\":1,\"MemTotal\":1928826880,\"DockerRootDir\":\"/var/lib/docker\",\"HttpProxy\":\"\",\"HttpsProxy\":\"\",\"NoProxy\":\"\",\"Name\":\"c1-eru-2.ricebook.link\",\"Labels\":[],\"ExperimentalBuild\":false,\"ServerVersion\":\"17.12.1-ce\",\"ClusterStore\":\"etcd://127.0.0.1:2379\",\"ClusterAdvertise\":\"\",\"Runtimes\":{\"runc\":{\"path\":\"docker-runc\"}},\"DefaultRuntime\":\"runc\",\"Swarm\":{\"NodeID\":\"\",\"NodeAddr\":\"\",\"LocalNodeState\":\"inactive\",\"ControlAvailable\":false,\"Error\":\"\",\"RemoteManagers\":null},\"LiveRestoreEnabled\":false,\"Isolation\":\"\",\"InitBinary\":\"docker-init\",\"ContainerdCommit\":{\"ID\":\"9b55aab90508bd389d7654c4baf173a981477d55\",\"Expected\":\"9b55aab90508bd389d7654c4baf173a981477d55\"},\"RuncCommit\":{\"ID\":\"9f9c96235cc97674e935002fc3d78361b696a69e\",\"Expected\":\"9f9c96235cc97674e935002fc3d78361b696a69e\"},\"InitCommit\":{\"ID\":\"949e6fa\",\"Expected\":\"949e6fa\"},\"SecurityOptions\":[\"name=seccomp,profile=default\"]}", "available": true, "labels": {}, "__class__": "Node" } ]
-
GET
/api/pod/
(name)¶ Get a single pod by name
Example response:
HTTP/1.1 200 OK Content-Type: application/json { "name": "eru", "desc": "eru test pod", "__class__": "Pod" }
App Management¶
-
POST
/api/app/register
¶ Register a release of the specified app
Request JSON Object: - appname (string) – required
- sha (string) – required, must be length 40
- git (string) – required, the repo address using git protocol, e.g.
git@github.com:projecteru2/citadel.git
- specs_text (string) – required, the yaml specs for this app
- branch (string) – optional git branch
- git_tag (string) – optional git tag
- commit_message (string) – optional commit message
- author (string) – optional author
-
GET
/api/app/
¶ List all the apps associated with the current logged in user, for administrators, list all apps
Example response:
HTTP/1.1 200 OK Content-Type: application/json [ { "id": 10001, "created": "2018-03-21 14:54:06", "updated": "2018-03-21 14:54:07", "name": "test-app", "git": "git@github.com:projecteru2/citadel.git", "tackle_rule": {}, "env_sets": {"prodenv": {"foo": "some-env-content"}} } ]
-
GET
/api/app/
(appname)/version/
(sha)/containers
¶ Get all containers of the specified release
Todo
- add example response
- test this API
-
GET
/api/app/
(appname)/containers
¶ Get all containers of the specified app
Todo
- add example response
- test this API
-
GET
/api/app/
(appname)/releases
¶ List every release of the specified app
Todo
- add example response
- test this API
-
GET
/api/app/
(appname)/version/
(sha)¶ Get one release of the specified app
Todo
- add example response
- test this API
-
GET
/api/app/
(appname)/users
¶ List users who has permissions to the specified app
Todo
- write tests for this API
- add example response
-
PUT
/api/app/
(appname)/users
¶ Grant permission to a user
Request JSON Object: - username (string) – you know what this is
- user_id (int) – must provide either username or user_id
-
DELETE
/api/app/
(appname)/users
¶ Revoke someone’s permission to a app
Request JSON Object: - username (string) – you know what this is
- user_id (int) – must provide either username or user_id
-
GET
/api/app/
(appname)/combo
¶ Get all the combos for the specified app
Todo
- write tests for this API
- add example response
-
PUT
/api/app/
(appname)/combo
¶ Create a combo for the specified app
Request JSON Object: - name (string) – required, the combo name
- entrypoint_name (string) – required
- podname (string) – required
- nodename (string) – optional, provide this only when your app can only be deployed in one machine
- extra_args (string) – optional, extra arguments to the entrypoint command, e.g.
[python -m http.server] --bind 0.0.0.0
- networks (list) – required, list of network names, which can be obtained using
GET /api/pod/(name)/networks
- cpu_quota (float) – required
- memory – required, can provide int (in bytes) or string values, like
"128MB"
or134217728
, when the provided value is string, it’ll be parsed byhumanfriendly.parse_size(binary=True)
- count (string) – number of containers, default to 1
- envname (string) – optional, name of the environment variable set to use
-
POST
/api/app/
(appname)/combo
¶ Edit the combo value for the specified app
Request JSON Object: - name (string) – required, the combo name
- entrypoint_name (string) – required
- podname (string) – required
- nodename (string) – optional, provide this only when your app can only be deployed in one machine
- extra_args (string) – optional, extra arguments to the entrypoint command, e.g.
[python -m http.server] --bind 0.0.0.0
- networks (list) – required, list of network names, which can be obtained using
GET /api/pod/(name)/networks
- cpu_quota (float) – required
- memory – required, can provide int (in bytes) or string values, like
"128MB"
or134217728
, when the provided value is string, it’ll be parsed byhumanfriendly.parse_size(binary=True)
- count (string) – number of containers, default to 1
- envname (string) – optional, name of the environment variable set to use
-
DELETE
/api/app/
(appname)/combo
¶ Delete one combo for the specified app
Request JSON Object: - name (string) – the combo name
-
PUT
/api/app/
(appname)/env/
(envname)¶ Create a environmental variable set
GET /<appname>/env/<envname> HTTP/1.1 Accept: application/json { "HTTP_PROXY": "whatever", "HTTPS_PROXY": "whatever" }
curl -i 'http://nohost/<appname>/env/<envname>' -H 'Accept: application/json' --data-raw '{ "HTTP_PROXY": "whatever", "HTTPS_PROXY": "whatever" }'
wget -S -O- 'http://nohost/<appname>/env/<envname>' --header='Accept: application/json' --body-data='{ "HTTP_PROXY": "whatever", "HTTPS_PROXY": "whatever" }'
echo '{ "HTTP_PROXY": "whatever", "HTTPS_PROXY": "whatever" }' | http 'http://nohost/<appname>/env/<envname>' Accept:application/json
requests.get('http://nohost/<appname>/env/<envname>', headers={'Accept': 'application/json'}, data='{\r\n "HTTP_PROXY": "whatever",\r\n "HTTPS_PROXY": "whatever"\r\n}')
-
POST
/api/app/
(appname)/env/
(envname)¶ Edit the specified env set, usage is the same as
GET /api/app/(appname)/env/(envname)
-
GET
/api/app/
(appname)/env/
(envname)¶ Get the content of the specified environmental variable set
Example response:
HTTP/1.1 200 OK Content-Type: application/json { "bar": "whatever", "FOO": "\"", "foo": "'" }
-
DELETE
/api/app/
(appname)/env/
(envname)¶ Delete the specified environmental variable set
-
GET
/api/app/
(appname)/env
¶ List all env sets for the specified app
Example response:
HTTP/1.1 200 OK Content-Type: application/json { "prodenv": { "password": "secret" }, "testenv": { "password": "not-so-secret" } }
-
GET
/api/app/
(appname)¶ Get a single app
Example response:
HTTP/1.1 200 OK Content-Type: application/json { "id": 10001, "created": "2018-03-21 14:54:06", "updated": "2018-03-21 14:54:07", "name": "test-app", "git": "git@github.com:projecteru2/citadel.git", "tackle_rule": {}, "env_sets": {"prodenv": {"foo": "some-env-content"}} }
Container Actions¶
Action APIs using websocket, upon connection, client should send a first json payload, and then server will work and steam the output as websocket frames
-
GET
/api/action/deploy-elb
¶ Remove the specified containers
Request JSON Object: - name (string) – required, ELB cluster name
- zone (string) – required
- sha (string) – required, minimum length is 7
- combo_name (string) – required, the combo used to create ELB containers
- nodename (string) – optional
-
GET
/api/action/deploy
¶ Create containers for the specified release
Request JSON Object: - appname (string) – required
- zone (string) – required
- sha (string) – required, minimum length is 7
- combo_name (string) – required, specify the combo to use, you can
update combo value using this API, so all parameters in the
POST /api/app/(appname)/combo
are supportedExample response:
HTTP/1.1 200 OK Content-Type: application/json { "podname": "eru", "nodename": "c1-eru-2.ricebook.link", "id": "9c91d06cb165e829e8e0ad5d5b5484c47d4596af04122489e4ead677113cccb4", "name": "test-app_web_kMqYFQ", "error": "", "success": true, "cpu": {"0": 20}, "quota": 0.2, "memory": 134217728, "publish": {"bridge": "172.17.0.5:6789"}, "hook": "I am the hook output", "__class__": "CreateContainerMessage" }
-
GET
/api/action/remove
¶ Remove the specified containers
Request JSON Object: - container_ids (list) – required, a list of container_id
Example response:
HTTP/1.1 200 OK Content-Type: application/json { "id": "9c91d06cb165e829e8e0ad5d5b5484c47d4596af04122489e4ead677113cccb4", "success": true, "message": "hook output", "__class__": "RemoveContainerMessage" }
-
GET
/api/action/build
¶ Build an image for the specified release, the API will return all docker build messages, key frames as shown in the example responses
Request JSON Object: - appname (string) – required, the app name
- sha (string) – required, minimum length is 7
Example response:
HTTP/1.1 200 OK Content-Type: application/json { "id": "", "status": "", "progress": "", "error": "", "stream": "Step 1/7 : FROM python:latest as make-artifacts", "error_detail": { "code": 0, "message": "", "__class__": "ErrorDetail" }, "__class__": "BuildImageMessage" } { "id": "0179a75e26fe", "status": "Pushing", "progress": "[==================================================>] 6.656kB", "error": "", "stream": "", "error_detail": { "code": 0, "message": "", "__class__": "ErrorDetail" }, "__class__": "BuildImageMessage" } { "id": "", "status": "finished", "progress": "hub.ricebook.net/projecteru2/test-app:3641aca", "error": "", "stream": "finished hub.ricebook.net/projecteru2/test-app:3641aca", "error_detail": { "code": 0, "message": "", "__class__": "ErrorDetail" }, "__class__": "BuildImageMessage" }
-
GET
/api/action/renew
¶ Create a new container to substitute the old one, this API can be used to upgrade a app to a specified version, or simply re-create a container using the same combo.
Things can go wrong at any step, the example response was the output generated by
renew("1aa8a638a153b393ee423c0a8c158757b13ab74591ade036b6e73ac33a4bdeac", "3641aca")
which failed because the newly created container didn’t become healthy within the given time limit.Request JSON Object: - container_ids (list) – required, a list of container_id
- sha (string) – required, minimum length is 7
Example response:
HTTP/1.1 200 OK Content-Type: application/json { "podname": "eru", "nodename": "c1-eru-2.ricebook.link", "id": "2f123f1abcdfc8208b298c89e10bcd8f48f9fdb25c9eb7874ea5cc7199825e6e", "name": "test-app_web_rvrhPg", "error": "", "success": true, "cpu": {"0": 20}, "quota": 0.2, "memory": 134217728, "publish": {"bridge": "172.17.0.5:6789"}, "hook": "hook output", "__class__": "CreateContainerMessage" } { "id": "2f123f1abcdfc8208b298c89e10bcd8f48f9fdb25c9eb7874ea5cc7199825e6e", "success": true, "message": "hook output", "__class__": "RemoveContainerMessage" } { "error": "New container <Container test-zone:test-app:3641aca:web:2f123f1 did't became healthy, remove result: id: 2f123f1abcdfc8208b298c89e10bcd8f48f9fdb25c9eb7874ea5cc7199825e6e success: true", "args": ["1aa8a638a153b393ee423c0a8c158757b13ab74591ade036b6e73ac33a4bdeac", "3641aca"], "kwargs": {"user_id": null} }