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.

2137 lines
83 KiB
Python
Raw Normal View History

from datetime import datetime
from moto.organizations.exceptions import InvalidInputException, TargetNotFoundException
from moto.organizations.models import (
FakeAccount,
FakeOrganization,
FakeOrganizationalUnit,
FakePolicy,
FakeRoot,
OrganizationsBackend,
)
import boto3
import json
2021-10-18 19:44:29 +00:00
import sure # noqa # pylint: disable=unused-import
from botocore.exceptions import ClientError
import pytest
from moto import mock_organizations
2022-08-13 09:49:43 +00:00
from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
from moto.organizations import utils
from .organizations_test_utils import (
validate_organization,
validate_roots,
validate_organizational_unit,
validate_account,
validate_create_account_status,
validate_service_control_policy,
validate_policy_summary,
)
2018-07-14 20:23:15 +00:00
@mock_organizations
def test_create_organization():
client = boto3.client("organizations", region_name="us-east-1")
response = client.create_organization(FeatureSet="ALL")
validate_organization(response)
response["Organization"]["FeatureSet"].should.equal("ALL")
response = client.list_accounts()
len(response["Accounts"]).should.equal(1)
response["Accounts"][0]["Name"].should.equal("master")
2022-08-13 09:49:43 +00:00
response["Accounts"][0]["Id"].should.equal(ACCOUNT_ID)
response["Accounts"][0]["Email"].should.equal(utils.MASTER_ACCOUNT_EMAIL)
response = client.list_policies(Filter="SERVICE_CONTROL_POLICY")
len(response["Policies"]).should.equal(1)
response["Policies"][0]["Name"].should.equal("FullAWSAccess")
response["Policies"][0]["Id"].should.equal(utils.DEFAULT_POLICY_ID)
response["Policies"][0]["AwsManaged"].should.equal(True)
response = client.list_targets_for_policy(PolicyId=utils.DEFAULT_POLICY_ID)
len(response["Targets"]).should.equal(2)
root_ou = [t for t in response["Targets"] if t["Type"] == "ROOT"][0]
root_ou["Name"].should.equal("Root")
master_account = [t for t in response["Targets"] if t["Type"] == "ACCOUNT"][0]
master_account["Name"].should.equal("master")
2018-07-14 20:23:15 +00:00
@mock_organizations
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)
response["Organization"]["FeatureSet"].should.equal("ALL")
@mock_organizations
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)
@mock_organizations
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
ex.operation_name.should.equal("DescribeOrganization")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("AWSOrganizationsNotInUseException")
ex.response["Error"]["Message"].should.equal(
"Your account is not a member of an organization."
)
# Organizational Units
2019-10-31 15:44:26 +00:00
2018-07-15 17:31:16 +00:00
@mock_organizations
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
@mock_organizations
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)
response["OrganizationalUnit"]["Name"].should.equal(ou_name)
@mock_organizations
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)
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
# verify the deletion
with pytest.raises(ClientError) as e:
client.describe_organizational_unit(OrganizationalUnitId=ou_id)
ex = e.value
ex.operation_name.should.equal("DescribeOrganizationalUnit")
ex.response["Error"]["Code"].should.equal("400")
ex.response["Error"]["Message"].should.contain(
"OrganizationalUnitNotFoundException"
)
@mock_organizations
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)
@mock_organizations
def test_describe_organizational_unit_exception():
client = boto3.client("organizations", region_name="us-east-1")
2021-10-18 19:44:29 +00:00
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
ex.operation_name.should.equal("DescribeOrganizationalUnit")
ex.response["Error"]["Code"].should.equal("400")
ex.response["Error"]["Message"].should.contain(
"OrganizationalUnitNotFoundException"
)
@mock_organizations
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)
response.should.have.key("OrganizationalUnits").should.be.a(list)
for ou in response["OrganizationalUnits"]:
validate_organizational_unit(org, dict(OrganizationalUnit=ou))
@mock_organizations
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)
response.should_not.have.key("NextToken")
len(response["OrganizationalUnits"]).should.be.greater_than_or_equal_to(i)
paginator = client.get_paginator("list_organizational_units_for_parent")
page_iterator = paginator.paginate(MaxResults=5, ParentId=root_id)
for page in page_iterator:
len(page["OrganizationalUnits"]).should.be.lower_than_or_equal_to(5)
page["OrganizationalUnits"][-1]["Name"].should.contain("19")
@mock_organizations
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
ex.operation_name.should.equal("ListOrganizationalUnitsForParent")
ex.response["Error"]["Code"].should.equal("400")
ex.response["Error"]["Message"].should.contain("ParentNotFoundException")
# Accounts
mockname = "mock-account"
mockdomain = "moto-example.org"
mockemail = "@".join([mockname, mockdomain])
2018-07-14 20:23:15 +00:00
@mock_organizations
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)
create_status["AccountName"].should.equal(mockname)
2018-07-14 20:23:15 +00:00
@mock_organizations
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 == {}
@mock_organizations
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"]
account["Status"].should.equal("SUSPENDED")
@mock_organizations
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
ex.operation_name.should.equal("CloseAccount")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("AccountNotFoundException")
ex.response["Error"]["Message"].should.equal(
"You specified an account that doesn't exist."
)
@mock_organizations
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"])
@mock_organizations
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"])
response["Account"]["Name"].should.equal(mockname)
response["Account"]["Email"].should.equal(mockemail)
2018-07-14 20:23:15 +00:00
@mock_organizations
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
ex.operation_name.should.equal("DescribeAccount")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("AccountNotFoundException")
ex.response["Error"]["Message"].should.equal(
"You specified an account that doesn't exist."
)
@mock_organizations
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()
response.should.have.key("Accounts")
accounts = response["Accounts"]
len(accounts).should.equal(6)
for account in accounts:
validate_account(org, account)
accounts[4]["Name"].should.equal(mockname + "3")
accounts[3]["Email"].should.equal(mockname + "2" + "@" + mockdomain)
@mock_organizations
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()
response.should_not.have.key("NextToken")
len(response["Accounts"]).should.be.greater_than_or_equal_to(i)
paginator = client.get_paginator("list_accounts")
page_iterator = paginator.paginate(MaxResults=5)
for page in page_iterator:
len(page["Accounts"]).should.be.lower_than_or_equal_to(5)
page["Accounts"][-1]["Name"].should.contain("24")
@mock_organizations
def test_list_accounts_for_parent():
client = boto3.client("organizations", region_name="us-east-1")
2021-10-18 19:44:29 +00:00
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)
account_id.should.be.within([account["Id"] for account in response["Accounts"]])
@mock_organizations
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)
response.should_not.have.key("NextToken")
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)
len(response["Accounts"]).should.be.greater_than_or_equal_to(i)
paginator = client.get_paginator("list_accounts_for_parent")
page_iterator = paginator.paginate(MaxResults=5, ParentId=root_id)
for page in page_iterator:
len(page["Accounts"]).should.be.lower_than_or_equal_to(5)
page["Accounts"][-1]["Name"].should.contain("20")
@mock_organizations
def test_move_account():
client = boto3.client("organizations", region_name="us-east-1")
2021-10-18 19:44:29 +00:00
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)
account_id.should.be.within([account["Id"] for account in response["Accounts"]])
@mock_organizations
def test_list_parents_for_ou():
client = boto3.client("organizations", region_name="us-east-1")
2021-10-18 19:44:29 +00:00
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)
response01.should.have.key("Parents").should.be.a(list)
response01["Parents"][0].should.have.key("Id").should.equal(root_id)
response01["Parents"][0].should.have.key("Type").should.equal("ROOT")
ou02 = client.create_organizational_unit(ParentId=ou01_id, Name="ou02")
ou02_id = ou02["OrganizationalUnit"]["Id"]
response02 = client.list_parents(ChildId=ou02_id)
response02.should.have.key("Parents").should.be.a(list)
response02["Parents"][0].should.have.key("Id").should.equal(ou01_id)
response02["Parents"][0].should.have.key("Type").should.equal("ORGANIZATIONAL_UNIT")
@mock_organizations
def test_list_parents_for_accounts():
client = boto3.client("organizations", region_name="us-east-1")
2021-10-18 19:44:29 +00:00
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)
response01.should.have.key("Parents").should.be.a(list)
response01["Parents"][0].should.have.key("Id").should.equal(root_id)
response01["Parents"][0].should.have.key("Type").should.equal("ROOT")
response02 = client.list_parents(ChildId=account02_id)
response02.should.have.key("Parents").should.be.a(list)
response02["Parents"][0].should.have.key("Id").should.equal(ou01_id)
response02["Parents"][0].should.have.key("Type").should.equal("ORGANIZATIONAL_UNIT")
@mock_organizations
def test_list_children():
client = boto3.client("organizations", region_name="us-east-1")
2021-10-18 19:44:29 +00:00
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")
2022-08-13 09:49:43 +00:00
response01["Children"][0]["Id"].should.equal(ACCOUNT_ID)
response01["Children"][0]["Type"].should.equal("ACCOUNT")
response01["Children"][1]["Id"].should.equal(account01_id)
response01["Children"][1]["Type"].should.equal("ACCOUNT")
response02["Children"][0]["Id"].should.equal(ou01_id)
response02["Children"][0]["Type"].should.equal("ORGANIZATIONAL_UNIT")
response03["Children"][0]["Id"].should.equal(account02_id)
response03["Children"][0]["Type"].should.equal("ACCOUNT")
response04["Children"][0]["Id"].should.equal(ou02_id)
response04["Children"][0]["Type"].should.equal("ORGANIZATIONAL_UNIT")
@mock_organizations
def test_list_children_exception():
client = boto3.client("organizations", region_name="us-east-1")
2021-10-18 19:44:29 +00:00
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
ex.operation_name.should.equal("ListChildren")
ex.response["Error"]["Code"].should.equal("400")
ex.response["Error"]["Message"].should.contain("ParentNotFoundException")
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
ex.operation_name.should.equal("ListChildren")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("InvalidInputException")
ex.response["Error"]["Message"].should.equal("You specified an invalid value.")
@mock_organizations
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"]
createAccountStatuses.should.have.length_of(1)
validate_create_account_status(createAccountStatuses[0])
2021-10-18 19:44:29 +00:00
client.create_account(AccountName=mockname, Email=mockemail)["CreateAccountStatus"][
"Id"
]
response = client.list_create_account_status()
createAccountStatuses = response["CreateAccountStatuses"]
createAccountStatuses.should.have.length_of(2)
for createAccountStatus in createAccountStatuses:
validate_create_account_status(createAccountStatus)
@mock_organizations
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"]
createAccountStatuses.should.have.length_of(1)
validate_create_account_status(createAccountStatuses[0])
@mock_organizations
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"]
createAccountStatuses.should.have.length_of(0)
@mock_organizations
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"]
createAccountStatuses.should.have.length_of(2)
for createAccountStatus in createAccountStatuses:
validate_create_account_status(createAccountStatus)
next_token = response["NextToken"]
next_token.should_not.equal(None)
response2 = client.list_create_account_status(NextToken=next_token)
createAccountStatuses.extend(response2["CreateAccountStatuses"])
createAccountStatuses.should.have.length_of(6)
assert "NextToken" not in response2.keys()
for createAccountStatus in createAccountStatuses:
validate_create_account_status(createAccountStatus)
@mock_organizations
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)
@mock_organizations
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 = dict(
Version="2012-10-17",
Statement=[
dict(Sid="MockPolicyStatement", Effect="Allow", Action="s3:*", Resource="*")
],
)
2019-10-31 15:44:26 +00:00
@mock_organizations
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)
policy["PolicySummary"]["Name"].should.equal("MockServiceControlPolicy")
policy["PolicySummary"]["Description"].should.equal(
"A dummy service control policy"
)
policy["Content"].should.equal(json.dumps(policy_doc01))
@mock_organizations
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
ex.operation_name.should.equal("CreatePolicy")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("InvalidInputException")
ex.response["Error"]["Message"].should.equal("You specified an invalid value.")
@mock_organizations
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)
policy["PolicySummary"]["Name"].should.equal("MockServiceControlPolicy")
policy["PolicySummary"]["Description"].should.equal(
"A dummy service control policy"
)
policy["Content"].should.equal(json.dumps(policy_doc01))
@mock_organizations
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
ex.operation_name.should.equal("DescribePolicy")
ex.response["Error"]["Code"].should.equal("400")
ex.response["Error"]["Message"].should.contain("PolicyNotFoundException")
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
ex.operation_name.should.equal("DescribePolicy")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("InvalidInputException")
ex.response["Error"]["Message"].should.equal("You specified an invalid value.")
@mock_organizations
def test_attach_policy():
client = boto3.client("organizations", region_name="us-east-1")
2021-10-18 19:44:29 +00:00
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)
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
response = client.attach_policy(PolicyId=policy_id, TargetId=ou_id)
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
response = client.attach_policy(PolicyId=policy_id, TargetId=account_id)
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
@mock_organizations
def test_detach_policy():
client = boto3.client("organizations", region_name="us-east-1")
2021-10-18 19:44:29 +00:00
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)]:
#
with sure.ensure("We should start with 0 policies"):
get_nonaws_policies(target, client).should.have.length_of(0)
#
client.attach_policy(PolicyId=policy_id, TargetId=target)
with sure.ensure("Expecting 1 policy after creation of target={0}", name):
get_nonaws_policies(target, client).should.have.length_of(1)
#
response = client.detach_policy(PolicyId=policy_id, TargetId=target)
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
with sure.ensure("Expecting 0 policies after deletion of target={0}", name):
get_nonaws_policies(target, client).should.have.length_of(0)
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"]
]
@mock_organizations
def test_detach_policy_root_ou_not_found_exception():
client = boto3.client("organizations", region_name="us-east-1")
2021-10-18 19:44:29 +00:00
client.create_organization(FeatureSet="ALL")["Organization"]
root_id = client.list_roots()["Roots"][0]["Id"]
2021-10-18 19:44:29 +00:00
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
ex.operation_name.should.equal("DetachPolicy")
ex.response["Error"]["Code"].should.equal("400")
ex.response["Error"]["Message"].should.contain(
"OrganizationalUnitNotFoundException"
)
@mock_organizations
def test_detach_policy_ou_not_found_exception():
client = boto3.client("organizations", region_name="us-east-1")
2021-10-18 19:44:29 +00:00
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
ex.operation_name.should.equal("DetachPolicy")
ex.response["Error"]["Code"].should.equal("400")
ex.response["Error"]["Message"].should.contain(
"OrganizationalUnitNotFoundException"
)
@mock_organizations
def test_detach_policy_account_id_not_found_exception():
client = boto3.client("organizations", region_name="us-east-1")
2021-10-18 19:44:29 +00:00
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
ex.operation_name.should.equal("DetachPolicy")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("AccountNotFoundException")
ex.response["Error"]["Message"].should.equal(
"You specified an account that doesn't exist."
)
@mock_organizations
def test_detach_policy_invalid_target_exception():
client = boto3.client("organizations", region_name="us-east-1")
2021-10-18 19:44:29 +00:00
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
ex.operation_name.should.equal("DetachPolicy")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("InvalidInputException")
ex.response["Error"]["Message"].should.equal("You specified an invalid value.")
@mock_organizations
def test_delete_policy():
client = boto3.client("organizations", region_name="us-east-1")
2021-10-18 19:44:29 +00:00
client.create_organization(FeatureSet="ALL")["Organization"]
base_policies = client.list_policies(Filter="SERVICE_CONTROL_POLICY")["Policies"]
base_policies.should.have.length_of(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"]
new_policies.should.have.length_of(2)
response = client.delete_policy(PolicyId=policy_id)
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
new_policies = client.list_policies(Filter="SERVICE_CONTROL_POLICY")["Policies"]
new_policies.should.equal(base_policies)
new_policies.should.have.length_of(1)
@mock_organizations
def test_delete_policy_exception():
client = boto3.client("organizations", region_name="us-east-1")
2021-10-18 19:44:29 +00:00
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
ex.operation_name.should.equal("DeletePolicy")
ex.response["Error"]["Code"].should.equal("400")
ex.response["Error"]["Message"].should.contain("PolicyNotFoundException")
# 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
ex.operation_name.should.equal("DeletePolicy")
ex.response["Error"]["Code"].should.equal("400")
ex.response["Error"]["Message"].should.contain("PolicyInUseException")
@mock_organizations
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
ex.operation_name.should.equal("AttachPolicy")
ex.response["Error"]["Code"].should.equal("400")
ex.response["Error"]["Message"].should.contain(
"OrganizationalUnitNotFoundException"
)
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
ex.operation_name.should.equal("AttachPolicy")
ex.response["Error"]["Code"].should.equal("400")
ex.response["Error"]["Message"].should.contain(
"OrganizationalUnitNotFoundException"
)
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
ex.operation_name.should.equal("AttachPolicy")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("AccountNotFoundException")
ex.response["Error"]["Message"].should.equal(
"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
ex.operation_name.should.equal("AttachPolicy")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("InvalidInputException")
ex.response["Error"]["Message"].should.equal("You specified an invalid value.")
@mock_organizations
def test_update_policy():
client = boto3.client("organizations", region_name="us-east-1")
org = client.create_organization(FeatureSet="ALL")["Organization"]
policy_dict = 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)
policy["Policy"]["PolicySummary"][key].should.equal("foobar")
validate_service_control_policy(org, response["Policy"])
response = client.update_policy(PolicyId=policy_id, Content="foobar")
policy = client.describe_policy(PolicyId=policy_id)
policy["Policy"]["Content"].should.equal("foobar")
validate_service_control_policy(org, response["Policy"])
@mock_organizations
def test_update_policy_exception():
client = boto3.client("organizations", region_name="us-east-1")
2021-10-18 19:44:29 +00:00
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
ex.operation_name.should.equal("UpdatePolicy")
ex.response["Error"]["Code"].should.equal("400")
ex.response["Error"]["Message"].should.contain("PolicyNotFoundException")
@mock_organizations
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
@mock_organizations
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)
@mock_organizations
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
ex.operation_name.should.equal("ListPoliciesForTarget")
ex.response["Error"]["Code"].should.equal("400")
ex.response["Error"]["Message"].should.contain(
"OrganizationalUnitNotFoundException"
)
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
ex.operation_name.should.equal("ListPoliciesForTarget")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("AccountNotFoundException")
ex.response["Error"]["Message"].should.equal(
"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
ex.operation_name.should.equal("ListPoliciesForTarget")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("InvalidInputException")
ex.response["Error"]["Message"].should.equal("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
ex.operation_name.should.equal("ListPoliciesForTarget")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("TargetNotFoundException")
ex.response["Error"]["Message"].should.equal(
"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
ex.operation_name.should.equal("ListPoliciesForTarget")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("InvalidInputException")
ex.response["Error"]["Message"].should.equal("You specified an invalid value.")
@mock_organizations
def test_list_targets_for_policy():
client = boto3.client("organizations", region_name="us-east-1")
2021-10-18 19:44:29 +00:00
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"]:
target.should.be.a(dict)
2021-07-26 06:40:39 +00:00
target.should.have.key("Name").should.be.a(str)
target.should.have.key("Arn").should.be.a(str)
target.should.have.key("TargetId").should.be.a(str)
target.should.have.key("Type").should.be.within(
["ROOT", "ORGANIZATIONAL_UNIT", "ACCOUNT"]
)
@mock_organizations
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
ex.operation_name.should.equal("ListTargetsForPolicy")
ex.response["Error"]["Code"].should.equal("400")
ex.response["Error"]["Message"].should.contain("PolicyNotFoundException")
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
ex.operation_name.should.equal("ListTargetsForPolicy")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("InvalidInputException")
ex.response["Error"]["Message"].should.equal("You specified an invalid value.")
2019-11-17 13:52:57 +00:00
@mock_organizations
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)
response["Tags"].should.equal([{"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)
response["Tags"].should.equal([{"Key": "key", "Value": "new-value"}])
client.untag_resource(ResourceId=resource_id, TagKeys=["key"])
response = client.list_tags_for_resource(ResourceId=resource_id)
response["Tags"].should.equal([])
@mock_organizations
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)
response["Tags"].should.equal([{"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)
response["Tags"].should.equal([{"Key": "key", "Value": "new-value"}])
client.untag_resource(ResourceId=resource_id, TagKeys=["key"])
response = client.list_tags_for_resource(ResourceId=resource_id)
response["Tags"].should.equal([])
@mock_organizations
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)
response["Tags"].should.equal([{"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)
response["Tags"].should.equal([{"Key": "key", "Value": "new-value"}])
client.untag_resource(ResourceId=resource_id, TagKeys=["key"])
response = client.list_tags_for_resource(ResourceId=resource_id)
response["Tags"].should.equal([])
2019-11-17 13:52:57 +00:00
@mock_organizations
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
2019-11-17 13:52:57 +00:00
ex.operation_name.should.equal("TagResource")
2019-11-21 21:03:25 +00:00
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("InvalidInputException")
ex.response["Error"]["Message"].should.equal(
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
ex.operation_name.should.equal("TagResource")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("TargetNotFoundException")
ex.response["Error"]["Message"].should.equal(
"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)
response.id.should.equal(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
ex.code.should.equal(400)
ex.description.should.contain("TargetNotFoundException")
ex.message.should.equal("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)
response.id.should.equal(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
ex.code.should.equal(400)
ex.description.should.contain("TargetNotFoundException")
ex.message.should.equal("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)
response.id.should.equal(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
ex.code.should.equal(400)
ex.description.should.contain("TargetNotFoundException")
ex.message.should.equal("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)
response.id.should.equal(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
ex.code.should.equal(400)
ex.description.should.contain("TargetNotFoundException")
ex.message.should.equal("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
ex.code.should.equal(400)
ex.description.should.contain("InvalidInputException")
ex.message.should.equal(
"You provided a value that does not match the required pattern."
)
@mock_organizations
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)
response["Tags"].should.equal([{"Key": "key", "Value": "value"}])
@mock_organizations
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
ex.operation_name.should.equal("ListTagsForResource")
2019-11-21 21:03:25 +00:00
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("InvalidInputException")
ex.response["Error"]["Message"].should.equal(
"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
ex.operation_name.should.equal("ListTagsForResource")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("TargetNotFoundException")
ex.response["Error"]["Message"].should.equal(
"You specified a target that doesn't exist."
)
2019-11-17 14:28:38 +00:00
@mock_organizations
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)
response["Tags"].should.equal([{"Key": "key", "Value": "value"}])
# 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)
response["Tags"].should.equal([{"Key": "key", "Value": "value"}])
client.untag_resource(ResourceId=account_id, TagKeys=["key"])
response = client.list_tags_for_resource(ResourceId=account_id)
response["Tags"].should.have.length_of(0)
@mock_organizations
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
2019-11-17 14:28:38 +00:00
ex.operation_name.should.equal("UntagResource")
2019-11-21 21:03:25 +00:00
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("InvalidInputException")
ex.response["Error"]["Message"].should.equal(
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
ex.operation_name.should.equal("UntagResource")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("TargetNotFoundException")
ex.response["Error"]["Message"].should.equal(
"You specified a target that doesn't exist."
)
@mock_organizations
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)
response["OrganizationalUnit"]["Name"].should.equal(ou_name)
new_ou_name = "ou02"
response = client.update_organizational_unit(
OrganizationalUnitId=response["OrganizationalUnit"]["Id"], Name=new_ou_name
)
validate_organizational_unit(org, response)
response["OrganizationalUnit"]["Name"].should.equal(new_ou_name)
@mock_organizations
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)
response["OrganizationalUnit"]["Name"].should.equal(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
exc.operation_name.should.equal("UpdateOrganizationalUnit")
exc.response["Error"]["Code"].should.contain("DuplicateOrganizationalUnitException")
exc.response["Error"]["Message"].should.equal(
"An OU with the same name already exists."
)
@mock_organizations
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()
response["EnabledServicePrincipals"].should.have.length_of(1)
service = response["EnabledServicePrincipals"][0]
service["ServicePrincipal"].should.equal("config.amazonaws.com")
date_enabled = service["DateEnabled"]
date_enabled.should.be.a(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()
response["EnabledServicePrincipals"].should.have.length_of(1)
service = response["EnabledServicePrincipals"][0]
service["ServicePrincipal"].should.equal("config.amazonaws.com")
service["DateEnabled"].should.equal(date_enabled)
@mock_organizations
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
ex.operation_name.should.equal("EnableAWSServiceAccess")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("InvalidInputException")
ex.response["Error"]["Message"].should.equal(
"You specified an unrecognized service principal."
)
@mock_organizations
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
response["EnabledServicePrincipals"].should.have.length_of(2)
services = sorted(
response["EnabledServicePrincipals"], key=lambda i: i["ServicePrincipal"]
)
services[0]["ServicePrincipal"].should.equal("config.amazonaws.com")
services[0]["DateEnabled"].should.be.a(datetime)
services[1]["ServicePrincipal"].should.equal("ram.amazonaws.com")
services[1]["DateEnabled"].should.be.a(datetime)
@mock_organizations
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()
response["EnabledServicePrincipals"].should.have.length_of(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()
response["EnabledServicePrincipals"].should.have.length_of(0)
@mock_organizations
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
ex.operation_name.should.equal("DisableAWSServiceAccess")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("InvalidInputException")
ex.response["Error"]["Message"].should.equal(
"You specified an unrecognized service principal."
)
@mock_organizations
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()
response["DelegatedAdministrators"].should.have.length_of(1)
admin = response["DelegatedAdministrators"][0]
admin["Id"].should.equal(account_id)
admin["Arn"].should.equal(
f"arn:aws:organizations::{ACCOUNT_ID}:account/{org_id}/{account_id}"
)
admin["Email"].should.equal(mockemail)
admin["Name"].should.equal(mockname)
admin["Status"].should.equal("ACTIVE")
admin["JoinedMethod"].should.equal("CREATED")
admin["JoinedTimestamp"].should.be.a(datetime)
admin["DelegationEnabledDate"].should.be.a(datetime)
@mock_organizations
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
ex.operation_name.should.equal("RegisterDelegatedAdministrator")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("ConstraintViolationException")
ex.response["Error"]["Message"].should.equal(
"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
ex.operation_name.should.equal("RegisterDelegatedAdministrator")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("AccountNotFoundException")
ex.response["Error"]["Message"].should.equal(
"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
ex.operation_name.should.equal("RegisterDelegatedAdministrator")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("InvalidInputException")
ex.response["Error"]["Message"].should.equal(
"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
ex.operation_name.should.equal("RegisterDelegatedAdministrator")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("AccountAlreadyRegisteredException")
ex.response["Error"]["Message"].should.equal(
"The provided account is already a delegated administrator for your organization."
)
@mock_organizations
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
response["DelegatedAdministrators"].should.have.length_of(2)
sorted([admin["Id"] for admin in response["DelegatedAdministrators"]]).should.equal(
sorted([account_id_1, account_id_2])
)
# when
response = client.list_delegated_administrators(
ServicePrincipal="ssm.amazonaws.com"
)
# then
response["DelegatedAdministrators"].should.have.length_of(1)
admin = response["DelegatedAdministrators"][0]
admin["Id"].should.equal(account_id_1)
admin["Arn"].should.equal(
f"arn:aws:organizations::{ACCOUNT_ID}:account/{org_id}/{account_id_1}"
)
admin["Email"].should.equal(mockemail)
admin["Name"].should.equal(mockname)
admin["Status"].should.equal("ACTIVE")
admin["JoinedMethod"].should.equal("CREATED")
admin["JoinedTimestamp"].should.be.a(datetime)
admin["DelegationEnabledDate"].should.be.a(datetime)
@mock_organizations
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
ex.operation_name.should.equal("ListDelegatedAdministrators")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("InvalidInputException")
ex.response["Error"]["Message"].should.equal(
"You specified an unrecognized service principal."
)
@mock_organizations
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
response["DelegatedServices"].should.have.length_of(2)
sorted(
[service["ServicePrincipal"] for service in response["DelegatedServices"]]
).should.equal(["guardduty.amazonaws.com", "ssm.amazonaws.com"])
@mock_organizations
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
ex.operation_name.should.equal("ListDelegatedServicesForAccount")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("AWSOrganizationsNotInUseException")
ex.response["Error"]["Message"].should.equal(
"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
ex.operation_name.should.equal("ListDelegatedServicesForAccount")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("AccountNotRegisteredException")
ex.response["Error"]["Message"].should.equal(
"The provided account is not a registered delegated administrator for your organization."
)
@mock_organizations
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()
response["DelegatedAdministrators"].should.have.length_of(0)
@mock_organizations
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
ex.operation_name.should.equal("DeregisterDelegatedAdministrator")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("ConstraintViolationException")
ex.response["Error"]["Message"].should.equal(
"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
ex.operation_name.should.equal("DeregisterDelegatedAdministrator")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("AccountNotFoundException")
ex.response["Error"]["Message"].should.equal(
"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
ex.operation_name.should.equal("DeregisterDelegatedAdministrator")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("AccountNotRegisteredException")
ex.response["Error"]["Message"].should.equal(
"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
ex.operation_name.should.equal("DeregisterDelegatedAdministrator")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("InvalidInputException")
ex.response["Error"]["Message"].should.equal(
"You specified an unrecognized service principal."
)
@mock_organizations
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"]
root["Id"].should.equal(root_id)
root["Arn"].should.equal(
utils.ROOT_ARN_FORMAT.format(org["MasterAccountId"], org["Id"], root_id)
)
root["Name"].should.equal("Root")
sorted(root["PolicyTypes"], key=lambda x: x["Type"]).should.equal(
2022-02-20 00:45:36 +00:00
[{"Type": "AISERVICES_OPT_OUT_POLICY", "Status": "ENABLED"}]
)
@mock_organizations
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
ex.operation_name.should.equal("EnablePolicyType")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("RootNotFoundException")
ex.response["Error"]["Message"].should.equal(
"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
ex.operation_name.should.equal("EnablePolicyType")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("PolicyTypeAlreadyEnabledException")
ex.response["Error"]["Message"].should.equal(
"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
ex.operation_name.should.equal("EnablePolicyType")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("InvalidInputException")
ex.response["Error"]["Message"].should.equal("You specified an invalid value.")
@mock_organizations
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"]
root["Id"].should.equal(root_id)
root["Arn"].should.equal(
utils.ROOT_ARN_FORMAT.format(org["MasterAccountId"], org["Id"], root_id)
)
root["Name"].should.equal("Root")
2022-02-20 00:45:36 +00:00
root["PolicyTypes"].should.equal([])
@mock_organizations
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
ex.operation_name.should.equal("DisablePolicyType")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("RootNotFoundException")
ex.response["Error"]["Message"].should.equal(
"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
ex.operation_name.should.equal("DisablePolicyType")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("PolicyTypeNotEnabledException")
ex.response["Error"]["Message"].should.equal(
"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
ex.operation_name.should.equal("DisablePolicyType")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("InvalidInputException")
ex.response["Error"]["Message"].should.equal("You specified an invalid value.")
@mock_organizations
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"]
summary["Id"].should.match(utils.POLICY_ID_REGEX)
summary["Arn"].should.equal(
utils.AI_POLICY_ARN_FORMAT.format(
org["MasterAccountId"], org["Id"], summary["Id"]
)
)
summary["Name"].should.equal("ai-opt-out")
summary["Description"].should.equal("Opt out of all AI services")
summary["Type"].should.equal("AISERVICES_OPT_OUT_POLICY")
summary["AwsManaged"].should.equal(False)
json.loads(response["Policy"]["Content"]).should.equal(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"
)
response["Policies"].should.have.length_of(1)
response["Policies"][0]["Id"].should.equal(policy_id)