Skip to content

Commit 81de3ce

Browse files
committed
refactoring
1 parent 1a39cdd commit 81de3ce

File tree

7 files changed

+110
-70
lines changed

7 files changed

+110
-70
lines changed

services/autoscaling/src/simcore_service_autoscaling/modules/cluster_scaling/_auto_scaling_core.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@
4949
ec2_startup_script,
5050
find_selected_instance_type_for_task,
5151
get_machine_buffer_type,
52-
node_host_name_from_ec2_private_dns,
5352
sort_drained_nodes,
5453
)
5554
from ...utils.rabbitmq import (
@@ -285,7 +284,7 @@ async def _try_attach_pending_ec2s(
285284
assert app_settings.AUTOSCALING_EC2_INSTANCES # nosec
286285
for instance_data in cluster.pending_ec2s:
287286
try:
288-
node_host_name = node_host_name_from_ec2_private_dns(
287+
node_host_name = utils_ec2.node_host_name_from_ec2_private_dns(
289288
instance_data.ec2_instance
290289
)
291290
if new_node := await utils_docker.find_node_with_name(

services/autoscaling/src/simcore_service_autoscaling/modules/dask.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
DaskWorkerNotFoundError,
2222
)
2323
from ..models import AssociatedInstance, DaskTask, DaskTaskId
24-
from ..utils.cluster_scaling import (
24+
from ..utils.utils_ec2 import (
2525
node_host_name_from_ec2_private_dns,
2626
node_ip_from_ec2_private_dns,
2727
)

services/autoscaling/src/simcore_service_autoscaling/utils/cluster_scaling.py

Lines changed: 5 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import functools
22
import logging
3-
import re
4-
from typing import Final, TypeAlias
3+
from typing import TypeAlias
54

65
from aws_library.ec2 import (
76
EC2InstanceBootSpecific,
@@ -19,39 +18,11 @@
1918
)
2019
from ..core.settings import ApplicationSettings
2120
from ..models import AssociatedInstance
22-
from . import utils_docker
21+
from . import utils_docker, utils_ec2
2322

24-
_EC2_INTERNAL_DNS_RE: Final[re.Pattern] = re.compile(r"^(?P<host_name>ip-[^.]+)\..+$")
2523
_logger = logging.getLogger(__name__)
2624

2725

28-
def node_host_name_from_ec2_private_dns(
29-
ec2_instance_data: EC2InstanceData,
30-
) -> str:
31-
"""returns the node host name 'ip-10-2-3-22' from the ec2 private dns
32-
Raises:
33-
Ec2InvalidDnsNameError: if the dns name does not follow the expected pattern
34-
"""
35-
if match := re.match(_EC2_INTERNAL_DNS_RE, ec2_instance_data.aws_private_dns):
36-
host_name: str = match.group("host_name")
37-
return host_name
38-
raise Ec2InvalidDnsNameError(aws_private_dns_name=ec2_instance_data.aws_private_dns)
39-
40-
41-
def node_ip_from_ec2_private_dns(
42-
ec2_instance_data: EC2InstanceData,
43-
) -> str:
44-
"""returns the node ipv4 from the ec2 private dns string
45-
Raises:
46-
Ec2InvalidDnsNameError: if the dns name does not follow the expected pattern
47-
"""
48-
return (
49-
node_host_name_from_ec2_private_dns(ec2_instance_data)
50-
.removeprefix("ip-")
51-
.replace("-", ".")
52-
)
53-
54-
5526
async def associate_ec2_instances_with_nodes(
5627
nodes: list[Node], ec2_instances: list[EC2InstanceData]
5728
) -> tuple[list[AssociatedInstance], list[EC2InstanceData]]:
@@ -65,7 +36,9 @@ def _find_node_with_name(node: Node) -> bool:
6536

6637
for instance_data in ec2_instances:
6738
try:
68-
docker_node_name = node_host_name_from_ec2_private_dns(instance_data)
39+
docker_node_name = utils_ec2.node_host_name_from_ec2_private_dns(
40+
instance_data
41+
)
6942
except Ec2InvalidDnsNameError:
7043
_logger.exception("Unexpected EC2 private dns name")
7144
non_associated_instances.append(instance_data)

services/autoscaling/src/simcore_service_autoscaling/utils/utils_ec2.py

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,27 @@
11
"""Free helper functions for AWS API"""
22

33
import logging
4+
import re
45
from collections import OrderedDict
56
from collections.abc import Callable
67
from textwrap import dedent
8+
from typing import Final
79

810
from aws_library.ec2 import AWSTagKey, AWSTagValue, EC2InstanceType, EC2Tags, Resources
11+
from aws_library.ec2._models import EC2InstanceData
912
from common_library.json_serialization import json_dumps
1013

1114
from .._meta import VERSION
12-
from ..core.errors import ConfigurationError, TaskBestFittingInstanceNotFoundError
15+
from ..core.errors import (
16+
ConfigurationError,
17+
Ec2InvalidDnsNameError,
18+
TaskBestFittingInstanceNotFoundError,
19+
)
1320
from ..core.settings import ApplicationSettings
1421

15-
logger = logging.getLogger(__name__)
22+
_logger = logging.getLogger(__name__)
23+
24+
_EC2_INTERNAL_DNS_RE: Final[re.Pattern] = re.compile(r"^(?P<host_name>ip-[^.]+)\..+$")
1625

1726

1827
def get_ec2_tags_dynamic(app_settings: ApplicationSettings) -> EC2Tags:
@@ -105,3 +114,30 @@ def find_best_fitting_ec2_instance(
105114
raise TaskBestFittingInstanceNotFoundError(needed_resources=resources)
106115

107116
return instance
117+
118+
119+
def node_host_name_from_ec2_private_dns(
120+
ec2_instance_data: EC2InstanceData,
121+
) -> str:
122+
"""returns the node host name 'ip-10-2-3-22' from the ec2 private dns
123+
Raises:
124+
Ec2InvalidDnsNameError: if the dns name does not follow the expected pattern
125+
"""
126+
if match := re.match(_EC2_INTERNAL_DNS_RE, ec2_instance_data.aws_private_dns):
127+
host_name: str = match.group("host_name")
128+
return host_name
129+
raise Ec2InvalidDnsNameError(aws_private_dns_name=ec2_instance_data.aws_private_dns)
130+
131+
132+
def node_ip_from_ec2_private_dns(
133+
ec2_instance_data: EC2InstanceData,
134+
) -> str:
135+
"""returns the node ipv4 from the ec2 private dns string
136+
Raises:
137+
Ec2InvalidDnsNameError: if the dns name does not follow the expected pattern
138+
"""
139+
return (
140+
node_host_name_from_ec2_private_dns(ec2_instance_data)
141+
.removeprefix("ip-")
142+
.replace("-", ".")
143+
)

services/autoscaling/tests/unit/test_modules_cluster_scaling_dynamic.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,15 @@
6666
AutoscalingDocker,
6767
get_docker_client,
6868
)
69-
from simcore_service_autoscaling.utils.cluster_scaling import (
70-
node_host_name_from_ec2_private_dns,
71-
)
7269
from simcore_service_autoscaling.utils.utils_docker import (
7370
_OSPARC_NODE_EMPTY_DATETIME_LABEL_KEY,
7471
_OSPARC_NODE_TERMINATION_PROCESS_LABEL_KEY,
7572
_OSPARC_SERVICE_READY_LABEL_KEY,
7673
_OSPARC_SERVICES_READY_DATETIME_LABEL_KEY,
7774
)
75+
from simcore_service_autoscaling.utils.utils_ec2 import (
76+
node_host_name_from_ec2_private_dns,
77+
)
7878
from types_aiobotocore_ec2.client import EC2Client
7979
from types_aiobotocore_ec2.literals import InstanceStateNameType, InstanceTypeType
8080
from types_aiobotocore_ec2.type_defs import FilterTypeDef, InstanceTypeDef

services/autoscaling/tests/unit/test_utils_cluster_scaling.py

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,12 @@
1919
from pydantic import TypeAdapter
2020
from pytest_simcore.helpers.monkeypatch_envs import setenvs_from_dict
2121
from pytest_simcore.helpers.typing_env import EnvVarsDict
22-
from simcore_service_autoscaling.core.errors import Ec2InvalidDnsNameError
2322
from simcore_service_autoscaling.core.settings import ApplicationSettings
2423
from simcore_service_autoscaling.models import AssociatedInstance, EC2InstanceData
2524
from simcore_service_autoscaling.utils.cluster_scaling import (
2625
associate_ec2_instances_with_nodes,
2726
ec2_startup_script,
2827
get_machine_buffer_type,
29-
node_host_name_from_ec2_private_dns,
3028
sort_drained_nodes,
3129
)
3230
from simcore_service_autoscaling.utils.utils_docker import (
@@ -52,34 +50,6 @@ def _creator(**overrides) -> DockerNode:
5250
return _creator
5351

5452

55-
@pytest.mark.parametrize(
56-
"aws_private_dns, expected_host_name",
57-
[
58-
("ip-10-12-32-3.internal-data", "ip-10-12-32-3"),
59-
("ip-10-12-32-32.internal-data", "ip-10-12-32-32"),
60-
("ip-10-0-3-129.internal-data", "ip-10-0-3-129"),
61-
("ip-10-0-3-12.internal-data", "ip-10-0-3-12"),
62-
],
63-
)
64-
def test_node_host_name_from_ec2_private_dns(
65-
fake_ec2_instance_data: Callable[..., EC2InstanceData],
66-
aws_private_dns: str,
67-
expected_host_name: str,
68-
):
69-
instance = fake_ec2_instance_data(
70-
aws_private_dns=aws_private_dns,
71-
)
72-
assert node_host_name_from_ec2_private_dns(instance) == expected_host_name
73-
74-
75-
def test_node_host_name_from_ec2_private_dns_raises_with_invalid_name(
76-
fake_ec2_instance_data: Callable[..., EC2InstanceData], faker: Faker
77-
):
78-
instance = fake_ec2_instance_data(aws_private_dns=faker.name())
79-
with pytest.raises(Ec2InvalidDnsNameError):
80-
node_host_name_from_ec2_private_dns(instance)
81-
82-
8353
@pytest.mark.parametrize("valid_ec2_dns", [True, False])
8454
async def test_associate_ec2_instances_with_nodes_with_no_correspondence(
8555
fake_ec2_instance_data: Callable[..., EC2InstanceData],

services/autoscaling/tests/unit/test_utils_ec2.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,24 @@
33
# pylint: disable=unused-variable
44

55

6+
from collections.abc import Callable
7+
68
import pytest
79
from aws_library.ec2 import EC2InstanceType, Resources
10+
from aws_library.ec2._models import EC2InstanceData
811
from faker import Faker
912
from pydantic import ByteSize
1013
from simcore_service_autoscaling.core.errors import (
1114
ConfigurationError,
15+
Ec2InvalidDnsNameError,
1216
TaskBestFittingInstanceNotFoundError,
1317
)
1418
from simcore_service_autoscaling.utils.utils_ec2 import (
1519
closest_instance_policy,
1620
compose_user_data,
1721
find_best_fitting_ec2_instance,
22+
node_host_name_from_ec2_private_dns,
23+
node_ip_from_ec2_private_dns,
1824
)
1925

2026

@@ -70,3 +76,59 @@ def test_compose_user_data(faker: Faker):
7076
user_data = compose_user_data(command)
7177
assert user_data.startswith("#!/bin/bash")
7278
assert command in user_data
79+
80+
81+
@pytest.mark.parametrize(
82+
"aws_private_dns, expected_host_name",
83+
[
84+
("ip-10-12-32-3.internal-data", "ip-10-12-32-3"),
85+
("ip-10-12-32-32.internal-data", "ip-10-12-32-32"),
86+
("ip-10-0-3-129.internal-data", "ip-10-0-3-129"),
87+
("ip-10-0-3-12.internal-data", "ip-10-0-3-12"),
88+
],
89+
)
90+
def test_node_host_name_from_ec2_private_dns(
91+
fake_ec2_instance_data: Callable[..., EC2InstanceData],
92+
aws_private_dns: str,
93+
expected_host_name: str,
94+
):
95+
instance = fake_ec2_instance_data(
96+
aws_private_dns=aws_private_dns,
97+
)
98+
assert node_host_name_from_ec2_private_dns(instance) == expected_host_name
99+
100+
101+
def test_node_host_name_from_ec2_private_dns_raises_with_invalid_name(
102+
fake_ec2_instance_data: Callable[..., EC2InstanceData], faker: Faker
103+
):
104+
instance = fake_ec2_instance_data(aws_private_dns=faker.name())
105+
with pytest.raises(Ec2InvalidDnsNameError):
106+
node_host_name_from_ec2_private_dns(instance)
107+
108+
109+
@pytest.mark.parametrize(
110+
"aws_private_dns, expected_host_name",
111+
[
112+
("ip-10-12-32-3.internal-data", "10.12.32.3"),
113+
("ip-10-12-32-32.internal-data", "10.12.32.32"),
114+
("ip-10-0-3-129.internal-data", "10.0.3.129"),
115+
("ip-10-0-3-12.internal-data", "10.0.3.12"),
116+
],
117+
)
118+
def test_node_ip_from_ec2_private_dns(
119+
fake_ec2_instance_data: Callable[..., EC2InstanceData],
120+
aws_private_dns: str,
121+
expected_host_name: str,
122+
):
123+
instance = fake_ec2_instance_data(
124+
aws_private_dns=aws_private_dns,
125+
)
126+
assert node_ip_from_ec2_private_dns(instance) == expected_host_name
127+
128+
129+
def test_node_ip_from_ec2_private_dns_raises_with_invalid_name(
130+
fake_ec2_instance_data: Callable[..., EC2InstanceData], faker: Faker
131+
):
132+
instance = fake_ec2_instance_data(aws_private_dns=faker.name())
133+
with pytest.raises(Ec2InvalidDnsNameError):
134+
node_ip_from_ec2_private_dns(instance)

0 commit comments

Comments
 (0)