Fabric API Service
ETSI HypO uses a dedicated service - titled Fabric API - to integrate with OpenZiti; an open-source secure networking platform that provides both zero-trust security and overlay networking as pure open source software. This service exposes an API that allows ETSI HypO to manage (create, read, update, delete) key OpenZiti entities, such as identities, connections, policies, etc.
The key feature in Fabric API is that it may integrate with multiple OpenZiti instances simultaneously.
API
The Fabric API exposes a set of REST API as shown in the following tables.
| Method | Endpoint | Description | Response Codes | Auth Roles | Leads to |
|---|---|---|---|---|---|
GET |
/fabric-api/network/controller |
Returns all network controllers | 200, 401, 403 | admin | |
GET |
/fabric-api/network/controller/{id} |
Returns a network controller matching the provided id | 200, 401, 403 | admin | |
POST |
/fabric-api/network/controller |
Creates a new network controller | 201, 401, 403 | admin | Stores a network object in the database. Sends a message to Registry API in order to store credentials |
PATCH |
/fabric-api/network/controller/{id} |
Updates a network controller matching the provided id | 200, 401, 403 | admin | Updates the network object in the database. |
DELETE |
/fabric-api/network/controller/{id} |
Deletes a network controller matching the provided id | 204, 401, 403 | admin | Deletes a network object in the database. Sends a message to Registry API in order to remove credential |
A sample POST body request is shown below:
{
"networkName": "Patras' Controller2",
"networkOwner": "Patras",
"networkLocation": "Patras University street address",
"networkEndpoint": "https://localhost:3333",
"username": "admin",
"password": "password"
}
The password is not stored in the Fabric API database. As soon as a network create request is received, a message is published
in the Kafka channel fabric-ziti-creds-persist-incoming-channel. Afterwards Registry API reads the message and stores a
secret for the triplet (networkControllerId, username, password). NetworkControllerId is a UUID generated by Fabric API at runtime
and is unique for each network object.
| Method | Endpoint | Description | Response Codes | Auth Roles | Leads to |
|---|---|---|---|---|---|
GET |
/fabric-api/network/controller/{networkControllerId}/domain/identities |
Returns all network ids for the provided network controller id | 200, 401, 403 | admin | GET call in the corresponding Ziti Controller |
GET |
/fabric-api/network/controller/{networkControllerId}/domain/identities/{id} |
Returns an identity based on its id and the managing network controller id | 200, 401, 403 | admin | GET call in the corresponding Ziti Controller |
GET |
/fabric-api/domain/identities |
Returns all Identities | 200, 401, 403 | admin | GET calls in all corresponding Ziti Controllers |
POST |
/fabric-api/network/controller/{networkControllerId}/domain/identities |
Creates a new Domain Identity under a specific network controller | 201, 401, 403 | admin | POST call in the corresponding Ziti Controller |
PATCH |
/fabric-api/network/controller/{networkControllerId}/domain/identities |
Creates a new Domain Identity under a specific network controller | 201, 401, 403 | admin | PATCH call in the corresponding Ziti Controller |
DELETE |
/fabric-api/network/controller/{networkControllerId}/domain/identities/{id} |
Deletes a Domain Identity matching the provided id and the managing network controller id | 204, 401, 403 | admin | DELETE call in the corresponding Ziti Controller |
A sample POST body request is provided below:
{
"domainIdentity": {
"name": "test",
"type": "Device",
"appData": {},
"isAdmin": true,
"roleAttributes": [
"ACME"
],
"authPolicyId": "default",
"externalId": "",
"defaultHostingCost": "0",
"defaultHostingPrecedence": "default",
"tags": {},
"enrollment": {
"ott": false
}
},
"organizationId": "3b730fdd-fc0b-427a-bb88-63ef6d540d8f",
"organizationName": "ACME"
}
When Fabric API receives the request, it retrieves the network controller from the path provided id and then a subsequent POST request is performed
using the network controller endpoint as the base URL. The body for this request is the domainIdentity value of the request above. If the request is successful
some basic data are persisted in the Fabric API database, the most important being the network controller generated domainIdentityId which is used as the unique
identifier in Fabric API as well. The organization fields are TMF API related and are used in the end user service flow.
A sample PATCH body request is presented below:
{
"domainIdentity": {
"roleAttributes": [
"ACME","CORP"
]
},
"organizationId": "3b730fdd-fc0b-427a-bb88-63ef6d540d8f",
"organizationName": "ACME"
}
The only updates allowed for an identity are on upon its roleAttributes and the related organization.
| Method | Endpoint | Description | Response Codes | Auth Roles | Leads to |
|---|---|---|---|---|---|
GET |
/fabric-api/network/controller/domain/connections |
Returns all domain connections | 200, 401, 403 | admin, infrastructure-provider | |
GET |
/fabric-api/network/controller/{networkControllerId}/domain/connections |
Returns all domain connections for a particular network controller id | 200, 401, 403 | admin, infrastructure-provider | |
GET |
/fabric-api/network/controller/{networkControllerId}/domain/connections/{id} |
Returns a domain connection for a provided id and a network controller id | 200, 401, 403 | admin, infrastructure-provider | |
POST |
/fabric-api/network/controller/{networkControllerId}/domain/connections |
Creates a new domain connection using a specific network controller id | 201, 401, 403 | admin, infrastructure-provider | Subsequent calls though the managing Controller in order to create Ziti objects tha ensure the domain connection |
DELETE |
/fabric-api/network/controller/{networkControllerId}/domain/connections/{id} |
Deletes a domain connection for a provided id and a network controller id | 204, 401, 403 | admin, infrastructure-provider | Removes all corresponding objects to Ziti and the Fabric API database objects |
A sample POST body request is shown below:
{
"serviceOrderId": "0ab14a96-4db0-4850-ac63-be653cd558f8",
"serviceOrderItemId": "f5a465ba-a976-4345-9cf2-496db7069294",
"serviceId": "ece47dec-16bc-4d45-a624-0729db80d1f4",
"domainIdentityId": "Acme Corporation",
"address": "10.20.30.40",
"port": 80,
"protocol": "TCP"
}
With the above provided, Fabric API sends additional requests in Ziti in order to create the quintuplet below that materializes a domain connection:
- a host config for the provided address, protocol and port
- an intercept config for the provided address, protocol and port
- a Ziti service
- a dial policy for the provided domain identity (which corresponds to the provided address and port)
- a bind policy for the provided domain identity (which corresponds to the provided address and port)
KAFKA Channels
| channel name | type | publisher | subscriber | action |
|---|---|---|---|---|
| fabric-ziti-creds-persist-incoming-channel | outgoing | FABRIC API |
REGISTRY API |
Stores Network Credentials |
| fabric-ziti-creds-delete-incoming-channel | outgoing | FABRIC API |
REGISTRY API |
Deletes Network Credentials |
| fabric-api-connection | incoming | SONATA |
FABRIC API |
Creates a new domain connection related to a Kubernetes Service |
| fabric-api-connection-result | outgoing | FABRIC API |
SONATA |
Domain creation result |
| fabric-api-connection-teardown | incoming | SONATA |
FABRIC API |
Deletes a domain connection related to a Kubernetes Service |
| fabric-api-connection-teardown-result | outgoing | FABRIC API |
SONATA |
Domain connection deletion result |
Sample messages for the channels are show below.
fabric-api-connection channel:
{
"specversion": "1.0",
"id": "8963475e-425c-4df1-b6a9-163b0037ac4d",
"source": "/process/fabricApiConfigurationProcess",
"type": "fabric-api-connection",
"time": "2024-02-26T15:07:11.763520617+02:00",
"kogitoproctype": "BPMN",
"kogitoprocinstanceid": "7aa45064-f4a7-4a25-a7a2-667afb07c3d1",
"kogitoprocist": "Active",
"kogitoprocversion": "1.0",
"kogitoprocid": "fabricApiConfigurationProcess",
"data": {
"serviceOrderId": "2c4fecbc-c436-4f8c-a5db-4a1159ebad2a",
"serviceId": "56165b84-40e1-4f53-a064-cc9ae6998beb",
"organizationName": "open-slice-uop",
"address": "10.0.2.4",
"ports": [8000, 30180],
"protocol": "tcp"
}
}
from the message above, Fabric API will create a domain connection for each of the ports included in the message, with the provided
protocol and http address. Through the organization id, Fabric API retrieves the corresponding domain identity and then the managed
network controller for this identity. Through this and the data provided in the message, a new domain connection is created.
Upon success or failure of the above operation, a message will be posted in the Kafka channel fabric-api-connection-result in order to inform
Sonata:
{
"specversion": "1.0",
"id": "21627e26-31eb-43e7-8343-92a696fd96b1",
"source": "/process/fabricApiServiceConnection",
"type": "fabric-api-connection-result",
"kogitoprocrefid": "7aa45064-f4a7-4a25-a7a2-667afb07c3d1",
"data": {
"serviceOrderId": "2c4fecbc-c436-4f8c-a5db-4a1159ebad2a",
"serviceId": "56165b84-40e1-4f53-a064-cc9ae6998beb",
"organizationName": "open-slice-uop",
"fabricApiClientStatus": "SUCCESS",
"fabricApiClientMessage": "everything went as expected"
}
}
A similar message is published in the topic fabric-api-connection-teardown when the Kubernetes service is terminated:
{
"specversion": "1.0",
"id": "383815b8-e92b-447b-96dc-99bc66d7d728",
"source": "/process/fabricApiServiceConnectionTeardown",
"type": "fabric-api-connection-teardown",
"time": "2024-02-26T15:07:11.763520617+02:00",
"kogitoproctype": "BPMN",
"kogitoprocinstanceid": "d12d2753-ac8f-4029-9546-5d7cca6db145",
"kogitoprocist": "Active",
"kogitoprocversion": "1.0",
"kogitoprocid": "fabricApiConfigurationProcess",
"data": {
"serviceOrderId": "2c4fecbc-c436-4f8c-a5db-4a1159ebad2a",
"serviceId": "56165b84-40e1-4f53-a064-cc9ae6998beb",
"organizationName": "open-slice-uop",
"address": "10.0.2.4",
"ports": [8000, 30180],
"protocol": "tcp"
}
}
The message above will delete or Ziti domain connection objects related to the serviceId, address, ports and protocol provided.
The network that will be used is the one that manages the organization with the provided organizationName. Upon finishing the
operation, Fabric API posts a callback message towards Sonata in the topic fabric-api-connection-teardown-result:
{
"specversion": "1.0",
"id": "966affd3-85f2-4276-8d76-103b314dc32e",
"source": "/process/fabricApiServiceConnection",
"type": "fabric-api-connection-result",
"kogitoprocrefid": "16bd05ff-261b-46c7-8a5e-173ac34eeec3",
"data": {
"serviceOrderId": "2c4fecbc-c436-4f8c-a5db-4a1159ebad2a",
"serviceId": "56165b84-40e1-4f53-a064-cc9ae6998beb",
"organizationName": "open-slice-uop",
"fabricApiClientStatus": "SUCCESS",
"fabricApiClientMessage": "everything went as expected"
}
}