Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Organizations: Extend validation and errors #8295

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions moto/organizations/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@ def __init__(self) -> None:
)


class AlreadyInOrganizationException(JsonRESTError):
code = 400

def __init__(self) -> None:
super().__init__(
"AlreadyInOrganizationException",
"The provided account is already a member of an organization.",
)


class AWSOrganizationsNotInUseException(JsonRESTError):
code = 400

Expand Down Expand Up @@ -83,6 +93,16 @@ def __init__(self) -> None:
)


class OrganizationNotEmptyException(JsonRESTError):
code = 400

def __init__(self) -> None:
super().__init__(
"OrganizationNotEmptyException",
"To delete an organization you must first remove all member accounts (except the master).",
)


class PolicyTypeAlreadyEnabledException(JsonRESTError):
code = 400

Expand Down
26 changes: 22 additions & 4 deletions moto/organizations/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@
AccountAlreadyRegisteredException,
AccountNotFoundException,
AccountNotRegisteredException,
AlreadyInOrganizationException,
AWSOrganizationsNotInUseException,
ConstraintViolationException,
DuplicateOrganizationalUnitException,
DuplicatePolicyException,
InvalidInputException,
OrganizationNotEmptyException,
PolicyNotFoundException,
PolicyTypeAlreadyEnabledException,
PolicyTypeNotEnabledException,
Expand Down Expand Up @@ -422,6 +424,9 @@ def _get_root_by_id(self, root_id: str) -> FakeRoot:
return root # type: ignore[return-value]

def create_organization(self, region: str, **kwargs: Any) -> Dict[str, Any]:
if self.org or self.account_id in organizations_backends.master_accounts:
raise AlreadyInOrganizationException

self.org = FakeOrganization(
self.account_id,
region_name=region,
Expand Down Expand Up @@ -468,11 +473,12 @@ def describe_organization(self) -> Dict[str, Any]:
raise AWSOrganizationsNotInUseException

def delete_organization(self) -> None:
if self.org is None:
raise AWSOrganizationsNotInUseException

if [account for account in self.accounts if account.name != "master"]:
raise RESTError(
"OrganizationNotEmptyException",
"To delete an organization you must first remove all member accounts (except the master).",
)
raise OrganizationNotEmptyException

self._reset()

def list_roots(self) -> Dict[str, Any]:
Expand Down Expand Up @@ -532,6 +538,12 @@ def list_organizational_units_for_parent(
]

def create_account(self, **kwargs: Any) -> Dict[str, Any]:
if (
self.org is None
or self.account_id not in organizations_backends.master_accounts
):
raise AWSOrganizationsNotInUseException

new_account = FakeAccount(self.org, **kwargs) # type: ignore
self.accounts.append(new_account)
self.attach_policy(PolicyId=utils.DEFAULT_POLICY_ID, TargetId=new_account.id)
Expand All @@ -542,6 +554,12 @@ def create_account(self, **kwargs: Any) -> Dict[str, Any]:
return new_account.create_account_status

def close_account(self, **kwargs: Any) -> None:
if (
self.org is None
or self.account_id not in organizations_backends.master_accounts
):
raise AWSOrganizationsNotInUseException

for account in self.accounts:
if account.id == kwargs["AccountId"]:
account.close()
Expand Down
Loading