deb-glare/doc/source/developer/webapi/v1.rst

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/>`_