ctfy.sdk.admin_resources.instances

client.admin.instances — live cluster-wide instance fleet (admin).

 1"""``client.admin.instances`` — live cluster-wide instance fleet (admin)."""
 2
 3from __future__ import annotations
 4
 5import builtins
 6from typing import Any
 7
 8from ctfy.sdk._helpers import _extract_items, _raise_for_status
 9from ctfy.sdk.base import BaseHttpClient
10from ctfy.server.models import InstanceInfo
11
12
13class AdminInstancesResource:
14    """Every live instance cluster-wide, with forensic pcap / traffic reads.
15    Archived (terminal) records live on :class:`AdminRecordsResource`."""
16
17    def __init__(self, http: BaseHttpClient) -> None:
18        self._http = http
19
20    def stop_all(self) -> builtins.list[dict[str, Any]]:
21        """Cluster-wide tear-down: stop every running instance. Used for
22        maintenance windows. Returns one :class:`StopResponse` row per
23        instance that was stopped."""
24        resp = self._http.request("DELETE", "/instances")
25        _raise_for_status(resp)
26        rows: builtins.list[dict[str, Any]] = resp.json()
27        return rows
28
29    def list(
30        self,
31        *,
32        node_id: str = "",
33        status: str = "",
34        offset: int = 0,
35        limit: int = 50,
36    ) -> builtins.list[InstanceInfo]:
37        """Every live instance cluster-wide (no team-ownership filter)."""
38        params: dict[str, Any] = {"offset": offset, "limit": limit}
39        if node_id:
40            params["node_id"] = node_id
41        if status:
42            params["status"] = status
43        resp = self._http.request("GET", "/admin/instances", params=params)
44        _raise_for_status(resp)
45        return _extract_items(resp.json(), InstanceInfo)
46
47    def get(self, instance_id: str) -> InstanceInfo:
48        """Single live instance, admin view (any team's)."""
49        resp = self._http.request("GET", f"/admin/instances/{instance_id}")
50        _raise_for_status(resp)
51        return InstanceInfo.model_validate(resp.json())
52
53    def pcap(self, instance_id: str) -> bytes:
54        """Live tcpdump capture for a running instance. Returns empty
55        ``bytes`` when none exists (sidecar off, never ran) so callers
56        can persist conditionally without try/except."""
57        resp = self._http.request("GET", f"/admin/instances/{instance_id}/pcap")
58        if resp.status_code == 404:
59            return b""
60        _raise_for_status(resp)
61        return resp.content
62
63    def traffic(self, instance_id: str) -> dict[str, Any]:
64        """Live mitmproxy traffic for any running instance (admin twin
65        of :meth:`InstancesResource.traffic`, no ownership check)."""
66        resp = self._http.request("GET", f"/admin/instances/{instance_id}/traffic")
67        _raise_for_status(resp)
68        data = resp.json()
69        return data if isinstance(data, dict) else {}
class AdminInstancesResource:
14class AdminInstancesResource:
15    """Every live instance cluster-wide, with forensic pcap / traffic reads.
16    Archived (terminal) records live on :class:`AdminRecordsResource`."""
17
18    def __init__(self, http: BaseHttpClient) -> None:
19        self._http = http
20
21    def stop_all(self) -> builtins.list[dict[str, Any]]:
22        """Cluster-wide tear-down: stop every running instance. Used for
23        maintenance windows. Returns one :class:`StopResponse` row per
24        instance that was stopped."""
25        resp = self._http.request("DELETE", "/instances")
26        _raise_for_status(resp)
27        rows: builtins.list[dict[str, Any]] = resp.json()
28        return rows
29
30    def list(
31        self,
32        *,
33        node_id: str = "",
34        status: str = "",
35        offset: int = 0,
36        limit: int = 50,
37    ) -> builtins.list[InstanceInfo]:
38        """Every live instance cluster-wide (no team-ownership filter)."""
39        params: dict[str, Any] = {"offset": offset, "limit": limit}
40        if node_id:
41            params["node_id"] = node_id
42        if status:
43            params["status"] = status
44        resp = self._http.request("GET", "/admin/instances", params=params)
45        _raise_for_status(resp)
46        return _extract_items(resp.json(), InstanceInfo)
47
48    def get(self, instance_id: str) -> InstanceInfo:
49        """Single live instance, admin view (any team's)."""
50        resp = self._http.request("GET", f"/admin/instances/{instance_id}")
51        _raise_for_status(resp)
52        return InstanceInfo.model_validate(resp.json())
53
54    def pcap(self, instance_id: str) -> bytes:
55        """Live tcpdump capture for a running instance. Returns empty
56        ``bytes`` when none exists (sidecar off, never ran) so callers
57        can persist conditionally without try/except."""
58        resp = self._http.request("GET", f"/admin/instances/{instance_id}/pcap")
59        if resp.status_code == 404:
60            return b""
61        _raise_for_status(resp)
62        return resp.content
63
64    def traffic(self, instance_id: str) -> dict[str, Any]:
65        """Live mitmproxy traffic for any running instance (admin twin
66        of :meth:`InstancesResource.traffic`, no ownership check)."""
67        resp = self._http.request("GET", f"/admin/instances/{instance_id}/traffic")
68        _raise_for_status(resp)
69        data = resp.json()
70        return data if isinstance(data, dict) else {}

Every live instance cluster-wide, with forensic pcap / traffic reads. Archived (terminal) records live on AdminRecordsResource.

AdminInstancesResource(http: ctfy.sdk.base.BaseHttpClient)
18    def __init__(self, http: BaseHttpClient) -> None:
19        self._http = http
def stop_all(self) -> list[dict[str, typing.Any]]:
21    def stop_all(self) -> builtins.list[dict[str, Any]]:
22        """Cluster-wide tear-down: stop every running instance. Used for
23        maintenance windows. Returns one :class:`StopResponse` row per
24        instance that was stopped."""
25        resp = self._http.request("DELETE", "/instances")
26        _raise_for_status(resp)
27        rows: builtins.list[dict[str, Any]] = resp.json()
28        return rows

Cluster-wide tear-down: stop every running instance. Used for maintenance windows. Returns one StopResponse row per instance that was stopped.

def list( self, *, node_id: str = '', status: str = '', offset: int = 0, limit: int = 50) -> list[ctfy.server.models.InstanceInfo]:
30    def list(
31        self,
32        *,
33        node_id: str = "",
34        status: str = "",
35        offset: int = 0,
36        limit: int = 50,
37    ) -> builtins.list[InstanceInfo]:
38        """Every live instance cluster-wide (no team-ownership filter)."""
39        params: dict[str, Any] = {"offset": offset, "limit": limit}
40        if node_id:
41            params["node_id"] = node_id
42        if status:
43            params["status"] = status
44        resp = self._http.request("GET", "/admin/instances", params=params)
45        _raise_for_status(resp)
46        return _extract_items(resp.json(), InstanceInfo)

Every live instance cluster-wide (no team-ownership filter).

def get(self, instance_id: str) -> ctfy.server.models.InstanceInfo:
48    def get(self, instance_id: str) -> InstanceInfo:
49        """Single live instance, admin view (any team's)."""
50        resp = self._http.request("GET", f"/admin/instances/{instance_id}")
51        _raise_for_status(resp)
52        return InstanceInfo.model_validate(resp.json())

Single live instance, admin view (any team's).

def pcap(self, instance_id: str) -> bytes:
54    def pcap(self, instance_id: str) -> bytes:
55        """Live tcpdump capture for a running instance. Returns empty
56        ``bytes`` when none exists (sidecar off, never ran) so callers
57        can persist conditionally without try/except."""
58        resp = self._http.request("GET", f"/admin/instances/{instance_id}/pcap")
59        if resp.status_code == 404:
60            return b""
61        _raise_for_status(resp)
62        return resp.content

Live tcpdump capture for a running instance. Returns empty bytes when none exists (sidecar off, never ran) so callers can persist conditionally without try/except.

def traffic(self, instance_id: str) -> dict[str, typing.Any]:
64    def traffic(self, instance_id: str) -> dict[str, Any]:
65        """Live mitmproxy traffic for any running instance (admin twin
66        of :meth:`InstancesResource.traffic`, no ownership check)."""
67        resp = self._http.request("GET", f"/admin/instances/{instance_id}/traffic")
68        _raise_for_status(resp)
69        data = resp.json()
70        return data if isinstance(data, dict) else {}

Live mitmproxy traffic for any running instance (admin twin of InstancesResource.traffic(), no ownership check).