anyscale 0.26.64__py3-none-any.whl → 0.26.65__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/docgen/__main__.py +23 -4
- anyscale/_private/docgen/generator.py +127 -34
- anyscale/_private/docgen/generator_legacy.py +35 -12
- anyscale/client/README.md +37 -0
- anyscale/client/openapi_client/__init__.py +26 -0
- anyscale/client/openapi_client/api/default_api.py +1423 -97
- anyscale/client/openapi_client/models/__init__.py +26 -0
- anyscale/client/openapi_client/models/connection_type.py +99 -0
- anyscale/client/openapi_client/models/create_experimental_workspace.py +29 -1
- anyscale/client/openapi_client/models/data_catalog.py +281 -0
- anyscale/client/openapi_client/models/data_catalog_connection.py +308 -0
- anyscale/client/openapi_client/models/data_catalog_connection_status.py +102 -0
- anyscale/client/openapi_client/models/data_catalog_provider.py +101 -0
- anyscale/client/openapi_client/models/databricks_connection_config.py +152 -0
- anyscale/client/openapi_client/models/databricks_connection_info.py +229 -0
- anyscale/client/openapi_client/models/databricks_connection_response.py +148 -0
- anyscale/client/openapi_client/models/databricks_register_request.py +187 -0
- anyscale/client/openapi_client/models/databricksconnectioninfo_response.py +121 -0
- anyscale/client/openapi_client/models/databricksconnectionresponse_response.py +121 -0
- anyscale/client/openapi_client/models/datacatalog_list_response.py +147 -0
- anyscale/client/openapi_client/models/datacatalogconnection_list_response.py +147 -0
- anyscale/client/openapi_client/models/decorated_session.py +29 -1
- anyscale/client/openapi_client/models/domain_verification.py +181 -0
- anyscale/client/openapi_client/models/list_databricks_connections.py +121 -0
- anyscale/client/openapi_client/models/o_auth_connection_response.py +229 -0
- anyscale/client/openapi_client/models/oauth_auth_url_response.py +121 -0
- anyscale/client/openapi_client/models/oauthconnectionresponse_response.py +121 -0
- anyscale/client/openapi_client/models/sso_config.py +148 -0
- anyscale/client/openapi_client/models/sso_connection.py +148 -0
- anyscale/client/openapi_client/models/sso_connection_state.py +100 -0
- anyscale/client/openapi_client/models/ssoconfig_response.py +121 -0
- anyscale/client/openapi_client/models/update_workspace_template.py +346 -0
- anyscale/client/openapi_client/models/usage_by_cluster_type.py +174 -0
- anyscale/client/openapi_client/models/usagebyclustertype_list_response.py +147 -0
- anyscale/client/openapi_client/models/validation_status.py +101 -0
- anyscale/commands/cloud_commands.py +310 -206
- anyscale/controllers/cloud_controller.py +174 -240
- anyscale/controllers/cloud_functional_verification_controller.py +6 -3
- anyscale/sdk/anyscale_client/models/session.py +31 -3
- anyscale/util.py +1 -1
- anyscale/version.py +1 -1
- {anyscale-0.26.64.dist-info → anyscale-0.26.65.dist-info}/METADATA +1 -1
- {anyscale-0.26.64.dist-info → anyscale-0.26.65.dist-info}/RECORD +48 -23
- anyscale/commands/cloud_commands_util.py +0 -10
- {anyscale-0.26.64.dist-info → anyscale-0.26.65.dist-info}/WHEEL +0 -0
- {anyscale-0.26.64.dist-info → anyscale-0.26.65.dist-info}/entry_points.txt +0 -0
- {anyscale-0.26.64.dist-info → anyscale-0.26.65.dist-info}/licenses/LICENSE +0 -0
- {anyscale-0.26.64.dist-info → anyscale-0.26.65.dist-info}/licenses/NOTICE +0 -0
- {anyscale-0.26.64.dist-info → anyscale-0.26.65.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,5 @@
|
|
1
1
|
from io import StringIO
|
2
|
+
import pathlib
|
2
3
|
import re
|
3
4
|
from typing import List, Optional
|
4
5
|
|
@@ -7,10 +8,21 @@ import yaml
|
|
7
8
|
|
8
9
|
import anyscale
|
9
10
|
from anyscale.cli_logger import BlockLogger
|
10
|
-
from anyscale.client.openapi_client.models import
|
11
|
+
from anyscale.client.openapi_client.models import (
|
12
|
+
AWSConfig,
|
13
|
+
CloudDeployment,
|
14
|
+
CloudProviders,
|
15
|
+
ClusterManagementStackVersions,
|
16
|
+
FileStorage,
|
17
|
+
GCPConfig,
|
18
|
+
KubernetesConfig,
|
19
|
+
NetworkingMode,
|
20
|
+
NFSMountTarget,
|
21
|
+
ObjectStorage,
|
22
|
+
)
|
11
23
|
from anyscale.client.openapi_client.models.compute_stack import ComputeStack
|
12
24
|
from anyscale.cloud.models import CreateCloudCollaborator, CreateCloudCollaborators
|
13
|
-
from anyscale.commands import
|
25
|
+
from anyscale.commands import command_examples
|
14
26
|
from anyscale.commands.util import AnyscaleCommand, OptionPromptNull
|
15
27
|
from anyscale.controllers.cloud_controller import CloudController
|
16
28
|
from anyscale.util import (
|
@@ -231,12 +243,14 @@ def setup_cloud( # noqa: PLR0913
|
|
231
243
|
@click.option(
|
232
244
|
"--max-items",
|
233
245
|
required=False,
|
234
|
-
default=
|
246
|
+
default=None,
|
235
247
|
type=int,
|
236
|
-
help="
|
248
|
+
help="Maximum number of clouds to return. If not specified, all results are returned.",
|
237
249
|
callback=validate_non_negative_arg,
|
238
250
|
)
|
239
|
-
def list_cloud(
|
251
|
+
def list_cloud(
|
252
|
+
name: Optional[str], cloud_id: Optional[str], max_items: Optional[int]
|
253
|
+
) -> None:
|
240
254
|
print(
|
241
255
|
CloudController().list_clouds(
|
242
256
|
cloud_name=name, cloud_id=cloud_id, max_items=max_items
|
@@ -893,6 +907,12 @@ def cloud_config_update( # noqa: PLR0913
|
|
893
907
|
"permissions after the cloud is created."
|
894
908
|
),
|
895
909
|
)
|
910
|
+
@click.option(
|
911
|
+
"--resource-file",
|
912
|
+
"-f",
|
913
|
+
help="Path to a YAML file defining a cloud resource. Schema: https://docs.anyscale.com/reference/cloud/#cloudresource.",
|
914
|
+
required=False,
|
915
|
+
)
|
896
916
|
def register_cloud( # noqa: PLR0913, PLR0912, C901
|
897
917
|
provider: str,
|
898
918
|
region: str,
|
@@ -933,240 +953,323 @@ def register_cloud( # noqa: PLR0913, PLR0912, C901
|
|
933
953
|
yes: bool,
|
934
954
|
skip_verifications: bool,
|
935
955
|
enable_auto_add_user: bool,
|
956
|
+
resource_file: Optional[str],
|
936
957
|
) -> None:
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
"
|
945
|
-
|
958
|
+
# Load CloudDeployment from the resource file if provided, otherwise build from CLI flags
|
959
|
+
if resource_file:
|
960
|
+
# Read the spec file.
|
961
|
+
path = pathlib.Path(resource_file)
|
962
|
+
if not path.exists():
|
963
|
+
raise click.ClickException(f"{resource_file} does not exist.")
|
964
|
+
if not path.is_file():
|
965
|
+
raise click.ClickException(f"{resource_file} is not a file.")
|
966
|
+
|
967
|
+
spec = yaml.safe_load(path.read_text())
|
968
|
+
try:
|
969
|
+
cloud_resource = CloudDeployment(**spec)
|
970
|
+
|
971
|
+
# Convert nested dict objects to model objects
|
972
|
+
if cloud_resource.file_storage:
|
973
|
+
cloud_resource.file_storage = FileStorage(**cloud_resource.file_storage)
|
974
|
+
if cloud_resource.object_storage:
|
975
|
+
cloud_resource.object_storage = ObjectStorage(
|
976
|
+
**cloud_resource.object_storage
|
977
|
+
)
|
978
|
+
if cloud_resource.aws_config:
|
979
|
+
cloud_resource.aws_config = AWSConfig(**cloud_resource.aws_config)
|
980
|
+
if cloud_resource.gcp_config:
|
981
|
+
cloud_resource.gcp_config = GCPConfig(**cloud_resource.gcp_config)
|
982
|
+
if cloud_resource.kubernetes_config:
|
983
|
+
cloud_resource.kubernetes_config = KubernetesConfig(
|
984
|
+
**cloud_resource.kubernetes_config
|
985
|
+
)
|
986
|
+
|
987
|
+
except Exception as e: # noqa: BLE001
|
988
|
+
raise click.ClickException(f"Failed to parse cloud resource: {e}")
|
946
989
|
|
947
|
-
|
948
|
-
|
949
|
-
if nfs_mount_target or nfs_mount_path:
|
950
|
-
storage_configs.append("NFS")
|
951
|
-
if persistent_volume_claim:
|
952
|
-
storage_configs.append("persistent volume claim")
|
953
|
-
if csi_ephemeral_volume_driver:
|
954
|
-
storage_configs.append("CSI ephemeral volume driver")
|
955
|
-
|
956
|
-
if len(storage_configs) > 1:
|
957
|
-
raise click.ClickException(
|
958
|
-
f"Storage configurations are mutually exclusive. Found: {', '.join(storage_configs)}. "
|
959
|
-
"Please specify only one of: --nfs-mount-target/--nfs-mount-path, --persistent-volume-claim, or --csi-ephemeral-volume-driver"
|
960
|
-
)
|
961
|
-
|
962
|
-
if provider == "aws":
|
963
|
-
if s3_bucket_id and not cloud_storage_bucket_name:
|
964
|
-
cloud_storage_bucket_name = s3_bucket_id
|
965
|
-
if efs_id and not file_storage_id:
|
966
|
-
file_storage_id = efs_id
|
967
|
-
# Check for missing required arguments for AWS clouds,
|
968
|
-
# based on the compute stack (not all args are required
|
969
|
-
# on all compute stacks).
|
970
|
-
required_resources = [
|
971
|
-
(vpc_id, "--vpc-id", (ComputeStack.VM)),
|
972
|
-
(subnet_ids, "--subnet-ids", (ComputeStack.VM)),
|
973
|
-
(anyscale_iam_role_id, "--anyscale-iam-role-id", (ComputeStack.VM),),
|
974
|
-
(instance_iam_role_id, "--instance-iam-role-id", (ComputeStack.VM)),
|
975
|
-
(security_group_ids, "--security-group-ids", (ComputeStack.VM)),
|
976
|
-
(
|
977
|
-
cloud_storage_bucket_name,
|
978
|
-
"--cloud-storage-bucket-name",
|
979
|
-
(ComputeStack.VM, ComputeStack.K8S),
|
980
|
-
),
|
981
|
-
(kubernetes_zones, "--kubernetes-zones", (ComputeStack.K8S)),
|
982
|
-
(
|
983
|
-
anyscale_operator_iam_identity,
|
984
|
-
"--anyscale-operator-iam-identity",
|
985
|
-
(ComputeStack.K8S),
|
986
|
-
),
|
987
|
-
]
|
990
|
+
else:
|
991
|
+
missing_args: List[str] = []
|
988
992
|
|
989
|
-
|
990
|
-
|
991
|
-
|
993
|
+
# Validate K8S-only storage flags
|
994
|
+
if (
|
995
|
+
persistent_volume_claim or csi_ephemeral_volume_driver
|
996
|
+
) and compute_stack != ComputeStack.K8S:
|
997
|
+
raise click.ClickException(
|
998
|
+
"--persistent-volume-claim and --csi-ephemeral-volume-driver are only supported with --compute-stack=k8s"
|
992
999
|
)
|
993
1000
|
|
994
|
-
|
995
|
-
|
996
|
-
|
1001
|
+
# Validate mutual exclusivity of storage configurations
|
1002
|
+
storage_configs = []
|
1003
|
+
if nfs_mount_target or nfs_mount_path:
|
1004
|
+
storage_configs.append("NFS")
|
1005
|
+
if persistent_volume_claim:
|
1006
|
+
storage_configs.append("persistent volume claim")
|
1007
|
+
if csi_ephemeral_volume_driver:
|
1008
|
+
storage_configs.append("CSI ephemeral volume driver")
|
997
1009
|
|
998
|
-
if len(
|
999
|
-
raise click.ClickException(
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
compute_stack=compute_stack,
|
1004
|
-
name=name,
|
1005
|
-
vpc_id=vpc_id,
|
1006
|
-
subnet_ids=subnet_ids.split(",") if subnet_ids else [],
|
1007
|
-
efs_id=file_storage_id,
|
1008
|
-
anyscale_iam_role_id=anyscale_iam_role_id,
|
1009
|
-
instance_iam_role_id=instance_iam_role_id,
|
1010
|
-
security_group_ids=security_group_ids.split(",")
|
1011
|
-
if security_group_ids
|
1012
|
-
else [],
|
1013
|
-
cloud_storage_bucket_name=cloud_storage_bucket_name,
|
1014
|
-
memorydb_cluster_id=memorydb_cluster_id,
|
1015
|
-
functional_verify=functional_verify,
|
1016
|
-
kubernetes_zones=kubernetes_zones.split(",") if kubernetes_zones else [],
|
1017
|
-
anyscale_operator_iam_identity=anyscale_operator_iam_identity,
|
1018
|
-
private_network=private_network,
|
1019
|
-
cluster_management_stack_version=ClusterManagementStackVersions.V2,
|
1020
|
-
yes=yes,
|
1021
|
-
skip_verifications=skip_verifications,
|
1022
|
-
auto_add_user=enable_auto_add_user,
|
1023
|
-
external_id=external_id,
|
1024
|
-
persistent_volume_claim=persistent_volume_claim,
|
1025
|
-
csi_ephemeral_volume_driver=csi_ephemeral_volume_driver,
|
1026
|
-
)
|
1027
|
-
elif provider == "gcp":
|
1028
|
-
if filestore_instance_id and not file_storage_id:
|
1029
|
-
file_storage_id = filestore_instance_id
|
1030
|
-
# Keep the parameter naming ({resource}_name or {resource}_id) consistent with GCP to reduce confusion for customers
|
1031
|
-
# Check if all required parameters are provided
|
1032
|
-
# memorystore_instance_name and host_project_id are optional for GCP clouds
|
1033
|
-
required_resources = [
|
1034
|
-
(project_id, "--project-id", (ComputeStack.VM)),
|
1035
|
-
(vpc_name, "--vpc-name", (ComputeStack.VM)),
|
1036
|
-
(subnet_names, "--subnet-names", (ComputeStack.VM)),
|
1037
|
-
(
|
1038
|
-
anyscale_service_account_email,
|
1039
|
-
"--anyscale-service-account-email",
|
1040
|
-
(ComputeStack.VM),
|
1041
|
-
),
|
1042
|
-
(
|
1043
|
-
instance_service_account_email,
|
1044
|
-
"--instance-service-account-email",
|
1045
|
-
(ComputeStack.VM),
|
1046
|
-
),
|
1047
|
-
(provider_name, "--provider-name", (ComputeStack.VM)),
|
1048
|
-
(firewall_policy_names, "--firewall-policy-names", (ComputeStack.VM)),
|
1049
|
-
(
|
1050
|
-
cloud_storage_bucket_name,
|
1051
|
-
"--cloud-storage-bucket-name",
|
1052
|
-
(ComputeStack.VM, ComputeStack.K8S),
|
1053
|
-
),
|
1054
|
-
(kubernetes_zones, "--kubernetes-zones", (ComputeStack.K8S)),
|
1055
|
-
(
|
1056
|
-
anyscale_operator_iam_identity,
|
1057
|
-
"--anyscale-operator-iam-identity",
|
1058
|
-
(ComputeStack.K8S),
|
1059
|
-
),
|
1060
|
-
]
|
1010
|
+
if len(storage_configs) > 1:
|
1011
|
+
raise click.ClickException(
|
1012
|
+
f"Storage configurations are mutually exclusive. Found: {', '.join(storage_configs)}. "
|
1013
|
+
"Please specify only one of: --nfs-mount-target/--nfs-mount-path, --persistent-volume-claim, or --csi-ephemeral-volume-driver"
|
1014
|
+
)
|
1061
1015
|
|
1062
|
-
if
|
1063
|
-
|
1064
|
-
|
1016
|
+
if provider == "aws":
|
1017
|
+
if s3_bucket_id and not cloud_storage_bucket_name:
|
1018
|
+
cloud_storage_bucket_name = s3_bucket_id
|
1019
|
+
if efs_id and not file_storage_id:
|
1020
|
+
file_storage_id = efs_id
|
1021
|
+
# Check for missing required arguments for AWS clouds,
|
1022
|
+
# based on the compute stack (not all args are required
|
1023
|
+
# on all compute stacks).
|
1024
|
+
required_resources = [
|
1025
|
+
(vpc_id, "--vpc-id", (ComputeStack.VM)),
|
1026
|
+
(subnet_ids, "--subnet-ids", (ComputeStack.VM)),
|
1027
|
+
(anyscale_iam_role_id, "--anyscale-iam_role-id", (ComputeStack.VM),),
|
1028
|
+
(instance_iam_role_id, "--instance-iam-role-id", (ComputeStack.VM)),
|
1029
|
+
(security_group_ids, "--security-group-ids", (ComputeStack.VM)),
|
1030
|
+
(
|
1031
|
+
cloud_storage_bucket_name,
|
1032
|
+
"--cloud-storage-bucket-name",
|
1033
|
+
(ComputeStack.VM, ComputeStack.K8S),
|
1034
|
+
),
|
1035
|
+
(kubernetes_zones, "--kubernetes-zones", (ComputeStack.K8S)),
|
1036
|
+
(
|
1037
|
+
anyscale_operator_iam_identity,
|
1038
|
+
"--anyscale-operator-iam-identity",
|
1039
|
+
(ComputeStack.K8S),
|
1040
|
+
),
|
1041
|
+
]
|
1042
|
+
|
1043
|
+
if not allow_optional_file_storage():
|
1044
|
+
required_resources.append(
|
1065
1045
|
(file_storage_id, "--file-storage-id", (ComputeStack.VM)),
|
1066
|
-
|
1067
|
-
|
1046
|
+
)
|
1047
|
+
|
1048
|
+
for resource in required_resources:
|
1049
|
+
if compute_stack in resource[2] and resource[0] is None:
|
1050
|
+
missing_args.append(resource[1])
|
1051
|
+
|
1052
|
+
if len(missing_args) > 0:
|
1053
|
+
raise click.ClickException(f"Please provide a value for {missing_args}")
|
1054
|
+
|
1055
|
+
cloud_resource = CloudDeployment(
|
1056
|
+
compute_stack=compute_stack,
|
1057
|
+
provider=CloudProviders.AWS,
|
1058
|
+
region=region,
|
1059
|
+
networking_mode=NetworkingMode.PRIVATE
|
1060
|
+
if private_network
|
1061
|
+
else NetworkingMode.PUBLIC,
|
1062
|
+
object_storage=ObjectStorage(bucket_name=cloud_storage_bucket_name),
|
1063
|
+
file_storage=FileStorage(
|
1064
|
+
file_storage_id=file_storage_id,
|
1065
|
+
persistent_volume_claim=persistent_volume_claim,
|
1066
|
+
csi_ephemeral_volume_driver=csi_ephemeral_volume_driver,
|
1067
|
+
)
|
1068
|
+
if file_storage_id
|
1069
|
+
or persistent_volume_claim
|
1070
|
+
or csi_ephemeral_volume_driver
|
1071
|
+
else None,
|
1072
|
+
aws_config=AWSConfig(
|
1073
|
+
vpc_id=vpc_id,
|
1074
|
+
subnet_ids=subnet_ids.split(",") if subnet_ids else [],
|
1075
|
+
security_group_ids=security_group_ids.split(",")
|
1076
|
+
if security_group_ids
|
1077
|
+
else [],
|
1078
|
+
anyscale_iam_role_id=anyscale_iam_role_id,
|
1079
|
+
external_id=external_id,
|
1080
|
+
cluster_iam_role_id=instance_iam_role_id,
|
1081
|
+
memorydb_cluster_name=memorydb_cluster_id,
|
1082
|
+
),
|
1083
|
+
kubernetes_config=KubernetesConfig(
|
1084
|
+
anyscale_operator_iam_identity=anyscale_operator_iam_identity,
|
1085
|
+
zones=kubernetes_zones.split(",") if kubernetes_zones else [],
|
1086
|
+
)
|
1087
|
+
if compute_stack == ComputeStack.K8S
|
1088
|
+
else None,
|
1068
1089
|
)
|
1069
1090
|
|
1070
|
-
|
1071
|
-
if
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1080
|
-
|
1091
|
+
elif provider == "gcp":
|
1092
|
+
if filestore_instance_id and not file_storage_id:
|
1093
|
+
file_storage_id = filestore_instance_id
|
1094
|
+
# Keep the parameter naming ({resource}_name or {resource}_id) consistent with GCP to reduce confusion for customers
|
1095
|
+
# Check if all required parameters are provided
|
1096
|
+
# memorystore_instance_name and host_project_id are optional for GCP clouds
|
1097
|
+
required_resources = [
|
1098
|
+
(project_id, "--project-id", (ComputeStack.VM)),
|
1099
|
+
(vpc_name, "--vpc-name", (ComputeStack.VM)),
|
1100
|
+
(subnet_names, "--subnet-names", (ComputeStack.VM)),
|
1101
|
+
(
|
1102
|
+
anyscale_service_account_email,
|
1103
|
+
"--anyscale-service-account-email",
|
1104
|
+
(ComputeStack.VM),
|
1105
|
+
),
|
1106
|
+
(
|
1107
|
+
instance_service_account_email,
|
1108
|
+
"--instance-service-account-email",
|
1109
|
+
(ComputeStack.VM),
|
1110
|
+
),
|
1111
|
+
(provider_name, "--provider-name", (ComputeStack.VM)),
|
1112
|
+
(firewall_policy_names, "--firewall-policy-names", (ComputeStack.VM)),
|
1113
|
+
(
|
1114
|
+
cloud_storage_bucket_name,
|
1115
|
+
"--cloud-storage-bucket-name",
|
1116
|
+
(ComputeStack.VM, ComputeStack.K8S),
|
1117
|
+
),
|
1118
|
+
(kubernetes_zones, "--kubernetes-zones", (ComputeStack.K8S)),
|
1119
|
+
(
|
1120
|
+
anyscale_operator_iam_identity,
|
1121
|
+
"--anyscale-operator-iam-identity",
|
1122
|
+
(ComputeStack.K8S),
|
1123
|
+
),
|
1124
|
+
]
|
1125
|
+
|
1126
|
+
if not allow_optional_file_storage():
|
1127
|
+
required_resources.extend(
|
1128
|
+
[
|
1129
|
+
(file_storage_id, "--file-storage-id", (ComputeStack.VM)),
|
1130
|
+
(filestore_location, "--filestore-location", (ComputeStack.VM)),
|
1131
|
+
]
|
1132
|
+
)
|
1133
|
+
|
1134
|
+
for resource in required_resources:
|
1135
|
+
if compute_stack in resource[2] and resource[0] is None:
|
1136
|
+
missing_args.append(resource[1])
|
1137
|
+
|
1138
|
+
if len(missing_args) > 0:
|
1139
|
+
raise click.ClickException(f"Please provide a value for {missing_args}")
|
1140
|
+
|
1141
|
+
cloud_resource = CloudDeployment(
|
1142
|
+
compute_stack=compute_stack,
|
1143
|
+
provider=CloudProviders.GCP,
|
1144
|
+
region=region,
|
1145
|
+
networking_mode=NetworkingMode.PRIVATE
|
1146
|
+
if private_network
|
1147
|
+
else NetworkingMode.PUBLIC,
|
1148
|
+
object_storage=ObjectStorage(bucket_name=cloud_storage_bucket_name),
|
1149
|
+
file_storage=FileStorage(
|
1150
|
+
file_storage_id="projects/{}/locations/{}/instances/{}".format(
|
1151
|
+
project_id, filestore_location, file_storage_id
|
1152
|
+
)
|
1153
|
+
if file_storage_id
|
1154
|
+
else None,
|
1155
|
+
persistent_volume_claim=persistent_volume_claim,
|
1156
|
+
csi_ephemeral_volume_driver=csi_ephemeral_volume_driver,
|
1157
|
+
)
|
1158
|
+
if file_storage_id
|
1159
|
+
or persistent_volume_claim
|
1160
|
+
or csi_ephemeral_volume_driver
|
1161
|
+
else None,
|
1162
|
+
gcp_config=GCPConfig(
|
1163
|
+
project_id=project_id,
|
1164
|
+
host_project_id=host_project_id,
|
1165
|
+
provider_name=provider_name,
|
1166
|
+
vpc_name=vpc_name,
|
1167
|
+
subnet_names=subnet_names.split(",") if subnet_names else [],
|
1168
|
+
firewall_policy_names=firewall_policy_names.split(",")
|
1169
|
+
if firewall_policy_names
|
1170
|
+
else [],
|
1171
|
+
anyscale_service_account_email=anyscale_service_account_email,
|
1172
|
+
cluster_service_account_email=instance_service_account_email,
|
1173
|
+
memorystore_instance_name=memorystore_instance_name,
|
1174
|
+
),
|
1175
|
+
kubernetes_config=KubernetesConfig(
|
1176
|
+
anyscale_operator_iam_identity=anyscale_operator_iam_identity,
|
1177
|
+
zones=kubernetes_zones.split(",") if kubernetes_zones else [],
|
1178
|
+
)
|
1179
|
+
if compute_stack == ComputeStack.K8S
|
1180
|
+
else None,
|
1081
1181
|
)
|
1082
1182
|
|
1083
|
-
|
1084
|
-
|
1085
|
-
|
1086
|
-
"
|
1087
|
-
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1183
|
+
elif provider in ("azure", "generic"):
|
1184
|
+
# For the 'generic' provider type, for the time being, most fields are optional; only 'name', 'provider', and 'compute-stack' are required.
|
1185
|
+
if not name:
|
1186
|
+
raise click.ClickException("Please provide a value for --name.")
|
1187
|
+
|
1188
|
+
if compute_stack != ComputeStack.K8S:
|
1189
|
+
raise click.ClickException(
|
1190
|
+
"--compute-stack=k8s must be passed to register this Anyscale cloud."
|
1191
|
+
)
|
1192
|
+
|
1193
|
+
# Handle parsing / conversion of nfs_mount_targets.
|
1194
|
+
mount_targets: List[NFSMountTarget] = []
|
1195
|
+
for target in nfs_mount_target or []:
|
1196
|
+
parts = [part.strip() for part in target.split(",")]
|
1197
|
+
if len(parts) == 1:
|
1198
|
+
mount_targets.append(NFSMountTarget(address=parts[0]))
|
1199
|
+
elif len(parts) == 2:
|
1200
|
+
mount_targets.append(
|
1201
|
+
NFSMountTarget(address=parts[1], zone=parts[0])
|
1202
|
+
)
|
1203
|
+
else:
|
1204
|
+
raise click.ClickException(
|
1205
|
+
f"Invalid mount target {target}; expected (zone,address) tuple or a singular address."
|
1206
|
+
)
|
1207
|
+
|
1208
|
+
cloud_provider = (
|
1209
|
+
CloudProviders.AZURE if provider == "azure" else CloudProviders.GENERIC
|
1093
1210
|
)
|
1094
1211
|
|
1095
|
-
|
1096
|
-
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1212
|
+
cloud_resource = CloudDeployment(
|
1213
|
+
compute_stack=ComputeStack.K8S,
|
1214
|
+
provider=cloud_provider,
|
1215
|
+
region=region or "default",
|
1216
|
+
object_storage=ObjectStorage(
|
1217
|
+
bucket_name=cloud_storage_bucket_name,
|
1218
|
+
region=cloud_storage_bucket_region or region,
|
1219
|
+
endpoint=cloud_storage_bucket_endpoint,
|
1220
|
+
)
|
1221
|
+
if cloud_storage_bucket_name
|
1222
|
+
else None,
|
1223
|
+
file_storage=FileStorage(
|
1224
|
+
mount_targets=mount_targets,
|
1225
|
+
mount_path=nfs_mount_path,
|
1226
|
+
persistent_volume_claim=persistent_volume_claim,
|
1227
|
+
csi_ephemeral_volume_driver=csi_ephemeral_volume_driver,
|
1228
|
+
)
|
1229
|
+
if mount_targets
|
1230
|
+
or persistent_volume_claim
|
1231
|
+
or csi_ephemeral_volume_driver
|
1232
|
+
else None,
|
1233
|
+
kubernetes_config=KubernetesConfig(
|
1234
|
+
zones=kubernetes_zones.split(",") if kubernetes_zones else [],
|
1235
|
+
),
|
1103
1236
|
)
|
1104
1237
|
|
1105
|
-
|
1106
|
-
# project ID should start with a letter
|
1238
|
+
else:
|
1107
1239
|
raise click.ClickException(
|
1108
|
-
"
|
1240
|
+
f"Invalid Cloud provider: {provider}. Available providers are [aws, gcp, azure, generic]."
|
1109
1241
|
)
|
1110
1242
|
|
1243
|
+
if provider == "aws":
|
1244
|
+
CloudController().register_aws_cloud(
|
1245
|
+
name=name,
|
1246
|
+
cloud_resource=cloud_resource,
|
1247
|
+
functional_verify=functional_verify,
|
1248
|
+
cluster_management_stack_version=ClusterManagementStackVersions.V2,
|
1249
|
+
yes=yes,
|
1250
|
+
skip_verifications=skip_verifications,
|
1251
|
+
auto_add_user=enable_auto_add_user,
|
1252
|
+
)
|
1253
|
+
elif provider == "gcp":
|
1111
1254
|
CloudController().register_gcp_cloud(
|
1112
|
-
region=region,
|
1113
1255
|
name=name,
|
1114
|
-
|
1115
|
-
project_id=project_id,
|
1116
|
-
vpc_name=vpc_name,
|
1117
|
-
subnet_names=subnet_names.split(",") if subnet_names else [],
|
1118
|
-
filestore_instance_id=file_storage_id,
|
1119
|
-
filestore_location=filestore_location,
|
1120
|
-
anyscale_service_account_email=anyscale_service_account_email,
|
1121
|
-
instance_service_account_email=instance_service_account_email,
|
1122
|
-
# TODO (allenyin): use provider_name instead of provider_id everywhere.
|
1123
|
-
provider_id=provider_name,
|
1124
|
-
firewall_policy_names=firewall_policy_names.split(",")
|
1125
|
-
if firewall_policy_names
|
1126
|
-
else [],
|
1127
|
-
cloud_storage_bucket_name=cloud_storage_bucket_name,
|
1128
|
-
memorystore_instance_name=memorystore_instance_name,
|
1129
|
-
host_project_id=host_project_id,
|
1130
|
-
kubernetes_zones=kubernetes_zones.split(",") if kubernetes_zones else [],
|
1131
|
-
anyscale_operator_iam_identity=anyscale_operator_iam_identity,
|
1256
|
+
cloud_resource=cloud_resource,
|
1132
1257
|
functional_verify=functional_verify,
|
1133
|
-
private_network=private_network,
|
1134
1258
|
cluster_management_stack_version=ClusterManagementStackVersions.V2,
|
1135
1259
|
yes=yes,
|
1136
1260
|
skip_verifications=skip_verifications,
|
1137
1261
|
auto_add_user=enable_auto_add_user,
|
1138
|
-
persistent_volume_claim=persistent_volume_claim,
|
1139
|
-
csi_ephemeral_volume_driver=csi_ephemeral_volume_driver,
|
1140
1262
|
)
|
1141
1263
|
elif provider in ("azure", "generic"):
|
1142
|
-
# For the 'generic' provider type, for the time being, most fields are optional; only 'name', 'provider', and 'compute-stack' are required.
|
1143
|
-
if not name:
|
1144
|
-
raise click.ClickException("Please provide a value for --name.")
|
1145
|
-
|
1146
|
-
if compute_stack != ComputeStack.K8S:
|
1147
|
-
raise click.ClickException(
|
1148
|
-
"--compute-stack=k8s must be passed to register this Anyscale cloud."
|
1149
|
-
)
|
1150
|
-
|
1151
1264
|
CloudController().register_azure_or_generic_cloud(
|
1152
1265
|
name=name,
|
1153
1266
|
provider=provider,
|
1267
|
+
cloud_resource=cloud_resource,
|
1154
1268
|
auto_add_user=enable_auto_add_user,
|
1155
|
-
region=region,
|
1156
|
-
cloud_storage_bucket_name=cloud_storage_bucket_name,
|
1157
|
-
cloud_storage_bucket_endpoint=cloud_storage_bucket_endpoint,
|
1158
|
-
cloud_storage_bucket_region=cloud_storage_bucket_region,
|
1159
|
-
nfs_mount_targets=list(nfs_mount_target) if nfs_mount_target else [],
|
1160
|
-
nfs_mount_path=nfs_mount_path,
|
1161
|
-
persistent_volume_claim=persistent_volume_claim,
|
1162
|
-
csi_ephemeral_volume_driver=csi_ephemeral_volume_driver,
|
1163
|
-
kubernetes_zones=kubernetes_zones.split(",") if kubernetes_zones else [],
|
1164
|
-
anyscale_operator_iam_identity=anyscale_operator_iam_identity,
|
1165
1269
|
)
|
1166
|
-
|
1167
1270
|
else:
|
1168
1271
|
raise click.ClickException(
|
1169
|
-
f"Invalid Cloud provider: {provider}. Available providers are [aws, gcp]."
|
1272
|
+
f"Invalid Cloud provider: {provider}. Available providers are [aws, gcp, azure, generic]."
|
1170
1273
|
)
|
1171
1274
|
|
1172
1275
|
|
@@ -1325,9 +1428,10 @@ def cloud_edit( # noqa: PLR0913
|
|
1325
1428
|
)
|
1326
1429
|
if (
|
1327
1430
|
memorystore_instance_name is not None
|
1328
|
-
and
|
1329
|
-
memorystore_instance_name
|
1431
|
+
and re.search(
|
1432
|
+
"projects/.+/locations/.+/instances/.+", memorystore_instance_name
|
1330
1433
|
)
|
1434
|
+
is None
|
1331
1435
|
):
|
1332
1436
|
raise click.ClickException(
|
1333
1437
|
"Please provide a valid memorystore instance name. Example: projects/<project number>/locations/<location>/instances/<instance id>"
|