moto/tests/test_organizations/test_organizations_boto3.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

2175 lines
82 KiB
Python
Raw Normal View History

import json
import re
from datetime import datetime
import boto3
import pytest
from botocore.exceptions import ClientError
2024-01-07 12:03:33 +00:00
from moto import mock_aws
from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
from moto.organizations import utils
from moto.organizations.exceptions import InvalidInputException, TargetNotFoundException
from moto.organizations.models import (
FakeAccount,
FakeOrganization,
FakeOrganizationalUnit,
FakePolicy,
FakeRoot,
OrganizationsBackend,
)
from .organizations_test_utils import (
validate_account,
validate_create_account_status,
validate_organization,
validate_organizational_unit,
validate_policy_summary,
validate_roots,
validate_service_control_policy,
)
2018-07-14 20:23:15 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
def test_create_organization():
client = boto3.client("organizations", region_name="us-east-1")
response = client.create_organization(FeatureSet="ALL")
validate_organization(response)
assert response["Organization"]["FeatureSet"] == "ALL"
response = client.list_accounts()
assert len(response["Accounts"]) == 1
assert response["Accounts"][0]["Name"] == "master"
assert response["Accounts"][0]["Id"] == ACCOUNT_ID
assert response["Accounts"][0]["Email"] == utils.MASTER_ACCOUNT_EMAIL
response = client.list_policies(Filter="SERVICE_CONTROL_POLICY")
assert len(response["Policies"]) == 1
assert response["Policies"][0]["Name"] == "FullAWSAccess"
assert response["Policies"][0]["Id"] == utils.DEFAULT_POLICY_ID
assert response["Policies"][0]["AwsManaged"] is True
response = client.list_targets_for_policy(PolicyId=utils.DEFAULT_POLICY_ID)
assert len(response["Targets"]) == 2
root_ou = [t for t in response["Targets"] if t["Type"] == "ROOT"][0]
assert root_ou["Name"] == "Root"
master_account = [t for t in response["Targets"] if t["Type"] == "ACCOUNT"][0]
assert master_account["Name"] == "master"
2018-07-14 20:23:15 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
def test_create_organization_without_feature_set():
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization()
response = client.describe_organization()
validate_organization(response)
assert response["Organization"]["FeatureSet"] == "ALL"
2024-01-07 12:03:33 +00:00
@mock_aws
def test_describe_organization():
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization(FeatureSet="ALL")
response = client.describe_organization()
validate_organization(response)
2024-01-07 12:03:33 +00:00
@mock_aws
def test_describe_organization_exception():
client = boto3.client("organizations", region_name="us-east-1")
with pytest.raises(ClientError) as e:
2021-10-18 19:44:29 +00:00
client.describe_organization()
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "DescribeOrganization"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "AWSOrganizationsNotInUseException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == (
"Your account is not a member of an organization."
)
# Organizational Units
2019-10-31 15:44:26 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2018-07-15 17:31:16 +00:00
def test_list_roots():
client = boto3.client("organizations", region_name="us-east-1")
org = client.create_organization(FeatureSet="ALL")["Organization"]
response = client.list_roots()
validate_roots(org, response)
2018-07-15 17:31:16 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
def test_create_organizational_unit():
client = boto3.client("organizations", region_name="us-east-1")
org = client.create_organization(FeatureSet="ALL")["Organization"]
root_id = client.list_roots()["Roots"][0]["Id"]
ou_name = "ou01"
response = client.create_organizational_unit(ParentId=root_id, Name=ou_name)
validate_organizational_unit(org, response)
assert response["OrganizationalUnit"]["Name"] == ou_name
2024-01-07 12:03:33 +00:00
@mock_aws
def test_delete_organizational_unit():
client = boto3.client("organizations", region_name="us-east-1")
org = client.create_organization(FeatureSet="ALL")["Organization"]
root_id = client.list_roots()["Roots"][0]["Id"]
ou_name = "ou01"
response = client.create_organizational_unit(ParentId=root_id, Name=ou_name)
validate_organizational_unit(org, response)
# delete organizational unit
ou_id = response["OrganizationalUnit"]["Id"]
response = client.delete_organizational_unit(OrganizationalUnitId=ou_id)
assert response["ResponseMetadata"]["HTTPStatusCode"] == 200
# verify the deletion
with pytest.raises(ClientError) as e:
client.describe_organizational_unit(OrganizationalUnitId=ou_id)
ex = e.value
assert ex.operation_name == "DescribeOrganizationalUnit"
assert ex.response["Error"]["Code"] == "400"
assert "OrganizationalUnitNotFoundException" in ex.response["Error"]["Message"]
2024-01-07 12:03:33 +00:00
@mock_aws
def test_describe_organizational_unit():
client = boto3.client("organizations", region_name="us-east-1")
org = client.create_organization(FeatureSet="ALL")["Organization"]
root_id = client.list_roots()["Roots"][0]["Id"]
ou_id = client.create_organizational_unit(ParentId=root_id, Name="ou01")[
"OrganizationalUnit"
]["Id"]
response = client.describe_organizational_unit(OrganizationalUnitId=ou_id)
validate_organizational_unit(org, response)
2024-01-07 12:03:33 +00:00
@mock_aws
def test_describe_organizational_unit_exception():
client = boto3.client("organizations", region_name="us-east-1")
_ = client.create_organization(FeatureSet="ALL")["Organization"]
with pytest.raises(ClientError) as e:
2021-10-18 19:44:29 +00:00
client.describe_organizational_unit(
OrganizationalUnitId=utils.make_random_root_id()
)
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "DescribeOrganizationalUnit"
assert ex.response["Error"]["Code"] == "400"
assert "OrganizationalUnitNotFoundException" in ex.response["Error"]["Message"]
2024-01-07 12:03:33 +00:00
@mock_aws
def test_list_organizational_units_for_parent():
client = boto3.client("organizations", region_name="us-east-1")
org = client.create_organization(FeatureSet="ALL")["Organization"]
root_id = client.list_roots()["Roots"][0]["Id"]
client.create_organizational_unit(ParentId=root_id, Name="ou01")
client.create_organizational_unit(ParentId=root_id, Name="ou02")
client.create_organizational_unit(ParentId=root_id, Name="ou03")
response = client.list_organizational_units_for_parent(ParentId=root_id)
assert isinstance(response["OrganizationalUnits"], list)
for ou in response["OrganizationalUnits"]:
validate_organizational_unit(org, {"OrganizationalUnit": ou})
2024-01-07 12:03:33 +00:00
@mock_aws
def test_list_organizational_units_pagination():
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization(FeatureSet="ALL")
root_id = client.list_roots()["Roots"][0]["Id"]
for i in range(20):
name = "ou" + str(i)
client.create_organizational_unit(ParentId=root_id, Name=name)
response = client.list_organizational_units_for_parent(ParentId=root_id)
assert "NextToken" not in response
assert len(response["OrganizationalUnits"]) >= i
paginator = client.get_paginator("list_organizational_units_for_parent")
page_iterator = paginator.paginate(MaxResults=5, ParentId=root_id)
page_list = list(page_iterator)
for page in page_list:
assert len(page["OrganizationalUnits"]) <= 5
assert "19" in page_list[-1]["OrganizationalUnits"][-1]["Name"]
2024-01-07 12:03:33 +00:00
@mock_aws
def test_list_organizational_units_for_parent_exception():
client = boto3.client("organizations", region_name="us-east-1")
with pytest.raises(ClientError) as e:
2021-10-18 19:44:29 +00:00
client.list_organizational_units_for_parent(
ParentId=utils.make_random_root_id()
)
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "ListOrganizationalUnitsForParent"
assert ex.response["Error"]["Code"] == "400"
assert "ParentNotFoundException" in ex.response["Error"]["Message"]
# Accounts
mockname = "mock-account"
mockdomain = "moto-example.org"
mockemail = "@".join([mockname, mockdomain])
2018-07-14 20:23:15 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
def test_create_account():
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization(FeatureSet="ALL")
create_status = client.create_account(AccountName=mockname, Email=mockemail)[
2018-07-14 20:23:15 +00:00
"CreateAccountStatus"
]
validate_create_account_status(create_status)
assert create_status["AccountName"] == mockname
2018-07-14 20:23:15 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
def test_close_account_returns_nothing():
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization(FeatureSet="ALL")
create_status = client.create_account(AccountName=mockname, Email=mockemail)[
"CreateAccountStatus"
]
created_account_id = create_status["AccountId"]
resp = client.close_account(AccountId=created_account_id)
del resp["ResponseMetadata"]
assert resp == {}
2024-01-07 12:03:33 +00:00
@mock_aws
def test_close_account_puts_account_in_suspended_status():
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization(FeatureSet="ALL")
create_status = client.create_account(AccountName=mockname, Email=mockemail)[
"CreateAccountStatus"
]
created_account_id = create_status["AccountId"]
client.close_account(AccountId=created_account_id)
account = client.describe_account(AccountId=created_account_id)["Account"]
assert account["Status"] == "SUSPENDED"
2024-01-07 12:03:33 +00:00
@mock_aws
def test_close_account_id_not_in_org_raises_exception():
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization(FeatureSet="ALL")
uncreated_fake_account_id = "123456789101"
with pytest.raises(ClientError) as e:
client.close_account(AccountId=uncreated_fake_account_id)
ex = e.value
assert ex.operation_name == "CloseAccount"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "AccountNotFoundException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == (
"You specified an account that doesn't exist."
)
2024-01-07 12:03:33 +00:00
@mock_aws
def test_describe_create_account_status():
client = boto3.client("organizations", region_name="us-east-1")
_ = client.create_organization(FeatureSet="ALL")["Organization"]
request_id = client.create_account(AccountName=mockname, Email=mockemail)[
"CreateAccountStatus"
]["Id"]
response = client.describe_create_account_status(CreateAccountRequestId=request_id)
validate_create_account_status(response["CreateAccountStatus"])
2024-01-07 12:03:33 +00:00
@mock_aws
def test_describe_account():
client = boto3.client("organizations", region_name="us-east-1")
org = client.create_organization(FeatureSet="ALL")["Organization"]
2018-07-14 20:23:15 +00:00
account_id = client.create_account(AccountName=mockname, Email=mockemail)[
"CreateAccountStatus"
]["AccountId"]
response = client.describe_account(AccountId=account_id)
validate_account(org, response["Account"])
assert response["Account"]["Name"] == mockname
assert response["Account"]["Email"] == mockemail
2018-07-14 20:23:15 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
def test_describe_account_exception():
client = boto3.client("organizations", region_name="us-east-1")
with pytest.raises(ClientError) as e:
2021-10-18 19:44:29 +00:00
client.describe_account(AccountId=utils.make_random_account_id())
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "DescribeAccount"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "AccountNotFoundException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == (
"You specified an account that doesn't exist."
)
2024-01-07 12:03:33 +00:00
@mock_aws
def test_list_accounts():
client = boto3.client("organizations", region_name="us-east-1")
org = client.create_organization(FeatureSet="ALL")["Organization"]
for i in range(5):
name = mockname + str(i)
email = name + "@" + mockdomain
client.create_account(AccountName=name, Email=email)
response = client.list_accounts()
assert "Accounts" in response
accounts = response["Accounts"]
assert len(accounts) == 6
for account in accounts:
validate_account(org, account)
assert accounts[4]["Name"] == mockname + "3"
assert accounts[3]["Email"] == mockname + "2" + "@" + mockdomain
2024-01-07 12:03:33 +00:00
@mock_aws
def test_list_accounts_pagination():
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization(FeatureSet="ALL")
for i in range(25):
name = mockname + str(i)
email = name + "@" + mockdomain
client.create_account(AccountName=name, Email=email)
response = client.list_accounts()
assert "NextToken" not in response
assert len(response["Accounts"]) >= i
paginator = client.get_paginator("list_accounts")
page_iterator = paginator.paginate(MaxResults=5)
page_list = list(page_iterator)
for page in page_list:
assert len(page["Accounts"]) <= 5
assert "24" in page_list[-1]["Accounts"][-1]["Name"]
2024-01-07 12:03:33 +00:00
@mock_aws
def test_list_accounts_for_parent():
client = boto3.client("organizations", region_name="us-east-1")
_ = client.create_organization(FeatureSet="ALL")["Organization"]
root_id = client.list_roots()["Roots"][0]["Id"]
account_id = client.create_account(AccountName=mockname, Email=mockemail)[
"CreateAccountStatus"
]["AccountId"]
response = client.list_accounts_for_parent(ParentId=root_id)
assert account_id in [account["Id"] for account in response["Accounts"]]
2024-01-07 12:03:33 +00:00
@mock_aws
def test_list_accounts_for_parent_pagination():
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization(FeatureSet="ALL")
root_id = client.list_roots()["Roots"][0]["Id"]
response = client.list_accounts_for_parent(ParentId=root_id)
assert "NextToken" not in response
num_existing_accounts = len(response["Accounts"])
for i in range(num_existing_accounts, 21):
name = mockname + str(i)
email = name + "@" + mockdomain
client.create_account(AccountName=name, Email=email)
response = client.list_accounts_for_parent(ParentId=root_id)
assert len(response["Accounts"]) >= i
paginator = client.get_paginator("list_accounts_for_parent")
page_iterator = paginator.paginate(MaxResults=5, ParentId=root_id)
page_list = list(page_iterator)
for page in page_list:
assert len(page["Accounts"]) <= 5
assert "20" in page_list[-1]["Accounts"][-1]["Name"]
2024-01-07 12:03:33 +00:00
@mock_aws
def test_move_account():
client = boto3.client("organizations", region_name="us-east-1")
_ = client.create_organization(FeatureSet="ALL")["Organization"]
root_id = client.list_roots()["Roots"][0]["Id"]
account_id = client.create_account(AccountName=mockname, Email=mockemail)[
"CreateAccountStatus"
]["AccountId"]
ou01 = client.create_organizational_unit(ParentId=root_id, Name="ou01")
ou01_id = ou01["OrganizationalUnit"]["Id"]
client.move_account(
AccountId=account_id, SourceParentId=root_id, DestinationParentId=ou01_id
)
response = client.list_accounts_for_parent(ParentId=ou01_id)
assert account_id in [account["Id"] for account in response["Accounts"]]
2024-01-07 12:03:33 +00:00
@mock_aws
def test_list_parents_for_ou():
client = boto3.client("organizations", region_name="us-east-1")
_ = client.create_organization(FeatureSet="ALL")["Organization"]
root_id = client.list_roots()["Roots"][0]["Id"]
ou01 = client.create_organizational_unit(ParentId=root_id, Name="ou01")
ou01_id = ou01["OrganizationalUnit"]["Id"]
response01 = client.list_parents(ChildId=ou01_id)
assert isinstance(response01["Parents"], list)
assert response01["Parents"][0]["Id"] == root_id
assert response01["Parents"][0]["Type"] == "ROOT"
ou02 = client.create_organizational_unit(ParentId=ou01_id, Name="ou02")
ou02_id = ou02["OrganizationalUnit"]["Id"]
response02 = client.list_parents(ChildId=ou02_id)
assert isinstance(response02["Parents"], list)
assert response02["Parents"][0]["Id"] == ou01_id
assert response02["Parents"][0]["Type"] == "ORGANIZATIONAL_UNIT"
2024-01-07 12:03:33 +00:00
@mock_aws
def test_list_parents_for_accounts():
client = boto3.client("organizations", region_name="us-east-1")
_ = client.create_organization(FeatureSet="ALL")["Organization"]
root_id = client.list_roots()["Roots"][0]["Id"]
ou01 = client.create_organizational_unit(ParentId=root_id, Name="ou01")
ou01_id = ou01["OrganizationalUnit"]["Id"]
account01_id = client.create_account(
AccountName="account01", Email="account01@moto-example.org"
)["CreateAccountStatus"]["AccountId"]
account02_id = client.create_account(
AccountName="account02", Email="account02@moto-example.org"
)["CreateAccountStatus"]["AccountId"]
client.move_account(
AccountId=account02_id, SourceParentId=root_id, DestinationParentId=ou01_id
)
response01 = client.list_parents(ChildId=account01_id)
assert isinstance(response01["Parents"], list)
assert response01["Parents"][0]["Id"] == root_id
assert response01["Parents"][0]["Type"] == "ROOT"
response02 = client.list_parents(ChildId=account02_id)
assert isinstance(response02["Parents"], list)
assert response02["Parents"][0]["Id"] == ou01_id
assert response02["Parents"][0]["Type"] == "ORGANIZATIONAL_UNIT"
2024-01-07 12:03:33 +00:00
@mock_aws
def test_list_children():
client = boto3.client("organizations", region_name="us-east-1")
_ = client.create_organization(FeatureSet="ALL")["Organization"]
root_id = client.list_roots()["Roots"][0]["Id"]
ou01 = client.create_organizational_unit(ParentId=root_id, Name="ou01")
ou01_id = ou01["OrganizationalUnit"]["Id"]
ou02 = client.create_organizational_unit(ParentId=ou01_id, Name="ou02")
ou02_id = ou02["OrganizationalUnit"]["Id"]
account01_id = client.create_account(
AccountName="account01", Email="account01@moto-example.org"
)["CreateAccountStatus"]["AccountId"]
account02_id = client.create_account(
AccountName="account02", Email="account02@moto-example.org"
)["CreateAccountStatus"]["AccountId"]
client.move_account(
AccountId=account02_id, SourceParentId=root_id, DestinationParentId=ou01_id
)
response01 = client.list_children(ParentId=root_id, ChildType="ACCOUNT")
response02 = client.list_children(ParentId=root_id, ChildType="ORGANIZATIONAL_UNIT")
response03 = client.list_children(ParentId=ou01_id, ChildType="ACCOUNT")
response04 = client.list_children(ParentId=ou01_id, ChildType="ORGANIZATIONAL_UNIT")
assert response01["Children"][0]["Id"] == ACCOUNT_ID
assert response01["Children"][0]["Type"] == "ACCOUNT"
assert response01["Children"][1]["Id"] == account01_id
assert response01["Children"][1]["Type"] == "ACCOUNT"
assert response02["Children"][0]["Id"] == ou01_id
assert response02["Children"][0]["Type"] == "ORGANIZATIONAL_UNIT"
assert response03["Children"][0]["Id"] == account02_id
assert response03["Children"][0]["Type"] == "ACCOUNT"
assert response04["Children"][0]["Id"] == ou02_id
assert response04["Children"][0]["Type"] == "ORGANIZATIONAL_UNIT"
2024-01-07 12:03:33 +00:00
@mock_aws
def test_list_children_exception():
client = boto3.client("organizations", region_name="us-east-1")
_ = client.create_organization(FeatureSet="ALL")["Organization"]
root_id = client.list_roots()["Roots"][0]["Id"]
with pytest.raises(ClientError) as e:
2021-10-18 19:44:29 +00:00
client.list_children(ParentId=utils.make_random_root_id(), ChildType="ACCOUNT")
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "ListChildren"
assert ex.response["Error"]["Code"] == "400"
assert "ParentNotFoundException" in ex.response["Error"]["Message"]
with pytest.raises(ClientError) as e:
2021-10-18 19:44:29 +00:00
client.list_children(ParentId=root_id, ChildType="BLEE")
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "ListChildren"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "InvalidInputException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == "You specified an invalid value."
2024-01-07 12:03:33 +00:00
@mock_aws
def test_list_create_account_status():
client = boto3.client("organizations", region_name="us-east-1")
_ = client.create_organization(FeatureSet="ALL")["Organization"]
response = client.list_create_account_status()
createAccountStatuses = response["CreateAccountStatuses"]
assert len(createAccountStatuses) == 1
validate_create_account_status(createAccountStatuses[0])
_ = client.create_account(AccountName=mockname, Email=mockemail)[
"CreateAccountStatus"
]["Id"]
response = client.list_create_account_status()
createAccountStatuses = response["CreateAccountStatuses"]
assert len(createAccountStatuses) == 2
for createAccountStatus in createAccountStatuses:
validate_create_account_status(createAccountStatus)
2024-01-07 12:03:33 +00:00
@mock_aws
def test_list_create_account_status_succeeded():
client = boto3.client("organizations", region_name="us-east-1")
_ = client.create_organization(FeatureSet="ALL")["Organization"]
requiredStates = ["SUCCEEDED"]
response = client.list_create_account_status(States=requiredStates)
createAccountStatuses = response["CreateAccountStatuses"]
assert len(createAccountStatuses) == 1
validate_create_account_status(createAccountStatuses[0])
2024-01-07 12:03:33 +00:00
@mock_aws
def test_list_create_account_status_in_progress():
client = boto3.client("organizations", region_name="us-east-1")
_ = client.create_organization(FeatureSet="ALL")["Organization"]
requiredStates = ["IN_PROGRESS"]
response = client.list_create_account_status(States=requiredStates)
createAccountStatuses = response["CreateAccountStatuses"]
assert len(createAccountStatuses) == 0
2024-01-07 12:03:33 +00:00
@mock_aws
def test_get_paginated_list_create_account_status():
client = boto3.client("organizations", region_name="us-east-1")
_ = client.create_organization(FeatureSet="ALL")["Organization"]
2021-10-18 19:44:29 +00:00
for _ in range(5):
_ = client.create_account(AccountName=mockname, Email=mockemail)[
"CreateAccountStatus"
]["Id"]
response = client.list_create_account_status(MaxResults=2)
createAccountStatuses = response["CreateAccountStatuses"]
assert len(createAccountStatuses) == 2
for createAccountStatus in createAccountStatuses:
validate_create_account_status(createAccountStatus)
next_token = response["NextToken"]
assert next_token is not None
response2 = client.list_create_account_status(NextToken=next_token)
createAccountStatuses.extend(response2["CreateAccountStatuses"])
assert len(createAccountStatuses) == 6
assert "NextToken" not in response2.keys()
for createAccountStatus in createAccountStatuses:
validate_create_account_status(createAccountStatus)
2024-01-07 12:03:33 +00:00
@mock_aws
def test_remove_account_from_organization():
client = boto3.client("organizations", region_name="us-east-1")
_ = client.create_organization(FeatureSet="ALL")["Organization"]
create_account_status = client.create_account(
AccountName=mockname, Email=mockemail
)["CreateAccountStatus"]
account_id = create_account_status["AccountId"]
def created_account_exists(accounts):
return any(
account
for account in accounts
if account["Name"] == mockname and account["Email"] == mockemail
)
accounts = client.list_accounts()["Accounts"]
assert len(accounts) == 2
assert created_account_exists(accounts)
client.remove_account_from_organization(AccountId=account_id)
accounts = client.list_accounts()["Accounts"]
assert len(accounts) == 1
assert not created_account_exists(accounts)
2024-01-07 12:03:33 +00:00
@mock_aws
def test_delete_organization_with_existing_account():
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization(FeatureSet="ALL")
create_account_status = client.create_account(
Email=mockemail, AccountName=mockname
)["CreateAccountStatus"]
account_id = create_account_status["AccountId"]
with pytest.raises(ClientError) as e:
client.delete_organization()
e.match("OrganizationNotEmptyException")
client.remove_account_from_organization(AccountId=account_id)
client.delete_organization()
with pytest.raises(ClientError) as e:
client.describe_organization()
e.match("AWSOrganizationsNotInUseException")
# Service Control Policies
policy_doc01 = {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "MockPolicyStatement",
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*",
}
],
}
2019-10-31 15:44:26 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
def test_create_policy():
client = boto3.client("organizations", region_name="us-east-1")
org = client.create_organization(FeatureSet="ALL")["Organization"]
policy = client.create_policy(
Content=json.dumps(policy_doc01),
Description="A dummy service control policy",
Name="MockServiceControlPolicy",
Type="SERVICE_CONTROL_POLICY",
)["Policy"]
validate_service_control_policy(org, policy)
assert policy["PolicySummary"]["Name"] == "MockServiceControlPolicy"
assert policy["PolicySummary"]["Description"] == "A dummy service control policy"
assert policy["Content"] == json.dumps(policy_doc01)
2024-01-07 12:03:33 +00:00
@mock_aws
def test_create_policy_errors():
# given
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization(FeatureSet="ALL")
# invalid policy type
# when
with pytest.raises(ClientError) as e:
client.create_policy(
Content=json.dumps(policy_doc01),
Description="moto",
Name="moto",
Type="MOTO",
)
# then
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "CreatePolicy"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "InvalidInputException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == "You specified an invalid value."
2024-01-07 12:03:33 +00:00
@mock_aws
def test_describe_policy():
client = boto3.client("organizations", region_name="us-east-1")
org = client.create_organization(FeatureSet="ALL")["Organization"]
policy_id = client.create_policy(
Content=json.dumps(policy_doc01),
Description="A dummy service control policy",
Name="MockServiceControlPolicy",
Type="SERVICE_CONTROL_POLICY",
)["Policy"]["PolicySummary"]["Id"]
policy = client.describe_policy(PolicyId=policy_id)["Policy"]
validate_service_control_policy(org, policy)
assert policy["PolicySummary"]["Name"] == "MockServiceControlPolicy"
assert policy["PolicySummary"]["Description"] == "A dummy service control policy"
assert policy["Content"] == json.dumps(policy_doc01)
2024-01-07 12:03:33 +00:00
@mock_aws
def test_describe_policy_exception():
client = boto3.client("organizations", region_name="us-east-1")
_ = client.create_organization(FeatureSet="ALL")["Organization"]
policy_id = "p-47fhe9s3"
with pytest.raises(ClientError) as e:
2021-10-18 19:44:29 +00:00
client.describe_policy(PolicyId=policy_id)
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "DescribePolicy"
assert ex.response["Error"]["Code"] == "PolicyNotFoundException"
assert (
ex.response["Error"]["Message"] == "You specified a policy that doesn't exist."
)
with pytest.raises(ClientError) as e:
2021-10-18 19:44:29 +00:00
client.describe_policy(PolicyId="meaninglessstring")
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "DescribePolicy"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "InvalidInputException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == "You specified an invalid value."
2024-01-07 12:03:33 +00:00
@mock_aws
def test_attach_policy():
client = boto3.client("organizations", region_name="us-east-1")
_ = client.create_organization(FeatureSet="ALL")["Organization"]
root_id = client.list_roots()["Roots"][0]["Id"]
ou_id = client.create_organizational_unit(ParentId=root_id, Name="ou01")[
"OrganizationalUnit"
]["Id"]
account_id = client.create_account(AccountName=mockname, Email=mockemail)[
"CreateAccountStatus"
]["AccountId"]
policy_id = client.create_policy(
Content=json.dumps(policy_doc01),
Description="A dummy service control policy",
Name="MockServiceControlPolicy",
Type="SERVICE_CONTROL_POLICY",
)["Policy"]["PolicySummary"]["Id"]
response = client.attach_policy(PolicyId=policy_id, TargetId=root_id)
assert response["ResponseMetadata"]["HTTPStatusCode"] == 200
response = client.attach_policy(PolicyId=policy_id, TargetId=ou_id)
assert response["ResponseMetadata"]["HTTPStatusCode"] == 200
response = client.attach_policy(PolicyId=policy_id, TargetId=account_id)
assert response["ResponseMetadata"]["HTTPStatusCode"] == 200
2024-01-07 12:03:33 +00:00
@mock_aws
def test_detach_policy():
client = boto3.client("organizations", region_name="us-east-1")
_ = client.create_organization(FeatureSet="ALL")["Organization"]
root_id = client.list_roots()["Roots"][0]["Id"]
ou_id = client.create_organizational_unit(ParentId=root_id, Name="ou01")[
"OrganizationalUnit"
]["Id"]
account_id = client.create_account(AccountName=mockname, Email=mockemail)[
"CreateAccountStatus"
]["AccountId"]
policy_id = client.create_policy(
Content=json.dumps(policy_doc01),
Description="A dummy service control policy",
Name="MockServiceControlPolicy",
Type="SERVICE_CONTROL_POLICY",
)["Policy"]["PolicySummary"]["Id"]
# Attach/List/Detach policy
for name, target in [("OU", ou_id), ("Root", root_id), ("Account", account_id)]:
#
assert (
len(get_nonaws_policies(target, client)) == 0
), "We should start with 0 policies"
#
client.attach_policy(PolicyId=policy_id, TargetId=target)
assert (
len(get_nonaws_policies(target, client)) == 1
), f"Expecting 1 policy after creation of target={name}"
#
response = client.detach_policy(PolicyId=policy_id, TargetId=target)
assert response["ResponseMetadata"]["HTTPStatusCode"] == 200
assert (
len(get_nonaws_policies(target, client)) == 0
), f"Expecting 0 policies after deletion of target={name}"
def get_nonaws_policies(account_id, client):
return [
p
for p in client.list_policies_for_target(
TargetId=account_id, Filter="SERVICE_CONTROL_POLICY"
)["Policies"]
if not p["AwsManaged"]
]
2024-01-07 12:03:33 +00:00
@mock_aws
def test_detach_policy_root_ou_not_found_exception():
client = boto3.client("organizations", region_name="us-east-1")
_ = client.create_organization(FeatureSet="ALL")["Organization"]
root_id = client.list_roots()["Roots"][0]["Id"]
_ = client.create_organizational_unit(ParentId=root_id, Name="ou01")[
"OrganizationalUnit"
]["Id"]
account_id = client.create_account(AccountName=mockname, Email=mockemail)[
"CreateAccountStatus"
]["AccountId"]
policy_id = client.create_policy(
Content=json.dumps(policy_doc01),
Description="A dummy service control policy",
Name="MockServiceControlPolicy",
Type="SERVICE_CONTROL_POLICY",
)["Policy"]["PolicySummary"]["Id"]
client.attach_policy(PolicyId=policy_id, TargetId=root_id)
client.attach_policy(PolicyId=policy_id, TargetId=account_id)
2020-10-06 06:04:09 +00:00
with pytest.raises(ClientError) as e:
2021-10-18 19:44:29 +00:00
client.detach_policy(PolicyId=policy_id, TargetId="r-xy85")
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "DetachPolicy"
assert ex.response["Error"]["Code"] == "400"
assert "OrganizationalUnitNotFoundException" in ex.response["Error"]["Message"]
2024-01-07 12:03:33 +00:00
@mock_aws
def test_detach_policy_ou_not_found_exception():
client = boto3.client("organizations", region_name="us-east-1")
_ = client.create_organization(FeatureSet="ALL")["Organization"]
root_id = client.list_roots()["Roots"][0]["Id"]
ou_id = client.create_organizational_unit(ParentId=root_id, Name="ou01")[
"OrganizationalUnit"
]["Id"]
policy_id = client.create_policy(
Content=json.dumps(policy_doc01),
Description="A dummy service control policy",
Name="MockServiceControlPolicy",
Type="SERVICE_CONTROL_POLICY",
)["Policy"]["PolicySummary"]["Id"]
client.attach_policy(PolicyId=policy_id, TargetId=ou_id)
2020-10-06 06:04:09 +00:00
with pytest.raises(ClientError) as e:
2021-10-18 19:44:29 +00:00
client.detach_policy(PolicyId=policy_id, TargetId="ou-zx86-z3x4yr2t7")
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "DetachPolicy"
assert ex.response["Error"]["Code"] == "400"
assert "OrganizationalUnitNotFoundException" in ex.response["Error"]["Message"]
2024-01-07 12:03:33 +00:00
@mock_aws
def test_detach_policy_account_id_not_found_exception():
client = boto3.client("organizations", region_name="us-east-1")
_ = client.create_organization(FeatureSet="ALL")["Organization"]
account_id = client.create_account(AccountName=mockname, Email=mockemail)[
"CreateAccountStatus"
]["AccountId"]
policy_id = client.create_policy(
Content=json.dumps(policy_doc01),
Description="A dummy service control policy",
Name="MockServiceControlPolicy",
Type="SERVICE_CONTROL_POLICY",
)["Policy"]["PolicySummary"]["Id"]
client.attach_policy(PolicyId=policy_id, TargetId=account_id)
2020-10-06 06:04:09 +00:00
with pytest.raises(ClientError) as e:
2021-10-18 19:44:29 +00:00
client.detach_policy(PolicyId=policy_id, TargetId="111619863336")
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "DetachPolicy"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "AccountNotFoundException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == (
"You specified an account that doesn't exist."
)
2024-01-07 12:03:33 +00:00
@mock_aws
def test_detach_policy_invalid_target_exception():
client = boto3.client("organizations", region_name="us-east-1")
_ = client.create_organization(FeatureSet="ALL")["Organization"]
root_id = client.list_roots()["Roots"][0]["Id"]
ou_id = client.create_organizational_unit(ParentId=root_id, Name="ou01")[
"OrganizationalUnit"
]["Id"]
policy_id = client.create_policy(
Content=json.dumps(policy_doc01),
Description="A dummy service control policy",
Name="MockServiceControlPolicy",
Type="SERVICE_CONTROL_POLICY",
)["Policy"]["PolicySummary"]["Id"]
client.attach_policy(PolicyId=policy_id, TargetId=ou_id)
2020-10-06 06:04:09 +00:00
with pytest.raises(ClientError) as e:
2021-10-18 19:44:29 +00:00
client.detach_policy(PolicyId=policy_id, TargetId="invalidtargetid")
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "DetachPolicy"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "InvalidInputException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == "You specified an invalid value."
2024-01-07 12:03:33 +00:00
@mock_aws
def test_delete_policy():
client = boto3.client("organizations", region_name="us-east-1")
_ = client.create_organization(FeatureSet="ALL")["Organization"]
base_policies = client.list_policies(Filter="SERVICE_CONTROL_POLICY")["Policies"]
assert len(base_policies) == 1
policy_id = client.create_policy(
Content=json.dumps(policy_doc01),
Description="A dummy service control policy",
Name="MockServiceControlPolicy",
Type="SERVICE_CONTROL_POLICY",
)["Policy"]["PolicySummary"]["Id"]
new_policies = client.list_policies(Filter="SERVICE_CONTROL_POLICY")["Policies"]
assert len(new_policies) == 2
response = client.delete_policy(PolicyId=policy_id)
assert response["ResponseMetadata"]["HTTPStatusCode"] == 200
new_policies = client.list_policies(Filter="SERVICE_CONTROL_POLICY")["Policies"]
assert new_policies == base_policies
assert len(new_policies) == 1
2024-01-07 12:03:33 +00:00
@mock_aws
def test_delete_policy_exception():
client = boto3.client("organizations", region_name="us-east-1")
_ = client.create_organization(FeatureSet="ALL")["Organization"]
non_existent_policy_id = utils.make_random_policy_id()
with pytest.raises(ClientError) as e:
2021-10-18 19:44:29 +00:00
client.delete_policy(PolicyId=non_existent_policy_id)
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "DeletePolicy"
assert ex.response["Error"]["Code"] == "PolicyNotFoundException"
assert (
ex.response["Error"]["Message"]
== "We can't find a policy with the PolicyId that you specified."
)
# Attempt to delete an attached policy
policy_id = client.create_policy(
Content=json.dumps(policy_doc01),
Description="A dummy service control policy",
Name="MockServiceControlPolicy",
Type="SERVICE_CONTROL_POLICY",
)["Policy"]["PolicySummary"]["Id"]
root_id = client.list_roots()["Roots"][0]["Id"]
client.attach_policy(PolicyId=policy_id, TargetId=root_id)
with pytest.raises(ClientError) as e:
2021-10-18 19:44:29 +00:00
client.delete_policy(PolicyId=policy_id)
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "DeletePolicy"
assert ex.response["Error"]["Code"] == "400"
assert "PolicyInUseException" in ex.response["Error"]["Message"]
2024-01-07 12:03:33 +00:00
@mock_aws
def test_attach_policy_exception():
client = boto3.client("organizations", region_name="us-east-1")
_ = client.create_organization(FeatureSet="ALL")["Organization"]
root_id = "r-dj873"
ou_id = "ou-gi99-i7r8eh2i2"
account_id = "126644886543"
policy_id = client.create_policy(
Content=json.dumps(policy_doc01),
Description="A dummy service control policy",
Name="MockServiceControlPolicy",
Type="SERVICE_CONTROL_POLICY",
)["Policy"]["PolicySummary"]["Id"]
with pytest.raises(ClientError) as e:
2021-10-18 19:44:29 +00:00
client.attach_policy(PolicyId=policy_id, TargetId=root_id)
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "AttachPolicy"
assert ex.response["Error"]["Code"] == "400"
assert "OrganizationalUnitNotFoundException" in ex.response["Error"]["Message"]
with pytest.raises(ClientError) as e:
2021-10-18 19:44:29 +00:00
client.attach_policy(PolicyId=policy_id, TargetId=ou_id)
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "AttachPolicy"
assert ex.response["Error"]["Code"] == "400"
assert "OrganizationalUnitNotFoundException" in ex.response["Error"]["Message"]
with pytest.raises(ClientError) as e:
2021-10-18 19:44:29 +00:00
client.attach_policy(PolicyId=policy_id, TargetId=account_id)
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "AttachPolicy"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "AccountNotFoundException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == (
"You specified an account that doesn't exist."
)
with pytest.raises(ClientError) as e:
2021-10-18 19:44:29 +00:00
client.attach_policy(PolicyId=policy_id, TargetId="meaninglessstring")
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "AttachPolicy"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "InvalidInputException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == "You specified an invalid value."
2024-01-07 12:03:33 +00:00
@mock_aws
def test_update_policy():
client = boto3.client("organizations", region_name="us-east-1")
org = client.create_organization(FeatureSet="ALL")["Organization"]
policy_dict = {
"Content": json.dumps(policy_doc01),
"Description": "A dummy service control policy",
"Name": "MockServiceControlPolicy",
"Type": "SERVICE_CONTROL_POLICY",
}
policy_id = client.create_policy(**policy_dict)["Policy"]["PolicySummary"]["Id"]
for key in ("Description", "Name"):
response = client.update_policy(**{"PolicyId": policy_id, key: "foobar"})
policy = client.describe_policy(PolicyId=policy_id)
assert policy["Policy"]["PolicySummary"][key] == "foobar"
validate_service_control_policy(org, response["Policy"])
response = client.update_policy(PolicyId=policy_id, Content="foobar")
policy = client.describe_policy(PolicyId=policy_id)
assert policy["Policy"]["Content"] == "foobar"
validate_service_control_policy(org, response["Policy"])
2024-01-07 12:03:33 +00:00
@mock_aws
def test_update_policy_exception():
client = boto3.client("organizations", region_name="us-east-1")
_ = client.create_organization(FeatureSet="ALL")["Organization"]
non_existent_policy_id = utils.make_random_policy_id()
with pytest.raises(ClientError) as e:
2021-10-18 19:44:29 +00:00
client.update_policy(PolicyId=non_existent_policy_id)
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "UpdatePolicy"
assert ex.response["Error"]["Code"] == "PolicyNotFoundException"
assert (
ex.response["Error"]["Message"]
== "We can't find a policy with the PolicyId that you specified."
)
2024-01-07 12:03:33 +00:00
@mock_aws
def test_list_polices():
client = boto3.client("organizations", region_name="us-east-1")
org = client.create_organization(FeatureSet="ALL")["Organization"]
for i in range(0, 4):
client.create_policy(
Content=json.dumps(policy_doc01),
Description="A dummy service control policy",
Name="MockServiceControlPolicy" + str(i),
Type="SERVICE_CONTROL_POLICY",
)
response = client.list_policies(Filter="SERVICE_CONTROL_POLICY")
for policy in response["Policies"]:
validate_policy_summary(org, policy)
2019-10-31 15:44:26 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
def test_list_policies_for_target():
client = boto3.client("organizations", region_name="us-east-1")
org = client.create_organization(FeatureSet="ALL")["Organization"]
root_id = client.list_roots()["Roots"][0]["Id"]
ou_id = client.create_organizational_unit(ParentId=root_id, Name="ou01")[
"OrganizationalUnit"
]["Id"]
account_id = client.create_account(AccountName=mockname, Email=mockemail)[
"CreateAccountStatus"
]["AccountId"]
policy_id = client.create_policy(
Content=json.dumps(policy_doc01),
Description="A dummy service control policy",
Name="MockServiceControlPolicy",
Type="SERVICE_CONTROL_POLICY",
)["Policy"]["PolicySummary"]["Id"]
client.attach_policy(PolicyId=policy_id, TargetId=ou_id)
response = client.list_policies_for_target(
TargetId=ou_id, Filter="SERVICE_CONTROL_POLICY"
)
for policy in response["Policies"]:
validate_policy_summary(org, policy)
client.attach_policy(PolicyId=policy_id, TargetId=account_id)
response = client.list_policies_for_target(
TargetId=account_id, Filter="SERVICE_CONTROL_POLICY"
)
for policy in response["Policies"]:
validate_policy_summary(org, policy)
2024-01-07 12:03:33 +00:00
@mock_aws
def test_list_policies_for_target_exception():
client = boto3.client("organizations", region_name="us-east-1")
_ = client.create_organization(FeatureSet="ALL")["Organization"]
root_id = client.list_roots()["Roots"][0]["Id"]
ou_id = "ou-gi99-i7r8eh2i2"
account_id = "126644886543"
with pytest.raises(ClientError) as e:
2021-10-18 19:44:29 +00:00
client.list_policies_for_target(TargetId=ou_id, Filter="SERVICE_CONTROL_POLICY")
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "ListPoliciesForTarget"
assert ex.response["Error"]["Code"] == "400"
assert "OrganizationalUnitNotFoundException" in ex.response["Error"]["Message"]
with pytest.raises(ClientError) as e:
2021-10-18 19:44:29 +00:00
client.list_policies_for_target(
TargetId=account_id, Filter="SERVICE_CONTROL_POLICY"
)
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "ListPoliciesForTarget"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "AccountNotFoundException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == (
"You specified an account that doesn't exist."
)
with pytest.raises(ClientError) as e:
2021-10-18 19:44:29 +00:00
client.list_policies_for_target(
TargetId="meaninglessstring", Filter="SERVICE_CONTROL_POLICY"
)
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "ListPoliciesForTarget"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "InvalidInputException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == "You specified an invalid value."
2019-10-31 15:44:26 +00:00
# not existing root
# when
with pytest.raises(ClientError) as e:
client.list_policies_for_target(
TargetId="r-0000", Filter="SERVICE_CONTROL_POLICY"
)
# then
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "ListPoliciesForTarget"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "TargetNotFoundException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == (
"You specified a target that doesn't exist."
)
# invalid policy type
# when
with pytest.raises(ClientError) as e:
client.list_policies_for_target(TargetId=root_id, Filter="MOTO")
# then
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "ListPoliciesForTarget"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "InvalidInputException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == "You specified an invalid value."
2024-01-07 12:03:33 +00:00
@mock_aws
def test_list_targets_for_policy():
client = boto3.client("organizations", region_name="us-east-1")
_ = client.create_organization(FeatureSet="ALL")["Organization"]
root_id = client.list_roots()["Roots"][0]["Id"]
ou_id = client.create_organizational_unit(ParentId=root_id, Name="ou01")[
"OrganizationalUnit"
]["Id"]
account_id = client.create_account(AccountName=mockname, Email=mockemail)[
"CreateAccountStatus"
]["AccountId"]
policy_id = client.create_policy(
Content=json.dumps(policy_doc01),
Description="A dummy service control policy",
Name="MockServiceControlPolicy",
Type="SERVICE_CONTROL_POLICY",
)["Policy"]["PolicySummary"]["Id"]
client.attach_policy(PolicyId=policy_id, TargetId=root_id)
client.attach_policy(PolicyId=policy_id, TargetId=ou_id)
client.attach_policy(PolicyId=policy_id, TargetId=account_id)
response = client.list_targets_for_policy(PolicyId=policy_id)
for target in response["Targets"]:
assert isinstance(target, dict)
assert isinstance(target["Name"], str)
assert isinstance(target["Arn"], str)
assert isinstance(target["TargetId"], str)
assert target["Type"] in ["ROOT", "ORGANIZATIONAL_UNIT", "ACCOUNT"]
2024-01-07 12:03:33 +00:00
@mock_aws
def test_list_targets_for_policy_exception():
client = boto3.client("organizations", region_name="us-east-1")
_ = client.create_organization(FeatureSet="ALL")["Organization"]
policy_id = "p-47fhe9s3"
with pytest.raises(ClientError) as e:
2021-10-18 19:44:29 +00:00
client.list_targets_for_policy(PolicyId=policy_id)
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "ListTargetsForPolicy"
assert ex.response["Error"]["Code"] == "PolicyNotFoundException"
assert (
ex.response["Error"]["Message"] == "You specified a policy that doesn't exist."
)
with pytest.raises(ClientError) as e:
2021-10-18 19:44:29 +00:00
client.list_targets_for_policy(PolicyId="meaninglessstring")
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "ListTargetsForPolicy"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "InvalidInputException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == "You specified an invalid value."
2019-11-17 13:52:57 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
def test_tag_resource_account():
2019-11-17 13:52:57 +00:00
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization(FeatureSet="ALL")
resource_id = client.create_account(AccountName=mockname, Email=mockemail)[
2019-11-17 13:52:57 +00:00
"CreateAccountStatus"
]["AccountId"]
client.tag_resource(ResourceId=resource_id, Tags=[{"Key": "key", "Value": "value"}])
2019-11-17 13:52:57 +00:00
response = client.list_tags_for_resource(ResourceId=resource_id)
assert response["Tags"] == [{"Key": "key", "Value": "value"}]
# adding a tag with an existing key, will update the value
client.tag_resource(
ResourceId=resource_id, Tags=[{"Key": "key", "Value": "new-value"}]
)
response = client.list_tags_for_resource(ResourceId=resource_id)
assert response["Tags"] == [{"Key": "key", "Value": "new-value"}]
client.untag_resource(ResourceId=resource_id, TagKeys=["key"])
response = client.list_tags_for_resource(ResourceId=resource_id)
assert response["Tags"] == []
2024-01-07 12:03:33 +00:00
@mock_aws
def test_tag_resource_organization_organization_root():
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization(FeatureSet="ALL")
resource_id = client.list_roots()["Roots"][0]["Id"]
client.tag_resource(ResourceId=resource_id, Tags=[{"Key": "key", "Value": "value"}])
response = client.list_tags_for_resource(ResourceId=resource_id)
assert response["Tags"] == [{"Key": "key", "Value": "value"}]
# adding a tag with an existing key, will update the value
client.tag_resource(
ResourceId=resource_id, Tags=[{"Key": "key", "Value": "new-value"}]
)
response = client.list_tags_for_resource(ResourceId=resource_id)
assert response["Tags"] == [{"Key": "key", "Value": "new-value"}]
client.untag_resource(ResourceId=resource_id, TagKeys=["key"])
response = client.list_tags_for_resource(ResourceId=resource_id)
assert response["Tags"] == []
2024-01-07 12:03:33 +00:00
@mock_aws
def test_tag_resource_organization_organizational_unit():
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization(FeatureSet="ALL")
root_id = client.list_roots()["Roots"][0]["Id"]
resource_id = client.create_organizational_unit(ParentId=root_id, Name="ou01")[
"OrganizationalUnit"
]["Id"]
client.tag_resource(ResourceId=resource_id, Tags=[{"Key": "key", "Value": "value"}])
response = client.list_tags_for_resource(ResourceId=resource_id)
assert response["Tags"] == [{"Key": "key", "Value": "value"}]
# adding a tag with an existing key, will update the value
client.tag_resource(
ResourceId=resource_id, Tags=[{"Key": "key", "Value": "new-value"}]
)
response = client.list_tags_for_resource(ResourceId=resource_id)
assert response["Tags"] == [{"Key": "key", "Value": "new-value"}]
client.untag_resource(ResourceId=resource_id, TagKeys=["key"])
response = client.list_tags_for_resource(ResourceId=resource_id)
assert response["Tags"] == []
2024-01-07 12:03:33 +00:00
@mock_aws
def test_tag_resource_policy():
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization(FeatureSet="ALL")
_ = client.list_roots()["Roots"][0]["Id"]
resource_id = client.create_policy(
Content=json.dumps(policy_doc01),
Description="A dummy service control policy",
Name="MockServiceControlPolicy",
Type="SERVICE_CONTROL_POLICY",
)["Policy"]["PolicySummary"]["Id"]
client.tag_resource(ResourceId=resource_id, Tags=[{"Key": "key", "Value": "value"}])
response = client.list_tags_for_resource(ResourceId=resource_id)
assert response["Tags"] == [{"Key": "key", "Value": "value"}]
# adding a tag with an existing key, will update the value
client.tag_resource(
ResourceId=resource_id, Tags=[{"Key": "key", "Value": "new-value"}]
)
response = client.list_tags_for_resource(ResourceId=resource_id)
assert response["Tags"] == [{"Key": "key", "Value": "new-value"}]
client.untag_resource(ResourceId=resource_id, TagKeys=["key"])
response = client.list_tags_for_resource(ResourceId=resource_id)
assert response["Tags"] == []
2019-11-17 13:52:57 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2019-11-17 13:52:57 +00:00
def test_tag_resource_errors():
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization(FeatureSet="ALL")
with pytest.raises(ClientError) as e:
2019-11-17 13:52:57 +00:00
client.tag_resource(
ResourceId="0A000000X000", Tags=[{"Key": "key", "Value": "value"}]
2019-11-17 13:52:57 +00:00
)
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "TagResource"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "InvalidInputException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == (
2019-11-17 13:52:57 +00:00
"You provided a value that does not match the required pattern."
)
with pytest.raises(ClientError) as e:
client.tag_resource(
ResourceId="000000000000", Tags=[{"Key": "key", "Value": "value"}]
)
ex = e.value
assert ex.operation_name == "TagResource"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "TargetNotFoundException" in ex.response["Error"]["Code"]
assert (
ex.response["Error"]["Message"] == "You specified a target that doesn't exist."
)
def test__get_resource_for_tagging_existing_root():
2022-08-13 09:49:43 +00:00
org = FakeOrganization(ACCOUNT_ID, "ALL")
root = FakeRoot(org)
org_backend = OrganizationsBackend(region_name="N/A", account_id="N/A")
org_backend.ou.append(root)
response = org_backend._get_resource_for_tagging(root.id)
assert response.id == root.id
def test__get_resource_for_tagging_existing_non_root():
org_backend = OrganizationsBackend(region_name="N/A", account_id="N/A")
with pytest.raises(TargetNotFoundException) as e:
org_backend._get_resource_for_tagging("r-abcd")
ex = e.value
assert ex.code == 400
assert "TargetNotFoundException" in ex.description
assert ex.message == "You specified a target that doesn't exist."
def test__get_resource_for_tagging_existing_ou():
2022-08-13 09:49:43 +00:00
org = FakeOrganization(ACCOUNT_ID, "ALL")
ou = FakeOrganizationalUnit(org)
org_backend = OrganizationsBackend(region_name="N/A", account_id="N/A")
org_backend.ou.append(ou)
response = org_backend._get_resource_for_tagging(ou.id)
assert response.id == ou.id
def test__get_resource_for_tagging_non_existing_ou():
org_backend = OrganizationsBackend(region_name="N/A", account_id="N/A")
with pytest.raises(TargetNotFoundException) as e:
org_backend._get_resource_for_tagging("ou-9oyc-lv2q36ln")
ex = e.value
assert ex.code == 400
assert "TargetNotFoundException" in ex.description
assert ex.message == "You specified a target that doesn't exist."
def test__get_resource_for_tagging_existing_account():
2022-08-13 09:49:43 +00:00
org = FakeOrganization(ACCOUNT_ID, "ALL")
org_backend = OrganizationsBackend(region_name="N/A", account_id="N/A")
account = FakeAccount(org, AccountName="test", Email="test@test.test")
org_backend.accounts.append(account)
response = org_backend._get_resource_for_tagging(account.id)
assert response.id == account.id
def test__get_resource_for_tagging_non_existing_account():
org_backend = OrganizationsBackend(region_name="N/A", account_id="N/A")
with pytest.raises(TargetNotFoundException) as e:
org_backend._get_resource_for_tagging("100326223992")
ex = e.value
assert ex.code == 400
assert "TargetNotFoundException" in ex.description
assert ex.message == "You specified a target that doesn't exist."
def test__get_resource_for_tagging_existing_policy():
2022-08-13 09:49:43 +00:00
org = FakeOrganization(ACCOUNT_ID, "ALL")
org_backend = OrganizationsBackend(region_name="N/A", account_id="N/A")
policy = FakePolicy(org, Type="SERVICE_CONTROL_POLICY")
org_backend.policies.append(policy)
response = org_backend._get_resource_for_tagging(policy.id)
assert response.id == policy.id
def test__get_resource_for_tagging_non_existing_policy():
org_backend = OrganizationsBackend(region_name="N/A", account_id="N/A")
with pytest.raises(TargetNotFoundException) as e:
org_backend._get_resource_for_tagging("p-y1vas4da")
ex = e.value
assert ex.code == 400
assert "TargetNotFoundException" in ex.description
assert ex.message == "You specified a target that doesn't exist."
def test__get_resource_to_tag_incorrect_resource():
org_backend = OrganizationsBackend(region_name="N/A", account_id="N/A")
with pytest.raises(InvalidInputException) as e:
org_backend._get_resource_for_tagging("10032622399200")
ex = e.value
assert ex.code == 400
assert "InvalidInputException" in ex.description
assert ex.message == (
"You provided a value that does not match the required pattern."
)
2024-01-07 12:03:33 +00:00
@mock_aws
def test_list_tags_for_resource():
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization(FeatureSet="ALL")
account_id = client.create_account(AccountName=mockname, Email=mockemail)[
"CreateAccountStatus"
]["AccountId"]
client.tag_resource(ResourceId=account_id, Tags=[{"Key": "key", "Value": "value"}])
response = client.list_tags_for_resource(ResourceId=account_id)
assert response["Tags"] == [{"Key": "key", "Value": "value"}]
2024-01-07 12:03:33 +00:00
@mock_aws
def test_list_tags_for_resource_errors():
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization(FeatureSet="ALL")
with pytest.raises(ClientError) as e:
client.list_tags_for_resource(ResourceId="000x00000A00")
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "ListTagsForResource"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "InvalidInputException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == (
"You provided a value that does not match the required pattern."
)
with pytest.raises(ClientError) as e:
client.list_tags_for_resource(ResourceId="000000000000")
ex = e.value
assert ex.operation_name == "ListTagsForResource"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "TargetNotFoundException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == (
"You specified a target that doesn't exist."
)
2019-11-17 14:28:38 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2019-11-17 14:28:38 +00:00
def test_untag_resource():
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization(FeatureSet="ALL")
account_id = client.create_account(AccountName=mockname, Email=mockemail)[
"CreateAccountStatus"
]["AccountId"]
client.tag_resource(ResourceId=account_id, Tags=[{"Key": "key", "Value": "value"}])
response = client.list_tags_for_resource(ResourceId=account_id)
assert response["Tags"] == [{"Key": "key", "Value": "value"}]
2019-11-17 14:28:38 +00:00
# removing a non existing tag should not raise any error
client.untag_resource(ResourceId=account_id, TagKeys=["not-existing"])
response = client.list_tags_for_resource(ResourceId=account_id)
assert response["Tags"] == [{"Key": "key", "Value": "value"}]
2019-11-17 14:28:38 +00:00
client.untag_resource(ResourceId=account_id, TagKeys=["key"])
response = client.list_tags_for_resource(ResourceId=account_id)
assert len(response["Tags"]) == 0
2019-11-17 14:28:38 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2019-11-17 14:28:38 +00:00
def test_untag_resource_errors():
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization(FeatureSet="ALL")
with pytest.raises(ClientError) as e:
client.untag_resource(ResourceId="0X00000000A0", TagKeys=["key"])
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "UntagResource"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "InvalidInputException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == (
2019-11-17 14:28:38 +00:00
"You provided a value that does not match the required pattern."
)
with pytest.raises(ClientError) as e:
client.untag_resource(ResourceId="000000000000", TagKeys=["key"])
ex = e.value
assert ex.operation_name == "UntagResource"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "TargetNotFoundException" in ex.response["Error"]["Code"]
assert (
ex.response["Error"]["Message"] == "You specified a target that doesn't exist."
)
2024-01-07 12:03:33 +00:00
@mock_aws
def test_update_organizational_unit():
client = boto3.client("organizations", region_name="us-east-1")
org = client.create_organization(FeatureSet="ALL")["Organization"]
root_id = client.list_roots()["Roots"][0]["Id"]
ou_name = "ou01"
response = client.create_organizational_unit(ParentId=root_id, Name=ou_name)
validate_organizational_unit(org, response)
assert response["OrganizationalUnit"]["Name"] == ou_name
new_ou_name = "ou02"
response = client.update_organizational_unit(
OrganizationalUnitId=response["OrganizationalUnit"]["Id"], Name=new_ou_name
)
validate_organizational_unit(org, response)
assert response["OrganizationalUnit"]["Name"] == new_ou_name
2024-01-07 12:03:33 +00:00
@mock_aws
def test_update_organizational_unit_duplicate_error():
client = boto3.client("organizations", region_name="us-east-1")
org = client.create_organization(FeatureSet="ALL")["Organization"]
root_id = client.list_roots()["Roots"][0]["Id"]
ou_name = "ou01"
response = client.create_organizational_unit(ParentId=root_id, Name=ou_name)
validate_organizational_unit(org, response)
assert response["OrganizationalUnit"]["Name"] == ou_name
with pytest.raises(ClientError) as e:
client.update_organizational_unit(
OrganizationalUnitId=response["OrganizationalUnit"]["Id"], Name=ou_name
)
2020-10-06 06:04:09 +00:00
exc = e.value
assert exc.operation_name == "UpdateOrganizationalUnit"
assert "DuplicateOrganizationalUnitException" in exc.response["Error"]["Code"]
assert (
exc.response["Error"]["Message"] == "An OU with the same name already exists."
)
2024-01-07 12:03:33 +00:00
@mock_aws
def test_enable_aws_service_access():
# given
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization(FeatureSet="ALL")
# when
client.enable_aws_service_access(ServicePrincipal="config.amazonaws.com")
# then
response = client.list_aws_service_access_for_organization()
assert len(response["EnabledServicePrincipals"]) == 1
service = response["EnabledServicePrincipals"][0]
assert service["ServicePrincipal"] == "config.amazonaws.com"
date_enabled = service["DateEnabled"]
assert isinstance(date_enabled, datetime)
# enabling the same service again should not result in any error or change
# when
client.enable_aws_service_access(ServicePrincipal="config.amazonaws.com")
# then
response = client.list_aws_service_access_for_organization()
assert len(response["EnabledServicePrincipals"]) == 1
service = response["EnabledServicePrincipals"][0]
assert service["ServicePrincipal"] == "config.amazonaws.com"
assert service["DateEnabled"] == date_enabled
2024-01-07 12:03:33 +00:00
@mock_aws
def test_enable_aws_service_access_error():
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization(FeatureSet="ALL")
with pytest.raises(ClientError) as e:
client.enable_aws_service_access(ServicePrincipal="moto.amazonaws.com")
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "EnableAWSServiceAccess"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "InvalidInputException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == (
"You specified an unrecognized service principal."
)
2024-01-07 12:03:33 +00:00
@mock_aws
def test_enable_multiple_aws_service_access():
# given
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization(FeatureSet="ALL")
client.enable_aws_service_access(ServicePrincipal="config.amazonaws.com")
client.enable_aws_service_access(ServicePrincipal="ram.amazonaws.com")
# when
response = client.list_aws_service_access_for_organization()
# then
assert len(response["EnabledServicePrincipals"]) == 2
services = sorted(
response["EnabledServicePrincipals"], key=lambda i: i["ServicePrincipal"]
)
assert services[0]["ServicePrincipal"] == "config.amazonaws.com"
assert isinstance(services[0]["DateEnabled"], datetime)
assert services[1]["ServicePrincipal"] == "ram.amazonaws.com"
assert isinstance(services[1]["DateEnabled"], datetime)
2024-01-07 12:03:33 +00:00
@mock_aws
def test_disable_aws_service_access():
# given
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization(FeatureSet="ALL")
client.enable_aws_service_access(ServicePrincipal="config.amazonaws.com")
# when
client.disable_aws_service_access(ServicePrincipal="config.amazonaws.com")
# then
response = client.list_aws_service_access_for_organization()
assert len(response["EnabledServicePrincipals"]) == 0
# disabling the same service again should not result in any error
# when
client.disable_aws_service_access(ServicePrincipal="config.amazonaws.com")
# then
response = client.list_aws_service_access_for_organization()
assert len(response["EnabledServicePrincipals"]) == 0
2024-01-07 12:03:33 +00:00
@mock_aws
def test_disable_aws_service_access_errors():
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization(FeatureSet="ALL")
with pytest.raises(ClientError) as e:
client.disable_aws_service_access(ServicePrincipal="moto.amazonaws.com")
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "DisableAWSServiceAccess"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "InvalidInputException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == (
"You specified an unrecognized service principal."
)
2024-01-07 12:03:33 +00:00
@mock_aws
def test_register_delegated_administrator():
# given
client = boto3.client("organizations", region_name="us-east-1")
org_id = client.create_organization(FeatureSet="ALL")["Organization"]["Id"]
account_id = client.create_account(AccountName=mockname, Email=mockemail)[
"CreateAccountStatus"
]["AccountId"]
# when
client.register_delegated_administrator(
AccountId=account_id, ServicePrincipal="ssm.amazonaws.com"
)
# then
response = client.list_delegated_administrators()
assert len(response["DelegatedAdministrators"]) == 1
admin = response["DelegatedAdministrators"][0]
assert admin["Id"] == account_id
assert admin["Arn"] == (
f"arn:aws:organizations::{ACCOUNT_ID}:account/{org_id}/{account_id}"
)
assert admin["Email"] == mockemail
assert admin["Name"] == mockname
assert admin["Status"] == "ACTIVE"
assert admin["JoinedMethod"] == "CREATED"
assert isinstance(admin["JoinedTimestamp"], datetime)
assert isinstance(admin["DelegationEnabledDate"], datetime)
2024-01-07 12:03:33 +00:00
@mock_aws
def test_register_delegated_administrator_errors():
# given
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization(FeatureSet="ALL")
account_id = client.create_account(AccountName=mockname, Email=mockemail)[
"CreateAccountStatus"
]["AccountId"]
client.register_delegated_administrator(
AccountId=account_id, ServicePrincipal="ssm.amazonaws.com"
)
# register master Account
# when
with pytest.raises(ClientError) as e:
client.register_delegated_administrator(
AccountId=ACCOUNT_ID, ServicePrincipal="ssm.amazonaws.com"
)
# then
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "RegisterDelegatedAdministrator"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "ConstraintViolationException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == (
"You cannot register master account/yourself as delegated "
"administrator for your organization."
)
# register not existing Account
# when
with pytest.raises(ClientError) as e:
client.register_delegated_administrator(
AccountId="000000000000", ServicePrincipal="ssm.amazonaws.com"
)
# then
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "RegisterDelegatedAdministrator"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "AccountNotFoundException" in ex.response["Error"]["Code"]
assert (
ex.response["Error"]["Message"]
== "You specified an account that doesn't exist."
)
# register not supported service
# when
with pytest.raises(ClientError) as e:
client.register_delegated_administrator(
AccountId=account_id, ServicePrincipal="moto.amazonaws.com"
)
# then
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "RegisterDelegatedAdministrator"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "InvalidInputException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == (
"You specified an unrecognized service principal."
)
# register service again
# when
with pytest.raises(ClientError) as e:
client.register_delegated_administrator(
AccountId=account_id, ServicePrincipal="ssm.amazonaws.com"
)
# then
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "RegisterDelegatedAdministrator"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "AccountAlreadyRegisteredException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == (
"The provided account is already a delegated administrator for your organization."
)
2024-01-07 12:03:33 +00:00
@mock_aws
def test_list_delegated_administrators():
# given
client = boto3.client("organizations", region_name="us-east-1")
org_id = client.create_organization(FeatureSet="ALL")["Organization"]["Id"]
account_id_1 = client.create_account(AccountName=mockname, Email=mockemail)[
"CreateAccountStatus"
]["AccountId"]
account_id_2 = client.create_account(AccountName=mockname, Email=mockemail)[
"CreateAccountStatus"
]["AccountId"]
client.register_delegated_administrator(
AccountId=account_id_1, ServicePrincipal="ssm.amazonaws.com"
)
client.register_delegated_administrator(
AccountId=account_id_2, ServicePrincipal="guardduty.amazonaws.com"
)
# when
response = client.list_delegated_administrators()
# then
assert len(response["DelegatedAdministrators"]) == 2
assert sorted([admin["Id"] for admin in response["DelegatedAdministrators"]]) == (
sorted([account_id_1, account_id_2])
)
# when
response = client.list_delegated_administrators(
ServicePrincipal="ssm.amazonaws.com"
)
# then
assert len(response["DelegatedAdministrators"]) == 1
admin = response["DelegatedAdministrators"][0]
assert admin["Id"] == account_id_1
assert admin["Arn"] == (
f"arn:aws:organizations::{ACCOUNT_ID}:account/{org_id}/{account_id_1}"
)
assert admin["Email"] == mockemail
assert admin["Name"] == mockname
assert admin["Status"] == "ACTIVE"
assert admin["JoinedMethod"] == "CREATED"
assert isinstance(admin["JoinedTimestamp"], datetime)
assert isinstance(admin["DelegationEnabledDate"], datetime)
2024-01-07 12:03:33 +00:00
@mock_aws
def test_list_delegated_administrators_erros():
# given
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization(FeatureSet="ALL")
# list not supported service
# when
with pytest.raises(ClientError) as e:
client.list_delegated_administrators(ServicePrincipal="moto.amazonaws.com")
# then
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "ListDelegatedAdministrators"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "InvalidInputException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == (
"You specified an unrecognized service principal."
)
2024-01-07 12:03:33 +00:00
@mock_aws
def test_list_delegated_services_for_account():
# given
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization(FeatureSet="ALL")
account_id = client.create_account(AccountName=mockname, Email=mockemail)[
"CreateAccountStatus"
]["AccountId"]
client.register_delegated_administrator(
AccountId=account_id, ServicePrincipal="ssm.amazonaws.com"
)
client.register_delegated_administrator(
AccountId=account_id, ServicePrincipal="guardduty.amazonaws.com"
)
# when
response = client.list_delegated_services_for_account(AccountId=account_id)
# then
assert len(response["DelegatedServices"]) == 2
assert sorted(
[service["ServicePrincipal"] for service in response["DelegatedServices"]]
) == ["guardduty.amazonaws.com", "ssm.amazonaws.com"]
2024-01-07 12:03:33 +00:00
@mock_aws
def test_list_delegated_services_for_account_erros():
# given
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization(FeatureSet="ALL")
# list services for not existing Account
# when
with pytest.raises(ClientError) as e:
client.list_delegated_services_for_account(AccountId="000000000000")
# then
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "ListDelegatedServicesForAccount"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "AWSOrganizationsNotInUseException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == (
"Your account is not a member of an organization."
)
# list services for not registered Account
# when
with pytest.raises(ClientError) as e:
client.list_delegated_services_for_account(AccountId=ACCOUNT_ID)
# then
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "ListDelegatedServicesForAccount"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "AccountNotRegisteredException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == (
"The provided account is not a registered delegated administrator for your organization."
)
2024-01-07 12:03:33 +00:00
@mock_aws
def test_deregister_delegated_administrator():
# given
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization(FeatureSet="ALL")
account_id = client.create_account(AccountName=mockname, Email=mockemail)[
"CreateAccountStatus"
]["AccountId"]
client.register_delegated_administrator(
AccountId=account_id, ServicePrincipal="ssm.amazonaws.com"
)
# when
client.deregister_delegated_administrator(
AccountId=account_id, ServicePrincipal="ssm.amazonaws.com"
)
# then
response = client.list_delegated_administrators()
assert len(response["DelegatedAdministrators"]) == 0
2024-01-07 12:03:33 +00:00
@mock_aws
def test_deregister_delegated_administrator_erros():
# given
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization(FeatureSet="ALL")
account_id = client.create_account(AccountName=mockname, Email=mockemail)[
"CreateAccountStatus"
]["AccountId"]
# deregister master Account
# when
with pytest.raises(ClientError) as e:
client.deregister_delegated_administrator(
AccountId=ACCOUNT_ID, ServicePrincipal="ssm.amazonaws.com"
)
# then
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "DeregisterDelegatedAdministrator"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "ConstraintViolationException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == (
"You cannot register master account/yourself as delegated "
"administrator for your organization."
)
# deregister not existing Account
# when
with pytest.raises(ClientError) as e:
client.deregister_delegated_administrator(
AccountId="000000000000", ServicePrincipal="ssm.amazonaws.com"
)
# then
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "DeregisterDelegatedAdministrator"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "AccountNotFoundException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == (
"You specified an account that doesn't exist."
)
# deregister not registered Account
# when
with pytest.raises(ClientError) as e:
client.deregister_delegated_administrator(
AccountId=account_id, ServicePrincipal="ssm.amazonaws.com"
)
# then
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "DeregisterDelegatedAdministrator"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "AccountNotRegisteredException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == (
"The provided account is not a registered delegated administrator for your organization."
)
# given
client.register_delegated_administrator(
AccountId=account_id, ServicePrincipal="ssm.amazonaws.com"
)
# deregister not registered service
# when
with pytest.raises(ClientError) as e:
client.deregister_delegated_administrator(
AccountId=account_id, ServicePrincipal="guardduty.amazonaws.com"
)
# then
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "DeregisterDelegatedAdministrator"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "InvalidInputException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == (
"You specified an unrecognized service principal."
)
2024-01-07 12:03:33 +00:00
@mock_aws
def test_enable_policy_type():
# given
client = boto3.client("organizations", region_name="us-east-1")
org = client.create_organization(FeatureSet="ALL")["Organization"]
root_id = client.list_roots()["Roots"][0]["Id"]
# when
response = client.enable_policy_type(
RootId=root_id, PolicyType="AISERVICES_OPT_OUT_POLICY"
)
# then
root = response["Root"]
assert root["Id"] == root_id
assert root["Arn"] == (
utils.ROOT_ARN_FORMAT.format(org["MasterAccountId"], org["Id"], root_id)
)
assert root["Name"] == "Root"
assert sorted(root["PolicyTypes"], key=lambda x: x["Type"]) == (
2022-02-20 00:45:36 +00:00
[{"Type": "AISERVICES_OPT_OUT_POLICY", "Status": "ENABLED"}]
)
2024-01-07 12:03:33 +00:00
@mock_aws
def test_enable_policy_type_errors():
# given
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization(FeatureSet="ALL")
root_id = client.list_roots()["Roots"][0]["Id"]
# not existing root
# when
with pytest.raises(ClientError) as e:
client.enable_policy_type(
RootId="r-0000", PolicyType="AISERVICES_OPT_OUT_POLICY"
)
# then
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "EnablePolicyType"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "RootNotFoundException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == (
"You specified a root that doesn't exist."
)
2022-02-20 00:45:36 +00:00
# enable policy again
# given
client.enable_policy_type(RootId=root_id, PolicyType="SERVICE_CONTROL_POLICY")
# when
with pytest.raises(ClientError) as e:
client.enable_policy_type(RootId=root_id, PolicyType="SERVICE_CONTROL_POLICY")
# then
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "EnablePolicyType"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "PolicyTypeAlreadyEnabledException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == (
"The specified policy type is already enabled."
)
# invalid policy type
# when
with pytest.raises(ClientError) as e:
client.enable_policy_type(RootId=root_id, PolicyType="MOTO")
# then
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "EnablePolicyType"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "InvalidInputException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == "You specified an invalid value."
2024-01-07 12:03:33 +00:00
@mock_aws
def test_disable_policy_type():
# given
client = boto3.client("organizations", region_name="us-east-1")
org = client.create_organization(FeatureSet="ALL")["Organization"]
root_id = client.list_roots()["Roots"][0]["Id"]
client.enable_policy_type(RootId=root_id, PolicyType="AISERVICES_OPT_OUT_POLICY")
# when
response = client.disable_policy_type(
RootId=root_id, PolicyType="AISERVICES_OPT_OUT_POLICY"
)
# then
root = response["Root"]
assert root["Id"] == root_id
assert root["Arn"] == (
utils.ROOT_ARN_FORMAT.format(org["MasterAccountId"], org["Id"], root_id)
)
assert root["Name"] == "Root"
assert root["PolicyTypes"] == []
2024-01-07 12:03:33 +00:00
@mock_aws
def test_disable_policy_type_errors():
# given
client = boto3.client("organizations", region_name="us-east-1")
client.create_organization(FeatureSet="ALL")
root_id = client.list_roots()["Roots"][0]["Id"]
# not existing root
# when
with pytest.raises(ClientError) as e:
client.disable_policy_type(
RootId="r-0000", PolicyType="AISERVICES_OPT_OUT_POLICY"
)
# then
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "DisablePolicyType"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "RootNotFoundException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == (
"You specified a root that doesn't exist."
)
# disable not enabled policy
# when
with pytest.raises(ClientError) as e:
client.disable_policy_type(
RootId=root_id, PolicyType="AISERVICES_OPT_OUT_POLICY"
)
# then
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "DisablePolicyType"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "PolicyTypeNotEnabledException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == (
"This operation can be performed only for enabled policy types."
)
# invalid policy type
# when
with pytest.raises(ClientError) as e:
client.disable_policy_type(RootId=root_id, PolicyType="MOTO")
# then
2020-10-06 06:04:09 +00:00
ex = e.value
assert ex.operation_name == "DisablePolicyType"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "InvalidInputException" in ex.response["Error"]["Code"]
assert ex.response["Error"]["Message"] == "You specified an invalid value."
2024-01-07 12:03:33 +00:00
@mock_aws
def test_aiservices_opt_out_policy():
# given
client = boto3.client("organizations", region_name="us-east-1")
org = client.create_organization(FeatureSet="ALL")["Organization"]
root_id = client.list_roots()["Roots"][0]["Id"]
client.enable_policy_type(RootId=root_id, PolicyType="AISERVICES_OPT_OUT_POLICY")
ai_policy = {
"services": {
"@@operators_allowed_for_child_policies": ["@@none"],
"default": {
"@@operators_allowed_for_child_policies": ["@@none"],
"opt_out_policy": {
"@@operators_allowed_for_child_policies": ["@@none"],
"@@assign": "optOut",
},
},
}
}
# when
response = client.create_policy(
Content=json.dumps(ai_policy),
Description="Opt out of all AI services",
Name="ai-opt-out",
Type="AISERVICES_OPT_OUT_POLICY",
)
# then
summary = response["Policy"]["PolicySummary"]
policy_id = summary["Id"]
assert re.match(utils.POLICY_ID_REGEX, summary["Id"])
assert summary["Arn"] == (
utils.AI_POLICY_ARN_FORMAT.format(
org["MasterAccountId"], org["Id"], summary["Id"]
)
)
assert summary["Name"] == "ai-opt-out"
assert summary["Description"] == "Opt out of all AI services"
assert summary["Type"] == "AISERVICES_OPT_OUT_POLICY"
assert summary["AwsManaged"] is False
assert json.loads(response["Policy"]["Content"]) == ai_policy
# when
client.attach_policy(PolicyId=policy_id, TargetId=root_id)
# then
response = client.list_policies_for_target(
TargetId=root_id, Filter="AISERVICES_OPT_OUT_POLICY"
)
assert len(response["Policies"]) == 1
assert response["Policies"][0]["Id"] == policy_id