Skip to content

Commit 2a13ae6

Browse files
authored
[LoginNodes] Modify cli to add custom action configuration parameters to login nodes (#6319)
* Add CustomActions configuration for login nodes - Added schema for login nodes custom actions - Added CustomAction to LoginNodesPool resource in cluster_config.py Signed-off-by: Chris Makin <cmakin@amazon.com> * Add login node Pool Name to dna_json * Add DescribeStack action to LoginNodesIamResources This change allows custom actions OnNodeUpdated to be performed for login nodes, which requires a check of the cluster stack status in custom_action_executor.py. * Modify integration test for custom actions on Login Nodes - Modified test_essential_features integration test to account for custom actions on login nodes. * Update unit tests to include login node custom action changes - Modified login node dna_json unit test to include pool_name - Ran tox autoformatter * Merge head and login nodes custom action schema unit test - Update changelog - Fix DescribeStacks resource error in unit test --------- Signed-off-by: Chris Makin <cmakin@amazon.com>
1 parent 937dcbc commit 2a13ae6

File tree

15 files changed

+149
-12
lines changed

15 files changed

+149
-12
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
CHANGELOG
22
=========
33

4+
3.11.0
5+
------
6+
7+
**ENHANCEMENTS**
8+
9+
- Add support for custom actions on login nodes.
10+
411
3.10.0
512
------
613

cli/src/pcluster/config/cluster_config.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1346,6 +1346,7 @@ def __init__(
13461346
networking: LoginNodesNetworking = None,
13471347
count: int = None,
13481348
ssh: LoginNodesSsh = None,
1349+
custom_actions: CustomActions = None,
13491350
iam: LoginNodesIam = None,
13501351
gracetime_period: int = None,
13511352
**kwargs,
@@ -1357,6 +1358,7 @@ def __init__(
13571358
self.networking = networking
13581359
self.count = Resource.init_param(count, default=1)
13591360
self.ssh = ssh
1361+
self.custom_actions = custom_actions
13601362
self.iam = iam or LoginNodesIam(implied=True)
13611363
self.gracetime_period = Resource.init_param(gracetime_period, default=10)
13621364

cli/src/pcluster/schemas/cluster_schema.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,6 +1315,19 @@ def make_resource(self, data, **kwargs):
13151315
return CustomActions(**data)
13161316

13171317

1318+
class LoginNodesCustomActionsSchema(BaseSchema):
1319+
"""Represent the schema for all available custom actions in a login node pool."""
1320+
1321+
on_node_start = OneOrManyCustomActionField(metadata={"update_policy": UpdatePolicy.UNSUPPORTED})
1322+
on_node_configured = OneOrManyCustomActionField(metadata={"update_policy": UpdatePolicy.UNSUPPORTED})
1323+
on_node_updated = OneOrManyCustomActionField(metadata={"update_policy": UpdatePolicy.UNSUPPORTED})
1324+
1325+
@post_load
1326+
def make_resource(self, data, **kwargs):
1327+
"""Generate resource."""
1328+
return CustomActions(**data)
1329+
1330+
13181331
class InstanceTypeSchema(BaseSchema):
13191332
"""Schema of a compute resource that supports a pool of instance types."""
13201333

@@ -1422,6 +1435,7 @@ class LoginNodesPoolSchema(BaseSchema):
14221435
metadata={"update_policy": UpdatePolicy.SUPPORTED},
14231436
)
14241437
ssh = fields.Nested(LoginNodesSshSchema, metadata={"update_policy": UpdatePolicy.LOGIN_NODES_STOP})
1438+
custom_actions = fields.Nested(LoginNodesCustomActionsSchema, metadata={"update_policy": UpdatePolicy.IGNORED})
14251439
iam = fields.Nested(LoginNodesIamSchema, metadata={"update_policy": UpdatePolicy.LOGIN_NODES_STOP})
14261440
gracetime_period = fields.Int(
14271441
validate=validate.Range(

cli/src/pcluster/templates/cdk_builder_utils.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -934,9 +934,18 @@ def _build_policy(self) -> List[iam.PolicyStatement]:
934934
sid="CloudFormation",
935935
actions=[
936936
"cloudformation:DescribeStackResource",
937+
"cloudformation:DescribeStacks",
937938
],
938939
effect=iam.Effect.ALLOW,
939-
resources=[core.Aws.STACK_ID],
940+
resources=[
941+
self._format_arn(
942+
service="cloudformation",
943+
resource=f"stack/{Stack.of(self).stack_name}/*",
944+
region=Stack.of(self).region,
945+
account=Stack.of(self).account,
946+
),
947+
core.Aws.STACK_ID,
948+
],
940949
),
941950
iam.PolicyStatement(
942951
sid="DynamoDBTable",

cli/src/pcluster/templates/login_nodes_stack.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ def _add_login_nodes_pool_launch_template(self):
258258
"hosted_zone": (str(self._cluster_hosted_zone.ref) if self._cluster_hosted_zone else ""),
259259
"log_group_name": self._log_group.log_group_name,
260260
"log_rotation_enabled": "true" if self._config.is_log_rotation_enabled else "false",
261+
"pool_name": self._pool.name,
261262
"node_type": "LoginNode",
262263
"proxy": self._pool.networking.proxy.http_proxy_address if self._pool.networking.proxy else "NONE",
263264
"raid_shared_dir": to_comma_separated_string(

cli/tests/pcluster/example_configs/slurm.full.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,22 @@ LoginNodes:
1717
- subnet-12345678
1818
Ssh:
1919
KeyName: ec2-key-name
20+
CustomActions:
21+
OnNodeStart:
22+
Script: https://test.tgz # s3:// | https://
23+
Args:
24+
- arg1
25+
- arg2
26+
OnNodeConfigured:
27+
Script: https://test.tgz # s3:// | https://
28+
Args:
29+
- arg1
30+
- arg2
31+
OnNodeUpdated:
32+
Script: https://test.tgz # s3:// | https://
33+
Args:
34+
- arg1
35+
- arg2
2036
Iam:
2137
InstanceRole: arn:aws:iam::aws:role/LoginNodeRole
2238
HeadNode:

cli/tests/pcluster/schemas/test_cluster_schema.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
HeadNodeIamSchema,
2626
HeadNodeRootVolumeSchema,
2727
ImageSchema,
28+
LoginNodesCustomActionsSchema,
2829
QueueCustomActionsSchema,
2930
QueueIamSchema,
3031
QueueTagSchema,
@@ -259,14 +260,18 @@ def test_head_node_root_volume_schema(mocker, config_dict, failure_message):
259260
),
260261
],
261262
)
262-
def test_head_node_custom_actions_schema(mocker, config_dict, failure_message):
263+
def test_head_login_node_custom_actions_schema(mocker, config_dict, failure_message):
263264
mock_aws_api(mocker)
264265
if failure_message:
265266
with pytest.raises(ValidationError, match=failure_message):
266267
HeadNodeCustomActionsSchema().load(config_dict)
268+
LoginNodesCustomActionsSchema().load(config_dict)
267269
else:
268-
conf = HeadNodeCustomActionsSchema().load(config_dict)
269-
HeadNodeCustomActionsSchema().dump(conf)
270+
head_conf = HeadNodeCustomActionsSchema().load(config_dict)
271+
login_conf = LoginNodesCustomActionsSchema().load(config_dict)
272+
273+
HeadNodeCustomActionsSchema().dump(head_conf)
274+
LoginNodesCustomActionsSchema().dump(login_conf)
270275

271276

272277
@pytest.mark.parametrize(

cli/tests/pcluster/templates/test_cluster_stack.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -756,11 +756,25 @@ def assert_iam_policy_properties(self, template, resource_name: str):
756756
"Sid": "Autoscaling",
757757
},
758758
{
759-
"Action": "cloudformation:DescribeStackResource",
759+
"Action": ["cloudformation:DescribeStackResource", "cloudformation:DescribeStacks"],
760760
"Effect": "Allow",
761-
"Resource": {
762-
"Ref": "AWS::StackId",
763-
},
761+
"Resource": [
762+
{
763+
"Fn::Join": [
764+
"",
765+
[
766+
"arn:",
767+
{"Ref": "AWS::Partition"},
768+
":cloudformation:",
769+
{"Ref": "AWS::Region"},
770+
":",
771+
{"Ref": "AWS::AccountId"},
772+
":stack/clustername/*",
773+
],
774+
]
775+
},
776+
{"Ref": "AWS::StackId"},
777+
],
764778
"Sid": "CloudFormation",
765779
},
766780
{

cli/tests/pcluster/templates/test_cluster_stack/test_cluster_config_limits/slurm.full.all_resources.yaml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,26 @@ LoginNodes:
2020
HttpProxyAddress: https://proxy-address:port
2121
Ssh:
2222
KeyName: validate_key_name
23+
CustomActions:
24+
OnNodeStart:
25+
Script: https://test.tgz
26+
Args:
27+
# Number of args doesn't impact number of resources, just the size of the template
28+
{% for i in range(number_of_script_args) %}
29+
- arg{{ i }}
30+
{% endfor %}
31+
OnNodeConfigured:
32+
Script: https://test.tgz
33+
Args:
34+
{% for i in range(number_of_script_args) %}
35+
- arg{{ i }}
36+
{% endfor %}
37+
OnNodeUpdated:
38+
Script: https://test.tgz
39+
Args:
40+
{% for i in range(number_of_script_args) %}
41+
- arg{{ i }}
42+
{% endfor %}
2343
Iam:
2444
AdditionalIamPolicies:
2545
- Policy: arn:aws:iam::aws:policy/AdministratorAccess

cli/tests/pcluster/templates/test_cluster_stack/test_cluster_config_limits/slurm.full_config.snapshot.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,19 @@ Imds:
8787
LoginNodes:
8888
Pools:
8989
- Count: 1
90+
CustomActions:
91+
OnNodeConfigured:
92+
Args:
93+
- arg0
94+
Script: https://test.tgz
95+
OnNodeStart:
96+
Args:
97+
- arg0
98+
Script: https://test.tgz
99+
OnNodeUpdated:
100+
Args:
101+
- arg0
102+
Script: https://test.tgz
90103
GracetimePeriod: 10
91104
Iam:
92105
AdditionalIamPolicies:

0 commit comments

Comments
 (0)