2023-08-13 20:42:50 +00:00
|
|
|
import re
|
2021-08-27 10:28:10 +00:00
|
|
|
|
2023-08-13 20:42:50 +00:00
|
|
|
import boto3
|
|
|
|
import pytest
|
2023-11-30 15:55:51 +00:00
|
|
|
import yaml
|
|
|
|
from botocore.exceptions import ClientError
|
2023-08-13 20:42:50 +00:00
|
|
|
|
2021-08-27 10:28:10 +00:00
|
|
|
from moto import mock_ssm
|
2023-11-30 15:55:51 +00:00
|
|
|
|
2021-08-27 10:28:10 +00:00
|
|
|
from .test_ssm_docs import _get_yaml_template
|
|
|
|
|
|
|
|
|
|
|
|
@mock_ssm
|
|
|
|
def test_describe_document_permissions_unknown_document():
|
|
|
|
client = boto3.client("ssm", region_name="us-east-1")
|
|
|
|
|
|
|
|
with pytest.raises(ClientError) as ex:
|
|
|
|
client.describe_document_permission(
|
|
|
|
Name="UnknownDocument", PermissionType="Share"
|
|
|
|
)
|
|
|
|
err = ex.value.response["Error"]
|
2023-08-13 20:42:50 +00:00
|
|
|
assert err["Code"] == "InvalidDocument"
|
|
|
|
assert err["Message"] == "The specified document does not exist."
|
2021-08-27 10:28:10 +00:00
|
|
|
|
|
|
|
|
|
|
|
def get_client():
|
|
|
|
template_file = _get_yaml_template()
|
|
|
|
json_doc = yaml.safe_load(template_file)
|
|
|
|
client = boto3.client("ssm", region_name="us-east-1")
|
|
|
|
client.create_document(
|
|
|
|
Content=yaml.dump(json_doc),
|
|
|
|
Name="TestDocument",
|
|
|
|
DocumentType="Command",
|
|
|
|
DocumentFormat="YAML",
|
|
|
|
VersionName="Base",
|
|
|
|
)
|
|
|
|
return client
|
|
|
|
|
|
|
|
|
|
|
|
@mock_ssm
|
|
|
|
def test_describe_document_permissions_initial():
|
|
|
|
client = get_client()
|
|
|
|
|
|
|
|
res = client.describe_document_permission(
|
|
|
|
Name="TestDocument", PermissionType="Share"
|
|
|
|
)
|
2023-08-13 20:42:50 +00:00
|
|
|
assert res["AccountIds"] == []
|
|
|
|
assert res["AccountSharingInfoList"] == []
|
2021-08-27 10:28:10 +00:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"ids",
|
|
|
|
[["111111111111"], ["all"], ["All"], ["111111111111", "222222222222"]],
|
|
|
|
ids=["one_value", "all", "All", "multiple_values"],
|
|
|
|
)
|
|
|
|
@mock_ssm
|
|
|
|
def test_modify_document_permission_add_account_id(ids):
|
|
|
|
client = get_client()
|
|
|
|
client.modify_document_permission(
|
|
|
|
Name="TestDocument", PermissionType="Share", AccountIdsToAdd=ids
|
|
|
|
)
|
|
|
|
|
|
|
|
res = client.describe_document_permission(
|
|
|
|
Name="TestDocument", PermissionType="Share"
|
|
|
|
)
|
2023-08-13 20:42:50 +00:00
|
|
|
assert "AccountIds" in res
|
|
|
|
assert set(res["AccountIds"]) == set(ids)
|
|
|
|
assert len(res["AccountSharingInfoList"]) == len(ids)
|
2021-09-08 05:56:20 +00:00
|
|
|
|
|
|
|
expected_account_sharing = [
|
|
|
|
{"AccountId": _id, "SharedDocumentVersion": "$DEFAULT"} for _id in ids
|
|
|
|
]
|
2023-08-13 20:42:50 +00:00
|
|
|
assert res["AccountSharingInfoList"] == expected_account_sharing
|
2021-08-27 10:28:10 +00:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"initial,to_remove",
|
|
|
|
[
|
|
|
|
(["all"], ["all"]),
|
|
|
|
(["111111111111"], ["111111111111"]),
|
|
|
|
(["111111111111", "222222222222"], ["222222222222"]),
|
|
|
|
(
|
|
|
|
["111111111111", "222222222222", "333333333333"],
|
|
|
|
["111111111111", "333333333333"],
|
|
|
|
),
|
|
|
|
],
|
|
|
|
ids=["all", "one_value", "multiple_initials", "multiple_to_remove"],
|
|
|
|
)
|
|
|
|
@mock_ssm
|
|
|
|
def test_modify_document_permission_remove_account_id(initial, to_remove):
|
|
|
|
client = get_client()
|
|
|
|
client.modify_document_permission(
|
|
|
|
Name="TestDocument", PermissionType="Share", AccountIdsToAdd=initial
|
|
|
|
)
|
|
|
|
client.modify_document_permission(
|
|
|
|
Name="TestDocument", PermissionType="Share", AccountIdsToRemove=to_remove
|
|
|
|
)
|
|
|
|
|
|
|
|
res = client.describe_document_permission(
|
|
|
|
Name="TestDocument", PermissionType="Share"
|
|
|
|
)
|
2023-08-13 20:42:50 +00:00
|
|
|
assert "AccountIds" in res
|
|
|
|
expected_new_list = {x for x in initial if x not in to_remove}
|
|
|
|
assert set(res["AccountIds"]) == expected_new_list
|
2021-09-08 05:56:20 +00:00
|
|
|
|
|
|
|
expected_account_sharing = [
|
|
|
|
{"AccountId": _id, "SharedDocumentVersion": "$DEFAULT"}
|
|
|
|
for _id in expected_new_list
|
|
|
|
]
|
2023-08-13 20:42:50 +00:00
|
|
|
assert res["AccountSharingInfoList"] == expected_account_sharing
|
2021-08-27 10:28:10 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ssm
|
|
|
|
def test_fail_modify_document_permission_wrong_permission_type():
|
|
|
|
client = get_client()
|
|
|
|
with pytest.raises(ClientError) as ex:
|
|
|
|
client.modify_document_permission(
|
|
|
|
Name="TestDocument", PermissionType="WrongValue", AccountIdsToAdd=[]
|
|
|
|
)
|
|
|
|
err = ex.value.response["Error"]
|
2023-08-13 20:42:50 +00:00
|
|
|
assert err["Code"] == "InvalidPermissionType"
|
|
|
|
assert re.search(r"Member must satisfy enum value set: \[Share\]", err["Message"])
|
2021-08-27 10:28:10 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ssm
|
|
|
|
def test_fail_modify_document_permission_wrong_document_version():
|
|
|
|
client = get_client()
|
|
|
|
with pytest.raises(ClientError) as ex:
|
|
|
|
client.modify_document_permission(
|
|
|
|
Name="TestDocument",
|
|
|
|
PermissionType="Share",
|
|
|
|
SharedDocumentVersion="unknown",
|
|
|
|
AccountIdsToAdd=[],
|
|
|
|
)
|
|
|
|
err = ex.value.response["Error"]
|
2023-08-13 20:42:50 +00:00
|
|
|
assert err["Code"] == "ValidationException"
|
|
|
|
assert re.search(r"Member must satisfy regular expression pattern", err["Message"])
|
2021-08-27 10:28:10 +00:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"value",
|
|
|
|
[["alll"], ["1234"], ["1234123412341234"], ["account_id"]],
|
|
|
|
ids=["all?", "too_short", "too_long", "no-digits"],
|
|
|
|
)
|
|
|
|
@mock_ssm
|
|
|
|
def test_fail_modify_document_permission_add_invalid_account_ids(value):
|
|
|
|
client = get_client()
|
|
|
|
with pytest.raises(ClientError) as ex:
|
|
|
|
client.modify_document_permission(
|
|
|
|
Name="TestDocument", PermissionType="Share", AccountIdsToAdd=value
|
|
|
|
)
|
|
|
|
err = ex.value.response["Error"]
|
2023-08-13 20:42:50 +00:00
|
|
|
assert err["Code"] == "ValidationException"
|
|
|
|
assert re.search(r"Member must satisfy regular expression pattern:", err["Message"])
|
2021-08-27 10:28:10 +00:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"value",
|
|
|
|
[["alll"], ["1234"], ["1234123412341234"], ["account_id"]],
|
|
|
|
ids=["all?", "too_short", "too_long", "no-digits"],
|
|
|
|
)
|
|
|
|
@mock_ssm
|
|
|
|
def test_fail_modify_document_permission_remove_invalid_account_ids(value):
|
|
|
|
client = get_client()
|
|
|
|
with pytest.raises(ClientError) as ex:
|
|
|
|
client.modify_document_permission(
|
|
|
|
Name="TestDocument", PermissionType="Share", AccountIdsToRemove=value
|
|
|
|
)
|
|
|
|
err = ex.value.response["Error"]
|
2023-08-13 20:42:50 +00:00
|
|
|
assert err["Code"] == "ValidationException"
|
|
|
|
assert re.search(r"Member must satisfy regular expression pattern:", err["Message"])
|
2021-08-27 10:28:10 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ssm
|
|
|
|
def test_fail_modify_document_permission_add_all_and_specific():
|
|
|
|
client = get_client()
|
|
|
|
with pytest.raises(ClientError) as ex:
|
|
|
|
client.modify_document_permission(
|
|
|
|
Name="TestDocument",
|
|
|
|
PermissionType="Share",
|
|
|
|
AccountIdsToAdd=["all", "123412341234"],
|
|
|
|
)
|
|
|
|
err = ex.value.response["Error"]
|
2023-08-13 20:42:50 +00:00
|
|
|
assert err["Code"] == "DocumentPermissionLimit"
|
|
|
|
assert err["Message"] == "Accounts can either be all or a group of AWS accounts"
|
2021-08-27 10:28:10 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ssm
|
|
|
|
def test_fail_modify_document_permission_remove_all_and_specific():
|
|
|
|
client = get_client()
|
|
|
|
with pytest.raises(ClientError) as ex:
|
|
|
|
client.modify_document_permission(
|
|
|
|
Name="TestDocument",
|
|
|
|
PermissionType="Share",
|
|
|
|
AccountIdsToRemove=["all", "123412341234"],
|
|
|
|
)
|
|
|
|
err = ex.value.response["Error"]
|
2023-08-13 20:42:50 +00:00
|
|
|
assert err["Code"] == "DocumentPermissionLimit"
|
|
|
|
assert err["Message"] == "Accounts can either be all or a group of AWS accounts"
|