diff --git a/IMPLEMENTATION_COVERAGE.md b/IMPLEMENTATION_COVERAGE.md index 84c574bc3..e1943aa9a 100644 --- a/IMPLEMENTATION_COVERAGE.md +++ b/IMPLEMENTATION_COVERAGE.md @@ -3147,7 +3147,7 @@ - [ ] update_server - [ ] update_server_engine_attributes -## organizations - 20% implemented +## organizations - 28% implemented - [ ] accept_handshake - [ ] attach_policy - [ ] cancel_handshake @@ -3174,7 +3174,7 @@ - [ ] invite_account_to_organization - [ ] leave_organization - [X] list_accounts -- [ ] list_accounts_for_parent +- [X] list_accounts_for_parent - [ ] list_aws_service_access_for_organization - [ ] list_children - [ ] list_create_account_status @@ -3186,7 +3186,7 @@ - [ ] list_policies_for_target - [X] list_roots - [ ] list_targets_for_policy -- [ ] move_account +- [X] move_account - [ ] remove_account_from_organization - [ ] update_organizational_unit - [ ] update_policy diff --git a/moto/organizations/models.py b/moto/organizations/models.py index b46c62798..bbcc1479b 100644 --- a/moto/organizations/models.py +++ b/moto/organizations/models.py @@ -51,7 +51,7 @@ class FakeOrganization(BaseModel): class FakeAccount(BaseModel): - def __init__(self, organization, **kwargs): + def __init__(self, organization, root_id, **kwargs): self.organization_id = organization.id self.master_account_id = organization.master_account_id self.create_account_status_id = utils.make_random_create_account_status_id() @@ -61,6 +61,7 @@ class FakeAccount(BaseModel): self.create_time = datetime.datetime.utcnow() self.status = 'ACTIVE' self.joined_method = 'CREATED' + self.parent_id = root_id @property def arn(self): @@ -215,7 +216,7 @@ class OrganizationsBackend(BaseBackend): return dict(Parents=root_parents + ou_parents) def create_account(self, **kwargs): - new_account = FakeAccount(self.org, **kwargs) + new_account = FakeAccount(self.org, self.roots[0].id, **kwargs) self.accounts.append(new_account) return new_account.create_account_status @@ -231,5 +232,25 @@ class OrganizationsBackend(BaseBackend): Accounts=[account.describe()['Account'] for account in self.accounts] ) + def list_accounts_for_parent(self, **kwargs): + return dict( + Accounts=[ + account.describe()['Account'] + for account in self.accounts + if account.parent_id == kwargs['ParentId'] + ] + ) + + def move_account(self, **kwargs): + new_parent_id = kwargs['DestinationParentId'] + all_parent_id = [parent.id for parent in self.roots + self.ou] + account = [ + account for account in self.accounts if account.account_id == kwargs['AccountId'] + ].pop(0) + assert new_parent_id in all_parent_id + assert account.parent_id == kwargs['SourceParentId'] + index = self.accounts.index(account) + self.accounts[index].parent_id = new_parent_id + organizations_backend = OrganizationsBackend() diff --git a/moto/organizations/responses.py b/moto/organizations/responses.py index 9fdb73317..6684ae685 100644 --- a/moto/organizations/responses.py +++ b/moto/organizations/responses.py @@ -70,3 +70,13 @@ class OrganizationsResponse(BaseResponse): return json.dumps( self.organizations_backend.list_accounts() ) + + def list_accounts_for_parent(self): + return json.dumps( + self.organizations_backend.list_accounts_for_parent(**self.request_params) + ) + + def move_account(self): + return json.dumps( + self.organizations_backend.move_account(**self.request_params) + ) diff --git a/tests/test_organizations/test_organizations_boto3.py b/tests/test_organizations/test_organizations_boto3.py index 8375ffbe3..5355e2716 100644 --- a/tests/test_organizations/test_organizations_boto3.py +++ b/tests/test_organizations/test_organizations_boto3.py @@ -274,3 +274,39 @@ def test_list_accounts(): accounts[3]['Name'].should.equal(mockname + '3') accounts[2]['Email'].should.equal(mockname + '2' + '@' + mockdomain) #assert False + + +@mock_organizations +def test_list_accounts_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'] + account_id = client.create_account( + AccountName=mockname, + Email=mockemail, + )['CreateAccountStatus']['AccountId'] + response = client.list_accounts_for_parent(ParentId=root_id) + #print(yaml.dump(response, default_flow_style=False)) + account_id.should.be.within([account['Id'] for account in response['Accounts']]) + #assert False + + +@mock_organizations +def test_move_account(): + client = boto3.client('organizations', region_name='us-east-1') + org = 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) + #print(yaml.dump(response, default_flow_style=False)) + account_id.should.be.within([account['Id'] for account in response['Accounts']]) + #assert False