2021-11-09 22:28:24 +00:00
|
|
|
import boto3
|
|
|
|
|
2024-01-07 12:03:33 +00:00
|
|
|
from moto import mock_aws
|
2021-11-09 22:28:24 +00:00
|
|
|
|
|
|
|
|
2024-01-07 12:03:33 +00:00
|
|
|
@mock_aws
|
2021-11-09 22:28:24 +00:00
|
|
|
def test_describe_maintenance_window():
|
|
|
|
ssm = boto3.client("ssm", region_name="us-east-1")
|
|
|
|
|
|
|
|
resp = ssm.describe_maintenance_windows()
|
2023-08-13 20:42:50 +00:00
|
|
|
assert resp["WindowIdentities"] == []
|
2021-11-09 22:28:24 +00:00
|
|
|
|
|
|
|
resp = ssm.describe_maintenance_windows(
|
|
|
|
Filters=[{"Key": "Name", "Values": ["fake-maintenance-window-name"]}]
|
|
|
|
)
|
2023-08-13 20:42:50 +00:00
|
|
|
assert resp["WindowIdentities"] == []
|
2021-11-09 22:28:24 +00:00
|
|
|
|
|
|
|
|
2024-01-07 12:03:33 +00:00
|
|
|
@mock_aws
|
2021-11-09 22:28:24 +00:00
|
|
|
def test_create_maintenance_windows_simple():
|
|
|
|
ssm = boto3.client("ssm", region_name="us-east-1")
|
|
|
|
|
|
|
|
resp = ssm.create_maintenance_window(
|
|
|
|
Name="simple-window",
|
|
|
|
Schedule="cron(15 12 * * ? *)",
|
|
|
|
Duration=2,
|
|
|
|
Cutoff=1,
|
|
|
|
AllowUnassociatedTargets=False,
|
|
|
|
)
|
2023-08-13 20:42:50 +00:00
|
|
|
assert "WindowId" in resp
|
2021-11-09 22:28:24 +00:00
|
|
|
_id = resp["WindowId"] # mw-01d6bbfdf6af2c39a
|
|
|
|
|
|
|
|
resp = ssm.describe_maintenance_windows()
|
2023-08-13 20:42:50 +00:00
|
|
|
assert len(resp["WindowIdentities"]) == 1
|
2021-11-09 22:28:24 +00:00
|
|
|
|
|
|
|
my_window = resp["WindowIdentities"][0]
|
2023-08-13 20:42:50 +00:00
|
|
|
assert my_window["WindowId"] == _id
|
|
|
|
assert my_window["Name"] == "simple-window"
|
|
|
|
assert my_window["Enabled"] is True
|
|
|
|
assert my_window["Duration"] == 2
|
|
|
|
assert my_window["Cutoff"] == 1
|
|
|
|
assert my_window["Schedule"] == "cron(15 12 * * ? *)"
|
|
|
|
# assert "NextExecutionTime" in my_window
|
|
|
|
assert "Description" not in my_window
|
|
|
|
assert "ScheduleTimezone" not in my_window
|
|
|
|
assert "ScheduleOffset" not in my_window
|
|
|
|
assert "EndDate" not in my_window
|
|
|
|
assert "StartDate" not in my_window
|
2021-11-09 22:28:24 +00:00
|
|
|
|
|
|
|
|
2024-01-07 12:03:33 +00:00
|
|
|
@mock_aws
|
2021-11-09 22:28:24 +00:00
|
|
|
def test_create_maintenance_windows_advanced():
|
|
|
|
ssm = boto3.client("ssm", region_name="us-east-1")
|
|
|
|
|
|
|
|
resp = ssm.create_maintenance_window(
|
|
|
|
Name="simple-window",
|
|
|
|
Description="French windows are just too fancy",
|
|
|
|
Schedule="cron(15 12 * * ? *)",
|
|
|
|
ScheduleTimezone="Europe/London",
|
|
|
|
ScheduleOffset=1,
|
|
|
|
Duration=5,
|
|
|
|
Cutoff=4,
|
|
|
|
AllowUnassociatedTargets=False,
|
|
|
|
StartDate="2021-11-01",
|
|
|
|
EndDate="2021-12-31",
|
|
|
|
)
|
2023-08-13 20:42:50 +00:00
|
|
|
assert "WindowId" in resp
|
2021-11-09 22:28:24 +00:00
|
|
|
_id = resp["WindowId"] # mw-01d6bbfdf6af2c39a
|
|
|
|
|
|
|
|
resp = ssm.describe_maintenance_windows()
|
2023-08-13 20:42:50 +00:00
|
|
|
assert len(resp["WindowIdentities"]) == 1
|
2021-11-09 22:28:24 +00:00
|
|
|
|
|
|
|
my_window = resp["WindowIdentities"][0]
|
2023-08-13 20:42:50 +00:00
|
|
|
assert my_window["WindowId"] == _id
|
|
|
|
assert my_window["Name"] == "simple-window"
|
|
|
|
assert my_window["Enabled"] is True
|
|
|
|
assert my_window["Duration"] == 5
|
|
|
|
assert my_window["Cutoff"] == 4
|
|
|
|
assert my_window["Schedule"] == "cron(15 12 * * ? *)"
|
|
|
|
# assert "NextExecutionTime" in my_window
|
|
|
|
assert my_window["Description"] == "French windows are just too fancy"
|
|
|
|
assert my_window["ScheduleTimezone"] == "Europe/London"
|
|
|
|
assert my_window["ScheduleOffset"] == 1
|
|
|
|
assert my_window["StartDate"] == "2021-11-01"
|
|
|
|
assert my_window["EndDate"] == "2021-12-31"
|
2021-11-09 22:28:24 +00:00
|
|
|
|
|
|
|
|
2024-01-07 12:03:33 +00:00
|
|
|
@mock_aws
|
2021-11-09 22:28:24 +00:00
|
|
|
def test_get_maintenance_windows():
|
|
|
|
ssm = boto3.client("ssm", region_name="us-east-1")
|
|
|
|
|
|
|
|
resp = ssm.create_maintenance_window(
|
|
|
|
Name="my-window",
|
|
|
|
Schedule="cron(15 12 * * ? *)",
|
|
|
|
Duration=2,
|
|
|
|
Cutoff=1,
|
|
|
|
AllowUnassociatedTargets=False,
|
|
|
|
)
|
2023-08-13 20:42:50 +00:00
|
|
|
assert "WindowId" in resp
|
2021-11-09 22:28:24 +00:00
|
|
|
_id = resp["WindowId"] # mw-01d6bbfdf6af2c39a
|
|
|
|
|
|
|
|
my_window = ssm.get_maintenance_window(WindowId=_id)
|
2023-08-13 20:42:50 +00:00
|
|
|
assert my_window["WindowId"] == _id
|
|
|
|
assert my_window["Name"] == "my-window"
|
|
|
|
assert my_window["Enabled"] is True
|
|
|
|
assert my_window["Duration"] == 2
|
|
|
|
assert my_window["Cutoff"] == 1
|
|
|
|
assert my_window["Schedule"] == "cron(15 12 * * ? *)"
|
|
|
|
# assert "NextExecutionTime" in my_window
|
|
|
|
assert "Description" not in my_window
|
|
|
|
assert "ScheduleTimezone" not in my_window
|
|
|
|
assert "ScheduleOffset" not in my_window
|
|
|
|
assert "EndDate" not in my_window
|
|
|
|
assert "StartDate" not in my_window
|
2021-11-09 22:28:24 +00:00
|
|
|
|
|
|
|
|
2024-01-07 12:03:33 +00:00
|
|
|
@mock_aws
|
2021-11-09 22:28:24 +00:00
|
|
|
def test_describe_maintenance_windows():
|
|
|
|
ssm = boto3.client("ssm", region_name="us-east-1")
|
|
|
|
|
|
|
|
for idx in range(0, 4):
|
|
|
|
ssm.create_maintenance_window(
|
|
|
|
Name=f"window_{idx}",
|
|
|
|
Schedule="cron(15 12 * * ? *)",
|
|
|
|
Duration=2,
|
|
|
|
Cutoff=1,
|
|
|
|
AllowUnassociatedTargets=False,
|
|
|
|
)
|
|
|
|
|
|
|
|
resp = ssm.describe_maintenance_windows()
|
2023-08-13 20:42:50 +00:00
|
|
|
assert len(resp["WindowIdentities"]) == 4
|
2021-11-09 22:28:24 +00:00
|
|
|
|
|
|
|
resp = ssm.describe_maintenance_windows(
|
|
|
|
Filters=[{"Key": "Name", "Values": ["window_0", "window_2"]}]
|
|
|
|
)
|
2023-08-13 20:42:50 +00:00
|
|
|
assert len(resp["WindowIdentities"]) == 2
|
2021-11-09 22:28:24 +00:00
|
|
|
|
|
|
|
|
2024-01-07 12:03:33 +00:00
|
|
|
@mock_aws
|
2021-11-09 22:28:24 +00:00
|
|
|
def test_delete_maintenance_windows():
|
|
|
|
ssm = boto3.client("ssm", region_name="us-east-1")
|
|
|
|
|
|
|
|
resp = ssm.create_maintenance_window(
|
|
|
|
Name="simple-window",
|
|
|
|
Schedule="cron(15 12 * * ? *)",
|
|
|
|
Duration=2,
|
|
|
|
Cutoff=1,
|
|
|
|
AllowUnassociatedTargets=False,
|
|
|
|
)
|
|
|
|
|
2023-08-13 20:42:50 +00:00
|
|
|
ssm.delete_maintenance_window(WindowId=resp["WindowId"])
|
2021-11-09 22:28:24 +00:00
|
|
|
|
|
|
|
resp = ssm.describe_maintenance_windows()
|
2023-08-13 20:42:50 +00:00
|
|
|
assert resp["WindowIdentities"] == []
|
2023-05-31 22:31:56 +00:00
|
|
|
|
|
|
|
|
2024-01-07 12:03:33 +00:00
|
|
|
@mock_aws
|
2023-05-31 22:31:56 +00:00
|
|
|
def test_tags():
|
|
|
|
ssm = boto3.client("ssm", region_name="us-east-1")
|
|
|
|
|
|
|
|
# create without & list
|
|
|
|
mw_id = ssm.create_maintenance_window(
|
|
|
|
Name="simple-window",
|
|
|
|
Schedule="cron(15 12 * * ? *)",
|
|
|
|
Duration=2,
|
|
|
|
Cutoff=1,
|
|
|
|
AllowUnassociatedTargets=False,
|
|
|
|
)["WindowId"]
|
|
|
|
|
|
|
|
# add & list
|
|
|
|
ssm.add_tags_to_resource(
|
|
|
|
ResourceType="MaintenanceWindow",
|
|
|
|
ResourceId=mw_id,
|
|
|
|
Tags=[{"Key": "k1", "Value": "v1"}],
|
|
|
|
)
|
|
|
|
tags = ssm.list_tags_for_resource(
|
|
|
|
ResourceType="MaintenanceWindow", ResourceId=mw_id
|
|
|
|
)["TagList"]
|
|
|
|
assert tags == [{"Key": "k1", "Value": "v1"}]
|
|
|
|
|
|
|
|
# create & list
|
|
|
|
mw_id = ssm.create_maintenance_window(
|
|
|
|
Name="simple-window",
|
|
|
|
Schedule="cron(15 12 * * ? *)",
|
|
|
|
Duration=2,
|
|
|
|
Cutoff=1,
|
|
|
|
AllowUnassociatedTargets=False,
|
|
|
|
Tags=[{"Key": "k2", "Value": "v2"}],
|
|
|
|
)["WindowId"]
|
|
|
|
tags = ssm.list_tags_for_resource(
|
|
|
|
ResourceType="MaintenanceWindow", ResourceId=mw_id
|
|
|
|
)["TagList"]
|
|
|
|
assert tags == [{"Key": "k2", "Value": "v2"}]
|
|
|
|
|
|
|
|
# add more & list
|
|
|
|
ssm.add_tags_to_resource(
|
|
|
|
ResourceType="MaintenanceWindow",
|
|
|
|
ResourceId=mw_id,
|
|
|
|
Tags=[{"Key": "k3", "Value": "v3"}],
|
|
|
|
)
|
|
|
|
tags = ssm.list_tags_for_resource(
|
|
|
|
ResourceType="MaintenanceWindow", ResourceId=mw_id
|
|
|
|
)["TagList"]
|
|
|
|
assert tags == [{"Key": "k2", "Value": "v2"}, {"Key": "k3", "Value": "v3"}]
|
|
|
|
|
|
|
|
# remove & list
|
|
|
|
ssm.remove_tags_from_resource(
|
|
|
|
ResourceType="MaintenanceWindow", ResourceId=mw_id, TagKeys=["k3"]
|
|
|
|
)
|
|
|
|
tags = ssm.list_tags_for_resource(
|
|
|
|
ResourceType="MaintenanceWindow", ResourceId=mw_id
|
|
|
|
)["TagList"]
|
|
|
|
assert tags == [{"Key": "k2", "Value": "v2"}]
|
2023-06-23 10:22:35 +00:00
|
|
|
|
|
|
|
|
2024-01-07 12:03:33 +00:00
|
|
|
@mock_aws
|
2023-06-23 10:22:35 +00:00
|
|
|
def test_register_maintenance_window_target():
|
|
|
|
ssm = boto3.client("ssm", region_name="us-east-1")
|
|
|
|
|
|
|
|
resp = ssm.create_maintenance_window(
|
|
|
|
Name="simple-window",
|
|
|
|
Schedule="cron(15 12 * * ? *)",
|
|
|
|
Duration=2,
|
|
|
|
Cutoff=1,
|
|
|
|
AllowUnassociatedTargets=False,
|
|
|
|
)
|
|
|
|
window_id = resp["WindowId"]
|
|
|
|
|
|
|
|
resp = ssm.register_target_with_maintenance_window(
|
|
|
|
WindowId=window_id,
|
|
|
|
ResourceType="INSTANCE",
|
|
|
|
Targets=[{"Key": "tag:Name", "Values": ["my-instance"]}],
|
|
|
|
)
|
2023-08-13 20:42:50 +00:00
|
|
|
assert "WindowTargetId" in resp
|
2023-06-23 10:22:35 +00:00
|
|
|
_id = resp["WindowTargetId"]
|
|
|
|
|
|
|
|
resp = ssm.describe_maintenance_window_targets(
|
|
|
|
WindowId=window_id,
|
|
|
|
)
|
2023-08-13 20:42:50 +00:00
|
|
|
assert len(resp["Targets"]) == 1
|
|
|
|
assert resp["Targets"][0]["ResourceType"] == "INSTANCE"
|
|
|
|
assert resp["Targets"][0]["WindowTargetId"] == _id
|
|
|
|
assert resp["Targets"][0]["Targets"][0]["Key"] == "tag:Name"
|
|
|
|
assert resp["Targets"][0]["Targets"][0]["Values"] == ["my-instance"]
|
2023-06-23 10:22:35 +00:00
|
|
|
|
|
|
|
|
2024-01-07 12:03:33 +00:00
|
|
|
@mock_aws
|
2023-06-23 10:22:35 +00:00
|
|
|
def test_deregister_target_from_maintenance_window():
|
|
|
|
ssm = boto3.client("ssm", region_name="us-east-1")
|
|
|
|
|
|
|
|
resp = ssm.create_maintenance_window(
|
|
|
|
Name="simple-window",
|
|
|
|
Schedule="cron(15 12 * * ? *)",
|
|
|
|
Duration=2,
|
|
|
|
Cutoff=1,
|
|
|
|
AllowUnassociatedTargets=False,
|
|
|
|
)
|
|
|
|
window_id = resp["WindowId"]
|
|
|
|
|
|
|
|
resp = ssm.register_target_with_maintenance_window(
|
|
|
|
WindowId=window_id,
|
|
|
|
ResourceType="INSTANCE",
|
|
|
|
Targets=[{"Key": "tag:Name", "Values": ["my-instance"]}],
|
|
|
|
)
|
|
|
|
_id = resp["WindowTargetId"]
|
|
|
|
|
|
|
|
ssm.deregister_target_from_maintenance_window(
|
|
|
|
WindowId=window_id,
|
|
|
|
WindowTargetId=_id,
|
|
|
|
)
|
|
|
|
|
|
|
|
resp = ssm.describe_maintenance_window_targets(
|
|
|
|
WindowId=window_id,
|
|
|
|
)
|
2023-08-13 20:42:50 +00:00
|
|
|
assert len(resp["Targets"]) == 0
|
2023-06-28 21:30:11 +00:00
|
|
|
|
|
|
|
|
2024-01-07 12:03:33 +00:00
|
|
|
@mock_aws
|
2023-06-28 21:30:11 +00:00
|
|
|
def test_describe_maintenance_window_with_no_task_or_targets():
|
|
|
|
ssm = boto3.client("ssm", region_name="us-east-1")
|
|
|
|
|
|
|
|
resp = ssm.create_maintenance_window(
|
|
|
|
Name="simple-window",
|
|
|
|
Schedule="cron(15 12 * * ? *)",
|
|
|
|
Duration=2,
|
|
|
|
Cutoff=1,
|
|
|
|
AllowUnassociatedTargets=False,
|
|
|
|
)
|
|
|
|
window_id = resp["WindowId"]
|
|
|
|
|
|
|
|
resp = ssm.describe_maintenance_window_tasks(
|
|
|
|
WindowId=window_id,
|
|
|
|
)
|
2023-08-13 20:42:50 +00:00
|
|
|
assert len(resp["Tasks"]) == 0
|
2023-06-28 21:30:11 +00:00
|
|
|
|
|
|
|
resp = ssm.describe_maintenance_window_targets(
|
|
|
|
WindowId=window_id,
|
|
|
|
)
|
2023-08-13 20:42:50 +00:00
|
|
|
assert len(resp["Targets"]) == 0
|
2023-06-28 21:30:11 +00:00
|
|
|
|
|
|
|
|
2024-01-07 12:03:33 +00:00
|
|
|
@mock_aws
|
2023-06-28 21:30:11 +00:00
|
|
|
def test_register_maintenance_window_task():
|
|
|
|
ssm = boto3.client("ssm", region_name="us-east-1")
|
|
|
|
|
|
|
|
resp = ssm.create_maintenance_window(
|
|
|
|
Name="simple-window",
|
|
|
|
Schedule="cron(15 12 * * ? *)",
|
|
|
|
Duration=2,
|
|
|
|
Cutoff=1,
|
|
|
|
AllowUnassociatedTargets=False,
|
|
|
|
)
|
|
|
|
window_id = resp["WindowId"]
|
|
|
|
|
|
|
|
resp = ssm.register_target_with_maintenance_window(
|
|
|
|
WindowId=window_id,
|
|
|
|
ResourceType="INSTANCE",
|
|
|
|
Targets=[{"Key": "tag:Name", "Values": ["my-instance"]}],
|
|
|
|
)
|
|
|
|
window_target_id = resp["WindowTargetId"]
|
|
|
|
|
|
|
|
resp = ssm.register_task_with_maintenance_window(
|
|
|
|
WindowId=window_id,
|
|
|
|
Targets=[{"Key": "WindowTargetIds", "Values": [window_target_id]}],
|
|
|
|
TaskArn="AWS-RunShellScript",
|
|
|
|
TaskType="RUN_COMMAND",
|
|
|
|
MaxConcurrency="1",
|
|
|
|
MaxErrors="1",
|
|
|
|
)
|
|
|
|
|
2023-08-13 20:42:50 +00:00
|
|
|
assert "WindowTaskId" in resp
|
2023-06-28 21:30:11 +00:00
|
|
|
_id = resp["WindowTaskId"]
|
|
|
|
|
|
|
|
resp = ssm.describe_maintenance_window_tasks(
|
|
|
|
WindowId=window_id,
|
|
|
|
)
|
2023-08-13 20:42:50 +00:00
|
|
|
assert len(resp["Tasks"]) == 1
|
|
|
|
assert resp["Tasks"][0]["WindowTaskId"] == _id
|
|
|
|
assert resp["Tasks"][0]["WindowId"] == window_id
|
|
|
|
assert resp["Tasks"][0]["TaskArn"] == "AWS-RunShellScript"
|
|
|
|
assert resp["Tasks"][0]["MaxConcurrency"] == "1"
|
|
|
|
assert resp["Tasks"][0]["MaxErrors"] == "1"
|
2023-06-28 21:30:11 +00:00
|
|
|
|
|
|
|
|
2024-01-07 12:03:33 +00:00
|
|
|
@mock_aws
|
2023-06-28 21:30:11 +00:00
|
|
|
def test_deregister_maintenance_window_task():
|
|
|
|
ssm = boto3.client("ssm", region_name="us-east-1")
|
|
|
|
|
|
|
|
resp = ssm.create_maintenance_window(
|
|
|
|
Name="simple-window",
|
|
|
|
Schedule="cron(15 12 * * ? *)",
|
|
|
|
Duration=2,
|
|
|
|
Cutoff=1,
|
|
|
|
AllowUnassociatedTargets=False,
|
|
|
|
)
|
|
|
|
window_id = resp["WindowId"]
|
|
|
|
|
|
|
|
resp = ssm.register_target_with_maintenance_window(
|
|
|
|
WindowId=window_id,
|
|
|
|
ResourceType="INSTANCE",
|
|
|
|
Targets=[{"Key": "tag:Name", "Values": ["my-instance"]}],
|
|
|
|
)
|
|
|
|
window_target_id = resp["WindowTargetId"]
|
|
|
|
|
|
|
|
resp = ssm.register_task_with_maintenance_window(
|
|
|
|
WindowId=window_id,
|
|
|
|
Targets=[{"Key": "WindowTargetIds", "Values": [window_target_id]}],
|
|
|
|
TaskArn="AWS-RunShellScript",
|
|
|
|
TaskType="RUN_COMMAND",
|
|
|
|
MaxConcurrency="1",
|
|
|
|
MaxErrors="1",
|
|
|
|
)
|
|
|
|
window_task_id = resp["WindowTaskId"]
|
|
|
|
|
|
|
|
ssm.deregister_task_from_maintenance_window(
|
|
|
|
WindowId=window_id,
|
|
|
|
WindowTaskId=window_task_id,
|
|
|
|
)
|
|
|
|
|
|
|
|
resp = ssm.describe_maintenance_window_tasks(
|
|
|
|
WindowId=window_id,
|
|
|
|
)
|
2023-08-13 20:42:50 +00:00
|
|
|
assert len(resp["Tasks"]) == 0
|