mantatech-sdk 0.5b0.dev65__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- manta/__init__.light.py +22 -0
- manta/__init__.py +83 -0
- manta/__main__.py +21 -0
- manta/apis/__init__.py +7 -0
- manta/apis/async_user_api.py +6458 -0
- manta/apis/graph.py +498 -0
- manta/apis/module.py +316 -0
- manta/apis/results.py +251 -0
- manta/apis/swarm.py +206 -0
- manta/apis/user_api.py +1016 -0
- manta/cli/__init__.py +1 -0
- manta/cli/commands/__init__.py +1 -0
- manta/cli/commands/base_handler.py +229 -0
- manta/cli/commands/doc.py +192 -0
- manta/cli/commands/install.py +346 -0
- manta/cli/commands/sdk.py +9 -0
- manta/cli/commands/sdk_cluster.py +211 -0
- manta/cli/commands/sdk_config.py +347 -0
- manta/cli/commands/sdk_globals.py +280 -0
- manta/cli/commands/sdk_logs.py +174 -0
- manta/cli/commands/sdk_main.py +167 -0
- manta/cli/commands/sdk_module.py +516 -0
- manta/cli/commands/sdk_nodes.py +168 -0
- manta/cli/commands/sdk_original.py +3873 -0
- manta/cli/commands/sdk_results.py +265 -0
- manta/cli/commands/sdk_swarm.py +454 -0
- manta/cli/commands/sdk_user.py +234 -0
- manta/cli/commands/status.py +292 -0
- manta/cli/component_detector.py +112 -0
- manta/cli/config_manager.py +445 -0
- manta/cli/main.py +265 -0
- manta/cli/utils/__init__.py +27 -0
- manta/cli/utils/converters.py +140 -0
- manta/clients/cluster_management_client.py +486 -0
- manta/clients/local_client.py +149 -0
- manta/clients/module_management_client.py +217 -0
- manta/clients/swarm_management_client.py +562 -0
- manta/clients/user_management_client.py +395 -0
- manta/clients/world_client.py +195 -0
- manta/light/__init__.py +31 -0
- manta/light/globals.py +245 -0
- manta/light/local.py +407 -0
- manta/light/logging_config.py +39 -0
- manta/light/path.py +116 -0
- manta/light/results.py +236 -0
- manta/light/task.py +100 -0
- manta/light/utils.py +217 -0
- manta/light/world.py +177 -0
- mantatech_sdk-0.5b0.dev65.dist-info/METADATA +1039 -0
- mantatech_sdk-0.5b0.dev65.dist-info/RECORD +54 -0
- mantatech_sdk-0.5b0.dev65.dist-info/WHEEL +5 -0
- mantatech_sdk-0.5b0.dev65.dist-info/entry_points.txt +2 -0
- mantatech_sdk-0.5b0.dev65.dist-info/licenses/LICENSE +683 -0
- mantatech_sdk-0.5b0.dev65.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""CLI utility functions and helpers."""
|
|
2
|
+
|
|
3
|
+
from .converters import (
|
|
4
|
+
enum_to_string,
|
|
5
|
+
timestamp_to_string,
|
|
6
|
+
bytes_to_gb,
|
|
7
|
+
extract_platform_type,
|
|
8
|
+
extract_node_resources,
|
|
9
|
+
NODE_STATUS_MAP,
|
|
10
|
+
SWARM_STATUS_MAP,
|
|
11
|
+
CLUSTER_STATUS_MAP,
|
|
12
|
+
TASK_STATUS_MAP,
|
|
13
|
+
LOG_SEVERITY_MAP,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"enum_to_string",
|
|
18
|
+
"timestamp_to_string",
|
|
19
|
+
"bytes_to_gb",
|
|
20
|
+
"extract_platform_type",
|
|
21
|
+
"extract_node_resources",
|
|
22
|
+
"NODE_STATUS_MAP",
|
|
23
|
+
"SWARM_STATUS_MAP",
|
|
24
|
+
"CLUSTER_STATUS_MAP",
|
|
25
|
+
"TASK_STATUS_MAP",
|
|
26
|
+
"LOG_SEVERITY_MAP",
|
|
27
|
+
]
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"""Utility functions for CLI data conversion and formatting."""
|
|
2
|
+
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from typing import Any, Dict, Optional, Union
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def enum_to_string(value: Union[int, str], enum_map: Dict[int, str]) -> str:
|
|
8
|
+
"""Convert enum value to string representation.
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
value: Enum value (int) or string
|
|
12
|
+
enum_map: Dictionary mapping enum int values to string names
|
|
13
|
+
|
|
14
|
+
Returns:
|
|
15
|
+
String representation of the enum value
|
|
16
|
+
"""
|
|
17
|
+
if isinstance(value, int):
|
|
18
|
+
return enum_map.get(value, "UNKNOWN")
|
|
19
|
+
return str(value)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def timestamp_to_string(
|
|
23
|
+
timestamp: Union[Dict[str, Any], str, int, float, None],
|
|
24
|
+
format: str = "%Y-%m-%d %H:%M:%S",
|
|
25
|
+
) -> str:
|
|
26
|
+
"""Convert various timestamp formats to string.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
timestamp: Timestamp in various formats (dict with seconds, string, int/float, or None)
|
|
30
|
+
format: Output format string
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
Formatted timestamp string or 'Unknown' if invalid
|
|
34
|
+
"""
|
|
35
|
+
if not timestamp:
|
|
36
|
+
return "Unknown"
|
|
37
|
+
|
|
38
|
+
if isinstance(timestamp, dict):
|
|
39
|
+
if "seconds" in timestamp:
|
|
40
|
+
return datetime.fromtimestamp(timestamp["seconds"]).strftime(format)
|
|
41
|
+
elif isinstance(timestamp, str):
|
|
42
|
+
return timestamp
|
|
43
|
+
elif isinstance(timestamp, (int, float)):
|
|
44
|
+
return datetime.fromtimestamp(timestamp).strftime(format)
|
|
45
|
+
|
|
46
|
+
return "Unknown"
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def bytes_to_gb(bytes_value: Union[int, float, None]) -> float:
|
|
50
|
+
"""Convert bytes to gigabytes.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
bytes_value: Value in bytes
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
Value in GB rounded to 2 decimal places
|
|
57
|
+
"""
|
|
58
|
+
if bytes_value is None:
|
|
59
|
+
return 0.0
|
|
60
|
+
return round(bytes_value / (1024**3), 2)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def extract_platform_type(platform_info: Optional[Dict[str, Any]]) -> str:
|
|
64
|
+
"""Extract platform type from platform_info structure.
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
platform_info: Platform information dictionary
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
Platform/OS type string
|
|
71
|
+
"""
|
|
72
|
+
if not platform_info:
|
|
73
|
+
return "Unknown"
|
|
74
|
+
|
|
75
|
+
# Try different possible field names
|
|
76
|
+
for field in ["system", "platform", "os"]:
|
|
77
|
+
if field in platform_info:
|
|
78
|
+
return platform_info[field]
|
|
79
|
+
|
|
80
|
+
return "Unknown"
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def extract_node_resources(
|
|
84
|
+
metrics_snapshot: Optional[Dict[str, Any]],
|
|
85
|
+
) -> Dict[str, Any]:
|
|
86
|
+
"""Extract resource information from metrics snapshot.
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
metrics_snapshot: Metrics snapshot dictionary
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
Dictionary with cpu_count and memory_gb
|
|
93
|
+
"""
|
|
94
|
+
resources = {"cpu_count": "Unknown", "memory_gb": "Unknown"}
|
|
95
|
+
|
|
96
|
+
if not metrics_snapshot:
|
|
97
|
+
return resources
|
|
98
|
+
|
|
99
|
+
# Extract CPU info
|
|
100
|
+
if "cpu" in metrics_snapshot and metrics_snapshot["cpu"]:
|
|
101
|
+
cpu_info = metrics_snapshot["cpu"]
|
|
102
|
+
if "count" in cpu_info:
|
|
103
|
+
resources["cpu_count"] = cpu_info["count"]
|
|
104
|
+
elif "cores" in cpu_info:
|
|
105
|
+
resources["cpu_count"] = cpu_info["cores"]
|
|
106
|
+
|
|
107
|
+
# Extract memory info
|
|
108
|
+
if "memory" in metrics_snapshot and metrics_snapshot["memory"]:
|
|
109
|
+
memory_info = metrics_snapshot["memory"]
|
|
110
|
+
if "total_bytes" in memory_info:
|
|
111
|
+
resources["memory_gb"] = bytes_to_gb(memory_info["total_bytes"])
|
|
112
|
+
elif "total" in memory_info:
|
|
113
|
+
resources["memory_gb"] = bytes_to_gb(memory_info["total"])
|
|
114
|
+
|
|
115
|
+
return resources
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
# Enum mappings for various status fields
|
|
119
|
+
NODE_STATUS_MAP = {0: "UNKNOWN", 1: "CONNECTED", 2: "DISCONNECTED"}
|
|
120
|
+
|
|
121
|
+
SWARM_STATUS_MAP = {
|
|
122
|
+
0: "PENDING",
|
|
123
|
+
1: "ACTIVE",
|
|
124
|
+
2: "PAUSED",
|
|
125
|
+
3: "STOPPED",
|
|
126
|
+
4: "COMPLETED",
|
|
127
|
+
5: "FAILED",
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
CLUSTER_STATUS_MAP = {0: "CREATED", 1: "RUNNING", 2: "STOPPED", 3: "ERROR"}
|
|
131
|
+
|
|
132
|
+
TASK_STATUS_MAP = {
|
|
133
|
+
0: "PENDING",
|
|
134
|
+
1: "RUNNING",
|
|
135
|
+
2: "COMPLETED",
|
|
136
|
+
3: "FAILED",
|
|
137
|
+
4: "CANCELLED",
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
LOG_SEVERITY_MAP = {0: "DEBUG", 1: "INFO", 2: "WARNING", 3: "ERROR", 4: "CRITICAL"}
|
|
@@ -0,0 +1,486 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Cluster Management Client implementation.
|
|
3
|
+
|
|
4
|
+
This module provides the ClusterManagementClient class for interacting with the ClusterManagement service.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from datetime import datetime
|
|
10
|
+
from logging import Logger
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import Any, AsyncIterator, Dict, Optional, Type, TypeVar
|
|
13
|
+
|
|
14
|
+
from manta_common.base_client import GrpcClientBase, MetadataDict
|
|
15
|
+
from manta_common.build.common.cluster import Cluster
|
|
16
|
+
from manta_common.build.common.informations import MetricsSnapshot, Node
|
|
17
|
+
from manta_common.build.common.system import (
|
|
18
|
+
CollectionIds,
|
|
19
|
+
Empty,
|
|
20
|
+
Error,
|
|
21
|
+
Response,
|
|
22
|
+
StrId,
|
|
23
|
+
)
|
|
24
|
+
from manta_common.build.core.user_services import ( # Request/Response messages; Service stub
|
|
25
|
+
ClusterManagementStub,
|
|
26
|
+
CreateClusterRequest,
|
|
27
|
+
ErrorsRequest,
|
|
28
|
+
NodeRequest,
|
|
29
|
+
TaskResponse,
|
|
30
|
+
)
|
|
31
|
+
from manta_common.retry import RetryPolicy
|
|
32
|
+
|
|
33
|
+
T = TypeVar("T")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class ClusterManagementClient(GrpcClientBase):
|
|
37
|
+
"""
|
|
38
|
+
Client for interacting with the ClusterManagement Service.
|
|
39
|
+
|
|
40
|
+
This client provides a high-level interface for making gRPC calls to the ClusterManagement service,
|
|
41
|
+
handling cluster lifecycle and node management operations.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
__slots__ = ("_secure", "cafile", "certfile", "keyfile")
|
|
45
|
+
|
|
46
|
+
def __init__(
|
|
47
|
+
self,
|
|
48
|
+
host: str,
|
|
49
|
+
port: int,
|
|
50
|
+
jwt_token: str,
|
|
51
|
+
secure: bool = False,
|
|
52
|
+
cafile: Optional[str] = None,
|
|
53
|
+
certfile: Optional[str] = None,
|
|
54
|
+
keyfile: Optional[str] = None,
|
|
55
|
+
channel_options: Optional[Dict[str, Any]] = None,
|
|
56
|
+
logger: Optional[Logger] = None,
|
|
57
|
+
retry_policy: Optional[RetryPolicy] = None,
|
|
58
|
+
streaming_retry_policy: Optional[RetryPolicy] = None,
|
|
59
|
+
):
|
|
60
|
+
"""
|
|
61
|
+
Initialize the ClusterManagementClient.
|
|
62
|
+
|
|
63
|
+
Parameters
|
|
64
|
+
----------
|
|
65
|
+
host : str
|
|
66
|
+
The host of the ClusterManagement service
|
|
67
|
+
port : int
|
|
68
|
+
The port of the ClusterManagement service
|
|
69
|
+
jwt_token : str
|
|
70
|
+
JWT token for authentication
|
|
71
|
+
secure : bool
|
|
72
|
+
Whether to use a secure connection
|
|
73
|
+
cafile : Optional[str]
|
|
74
|
+
Path to the CA certificate file for verifying the server
|
|
75
|
+
certfile : Optional[str]
|
|
76
|
+
Path to the client certificate file
|
|
77
|
+
keyfile : Optional[str]
|
|
78
|
+
Path to the client private key file
|
|
79
|
+
channel_options : Optional[Dict[str, Any]]
|
|
80
|
+
The channel options
|
|
81
|
+
logger : Optional[Logger]
|
|
82
|
+
The logger
|
|
83
|
+
retry_policy : Optional[RetryPolicy]
|
|
84
|
+
The retry policy
|
|
85
|
+
streaming_retry_policy : Optional[RetryPolicy]
|
|
86
|
+
The streaming retry policy
|
|
87
|
+
"""
|
|
88
|
+
super().__init__(
|
|
89
|
+
host=host,
|
|
90
|
+
port=port,
|
|
91
|
+
secure=secure,
|
|
92
|
+
channel_options=channel_options,
|
|
93
|
+
tracer=logger,
|
|
94
|
+
retry_policy=retry_policy,
|
|
95
|
+
streaming_retry_policy=streaming_retry_policy,
|
|
96
|
+
)
|
|
97
|
+
self.jwt_token = jwt_token
|
|
98
|
+
self._secure = secure
|
|
99
|
+
self.cafile = Path(cafile) if cafile is not None else None
|
|
100
|
+
self.certfile = Path(certfile) if certfile is not None else None
|
|
101
|
+
self.keyfile = Path(keyfile) if keyfile is not None else None
|
|
102
|
+
|
|
103
|
+
def _get_stub_class(self) -> Type[ClusterManagementStub]:
|
|
104
|
+
"""Get the stub class for the ClusterManagement service."""
|
|
105
|
+
return ClusterManagementStub
|
|
106
|
+
|
|
107
|
+
@property
|
|
108
|
+
def metadata(self) -> MetadataDict:
|
|
109
|
+
return {"authorization": self.jwt_token}
|
|
110
|
+
|
|
111
|
+
async def is_available(self) -> Response:
|
|
112
|
+
"""
|
|
113
|
+
Check if the ClusterManagement service is available.
|
|
114
|
+
|
|
115
|
+
Returns
|
|
116
|
+
-------
|
|
117
|
+
Response
|
|
118
|
+
Service availability status
|
|
119
|
+
"""
|
|
120
|
+
return await self.call_service_method(
|
|
121
|
+
"is_available",
|
|
122
|
+
Empty(),
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
async def create_cluster(self, name: Optional[str] = None) -> StrId:
|
|
126
|
+
"""
|
|
127
|
+
Create a new cluster.
|
|
128
|
+
|
|
129
|
+
Parameters
|
|
130
|
+
----------
|
|
131
|
+
name : Optional[str]
|
|
132
|
+
Name for the cluster
|
|
133
|
+
|
|
134
|
+
Returns
|
|
135
|
+
-------
|
|
136
|
+
StrId
|
|
137
|
+
Cluster ID
|
|
138
|
+
"""
|
|
139
|
+
request = CreateClusterRequest()
|
|
140
|
+
if name:
|
|
141
|
+
request.name = name
|
|
142
|
+
return await self.call_service_method(
|
|
143
|
+
"create_cluster",
|
|
144
|
+
request,
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
async def start_cluster(self, cluster_id: str) -> Cluster:
|
|
148
|
+
"""
|
|
149
|
+
Start cluster services.
|
|
150
|
+
|
|
151
|
+
Parameters
|
|
152
|
+
----------
|
|
153
|
+
cluster_id : str
|
|
154
|
+
ID of the cluster to start
|
|
155
|
+
|
|
156
|
+
Returns
|
|
157
|
+
-------
|
|
158
|
+
Cluster
|
|
159
|
+
Cluster details
|
|
160
|
+
"""
|
|
161
|
+
return await self.call_service_method(
|
|
162
|
+
"start_cluster",
|
|
163
|
+
StrId(id=cluster_id),
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
async def stop_cluster(self, cluster_id: str) -> Response:
|
|
167
|
+
"""
|
|
168
|
+
Stop cluster services.
|
|
169
|
+
|
|
170
|
+
Parameters
|
|
171
|
+
----------
|
|
172
|
+
cluster_id : str
|
|
173
|
+
ID of the cluster to stop
|
|
174
|
+
|
|
175
|
+
Returns
|
|
176
|
+
-------
|
|
177
|
+
Response
|
|
178
|
+
Stop operation response
|
|
179
|
+
"""
|
|
180
|
+
return await self.call_service_method(
|
|
181
|
+
"stop_cluster",
|
|
182
|
+
StrId(id=cluster_id),
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
async def delete_cluster(self, cluster_id: str) -> Response:
|
|
186
|
+
"""
|
|
187
|
+
Delete a cluster.
|
|
188
|
+
|
|
189
|
+
Parameters
|
|
190
|
+
----------
|
|
191
|
+
cluster_id : str
|
|
192
|
+
ID of the cluster to delete
|
|
193
|
+
|
|
194
|
+
Returns
|
|
195
|
+
-------
|
|
196
|
+
Response
|
|
197
|
+
Deletion confirmation response
|
|
198
|
+
"""
|
|
199
|
+
return await self.call_service_method(
|
|
200
|
+
"delete_cluster",
|
|
201
|
+
StrId(id=cluster_id),
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
async def list_cluster_ids(self) -> CollectionIds:
|
|
205
|
+
"""
|
|
206
|
+
List all cluster IDs for the authenticated user.
|
|
207
|
+
|
|
208
|
+
Returns
|
|
209
|
+
-------
|
|
210
|
+
CollectionIds
|
|
211
|
+
Collection of cluster IDs
|
|
212
|
+
"""
|
|
213
|
+
return await self.call_service_method(
|
|
214
|
+
"list_cluster_ids",
|
|
215
|
+
Empty(),
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
async def stream_clusters(self) -> AsyncIterator[Cluster]:
|
|
219
|
+
"""
|
|
220
|
+
Stream all clusters for the authenticated user.
|
|
221
|
+
|
|
222
|
+
Yields
|
|
223
|
+
------
|
|
224
|
+
Cluster
|
|
225
|
+
Cluster details
|
|
226
|
+
"""
|
|
227
|
+
async for cluster in self.stream_service_method(
|
|
228
|
+
"stream_clusters",
|
|
229
|
+
Empty(),
|
|
230
|
+
):
|
|
231
|
+
yield cluster
|
|
232
|
+
|
|
233
|
+
async def get_cluster(self, cluster_id: str) -> Cluster:
|
|
234
|
+
"""
|
|
235
|
+
Get a cluster by its ID.
|
|
236
|
+
|
|
237
|
+
Parameters
|
|
238
|
+
----------
|
|
239
|
+
cluster_id : str
|
|
240
|
+
ID of the cluster
|
|
241
|
+
|
|
242
|
+
Returns
|
|
243
|
+
-------
|
|
244
|
+
Cluster
|
|
245
|
+
Cluster details
|
|
246
|
+
"""
|
|
247
|
+
return await self.call_service_method(
|
|
248
|
+
"get_cluster",
|
|
249
|
+
StrId(id=cluster_id),
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
async def list_node_ids(self, cluster_id: str) -> CollectionIds:
|
|
253
|
+
"""
|
|
254
|
+
List node IDs in a cluster.
|
|
255
|
+
|
|
256
|
+
Parameters
|
|
257
|
+
----------
|
|
258
|
+
cluster_id : str
|
|
259
|
+
ID of the cluster
|
|
260
|
+
|
|
261
|
+
Returns
|
|
262
|
+
-------
|
|
263
|
+
CollectionIds
|
|
264
|
+
Collection of node IDs
|
|
265
|
+
"""
|
|
266
|
+
return await self.call_service_method(
|
|
267
|
+
"list_node_ids",
|
|
268
|
+
StrId(id=cluster_id),
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
async def stream_nodes(self, cluster_id: str) -> AsyncIterator[Node]:
|
|
272
|
+
"""
|
|
273
|
+
Stream all nodes in a cluster.
|
|
274
|
+
|
|
275
|
+
Parameters
|
|
276
|
+
----------
|
|
277
|
+
cluster_id : str
|
|
278
|
+
ID of the cluster
|
|
279
|
+
|
|
280
|
+
Yields
|
|
281
|
+
------
|
|
282
|
+
Node
|
|
283
|
+
Node information
|
|
284
|
+
"""
|
|
285
|
+
async for node in self.stream_service_method(
|
|
286
|
+
"stream_nodes",
|
|
287
|
+
StrId(id=cluster_id),
|
|
288
|
+
):
|
|
289
|
+
yield node
|
|
290
|
+
|
|
291
|
+
async def stop_node(self, cluster_id: str, node_id: str) -> Response:
|
|
292
|
+
"""
|
|
293
|
+
Stop a specific node.
|
|
294
|
+
|
|
295
|
+
Parameters
|
|
296
|
+
----------
|
|
297
|
+
cluster_id : str
|
|
298
|
+
ID of the cluster
|
|
299
|
+
node_id : str
|
|
300
|
+
ID of the node to stop
|
|
301
|
+
|
|
302
|
+
Returns
|
|
303
|
+
-------
|
|
304
|
+
Response
|
|
305
|
+
Stop operation response
|
|
306
|
+
"""
|
|
307
|
+
return await self.call_service_method(
|
|
308
|
+
"stop_node",
|
|
309
|
+
NodeRequest(cluster_id=cluster_id, node_id=node_id),
|
|
310
|
+
)
|
|
311
|
+
|
|
312
|
+
async def remove_node(self, cluster_id: str, node_id: str) -> Response:
|
|
313
|
+
"""
|
|
314
|
+
Remove a node from the cluster.
|
|
315
|
+
|
|
316
|
+
Parameters
|
|
317
|
+
----------
|
|
318
|
+
cluster_id : str
|
|
319
|
+
ID of the cluster
|
|
320
|
+
node_id : str
|
|
321
|
+
ID of the node to remove
|
|
322
|
+
|
|
323
|
+
Returns
|
|
324
|
+
-------
|
|
325
|
+
Response
|
|
326
|
+
Removal confirmation response
|
|
327
|
+
"""
|
|
328
|
+
return await self.call_service_method(
|
|
329
|
+
"remove_node",
|
|
330
|
+
NodeRequest(cluster_id=cluster_id, node_id=node_id),
|
|
331
|
+
)
|
|
332
|
+
|
|
333
|
+
async def get_node(self, cluster_id: str, node_id: str) -> Node:
|
|
334
|
+
"""
|
|
335
|
+
Get a node by its ID.
|
|
336
|
+
|
|
337
|
+
Parameters
|
|
338
|
+
----------
|
|
339
|
+
cluster_id : str
|
|
340
|
+
ID of the cluster
|
|
341
|
+
node_id : str
|
|
342
|
+
ID of the node
|
|
343
|
+
|
|
344
|
+
Returns
|
|
345
|
+
-------
|
|
346
|
+
Node
|
|
347
|
+
Node information
|
|
348
|
+
"""
|
|
349
|
+
return await self.call_service_method(
|
|
350
|
+
"get_node",
|
|
351
|
+
NodeRequest(cluster_id=cluster_id, node_id=node_id),
|
|
352
|
+
)
|
|
353
|
+
|
|
354
|
+
async def get_node_resources(
|
|
355
|
+
self, cluster_id: str, node_id: str
|
|
356
|
+
) -> MetricsSnapshot:
|
|
357
|
+
"""
|
|
358
|
+
Get node resources for a specific node.
|
|
359
|
+
|
|
360
|
+
Parameters
|
|
361
|
+
----------
|
|
362
|
+
cluster_id : str
|
|
363
|
+
ID of the cluster
|
|
364
|
+
node_id : str
|
|
365
|
+
ID of the node
|
|
366
|
+
|
|
367
|
+
Returns
|
|
368
|
+
-------
|
|
369
|
+
MetricsSnapshot
|
|
370
|
+
Node resource metrics
|
|
371
|
+
"""
|
|
372
|
+
return await self.call_service_method(
|
|
373
|
+
"get_node_resources",
|
|
374
|
+
NodeRequest(cluster_id=cluster_id, node_id=node_id),
|
|
375
|
+
)
|
|
376
|
+
|
|
377
|
+
async def stream_node_resources(
|
|
378
|
+
self, cluster_id: str, node_id: str
|
|
379
|
+
) -> AsyncIterator[MetricsSnapshot]:
|
|
380
|
+
"""
|
|
381
|
+
Stream node resources for a specific node.
|
|
382
|
+
|
|
383
|
+
Parameters
|
|
384
|
+
----------
|
|
385
|
+
cluster_id : str
|
|
386
|
+
ID of the cluster
|
|
387
|
+
node_id : str
|
|
388
|
+
ID of the node
|
|
389
|
+
|
|
390
|
+
Yields
|
|
391
|
+
------
|
|
392
|
+
MetricsSnapshot
|
|
393
|
+
Stream of node resource metrics
|
|
394
|
+
"""
|
|
395
|
+
async for resource in self.stream_service_method(
|
|
396
|
+
"stream_node_resources",
|
|
397
|
+
NodeRequest(cluster_id=cluster_id, node_id=node_id),
|
|
398
|
+
):
|
|
399
|
+
yield resource
|
|
400
|
+
|
|
401
|
+
async def list_available_node_ids(self, cluster_id: str) -> CollectionIds:
|
|
402
|
+
"""
|
|
403
|
+
List available node IDs in a cluster.
|
|
404
|
+
|
|
405
|
+
Parameters
|
|
406
|
+
----------
|
|
407
|
+
cluster_id : str
|
|
408
|
+
ID of the cluster
|
|
409
|
+
|
|
410
|
+
Returns
|
|
411
|
+
-------
|
|
412
|
+
CollectionIds
|
|
413
|
+
Collection of available node IDs
|
|
414
|
+
"""
|
|
415
|
+
return await self.call_service_method(
|
|
416
|
+
"list_available_node_ids",
|
|
417
|
+
StrId(id=cluster_id),
|
|
418
|
+
)
|
|
419
|
+
|
|
420
|
+
async def collect_errors(
|
|
421
|
+
self,
|
|
422
|
+
cluster_id: str,
|
|
423
|
+
start_time: Optional[datetime] = None,
|
|
424
|
+
end_time: Optional[datetime] = None,
|
|
425
|
+
limit: Optional[int] = None,
|
|
426
|
+
sort_order: Optional[str] = None,
|
|
427
|
+
) -> AsyncIterator[Error]:
|
|
428
|
+
"""
|
|
429
|
+
Collect errors from a cluster.
|
|
430
|
+
|
|
431
|
+
Parameters
|
|
432
|
+
----------
|
|
433
|
+
cluster_id : str
|
|
434
|
+
ID of the cluster
|
|
435
|
+
start_time : Optional[datetime]
|
|
436
|
+
Start time for filtering errors
|
|
437
|
+
end_time : Optional[datetime]
|
|
438
|
+
End time for filtering errors
|
|
439
|
+
limit : Optional[int]
|
|
440
|
+
Maximum number of errors to return
|
|
441
|
+
sort_order : Optional[str]
|
|
442
|
+
Sort order for results
|
|
443
|
+
|
|
444
|
+
Yields
|
|
445
|
+
------
|
|
446
|
+
Error
|
|
447
|
+
Stream of errors
|
|
448
|
+
"""
|
|
449
|
+
request = ErrorsRequest(cluster_id=cluster_id)
|
|
450
|
+
if start_time:
|
|
451
|
+
request.start_time = start_time
|
|
452
|
+
if end_time:
|
|
453
|
+
request.end_time = end_time
|
|
454
|
+
if limit:
|
|
455
|
+
request.limit = limit
|
|
456
|
+
if sort_order:
|
|
457
|
+
request.sort_order = sort_order
|
|
458
|
+
async for error in self.stream_service_method(
|
|
459
|
+
"collect_errors",
|
|
460
|
+
request,
|
|
461
|
+
):
|
|
462
|
+
yield error
|
|
463
|
+
|
|
464
|
+
async def select_tasks(
|
|
465
|
+
self, cluster_id: str, node_id: str
|
|
466
|
+
) -> AsyncIterator[TaskResponse]:
|
|
467
|
+
"""
|
|
468
|
+
Select tasks for a specific node.
|
|
469
|
+
|
|
470
|
+
Parameters
|
|
471
|
+
----------
|
|
472
|
+
cluster_id : str
|
|
473
|
+
ID of the cluster
|
|
474
|
+
node_id : str
|
|
475
|
+
ID of the node
|
|
476
|
+
|
|
477
|
+
Yields
|
|
478
|
+
------
|
|
479
|
+
TaskResponse
|
|
480
|
+
Stream of task information
|
|
481
|
+
"""
|
|
482
|
+
async for task in self.stream_service_method(
|
|
483
|
+
"select_tasks",
|
|
484
|
+
NodeRequest(cluster_id=cluster_id, node_id=node_id),
|
|
485
|
+
):
|
|
486
|
+
yield task
|