Skip to content

Commit

Permalink
[DFSM][Test] Add unit tests to cover dna.json and iam permissions for…
Browse files Browse the repository at this point in the history
… compute nodes.

Signed-off-by: Giacomo Marciani <[email protected]>
  • Loading branch information
gmarciani committed Jan 15, 2024
1 parent be155ba commit 0955b3c
Show file tree
Hide file tree
Showing 8 changed files with 354 additions and 0 deletions.
182 changes: 182 additions & 0 deletions cli/tests/pcluster/templates/test_queues_stack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
import json

import pytest
from assertpy import assert_that
from freezegun import freeze_time

from tests.pcluster.aws.dummy_aws_api import mock_aws_api

from tests.pcluster.models.dummy_s3_bucket import mock_bucket_object_utils, dummy_cluster_bucket

from pcluster.schemas.cluster_schema import ClusterSchema
from pcluster.templates.cdk_builder import CDKTemplateBuilder
from pcluster.utils import load_yaml_dict, load_json_dict
from tests.pcluster.templates.test_cluster_stack import get_generated_template_and_cdk_assets, IamPolicyAssertion, \
_get_cfn_init_file_content

Check notice

Code scanning / CodeQL

Unused import Note test

Import of '_get_cfn_init_file_content' is not used.

from tests.pcluster.utils import get_asset_content_with_resource_name, get_resource_from_assets, render_user_data, \
validate_dna_json_fields

Check notice

Code scanning / CodeQL

Unused import Note test

Import of 'get_resource_from_assets' is not used.
Import of 'render_user_data' is not used.
Import of 'validate_dna_json_fields' is not used.


@pytest.mark.parametrize(
"config_file_name, iam_policy_assertions",
[
(
"config.yaml",
[
IamPolicyAssertion(
expected_statements=[
{
"Action": "ec2:DescribeInstanceAttribute",
"Effect": "Allow",
"Resource": "*",
"Sid": "Ec2",
},
{
"Action": "s3:GetObject",
"Effect": "Allow",
"Resource": {
"Fn::Join": [
"",
[
"arn:",
{"Ref": "AWS::Partition"},
":s3:::",
{"Ref": "AWS::Region"},
"-aws-parallelcluster/*",
],
]
},
"Sid": "S3GetObj",
},
{
"Action": "cloudformation:DescribeStackResource",
"Effect": "Allow",
"Resource": {
"Fn::Join": [
"",
[
"arn:",
{"Ref": "AWS::Partition"},
":cloudformation:",
{"Ref": "AWS::Region"},
":",
{"Ref": "AWS::AccountId"},
":stack/clustername-*/*",
],
]
},
"Sid": "CloudFormation",
},
{
"Action": [
"dynamodb:UpdateItem",
"dynamodb:PutItem",
"dynamodb:GetItem",
],
"Effect": "Allow",
"Resource": {
"Fn::Join": [
"",
[
"arn:",
{"Ref": "AWS::Partition"},
":dynamodb:",
{"Ref": "AWS::Region"},
":",
{"Ref": "AWS::AccountId"},
":table/parallelcluster-clustername",
],
]
},
"Sid": "DynamoDBTable",
},
]
),
],
),
],
)
def test_compute_nodes_iam_permissions(
mocker,
config_file_name,
iam_policy_assertions,
test_datadir,
):
generated_template, cdk_assets = get_generated_template_and_cdk_assets(
mocker,
config_file_name,
test_datadir,
)

asset_content_iam_policies = get_asset_content_with_resource_name(
cdk_assets,
"ParallelClusterPolicies15b342af42246b70",
)
for iam_policy_assertion in iam_policy_assertions:
iam_policy_assertion.assert_iam_policy_properties(
asset_content_iam_policies, "ParallelClusterPolicies15b342af42246b70"
)


@freeze_time("2024-01-15T15:30:45")
@pytest.mark.parametrize(
"config_file_name, expected_compute_node_dna_json_file_name, expected_compute_node_extra_json_file_name",
[
("config-1.yaml", "dna-1.json", "extra-1.json"),
("config-2.yaml", "dna-2.json", "extra-2.json"),
],
)
def test_compute_nodes_dna_json(mocker, test_datadir, config_file_name,
expected_compute_node_dna_json_file_name,
expected_compute_node_extra_json_file_name):
mock_aws_api(mocker)
mock_bucket_object_utils(mocker)

# Read yaml and render CF Template
input_yaml = load_yaml_dict(test_datadir / config_file_name)
cluster_config = ClusterSchema(cluster_name="clustername").load(input_yaml)
_, cdk_assets = CDKTemplateBuilder().build_cluster_template(
cluster_config=cluster_config, bucket=dummy_cluster_bucket(), stack_name="clustername"
)

# Generated dna.json and extra.json
compute_node_lt_asset = get_asset_content_with_resource_name(cdk_assets, "LaunchTemplateA7211c84b953696f")
compute_node_lt = compute_node_lt_asset["Resources"]["LaunchTemplateA7211c84b953696f"]
compute_node_cfn_init_files = compute_node_lt["Metadata"]["AWS::CloudFormation::Init"]["deployConfigFiles"]["files"]
compute_node_dna_json = compute_node_cfn_init_files["/tmp/dna.json"]
compute_node_extra_json = compute_node_cfn_init_files["/tmp/extra.json"]

# Expected dna.json and extra.json
expected_compute_node_dna_json = load_json_dict(test_datadir / expected_compute_node_dna_json_file_name)
expected_compute_node_extra_json = load_json_dict(test_datadir / expected_compute_node_extra_json_file_name)
expected_owner = expected_group = "root"
expected_mode = "000644"

# Assertions on dna.json
rendered_dna_json_content = render_join(compute_node_dna_json["content"]["Fn::Join"])
rendered_dna_json_content_as_json = json.loads(rendered_dna_json_content)
assert_that(compute_node_dna_json["owner"]).is_equal_to(expected_owner)
assert_that(compute_node_dna_json["group"]).is_equal_to(expected_group)
assert_that(compute_node_dna_json["mode"]).is_equal_to(expected_mode)
assert_that(rendered_dna_json_content_as_json).is_equal_to(expected_compute_node_dna_json)

# Assertions on extra.json
assert_that(compute_node_extra_json["owner"]).is_equal_to(expected_owner)
assert_that(compute_node_extra_json["group"]).is_equal_to(expected_group)
assert_that(compute_node_extra_json["mode"]).is_equal_to(expected_mode)
assert_that(json.loads(compute_node_extra_json["content"])).is_equal_to(expected_compute_node_extra_json)


def render_join(elem: dict):
sep = str(elem[0])
body = elem[1]
rendered_body = []
for item in body:
if isinstance(item, str):
rendered_body.append(str(item).strip())
elif isinstance(item, dict):
rendered_body.append(str(json.dumps(item).replace("\"", "\\\"")).strip())
else:
raise ValueError("Found unsupported item type while rendering Fn::Join")
return sep.join(rendered_body)
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Region: eu-west-1
Image:
Os: alinux2
HeadNode:
InstanceType: t2.micro
Networking:
SubnetId: subnet-12345678
Ssh:
KeyName: ec2-key-name
Scheduling:
Scheduler: slurm
SlurmQueues:
- Name: queue1
ComputeResources:
- Name: cr1
InstanceType: c4.xlarge
MinCount: 0
MaxCount: 10
Networking:
SubnetIds:
- subnet-12345678
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
Region: eu-west-1
Image:
Os: alinux2
HeadNode:
InstanceType: t2.micro
Networking:
SubnetId: subnet-12345678
Ssh:
KeyName: ec2-key-name
Scheduling:
Scheduler: slurm
SlurmQueues:
- Name: queue1
ComputeResources:
- Name: cr1
InstanceType: c4.xlarge
MinCount: 0
MaxCount: 10
Networking:
SubnetIds:
- subnet-12345678
DirectoryService:
DomainName: corp.pcluster.com
DomainAddr: ldaps://corp.pcluster.com
PasswordSecretArn: arn:aws:secretsmanager:eu-west-1:XXXXXXXXXXXX:secret:XXXXXXXXXX
DomainReadOnlyUser: cn=ReadOnlyUser,ou=Users,ou=CORP,dc=corp,dc=pcluster,dc=com
LdapTlsReqCert: never
GenerateSshKeysForUsers: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"cluster": {
"cluster_name": "clustername",
"stack_name": "clustername",
"stack_arn": "{\"Ref\": \"AWS::StackId\"}",
"cluster_s3_bucket": "parallelcluster-a69601b5ee1fc2f2-v1-do-not-delete",
"cluster_config_s3_key": "parallelcluster/clusters/dummy-cluster-randomstring123/configs/cluster-config-with-implied-values.yaml",
"cluster_config_version": "",
"enable_efa": "NONE",
"raid_shared_dir": "",
"raid_type": "",
"base_os": "alinux2",
"region": "us-east-1",
"shared_storage_type": "ebs",
"efs_fs_ids": "",
"efs_shared_dirs": "",
"efs_encryption_in_transits": "",
"efs_iam_authorizations": "",
"fsx_fs_ids": "",
"fsx_mount_names": "",
"fsx_dns_names": "",
"fsx_volume_junction_paths": "",
"fsx_fs_types": "",
"fsx_shared_dirs": "",
"scheduler": "slurm",
"ephemeral_dir": "/scratch",
"ebs_shared_dirs": "",
"proxy": "NONE",
"slurm_ddb_table": "{\"Ref\": \"referencetoclusternameSlurmDynamoDBTable99119DBERef\"}",
"log_group_name": "/aws/parallelcluster/clustername-202401151530",
"dns_domain": "{\"Ref\": \"referencetoclusternameClusterDNSDomain8D0872E1Ref\"}",
"hosted_zone": "{\"Ref\": \"referencetoclusternameRoute53HostedZone2388733DRef\"}",
"node_type": "ComputeFleet",
"cluster_user": "ec2-user",
"enable_intel_hpc_platform": "false",
"cw_logging_enabled": "true",
"log_rotation_enabled": "true",
"scheduler_queue_name": "queue1",
"scheduler_compute_resource_name": "cr1",
"enable_efa_gdr": "NONE",
"custom_node_package": "",
"custom_awsbatchcli_package": "",
"use_private_hostname": "false",
"head_node_private_ip": "{\"Ref\": \"referencetoclusternameHeadNodeENI6497A502PrimaryPrivateIpAddress\"}",
"directory_service": {
"enabled": "false"
},
"disable_sudo_access_for_default_user": "false"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"cluster": {
"cluster_name": "clustername",
"stack_name": "clustername",
"stack_arn": "{\"Ref\": \"AWS::StackId\"}",
"cluster_s3_bucket": "parallelcluster-a69601b5ee1fc2f2-v1-do-not-delete",
"cluster_config_s3_key": "parallelcluster/clusters/dummy-cluster-randomstring123/configs/cluster-config-with-implied-values.yaml",
"cluster_config_version": "",
"enable_efa": "NONE",
"raid_shared_dir": "",
"raid_type": "",
"base_os": "alinux2",
"region": "us-east-1",
"shared_storage_type": "ebs",
"efs_fs_ids": "",
"efs_shared_dirs": "",
"efs_encryption_in_transits": "",
"efs_iam_authorizations": "",
"fsx_fs_ids": "",
"fsx_mount_names": "",
"fsx_dns_names": "",
"fsx_volume_junction_paths": "",
"fsx_fs_types": "",
"fsx_shared_dirs": "",
"scheduler": "slurm",
"ephemeral_dir": "/scratch",
"ebs_shared_dirs": "",
"proxy": "NONE",
"slurm_ddb_table": "{\"Ref\": \"referencetoclusternameSlurmDynamoDBTable99119DBERef\"}",
"log_group_name": "/aws/parallelcluster/clustername-202401151530",
"dns_domain": "{\"Ref\": \"referencetoclusternameClusterDNSDomain8D0872E1Ref\"}",
"hosted_zone": "{\"Ref\": \"referencetoclusternameRoute53HostedZone2388733DRef\"}",
"node_type": "ComputeFleet",
"cluster_user": "ec2-user",
"enable_intel_hpc_platform": "false",
"cw_logging_enabled": "true",
"log_rotation_enabled": "true",
"scheduler_queue_name": "queue1",
"scheduler_compute_resource_name": "cr1",
"enable_efa_gdr": "NONE",
"custom_node_package": "",
"custom_awsbatchcli_package": "",
"use_private_hostname": "false",
"head_node_private_ip": "{\"Ref\": \"referencetoclusternameHeadNodeENI6497A502PrimaryPrivateIpAddress\"}",
"directory_service": {
"enabled": "true"
},
"disable_sudo_access_for_default_user": "false"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Region: eu-west-1
Image:
Os: alinux2
HeadNode:
InstanceType: t2.micro
Networking:
SubnetId: subnet-12345678
Ssh:
KeyName: ec2-key-name
Scheduling:
Scheduler: slurm
SlurmQueues:
- Name: queue1
ComputeResources:
- Name: cr1
InstanceType: c4.xlarge
MinCount: 0
MaxCount: 10
Networking:
SubnetIds:
- subnet-12345678

0 comments on commit 0955b3c

Please sign in to comment.