1343 lines
40 KiB
ReStructuredText
1343 lines
40 KiB
ReStructuredText
V1 API
|
|
======
|
|
|
|
This API describes the different ways of interacting with Glare service via HTTP protocol
|
|
using Representational State Transfer concept (ReST).
|
|
|
|
**Glossary**
|
|
|
|
* *Glare* (from GLare Artifact REpository) - a service that provides access
|
|
to a unified catalog of immutable objects with structured meta-information as
|
|
well as related binary data (these structures are also called *'artifacts'*).
|
|
Glare controls artifact consistency and guaranties that binary data and
|
|
fields won't change during artifact lifetime.
|
|
|
|
.. note::
|
|
|
|
Artifact type developer can declare fields whose values may be
|
|
changed, but he has to do it explicitly, because by default all fields
|
|
are considered as immutable.
|
|
|
|
* *Artifact* - in terms of Glare, an Artifact is a structured immutable object
|
|
with some fields, related binary data, and metadata.
|
|
|
|
* *Artifact Version* - field of an artifact that defines its version in SemVer
|
|
format.
|
|
|
|
* *Artifact type* - defines artifact structure of both its binary data and
|
|
fields. Examples of OpenStack artifact types that will be supported
|
|
in Glare are: Heat templates, Murano Packages, Nova Images, Tacker VNFs and
|
|
so on. All artifact types are inherited from abstract Base type and extended
|
|
with new fields. Base type is inherited from Base class
|
|
from oslo_versionedobjects library (oslo_vo).
|
|
|
|
* *Artifact status* - specifies the state of the artifact and the possible
|
|
actions that can be done with it. List of possible artifact statuses:
|
|
|
|
* *drafted* - Artifact is created but not activated, so it can be changed by
|
|
Artifact owner or Administrator.
|
|
|
|
* *active* - Artifact is activated, immutable fields cannot be changed.
|
|
Artifact available for download to other Users.
|
|
|
|
* *deactivated* - Artifact is not available to other users except
|
|
administrators. Used when Cloud Admin need to check the artifact.
|
|
|
|
* *deleted* - Artifact's deleted.
|
|
|
|
.. list-table:: **Artifact status transition table**
|
|
:header-rows: 1
|
|
|
|
* - Artifacts Status
|
|
- drafted
|
|
- active
|
|
- deactivated
|
|
- deleted
|
|
|
|
* - **drafted**
|
|
- X
|
|
- activate Artifact
|
|
- N/A
|
|
- delete Artifact
|
|
|
|
* - **active**
|
|
- N/A
|
|
- X
|
|
- deactivate Artifact
|
|
- delete Artifact
|
|
|
|
* - **deactivated**
|
|
- N/A
|
|
- reactivate Artifact
|
|
- X
|
|
- delete Artifact
|
|
|
|
* - **deleted**
|
|
- N/A
|
|
- N/A
|
|
- N/A
|
|
- X
|
|
|
|
|
|
* *Artifact Field* - field of an artifact that defines some information
|
|
about the artifact. Artifact fields always have name, type, value and
|
|
several additional parameters, described below.
|
|
|
|
Glare uses several primitive types from oslo.versionedobjects directly:
|
|
|
|
* *String*;
|
|
|
|
* *Integer*;
|
|
|
|
* *Float*;
|
|
|
|
* *Boolean*;
|
|
|
|
And also Glare expands this list with custom types:
|
|
|
|
* *Blob*;
|
|
|
|
* *Link*;
|
|
|
|
* Structured generic types *Dict* or *List*.
|
|
|
|
Each field has additional properties:
|
|
|
|
* **required_on_activate** - boolean value indicating if the field value
|
|
should be specified for the artifact before activation. (Default: True)
|
|
|
|
* **mutable** - boolean value indicating if the field value may be changed
|
|
after the artifact is activated. (Default: False)
|
|
|
|
* **system** - boolean value indicating if the field value cannot be edited
|
|
by User. (Default: False)
|
|
|
|
* **sortable** - boolean value indicating if there is a possibility to sort by
|
|
this field's values. (Default: False)
|
|
|
|
.. note::
|
|
|
|
Only the fields of 4 primitive types may be sortable: integer, string, float
|
|
and boolean.
|
|
|
|
* **nullable** - boolean value indicating if field's value can be empty
|
|
(Default: True).
|
|
|
|
* **default** - a default value for the field may be specified by the Artifact
|
|
Type. (Default: None)
|
|
|
|
* **validators** - a list of objects. When a user sets a value to the field with
|
|
additional validators, Glare applies them before setting the value and
|
|
raises `ValueError` if at least one of the validator requirements is not
|
|
satisfied.
|
|
|
|
* **filter_ops** - a list of available filter operators for the field. There
|
|
are seven available operators: 'eq', 'neq', 'lt', 'lte', 'gt', 'gte', 'in'.
|
|
|
|
* *Artifact Link* - field type that defines soft dependency of the
|
|
Artifact from another Artifact. It is an url that allows user to obtain
|
|
some Artifact data. For external links the format is the following:
|
|
*http(s)://<netloc>/<path>*
|
|
For internal links its value contains only <path>.
|
|
Example of <path>:
|
|
``/artifacts/<artifact_type>/<artifact identifier>``
|
|
|
|
* *Artifact Blob* - field type that defines binary data for Artifact.
|
|
User can download Artifact blob from Glare. Each blob field has a flag
|
|
*external*, that indicates if the field was created during file upload
|
|
(False) or by direct user request (True). In other words, “external” means
|
|
that blob field url is just a reference to some external file and Glare
|
|
does not manage the blob operations in that case.
|
|
Json schema that defines blob format:
|
|
|
|
.. code-block:: javascript
|
|
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"url": {"type": ["string", "null"], "format": "uri",
|
|
"maxLength": 2048},
|
|
"size": {"type": ["number", "null"]},
|
|
"md5": {"type": ["string", "null"]},
|
|
"sha1": {"type": ["string", "null"]},
|
|
"sha256": {"type": ["string", "null"]},
|
|
"external": {"type": "boolean"},
|
|
"id": {"type": "string"},
|
|
"status": {"type": "string",
|
|
"enum": ["saving", "active", "pending_delete"]},
|
|
"content_type": {"type": ["string", "null"]},
|
|
},
|
|
"required": ["url", "size", "md5", "sha1", "sha256", "external",
|
|
"status", "id", "content_type"]
|
|
}
|
|
|
|
Artifact blob fields may have the following statuses:
|
|
|
|
* *saving* - Artifact blob record created in table, blob upload started.
|
|
|
|
* *active* - blob upload successfully finished.
|
|
|
|
* *pending_delete* - indicates that blob will be deleted soon by Scrubber
|
|
(if delayed delete is enabled) or by Glare itself.
|
|
|
|
.. list-table:: **Blob status transition table**
|
|
:header-rows: 1
|
|
|
|
* - Blob Status
|
|
- saving
|
|
- active
|
|
- pending delete
|
|
|
|
* - **saving**
|
|
- X
|
|
- finish blob upload
|
|
- request for artifact delete
|
|
|
|
* - **active**
|
|
- N/A
|
|
- X
|
|
- request for artifact delete
|
|
|
|
* - **pending_delete**
|
|
- N/A
|
|
- N/A
|
|
- X
|
|
|
|
* *Artifact Dict and List* - compound generic field types that
|
|
implement Dict or List interfaces respectively, and contain values of some
|
|
primitive type, defined by `element_type` attribute.
|
|
|
|
* *Artifact visibility* - defines who may have an access to Artifact.
|
|
Initially there are 2 options:
|
|
|
|
* `private` artifact is accessible by its owner and
|
|
admin only. When artifact is 'drafted' its visibility is always `private`.
|
|
|
|
* `public`, when all users have an access to the artifact by default.
|
|
|
|
It's allowed to change visibility only when artifact has `active` status.
|
|
|
|
* *Artifact immutability* - when artifact is *drafted* all its fields
|
|
are editable, but when it becomes *active* it is "immutable" and cannot be modified
|
|
(except for those fields explicitly declared as `mutable`).
|
|
|
|
* *Base type json-schema*:
|
|
|
|
.. code-block:: javascript
|
|
|
|
{
|
|
"name": "Base artifact type",
|
|
"properties": {
|
|
"activated_at": {
|
|
"description": "Datetime when artifact has became active.",
|
|
"filter_ops": ["eq",
|
|
"neq",
|
|
"in",
|
|
"gt",
|
|
"gte",
|
|
"lt",
|
|
"lte"
|
|
],
|
|
"format": "date-time",
|
|
"glareType": "DateTime",
|
|
"readOnly": true,
|
|
"required_on_activate": false,
|
|
"sortable": true,
|
|
"type": ["string",
|
|
"null"
|
|
]
|
|
},
|
|
"created_at": {
|
|
"description": "Datetime when artifact has been created.",
|
|
"filter_ops": ["eq",
|
|
"neq",
|
|
"in",
|
|
"gt",
|
|
"gte",
|
|
"lt",
|
|
"lte"
|
|
],
|
|
"format": "date-time",
|
|
"glareType": "DateTime",
|
|
"readOnly": true,
|
|
"sortable": true,
|
|
"type": "string"
|
|
},
|
|
"description": {
|
|
"default": "",
|
|
"description": "Artifact description.",
|
|
"filter_ops": ["eq",
|
|
"neq",
|
|
"in"
|
|
],
|
|
"glareType": "String",
|
|
"maxLength": 4096,
|
|
"mutable": true,
|
|
"required_on_activate": false,
|
|
"type": ["string",
|
|
"null"
|
|
]
|
|
},
|
|
"id": {
|
|
"description": "Artifact UUID.",
|
|
"filter_ops": ["eq",
|
|
"neq",
|
|
"in"
|
|
],
|
|
"glareType": "String",
|
|
"maxLength": 255,
|
|
"pattern": "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}$",
|
|
"readOnly": true,
|
|
"sortable": true,
|
|
"type": "string"
|
|
},
|
|
"metadata": {
|
|
"additionalProperties": {
|
|
"type": "string"
|
|
},
|
|
"default": {},
|
|
"description": "Key-value dict with useful information about an artifact.",
|
|
"filter_ops": ["eq",
|
|
"neq"
|
|
],
|
|
"glareType": "StringDict",
|
|
"maxProperties": 255,
|
|
"required_on_activate": false,
|
|
"type": ["object",
|
|
"null"
|
|
]
|
|
},
|
|
"name": {
|
|
"description": "Artifact Name.",
|
|
"filter_ops": ["eq",
|
|
"neq",
|
|
"in"
|
|
],
|
|
"glareType": "String",
|
|
"maxLength": 255,
|
|
"required_on_activate": false,
|
|
"sortable": true,
|
|
"type": "string"
|
|
},
|
|
"owner": {
|
|
"description": "ID of user/tenant who uploaded artifact.",
|
|
"filter_ops": ["eq",
|
|
"neq",
|
|
"in"
|
|
],
|
|
"glareType": "String",
|
|
"maxLength": 255,
|
|
"readOnly": true,
|
|
"required_on_activate": false,
|
|
"sortable": true,
|
|
"type": "string"
|
|
},
|
|
"status": {
|
|
"default": "drafted",
|
|
"description": "Artifact status.",
|
|
"enum": ["drafted",
|
|
"active",
|
|
"deactivated",
|
|
"deleted"
|
|
],
|
|
"filter_ops": ["eq",
|
|
"neq",
|
|
"in"
|
|
],
|
|
"glareType": "String",
|
|
"sortable": true,
|
|
"type": "string"
|
|
},
|
|
"tags": {
|
|
"default": [],
|
|
"description": "List of tags added to Artifact.",
|
|
"filter_ops": ["eq",
|
|
"neq",
|
|
"in"
|
|
],
|
|
"glareType": "StringList",
|
|
"items": {
|
|
"type": "string"
|
|
},
|
|
"maxItems": 255,
|
|
"mutable": true,
|
|
"required_on_activate": false,
|
|
"type": ["array",
|
|
"null"
|
|
]
|
|
},
|
|
"updated_at": {
|
|
"description": "Datetime when artifact has been updated last time.",
|
|
"filter_ops": ["eq",
|
|
"neq",
|
|
"in",
|
|
"gt",
|
|
"gte",
|
|
"lt",
|
|
"lte"
|
|
],
|
|
"format": "date-time",
|
|
"glareType": "DateTime",
|
|
"readOnly": true,
|
|
"sortable": true,
|
|
"type": "string"
|
|
},
|
|
"version": {
|
|
"default": "0.0.0",
|
|
"description": "Artifact version(semver).",
|
|
"filter_ops": ["eq",
|
|
"neq",
|
|
"in",
|
|
"gt",
|
|
"gte",
|
|
"lt",
|
|
"lte"
|
|
],
|
|
"glareType": "String",
|
|
"pattern": "/^([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?(?:\\+[0-9A-Za-z-]+)?$/",
|
|
"required_on_activate": false,
|
|
"sortable": true,
|
|
"type": "string"
|
|
},
|
|
"visibility": {
|
|
"default": "private",
|
|
"description": "Artifact visibility that defines if artifact can be available to other users.",
|
|
"filter_ops": ["eq"],
|
|
"glareType": "String",
|
|
"maxLength": 255,
|
|
"sortable": true,
|
|
"type": "string"
|
|
}
|
|
},
|
|
"required": ["name"],
|
|
"type": "object"
|
|
}
|
|
|
|
Basics
|
|
------
|
|
|
|
Glare API complies with OpenStack API-WG guidelines:
|
|
|
|
* `Filtering, sorting and pagination
|
|
<https://github.com/openstack/api-wg/blob/master/guidelines/
|
|
pagination_filter_sort.rst>`_
|
|
|
|
* `Errors
|
|
<http://specs.openstack.org/openstack/api-wg/guidelines/errors.html>`_
|
|
|
|
For updating artifact field values, Glare API uses `json-patch
|
|
<http://jsonpatch.com/>`_.
|
|
|
|
Glare supports microversions to define what API version it should use:
|
|
`API-WG microversion guidelines <http://specs.openstack.org/openstack/
|
|
api-wg/guidelines/microversion_specification.html>`_.
|
|
|
|
For description of artifact type `json-schema <http://json-schema.org/>`_ is
|
|
used.
|
|
|
|
Media types
|
|
^^^^^^^^^^^
|
|
|
|
Currently this API relies on JSON to represent states of REST resources.
|
|
|
|
Error states
|
|
^^^^^^^^^^^^
|
|
|
|
The common HTTP Response Status Codes (https://github.com/for-GET/know-your-http-well/blob/master/status-codes.md) are used.
|
|
|
|
Application root [/]
|
|
^^^^^^^^^^^^^^^^^^^^
|
|
Application Root provides links to all possible API versions for Glare. URLs
|
|
for other resources described below are relative to Application Root.
|
|
|
|
API schemas root [/schemas/]
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
All the API urls are relative to schemas of artifact types.
|
|
|
|
* **List of enabled artifact type schemas**
|
|
* **GET /schemas** - JSON-schemas list of all enabled artifact types
|
|
|
|
* HTTP Responses:
|
|
* 200
|
|
|
|
* Response schema: JSON dictionary with elements <type_name>: <JSON_schema>
|
|
|
|
* **Get artifact type schema**
|
|
* **GET /schemas/{artifact_type}** - get JSON-schema of artifact type `artifact_type`
|
|
|
|
* HTTP Responses:
|
|
* 200 if `artifact_type` is enabled
|
|
* 404 if no artifact type is defined to handle the specified value of `artifact_type`
|
|
|
|
* Response schema: JSON-schema for requested type
|
|
|
|
|
|
API artifacts root [/artifacts/]
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
All the API urls are relative to artifacts.
|
|
|
|
All the APIs which are specific to the particular artifact type are
|
|
placed to `/artifacts/{artifact_type}`, where `artifact_type` is a constant
|
|
defined by the artifact type definition (i.e. by the related oslo_vo class).
|
|
For example, for artifacts of type "images" the API endpoints will start
|
|
with `/artifacts/images`.
|
|
|
|
The `artifact_type` constant should unambiguously identify the
|
|
artifact type, so the values of this constants should be unique among all the
|
|
enabled artifact types.
|
|
|
|
|
|
* **List artifacts**
|
|
* **GET /artifacts/{artifact_type}** - list artifacts of given type
|
|
|
|
Returns the list of artifacts having the specified type and scoped
|
|
by the current tenant. If the user is ``administrator``, it
|
|
returns the artifacts owned by all the tenants.
|
|
|
|
* **GET /artifacts/all** - list artifacts regardless of their type
|
|
|
|
Returns the list of artifacts of all types for given tenant. Only
|
|
common fields will be shown in the output. All type-specific fields
|
|
are skipped.
|
|
|
|
* URL parameters:
|
|
* `artifact_type` identifier of the artifact type, should be equal to a
|
|
valid constant defined in one of the enabled oslo_vo classes.
|
|
|
|
* Query parameters:
|
|
Query may contain parameters intended for filtering and soring by most
|
|
of the common and type-specific artifact fields.
|
|
The set of parameters and their values should be compliant to the
|
|
schema defined by the artifact type and its version.
|
|
|
|
**Filtering**:
|
|
|
|
* Filter keys may be any common or type-specific fields of
|
|
primitive type, like 'String', 'Float', 'Integer' and 'Boolean'. Also
|
|
it is possible to filter artifacts by Dict keys and Dict or List
|
|
values.
|
|
|
|
Direct comparison requires a field name to be specified as query
|
|
parameter and the filtering value as its value, e.g. `?name=some_name`
|
|
|
|
Parameter names and values are case sensitive.
|
|
|
|
* Artifact API supports filtering operations in the format
|
|
`?name=<op>:some_name`, where `op` is one of the following:
|
|
|
|
1. **eq**: equal;
|
|
2. **neq**: not equal;
|
|
3. **gt**: greater than;
|
|
4. **gte**: greater or equal than;
|
|
5. **lt**: lesser than;
|
|
6. **lte**: lesser or equal than;
|
|
7. **in**: in a list of.
|
|
|
|
Operator `eq` is default and may be omitted, i.e. filter
|
|
`<field_name>=eq:<value>` is equal to `<field_name>=<value>`
|
|
|
|
* Set comparison requires a field name to be specified as query
|
|
parameter. The parameter may be repeated several times, e.g. the query
|
|
`?name=qwerty&version=gt:1.0&version=lt:5.0` will filter the artifacts
|
|
having name `qwerty` and versions from 1.0 to 5.0 excluding.
|
|
|
|
* If it's required to filter the artifacts by any of the values, **in** operator
|
|
should be used. List of comma-separated values should be provided for
|
|
this operator. Query `?name=in:abc,def,ghi` will return all artifacts
|
|
with names `abc`, `def` and `ghi`.
|
|
|
|
* Filtering by Dict values is performed in format
|
|
`<dict_name>.<key_name>=[<op_name>:]<value>`. This filter returns only
|
|
those artifacts, that have the key `key_name` in their Dict `dict_name`
|
|
and the `value` of the key satisfies the right part of the filter.
|
|
It is allowed to filter values for Dict of primitive types only.
|
|
|
|
* Dicts can be filtered by their keys in format
|
|
`dict_name`=[<op_name>:]<value>. Only `eq`, `neq`, `in` can be used
|
|
as filtering operators. For `eq`, it returns all artifacts, that have
|
|
key `value` in their Dict field `dict_name`; for `neq`, it returns all artifacts
|
|
that don't have that key in Dict `dict_name`; for `in`, it returns
|
|
artifacts with any of the keys in comma-separated list `value`.
|
|
|
|
* Filtering by List values may be performed in the same manner as by
|
|
Dict keys.
|
|
|
|
**Sorting**
|
|
|
|
In order to retrieve data in any sort order and direction, artifacts
|
|
REST API accepts multiple sort keys and directions.
|
|
|
|
Artifacts API will align with the `API Working group sorting guidelines
|
|
<https://github.com/openstack/api-wg/blob/master/guidelines/
|
|
pagination_filter_sort.rst>`_ and support the following parameter on
|
|
the request:
|
|
|
|
* sort: Comma-separated list of sort keys. Each key is optionally
|
|
appended with <:dir>, where 'dir' is the direction for the
|
|
corresponding sort key (supported values are 'asc' for ascending
|
|
and 'desc' for descending)
|
|
|
|
Sort keys may be any generic and type-specific metadata fields of
|
|
primitive type, like 'string', 'numeric', 'int' and 'bool'. But sorting
|
|
by type-specific fields is allowed only when artifact version
|
|
is provided.
|
|
|
|
Default value for sort direction is 'desc'. Default value for sort key
|
|
is 'created_at'.
|
|
|
|
**Pagination**
|
|
|
|
`limit` and `marker` query parameters may be used to paginate through
|
|
the artifacts collection in the same way as it is done in the current
|
|
version of Glance "List Images" API.
|
|
|
|
Maximum `limit` number is 1000. It is done for security reasons to protect
|
|
the system from intruders to prevent them from sending requests that can
|
|
pull the entire database at a time.
|
|
|
|
* HTTP Responses:
|
|
* 200 if `artifact_type` is enabled
|
|
* 400 if query has incorrect filter or sort parameters
|
|
* 404 if no artifact type is defined to handle the specified value of `artifact_type`
|
|
|
|
* Response schema:
|
|
|
|
.. code-block:: javascript
|
|
|
|
{
|
|
"<type_name>": [<JSON_list_with_artifacts_data>],
|
|
"first": "/artifacts/<type_name>",
|
|
"schema": "/schemas/<type_name>",
|
|
"next": "<url_to_the_next_page>"
|
|
}
|
|
|
|
* **Create a new artifact**
|
|
|
|
* **POST /artifacts/{artifact_type}**
|
|
|
|
* Creates a new artifact record in database. The status of artifact is set
|
|
to `drafted`. Request body may contain initial metadata of the artifact.
|
|
It's mandatory to define at least artifact `name` and `version` in the request
|
|
body.
|
|
|
|
* URL parameters:
|
|
|
|
* `artifact_type` identifier of the artifact type. It should be equal to a
|
|
valid constant defined in one of the enabled oslo_vo classes.
|
|
|
|
* HTTP Responses:
|
|
|
|
* 201 if everything went fine.
|
|
|
|
* 409 if an artifact of this type with the same name and version already
|
|
exists for tenant.
|
|
|
|
* 400 if incorrect initial values were provided in request body.
|
|
|
|
* 404 if no Artifact Type is defined to handle the specified value of `artifact_type`.
|
|
|
|
* Request content-type: `application/json`
|
|
|
|
* Response content-type: `application/json`
|
|
|
|
* Response schema: JSON with definition of created artifact
|
|
|
|
* **Get an artifact info**
|
|
|
|
* **GET /artifacts/{artifact_type}/{id}**
|
|
|
|
* Returns an artifact record with all the common and type-specific fields
|
|
|
|
* URL parameters:
|
|
|
|
* `artifact_type` identifier of the artifact type. It should be equal to a
|
|
valid constant defined in one of the enabled oslo_vo classes.
|
|
|
|
* `id` identifier of the artifact.
|
|
|
|
* HTTP Responses:
|
|
|
|
* 200 if everything went fine.
|
|
|
|
* 404 if no artifact with the given ID was found.
|
|
|
|
* 404 if the type of the found artifact differs from the type specified by `artifact_type`
|
|
parameter.
|
|
|
|
* Response content-type: `application/json`.
|
|
|
|
* Response body: JSON with artifact definition.
|
|
|
|
* **GET /artifacts/all/{id}**
|
|
|
|
* Returns an artifact record with common fields only, regardless of its type.
|
|
|
|
* URL parameters:
|
|
|
|
* `id` identifier of the artifact
|
|
|
|
* HTTP Responses:
|
|
|
|
* 200 if everything went fine
|
|
|
|
* 404 if no artifact with the given ID was found
|
|
|
|
* Response content-type: `application/json`
|
|
|
|
* Response schema: JSON with artifact definition
|
|
|
|
* **Update an Artifact**
|
|
|
|
* **PATCH /artifacts/{artifact_type}/{id}**
|
|
|
|
* Updates artifact's fields using json-patch notation. If the artifact
|
|
has a status other than `drafted` then only mutable fields may be updated.
|
|
|
|
* URL parameters:
|
|
|
|
* `artifact_type` identifier of the artifact type, should be equal to a
|
|
valid constant defined in one of the enabled oslo_vo classes.
|
|
|
|
* `id` identifier of the artifact.
|
|
|
|
* HTTP Responses:
|
|
|
|
* 200 if everything went fine.
|
|
|
|
* 404 if no artifact with the given ID was found.
|
|
|
|
* 404 if the type of the found artifact differs from type specified by
|
|
`artifact_type` parameter.
|
|
|
|
* 403 if the PATCH attempts to modify the immutable field while the
|
|
artifact's state is other than `drafted`.
|
|
|
|
* 400 if incorrect initial values were provided in request body.
|
|
|
|
* 409 if artifact with updated name and version already exists for the
|
|
tenant.
|
|
|
|
* Request content-type: `application/json-patch+json`
|
|
|
|
* Response content-type: `application/json`
|
|
|
|
* Response body: JSON definition of updated artifact
|
|
|
|
* **Delete an Artifact**
|
|
|
|
* **DELETE /artifacts/{artifact_type}/{id}**
|
|
|
|
* Deletes an artifact db record and all its binary data from store.
|
|
|
|
* URL parameters:
|
|
|
|
* `artifact_type` identifier of the artifact type. It should be equal to a
|
|
valid constant defined in one of the enabled oslo_vo classes.
|
|
|
|
* `id` identifier of the artifact
|
|
|
|
* HTTP Responses:
|
|
|
|
* 204 if everything went fine.
|
|
|
|
* 404 if no artifact with the given ID was found.
|
|
|
|
* 404 if the type of the found artifact differs from type specified by
|
|
`artifact_type` parameter.
|
|
|
|
* **Upload a blob**
|
|
|
|
* **PUT /artifacts/{artifact_type}/{id}/{blob_name}[/{key_name}]**
|
|
|
|
* Uploads binary data to a blob field.
|
|
|
|
* URL parameters:
|
|
|
|
* `artifact_type` identifier of the artifact type, should be equal to a
|
|
valid constant defined in one of the enabled oslo_vo classes.
|
|
|
|
* `id` identifier of the artifact.
|
|
|
|
* `blob_name` name of blob field.
|
|
|
|
* optional: `key_name` name of a key if user uploads data in blob
|
|
dictionary.
|
|
|
|
* HTTP Responses:
|
|
|
|
* 200 if everything went fine.
|
|
|
|
* 404 if no artifact with the given ID was found.
|
|
|
|
* 404 if the type of the found artifact differs from type specified by.
|
|
`artifact_type` parameter.
|
|
|
|
* 400 if `blob_name` field doesn't exist in `artifact_type` or it's not
|
|
a blob field.
|
|
|
|
* 409 if blob is already uploaded and has status `active`.
|
|
|
|
* 409 if blob has status `saving`.
|
|
|
|
* 413 if blob size exceeds the limit specified by artifact type.
|
|
|
|
* Request content-type: any, except
|
|
`application/vnd+openstack.glare-custom-location+json`.
|
|
|
|
* Response content-type: `application/json`.
|
|
|
|
* Response body: JSON definition of the artifact.
|
|
|
|
* **Download a blob**
|
|
|
|
* **GET /artifacts/{artifact_type}/{id}/{blob_name}[/{key_name}]**
|
|
|
|
* Downloads binary data from a blob field.
|
|
|
|
* URL parameters:
|
|
|
|
* `artifact_type` identifier of the artifact type, should be equal to a
|
|
valid constant defined in one of the enabled oslo_vo classes.
|
|
|
|
* `id` identifier of the artifact.
|
|
|
|
* `blob_name` name of blob field.
|
|
|
|
* optional: `key_name` name of a key if user downloads data from blob
|
|
dictionary.
|
|
|
|
* HTTP Responses:
|
|
|
|
* 200 if everything went fine.
|
|
|
|
* 301 if blob has `external` location.
|
|
|
|
* 404 if no artifact with the given ID was found.
|
|
|
|
* 404 if the type of the found artifact differs from type specified by
|
|
`artifact_type` parameter.
|
|
|
|
* 400 if `blob_name` field doesn't exist in `artifact_type` or it's not
|
|
a blob field.
|
|
|
|
* 403 if artifact has status `deactivated`.
|
|
|
|
* Response content-type: specified by `content-type` field from the blob
|
|
description.
|
|
|
|
* Response body: binary data of the blob.
|
|
|
|
* **Add location to a blob**
|
|
|
|
* **PUT /artifacts/{artifact_type}/{id}/{blob_name}[/{key_name}]**
|
|
|
|
* Adds external location to a blob field instead of upload data.
|
|
|
|
* URL parameters:
|
|
|
|
* `artifact_type` identifier of the artifact type, should be equal to a
|
|
valid constant defined in one of the enabled oslo_vo classes.
|
|
|
|
* `id` identifier of the artifact.
|
|
|
|
* `blob_name` name of blob field.
|
|
|
|
* optional: `key_name` name of a key if user inserts location in blob
|
|
dictionary.
|
|
|
|
* HTTP Responses:
|
|
|
|
* 200 if everything went fine.
|
|
|
|
* 404 if no artifact with the given ID was found.
|
|
|
|
* 404 if the type of the found artifact differs from type specified by
|
|
`artifact_type` parameter.
|
|
|
|
* 400 if `blob_name` field doesn't exist in `artifact_type` or it's not
|
|
a blob field.
|
|
|
|
* 409 if blob is already uploaded and has status `active`.
|
|
|
|
* 409 if blob has status `saving`.
|
|
|
|
* Request content-type: `application/vnd+openstack.glare-custom-location+json`.
|
|
|
|
* Response content-type: `application/json`.
|
|
|
|
* Response body: JSON definition of the artifact.
|
|
|
|
.. note::
|
|
|
|
Json-schema for `application/vnd+openstack.glare-external-location+json` and
|
|
`application/vnd+openstack.glare-internal-location+json`:
|
|
|
|
.. code-block:: javascript
|
|
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"url": {"type": ["string", "null"], "format": "uri",
|
|
"max_length": 255}
|
|
},
|
|
"required": ["url"]
|
|
}
|
|
|
|
A detailed example
|
|
^^^^^^^^^^^^^^^^^^
|
|
|
|
For this example, we have an artifact type 'example_type' with fields:
|
|
|
|
* id: StringField
|
|
|
|
* name: StringField
|
|
|
|
* visibility: StringField
|
|
|
|
* status: StringField
|
|
|
|
* blob_file: BlobField
|
|
|
|
* metadata: DictOfStringsField
|
|
|
|
* version: VersionField
|
|
|
|
.. note::
|
|
|
|
For output simplicity this artifact type doesn't contain all required
|
|
fields from Base artifact type.
|
|
|
|
1. Create artifact
|
|
|
|
Request:
|
|
|
|
* Method: POST
|
|
|
|
* URL: http://host:port/artifacts/example_type
|
|
|
|
* Body:
|
|
|
|
.. code-block:: javascript
|
|
|
|
{
|
|
"name": "new_art",
|
|
"version": "1.0"
|
|
}
|
|
|
|
Response:
|
|
|
|
201 Created
|
|
|
|
.. code-block:: javascript
|
|
|
|
{
|
|
"status": "drafted",
|
|
"name": "new_art",
|
|
"id": "art_id1",
|
|
"version": "1.0.0",
|
|
"blob_file": null,
|
|
"metadata": {},
|
|
"visibility": "private"
|
|
}
|
|
|
|
2. Get artifact
|
|
|
|
Request:
|
|
|
|
* Method: GET
|
|
|
|
* URL: http://host:port/artifacts/example_type/art_id1
|
|
|
|
Response:
|
|
|
|
200 OK
|
|
|
|
.. code-block:: javascript
|
|
|
|
{
|
|
"status": "drafted",
|
|
"name": "new_art",
|
|
"id": "art_id1",
|
|
"version": "1.0.0",
|
|
"blob_file": null,
|
|
"metadata": {},
|
|
"visibility": "private"
|
|
}
|
|
|
|
3. List artifacts
|
|
|
|
Request:
|
|
|
|
* Method: GET
|
|
|
|
* URL: http://host:port/artifacts/example_type
|
|
|
|
Response:
|
|
|
|
200 OK
|
|
|
|
.. code-block:: javascript
|
|
|
|
{
|
|
"example_type": [{
|
|
"status": "drafted",
|
|
"name": "new_art",
|
|
"id": "art_id1",
|
|
"version": "1.0.0",
|
|
"blob_file": null,
|
|
"metadata": {},
|
|
"visibility": "private"
|
|
}, {
|
|
"status": "drafted",
|
|
"name": "old_art",
|
|
"id": "art_id2",
|
|
"version": "0.0.0",
|
|
"blob_file": null,
|
|
"metadata": {},
|
|
"visibility": "private"
|
|
}, {
|
|
"status": "drafted",
|
|
"name": "old_art",
|
|
"id": "art_id3",
|
|
"version": "1.0.0",
|
|
"blob_file": null,
|
|
"metadata": {},
|
|
"visibility": "private"
|
|
}],
|
|
"first": "/artifacts/example_type",
|
|
"schema": "/schemas/example_type"
|
|
}
|
|
|
|
Request:
|
|
|
|
* Method: GET
|
|
|
|
* URL: http://host:port/artifacts/example_type?name=eq:old_art
|
|
|
|
Response:
|
|
|
|
200 OK
|
|
|
|
.. code-block:: javascript
|
|
|
|
{
|
|
"example_type": [{
|
|
"status": "drafted",
|
|
"name": "old_art",
|
|
"id": "art_id2",
|
|
"version": "0.0.0",
|
|
"blob_file": null,
|
|
"metadata": {},
|
|
"visibility": "private"
|
|
}, {
|
|
"status": "drafted",
|
|
"name": "old_art",
|
|
"id": "art_id3",
|
|
"version": "1.0.0",
|
|
"blob_file": null,
|
|
"metadata": {},
|
|
"visibility": "private"
|
|
}],
|
|
"first": "/artifacts/example_type?name=eq%3Aold_art",
|
|
"schema": "/schemas/example_type"
|
|
}
|
|
|
|
4. Update artifact
|
|
|
|
Request:
|
|
|
|
* Method: PATCH
|
|
|
|
* URL: http://host:port/artifacts/example_type/art_id1
|
|
|
|
* Body:
|
|
|
|
.. code-block:: javascript
|
|
|
|
[{
|
|
"op": "replace",
|
|
"path": "/name",
|
|
"value": "another_artifact"
|
|
}, {
|
|
"op": "add",
|
|
"path": "/metadata/item",
|
|
"value": "qwerty"
|
|
}]
|
|
|
|
Response:
|
|
|
|
200 OK
|
|
|
|
.. code-block:: javascript
|
|
|
|
{
|
|
"status": "drafted",
|
|
"name": "another_artifact",
|
|
"id": "art_id1",
|
|
"version": "1.0.0",
|
|
"blob_file": null,
|
|
"metadata": {
|
|
"item": "qwerty"
|
|
},
|
|
"visibility": "private"
|
|
}
|
|
|
|
5. Upload blob
|
|
|
|
Request:
|
|
|
|
* Method: PUT
|
|
|
|
* URL: http://host:port/artifacts/example_type/art_id1/blob_file
|
|
|
|
* Body: ``some binary data``
|
|
|
|
Response:
|
|
|
|
200 OK
|
|
|
|
.. code-block:: javascript
|
|
|
|
{
|
|
"status": "drafted",
|
|
"name": "another_artifact",
|
|
"id": "art_id1",
|
|
"version": "1.0.0",
|
|
"metadata": {
|
|
"item": "qwerty"
|
|
},
|
|
"blob_file": {
|
|
"status": "active",
|
|
"checksum": "8452e47f27b9618152a2b172357a547d",
|
|
"external": false,
|
|
"size": 594,
|
|
"content_type": "application/octet-stream",
|
|
"md5": "35d83e8eedfbdb87ff97d1f2761f8ebf",
|
|
"sha1": "942854360eeec1335537702399c5aed940401602",
|
|
"sha256": "d8a7834fc6652f316322d80196f6dcf294417030e37c15412e4deb7a67a367dd",
|
|
"url": "/artifacts//example_type/art_id1/blob_file"
|
|
},
|
|
"visibility": "private"
|
|
}
|
|
|
|
6. Download blob
|
|
|
|
Request:
|
|
|
|
* Method: GET
|
|
|
|
* URL: http://host:port/artifacts/example_type/art_id1/blob_file
|
|
|
|
Response:
|
|
|
|
200 OK
|
|
|
|
Body: ``blob binary data``
|
|
|
|
|
|
7. Activate artifact
|
|
|
|
Request:
|
|
|
|
* Method: PATCH
|
|
|
|
* URL: http://host:port/artifacts/example_type/art_id1
|
|
|
|
* Body:
|
|
|
|
.. code-block:: javascript
|
|
|
|
[{
|
|
"op": "replace",
|
|
"path": "/status",
|
|
"value": "active"
|
|
}]
|
|
|
|
Response:
|
|
|
|
200 OK
|
|
|
|
.. code-block:: javascript
|
|
|
|
{
|
|
"status": "active",
|
|
"name": "another_artifact",
|
|
"id": "art_id1",
|
|
"version": "1.0.0",
|
|
"metadata": {
|
|
"item": "qwerty"
|
|
},
|
|
"blob_file": {
|
|
"status": "active",
|
|
"checksum": "8452e47f27b9618152a2b172357a547d",
|
|
"external": false,
|
|
"size": 594,
|
|
"content_type": "application/octet-stream",
|
|
"md5": "35d83e8eedfbdb87ff97d1f2761f8ebf",
|
|
"sha1": "942854360eeec1335537702399c5aed940401602",
|
|
"sha256": "d8a7834fc6652f316322d80196f6dcf294417030e37c15412e4deb7a67a367dd",
|
|
"url": "/artifacts//example_type/art_id1/blob_file"
|
|
},
|
|
"visibility": "private"
|
|
}
|
|
|
|
8. Deactivate artifact
|
|
|
|
Request:
|
|
|
|
* Method: PATCH
|
|
|
|
* URL: http://host:port/artifacts/example_type/art_id1
|
|
|
|
* Body:
|
|
|
|
.. code-block:: javascript
|
|
|
|
[{
|
|
"op": "replace",
|
|
"path": "/status",
|
|
"value": "deactivated"
|
|
}]
|
|
|
|
Response:
|
|
|
|
200 OK
|
|
|
|
.. code-block:: javascript
|
|
|
|
{
|
|
"status": "deactivated",
|
|
"name": "another_artifact",
|
|
"id": "art_id1",
|
|
"version": "1.0.0",
|
|
"metadata": {
|
|
"item": "qwerty"
|
|
},
|
|
"blob_file": {
|
|
"status": "active",
|
|
"checksum": "8452e47f27b9618152a2b172357a547d",
|
|
"external": false,
|
|
"size": 594,
|
|
"content_type": "application/octet-stream",
|
|
"md5": "35d83e8eedfbdb87ff97d1f2761f8ebf",
|
|
"sha1": "942854360eeec1335537702399c5aed940401602",
|
|
"sha256": "d8a7834fc6652f316322d80196f6dcf294417030e37c15412e4deb7a67a367dd",
|
|
"url": "/artifacts//example_type/art_id1/blob_file"
|
|
},
|
|
"visibility": "private"
|
|
}
|
|
|
|
9. Reactivate artifact
|
|
|
|
Request:
|
|
|
|
* Method: PATCH
|
|
|
|
* URL: http://host:port/artifacts/example_type/art_id1
|
|
|
|
* Body:
|
|
|
|
.. code-block:: javascript
|
|
|
|
[{
|
|
"op": "replace",
|
|
"path": "/status",
|
|
"value": "active"
|
|
}]
|
|
|
|
Response:
|
|
|
|
200 OK
|
|
|
|
.. code-block:: javascript
|
|
|
|
{
|
|
"status": "active",
|
|
"name": "another_artifact",
|
|
"id": "art_id1",
|
|
"version": "1.0.0",
|
|
"metadata": {
|
|
"item": "qwerty"
|
|
},
|
|
"blob_file": {
|
|
"status": "active",
|
|
"checksum": "8452e47f27b9618152a2b172357a547d",
|
|
"external": false,
|
|
"size": 594,
|
|
"content_type": "application/octet-stream",
|
|
"md5": "35d83e8eedfbdb87ff97d1f2761f8ebf",
|
|
"sha1": "942854360eeec1335537702399c5aed940401602",
|
|
"sha256": "d8a7834fc6652f316322d80196f6dcf294417030e37c15412e4deb7a67a367dd",
|
|
"url": "/artifacts//example_type/art_id1/blob_file"
|
|
},
|
|
"visibility": "private"
|
|
}
|
|
|
|
10. Publish artifact
|
|
|
|
Request:
|
|
|
|
* Method: PATCH
|
|
|
|
* URL: http://host:port/artifacts/example_type/art_id1
|
|
|
|
* Body:
|
|
|
|
.. code-block:: javascript
|
|
|
|
[{
|
|
"op": "replace",
|
|
"path": "/visibility",
|
|
"value": "public"
|
|
}]
|
|
|
|
Response:
|
|
|
|
200 OK
|
|
|
|
.. code-block:: javascript
|
|
|
|
{
|
|
"status": "active",
|
|
"name": "another_artifact",
|
|
"id": "art_id1",
|
|
"version": "1.0.0",
|
|
"metadata": {
|
|
"item": "qwerty"
|
|
},
|
|
"blob_file": {
|
|
"status": "active",
|
|
"checksum": "8452e47f27b9618152a2b172357a547d",
|
|
"external": false,
|
|
"size": 594,
|
|
"content_type": "application/octet-stream",
|
|
"md5": "35d83e8eedfbdb87ff97d1f2761f8ebf",
|
|
"sha1": "942854360eeec1335537702399c5aed940401602",
|
|
"sha256": "d8a7834fc6652f316322d80196f6dcf294417030e37c15412e4deb7a67a367dd",
|
|
"url": "/artifacts//example_type/art_id1/blob_file"
|
|
},
|
|
"visibility": "public"
|
|
}
|
|
|
|
11. Delete artifact
|
|
|
|
Request:
|
|
|
|
* Method: DELETE
|
|
|
|
* URL: http://host:port/artifacts/example_type/art_id1
|
|
|
|
Response:
|
|
|
|
204 No Content
|
|
|
|
References
|
|
==========
|
|
#. `Filtering and sorting API-WG guideline <http://specs.openstack.org/openstack/api-wg/guidelines/pagination_filter_sort.html>`_
|
|
|
|
#. `Errors API-WG guideline <http://specs.openstack.org/openstack/api-wg/guidelines/errors.html>`_
|
|
|
|
#. `json-patch description <http://jsonpatch.com/>`_
|
|
|
|
#. `json-schema description <http://json-schema.org/>`_
|