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):///* For internal links its value contains only . Example of : ``/artifacts//`` * *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 `_ * `Errors `_ For updating artifact field values, Glare API uses `json-patch `_. Glare supports microversions to define what API version it should use: `API-WG microversion guidelines `_. For description of artifact type `json-schema `_ 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 : * **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=: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 `=eq:` is equal to `=` * 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 `.=[:]`. 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`=[:]. 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 `_ 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 { "": [], "first": "/artifacts/", "schema": "/schemas/", "next": "" } * **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 `_ #. `Errors API-WG guideline `_ #. `json-patch description `_ #. `json-schema description `_