anyscale 0.26.45__py3-none-any.whl → 0.26.47__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 -2
- anyscale/_private/anyscale_client/common.py +2 -0
- anyscale/_private/anyscale_client/fake_anyscale_client.py +4 -1
- anyscale/client/README.md +4 -0
- anyscale/client/openapi_client/__init__.py +2 -0
- anyscale/client/openapi_client/api/default_api.py +247 -0
- anyscale/client/openapi_client/models/__init__.py +2 -0
- anyscale/client/openapi_client/models/clouddeployment_response.py +121 -0
- anyscale/client/openapi_client/models/collaborator_type.py +101 -0
- anyscale/client/openapi_client/models/task_table_row.py +29 -3
- anyscale/cloud_resource.py +120 -150
- anyscale/commands/cloud_commands.py +46 -3
- anyscale/commands/command_examples.py +8 -0
- anyscale/controllers/cloud_controller.py +361 -76
- anyscale/gcp_verification.py +51 -38
- anyscale/utils/s3.py +2 -2
- anyscale/utils/user_utils.py +2 -1
- anyscale/version.py +1 -1
- {anyscale-0.26.45.dist-info → anyscale-0.26.47.dist-info}/METADATA +11 -2
- {anyscale-0.26.45.dist-info → anyscale-0.26.47.dist-info}/RECORD +25 -23
- {anyscale-0.26.45.dist-info → anyscale-0.26.47.dist-info}/WHEEL +1 -1
- {anyscale-0.26.45.dist-info → anyscale-0.26.47.dist-info}/entry_points.txt +0 -0
- {anyscale-0.26.45.dist-info → anyscale-0.26.47.dist-info/licenses}/LICENSE +0 -0
- {anyscale-0.26.45.dist-info → anyscale-0.26.47.dist-info/licenses}/NOTICE +0 -0
- {anyscale-0.26.45.dist-info → anyscale-0.26.47.dist-info}/top_level.txt +0 -0
|
@@ -46,15 +46,15 @@ from anyscale.client.openapi_client.models import (
|
|
|
46
46
|
EditableCloudResourceGCP,
|
|
47
47
|
FileStorage,
|
|
48
48
|
GCPConfig,
|
|
49
|
+
GCPFileStoreConfig,
|
|
50
|
+
NetworkingMode,
|
|
49
51
|
NFSMountTarget,
|
|
52
|
+
ObjectStorage,
|
|
50
53
|
SubnetIdWithAvailabilityZoneAWS,
|
|
51
54
|
UpdateCloudWithCloudResource,
|
|
52
55
|
UpdateCloudWithCloudResourceGCP,
|
|
53
56
|
WriteCloud,
|
|
54
57
|
)
|
|
55
|
-
from anyscale.client.openapi_client.models.gcp_file_store_config import (
|
|
56
|
-
GCPFileStoreConfig,
|
|
57
|
-
)
|
|
58
58
|
from anyscale.cloud_resource import (
|
|
59
59
|
associate_aws_subnets_with_azs,
|
|
60
60
|
GCS_STORAGE_PREFIX,
|
|
@@ -1622,6 +1622,7 @@ class CloudController(BaseController):
|
|
|
1622
1622
|
return
|
|
1623
1623
|
|
|
1624
1624
|
gcp_config = GCPConfig(**deployment.gcp_config)
|
|
1625
|
+
deployment.gcp_config = gcp_config
|
|
1625
1626
|
if not deployment.file_storage and not gcp_config.memorystore_instance_name:
|
|
1626
1627
|
return
|
|
1627
1628
|
|
|
@@ -1668,7 +1669,11 @@ class CloudController(BaseController):
|
|
|
1668
1669
|
deployment.gcp_config = gcp_config
|
|
1669
1670
|
|
|
1670
1671
|
def add_cloud_deployment(
|
|
1671
|
-
self,
|
|
1672
|
+
self,
|
|
1673
|
+
cloud_name: str,
|
|
1674
|
+
spec_file: str,
|
|
1675
|
+
skip_verification: bool = False,
|
|
1676
|
+
yes: bool = False,
|
|
1672
1677
|
):
|
|
1673
1678
|
cloud_id, _ = get_cloud_id_and_name(self.api_client, cloud_name=cloud_name)
|
|
1674
1679
|
|
|
@@ -1690,6 +1695,11 @@ class CloudController(BaseController):
|
|
|
1690
1695
|
elif new_deployment.provider == CloudProviders.GCP:
|
|
1691
1696
|
self._preprocess_gcp(deployment=new_deployment)
|
|
1692
1697
|
|
|
1698
|
+
if not skip_verification and not self.verify_cloud_deployment(
|
|
1699
|
+
cloud_id=cloud_id, cloud_deployment=new_deployment
|
|
1700
|
+
):
|
|
1701
|
+
raise ClickException("Cloud deployment verification failed.")
|
|
1702
|
+
|
|
1693
1703
|
# Log an additional warning if a new deployment is being added but a deployment with the same AWS/GCP region already exists.
|
|
1694
1704
|
existing_spec = self.get_cloud_deployments(cloud_id)
|
|
1695
1705
|
existing_deployments = {
|
|
@@ -1720,11 +1730,11 @@ class CloudController(BaseController):
|
|
|
1720
1730
|
raise ClickException(f"Failed to add cloud deployment: {e}")
|
|
1721
1731
|
|
|
1722
1732
|
self.log.info(
|
|
1723
|
-
f"Successfully added deployment
|
|
1733
|
+
f"Successfully added deployment{' ' + new_deployment.name if new_deployment.name else ''} to cloud {existing_spec['name']}!"
|
|
1724
1734
|
)
|
|
1725
1735
|
|
|
1726
|
-
def update_cloud_deployments( # noqa: PLR0912
|
|
1727
|
-
self, spec_file: str, yes: bool = False,
|
|
1736
|
+
def update_cloud_deployments( # noqa: PLR0912, C901
|
|
1737
|
+
self, spec_file: str, skip_verification: bool = False, yes: bool = False,
|
|
1728
1738
|
):
|
|
1729
1739
|
# Read the spec file.
|
|
1730
1740
|
path = pathlib.Path(spec_file)
|
|
@@ -1777,17 +1787,23 @@ class CloudController(BaseController):
|
|
|
1777
1787
|
if deployment != existing_deployments[deployment.cloud_deployment_id]:
|
|
1778
1788
|
updated_deployments.append(deployment)
|
|
1779
1789
|
|
|
1780
|
-
# Log the diff and confirm.
|
|
1781
|
-
self.log.info(f"Detected the following changes:\n{diff}")
|
|
1782
|
-
|
|
1783
|
-
confirm("Would you like to proceed with updating this cloud?", yes)
|
|
1784
|
-
|
|
1785
1790
|
# Preprocess the deployments if necessary.
|
|
1786
1791
|
for deployment in updated_deployments:
|
|
1787
1792
|
if deployment.provider == CloudProviders.AWS:
|
|
1788
1793
|
self._preprocess_aws(cloud_id=spec["id"], deployment=deployment)
|
|
1789
1794
|
elif deployment.provider == CloudProviders.GCP:
|
|
1790
1795
|
self._preprocess_gcp(deployment=deployment)
|
|
1796
|
+
if not skip_verification and not self.verify_cloud_deployment(
|
|
1797
|
+
cloud_id=spec["id"], cloud_deployment=deployment
|
|
1798
|
+
):
|
|
1799
|
+
raise ClickException(
|
|
1800
|
+
f"Verification failed for cloud deployment {deployment.name}."
|
|
1801
|
+
)
|
|
1802
|
+
|
|
1803
|
+
# Log the diff and confirm.
|
|
1804
|
+
self.log.info(f"Detected the following changes:\n{diff}")
|
|
1805
|
+
|
|
1806
|
+
confirm("Would you like to proceed with updating this cloud?", yes)
|
|
1791
1807
|
|
|
1792
1808
|
# Update the deployments.
|
|
1793
1809
|
try:
|
|
@@ -1799,6 +1815,31 @@ class CloudController(BaseController):
|
|
|
1799
1815
|
|
|
1800
1816
|
self.log.info(f"Successfully updated cloud {spec['name']}!")
|
|
1801
1817
|
|
|
1818
|
+
def remove_cloud_deployment(
|
|
1819
|
+
self, cloud_name: str, deployment_name: str, yes: bool,
|
|
1820
|
+
):
|
|
1821
|
+
confirm(
|
|
1822
|
+
f"Please confirm that you would like to remove deployment {deployment_name} from cloud {cloud_name}.",
|
|
1823
|
+
yes,
|
|
1824
|
+
)
|
|
1825
|
+
|
|
1826
|
+
cloud_id, _ = get_cloud_id_and_name(self.api_client, cloud_name=cloud_name)
|
|
1827
|
+
try:
|
|
1828
|
+
with self.log.spinner("Removing cloud deployment..."):
|
|
1829
|
+
self.api_client.remove_cloud_deployment_api_v2_clouds_cloud_id_remove_deployment_delete(
|
|
1830
|
+
cloud_id=cloud_id, cloud_deployment_name=deployment_name,
|
|
1831
|
+
)
|
|
1832
|
+
except Exception as e: # noqa: BLE001
|
|
1833
|
+
raise ClickException(f"Failed to remove cloud deployment: {e}")
|
|
1834
|
+
|
|
1835
|
+
self.log.warning(
|
|
1836
|
+
"The trust policy or service account that provides access to Anyscale's control plane needs to be deleted manually if you no longer wish for Anyscale to have access."
|
|
1837
|
+
)
|
|
1838
|
+
|
|
1839
|
+
self.log.info(
|
|
1840
|
+
f"Successfully removed deployment {deployment_name} from cloud {cloud_name}!"
|
|
1841
|
+
)
|
|
1842
|
+
|
|
1802
1843
|
def get_cloud_config(
|
|
1803
1844
|
self, cloud_name: Optional[str] = None, cloud_id: Optional[str] = None,
|
|
1804
1845
|
) -> CloudDeploymentConfig:
|
|
@@ -1965,7 +2006,7 @@ class CloudController(BaseController):
|
|
|
1965
2006
|
if cloud.provider == "AWS":
|
|
1966
2007
|
if boto3_session is None:
|
|
1967
2008
|
boto3_session = boto3.Session(region_name=cloud.region)
|
|
1968
|
-
if not self.
|
|
2009
|
+
if not self.verify_aws_cloud_resources_for_create_cloud_resource(
|
|
1969
2010
|
cloud_resource=cloud_resource,
|
|
1970
2011
|
boto3_session=boto3_session,
|
|
1971
2012
|
region=cloud.region,
|
|
@@ -1987,7 +2028,7 @@ class CloudController(BaseController):
|
|
|
1987
2028
|
credentials_dict = json.loads(cloud.credentials)
|
|
1988
2029
|
project_id = credentials_dict["project_id"]
|
|
1989
2030
|
host_project_id = credentials_dict.get("host_project_id")
|
|
1990
|
-
if not self.
|
|
2031
|
+
if not self.verify_gcp_cloud_resources_from_create_cloud_resource(
|
|
1991
2032
|
cloud_resource=cloud_resource,
|
|
1992
2033
|
project_id=project_id,
|
|
1993
2034
|
host_project_id=host_project_id,
|
|
@@ -2025,10 +2066,130 @@ class CloudController(BaseController):
|
|
|
2025
2066
|
self.cloud_event_producer, self.log
|
|
2026
2067
|
).start_verification(cloud_id, cloud.provider, functions_to_verify, yes=yes)
|
|
2027
2068
|
|
|
2069
|
+
def verify_cloud_deployment(
|
|
2070
|
+
self, cloud_id: str, cloud_deployment: CloudDeployment
|
|
2071
|
+
) -> bool:
|
|
2072
|
+
if cloud_deployment.compute_stack != ComputeStack.VM:
|
|
2073
|
+
# Verification is only supported for VM stack.
|
|
2074
|
+
return True
|
|
2075
|
+
|
|
2076
|
+
if cloud_deployment.provider == CloudProviders.AWS:
|
|
2077
|
+
return self.verify_aws_cloud_resources_for_cloud_deployment(
|
|
2078
|
+
cloud_id=cloud_id, cloud_deployment=cloud_deployment,
|
|
2079
|
+
)
|
|
2080
|
+
elif cloud_deployment.provider == CloudProviders.GCP:
|
|
2081
|
+
return self.verify_gcp_cloud_resources_from_cloud_deployment(
|
|
2082
|
+
cloud_id=cloud_id, cloud_deployment=cloud_deployment,
|
|
2083
|
+
)
|
|
2084
|
+
else:
|
|
2085
|
+
raise ValueError(f"Unsupported cloud provider: {cloud_deployment.provider}")
|
|
2086
|
+
|
|
2087
|
+
def verify_aws_cloud_resources_for_cloud_deployment(
|
|
2088
|
+
self, cloud_id: str, cloud_deployment: CloudDeployment,
|
|
2089
|
+
) -> bool:
|
|
2090
|
+
assert cloud_deployment.region
|
|
2091
|
+
assert cloud_deployment.aws_config
|
|
2092
|
+
aws_config = cloud_deployment.aws_config
|
|
2093
|
+
file_storage = cloud_deployment.file_storage
|
|
2094
|
+
object_storage = (
|
|
2095
|
+
ObjectStorage(**cloud_deployment.object_storage)
|
|
2096
|
+
if cloud_deployment.object_storage
|
|
2097
|
+
else None
|
|
2098
|
+
)
|
|
2099
|
+
|
|
2100
|
+
return self.verify_aws_cloud_resources(
|
|
2101
|
+
aws_vpc_id=aws_config.vpc_id,
|
|
2102
|
+
aws_subnet_ids=aws_config.subnet_ids or [],
|
|
2103
|
+
aws_control_plane_role=aws_config.anyscale_iam_role_id,
|
|
2104
|
+
aws_data_plane_role=aws_config.cluster_iam_role_id,
|
|
2105
|
+
aws_security_groups=aws_config.security_group_ids,
|
|
2106
|
+
aws_s3_id=object_storage.bucket_name[len(S3_STORAGE_PREFIX) :]
|
|
2107
|
+
if object_storage and object_storage.bucket_name
|
|
2108
|
+
else None,
|
|
2109
|
+
aws_efs_id=file_storage.file_storage_id if file_storage else None,
|
|
2110
|
+
aws_efs_mount_target_ip=file_storage.mount_targets[0].address
|
|
2111
|
+
if file_storage and file_storage.mount_targets
|
|
2112
|
+
else None,
|
|
2113
|
+
aws_cloudformation_stack_id=None,
|
|
2114
|
+
memorydb_cluster_config=AWSMemoryDBClusterConfig(
|
|
2115
|
+
id=aws_config.memorydb_cluster_name,
|
|
2116
|
+
endpoint=aws_config.memorydb_cluster_endpoint,
|
|
2117
|
+
),
|
|
2118
|
+
boto3_session=boto3.Session(region_name=cloud_deployment.region),
|
|
2119
|
+
region=cloud_deployment.region,
|
|
2120
|
+
cloud_id=cloud_id,
|
|
2121
|
+
is_bring_your_own_resource=True,
|
|
2122
|
+
is_private_network=cloud_deployment.networking_mode
|
|
2123
|
+
== NetworkingMode.PRIVATE,
|
|
2124
|
+
)
|
|
2125
|
+
|
|
2126
|
+
def verify_aws_cloud_resources_for_create_cloud_resource( # noqa: PLR0913
|
|
2127
|
+
self,
|
|
2128
|
+
cloud_resource: CreateCloudResource,
|
|
2129
|
+
boto3_session: boto3.Session,
|
|
2130
|
+
region: str,
|
|
2131
|
+
is_private_network: bool,
|
|
2132
|
+
cloud_id: str,
|
|
2133
|
+
is_bring_your_own_resource: bool = False,
|
|
2134
|
+
ignore_capacity_errors: bool = IGNORE_CAPACITY_ERRORS,
|
|
2135
|
+
logger: CloudSetupLogger = None,
|
|
2136
|
+
strict: bool = False,
|
|
2137
|
+
_use_strict_iam_permissions: bool = False, # This should only be used in testing.
|
|
2138
|
+
) -> bool:
|
|
2139
|
+
subnet_ids = (
|
|
2140
|
+
[
|
|
2141
|
+
subnet_id_with_az.subnet_id
|
|
2142
|
+
for subnet_id_with_az in cloud_resource.aws_subnet_ids_with_availability_zones
|
|
2143
|
+
]
|
|
2144
|
+
if cloud_resource.aws_subnet_ids_with_availability_zones
|
|
2145
|
+
else []
|
|
2146
|
+
)
|
|
2147
|
+
aws_control_plane_role = (
|
|
2148
|
+
cloud_resource.aws_iam_role_arns[0]
|
|
2149
|
+
if cloud_resource.aws_iam_role_arns
|
|
2150
|
+
else None
|
|
2151
|
+
)
|
|
2152
|
+
aws_data_plane_role = (
|
|
2153
|
+
cloud_resource.aws_iam_role_arns[1]
|
|
2154
|
+
if cloud_resource.aws_iam_role_arns
|
|
2155
|
+
and len(cloud_resource.aws_iam_role_arns) > 1
|
|
2156
|
+
else None
|
|
2157
|
+
)
|
|
2158
|
+
return self.verify_aws_cloud_resources(
|
|
2159
|
+
aws_vpc_id=cloud_resource.aws_vpc_id,
|
|
2160
|
+
aws_subnet_ids=subnet_ids,
|
|
2161
|
+
aws_control_plane_role=aws_control_plane_role,
|
|
2162
|
+
aws_data_plane_role=aws_data_plane_role,
|
|
2163
|
+
aws_security_groups=cloud_resource.aws_security_groups,
|
|
2164
|
+
aws_s3_id=cloud_resource.aws_s3_id,
|
|
2165
|
+
aws_efs_id=cloud_resource.aws_efs_id,
|
|
2166
|
+
aws_efs_mount_target_ip=cloud_resource.aws_efs_mount_target_ip,
|
|
2167
|
+
aws_cloudformation_stack_id=cloud_resource.aws_cloudformation_stack_id,
|
|
2168
|
+
memorydb_cluster_config=cloud_resource.memorydb_cluster_config,
|
|
2169
|
+
boto3_session=boto3_session,
|
|
2170
|
+
region=region,
|
|
2171
|
+
cloud_id=cloud_id,
|
|
2172
|
+
is_bring_your_own_resource=is_bring_your_own_resource,
|
|
2173
|
+
ignore_capacity_errors=ignore_capacity_errors,
|
|
2174
|
+
logger=logger,
|
|
2175
|
+
is_private_network=is_private_network,
|
|
2176
|
+
strict=strict,
|
|
2177
|
+
_use_strict_iam_permissions=_use_strict_iam_permissions,
|
|
2178
|
+
)
|
|
2179
|
+
|
|
2028
2180
|
def verify_aws_cloud_resources(
|
|
2029
2181
|
self,
|
|
2030
2182
|
*,
|
|
2031
|
-
|
|
2183
|
+
aws_vpc_id: Optional[str],
|
|
2184
|
+
aws_subnet_ids: List[str],
|
|
2185
|
+
aws_control_plane_role: Optional[str],
|
|
2186
|
+
aws_data_plane_role: Optional[str],
|
|
2187
|
+
aws_security_groups: Optional[List[str]],
|
|
2188
|
+
aws_s3_id: Optional[str],
|
|
2189
|
+
aws_efs_id: Optional[str],
|
|
2190
|
+
aws_efs_mount_target_ip: Optional[str],
|
|
2191
|
+
aws_cloudformation_stack_id: Optional[str],
|
|
2192
|
+
memorydb_cluster_config: Optional[AWSMemoryDBClusterConfig],
|
|
2032
2193
|
boto3_session: boto3.Session,
|
|
2033
2194
|
region: str,
|
|
2034
2195
|
is_private_network: bool,
|
|
@@ -2038,19 +2199,21 @@ class CloudController(BaseController):
|
|
|
2038
2199
|
logger: CloudSetupLogger = None,
|
|
2039
2200
|
strict: bool = False,
|
|
2040
2201
|
_use_strict_iam_permissions: bool = False, # This should only be used in testing.
|
|
2041
|
-
):
|
|
2202
|
+
) -> bool:
|
|
2042
2203
|
if not logger:
|
|
2043
2204
|
logger = self.log
|
|
2044
2205
|
|
|
2045
2206
|
verify_aws_vpc_result = verify_aws_vpc(
|
|
2046
|
-
|
|
2207
|
+
aws_vpc_id=aws_vpc_id,
|
|
2047
2208
|
boto3_session=boto3_session,
|
|
2048
2209
|
logger=logger,
|
|
2049
2210
|
ignore_capacity_errors=ignore_capacity_errors,
|
|
2050
2211
|
strict=strict,
|
|
2051
2212
|
)
|
|
2213
|
+
|
|
2052
2214
|
verify_aws_subnets_result = verify_aws_subnets(
|
|
2053
|
-
|
|
2215
|
+
aws_vpc_id=aws_vpc_id,
|
|
2216
|
+
aws_subnet_ids=aws_subnet_ids,
|
|
2054
2217
|
region=region,
|
|
2055
2218
|
logger=logger,
|
|
2056
2219
|
ignore_capacity_errors=ignore_capacity_errors,
|
|
@@ -2061,8 +2224,10 @@ class CloudController(BaseController):
|
|
|
2061
2224
|
anyscale_aws_account = (
|
|
2062
2225
|
self.api_client.get_anyscale_aws_account_api_v2_clouds_anyscale_aws_account_get().result.anyscale_aws_account
|
|
2063
2226
|
)
|
|
2227
|
+
|
|
2064
2228
|
verify_aws_iam_roles_result = verify_aws_iam_roles(
|
|
2065
|
-
|
|
2229
|
+
control_plane_role=aws_control_plane_role,
|
|
2230
|
+
data_plane_role=aws_data_plane_role,
|
|
2066
2231
|
boto3_session=boto3_session,
|
|
2067
2232
|
anyscale_aws_account=anyscale_aws_account,
|
|
2068
2233
|
logger=logger,
|
|
@@ -2071,22 +2236,29 @@ class CloudController(BaseController):
|
|
|
2071
2236
|
_use_strict_iam_permissions=_use_strict_iam_permissions,
|
|
2072
2237
|
)
|
|
2073
2238
|
verify_aws_security_groups_result = verify_aws_security_groups(
|
|
2074
|
-
|
|
2239
|
+
aws_security_group_ids=aws_security_groups,
|
|
2075
2240
|
boto3_session=boto3_session,
|
|
2076
2241
|
logger=logger,
|
|
2077
2242
|
strict=strict,
|
|
2078
2243
|
)
|
|
2079
2244
|
verify_aws_s3_result = verify_aws_s3(
|
|
2080
|
-
|
|
2245
|
+
aws_s3_id=aws_s3_id,
|
|
2246
|
+
control_plane_role=aws_control_plane_role,
|
|
2247
|
+
data_plane_role=aws_data_plane_role,
|
|
2081
2248
|
boto3_session=boto3_session,
|
|
2082
2249
|
region=region,
|
|
2083
2250
|
logger=logger,
|
|
2084
2251
|
strict=strict,
|
|
2085
2252
|
)
|
|
2086
2253
|
verify_aws_efs_result = True
|
|
2087
|
-
if
|
|
2254
|
+
if aws_efs_id:
|
|
2088
2255
|
verify_aws_efs_result = verify_aws_efs(
|
|
2089
|
-
|
|
2256
|
+
aws_efs_id=aws_efs_id,
|
|
2257
|
+
aws_efs_mount_target_ips=[aws_efs_mount_target_ip]
|
|
2258
|
+
if aws_efs_mount_target_ip
|
|
2259
|
+
else [],
|
|
2260
|
+
aws_subnet_ids=aws_subnet_ids,
|
|
2261
|
+
aws_security_groups=aws_security_groups,
|
|
2090
2262
|
boto3_session=boto3_session,
|
|
2091
2263
|
logger=logger,
|
|
2092
2264
|
strict=strict,
|
|
@@ -2095,14 +2267,19 @@ class CloudController(BaseController):
|
|
|
2095
2267
|
verify_aws_cloudformation_stack_result = True
|
|
2096
2268
|
if not is_bring_your_own_resource:
|
|
2097
2269
|
verify_aws_cloudformation_stack_result = verify_aws_cloudformation_stack(
|
|
2098
|
-
|
|
2270
|
+
aws_cloudformation_stack_id=aws_cloudformation_stack_id,
|
|
2099
2271
|
boto3_session=boto3_session,
|
|
2100
2272
|
logger=logger,
|
|
2101
2273
|
strict=strict,
|
|
2102
2274
|
)
|
|
2103
|
-
if
|
|
2275
|
+
if memorydb_cluster_config is not None:
|
|
2276
|
+
assert aws_security_groups
|
|
2277
|
+
assert aws_vpc_id
|
|
2104
2278
|
verify_aws_memorydb_cluster_result = verify_aws_memorydb_cluster(
|
|
2105
|
-
|
|
2279
|
+
memorydb_cluster_config=memorydb_cluster_config,
|
|
2280
|
+
aws_security_groups=aws_security_groups,
|
|
2281
|
+
aws_vpc_id=aws_vpc_id,
|
|
2282
|
+
aws_subnet_ids=aws_subnet_ids,
|
|
2106
2283
|
boto3_session=boto3_session,
|
|
2107
2284
|
logger=logger,
|
|
2108
2285
|
strict=strict,
|
|
@@ -2122,11 +2299,11 @@ class CloudController(BaseController):
|
|
|
2122
2299
|
f"s3: {self._passed_or_failed_str_from_bool(verify_aws_s3_result)}",
|
|
2123
2300
|
f"cloudformation stack: {self._passed_or_failed_str_from_bool(verify_aws_cloudformation_stack_result) if not is_bring_your_own_resource else 'N/A'}",
|
|
2124
2301
|
]
|
|
2125
|
-
if
|
|
2302
|
+
if aws_efs_id:
|
|
2126
2303
|
verification_result_summary.append(
|
|
2127
2304
|
f"efs: {self._passed_or_failed_str_from_bool(verify_aws_efs_result)}"
|
|
2128
2305
|
)
|
|
2129
|
-
if
|
|
2306
|
+
if memorydb_cluster_config is not None:
|
|
2130
2307
|
verification_result_summary.append(
|
|
2131
2308
|
f"memorydb cluster: {self._passed_or_failed_str_from_bool(verify_aws_memorydb_cluster_result)}"
|
|
2132
2309
|
)
|
|
@@ -2536,14 +2713,17 @@ class CloudController(BaseController):
|
|
|
2536
2713
|
with self.log.spinner("Verifying cloud resources...") as spinner:
|
|
2537
2714
|
if boto3_session is None:
|
|
2538
2715
|
boto3_session = boto3.Session(region_name=region)
|
|
2539
|
-
if
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2716
|
+
if (
|
|
2717
|
+
not skip_verifications
|
|
2718
|
+
and not self.verify_aws_cloud_resources_for_create_cloud_resource(
|
|
2719
|
+
cloud_resource=create_cloud_resource,
|
|
2720
|
+
boto3_session=boto3_session,
|
|
2721
|
+
region=region,
|
|
2722
|
+
is_bring_your_own_resource=True,
|
|
2723
|
+
is_private_network=private_network,
|
|
2724
|
+
cloud_id=cloud_id,
|
|
2725
|
+
logger=CloudSetupLogger(spinner_manager=spinner),
|
|
2726
|
+
)
|
|
2547
2727
|
):
|
|
2548
2728
|
raise ClickException(
|
|
2549
2729
|
"Please make sure all the resources provided meet the requirements and try again."
|
|
@@ -2647,7 +2827,42 @@ class CloudController(BaseController):
|
|
|
2647
2827
|
self.cloud_event_producer, self.log
|
|
2648
2828
|
).start_verification(cloud_id, CloudProviders.AWS, functions_to_verify, yes)
|
|
2649
2829
|
|
|
2650
|
-
def
|
|
2830
|
+
def verify_gcp_cloud_resources_from_cloud_deployment(
|
|
2831
|
+
self, cloud_id: str, cloud_deployment: CloudDeployment,
|
|
2832
|
+
) -> bool:
|
|
2833
|
+
assert cloud_deployment.region
|
|
2834
|
+
assert cloud_deployment.gcp_config
|
|
2835
|
+
gcp_config = cloud_deployment.gcp_config
|
|
2836
|
+
file_storage = cloud_deployment.file_storage
|
|
2837
|
+
object_storage = (
|
|
2838
|
+
ObjectStorage(**cloud_deployment.object_storage)
|
|
2839
|
+
if cloud_deployment.object_storage
|
|
2840
|
+
else None
|
|
2841
|
+
)
|
|
2842
|
+
return self.verify_gcp_cloud_resources(
|
|
2843
|
+
project_id=gcp_config.project_id,
|
|
2844
|
+
vpc_id=gcp_config.vpc_name,
|
|
2845
|
+
subnet_ids=gcp_config.subnet_names,
|
|
2846
|
+
firewall_policy_ids=gcp_config.firewall_policy_names,
|
|
2847
|
+
control_plane_service_account=gcp_config.anyscale_service_account_email,
|
|
2848
|
+
data_plane_service_account=gcp_config.cluster_service_account_email,
|
|
2849
|
+
cloud_storage_bucket_name=object_storage.bucket_name[
|
|
2850
|
+
len(GCS_STORAGE_PREFIX) :
|
|
2851
|
+
]
|
|
2852
|
+
if object_storage and object_storage.bucket_name
|
|
2853
|
+
else None
|
|
2854
|
+
if object_storage
|
|
2855
|
+
else None,
|
|
2856
|
+
filestore_instance_name=file_storage.file_storage_id
|
|
2857
|
+
if file_storage
|
|
2858
|
+
else None,
|
|
2859
|
+
memorystore_instance_name=gcp_config.memorystore_instance_name,
|
|
2860
|
+
region=cloud_deployment.region,
|
|
2861
|
+
cloud_id=cloud_id,
|
|
2862
|
+
host_project_id=gcp_config.host_project_id,
|
|
2863
|
+
)
|
|
2864
|
+
|
|
2865
|
+
def verify_gcp_cloud_resources_from_create_cloud_resource(
|
|
2651
2866
|
self,
|
|
2652
2867
|
*,
|
|
2653
2868
|
cloud_resource: CreateCloudResourceGCP,
|
|
@@ -2659,6 +2874,49 @@ class CloudController(BaseController):
|
|
|
2659
2874
|
factory: Any = None,
|
|
2660
2875
|
strict: bool = False,
|
|
2661
2876
|
is_private_service_cloud: bool = False,
|
|
2877
|
+
) -> bool:
|
|
2878
|
+
return self.verify_gcp_cloud_resources(
|
|
2879
|
+
project_id=project_id,
|
|
2880
|
+
vpc_id=cloud_resource.gcp_vpc_id,
|
|
2881
|
+
subnet_ids=cloud_resource.gcp_subnet_ids,
|
|
2882
|
+
firewall_policy_ids=cloud_resource.gcp_firewall_policy_ids,
|
|
2883
|
+
control_plane_service_account=cloud_resource.gcp_anyscale_iam_service_account_email,
|
|
2884
|
+
data_plane_service_account=cloud_resource.gcp_cluster_node_service_account_email,
|
|
2885
|
+
cloud_storage_bucket_name=cloud_resource.gcp_cloud_storage_bucket_id,
|
|
2886
|
+
filestore_instance_name=cloud_resource.gcp_filestore_config.instance_name
|
|
2887
|
+
if cloud_resource.gcp_filestore_config
|
|
2888
|
+
else None,
|
|
2889
|
+
memorystore_instance_name=cloud_resource.memorystore_instance_config.name
|
|
2890
|
+
if cloud_resource.memorystore_instance_config
|
|
2891
|
+
else None,
|
|
2892
|
+
region=region,
|
|
2893
|
+
cloud_id=cloud_id,
|
|
2894
|
+
yes=yes,
|
|
2895
|
+
host_project_id=host_project_id,
|
|
2896
|
+
factory=factory,
|
|
2897
|
+
strict=strict,
|
|
2898
|
+
is_private_service_cloud=is_private_service_cloud,
|
|
2899
|
+
)
|
|
2900
|
+
|
|
2901
|
+
def verify_gcp_cloud_resources(
|
|
2902
|
+
self,
|
|
2903
|
+
*,
|
|
2904
|
+
project_id: str,
|
|
2905
|
+
vpc_id: Optional[str],
|
|
2906
|
+
subnet_ids: Optional[List[str]],
|
|
2907
|
+
firewall_policy_ids: Optional[List[str]],
|
|
2908
|
+
control_plane_service_account: Optional[str],
|
|
2909
|
+
data_plane_service_account: Optional[str],
|
|
2910
|
+
cloud_storage_bucket_name: Optional[str],
|
|
2911
|
+
filestore_instance_name: Optional[str],
|
|
2912
|
+
memorystore_instance_name: Optional[str],
|
|
2913
|
+
region: str,
|
|
2914
|
+
cloud_id: str,
|
|
2915
|
+
yes: bool = False,
|
|
2916
|
+
host_project_id: Optional[str] = None,
|
|
2917
|
+
factory: Any = None,
|
|
2918
|
+
strict: bool = False,
|
|
2919
|
+
is_private_service_cloud: bool = False,
|
|
2662
2920
|
) -> bool:
|
|
2663
2921
|
gcp_utils = try_import_gcp_utils()
|
|
2664
2922
|
if not factory:
|
|
@@ -2672,51 +2930,78 @@ class CloudController(BaseController):
|
|
|
2672
2930
|
with self.log.spinner("Verifying cloud resources...") as spinner:
|
|
2673
2931
|
gcp_logger = GCPLogger(self.log, project_id, spinner, yes)
|
|
2674
2932
|
verify_gcp_project_result = verify_lib.verify_gcp_project(
|
|
2675
|
-
factory,
|
|
2933
|
+
factory=factory,
|
|
2934
|
+
project_id=project_id,
|
|
2935
|
+
enable_memorystore_api=memorystore_instance_name is not None,
|
|
2936
|
+
logger=gcp_logger,
|
|
2937
|
+
strict=strict,
|
|
2676
2938
|
)
|
|
2677
2939
|
verify_gcp_access_service_account_result = verify_lib.verify_gcp_access_service_account(
|
|
2678
|
-
factory,
|
|
2940
|
+
factory=factory,
|
|
2941
|
+
anyscale_access_service_account=control_plane_service_account,
|
|
2942
|
+
project_id=project_id,
|
|
2943
|
+
logger=gcp_logger,
|
|
2679
2944
|
)
|
|
2680
2945
|
verify_gcp_dataplane_service_account_result = verify_lib.verify_gcp_dataplane_service_account(
|
|
2681
|
-
factory,
|
|
2946
|
+
factory=factory,
|
|
2947
|
+
service_account=data_plane_service_account,
|
|
2948
|
+
project_id=project_id,
|
|
2949
|
+
logger=gcp_logger,
|
|
2950
|
+
strict=strict,
|
|
2682
2951
|
)
|
|
2683
2952
|
verify_gcp_networking_result = verify_lib.verify_gcp_networking(
|
|
2684
|
-
factory,
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2953
|
+
factory=factory,
|
|
2954
|
+
vpc_name=vpc_id,
|
|
2955
|
+
subnet_ids=subnet_ids,
|
|
2956
|
+
project_id=network_project_id,
|
|
2957
|
+
cloud_region=region,
|
|
2958
|
+
logger=gcp_logger,
|
|
2689
2959
|
strict=strict,
|
|
2690
2960
|
is_private_service_cloud=is_private_service_cloud,
|
|
2691
2961
|
)
|
|
2692
2962
|
verify_firewall_policy_result = verify_lib.verify_firewall_policy(
|
|
2693
|
-
factory,
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2963
|
+
factory=factory,
|
|
2964
|
+
firewall_policy_ids=firewall_policy_ids,
|
|
2965
|
+
vpc_name=vpc_id,
|
|
2966
|
+
subnet_ids=subnet_ids,
|
|
2967
|
+
project_id=network_project_id,
|
|
2968
|
+
cloud_region=region,
|
|
2969
|
+
use_shared_vpc=use_shared_vpc,
|
|
2970
|
+
is_private_service_cloud=is_private_service_cloud,
|
|
2971
|
+
logger=gcp_logger,
|
|
2700
2972
|
strict=strict,
|
|
2701
2973
|
)
|
|
2702
2974
|
verify_cloud_storage_result = verify_lib.verify_cloud_storage(
|
|
2703
|
-
factory
|
|
2975
|
+
factory=factory,
|
|
2976
|
+
bucket_name=cloud_storage_bucket_name,
|
|
2977
|
+
controlplane_service_account=control_plane_service_account,
|
|
2978
|
+
dataplane_service_account=data_plane_service_account,
|
|
2979
|
+
project_id=project_id,
|
|
2980
|
+
cloud_region=region,
|
|
2981
|
+
logger=gcp_logger,
|
|
2982
|
+
strict=strict,
|
|
2704
2983
|
)
|
|
2705
2984
|
verify_anyscale_access_result = verify_anyscale_access(
|
|
2706
2985
|
self.api_client, cloud_id, CloudProviders.GCP, self.log
|
|
2707
2986
|
)
|
|
2708
2987
|
verify_filestore_result = True
|
|
2709
|
-
if
|
|
2710
|
-
cloud_resource.gcp_filestore_config
|
|
2711
|
-
and cloud_resource.gcp_filestore_config.instance_name
|
|
2712
|
-
):
|
|
2988
|
+
if filestore_instance_name:
|
|
2713
2989
|
verify_filestore_result = verify_lib.verify_filestore(
|
|
2714
|
-
factory,
|
|
2990
|
+
factory=factory,
|
|
2991
|
+
file_store_instance_name=filestore_instance_name,
|
|
2992
|
+
vpc_name=vpc_id,
|
|
2993
|
+
cloud_region=region,
|
|
2994
|
+
logger=gcp_logger,
|
|
2995
|
+
strict=strict,
|
|
2715
2996
|
)
|
|
2716
2997
|
verify_memorystore_result = True
|
|
2717
|
-
if
|
|
2998
|
+
if memorystore_instance_name:
|
|
2718
2999
|
verify_memorystore_result = verify_lib.verify_memorystore(
|
|
2719
|
-
factory
|
|
3000
|
+
factory=factory,
|
|
3001
|
+
redis_instance_name=memorystore_instance_name,
|
|
3002
|
+
cloud_vpc_name=vpc_id,
|
|
3003
|
+
logger=gcp_logger,
|
|
3004
|
+
strict=strict,
|
|
2720
3005
|
)
|
|
2721
3006
|
|
|
2722
3007
|
verification_results = [
|
|
@@ -2730,14 +3015,11 @@ class CloudController(BaseController):
|
|
|
2730
3015
|
f"cloud storage: {self._passed_or_failed_str_from_bool(verify_cloud_storage_result)}",
|
|
2731
3016
|
]
|
|
2732
3017
|
|
|
2733
|
-
if
|
|
2734
|
-
cloud_resource.gcp_filestore_config
|
|
2735
|
-
and cloud_resource.gcp_filestore_config.instance_name
|
|
2736
|
-
):
|
|
3018
|
+
if filestore_instance_name:
|
|
2737
3019
|
verification_results.append(
|
|
2738
3020
|
f"filestore: {self._passed_or_failed_str_from_bool(verify_filestore_result)}"
|
|
2739
3021
|
)
|
|
2740
|
-
if
|
|
3022
|
+
if memorystore_instance_name:
|
|
2741
3023
|
verification_results.append(
|
|
2742
3024
|
f"memorystore: {self._passed_or_failed_str_from_bool(verify_memorystore_result)}"
|
|
2743
3025
|
)
|
|
@@ -2940,15 +3222,18 @@ class CloudController(BaseController):
|
|
|
2940
3222
|
# Verification is only performed for VM compute stack.
|
|
2941
3223
|
# TODO (shomilj): Add verification to the K8S compute stack as well.
|
|
2942
3224
|
if compute_stack == ComputeStack.VM:
|
|
2943
|
-
if
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
3225
|
+
if (
|
|
3226
|
+
not skip_verifications
|
|
3227
|
+
and not self.verify_gcp_cloud_resources_from_create_cloud_resource(
|
|
3228
|
+
cloud_resource=create_cloud_resource_gcp,
|
|
3229
|
+
project_id=project_id,
|
|
3230
|
+
host_project_id=host_project_id,
|
|
3231
|
+
region=region,
|
|
3232
|
+
cloud_id=cloud_id,
|
|
3233
|
+
yes=yes,
|
|
3234
|
+
factory=factory,
|
|
3235
|
+
is_private_service_cloud=is_private_service_cloud,
|
|
3236
|
+
)
|
|
2952
3237
|
):
|
|
2953
3238
|
raise ClickException(
|
|
2954
3239
|
"Please make sure all the resources provided meet the requirements and try again."
|
|
@@ -3545,7 +3830,7 @@ class CloudController(BaseController):
|
|
|
3545
3830
|
if memorydb_cluster_id:
|
|
3546
3831
|
new_cloud_resource.memorydb_cluster_config = memorydb_cluster_config
|
|
3547
3832
|
|
|
3548
|
-
if not self.
|
|
3833
|
+
if not self.verify_aws_cloud_resources_for_create_cloud_resource(
|
|
3549
3834
|
cloud_resource=new_cloud_resource,
|
|
3550
3835
|
boto3_session=boto3_session,
|
|
3551
3836
|
region=cloud.region,
|
|
@@ -3892,7 +4177,7 @@ class CloudController(BaseController):
|
|
|
3892
4177
|
)
|
|
3893
4178
|
if memorystore_instance_config:
|
|
3894
4179
|
new_cloud_resource.memorystore_instance_config = memorystore_instance_config
|
|
3895
|
-
if not self.
|
|
4180
|
+
if not self.verify_gcp_cloud_resources_from_create_cloud_resource(
|
|
3896
4181
|
cloud_resource=new_cloud_resource,
|
|
3897
4182
|
project_id=project_id,
|
|
3898
4183
|
host_project_id=host_project_id,
|