Skip to content

Commit

Permalink
Decouple region support from CLI release
Browse files Browse the repository at this point in the history
Remove the constant variable and move the content to a file. This file will be uploaded to official S3 buckets during CLI release and/or region expansion.

If the file in S3 is not accessible, the code falls back to the local file. The file in S3 is not accessible when we are developing new versions or network access is limited

Signed-off-by: Hanwen <[email protected]>
  • Loading branch information
hanwen-cluster authored and hanwen-pcluste committed Jun 6, 2024
1 parent fcb798c commit ff481cd
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 38 deletions.
14 changes: 9 additions & 5 deletions cli/src/pcluster/api/controllers/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,26 @@
)
from pcluster.aws.common import BadRequestError, LimitExceededError, StackNotFoundError, get_region
from pcluster.config.common import AllValidatorsSuppressor, TypeMatchValidatorsSuppressor, ValidatorSuppressor
from pcluster.constants import SUPPORTED_REGIONS, UNSUPPORTED_OPERATIONS_MAP, Operation
from pcluster.constants import UNSUPPORTED_OPERATIONS_MAP, Operation
from pcluster.models.cluster import Cluster
from pcluster.models.common import BadRequest, Conflict, LimitExceeded, NotFound, parse_config
from pcluster.utils import get_installed_version, to_utc_datetime
from pcluster.utils import get_installed_version, retrieve_supported_regions, to_utc_datetime

LOGGER = logging.getLogger(__name__)


def _set_region(region):
if not region:
raise BadRequestException("region needs to be set")
if region not in SUPPORTED_REGIONS:
raise BadRequestException(f"invalid or unsupported region '{region}'")

region_backup = os.environ.get("AWS_DEFAULT_REGION")
LOGGER.info("Setting AWS Region to %s", region)
os.environ["AWS_DEFAULT_REGION"] = region
if region not in retrieve_supported_regions():
if region_backup:
os.environ["AWS_DEFAULT_REGION"] = region_backup
else:
del os.environ["AWS_DEFAULT_REGION"]
raise BadRequestException(f"invalid or unsupported region '{region}'")


def configure_aws_region_from_config(region: Union[None, str], config_str: str):
Expand Down
6 changes: 4 additions & 2 deletions cli/src/pcluster/cli/commands/configure/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

from pcluster.aws.aws_api import AWSApi
from pcluster.aws.common import AWSClientError
from pcluster.constants import SUPPORTED_REGIONS
from pcluster.utils import retrieve_supported_regions

LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -201,7 +201,9 @@ def get_rows_and_header(items):
def get_regions():
ec2 = boto3.client("ec2")
regions = ec2.describe_regions().get("Regions")
regions = [region.get("RegionName") for region in regions if region.get("RegionName") in SUPPORTED_REGIONS]
regions = [
region.get("RegionName") for region in regions if region.get("RegionName") in retrieve_supported_regions()
]
regions.sort()
return regions

Expand Down
29 changes: 0 additions & 29 deletions cli/src/pcluster/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,35 +198,6 @@

PCLUSTER_S3_BUCKET_VERSION = "v1"

SUPPORTED_REGIONS = [
"af-south-1",
"ap-east-1",
"ap-northeast-1",
"ap-northeast-2",
"ap-south-1",
"ap-southeast-1",
"ap-southeast-2",
"ca-central-1",
"cn-north-1",
"cn-northwest-1",
"eu-central-1",
"eu-north-1",
"eu-south-1",
"eu-west-1",
"eu-west-2",
"eu-west-3",
"il-central-1",
"me-south-1",
"sa-east-1",
"us-east-1",
"us-east-2",
"us-iso-east-1",
"us-isob-east-1",
"us-gov-east-1",
"us-gov-west-1",
"us-west-1",
"us-west-2",
]

# see https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html
NODEJS_MIN_VERSION = "10.13.0"
Expand Down
27 changes: 27 additions & 0 deletions cli/src/pcluster/resources/supported-regions
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
af-south-1
ap-east-1
ap-northeast-1
ap-northeast-2
ap-south-1
ap-southeast-1
ap-southeast-2
ca-central-1
cn-north-1
cn-northwest-1
eu-central-1
eu-north-1
eu-south-1
eu-west-1
eu-west-2
eu-west-3
il-central-1
me-south-1
sa-east-1
us-east-1
us-east-2
us-iso-east-1
us-isob-east-1
us-gov-east-1
us-gov-west-1
us-west-1
us-west-2
21 changes: 21 additions & 0 deletions cli/src/pcluster/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,16 @@
import string
import sys
import time
import urllib
import zipfile
from concurrent.futures import ThreadPoolExecutor
from io import BytesIO
from shlex import quote
from typing import Callable, NoReturn
from urllib.error import URLError
from urllib.parse import urlparse

import boto3
import dateutil.parser
import pkg_resources
import yaml
Expand Down Expand Up @@ -558,3 +561,21 @@ async def wrapper(self, *args, **kwargs):
)

return wrapper


def retrieve_supported_regions():
"""Retrieve the list of supported regions."""
if not hasattr(retrieve_supported_regions, "cache"):
region = boto3.Session().region_name or "us-east-1"
try:
url = "https://{region}-aws-parallelcluster.s3.{region}.{aws_domain}/supported-regions".format(
region=region,
aws_domain=get_partition(region),
)
with urllib.request.urlopen(url) as f: # nosec B310 nosemgrep
retrieve_supported_regions.cache = f.read().decode("utf-8").split("\n")
except URLError:
# When the file is not found on the URL, use local file. This is useful when developing new versions.
with open(pkg_resources.resource_filename(__name__, "/resources/supported-regions"), encoding="utf-8") as f:
retrieve_supported_regions.cache = f.read().split("\n")
return retrieve_supported_regions.cache
4 changes: 2 additions & 2 deletions cli/src/pcluster/validators/cluster_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
RETAIN_POLICY,
SCHEDULERS_SUPPORTING_IMDS_SECURED,
SUPPORTED_OSES,
SUPPORTED_REGIONS,
SUPPORTED_SCHEDULERS,
)
from pcluster.launch_template_utils import _LaunchTemplateBuilder
Expand All @@ -45,6 +44,7 @@
get_supported_os_for_architecture,
get_supported_os_for_scheduler,
remove_none_values,
retrieve_supported_regions,
)
from pcluster.validators.common import FailureLevel, Validator

Expand Down Expand Up @@ -117,7 +117,7 @@ class RegionValidator(Validator):
"""Region validator."""

def _validate(self, region):
if region not in SUPPORTED_REGIONS:
if region not in retrieve_supported_regions():
self._add_failure(
f"Region '{region}' is not yet officially supported by ParallelCluster", FailureLevel.ERROR
)
Expand Down

0 comments on commit ff481cd

Please sign in to comment.