sagemaker-hyperpod 3.0.0__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.
- sagemaker/__init__.py +0 -0
- sagemaker/hyperpod/__init__.py +2 -0
- sagemaker/hyperpod/cli/__init__.py +0 -0
- sagemaker/hyperpod/cli/clients/__init__.py +12 -0
- sagemaker/hyperpod/cli/clients/kubernetes_client.py +365 -0
- sagemaker/hyperpod/cli/commands/__init__.py +0 -0
- sagemaker/hyperpod/cli/commands/cluster.py +627 -0
- sagemaker/hyperpod/cli/commands/inference.py +659 -0
- sagemaker/hyperpod/cli/commands/training.py +347 -0
- sagemaker/hyperpod/cli/constants/__init__.py +0 -0
- sagemaker/hyperpod/cli/constants/command_constants.py +105 -0
- sagemaker/hyperpod/cli/constants/exception_constants.py +13 -0
- sagemaker/hyperpod/cli/constants/hyperpod_instance_types.py +100 -0
- sagemaker/hyperpod/cli/constants/kueue_constants.py +17 -0
- sagemaker/hyperpod/cli/constants/pytorch_constants.py +15 -0
- sagemaker/hyperpod/cli/hyp_cli.py +132 -0
- sagemaker/hyperpod/cli/inference_utils.py +121 -0
- sagemaker/hyperpod/cli/service/__init__.py +12 -0
- sagemaker/hyperpod/cli/service/cancel_training_job.py +70 -0
- sagemaker/hyperpod/cli/service/discover_namespaces.py +108 -0
- sagemaker/hyperpod/cli/service/exec_command.py +75 -0
- sagemaker/hyperpod/cli/service/get_logs.py +136 -0
- sagemaker/hyperpod/cli/service/get_namespaces.py +59 -0
- sagemaker/hyperpod/cli/service/get_training_job.py +110 -0
- sagemaker/hyperpod/cli/service/list_pods.py +138 -0
- sagemaker/hyperpod/cli/service/list_training_jobs.py +178 -0
- sagemaker/hyperpod/cli/service/self_subject_access_review.py +47 -0
- sagemaker/hyperpod/cli/telemetry/__init__.py +12 -0
- sagemaker/hyperpod/cli/telemetry/user_agent.py +36 -0
- sagemaker/hyperpod/cli/templates/__init__.py +12 -0
- sagemaker/hyperpod/cli/templates/k8s_pytorch_job_template.py +74 -0
- sagemaker/hyperpod/cli/training_utils.py +200 -0
- sagemaker/hyperpod/cli/utils.py +183 -0
- sagemaker/hyperpod/cli/validators/__init__.py +12 -0
- sagemaker/hyperpod/cli/validators/cluster_validator.py +52 -0
- sagemaker/hyperpod/cli/validators/job_validator.py +346 -0
- sagemaker/hyperpod/cli/validators/validator.py +75 -0
- sagemaker/hyperpod/common/__init__.py +0 -0
- sagemaker/hyperpod/common/config/__init__.py +1 -0
- sagemaker/hyperpod/common/config/metadata.py +18 -0
- sagemaker/hyperpod/common/utils.py +299 -0
- sagemaker/hyperpod/inference/__init__.py +11 -0
- sagemaker/hyperpod/inference/config/__init__.py +0 -0
- sagemaker/hyperpod/inference/config/constants.py +18 -0
- sagemaker/hyperpod/inference/config/hp_endpoint_config.py +767 -0
- sagemaker/hyperpod/inference/config/hp_jumpstart_endpoint_config.py +572 -0
- sagemaker/hyperpod/inference/hp_endpoint.py +203 -0
- sagemaker/hyperpod/inference/hp_endpoint_base.py +223 -0
- sagemaker/hyperpod/inference/hp_jumpstart_endpoint.py +232 -0
- sagemaker/hyperpod/observability/MonitoringConfig.py +10 -0
- sagemaker/hyperpod/observability/__init__.py +0 -0
- sagemaker/hyperpod/observability/constants.py +2 -0
- sagemaker/hyperpod/observability/utils.py +64 -0
- sagemaker/hyperpod/training/__init__.py +9 -0
- sagemaker/hyperpod/training/config/__init__.py +1 -0
- sagemaker/hyperpod/training/config/hyperpod_pytorch_job_config.py +2977 -0
- sagemaker/hyperpod/training/config/hyperpod_pytorch_job_status.py +3083 -0
- sagemaker/hyperpod/training/hyperpod_pytorch_job.py +253 -0
- sagemaker_hyperpod-3.0.0.dist-info/METADATA +534 -0
- sagemaker_hyperpod-3.0.0.dist-info/RECORD +66 -0
- sagemaker_hyperpod-3.0.0.dist-info/WHEEL +5 -0
- sagemaker_hyperpod-3.0.0.dist-info/entry_points.txt +2 -0
- sagemaker_hyperpod-3.0.0.dist-info/licenses/LICENSE +175 -0
- sagemaker_hyperpod-3.0.0.dist-info/licenses/NOTICE +1 -0
- sagemaker_hyperpod-3.0.0.dist-info/top_level.txt +1 -0
- sagemaker_hyperpod-3.0.0.dist-info/zip-safe +1 -0
sagemaker/__init__.py
ADDED
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
|
4
|
+
# may not use this file except in compliance with the License. A copy of
|
|
5
|
+
# the License is located at
|
|
6
|
+
#
|
|
7
|
+
# http://aws.amazon.com/apache2.0/
|
|
8
|
+
#
|
|
9
|
+
# or in the "license" file accompanying this file. This file is
|
|
10
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
|
11
|
+
# ANY KIND, either express or implied. See the License for the specific
|
|
12
|
+
# language governing permissions and limitations under the License.
|
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
|
4
|
+
# may not use this file except in compliance with the License. A copy of
|
|
5
|
+
# the License is located at
|
|
6
|
+
#
|
|
7
|
+
# http://aws.amazon.com/apache2.0/
|
|
8
|
+
#
|
|
9
|
+
# or in the "license" file accompanying this file. This file is
|
|
10
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
|
11
|
+
# ANY KIND, either express or implied. See the License for the specific
|
|
12
|
+
# language governing permissions and limitations under the License.
|
|
13
|
+
import os
|
|
14
|
+
from typing import List, Optional
|
|
15
|
+
|
|
16
|
+
import yaml
|
|
17
|
+
from kubernetes import client, config, stream
|
|
18
|
+
from kubernetes.client import (
|
|
19
|
+
V1Namespace,
|
|
20
|
+
V1NamespaceList,
|
|
21
|
+
)
|
|
22
|
+
from kubernetes.config import (
|
|
23
|
+
KUBE_CONFIG_DEFAULT_LOCATION,
|
|
24
|
+
)
|
|
25
|
+
from kubernetes.client.rest import ApiException
|
|
26
|
+
from sagemaker.hyperpod.cli.constants.command_constants import (
|
|
27
|
+
SAGEMAKER_MANAGED_QUEUE_LABEL,
|
|
28
|
+
TEMP_KUBE_CONFIG_FILE,
|
|
29
|
+
)
|
|
30
|
+
from sagemaker.hyperpod.cli.constants.exception_constants import RESOURCE_NOT_FOUND_CODE
|
|
31
|
+
from sagemaker.hyperpod.cli.constants.kueue_constants import (
|
|
32
|
+
CLUSTER_QUEUE_PRIORITY_CLASS_CUSTOM_OBJECT_PLURAL,
|
|
33
|
+
KUEUE_CUSTOM_OBJECT_GROUP,
|
|
34
|
+
KUEUE_CUSTOM_OBJECT_VERSION,
|
|
35
|
+
WORKLOAD_CUSTOM_OBJECT_PLURAL,
|
|
36
|
+
WORKLOAD_PRIORITY_CLASS_CUSTOM_OBJECT_PLURAL,
|
|
37
|
+
)
|
|
38
|
+
from sagemaker.hyperpod.cli.constants.pytorch_constants import (
|
|
39
|
+
PYTORCH_CUSTOM_OBJECT_GROUP,
|
|
40
|
+
PYTORCH_CUSTOM_OBJECT_PLURAL,
|
|
41
|
+
PYTORCH_CUSTOM_OBJECT_VERSION,
|
|
42
|
+
)
|
|
43
|
+
from sagemaker.hyperpod.cli.utils import setup_logger
|
|
44
|
+
|
|
45
|
+
logger = setup_logger(__name__)
|
|
46
|
+
|
|
47
|
+
KUBE_CONFIG_PATH = os.path.expanduser(KUBE_CONFIG_DEFAULT_LOCATION)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class KubernetesClient:
|
|
51
|
+
_instance = None
|
|
52
|
+
_kube_client = None
|
|
53
|
+
|
|
54
|
+
def __new__(cls, is_get_capacity: bool = False) -> "KubernetesClient":
|
|
55
|
+
if cls._instance is None:
|
|
56
|
+
cls._instance = super(KubernetesClient, cls).__new__(cls)
|
|
57
|
+
config.load_kube_config(
|
|
58
|
+
config_file=KUBE_CONFIG_PATH
|
|
59
|
+
if not is_get_capacity
|
|
60
|
+
else TEMP_KUBE_CONFIG_FILE
|
|
61
|
+
) # or config.load_incluster_config() for in-cluster config
|
|
62
|
+
cls._instance._kube_client = client.ApiClient()
|
|
63
|
+
return cls._instance
|
|
64
|
+
|
|
65
|
+
def set_context(
|
|
66
|
+
self,
|
|
67
|
+
context_name: str,
|
|
68
|
+
namespace: Optional[str],
|
|
69
|
+
) -> None:
|
|
70
|
+
"""
|
|
71
|
+
Set the current context in the kubeconfig file.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
context_name (str): The name of the context to set as current.
|
|
75
|
+
namespace (str): The name of the namespace to use.
|
|
76
|
+
"""
|
|
77
|
+
with open(KUBE_CONFIG_PATH, "r") as file:
|
|
78
|
+
kubeconfig = yaml.safe_load(file)
|
|
79
|
+
|
|
80
|
+
# Check if the context exists in the kubeconfig and update the context namespace
|
|
81
|
+
# when namespace is specified in command line
|
|
82
|
+
exist = False
|
|
83
|
+
for context in kubeconfig["contexts"]:
|
|
84
|
+
if context["name"] == context_name:
|
|
85
|
+
if namespace is not None:
|
|
86
|
+
context["context"]["namespace"] = namespace
|
|
87
|
+
logger.debug(f"updated the namespace to {namespace}")
|
|
88
|
+
else:
|
|
89
|
+
context["context"].pop("namespace", None)
|
|
90
|
+
exist = True
|
|
91
|
+
|
|
92
|
+
if not exist:
|
|
93
|
+
raise ValueError(f"Context '{context_name}' not found in kubeconfig file")
|
|
94
|
+
|
|
95
|
+
# Set the current context
|
|
96
|
+
kubeconfig["current-context"] = context_name
|
|
97
|
+
|
|
98
|
+
# Write the updated kubeconfig back to the file
|
|
99
|
+
with open(KUBE_CONFIG_PATH, "w") as file:
|
|
100
|
+
yaml.safe_dump(kubeconfig, file)
|
|
101
|
+
|
|
102
|
+
# Load the updated kubeconfig
|
|
103
|
+
config.load_kube_config(config_file=KUBE_CONFIG_PATH)
|
|
104
|
+
logger.debug(f"Current context set to '{context_name}'")
|
|
105
|
+
|
|
106
|
+
def get_core_v1_api(self) -> client.CoreV1Api:
|
|
107
|
+
"""
|
|
108
|
+
Get the CoreV1Api client.
|
|
109
|
+
|
|
110
|
+
Returns:
|
|
111
|
+
client.CoreV1Api: The CoreV1Api client.
|
|
112
|
+
"""
|
|
113
|
+
if self._kube_client is None:
|
|
114
|
+
raise RuntimeError(
|
|
115
|
+
"Kubernetes client is not initialized. Call set_context() first."
|
|
116
|
+
)
|
|
117
|
+
return client.CoreV1Api(self._kube_client)
|
|
118
|
+
|
|
119
|
+
def get_apps_v1_api(self) -> client.AppsV1Api:
|
|
120
|
+
"""
|
|
121
|
+
Get the AppsV1Api client.
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
client.AppsV1Api: The AppsV1Api client.
|
|
125
|
+
"""
|
|
126
|
+
if self._kube_client is None:
|
|
127
|
+
raise RuntimeError(
|
|
128
|
+
"Kubernetes client is not initialized. Call set_context() first."
|
|
129
|
+
)
|
|
130
|
+
return client.AppsV1Api(self._kube_client)
|
|
131
|
+
|
|
132
|
+
def get_auth_v1_api(self) -> client.AuthorizationV1Api:
|
|
133
|
+
"""
|
|
134
|
+
Get the AuthorizationV1Api client.
|
|
135
|
+
|
|
136
|
+
Returns:
|
|
137
|
+
client.AuthorizationV1Api: The AuthorizationV1Api client.
|
|
138
|
+
"""
|
|
139
|
+
|
|
140
|
+
if self._kube_client is None:
|
|
141
|
+
raise RuntimeError(
|
|
142
|
+
"Kubernetes client is not initialized. Call set_context() first."
|
|
143
|
+
)
|
|
144
|
+
return client.AuthorizationV1Api(self._kube_client)
|
|
145
|
+
|
|
146
|
+
def context_exists(self, context: str) -> bool:
|
|
147
|
+
"""
|
|
148
|
+
Check if the specified context exists in the kubeconfig.
|
|
149
|
+
|
|
150
|
+
Args:
|
|
151
|
+
context (str): The name of the context to check.
|
|
152
|
+
|
|
153
|
+
Returns:
|
|
154
|
+
bool: True if the context exists, False otherwise.
|
|
155
|
+
"""
|
|
156
|
+
try:
|
|
157
|
+
contexts, _ = config.list_kube_config_contexts()
|
|
158
|
+
return any(ctx["name"] == context for ctx in contexts)
|
|
159
|
+
except Exception as e:
|
|
160
|
+
raise RuntimeError(f"Failed to check Kubernetes context: {e}")
|
|
161
|
+
|
|
162
|
+
def list_node_with_temp_config(
|
|
163
|
+
self,
|
|
164
|
+
file: str,
|
|
165
|
+
selector_str: str,
|
|
166
|
+
) -> List:
|
|
167
|
+
"""
|
|
168
|
+
Load kubeconfig from a local file
|
|
169
|
+
|
|
170
|
+
Args:
|
|
171
|
+
file (str): The path to the kubeconfig file
|
|
172
|
+
selector_str (str): Selector to filter
|
|
173
|
+
"""
|
|
174
|
+
config.load_kube_config(config_file=file)
|
|
175
|
+
v1Client = client.CoreV1Api()
|
|
176
|
+
_continue = None
|
|
177
|
+
|
|
178
|
+
nodes = []
|
|
179
|
+
while True:
|
|
180
|
+
response = v1Client.list_node(
|
|
181
|
+
label_selector=selector_str,
|
|
182
|
+
limit=200, # Set a reasonable limit
|
|
183
|
+
_continue=_continue,
|
|
184
|
+
)
|
|
185
|
+
nodes.extend(response.items)
|
|
186
|
+
|
|
187
|
+
_continue = response._metadata._continue # Get the continue token
|
|
188
|
+
|
|
189
|
+
if not _continue: # If there's no more data, break the loop
|
|
190
|
+
break
|
|
191
|
+
return nodes
|
|
192
|
+
|
|
193
|
+
def get_current_context_namespace(
|
|
194
|
+
self,
|
|
195
|
+
) -> str:
|
|
196
|
+
"""
|
|
197
|
+
Returns current user namespace context
|
|
198
|
+
"""
|
|
199
|
+
contexts, active_context = config.list_kube_config_contexts()
|
|
200
|
+
return active_context["context"]["namespace"] if "namespace" in active_context["context"] else None
|
|
201
|
+
|
|
202
|
+
def list_namespaces(self) -> List[str]:
|
|
203
|
+
"""
|
|
204
|
+
returns all namespaces
|
|
205
|
+
"""
|
|
206
|
+
result: List[str] = []
|
|
207
|
+
namespaces: V1NamespaceList = client.CoreV1Api().list_namespace()
|
|
208
|
+
namespace: V1Namespace
|
|
209
|
+
for namespace in namespaces.items:
|
|
210
|
+
if namespace.metadata and namespace.metadata.name:
|
|
211
|
+
result.append(namespace.metadata.name)
|
|
212
|
+
return result
|
|
213
|
+
|
|
214
|
+
def get_sagemaker_managed_namespace(self, namespace: Optional[str]):
|
|
215
|
+
"""
|
|
216
|
+
Verify if a namespace is sagemaker managed. SageMaker created namespaces have custom label
|
|
217
|
+
attached, indicating that the namespace is SageMaker managed.
|
|
218
|
+
|
|
219
|
+
Args:
|
|
220
|
+
namespace (Optional[str]): The input namespace that will be checked.
|
|
221
|
+
|
|
222
|
+
Returns:
|
|
223
|
+
Optional[V1Namespace]: V1Namespace response if namespace exists and it is verified being managed by SageMaker. Otherwise return None.
|
|
224
|
+
"""
|
|
225
|
+
if namespace is None:
|
|
226
|
+
return None
|
|
227
|
+
try:
|
|
228
|
+
response = client.CoreV1Api().read_namespace(name=namespace)
|
|
229
|
+
labels = response.metadata.labels
|
|
230
|
+
if labels and SAGEMAKER_MANAGED_QUEUE_LABEL in labels and labels[SAGEMAKER_MANAGED_QUEUE_LABEL] == "true":
|
|
231
|
+
return response
|
|
232
|
+
except ApiException as e:
|
|
233
|
+
if e.status == RESOURCE_NOT_FOUND_CODE:
|
|
234
|
+
return None
|
|
235
|
+
else:
|
|
236
|
+
raise e
|
|
237
|
+
return None
|
|
238
|
+
|
|
239
|
+
def list_pods_with_labels(self, namespace: str, label_selector: str):
|
|
240
|
+
return client.CoreV1Api().list_namespaced_pod(
|
|
241
|
+
namespace=namespace,
|
|
242
|
+
label_selector=label_selector,
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
def list_pods_in_all_namespaces_with_labels(self, label_selector: str):
|
|
246
|
+
v1Client = client.CoreV1Api()
|
|
247
|
+
pods = []
|
|
248
|
+
_continue = None
|
|
249
|
+
|
|
250
|
+
while True:
|
|
251
|
+
response = v1Client.list_pod_for_all_namespaces(
|
|
252
|
+
label_selector=label_selector,
|
|
253
|
+
limit=200, # Set a reasonable limit
|
|
254
|
+
_continue=_continue,
|
|
255
|
+
)
|
|
256
|
+
pods.extend(response.items)
|
|
257
|
+
|
|
258
|
+
_continue = response._metadata._continue # Get the continue token
|
|
259
|
+
|
|
260
|
+
if not _continue: # If there's no more data, break the loop
|
|
261
|
+
break
|
|
262
|
+
|
|
263
|
+
return pods
|
|
264
|
+
|
|
265
|
+
def get_logs_for_pod(self, pod_name: str, namespace: str):
|
|
266
|
+
return client.CoreV1Api().read_namespaced_pod_log(
|
|
267
|
+
name=pod_name, namespace=namespace
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
def get_job(self, job_name: str, namespace: str):
|
|
271
|
+
return client.CustomObjectsApi().get_namespaced_custom_object(
|
|
272
|
+
group=PYTORCH_CUSTOM_OBJECT_GROUP,
|
|
273
|
+
version=PYTORCH_CUSTOM_OBJECT_VERSION,
|
|
274
|
+
namespace=namespace,
|
|
275
|
+
plural=PYTORCH_CUSTOM_OBJECT_PLURAL,
|
|
276
|
+
name=job_name,
|
|
277
|
+
)
|
|
278
|
+
|
|
279
|
+
def get_pod_details(self, pod_name: str, namespace: str):
|
|
280
|
+
return client.CoreV1Api().read_namespaced_pod(
|
|
281
|
+
name=pod_name, namespace=namespace
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
def delete_training_job(self, job_name: str, namespace: str):
|
|
285
|
+
return client.CustomObjectsApi().delete_namespaced_custom_object(
|
|
286
|
+
group=PYTORCH_CUSTOM_OBJECT_GROUP,
|
|
287
|
+
version=PYTORCH_CUSTOM_OBJECT_VERSION,
|
|
288
|
+
namespace=namespace,
|
|
289
|
+
plural=PYTORCH_CUSTOM_OBJECT_PLURAL,
|
|
290
|
+
name=job_name,
|
|
291
|
+
)
|
|
292
|
+
|
|
293
|
+
def list_training_jobs(
|
|
294
|
+
self,
|
|
295
|
+
namespace: str,
|
|
296
|
+
label_selector: Optional[str],
|
|
297
|
+
):
|
|
298
|
+
return client.CustomObjectsApi().list_namespaced_custom_object(
|
|
299
|
+
group=PYTORCH_CUSTOM_OBJECT_GROUP,
|
|
300
|
+
version=PYTORCH_CUSTOM_OBJECT_VERSION,
|
|
301
|
+
namespace=namespace,
|
|
302
|
+
plural=PYTORCH_CUSTOM_OBJECT_PLURAL,
|
|
303
|
+
label_selector=label_selector,
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
def check_if_namespace_exists(self, namespace: str):
|
|
307
|
+
try:
|
|
308
|
+
client.CoreV1Api().read_namespace(name=namespace)
|
|
309
|
+
return True
|
|
310
|
+
except client.rest.ApiException as e:
|
|
311
|
+
if e.status == 404:
|
|
312
|
+
return False
|
|
313
|
+
else:
|
|
314
|
+
print(f"Exception when calling read_namespace: {e}")
|
|
315
|
+
raise e
|
|
316
|
+
|
|
317
|
+
def exec_command_on_pod(
|
|
318
|
+
self,
|
|
319
|
+
pod: str,
|
|
320
|
+
namespace: str,
|
|
321
|
+
bash_command: str,
|
|
322
|
+
):
|
|
323
|
+
return stream.stream(
|
|
324
|
+
client.CoreV1Api().connect_get_namespaced_pod_exec,
|
|
325
|
+
stderr=True,
|
|
326
|
+
stdout=True,
|
|
327
|
+
name=pod,
|
|
328
|
+
namespace=namespace,
|
|
329
|
+
command=bash_command,
|
|
330
|
+
)
|
|
331
|
+
|
|
332
|
+
def patch_workload(self, workload_name: str, namespace: str, patch_body: str):
|
|
333
|
+
return client.CustomObjectsApi().patch_namespaced_custom_object(
|
|
334
|
+
group=KUEUE_CUSTOM_OBJECT_GROUP,
|
|
335
|
+
version=KUEUE_CUSTOM_OBJECT_VERSION,
|
|
336
|
+
namespace=namespace,
|
|
337
|
+
plural=WORKLOAD_CUSTOM_OBJECT_PLURAL,
|
|
338
|
+
name=workload_name,
|
|
339
|
+
body=patch_body
|
|
340
|
+
)
|
|
341
|
+
|
|
342
|
+
def get_workload_by_label(self, label_selector: str, namespace: str):
|
|
343
|
+
return client.CustomObjectsApi().list_namespaced_custom_object(
|
|
344
|
+
group=KUEUE_CUSTOM_OBJECT_GROUP,
|
|
345
|
+
version=KUEUE_CUSTOM_OBJECT_VERSION,
|
|
346
|
+
namespace=namespace,
|
|
347
|
+
plural=WORKLOAD_CUSTOM_OBJECT_PLURAL,
|
|
348
|
+
label_selector=label_selector,
|
|
349
|
+
)
|
|
350
|
+
|
|
351
|
+
def list_workload_priority_classes(self):
|
|
352
|
+
return client.CustomObjectsApi().list_cluster_custom_object(
|
|
353
|
+
group=KUEUE_CUSTOM_OBJECT_GROUP,
|
|
354
|
+
version=KUEUE_CUSTOM_OBJECT_VERSION,
|
|
355
|
+
plural=WORKLOAD_PRIORITY_CLASS_CUSTOM_OBJECT_PLURAL,
|
|
356
|
+
)
|
|
357
|
+
|
|
358
|
+
def get_cluster_queue(self, cluster_queue_name: str):
|
|
359
|
+
return client.CustomObjectsApi().get_cluster_custom_object(
|
|
360
|
+
group=KUEUE_CUSTOM_OBJECT_GROUP,
|
|
361
|
+
version=KUEUE_CUSTOM_OBJECT_VERSION,
|
|
362
|
+
plural=CLUSTER_QUEUE_PRIORITY_CLASS_CUSTOM_OBJECT_PLURAL,
|
|
363
|
+
name=cluster_queue_name
|
|
364
|
+
)
|
|
365
|
+
# Add more methods to access other APIs as needed
|
|
File without changes
|