Commit aa6b57ec authored by Konstantinos Togias's avatar Konstantinos Togias
Browse files

docs: record TF-SDK 2.0.0 support and release limits

parent 565cc4cc
Loading
Loading
Loading
Loading
Loading
+3 −0
Changes for ci/lab/EXPLAINED.md: 3 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -142,6 +142,9 @@ accuracy. The matrix keeps these limits alongside each result.

## Choose a check or run the lab

The [Release 2.0.0 TF-SDK support matrix](../../docs/releases/2.0.0/tf-sdk-support-matrix.md)
records SDK fields, operations and limits. Use the generated run matrix for actual E2E results.

The [individual check catalogue](CHECKS.md) explains each test with its own
flow diagram and source link. The [operator guide](README.md) contains local
commands, profiles and troubleshooting.
+4 −1
Changes for ci/lab/README.md: 4 added lines, 1 removed line.
Original line number Diff line number Diff line
# Progressive disposable platform lab

New to OpenOP? Read the short [illustrated overview](EXPLAINED.md) and
[individual check catalogue](CHECKS.md) first. This page is the operator guide.
[individual check catalogue](CHECKS.md) first. The
[Release 2.0.0 TF-SDK support matrix](../../docs/releases/2.0.0/tf-sdk-support-matrix.md)
records SDK implementation limits; the generated feature matrix records each run.
This page is the operator guide.

## Find the results

+250 −0
Changes for docs/releases/2.0.0/tf-sdk-support-matrix.md: 250 added lines, 0 removed lines.
Original line number Diff line number Diff line
# TF-SDK support matrix: Release 2.0.0

OpenOP receives application and network requests through OEG. SRM resolves
their target and calls TF-SDK. The SDK translates that resolved request for
the selected cluster or network backend.

This matrix describes the SDK part of that path. It records the release
implementation, including limits; a listed operation alone does not prove
that the complete public API works with every backend.

Source: [TF-SDK release commit 41db8de](https://labs.etsi.org/rep/oop/code/tf-sdk/-/commit/41db8de823167088063cc562ae976449fa560688).
This release snapshot is kept beside the deployment documentation while the
SDK release source stays frozen. SDK code and Architecture remain the
implementation and specification authorities respectively.

## 1. Read implementation and test results separately

| Label | Meaning |
|---|---|
| Implemented | The SDK handles the stated input or operation; backend and end-to-end verification are separate. |
| Partial | The implementation has the limit described in that row. |
| No effect | This SDK path does not apply the field. |
| Unsupported | The release does not offer the operation, or the stated input is rejected. |

The [lab guide](../../../ci/lab/EXPLAINED.md) explains the real execution.
Its [check catalogue](../../../ci/lab/CHECKS.md) links each check to a diagram
and assertions. Open a pipeline's **release-feature-report** for its generated
feature matrix, component identities and links to actual runs. A historical
pass qualifies its recorded inputs; it does not qualify a later release image.
Unexecuted features remain **not run**.

## 2. Adapters and contract operations

| Adapter | Backend | Release contract support | Lab coverage |
|---|---|---|---|
| `kubernetes` | Kubernetes, using Helm | `workload`, with `helm` and `container` runtime types | Container lifecycle and the bundled test chart |
| `oai` | EURECOM NEF | `qod_session`, `location_context`, `traffic_influence` | EURECOM/CoreSim and one simulated IPv4 device |
| `open5gs` | Open5GS NEF | `qod_session`, `location_context` | Not tested by this lab |
| `open5gcore` | Open5GCore NEF | `qod_session` | Not tested by this lab |
| `i2edge`, `i2cat_ric` | Retained legacy clients | No advertised capabilities in this release | Not tested |
| `aeros`, `juniper_ric` | Legacy code or placeholder | No registered contract adapter | Not tested |

| Adapter/capability | Operations offered by the SDK |
|---|---|
| Kubernetes `workload` | `activate`, `update`, `terminate`, `read_runtime_state` |
| OAI/Open5GS/Open5GCore `qod_session` | `activate`, `terminate`, `read_runtime_state` |
| OAI/Open5GS `location_context` | `query` |
| OAI `traffic_influence` | `activate`, `update`, `terminate`, `read_runtime_state` |

`capability_surface` returns `([], [])` for an unsupported capability of a
registered adapter. An unknown adapter kind raises `UnknownAdapterKind`.
Offering an SDK operation does not imply a corresponding public OEG route.
Kubernetes does not offer `query_available_resources` through this surface.

## 3. Control-path configuration

| Adapter | Setting | Release behavior |
|---|---|---|
| All contract adapters | `control_path_ref` | Required construction identity. SRM derives it from the bootstrap entry's `ref`; the SDK rejects a request addressed to another instance. |
| Kubernetes | `kubeconfig_path`, `kube_context`, `namespace` | Explicit absolute file, selected context and workload namespace. |
| Kubernetes | `in_cluster: true`, `namespace` | Alternative using the SRM Pod's service account. It cannot be combined with file/context selection. |
| Kubernetes | `endpoint_host` | Address clients use to reach application NodePorts; different purpose from the Kubernetes API address. Without it, endpoint metadata is absent. |
| Kubernetes | `tls_verify`, `runtime_directory`, `helm_binary` | Explicit TLS policy, private execution files and Helm executable; runtime directory defaults to `/var/run/openop-tfsdk`. |
| Kubernetes | `helm_environment` | Explicit supported Helm registry/repository file paths. Ambient Helm connection overrides are excluded. |
| Network | `base_url`, `scs_as_id` | NEF address and AF/SCS identity used in the backend URLs. |
| OAI | `qos_profiles` | Optional per-control-path allowlist. When omitted, syntactically valid profile names reach the NEF, which accepts or refuses them. |
| Network QoD/TI | `notification_url` | Technical destination used by the selected SDK/backend path; distinct from OEG's public client callbacks. QoD retains an explicit legacy fallback to `parameters.extra.sink`. |

Kubernetes configuration without either explicit connection mode is rejected.
Unresolved `kubeconfig_ref`, independent `api_server` overrides, external
credential plugins, basic authentication and configured kubeconfig proxies
are outside the supported connection profile. Deployment tooling prepares
the file/Secret mounts; the SDK does not fetch those Secrets itself.

QoD's assessed [3GPP AS Session with QoS schema](https://forge.3gpp.org/rep/all/5G_APIs/-/blob/REL-18/TS29122_AsSessionWithQoS.yaml)
requires `notificationDestination`. Traffic Influence's
[3GPP schema](https://forge.3gpp.org/rep/all/5G_APIs/-/blame/7a3e815e9b0e6d8836eabbefc3360c8bdea8d9d0/TS29522_TrafficInfluence.yaml)
requires it when `subscribedEvents` is supplied. The current SDK/EURECOM TI
path requires a configured URL even without that field; this provider-path
constraint must not be described as an unconditional TI standard rule.

The lab supplies a callback returning HTTP 204 through the bootstrap
`notification_url`. It checks the destination carried by QoD/TI subscriptions,
not notification delivery or processing. A syntactically valid dummy URL
alone proves neither reachability nor working callbacks. Location currently
uses backend-client placeholder destinations, not this configuration setting.

## 4. Quality on Demand (`qod_session`)

### Backend limits

| Backend | Profile names | Device/server addresses | Flow ports |
|---|---|---|---|
| OAI | Explicit `qos_profiles`, or pass-through when omitted | IPv4; the application flow expects a single host | IP-to-IP only |
| Open5GS | `qos-e`, `qos-s`, `qos-m`, `qos-l`, lowercase | Client supports IPv4/IPv6, but the current GET reconstruction is IPv4-specific | Client supports them when supplied through traffic filters |
| Open5GCore | Same four names, case-insensitive validation | Client supports IPv4/IPv6, but the current GET reconstruction is IPv4-specific | Client supports them when supplied through traffic filters |

| CAMARA input | SDK field | Release behavior |
|---|---|---|
| `device.ipv4Address.publicAddress` | `target.device.ipv4` | Used; also becomes the private address when none is supplied. |
| `device.ipv4Address.privateAddress` | `target.device.ipv4_private` | Preferred for the UE address and flow, including behind NAT. |
| `device.ipv4Address.publicPort` | `target.device.ipv4_port` | Carried into the client model; no effect on the current NEF UE selection. |
| `device.ipv6Address` | `target.device.ipv6` | Partial: supported by the non-OAI create path; OAI requires IPv4. GET reconstruction has the separate limit above. |
| `device.phoneNumber` | `target.device.phone_number` | No effect for QoD; a device still needs an IPv4/IPv6 address. |
| `device.networkAccessIdentifier` | `target.device.network_access_id` | No effect for QoD device selection. |
| `applicationServer.ipv4Address` | `target.application_server.ipv4` | A host is sent without `/32`; a subnet retains CIDR. The OAI flow builder appends `/32`, so subnets are outside its supported host path. |
| `applicationServer.ipv6Address` | `target.application_server.ipv6` | Partial: non-OAI clients; OAI requires an application IPv4 address. |
| `devicePorts` | No equivalent device-model field | Not carried through that model. The adapter can use `traffic_filters.source.port`; the assessed SRM QoD mapping does not populate it. |
| `applicationServerPorts` | No equivalent server-model field | The equivalent alternative is `traffic_filters.destination.port`; same mapping limit. |
| `qosProfile` | `parameters.profile_ref` | Invalid syntax or an explicit client allowlist can fail locally. A valid OAI name without an allowlist reaches the NEF; a backend refusal becomes `DomainExecutionFailed` with available safe details. |
| `duration` | `parameters.duration_seconds` | Sent as `usageThreshold.duration`. |
| `sink`, `sinkCredential` | Public callback handling belongs to OEG | The technical NEF destination comes from control-path configuration; QoD retains the explicit legacy sink fallback. This does not implement public notification processing. |

| Operation | Backend action and SDK result |
|---|---|
| `activate` | POST the QoS subscription; return its ID and lifecycle `active` after creation. This is not proof of radio QoS enforcement. |
| `read_runtime_state` | GET the subscription. The adapter maps `AVAILABLE` to `active` and `UNAVAILABLE` to `failed`; the current shared client reconstructs a successful GET with `AVAILABLE`. Not-found maps to `unknown`. |
| `terminate` | DELETE the subscription; return `deactivated`, or `ResourceNotFound` when missing. |
| `update` | Unsupported by the offered QoD contract surface; use terminate/create for a changed subscription. |

## 5. Location Retrieval (`location_context`)

The public SDK operation is a synchronous `query`, returning a location rather
than a lifecycle handle. Internally it sends a NEF Monitoring Event request;
the OAI path requests one immediate report. It must not be described as
performing no backend subscription operation.

| Backend | Accepted identifier | Result |
|---|---|---|
| OAI | `network_access_id` first; otherwise IPv4, resolved through the NEF UE-ID API, preferring private IPv4 | Geographic circle/polygon. A cell-only response is insufficient. |
| Open5GS | `phone_number` | Last-known polygon location through its client; no live coverage in this lab. |
| Open5GCore | None | No offered location capability. |

| CAMARA field | SDK field | Release behavior |
|---|---|---|
| Public/private IPv4 | `target.device.ipv4` / `ipv4_private` | OAI identifier lookup; private address takes precedence. |
| Public IPv4 port | `target.device.ipv4_port` | No effect. |
| `phoneNumber` | `target.device.phone_number` | Open5GS only. |
| `networkAccessIdentifier` | `target.device.network_access_id` | OAI external identifier. |
| `ipv6Address` | `target.device.ipv6` | No supported location identifier; IPv6-only selection raises `UnsupportedIdentifier`. |
| `maxAge` | `parameters.max_age_seconds` | Checked against the returned fix time; older fixes raise `MaxAgeUnsatisfiable`. The SDK does not force a fresh measurement. Zero leaves no age tolerance. |
| `maxSurface` | `parameters.max_surface_sqm` | Checks the returned circle/polygon area; an excessive area raises `MaxSurfaceUnsatisfiable`. |
| `lastLocationTime` | `result.last_location_time` | Uses the backend fix timestamp when present; otherwise the report time minus the age in minutes. |
| `area` | `result.area` | Circle (`center`, `radius_m`) or polygon (`boundary`). |
| Identifier metadata | `srm_resolved_identifier` | Name of the selected SDK identifier field, such as `ipv4`; not the actual subscriber ID or an automatic echo of the public response device. |

Location refusals have distinct SDK types: `SubscriberNotFound`,
`UnsupportedIdentifier`, `TargetNotLocatable`, `MaxAgeUnsatisfiable` and
`MaxSurfaceUnsatisfiable`. SRM/OEG own their public HTTP/CAMARA mapping;
the SDK table alone does not verify those downstream responses.

## 6. Traffic Influence (`traffic_influence`)

The offered adapter is OAI/EURECOM. Device TI needs both a device IPv4 and
the application's actual host IPv4. An application instance ID is not an IP.

| Public input/concept | SDK field | Release behavior |
|---|---|---|
| `appId` | `target.application_reference.external_app_id` | Sent as the backend `afAppId`. |
| `appInstanceId` | Resolved by SRM to `target.application_server.ipv4` | SRM supplies the observed endpoint host; the SDK passes that host IP to the NEF. Arbitrary FQDNs or missing endpoints need separate handling. |
| `edgeCloudZoneId` | Resolved `target.zone_ref` | Used as a DNAI in `trafficRoutes`; configuration must match the NEF/core's DNAI. |
| `edgeCloudRegion` | Resolved upstream to a zone | No independent region-resolution behavior in the SDK. Upstream region selection requires its own consumer evidence. |
| Device | `target.device.ipv4` / `ipv4_private` | Required; private address preferred. All-device TI is outside the selected EURECOM release path. |
| Source/destination traffic filters | `parameters.traffic_filters` | No effect on this client path; it builds an IP-to-IP flow. |
| `subscriptionRequest` | Public callbacks belong to OEG | The NEF destination comes from the control path's `notification_url`. |
| QoD duration/profile | `duration_seconds`, `profile_ref` | Not used by TI. |

Missing device, application reference, application IPv4 or technical
notification destination fails before the provider create/update call.

| Operation | Backend action and SDK result |
|---|---|
| `activate` | POST; return lifecycle `active` and the subscription ID from its self link. |
| `update` | PUT; return lifecycle `active` with the same ID. Public update availability is a separate OEG concern. |
| `read_runtime_state` | GET; `active` when present, `unknown` when not found. This is subscription state, not a packet-steering measurement. |
| `terminate` | DELETE; return `deactivated`, or `ResourceNotFound` when missing. |

## 7. Application deployment (`workload`)

The Kubernetes adapter requires Helm 3.10 or later and invokes it for both a
supplied chart and a plain container image. A container uses the SDK's bundled chart. Service observation
uses the Kubernetes client through the same explicit control-path connection.

| Public input/concept | SDK field | Release behavior |
|---|---|---|
| `appRepo.imagePath` | `deployment_unit.artifact_ref` | Helm chart reference/archive or container image, according to runtime type. |
| Deployment name | `deployment_unit.deployment_unit_ref` | Normalized Helm release name: lowercase, invalid characters replaced, letter prefix when needed, maximum 53 characters. The returned `external_id` is this name. |
| `packageType` | `runtime_type` | `helm` and `container` only. |
| CPU/memory | `resource_requirements.compute` | Container requests: `<millicores>m` and decimal `<memory_mb>M`; absent/zero values add no request. Negative values are rejected. |
| Resource limits, GPU, storage | No implemented mapping | Not applied by this deployment path. |
| Compute with a Helm package | Same compute field | No effect on the supplied chart; chart-owned values determine resources. |
| Network interfaces | `resource_requirements.interfaces` | Container ports and one Service: NodePort for external visibility, ClusterIP for internal. Mixed visibility and unsupported protocols are rejected. |
| Interfaces with a Helm package | Same interfaces field | Do not configure the chart. External interfaces are used to match observed NodePort Services by target port/protocol. |
| App-repository credentials | No per-request mapping here | Not received through this SDK deployment input. Explicit deployment-owned Helm registry/repository configuration remains available. |
| Zone/cluster reference | Resolved request target and control path | SRM selects the target; the SDK uses that adapter's configured connection and checks instance identity. |

| Operation | Helm command and result |
|---|---|
| `activate` | `helm install --create-namespace --atomic --wait`; return `active`, release ID and any observed endpoints. A failed install raises a domain error. |
| `update` | `helm upgrade --atomic --wait`; return `active` and the release ID. The result currently does not refresh endpoint metadata. |
| `read_runtime_state` | `helm status -o json`: deployed becomes `active`, failed becomes `failed`, other states become `degraded`. A nonzero status command currently returns `unknown`; it can also hide an observation failure. |
| `terminate` | `helm uninstall --wait`; return `deactivated`. Missing release maps to `ResourceNotFound`; other recognized command failures map to a domain error. |

After activation, each reported external endpoint uses `endpoint_host` and an
observed NodePort. Helm Services must belong to the selected release/namespace,
and each requested port/protocol must match uniquely. Ingress, LoadBalancer
and ambiguous or named target-port discovery are outside this observation path.

Missing endpoint configuration or failed observation preserves the installed
release handle and returns no endpoints, with a warning. A successful deployment
therefore does not guarantee usable public endpoint metadata.

## 8. Errors and diagnostic limits

| Contract error | Meaning in the implemented paths |
|---|---|
| `ValidationError` | Invalid supported request/configuration, unsupported operation or a client-side refusal. |
| `ResourceNotFound` | Recognized missing backend subscription or Helm release. |
| `DomainExecutionFailed` | Backend/transport/execution failure; network failures can carry allowlisted HTTP status and reason details. |
| Location refusal types | The five distinct target/identifier/age/area outcomes listed above. |
| `UnknownAdapterKind` | No registered contract adapter for the requested kind. |
| `InvalidTargetRef` | An undeclared bootstrap binding or execution directed to another control-path instance. |

Contract adapters use structured events and allowlisted diagnostic helpers
for selected handled failures. Some retained legacy clients still
log backend URLs or response content. This release does not establish that
every SDK log is redacted or every malformed backend response becomes a typed
contract error. Configure log access/levels accordingly and keep that boundary
visible when assessing diagnostic behavior.

## 9. Release limits and evidence

The implemented scope excludes mapped QoD device/server port lists, container
resource limits/GPU/storage, mixed container-port visibility, Helm values from
CAMARA compute requests, IPv6-only location, new notification receivers and
all-device TI through the selected EURECOM path. DNN/S-NSSAI are not exposed
through the assessed public-to-SDK request mapping.

The lab's network checks prove provider subscription parameters and cleanup,
not radio QoS, actual packet steering, notification processing or real-device
positioning accuracy. Open5GS/Open5GCore, browser login, Portal, AI2, Data Lab,
bilateral federation, multi-cluster execution and every arbitrary Helm chart
remain outside this core lab's live coverage.

Review the source and matching evidence when a field matters:

- [SDK contract adapters and models](https://labs.etsi.org/rep/oop/code/tf-sdk/-/tree/41db8de823167088063cc562ae976449fa560688/src/openop_tfsdk/contract).
- [SDK network clients](https://labs.etsi.org/rep/oop/code/tf-sdk/-/tree/41db8de823167088063cc562ae976449fa560688/src/openop_tfsdk/network).
- [SDK contract tests](https://labs.etsi.org/rep/oop/code/tf-sdk/-/tree/41db8de823167088063cc562ae976449fa560688/tests/contract): deterministic client/command tests do not count as live backend acceptance.
- [Individual lab checks and flow diagrams](../../../ci/lab/CHECKS.md), followed by the actual pipeline's generated feature matrix and candidate receipt.