Skip to content

Commit 51c066f

Browse files
authored
add msk probes and actions (#148)
* chaosaws msk ready Signed-off-by: Jorge Tapicha <[email protected]> Signed-off-by: Jorge Tapicha <[email protected]> * add changelog and activities extends Signed-off-by: Jorge Tapicha <[email protected]> Signed-off-by: Jorge Tapicha <[email protected]> * remove unnecesary empty response test Signed-off-by: Jorge Tapicha <[email protected]> * first corrections Pull Request Signed-off-by: Jorge Tapicha <[email protected]> * fix f-string without any placeholders Signed-off-by: Jorge Tapicha <[email protected]> --------- Signed-off-by: Jorge Tapicha <[email protected]>
1 parent d11e8fd commit 51c066f

File tree

7 files changed

+275
-0
lines changed

7 files changed

+275
-0
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
## [Unreleased][]
44

5+
### Added
6+
7+
* MSK probes `chaosaws.msk.probes.describe_msk_cluster` `chaosaws.msk.probes.get_bootstrap_servers`
8+
* MSK actions `chaosaws.msk.actions.reboot_msk_broker` `chaosaws.msk.actions.delete_cluster`
9+
510
[Unreleased]: https://github.com/chaostoolkit-incubator/chaostoolkit-aws/compare/0.33.0...HEAD
611

712
## [0.33.0][] - 2024-02-26

chaosaws/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,8 @@ def load_exported_activities() -> List[DiscoveredActivities]:
307307
activities.extend(discover_actions("chaosaws.fis.actions"))
308308
activities.extend(discover_probes("chaosaws.s3.probes"))
309309
activities.extend(discover_actions("chaosaws.s3.actions"))
310+
activities.extend(discover_probes("chaosaws.msk.probes"))
311+
activities.extend(discover_actions("chaosaws.msk.actions"))
310312
activities.extend(
311313
discover_activities("chaosaws.s3.controls.upload", "control")
312314
)

chaosaws/msk/__init__.py

Whitespace-only changes.

chaosaws/msk/actions.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from typing import List
2+
3+
from chaoslib.types import Configuration, Secrets
4+
from chaoslib.exceptions import FailedActivity
5+
6+
from chaosaws import aws_client, get_logger
7+
from chaosaws.types import AWSResponse
8+
9+
__all__ = ["reboot_msk_broker", "delete_cluster"]
10+
11+
logger = get_logger()
12+
13+
14+
def reboot_msk_broker(
15+
cluster_arn: str,
16+
broker_ids: List[str],
17+
configuration: Configuration = None,
18+
secrets: Secrets = None,
19+
) -> AWSResponse:
20+
"""
21+
Reboot the specified brokers in an MSK cluster.
22+
"""
23+
client = aws_client("kafka", configuration, secrets)
24+
logger.debug(
25+
f"Rebooting MSK brokers: {broker_ids} in cluster {cluster_arn}"
26+
)
27+
try:
28+
return client.reboot_broker(
29+
ClusterArn=cluster_arn,
30+
BrokerIds=broker_ids
31+
)
32+
except client.exceptions.NotFoundException:
33+
raise FailedActivity("The specified cluster was not found" )
34+
35+
36+
def delete_cluster(
37+
cluster_arn: str,
38+
configuration: Configuration = None,
39+
secrets: Secrets = None,
40+
) -> AWSResponse:
41+
"""
42+
Delete the given MSK cluster.
43+
"""
44+
client = aws_client("kafka", configuration, secrets)
45+
logger.debug(f"Deleting MSK cluster: {cluster_arn}")
46+
try:
47+
return client.delete_cluster(ClusterArn=cluster_arn)
48+
except client.exceptions.NotFoundException:
49+
raise FailedActivity("The specified cluster was not found")

chaosaws/msk/probes.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
from typing import List
2+
3+
from chaoslib.types import Configuration, Secrets
4+
from chaoslib.exceptions import FailedActivity
5+
6+
from chaosaws import aws_client, get_logger
7+
from chaosaws.types import AWSResponse
8+
9+
__all__ = ["describe_msk_cluster", "get_bootstrap_servers"]
10+
11+
logger = get_logger()
12+
13+
14+
def describe_msk_cluster(
15+
cluster_arn: str,
16+
configuration: Configuration = None,
17+
secrets: Secrets = None,
18+
) -> AWSResponse:
19+
"""
20+
Describe an MSK cluster.
21+
"""
22+
client = aws_client("kafka", configuration, secrets)
23+
logger.debug(f"Describing MSK cluster: {cluster_arn}")
24+
try:
25+
return client.describe_cluster(ClusterArn=cluster_arn)
26+
except client.exceptions.NotFoundException:
27+
raise FailedActivity("The specified cluster was not found")
28+
29+
30+
def get_bootstrap_servers(
31+
cluster_arn: str,
32+
configuration: Configuration = None,
33+
secrets: Secrets = None,
34+
) -> List[str]:
35+
"""
36+
Get the bootstrap servers for an MSK cluster.
37+
"""
38+
client = aws_client("kafka", configuration, secrets)
39+
logger.debug(f"Getting bootstrap servers for MSK cluster: {cluster_arn}")
40+
try:
41+
response = client.get_bootstrap_brokers(ClusterArn=cluster_arn)
42+
return response["BootstrapBrokerString"].split(",") if response else []
43+
except client.exceptions.NotFoundException:
44+
raise FailedActivity("The specified cluster was not found")

tests/msk/test_msk_actions.py

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
from unittest.mock import MagicMock, patch
2+
import pytest
3+
from chaosaws.msk.actions import reboot_msk_broker, delete_cluster
4+
from chaoslib.exceptions import FailedActivity
5+
6+
7+
class NotFoundException(Exception):
8+
def __init__(self, message="Cluster not found"):
9+
super().__init__(f"{message}")
10+
11+
12+
@patch("chaosaws.msk.actions.aws_client", autospec=True)
13+
def test_reboot_msk_broker_success(aws_client):
14+
client = MagicMock()
15+
aws_client.return_value = client
16+
cluster_arn = "arn_msk_cluster"
17+
broker_ids = ["1"]
18+
client.reboot_broker.return_value = {
19+
"ResponseMetadata": {
20+
"HTTPStatusCode": 200
21+
}
22+
}
23+
24+
response = reboot_msk_broker(cluster_arn=cluster_arn,
25+
broker_ids=broker_ids)
26+
27+
client.reboot_broker.assert_called_with(ClusterArn=cluster_arn,
28+
BrokerIds=broker_ids)
29+
assert response["ResponseMetadata"]["HTTPStatusCode"] == 200
30+
31+
32+
@patch("chaosaws.msk.actions.aws_client", autospec=True)
33+
def test_reboot_msk_broker_not_found(aws_client):
34+
client = MagicMock()
35+
aws_client.return_value = client
36+
cluster_arn = "arn_msk_cluster"
37+
broker_ids = ["1"]
38+
39+
client.exceptions = MagicMock()
40+
client.exceptions.NotFoundException = NotFoundException
41+
client.reboot_broker.side_effect = NotFoundException(
42+
"Cluster not found"
43+
)
44+
45+
expected_error_message = "The specified cluster was not found"
46+
47+
with pytest.raises(FailedActivity) as exc_info:
48+
reboot_msk_broker(cluster_arn=cluster_arn, broker_ids=broker_ids)
49+
50+
assert expected_error_message in str(
51+
exc_info.value
52+
)
53+
54+
55+
@patch("chaosaws.msk.actions.aws_client", autospec=True)
56+
def test_delete_cluster_success(aws_client):
57+
client = MagicMock()
58+
aws_client.return_value = client
59+
cluster_arn = "arn_msk_cluster"
60+
client.delete_cluster.return_value = {
61+
"ResponseMetadata": {
62+
"HTTPStatusCode": 200
63+
}
64+
}
65+
66+
response = delete_cluster(cluster_arn=cluster_arn)
67+
68+
client.delete_cluster.assert_called_with(ClusterArn=cluster_arn)
69+
assert response["ResponseMetadata"]["HTTPStatusCode"] == 200
70+
71+
72+
@patch("chaosaws.msk.actions.aws_client", autospec=True)
73+
def test_delete_cluster_not_found(aws_client):
74+
client = MagicMock()
75+
aws_client.return_value = client
76+
cluster_arn = "arn_msk_cluster"
77+
78+
client.exceptions = MagicMock()
79+
client.exceptions.NotFoundException = NotFoundException
80+
client.delete_cluster.side_effect = NotFoundException(
81+
"Cluster not found"
82+
)
83+
84+
expected_error_message = "The specified cluster was not found"
85+
86+
with pytest.raises(FailedActivity) as exc_info:
87+
delete_cluster(cluster_arn=cluster_arn)
88+
89+
assert expected_error_message in str(
90+
exc_info.value
91+
)

tests/msk/test_msk_probes.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
from unittest.mock import MagicMock, patch
2+
import pytest
3+
from chaosaws.msk.probes import describe_msk_cluster, get_bootstrap_servers
4+
from chaoslib.exceptions import FailedActivity
5+
6+
7+
class NotFoundException(Exception):
8+
def __init__(self, message="Cluster not found"):
9+
super().__init__(f"{message}")
10+
11+
12+
@patch("chaosaws.msk.probes.aws_client", autospec=True)
13+
def test_describe_msk_cluster_success(aws_client):
14+
client = MagicMock()
15+
aws_client.return_value = client
16+
cluster_arn = "arn_msk_cluster"
17+
expected_response = {"ClusterInfo": {"ClusterArn": cluster_arn}}
18+
19+
client.describe_cluster.return_value = expected_response
20+
21+
response = describe_msk_cluster(cluster_arn=cluster_arn)
22+
23+
client.describe_cluster.assert_called_with(ClusterArn=cluster_arn)
24+
assert response == expected_response
25+
26+
27+
@patch("chaosaws.msk.probes.aws_client", autospec=True)
28+
def test_describe_msk_cluster_not_found(aws_client):
29+
client = MagicMock()
30+
aws_client.return_value = client
31+
cluster_arn = "arn_msk_cluster"
32+
33+
client.exceptions = MagicMock()
34+
client.exceptions.NotFoundException = NotFoundException
35+
client.describe_cluster.side_effect = NotFoundException(
36+
"Cluster not found"
37+
)
38+
39+
expected_error_message = "The specified cluster was not found"
40+
41+
with pytest.raises(FailedActivity) as exc_info:
42+
describe_msk_cluster(cluster_arn=cluster_arn)
43+
44+
assert expected_error_message in str(
45+
exc_info.value
46+
)
47+
48+
49+
@patch("chaosaws.msk.probes.aws_client", autospec=True)
50+
def test_get_bootstrap_servers_success(aws_client):
51+
client = MagicMock()
52+
aws_client.return_value = client
53+
cluster_arn = "arn_msk_cluster"
54+
bootstrap_servers = "broker1,broker2,broker3"
55+
expected_response = {"BootstrapBrokerString": bootstrap_servers}
56+
57+
client.get_bootstrap_brokers.return_value = expected_response
58+
59+
response = get_bootstrap_servers(cluster_arn=cluster_arn)
60+
61+
client.get_bootstrap_brokers.assert_called_with(ClusterArn=cluster_arn)
62+
assert response == bootstrap_servers.split(",")
63+
64+
65+
@patch("chaosaws.msk.probes.aws_client", autospec=True)
66+
def test_get_bootstrap_server_cluster_not_found(aws_client):
67+
client = MagicMock()
68+
aws_client.return_value = client
69+
cluster_arn = "arn_msk_cluster"
70+
71+
client.exceptions = MagicMock()
72+
client.exceptions.NotFoundException = NotFoundException
73+
client.get_bootstrap_brokers.side_effect = NotFoundException(
74+
"Cluster not found"
75+
)
76+
77+
expected_error_message = "The specified cluster was not found"
78+
79+
with pytest.raises(FailedActivity) as exc_info:
80+
get_bootstrap_servers(cluster_arn=cluster_arn)
81+
82+
assert expected_error_message in str(
83+
exc_info.value
84+
)

0 commit comments

Comments
 (0)