anyscale 0.26.61__py3-none-any.whl → 0.26.63__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.
- anyscale/_private/anyscale_client/anyscale_client.py +4 -1
- anyscale/_private/docgen/__main__.py +0 -2
- anyscale/_private/docgen/models.md +2 -0
- anyscale/client/README.md +17 -3
- anyscale/client/openapi_client/__init__.py +10 -3
- anyscale/client/openapi_client/api/default_api.py +3229 -2400
- anyscale/client/openapi_client/models/__init__.py +10 -3
- anyscale/client/openapi_client/models/api_key_info.py +280 -0
- anyscale/client/openapi_client/models/api_key_parameters.py +29 -3
- anyscale/client/openapi_client/models/{aggregatedinstanceusagecsv_list_response.py → apikeyinfo_list_response.py} +15 -15
- anyscale/client/openapi_client/models/compute_node_type.py +29 -1
- anyscale/client/openapi_client/models/gpu_usage.py +236 -0
- anyscale/client/openapi_client/models/node_metrics.py +404 -0
- anyscale/client/openapi_client/models/node_metrics_response.py +123 -0
- anyscale/client/openapi_client/models/nodemetricsresponse_response.py +121 -0
- anyscale/client/openapi_client/models/operator_metrics.py +27 -1
- anyscale/client/openapi_client/models/revoke_api_keys_request.py +123 -0
- anyscale/client/openapi_client/models/revoke_api_keys_response.py +202 -0
- anyscale/client/openapi_client/models/revokeapikeysresponse_response.py +121 -0
- anyscale/client/openapi_client/models/{cloud_hosting_type.py → task_summary_config.py} +33 -13
- anyscale/client/openapi_client/models/task_table_config.py +29 -3
- anyscale/client/openapi_client/models/task_table_row.py +29 -3
- anyscale/client/openapi_client/models/worker_node_type.py +29 -1
- anyscale/commands/cloud_commands.py +146 -61
- anyscale/commands/command_examples.py +12 -0
- anyscale/commands/service_account_commands.py +0 -21
- anyscale/compute_config/_private/compute_config_sdk.py +4 -0
- anyscale/compute_config/models.py +24 -0
- anyscale/controllers/cloud_controller.py +94 -20
- anyscale/sdk/anyscale_client/models/compute_node_type.py +29 -1
- anyscale/sdk/anyscale_client/models/worker_node_type.py +29 -1
- anyscale/service_account/_private/service_account_sdk.py +10 -1
- anyscale/version.py +1 -1
- anyscale/workspace/commands.py +23 -114
- {anyscale-0.26.61.dist-info → anyscale-0.26.63.dist-info}/METADATA +1 -1
- {anyscale-0.26.61.dist-info → anyscale-0.26.63.dist-info}/RECORD +41 -34
- anyscale/client/openapi_client/models/aggregated_instance_usage_csv.py +0 -889
- {anyscale-0.26.61.dist-info → anyscale-0.26.63.dist-info}/WHEEL +0 -0
- {anyscale-0.26.61.dist-info → anyscale-0.26.63.dist-info}/entry_points.txt +0 -0
- {anyscale-0.26.61.dist-info → anyscale-0.26.63.dist-info}/licenses/LICENSE +0 -0
- {anyscale-0.26.61.dist-info → anyscale-0.26.63.dist-info}/licenses/NOTICE +0 -0
- {anyscale-0.26.61.dist-info → anyscale-0.26.63.dist-info}/top_level.txt +0 -0
@@ -629,6 +629,18 @@ Output
|
|
629
629
|
--enable-system-cluster is specified. [...] Are you sure you want to enable system cluster? [y/N]: y
|
630
630
|
Output
|
631
631
|
(anyscale +11.4s) Successfully enabled system cluster for cloud cloud_id
|
632
|
+
|
633
|
+
$ anyscale cloud config update --cloud-id cloud_id --spec-file iam.yaml
|
634
|
+
Output
|
635
|
+
(anyscale +2.1s) Successfully updated cloud configuration for cloud my-cloud (resource: cldrsrc_xyz123)
|
636
|
+
|
637
|
+
$ anyscale cloud config update --cloud-id cloud_id --resource shared-usw2 --spec-file iam.yaml
|
638
|
+
Output
|
639
|
+
(anyscale +2.1s) Successfully updated cloud configuration for cloud my-cloud (resource: cldrsrc_abc456)
|
640
|
+
|
641
|
+
$ anyscale cloud config update --cloud-id cloud_id --cloud-resource-id cldrsrc_xyz123 --spec-file iam.yaml
|
642
|
+
Output
|
643
|
+
(anyscale +2.1s) Successfully updated cloud configuration for cloud my-cloud (resource: cldrsrc_xyz123)
|
632
644
|
"""
|
633
645
|
|
634
646
|
CLOUD_TERMINATE_SYSTEM_CLUSTER_EXAMPLE = """\
|
@@ -106,24 +106,3 @@ def delete(email: Optional[str], name: Optional[str]) -> None:
|
|
106
106
|
log.info(f"Service account {email or name} deleted successfully.")
|
107
107
|
except ValueError as e:
|
108
108
|
log.error(f"Error deleting service account: {e}")
|
109
|
-
|
110
|
-
|
111
|
-
@service_account_cli.command(
|
112
|
-
name="rotate-api-keys", help="Rotate all api keys of a service account."
|
113
|
-
)
|
114
|
-
@click.option(
|
115
|
-
"--email", help="Rotate API keys for the service account with this email.", type=str
|
116
|
-
)
|
117
|
-
@click.option(
|
118
|
-
"--name", help="Rotate API keys for the service account with this name.", type=str
|
119
|
-
)
|
120
|
-
def rotate_api_keys(email: Optional[str], name: Optional[str]) -> None:
|
121
|
-
try:
|
122
|
-
api_key = anyscale.service_account.rotate_api_keys(email, name)
|
123
|
-
|
124
|
-
log.info(
|
125
|
-
f"\nAll API keys for service account {email or name} rotated successfully."
|
126
|
-
)
|
127
|
-
_print_new_api_key(api_key)
|
128
|
-
except ValueError as e:
|
129
|
-
log.error(f"Error rotating API keys: {e}")
|
@@ -84,6 +84,7 @@ class PrivateComputeConfigSDK(BaseSDK):
|
|
84
84
|
resources=self._convert_resource_dict_to_api_model(config.resources)
|
85
85
|
if config.resources is not None or schedulable_by_default
|
86
86
|
else UNSCHEDULABLE_RESOURCES,
|
87
|
+
labels=config.labels,
|
87
88
|
flags=flags or None,
|
88
89
|
advanced_configurations_json=config.advanced_instance_config or None,
|
89
90
|
)
|
@@ -110,6 +111,7 @@ class PrivateComputeConfigSDK(BaseSDK):
|
|
110
111
|
name=config.name,
|
111
112
|
instance_type=config.instance_type,
|
112
113
|
resources=self._convert_resource_dict_to_api_model(config.resources),
|
114
|
+
labels=config.labels,
|
113
115
|
min_workers=config.min_nodes,
|
114
116
|
max_workers=config.max_nodes,
|
115
117
|
use_spot=config.market_type
|
@@ -318,6 +320,7 @@ class PrivateComputeConfigSDK(BaseSDK):
|
|
318
320
|
return HeadNodeConfig(
|
319
321
|
instance_type=api_model.instance_type,
|
320
322
|
resources=self._convert_api_model_to_resource_dict(api_model.resources),
|
323
|
+
labels=api_model.labels,
|
321
324
|
advanced_instance_config=self._convert_api_model_to_advanced_instance_config(
|
322
325
|
api_model,
|
323
326
|
),
|
@@ -365,6 +368,7 @@ class PrivateComputeConfigSDK(BaseSDK):
|
|
365
368
|
resources=self._convert_api_model_to_resource_dict(
|
366
369
|
api_model.resources
|
367
370
|
),
|
371
|
+
labels=api_model.labels,
|
368
372
|
advanced_instance_config=self._convert_api_model_to_advanced_instance_config(
|
369
373
|
api_model,
|
370
374
|
),
|
@@ -6,6 +6,7 @@ from anyscale._private.models import ModelBase, ModelEnum
|
|
6
6
|
|
7
7
|
|
8
8
|
ResourceDict = Dict[str, float]
|
9
|
+
LabelDict = Dict[str, str]
|
9
10
|
AdvancedInstanceConfigDict = Dict[str, Any]
|
10
11
|
|
11
12
|
|
@@ -30,6 +31,18 @@ def _validate_resource_dict(r: Optional[ResourceDict], *, field_name: str):
|
|
30
31
|
)
|
31
32
|
|
32
33
|
|
34
|
+
def _validate_label_dict(labels: Optional[LabelDict]):
|
35
|
+
if labels is None:
|
36
|
+
return
|
37
|
+
|
38
|
+
# Convert any non-string keys/values to strings to ensure compatibility
|
39
|
+
for k, v in labels.items():
|
40
|
+
if not isinstance(k, str):
|
41
|
+
raise TypeError(f"'labels' keys must be strings, but got: {k}")
|
42
|
+
if not isinstance(v, str):
|
43
|
+
raise TypeError(f"'labels' values must be strings, but got: {v}")
|
44
|
+
|
45
|
+
|
33
46
|
def _validate_advanced_instance_config_dict(c: Optional[AdvancedInstanceConfigDict]):
|
34
47
|
if c is None:
|
35
48
|
return
|
@@ -119,6 +132,17 @@ class _NodeConfig(ModelBase):
|
|
119
132
|
def _validate_resources(self, resources: Optional[ResourceDict]):
|
120
133
|
_validate_resource_dict(resources, field_name="resources")
|
121
134
|
|
135
|
+
labels: Optional[LabelDict] = field(
|
136
|
+
default=None,
|
137
|
+
repr=False,
|
138
|
+
metadata={
|
139
|
+
"docstring": "Labels to associate the node with for scheduling purposes. Defaults to the list of Ray & Anyscale default labels."
|
140
|
+
},
|
141
|
+
)
|
142
|
+
|
143
|
+
def _validate_labels(self, labels: Optional[LabelDict]):
|
144
|
+
_validate_label_dict(labels)
|
145
|
+
|
122
146
|
advanced_instance_config: Optional[AdvancedInstanceConfigDict] = field(
|
123
147
|
default=None,
|
124
148
|
repr=False,
|
@@ -1929,18 +1929,94 @@ class CloudController(BaseController):
|
|
1929
1929
|
f"Successfully removed resource {resource_name} from cloud {cloud_name}!"
|
1930
1930
|
)
|
1931
1931
|
|
1932
|
+
def _resolve_cloud_resource_id(
|
1933
|
+
self,
|
1934
|
+
cloud_id: str,
|
1935
|
+
resource: Optional[str] = None,
|
1936
|
+
cloud_resource_id: Optional[str] = None,
|
1937
|
+
) -> str:
|
1938
|
+
"""
|
1939
|
+
Resolve cloud resource ID based on resolution order: id > name > primary.
|
1940
|
+
|
1941
|
+
Returns the resolved cloud_resource_id to use for API calls.
|
1942
|
+
"""
|
1943
|
+
# If cloud_resource_id is provided, use it directly
|
1944
|
+
if cloud_resource_id:
|
1945
|
+
self.log.info(f"Using provided cloud resource ID: {cloud_resource_id}")
|
1946
|
+
return cloud_resource_id
|
1947
|
+
|
1948
|
+
# If resource name is provided, resolve by name
|
1949
|
+
if resource:
|
1950
|
+
# Get all cloud resources to resolve by name
|
1951
|
+
cloud_resources = self.api_client.get_cloud_deployments_api_v2_clouds_cloud_id_deployments_get(
|
1952
|
+
cloud_id=cloud_id
|
1953
|
+
).results
|
1954
|
+
|
1955
|
+
if not cloud_resources:
|
1956
|
+
raise RuntimeError(f"No cloud resources found for cloud {cloud_id}")
|
1957
|
+
|
1958
|
+
# Find resources with matching name
|
1959
|
+
matching_resources = [r for r in cloud_resources if r.name == resource]
|
1960
|
+
|
1961
|
+
if not matching_resources:
|
1962
|
+
raise RuntimeError(
|
1963
|
+
f"No cloud resource found with name '{resource}' in cloud {cloud_id}"
|
1964
|
+
)
|
1965
|
+
|
1966
|
+
if len(matching_resources) > 1:
|
1967
|
+
raise RuntimeError(
|
1968
|
+
f"Multiple cloud resources found with name '{resource}'. "
|
1969
|
+
f"Please use --cloud-resource-id to specify which resource to use. "
|
1970
|
+
f"Available resource IDs: {[r.cloud_deployment_id for r in matching_resources]}"
|
1971
|
+
)
|
1972
|
+
|
1973
|
+
resolved_id = matching_resources[0].cloud_deployment_id
|
1974
|
+
self.log.info(f"Resolved resource name '{resource}' to ID: {resolved_id}")
|
1975
|
+
return resolved_id
|
1976
|
+
|
1977
|
+
# Default to primary resource (marked with is_default=True)
|
1978
|
+
cloud_resources = self.api_client.get_cloud_deployments_api_v2_clouds_cloud_id_deployments_get(
|
1979
|
+
cloud_id=cloud_id
|
1980
|
+
).results
|
1981
|
+
|
1982
|
+
if not cloud_resources:
|
1983
|
+
raise RuntimeError(f"No cloud resources found for cloud {cloud_id}")
|
1984
|
+
|
1985
|
+
# Find primary resource (is_default=True)
|
1986
|
+
primary_resources = [r for r in cloud_resources if r.is_default]
|
1987
|
+
|
1988
|
+
if not primary_resources:
|
1989
|
+
raise RuntimeError(f"No primary cloud resource found for cloud {cloud_id}")
|
1990
|
+
|
1991
|
+
if len(primary_resources) > 1:
|
1992
|
+
raise RuntimeError(
|
1993
|
+
f"Multiple primary cloud resources found for cloud {cloud_id}"
|
1994
|
+
)
|
1995
|
+
|
1996
|
+
resolved_id = primary_resources[0].cloud_deployment_id
|
1997
|
+
self.log.info(f"Using primary cloud resource ID: {resolved_id}")
|
1998
|
+
return resolved_id
|
1999
|
+
|
1932
2000
|
def get_cloud_config(
|
1933
|
-
self,
|
2001
|
+
self,
|
2002
|
+
cloud_name: Optional[str] = None,
|
2003
|
+
cloud_id: Optional[str] = None,
|
2004
|
+
resource: Optional[str] = None,
|
2005
|
+
cloud_resource_id: Optional[str] = None,
|
1934
2006
|
) -> CloudDeploymentConfig:
|
1935
2007
|
"""Get a cloud's current JSON configuration."""
|
1936
2008
|
|
1937
|
-
|
2009
|
+
resolved_cloud_id, cloud_name = get_cloud_id_and_name(
|
1938
2010
|
self.api_client, cloud_id, cloud_name
|
1939
2011
|
)
|
1940
2012
|
|
1941
|
-
#
|
2013
|
+
# Resolve the cloud resource ID to use
|
2014
|
+
resolved_cloud_resource_id = self._resolve_cloud_resource_id(
|
2015
|
+
resolved_cloud_id, resource, cloud_resource_id
|
2016
|
+
)
|
2017
|
+
|
1942
2018
|
config: CloudDeploymentConfig = self.api_client.get_cloud_deployment_config_api_v2_clouds_cloud_id_deployment_cloud_deployment_id_config_get(
|
1943
|
-
cloud_id=
|
2019
|
+
cloud_id=resolved_cloud_id, cloud_deployment_id=resolved_cloud_resource_id
|
1944
2020
|
).result
|
1945
2021
|
|
1946
2022
|
return config
|
@@ -1951,21 +2027,23 @@ class CloudController(BaseController):
|
|
1951
2027
|
cloud_id: Optional[str] = None,
|
1952
2028
|
enable_log_ingestion: Optional[bool] = None,
|
1953
2029
|
spec_file: Optional[str] = None,
|
2030
|
+
resource: Optional[str] = None,
|
2031
|
+
cloud_resource_id: Optional[str] = None,
|
1954
2032
|
):
|
1955
2033
|
"""Update a cloud's configuration."""
|
1956
2034
|
if enable_log_ingestion is None and spec_file is None:
|
1957
2035
|
return
|
1958
2036
|
|
1959
|
-
|
2037
|
+
resolved_cloud_id, cloud_name = get_cloud_id_and_name(
|
1960
2038
|
self.api_client, cloud_id, cloud_name
|
1961
2039
|
)
|
1962
2040
|
if enable_log_ingestion is not None:
|
1963
2041
|
self._update_customer_aggregated_logs_config(
|
1964
|
-
cloud_id=
|
2042
|
+
cloud_id=resolved_cloud_id, is_enabled=enable_log_ingestion, # type: ignore
|
1965
2043
|
)
|
1966
2044
|
self.log.info(
|
1967
2045
|
f"Successfully updated log ingestion configuration for cloud, "
|
1968
|
-
f"{
|
2046
|
+
f"{resolved_cloud_id} to {enable_log_ingestion}"
|
1969
2047
|
)
|
1970
2048
|
elif spec_file is not None:
|
1971
2049
|
path = pathlib.Path(spec_file)
|
@@ -1975,15 +2053,21 @@ class CloudController(BaseController):
|
|
1975
2053
|
if not path.is_file():
|
1976
2054
|
raise ValueError(f"File {spec_file} is not a file.")
|
1977
2055
|
|
2056
|
+
# Resolve the cloud resource ID to use
|
2057
|
+
resolved_cloud_resource_id = self._resolve_cloud_resource_id(
|
2058
|
+
resolved_cloud_id, resource, cloud_resource_id
|
2059
|
+
)
|
2060
|
+
|
1978
2061
|
spec = yaml.safe_load(path.read_text())
|
1979
2062
|
config = CloudDeploymentConfig(spec=spec)
|
1980
2063
|
self.api_client.update_cloud_deployment_config_api_v2_clouds_cloud_id_deployment_cloud_deployment_id_config_put(
|
1981
|
-
cloud_id=
|
1982
|
-
cloud_deployment_id=
|
2064
|
+
cloud_id=resolved_cloud_id,
|
2065
|
+
cloud_deployment_id=resolved_cloud_resource_id,
|
1983
2066
|
cloud_deployment_config=config,
|
1984
2067
|
)
|
1985
2068
|
self.log.info(
|
1986
|
-
f"Successfully updated cloud configuration for cloud {cloud_name}"
|
2069
|
+
f"Successfully updated cloud configuration for cloud {cloud_name} "
|
2070
|
+
f"(resource: {resolved_cloud_resource_id})"
|
1987
2071
|
)
|
1988
2072
|
|
1989
2073
|
def set_default_cloud(
|
@@ -2693,7 +2777,6 @@ class CloudController(BaseController):
|
|
2693
2777
|
provider=provider,
|
2694
2778
|
cloud_deployment_id=cloud_resource_id,
|
2695
2779
|
region=region if cloud_provider == CloudProviders.AZURE else None,
|
2696
|
-
kubernetes_zones=kubernetes_zones,
|
2697
2780
|
operator_iam_identity=anyscale_operator_iam_identity
|
2698
2781
|
if cloud_provider == CloudProviders.AZURE
|
2699
2782
|
else None,
|
@@ -2939,7 +3022,6 @@ class CloudController(BaseController):
|
|
2939
3022
|
provider="aws",
|
2940
3023
|
cloud_deployment_id=cloud_resource_id,
|
2941
3024
|
region=region,
|
2942
|
-
kubernetes_zones=kubernetes_zones,
|
2943
3025
|
)
|
2944
3026
|
self.log.info(
|
2945
3027
|
f"Cloud registration complete! To install the Anyscale operator, run:\n\n{helm_command}"
|
@@ -3434,7 +3516,6 @@ class CloudController(BaseController):
|
|
3434
3516
|
provider="gcp",
|
3435
3517
|
cloud_deployment_id=cloud_resource_id,
|
3436
3518
|
region=region,
|
3437
|
-
kubernetes_zones=kubernetes_zones,
|
3438
3519
|
operator_iam_identity=anyscale_service_account_email,
|
3439
3520
|
)
|
3440
3521
|
gcloud_command = self._generate_gcp_workload_identity_command(
|
@@ -4160,7 +4241,6 @@ class CloudController(BaseController):
|
|
4160
4241
|
provider: str,
|
4161
4242
|
cloud_deployment_id: str,
|
4162
4243
|
region: Optional[str] = None,
|
4163
|
-
kubernetes_zones: Optional[List[str]] = None,
|
4164
4244
|
operator_iam_identity: Optional[str] = None,
|
4165
4245
|
anyscale_cli_token: Optional[str] = None,
|
4166
4246
|
) -> str:
|
@@ -4171,7 +4251,6 @@ class CloudController(BaseController):
|
|
4171
4251
|
provider: Cloud provider ('aws', 'gcp', 'azure', 'generic')
|
4172
4252
|
cloud_deployment_id: The cloud deployment ID from registration
|
4173
4253
|
region: Cloud region (optional for generic provider)
|
4174
|
-
kubernetes_zones: Optional list of Kubernetes zones
|
4175
4254
|
operator_iam_identity: IAM identity for the operator (GCP service account email, Azure client ID)
|
4176
4255
|
anyscale_cli_token: CLI token (required for Azure and generic providers)
|
4177
4256
|
|
@@ -4226,11 +4305,6 @@ class CloudController(BaseController):
|
|
4226
4305
|
]
|
4227
4306
|
)
|
4228
4307
|
|
4229
|
-
# Add zones if provided (mainly for K8s deployments)
|
4230
|
-
if kubernetes_zones:
|
4231
|
-
zones_str = ",".join(kubernetes_zones)
|
4232
|
-
command_parts.append(f" --set-string zones={zones_str}")
|
4233
|
-
|
4234
4308
|
return " \\\n".join(command_parts)
|
4235
4309
|
|
4236
4310
|
def _generate_gcp_workload_identity_command(
|
@@ -36,6 +36,7 @@ class ComputeNodeType(object):
|
|
36
36
|
'name': 'str',
|
37
37
|
'instance_type': 'str',
|
38
38
|
'resources': 'Resources',
|
39
|
+
'labels': 'dict(str, str)',
|
39
40
|
'aws_advanced_configurations_json': 'object',
|
40
41
|
'gcp_advanced_configurations_json': 'object',
|
41
42
|
'advanced_configurations_json': 'object',
|
@@ -46,13 +47,14 @@ class ComputeNodeType(object):
|
|
46
47
|
'name': 'name',
|
47
48
|
'instance_type': 'instance_type',
|
48
49
|
'resources': 'resources',
|
50
|
+
'labels': 'labels',
|
49
51
|
'aws_advanced_configurations_json': 'aws_advanced_configurations_json',
|
50
52
|
'gcp_advanced_configurations_json': 'gcp_advanced_configurations_json',
|
51
53
|
'advanced_configurations_json': 'advanced_configurations_json',
|
52
54
|
'flags': 'flags'
|
53
55
|
}
|
54
56
|
|
55
|
-
def __init__(self, name=None, instance_type=None, resources=None, aws_advanced_configurations_json=None, gcp_advanced_configurations_json=None, advanced_configurations_json=None, flags=None, local_vars_configuration=None): # noqa: E501
|
57
|
+
def __init__(self, name=None, instance_type=None, resources=None, labels=None, aws_advanced_configurations_json=None, gcp_advanced_configurations_json=None, advanced_configurations_json=None, flags=None, local_vars_configuration=None): # noqa: E501
|
56
58
|
"""ComputeNodeType - a model defined in OpenAPI""" # noqa: E501
|
57
59
|
if local_vars_configuration is None:
|
58
60
|
local_vars_configuration = Configuration()
|
@@ -61,6 +63,7 @@ class ComputeNodeType(object):
|
|
61
63
|
self._name = None
|
62
64
|
self._instance_type = None
|
63
65
|
self._resources = None
|
66
|
+
self._labels = None
|
64
67
|
self._aws_advanced_configurations_json = None
|
65
68
|
self._gcp_advanced_configurations_json = None
|
66
69
|
self._advanced_configurations_json = None
|
@@ -71,6 +74,8 @@ class ComputeNodeType(object):
|
|
71
74
|
self.instance_type = instance_type
|
72
75
|
if resources is not None:
|
73
76
|
self.resources = resources
|
77
|
+
if labels is not None:
|
78
|
+
self.labels = labels
|
74
79
|
if aws_advanced_configurations_json is not None:
|
75
80
|
self.aws_advanced_configurations_json = aws_advanced_configurations_json
|
76
81
|
if gcp_advanced_configurations_json is not None:
|
@@ -153,6 +158,29 @@ class ComputeNodeType(object):
|
|
153
158
|
|
154
159
|
self._resources = resources
|
155
160
|
|
161
|
+
@property
|
162
|
+
def labels(self):
|
163
|
+
"""Gets the labels of this ComputeNodeType. # noqa: E501
|
164
|
+
|
165
|
+
Labels to associate the node with for scheduling purposes. Defaults to the list of Ray & Anyscale default labels. # noqa: E501
|
166
|
+
|
167
|
+
:return: The labels of this ComputeNodeType. # noqa: E501
|
168
|
+
:rtype: dict(str, str)
|
169
|
+
"""
|
170
|
+
return self._labels
|
171
|
+
|
172
|
+
@labels.setter
|
173
|
+
def labels(self, labels):
|
174
|
+
"""Sets the labels of this ComputeNodeType.
|
175
|
+
|
176
|
+
Labels to associate the node with for scheduling purposes. Defaults to the list of Ray & Anyscale default labels. # noqa: E501
|
177
|
+
|
178
|
+
:param labels: The labels of this ComputeNodeType. # noqa: E501
|
179
|
+
:type: dict(str, str)
|
180
|
+
"""
|
181
|
+
|
182
|
+
self._labels = labels
|
183
|
+
|
156
184
|
@property
|
157
185
|
def aws_advanced_configurations_json(self):
|
158
186
|
"""Gets the aws_advanced_configurations_json of this ComputeNodeType. # noqa: E501
|
@@ -36,6 +36,7 @@ class WorkerNodeType(object):
|
|
36
36
|
'name': 'str',
|
37
37
|
'instance_type': 'str',
|
38
38
|
'resources': 'Resources',
|
39
|
+
'labels': 'dict(str, str)',
|
39
40
|
'aws_advanced_configurations_json': 'object',
|
40
41
|
'gcp_advanced_configurations_json': 'object',
|
41
42
|
'advanced_configurations_json': 'object',
|
@@ -50,6 +51,7 @@ class WorkerNodeType(object):
|
|
50
51
|
'name': 'name',
|
51
52
|
'instance_type': 'instance_type',
|
52
53
|
'resources': 'resources',
|
54
|
+
'labels': 'labels',
|
53
55
|
'aws_advanced_configurations_json': 'aws_advanced_configurations_json',
|
54
56
|
'gcp_advanced_configurations_json': 'gcp_advanced_configurations_json',
|
55
57
|
'advanced_configurations_json': 'advanced_configurations_json',
|
@@ -60,7 +62,7 @@ class WorkerNodeType(object):
|
|
60
62
|
'fallback_to_ondemand': 'fallback_to_ondemand'
|
61
63
|
}
|
62
64
|
|
63
|
-
def __init__(self, name=None, instance_type=None, resources=None, aws_advanced_configurations_json=None, gcp_advanced_configurations_json=None, advanced_configurations_json=None, flags=None, min_workers=None, max_workers=None, use_spot=False, fallback_to_ondemand=False, local_vars_configuration=None): # noqa: E501
|
65
|
+
def __init__(self, name=None, instance_type=None, resources=None, labels=None, aws_advanced_configurations_json=None, gcp_advanced_configurations_json=None, advanced_configurations_json=None, flags=None, min_workers=None, max_workers=None, use_spot=False, fallback_to_ondemand=False, local_vars_configuration=None): # noqa: E501
|
64
66
|
"""WorkerNodeType - a model defined in OpenAPI""" # noqa: E501
|
65
67
|
if local_vars_configuration is None:
|
66
68
|
local_vars_configuration = Configuration()
|
@@ -69,6 +71,7 @@ class WorkerNodeType(object):
|
|
69
71
|
self._name = None
|
70
72
|
self._instance_type = None
|
71
73
|
self._resources = None
|
74
|
+
self._labels = None
|
72
75
|
self._aws_advanced_configurations_json = None
|
73
76
|
self._gcp_advanced_configurations_json = None
|
74
77
|
self._advanced_configurations_json = None
|
@@ -83,6 +86,8 @@ class WorkerNodeType(object):
|
|
83
86
|
self.instance_type = instance_type
|
84
87
|
if resources is not None:
|
85
88
|
self.resources = resources
|
89
|
+
if labels is not None:
|
90
|
+
self.labels = labels
|
86
91
|
if aws_advanced_configurations_json is not None:
|
87
92
|
self.aws_advanced_configurations_json = aws_advanced_configurations_json
|
88
93
|
if gcp_advanced_configurations_json is not None:
|
@@ -173,6 +178,29 @@ class WorkerNodeType(object):
|
|
173
178
|
|
174
179
|
self._resources = resources
|
175
180
|
|
181
|
+
@property
|
182
|
+
def labels(self):
|
183
|
+
"""Gets the labels of this WorkerNodeType. # noqa: E501
|
184
|
+
|
185
|
+
Labels to associate the node with for scheduling purposes. Defaults to the list of Ray & Anyscale default labels. # noqa: E501
|
186
|
+
|
187
|
+
:return: The labels of this WorkerNodeType. # noqa: E501
|
188
|
+
:rtype: dict(str, str)
|
189
|
+
"""
|
190
|
+
return self._labels
|
191
|
+
|
192
|
+
@labels.setter
|
193
|
+
def labels(self, labels):
|
194
|
+
"""Sets the labels of this WorkerNodeType.
|
195
|
+
|
196
|
+
Labels to associate the node with for scheduling purposes. Defaults to the list of Ray & Anyscale default labels. # noqa: E501
|
197
|
+
|
198
|
+
:param labels: The labels of this WorkerNodeType. # noqa: E501
|
199
|
+
:type: dict(str, str)
|
200
|
+
"""
|
201
|
+
|
202
|
+
self._labels = labels
|
203
|
+
|
176
204
|
@property
|
177
205
|
def aws_advanced_configurations_json(self):
|
178
206
|
"""Gets the aws_advanced_configurations_json of this WorkerNodeType. # noqa: E501
|
@@ -33,8 +33,11 @@ class PrivateServiceAccountSDK(BaseSDK):
|
|
33
33
|
raise ValueError(f"No service account {identifier} found.")
|
34
34
|
|
35
35
|
if len(service_accounts) > 1:
|
36
|
+
names = [sa.name for sa in service_accounts]
|
37
|
+
emails = [sa.email for sa in service_accounts]
|
36
38
|
raise ValueError(
|
37
|
-
f"
|
39
|
+
f"Found {len(service_accounts)} service accounts matching '{identifier}'. "
|
40
|
+
f"Names: {names}, Emails: {emails}. This should not happen - please contact support."
|
38
41
|
)
|
39
42
|
|
40
43
|
def _get_service_account(
|
@@ -44,6 +47,12 @@ class PrivateServiceAccountSDK(BaseSDK):
|
|
44
47
|
service_accounts = self.client.get_organization_collaborators(
|
45
48
|
email=email, name=name, is_service_account=True
|
46
49
|
)
|
50
|
+
|
51
|
+
if name is not None:
|
52
|
+
service_accounts = [sa for sa in service_accounts if sa.name == name]
|
53
|
+
if email is not None:
|
54
|
+
service_accounts = [sa for sa in service_accounts if sa.email == email]
|
55
|
+
|
47
56
|
self._validate_exactly_one_service_account_per_email_or_name(
|
48
57
|
service_accounts, identifier
|
49
58
|
)
|
anyscale/version.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "0.26.
|
1
|
+
__version__ = "0.26.63"
|