Skip to content

Commit 29e0cce

Browse files
committed
feat: add vpc selection in cli
1 parent 211922b commit 29e0cce

File tree

4 files changed

+84
-5
lines changed

4 files changed

+84
-5
lines changed

src/dmaa/cfn/ecs/post_build.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,11 +123,11 @@ def post_build():
123123

124124
extra_params = json.loads(args.extra_params) if args.extra_params else {}
125125

126-
if 'VpcID' not in extra_params:
126+
if 'vpc_id' not in extra_params:
127127
vpc_id, subnets = deploy_vpc_template(args.region)
128128
else:
129-
vpc_id = extra_params.get('VpcID')
130-
subnets = extra_params.get('Subnets')
129+
vpc_id = extra_params.get('vpc_id')
130+
subnets = extra_params.get('subnet_ids')
131131
update_parameters_file('parameters.json', {'VpcID': vpc_id, 'Subnets': subnets})
132132

133133
deploy_ecs_cluster_template(args.region, vpc_id, subnets)

src/dmaa/commands/deploy.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,76 @@ def deploy(
269269
if not check_service_support_on_cn_region(service_type,region):
270270
raise ServiceNotSupported(region, service_type=service_type)
271271

272+
if Service.get_service_from_name(service_name).need_vpc and service_type != ServiceType.LOCAL:
273+
client = boto3.client('ec2', region_name=region)
274+
vpcs = []
275+
dmaa_default_vpc = None
276+
paginator = client.get_paginator('describe_vpcs')
277+
for page in paginator.paginate():
278+
for vpc in page['Vpcs']:
279+
if any(tag['Key'] == 'Name' and tag['Value'] == 'DMAA-vpc' for tag in vpc.get('Tags', [])):
280+
dmaa_default_vpc = vpc
281+
continue
282+
vpcs.append(vpc)
283+
else:
284+
for vpc in vpcs:
285+
vpc_name = next((tag['Value'] for tag in vpc.get('Tags', []) if tag.get('Key') == 'Name'), None)
286+
vpc['Name'] = vpc_name if vpc_name else '-'
287+
dmaa_vpc = select_with_help(
288+
"Select the VPC (Virtual Private Cloud) you want to deploy the ESC service:",
289+
choices=[
290+
Choice(
291+
title=f"{dmaa_default_vpc['VpcId']} ({dmaa_default_vpc['CidrBlock']}) (DMAA-vpc)" if dmaa_default_vpc else 'Create a new VPC',
292+
description='Use the existing DMAA-VPC for the new model deployment (recommended)' if dmaa_default_vpc else 'Create a new VPC with two public subnets and a S3 Endpoint for the model deployment. Select this option if you do not know what is VPC',
293+
)
294+
] + [
295+
Choice(
296+
title=f"{vpc['VpcId']} ({vpc['CidrBlock']}) ({vpc['Name']})",
297+
description="Custom VPC requirement: A NAT Gateway or S3 Endpoint, with at least two public and two private subnet.",
298+
)
299+
for vpc in vpcs
300+
],
301+
style=custom_style
302+
).ask()
303+
304+
vpc_id = None
305+
selected_subnet_ids = []
306+
if 'Create a new VPC' == dmaa_vpc:
307+
pass
308+
elif 'DMAA-vpc' in dmaa_vpc:
309+
vpc_id = dmaa_vpc.split()[0]
310+
paginator = client.get_paginator('describe_subnets')
311+
for page in paginator.paginate(Filters=[{'Name': 'vpc-id', 'Values': [vpc_id]}]):
312+
for subnet in page['Subnets']:
313+
selected_subnet_ids.append(subnet['SubnetId'])
314+
else:
315+
vpc_id = dmaa_vpc.split()[0]
316+
subnets = []
317+
paginator = client.get_paginator('describe_subnets')
318+
for page in paginator.paginate(Filters=[{'Name': 'vpc-id', 'Values': [vpc_id]}]):
319+
for subnet in page['Subnets']:
320+
subnets.append(subnet)
321+
if not subnets:
322+
console.print("[bold red]No subnets found in the selected VPC.[/bold red]")
323+
raise typer.Exit(0)
324+
else:
325+
for subnet in subnets:
326+
subnet_name = next((tag['Value'] for tag in subnet.get('Tags', []) if tag.get('Key') == 'Name'), None)
327+
subnet['Name'] = subnet_name if subnet_name else '-'
328+
selected_subnet = questionary.checkbox(
329+
"Select multiple subnets for the model deployment:",
330+
choices=[
331+
f"{subnet['SubnetId']} ({subnet['CidrBlock']}) ({subnet['Name']})"
332+
for subnet in subnets
333+
],
334+
style=custom_style
335+
).ask()
336+
if selected_subnet is None:
337+
raise typer.Exit(0)
338+
else:
339+
for subnet in selected_subnet:
340+
selected_subnet_ids.append(subnet.split()[0])
341+
272342
# support instance
273343
supported_instances = model.supported_instances
274344
supported_instances = supported_instances_filter(region,allow_local_deploy,supported_instances)
@@ -393,6 +463,12 @@ def deploy(
393463
except json.JSONDecodeError as e:
394464
console.print("[red]Invalid JSON format. Please try again.[/red]")
395465

466+
# append extra params for VPC and subnets
467+
if vpc_id is not None:
468+
extra_params['service_params'] = {
469+
'vpc_id': vpc_id,
470+
'subnet_ids': selected_subnet_ids
471+
}
396472
# model tag
397473
if model_tag==MODEL_DEFAULT_TAG and not skip_confirm:
398474
while True:

src/dmaa/models/model.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ class Service(ModelBase):
9898
name: str
9999
description: str
100100
support_cn_region: bool
101+
need_vpc: bool = False
101102

102103
# class vars
103104
service_name_maps: ClassVar[dict] = {}

src/dmaa/models/services.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@
5757
name = "Amazon EC2",
5858
service_type=ServiceType.EC2,
5959
description="Amazon Elastic Compute Cloud (Amazon EC2) provides scalable computing capacity in the Amazon Web Services (AWS) cloud.",
60-
support_cn_region = False
60+
support_cn_region = False,
61+
need_vpc = True
6162
)
6263

6364
ecs_service = Service(
@@ -77,7 +78,8 @@
7778
name = "Amazon ECS",
7879
service_type=ServiceType.ECS,
7980
description="Amazon ECS is a fully managed service that provides scalable and reliable container orchestration for your applications.",
80-
support_cn_region = False
81+
support_cn_region = False,
82+
need_vpc = True
8183
)
8284

8385

0 commit comments

Comments
 (0)