Add documentation for the API routes.

Use Sphinx on a CentOS7/RHEL7 system to generate the docs with 'make docs'
This commit is contained in:
Brian C. Lane 2018-01-15 14:14:35 -08:00
parent 377f5e4124
commit 57d9d40c29
1 changed files with 611 additions and 2 deletions

View File

@ -1,5 +1,5 @@
#
# Copyright (C) 2017 Red Hat, Inc.
# Copyright (C) 2017-2018 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -14,6 +14,605 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
""" Setup v0 of the API server
v0_api() must be called to setup the API routes for Flask
Status Responses
----------------
Some requests only return a status/error response.
The response will be a status response with `status` set to true, or an
error response with it set to false and an error message included.
Example response::
{
"status": true
}
Error response::
{
"error": {
"msg": "ggit-error: Failed to remove entry. File isn't in the tree - jboss.toml (-1)"
},
"status": false
}
API Routes
----------
All of the recipes routes support the optional `branch` argument. If it is not
used then the API will use the `master` branch for recipes. If you want to create
a new branch use the `new` or `workspace` routes with ?branch=<branch-name> to
store the new recipe on the new branch.
`/api/v0/test`
^^^^^^^^^^^^^^
Return a test string. It is not JSON encoded.
`/api/v0/status`
^^^^^^^^^^^^^^^^
Return the status of the API Server::
{ "api": "0",
"build": "devel",
"db_supported": false,
"db_version": "0",
"schema_version": "0" }
`/api/v0/recipes/list`
^^^^^^^^^^^^^^^^^^^^^^
List the available recipes::
{ "limit": 20,
"offset": 0,
"recipes": [
"atlas",
"development",
"glusterfs",
"http-server",
"jboss",
"kubernetes" ],
"total": 6 }
`/api/v0/recipes/info/<recipe_names>`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Return the JSON representation of the recipe. This includes 3 top level
objects. `changes` which lists whether or not the workspace is different from
the most recent commit. `recipes` which lists the JSON representation of the
recipe, and `errors` which will list any errors, like non-existant recipes.
Example::
{
"changes": [
{
"changed": false,
"name": "glusterfs"
}
],
"errors": [],
"recipes": [
{
"description": "An example GlusterFS server with samba",
"modules": [
{
"name": "glusterfs",
"version": "3.7.*"
},
{
"name": "glusterfs-cli",
"version": "3.7.*"
}
],
"name": "glusterfs",
"packages": [
{
"name": "2ping",
"version": "3.2.1"
},
{
"name": "samba",
"version": "4.2.*"
}
],
"version": "0.0.6"
}
]
}
Error example::
{
"changes": [],
"errors": [
{
"msg": "ggit-error: the path 'missing.toml' does not exist in the given tree (-3)",
"recipe": "missing"
}
],
"recipes": []
}
`/api/v0/recipes/changes/<recipe_names>[?offset=0&limit=20]`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Return the commits to a recipe. By default it returns the first 20 commits, this
can be changed by passing `offset` and/or `limit`. The response will include the
commit hash, summary, timestamp, and optionally the revision number. The commit
hash can be passed to `/api/v0/recipes/diff/` to retrieve the exact changes.
Example::
{
"errors": [],
"limit": 20,
"offset": 0,
"recipes": [
{
"changes": [
{
"commit": "e083921a7ed1cf2eec91ad12b9ad1e70ef3470be",
"message": "Recipe glusterfs, version 0.0.6 saved.",
"revision": null,
"timestamp": "2017-11-23T00:18:13Z"
},
{
"commit": "cee5f4c20fc33ea4d54bfecf56f4ad41ad15f4f3",
"message": "Recipe glusterfs, version 0.0.5 saved.",
"revision": null,
"timestamp": "2017-11-11T01:00:28Z"
},
{
"commit": "29b492f26ed35d80800b536623bafc51e2f0eff2",
"message": "Recipe glusterfs, version 0.0.4 saved.",
"revision": null,
"timestamp": "2017-11-11T00:28:30Z"
},
{
"commit": "03374adbf080fe34f5c6c29f2e49cc2b86958bf2",
"message": "Recipe glusterfs, version 0.0.3 saved.",
"revision": null,
"timestamp": "2017-11-10T23:15:52Z"
},
{
"commit": "0e08ecbb708675bfabc82952599a1712a843779d",
"message": "Recipe glusterfs, version 0.0.2 saved.",
"revision": null,
"timestamp": "2017-11-10T23:14:56Z"
},
{
"commit": "3e11eb87a63d289662cba4b1804a0947a6843379",
"message": "Recipe glusterfs, version 0.0.1 saved.",
"revision": null,
"timestamp": "2017-11-08T00:02:47Z"
}
],
"name": "glusterfs",
"total": 6
}
]
}
POST `/api/v0/recipes/new`
^^^^^^^^^^^^^^^^^^^^^^^^^^
Create a new recipe, or update an existing recipe. This supports both JSON and TOML
for the recipe format. The recipe should be in the body of the request with the
`Content-Type` header set to either `application/json` or `text/x-toml`.
The response will be a status response with `status` set to true, or an
error response with it set to false and an error message included.
DELETE `/api/v0/recipes/delete/<recipe_name>`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Delete a recipe. The recipe is deleted from the branch, and will no longer
be listed by the `list` route. A recipe can be undeleted using the `undo` route
to revert to a previous commit.
The response will be a status response with `status` set to true, or an
error response with it set to false and an error message included.
POST `/api/v0/recipes/workspace`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Write a recipe to the temporary workspace. This works exactly the same as `new` except
that it does not create a commit. JSON and TOML bodies are supported.
The workspace is meant to be used as a temporary recipe storage for clients.
It will be read by the `info` and `diff` routes if it is different from the
most recent commit.
The response will be a status response with `status` set to true, or an
error response with it set to false and an error message included.
DELETE `/api/v0/recipes/workspace/<recipe_name>`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Remove the temporary workspace copy of a recipe. The `info` route will now
return the most recent commit of the recipe. Any changes that were in the
workspace will be lost.
The response will be a status response with `status` set to true, or an
error response with it set to false and an error message included.
POST `/api/v0/recipes/undo/<recipe_name>/<commit>`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This will revert the recipe to a previous commit. The commit hash from the `changes`
route can be used in this request.
The response will be a status response with `status` set to true, or an
error response with it set to false and an error message included.
POST `/api/v0/recipes/tag/<recipe_name>`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Tag a recipe as a new release. This uses git tags with a special format.
`refs/tags/<branch>/<filename>/r<revision>`. Only the most recent recipe commit
can be tagged. Revisions start at 1 and increment for each new tag
(per-recipe). If the commit has already been tagged it will return false.
The response will be a status response with `status` set to true, or an
error response with it set to false and an error message included.
`/api/v0/recipes/diff/<recipe_name>/<from_commit>/<to_commit>`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Return the differences between two commits, or the workspace. The commit hash
from the `changes` response can be used here, or several special strings:
- NEWEST will select the newest git commit. This works for `from_commit` or `to_commit`
- WORKSPACE will select the workspace copy. This can only be used in `to_commit`
eg. `/api/v0/recipes/diff/glusterfs/NEWEST/WORKSPACE` will return the differences
between the most recent git commit and the contents of the workspace.
Each entry in the response's diff object contains the old recipe value and the new one.
If old is null and new is set, then it was added.
If new is null and old is set, then it was removed.
If both are set, then it was changed.
The old/new entries will have the name of the recipe field that was changed. This
can be one of: Name, Description, Version, Module, or Package.
The contents for these will be the old/new values for them.
In the example below the version was changed and the ping package was added.
Example::
{
"diff": [
{
"new": {
"Version": "0.0.6"
},
"old": {
"Version": "0.0.5"
}
},
{
"new": {
"Package": {
"name": "ping",
"version": "3.2.1"
}
},
"old": null
}
]
}
`/api/v0/recipes/freeze/<recipe_names>`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Return a JSON representation of the recipe with the package and module versions set
to the exact versions chosen by depsolving the recipe.
Example::
{
"errors": [],
"recipes": [
{
"recipe": {
"description": "An example GlusterFS server with samba",
"modules": [
{
"name": "glusterfs",
"version": "3.8.4-18.4.el7.x86_64"
},
{
"name": "glusterfs-cli",
"version": "3.8.4-18.4.el7.x86_64"
}
],
"name": "glusterfs",
"packages": [
{
"name": "ping",
"version": "2:3.2.1-2.el7.noarch"
},
{
"name": "samba",
"version": "4.6.2-8.el7.x86_64"
}
],
"version": "0.0.6"
}
}
]
}
`/api/v0/recipes/depsolve/<recipe_names>`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Depsolve the recipe using yum, return the recipe used, and the NEVRAs of the packages
chosen to satisfy the recipe's requirements. The response will include a list of results,
with the full dependency list in `dependencies`, the NEVRAs for the recipe's direct modules
and packages in `modules`, and any error will be in `errors`.
Example::
{
"errors": [],
"recipes": [
{
"dependencies": [
{
"arch": "noarch",
"epoch": "0",
"name": "2ping",
"release": "2.el7",
"version": "3.2.1"
},
{
"arch": "x86_64",
"epoch": "0",
"name": "acl",
"release": "12.el7",
"version": "2.2.51"
},
{
"arch": "x86_64",
"epoch": "0",
"name": "audit-libs",
"release": "3.el7",
"version": "2.7.6"
},
{
"arch": "x86_64",
"epoch": "0",
"name": "avahi-libs",
"release": "17.el7",
"version": "0.6.31"
},
...
],
"modules": [
{
"arch": "noarch",
"epoch": "0",
"name": "2ping",
"release": "2.el7",
"version": "3.2.1"
},
{
"arch": "x86_64",
"epoch": "0",
"name": "glusterfs",
"release": "18.4.el7",
"version": "3.8.4"
},
...
],
"recipe": {
"description": "An example GlusterFS server with samba",
"modules": [
{
"name": "glusterfs",
"version": "3.7.*"
},
...
}
}
]
}
`/api/v0/projects/list[?offset=0&limit=20]`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
List all of the available projects. By default this returns the first 20 items,
but this can be changed by setting the `offset` and `limit` arguments.
Example::
{
"limit": 20,
"offset": 0,
"projects": [
{
"description": "0 A.D. (pronounced \"zero ey-dee\") is a ...",
"homepage": "http://play0ad.com",
"name": "0ad",
"summary": "Cross-Platform RTS Game of Ancient Warfare",
"upstream_vcs": "UPSTREAM_VCS"
},
...
],
"total": 21770
}
`/api/v0/projects/info/<project_names>`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Return information about the comma-separated list of projects. It includes the description
of the package along with the list of available builds.
Example::
{
"projects": [
{
"builds": [
{
"arch": "x86_64",
"build_config_ref": "BUILD_CONFIG_REF",
"build_env_ref": "BUILD_ENV_REF",
"build_time": "2017-03-01T08:39:23",
"changelog": "- restore incremental backups correctly, files ...",
"epoch": "2",
"metadata": {},
"release": "32.el7",
"source": {
"license": "GPLv3+",
"metadata": {},
"source_ref": "SOURCE_REF",
"version": "1.26"
}
}
],
"description": "The GNU tar program saves many ...",
"homepage": "http://www.gnu.org/software/tar/",
"name": "tar",
"summary": "A GNU file archiving program",
"upstream_vcs": "UPSTREAM_VCS"
}
]
}
`/api/v0/projects/depsolve/<project_names>`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Depsolve the comma-separated list of projects and return the list of NEVRAs needed
to satisfy the request.
Example::
{
"projects": [
{
"arch": "noarch",
"epoch": "0",
"name": "basesystem",
"release": "7.el7",
"version": "10.0"
},
{
"arch": "x86_64",
"epoch": "0",
"name": "bash",
"release": "28.el7",
"version": "4.2.46"
},
{
"arch": "x86_64",
"epoch": "0",
"name": "filesystem",
"release": "21.el7",
"version": "3.2"
},
...
]
}
`/api/v0/modules/list[?offset=0&limit=20]`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Return a list of all of the available modules. This includes the name and the
group_type, which is always "rpm" for lorax-composer. By default this returns
the first 20 items. This can be changed by setting the `offset` and `limit`
arguments.
Example::
{
"limit": 20,
"modules": [
{
"group_type": "rpm",
"name": "0ad"
},
{
"group_type": "rpm",
"name": "0ad-data"
},
{
"group_type": "rpm",
"name": "0install"
},
{
"group_type": "rpm",
"name": "2048-cli"
},
...
]
"total": 21770
}
`/api/v0/modules/list/<module_names>[?offset=0&limit=20]`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Return the list of comma-separated modules. Output is the same as `/modules/list`
Example::
{
"limit": 20,
"modules": [
{
"group_type": "rpm",
"name": "tar"
}
],
"offset": 0,
"total": 1
}
`/api/v0/modules/info/<module_names>`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Return the module's dependencies, and the information about the module.
Example::
{
"modules": [
{
"dependencies": [
{
"arch": "noarch",
"epoch": "0",
"name": "basesystem",
"release": "7.el7",
"version": "10.0"
},
{
"arch": "x86_64",
"epoch": "0",
"name": "bash",
"release": "28.el7",
"version": "4.2.46"
},
...
],
"description": "The GNU tar program saves ...",
"homepage": "http://www.gnu.org/software/tar/",
"name": "tar",
"summary": "A GNU file archiving program",
"upstream_vcs": "UPSTREAM_VCS"
}
]
}
"""
import logging
log = logging.getLogger("lorax-composer")
@ -48,10 +647,20 @@ except ImportError:
libvirt = None
def take_limits(iterable, offset, limit):
""" Apply offset and limit to an iterable object
:param iterable: The object to limit
:type iterable: iter
:param offset: The number of items to skip
:type offset: int
:param limit: The total number of items to return
:type limit: int
:returns: A subset of the iterable
"""
return iterable[offset:][:limit]
def v0_api(api):
""" Setup v0 of the API server"""
# Note that Sphinx will not generate documentations for any of these.
@api.route("/api/v0/test")
@crossdomain(origin="*")
def v0_test():