Commit 5095fd9c authored by Konstantinos Togias's avatar Konstantinos Togias
Browse files

Merge release resource and QoD fixes into Helm endpoint work

parents f31da05c 55b67ac5
Loading
Loading
Loading
Loading
+41 −0
Changes for README.md: 41 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -261,6 +261,47 @@ credentials. Keep runtime config out of normalized responses and persisted
topology. The deployment owns mounts; the SDK does not parse a secret URI.
See `tests/contract/bootstrap_example.yaml` for an explicit file-mode example.

## OAI QoD provider profiles

Optionally restrict profile identifiers in an OAI control path's runtime
infrastructure. For example, when the NEF offers these names:

```yaml
control_paths:
  - ref: oai-nef-lab
    adapter_family: network
    adapter_type: oai
    adapter_contract_version: v1
    infrastructure:
      base_url: http://nef.example.test:8080
      scs_as_id: openop
      notification_url: http://notifications.example.test/nef
      qos_profiles: [qos-e, qos2, qos3, qos4]
```

The existing bootstrap runtime accessor and SRM registry pass this configuration
to the SDK factory. The adapter snapshots the list for its own client. Profiles
are opaque provider names: they reach the NEF unchanged, with no inferred aliases
or QoS policy mapping. Configure the actual names and policies offered by that
NEF; the example does not assert a universal OAI default.

Omitting qos_profiles applies no local allowlist: syntactically valid profile
identifiers reach the NEF unchanged. The NEF decides whether a profile exists
and can be applied. There are no built-in provider profile names. An explicit
null, empty, duplicate or malformed list fails adapter construction with
ValidationError. Requests outside a configured list fail before HTTP. Each
control path keeps its own optional restriction. Backend refusals remain typed
execution failures even for profiles allowed locally. The
existing notification destination requirement still applies; configuring profiles
does not implement a receiver or establish data-plane QoS guarantees.

Network DomainExecutionFailed errors include the existing allowlisted backend
status/reason diagnostics in details when available. HTTP400 carries
`{"backend_status": 400, "reason": "bad_request"}`; transport errors carry a safe
reason. Raw response bodies, URLs and exception text are not copied. Error
classes, retryable flags and wrapped HTTP404 classification are unchanged.
SRM's existing bridge can preserve these details without a new contract field.

## Helm workload endpoints

The Kubernetes adapter can report external NodePort endpoints after activating
+4 −0
Changes for ci/README.md: 4 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -54,3 +54,7 @@ The downstream trigger disables inheritance of SDK default variables and passes
only the explicit SDK artifact coordinates. Job-only paths such as TMPDIR must
be established by the owning project. Candidate rc1 exposed this boundary issue
and was not published; rc2 retains a new immutable tag instead of moving rc1.

Packaged container chart checks render canonical CPU millicores and decimal MB
requests, including omission and absence of invented limits. Provider regressions
exercise the same mapping through activation and update.
+17 −5
Changes for ci/verify.py: 17 added lines, 5 removed lines.
Original line number Diff line number Diff line
@@ -182,13 +182,23 @@ def charts():
    chart = Path(openop_tfsdk.__file__).parent / "contract/adapters/charts/container"
    helm = helm_binary()
    image = "example.invalid/fixture@sha256:" + "a" * 64
    for name, service_type, ports in [
        ("none", "ClusterIP", []),
        ("internal", "ClusterIP", [{"name": "p80-tcp", "port": 80, "protocol": "TCP"}]),
        ("external", "NodePort", [{"name": "p80-tcp", "port": 80, "protocol": "TCP"}]),
    for name, service_type, ports, requests in [
        ("none", "ClusterIP", [], {}),
        ("internal", "ClusterIP", [{"name": "p80-tcp", "port": 80, "protocol": "TCP"}], {}),
        ("external", "NodePort", [{"name": "p80-tcp", "port": 80, "protocol": "TCP"}], {}),
        ("requests", "ClusterIP", [], {"cpu": "250m", "memory": "257M"}),
    ]:
        values = OUT / f"chart-{name}.json"
        write_json(values, {"image": image, "serviceType": service_type, "ports": ports})
        expected_resources = {"requests": requests} if requests else {}
        write_json(
            values,
            {
                "image": image,
                "serviceType": service_type,
                "ports": ports,
                "resources": expected_resources,
            },
        )
        run(helm, "lint", chart, "--strict", "-f", values)
        raw = subprocess.check_output(
            [
@@ -208,6 +218,8 @@ def charts():
        deployment = objects["Deployment"]
        spec = deployment["spec"]["template"]["spec"]["containers"][0]
        assert spec["image"] == image
        assert spec.get("resources", {}) == expected_resources
        assert "limits" not in spec.get("resources", {})
        assert spec.get("ports", []) == [
            {"name": p["name"], "containerPort": p["port"], "protocol": p["protocol"]}
            for p in ports
+1 −1
Changes for src/openop_tfsdk/_diagnostics.py: 1 added line, 1 removed line.
Original line number Diff line number Diff line
"""Small log-only summaries; never copy backend text, payloads or input values."""
"""Allowlisted diagnostic summaries; never copy backend text, payloads or input values."""

from typing import get_args

+4 −0
Changes for src/openop_tfsdk/contract/adapters/charts/container/templates/deployment.yaml: 4 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -25,3 +25,7 @@ spec:
              protocol: {{ .protocol }}
            {{- end }}
          {{- end }}
          {{- with .Values.resources }}
          resources:
            {{- toYaml . | nindent 12 }}
          {{- end }}
Loading