Skip to content
RafaelSche edited this page May 24, 2019 · 9 revisions

The packager can be executed as service (bare metal or running inside a container) and offers a REST API to which packages can be uploaded to be unpackaged. The resulting artifacts are then pushed to the configured storage backend. The available REST API follows a asynchronous design which means that it directly returns with 200 after a package is uploaded and the unpackaging process is triggered. At this point the unpackaging process is still running and may still fail.

To notify a client about the end of an unpackaging process or an error, we use a callback mechanism: The user can specify a URL in his request the packager calls this URL once the packaging process finishes or an error occurs. More details can be found in the following.

Swagger-based REST API documentation

We use Swagger (OpenAPI) to specify and document the REST API of the packager. This documentation is automatically generated from the Python code and models without any additional human interaction. This ensures that the documentation is always in sync with the code.

You can find it here: REST API specification

Callback

Callbacks are send from the packager to the callback_url given in the unpackaging request once the unpackaging is done. Request type is POST. Expected response is 200 OK.

The callback endpoint is specified with this OpenAPI model.

An example request body looks like this:

{  
    "event_name":"onPackageChangeEvent",
    "package_id":"24c616cf-fe01-4c08-ae44-45d43ae67576",
    "package_location":"http://tng-cat:4011/catalogues/api/v2/tgo-packages/24c616cf-fe01-4c08-ae44-45d43ae67576",
    "package_metadata":null,
    "package_process_uuid":"d5cea225-033f-4fc6-816f-4a642461086a",
    "package_process_status": "success"
}

The package_metadata field can contain arbitrary complex data structures, usually based on the package descriptor of the unpackaged package.

The package_process_uuid can be used by clients to correlate a received callback request to the initial package upload request that triggered the unpackaging procedure.

Examples

The following examples assume that an instance of tng-sdk-package is running locally using port 5099 and that there the following endpoint is available to perform callbacks: http://127.0.0.1:8000/api/v1/packages/on-change.

This setup can be created as follows:

# terminal 1 (run tng-sdk-package service locally without connection to a storage backend, e.g., a catalog)
tng-pkg -s -v --store-skip

# terminal 2 (callback dummy server)
python misc/callback_mock.py

Now the following unpackaging examples can be performed:

Example 1: Unpack a valid package

Request

curl -X POST -v -H "Content-Type: multipart/form-data" \
    -F callback_url="http://127.0.0.1:8000/api/v1/packages/on-change" \
    -F package="@misc/5gtango-ns-package-example.tgo" \
    http://127.0.0.1:5099/api/v1/packages

Response

HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 119
Body:
{
    "package_process_uuid": "e141bb04-bb11-4913-8f14-823b398ab8b6",
    "status": "running",
    "error_msg": null
}

Callback

{"event_name": "onPackageChangeEvent", "package_id": null, "package_location": null, "package_metadata": {"error": null, "warning": null, "descriptor_schema": "https://raw.githubusercontent.com/sonata-nfv/tng-schema/master/package-specification/napd-schema.yml", "vendor": "eu.5gtango", "name": "ns-package-example", "version": "0.1", "package_type": "application/vnd.5gtango.package.nsp", "maintainer": "Manuel Peuster, Paderborn University", "release_date_time": "2009-01-01T10:01:02Z", "metadata": {"tosca": [{"TOSCA-Meta-Version": "1.0", "CSAR-Version": "1.0", "Created-By": "Manuel Peuster (Paderborn University)", "Entry-Definitions": "Definitions/mynsd.yaml", "Entry-Manifest": "mynsd.mf", "Entry-Change-Log": "ChangeLog.txt", "Entry-Licenses": "Licenses"}, {"Name": "TOSCA-Metadata/NAPD.yaml", "Content-Type": "application/vnd.5gtango.napd"}], "etsi": [{"ns_product_name": "ns-package-example", "ns_provider_id": "eu.5gtango", "ns_package_version": "0.1", "ns_release_date_time": "2009-01-01T10:01:02Z"}, {"Source": "Definitions/mynsd.yaml", "Algorithm": "SHA-256", "Hash": "a3734cb3eeaa18dee2daf7f2538c4c3be185bead6fc5a28729f44bf78f2b8af8"}, {"Source": "Definitions/myvnfd.yaml", "Algorithm": "SHA-256", "Hash": "44fc832e0be9c78d8a59d8b57abd8d8f47e6b2e5e7ed264f111e51d3413f911b"}, {"Source": "Icons/upb_logo.png", "Algorithm": "SHA-256", "Hash": "dd83757e632740f9f390af15eeb8bc25480a0c412c7ea9ac9abbb0e5e025e508"}, {"Source": "Images/mycloudimage.ref", "Algorithm": "SHA-256", "Hash": "e26ff11f2cd2efc1eed3a47a94fccbf6fc8d0c844ff15b65aeb02576c1d02640"}, {"Source": "Licenses/LICENSE", "Algorithm": "SHA-256", "Hash": "179f180ea1630016d585ff32321037b18972d389be0518c0192021286c4898ca"}, {"Source": "Scripts/cloud.init", "Algorithm": "SHA-256", "Hash": "e16360cc3518bde752ac2d506e6bdb6bcb6638a0f94df9ea06975ae910204277"}], "_napd_path": "/var/folders/yx/lvxqrl7j7954pkz6mmsh72br0000gn/T/tmp8ry0tkcl/TOSCA-Metadata/NAPD.yaml"}, "package_content": [{"source": "Definitions/mynsd.yaml", "algorithm": "SHA-256", "hash": "a3734cb3eeaa18dee2daf7f2538c4c3be185bead6fc5a28729f44bf78f2b8af8", "content-type": "application/vnd.5gtango.nsd", "tags": ["eu.5gtango"]}, {"source": "Definitions/myvnfd.yaml", "algorithm": "SHA-256", "hash": "44fc832e0be9c78d8a59d8b57abd8d8f47e6b2e5e7ed264f111e51d3413f911b", "content-type": "application/vnd.5gtango.vnfd", "tags": ["eu.5gtango"]}, {"source": "Icons/upb_logo.png", "algorithm": "SHA-256", "hash": "dd83757e632740f9f390af15eeb8bc25480a0c412c7ea9ac9abbb0e5e025e508", "content-type": "image/png"}, {"source": "Images/mycloudimage.ref", "algorithm": "SHA-256", "hash": "e26ff11f2cd2efc1eed3a47a94fccbf6fc8d0c844ff15b65aeb02576c1d02640", "content-type": "application/vnd.5gtango.ref"}, {"source": "Licenses/LICENSE", "algorithm": "SHA-256", "hash": "179f180ea1630016d585ff32321037b18972d389be0518c0192021286c4898ca", "content-type": "text/plain"}, {"source": "Scripts/cloud.init", "algorithm": "SHA-256", "hash": "e16360cc3518bde752ac2d506e6bdb6bcb6638a0f94df9ea06975ae910204277", "content-type": "text/x-shellscript"}], "description": "This is an example 5GTANGO network service package.", "logo": "Icons/upb_logo.png"}, "package_process_status": "success", "package_process_uuid": "8bc03bdd-b577-47bb-8230-436cec766767"}

Example 2: Unpack an invalid package

Request

curl -X POST -v -H "Content-Type: multipart/form-data" \
    -F callback_url="http://127.0.0.1:8000/api/v1/packages/on-change" \
    -F package="@misc/5gtango-ns-package-example-malformed.tgo" \
    http://127.0.0.1:5099/api/v1/packages

Response

HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 119
{
    "package_process_uuid": "c27c03dc-d530-4ff7-9fb0-da412078a243",
    "status": "running",
    "error_msg": null
}

Callback

{"event_name": "onPackageChangeEvent", "package_id": null, "package_location": null, "package_metadata": {"error": "Validation of /var/folders/yx/lvxqrl7j7954pkz6mmsh72br0000gn/T/tmpc3o95kqf/TOSCA-Metadata/NAPD.yaml failed.", "warning": null, "descriptor_schema": "https://raw.githubusercontent.com/sonata-nfv/tng-schema/master/package-specification/napd-schema.yml", "vendor": null, "name": null, "version": null, "package_type": null, "maintainer": null, "release_date_time": null, "metadata": {}, "package_content": []}, "package_process_status": "failed", "package_process_uuid": "c27c03dc-d530-4ff7-9fb0-da412078a243"}

Example 3: Unpack a package with bad checksum

Request

curl -X POST -v -H "Content-Type: multipart/form-data" \
    -F callback_url="http://127.0.0.1:8000/api/v1/packages/on-change" \
    -F package="@misc/5gtango-ns-package-example-bad-checksum.tgo" \
    http://127.0.0.1:5099/api/v1/packages

Response

HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 119
{
    "package_process_uuid": "6135eafe-8a5a-438f-aa04-0c789a87aab7",
    "status": "running",
    "error_msg": null
}

Callback

{"event_name": "onPackageChangeEvent", "package_id": null, "package_location": null, "package_metadata": {"error": "Checksum mismatch! /var/folders/yx/lvxqrl7j7954pkz6mmsh72br0000gn/T/tmpv0c9ay4x/Definitions/myvnfd.yaml(44fc832e0be9c78d8a59d8b57abd8d8f47e6b2e5e7ed264f111e51d3413f911b) != napdr(44fc832e0be9c78d8a59d8b57abd8d8f47e6b2e5e7ed264f111e51d3413f911c)", "warning": null, "descriptor_schema": "https://raw.githubusercontent.com/sonata-nfv/tng-schema/master/package-specification/napd-schema.yml", "vendor": "eu.5gtango", "name": "ns-package-example", "version": "0.1", "package_type": "application/vnd.5gtango.package.nsp", "maintainer": "Manuel Peuster, Paderborn University", "release_date_time": "2009-01-01T10:01:02Z", "metadata": {"tosca": [{"TOSCA-Meta-Version": "1.0", "CSAR-Version": "1.0", "Created-By": "Manuel Peuster (Paderborn University)", "Entry-Definitions": "Definitions/mynsd.yaml", "Entry-Manifest": "mynsd.mf", "Entry-Change-Log": "ChangeLog.txt", "Entry-Licenses": "Licenses"}, {"Name": "TOSCA-Metadata/NAPD.yaml", "Content-Type": "application/vnd.5gtango.napd"}], "etsi": [{"ns_product_name": "ns-package-example", "ns_provider_id": "eu.5gtango", "ns_package_version": "0.1", "ns_release_date_time": "2009-01-01T10:01:02Z"}, {"Source": "Definitions/mynsd.yaml", "Algorithm": "SHA-256", "Hash": "a3734cb3eeaa18dee2daf7f2538c4c3be185bead6fc5a28729f44bf78f2b8af8"}, {"Source": "Definitions/myvnfd.yaml", "Algorithm": "SHA-256", "Hash": "44fc832e0be9c78d8a59d8b57abd8d8f47e6b2e5e7ed264f111e51d3413f911b"}, {"Source": "Icons/upb_logo.png", "Algorithm": "SHA-256", "Hash": "dd83757e632740f9f390af15eeb8bc25480a0c412c7ea9ac9abbb0e5e025e508"}, {"Source": "Images/mycloudimage.ref", "Algorithm": "SHA-256", "Hash": "e26ff11f2cd2efc1eed3a47a94fccbf6fc8d0c844ff15b65aeb02576c1d02640"}, {"Source": "Licenses/LICENSE", "Algorithm": "SHA-256", "Hash": "179f180ea1630016d585ff32321037b18972d389be0518c0192021286c4898ca"}, {"Source": "Scripts/cloud.init", "Algorithm": "SHA-256", "Hash": "e16360cc3518bde752ac2d506e6bdb6bcb6638a0f94df9ea06975ae910204277"}], "_napd_path": "/var/folders/yx/lvxqrl7j7954pkz6mmsh72br0000gn/T/tmpv0c9ay4x/TOSCA-Metadata/NAPD.yaml"}, "package_content": [{"source": "Definitions/mynsd.yaml", "algorithm": "SHA-256", "hash": "a3734cb3eeaa18dee2daf7f2538c4c3be185bead6fc5a28729f44bf78f2b8af8", "content-type": "application/vnd.5gtango.nsd", "tags": ["eu.5gtango"]}, {"source": "Definitions/myvnfd.yaml", "algorithm": "SHA-256", "hash": "44fc832e0be9c78d8a59d8b57abd8d8f47e6b2e5e7ed264f111e51d3413f911c", "content-type": "application/vnd.5gtango.vnfd", "tags": ["eu.5gtango"]}, {"source": "Icons/upb_logo.png", "algorithm": "SHA-256", "hash": "dd83757e632740f9f390af15eeb8bc25480a0c412c7ea9ac9abbb0e5e025e508", "content-type": "image/png"}, {"source": "Images/mycloudimage.ref", "algorithm": "SHA-256", "hash": "e26ff11f2cd2efc1eed3a47a94fccbf6fc8d0c844ff15b65aeb02576c1d02640", "content-type": "application/vnd.5gtango.ref"}, {"source": "Licenses/LICENSE", "algorithm": "SHA-256", "hash": "179f180ea1630016d585ff32321037b18972d389be0518c0192021286c4898ca", "content-type": "text/plain"}, {"source": "Scripts/cloud.init", "algorithm": "SHA-256", "hash": "e16360cc3518bde752ac2d506e6bdb6bcb6638a0f94df9ea06975ae910204277", "content-type": "text/x-shellscript"}], "description": "This is an example 5GTANGO network service package.", "logo": "Icons/upb_logo.png"}, "package_process_status": "failed", "package_process_uuid": "6135eafe-8a5a-438f-aa04-0c789a87aab7"}

Example 4: Create a package:

Request:

curl -X POST -F project="@misc/5gtango_ns_a10_nginx_zipped_project_example.zip" http://127.0.0.1:5099/api/v1/projects

Response:

{
    "package_process_uuid": "198a8afb-3b8a-4272-965d-3e92fcfeafe3",
    "status": "running",
    "error_msg": null
}

Callback

{"event_name": "onPackageChangeEvent",
 'package_download_link': '/api/v1/projects/eu.5gtango.a10networks-nginx.0.1.tgo',
 'package_id': None,
 'package_location': 'packages/eu.5gtango.a10networks-nginx.0.1.tgo',
 'package_metadata': {...},
 'package_process_status': 'success',
 'package_process_uuid': '2e268638-f112-4e0e-8165-ed99a8476a8b'}

Get list of all available packages:

curl -X GET http://0.0.0.0:5099/api/v1/projects

Response

[
    {
        "package_name": "eu.5gtango.a10networks-nginx.0.1.tgo",
        "package_download_link": "http://0.0.0.0:5099/api/v1/projects/eu.5gtango.a10networks-nginx.0.1.tgo"
    },
    ...
]

It also possible to download the package directly by appending the filename of the created package on to the projects endpoint.

Example

curl -X GET http://127.0.0.1:5099/api/v1/projects/eu.5gtango.a10networks-nginx.0.1.tgo --output eu.5gtango.a10networks-nginx.0.1.tgo

Querying the packager status

# get status of all known packageing processes
curl -X GET http://127.0.0.1:5099/api/v1/packages/status

# get status of specific packageing process
curl -X GET http://127.0.0.1:5099/api/v1/packages/status/<packager_process_uuid>