organizations: add 2 more endpoints

create_organizational_unit
describe_organizational_unit
This commit is contained in:
Ashley Gould 2018-07-15 11:49:26 -07:00
parent 6c0c6148f1
commit beebb9abc8
4 changed files with 107 additions and 32 deletions

View File

@ -3147,13 +3147,13 @@
- [ ] update_server - [ ] update_server
- [ ] update_server_engine_attributes - [ ] update_server_engine_attributes
## organizations - 8% implemented ## organizations - 19% implemented
- [ ] accept_handshake - [ ] accept_handshake
- [ ] attach_policy - [ ] attach_policy
- [ ] cancel_handshake - [ ] cancel_handshake
- [X] create_account - [X] create_account
- [X] create_organization - [X] create_organization
- [ ] create_organizational_unit - [X] create_organizational_unit
- [ ] create_policy - [ ] create_policy
- [ ] decline_handshake - [ ] decline_handshake
- [ ] delete_organization - [ ] delete_organization
@ -3163,7 +3163,7 @@
- [ ] describe_create_account_status - [ ] describe_create_account_status
- [ ] describe_handshake - [ ] describe_handshake
- [X] describe_organization - [X] describe_organization
- [ ] describe_organizational_unit - [X] describe_organizational_unit
- [ ] describe_policy - [ ] describe_policy
- [ ] detach_policy - [ ] detach_policy
- [ ] disable_aws_service_access - [ ] disable_aws_service_access
@ -3184,7 +3184,7 @@
- [ ] list_parents - [ ] list_parents
- [ ] list_policies - [ ] list_policies
- [ ] list_policies_for_target - [ ] list_policies_for_target
- [ ] list_roots - [X] list_roots
- [ ] list_targets_for_policy - [ ] list_targets_for_policy
- [ ] move_account - [ ] move_account
- [ ] remove_account_from_organization - [ ] remove_account_from_organization

View File

@ -12,6 +12,7 @@ ORGANIZATION_ARN_FORMAT = 'arn:aws:organizations::{0}:organization/{1}'
MASTER_ACCOUNT_ARN_FORMAT = 'arn:aws:organizations::{0}:account/{1}/{0}' MASTER_ACCOUNT_ARN_FORMAT = 'arn:aws:organizations::{0}:account/{1}/{0}'
ACCOUNT_ARN_FORMAT = 'arn:aws:organizations::{0}:account/{1}/{2}' ACCOUNT_ARN_FORMAT = 'arn:aws:organizations::{0}:account/{1}/{2}'
ROOT_ARN_FORMAT = 'arn:aws:organizations::{0}:root/{1}/{2}' ROOT_ARN_FORMAT = 'arn:aws:organizations::{0}:root/{1}/{2}'
OU_ARN_FORMAT = 'arn:aws:organizations::{0}:ou/{1}/{2}'
class FakeOrganization(BaseModel): class FakeOrganization(BaseModel):
@ -95,32 +96,6 @@ class FakeAccount(BaseModel):
} }
class FakeOrganizationalUnit(BaseModel):
def __init__(self, organization, **kwargs):
self.organization_id = organization.id
self.master_account_id = organization.master_account_id
self.id = utils.make_random_ou_id()
self.name = kwargs['Name']
@property
def arn(self):
return OU_ARN_FORMAT.format(
self.master_account_id,
self.organization_id,
self.id
)
def describe(self):
return {
'OrganizationalUnit': {
'Id': self.id,
'Arn': self.arn,
'Name': self.name,
}
}
class FakeRoot(BaseModel): class FakeRoot(BaseModel):
def __init__(self, organization, **kwargs): def __init__(self, organization, **kwargs):
@ -150,12 +125,40 @@ class FakeRoot(BaseModel):
} }
class FakeOrganizationalUnit(BaseModel):
def __init__(self, organization, root_id, **kwargs):
self.organization_id = organization.id
self.master_account_id = organization.master_account_id
self.id = utils.make_random_ou_id(root_id)
self.name = kwargs['Name']
self.parent_id = kwargs['ParentId']
@property
def arn(self):
return OU_ARN_FORMAT.format(
self.master_account_id,
self.organization_id,
self.id
)
def describe(self):
return {
'OrganizationalUnit': {
'Id': self.id,
'Arn': self.arn,
'Name': self.name,
}
}
class OrganizationsBackend(BaseBackend): class OrganizationsBackend(BaseBackend):
def __init__(self): def __init__(self):
self.org = None self.org = None
self.accounts = [] self.accounts = []
self.roots = [] self.roots = []
self.ou = []
def create_organization(self, **kwargs): def create_organization(self, **kwargs):
self.org = FakeOrganization(kwargs['FeatureSet']) self.org = FakeOrganization(kwargs['FeatureSet'])
@ -170,14 +173,27 @@ class OrganizationsBackend(BaseBackend):
Roots=[root.describe() for root in self.roots] Roots=[root.describe() for root in self.roots]
) )
def create_organizational_unit(self, **kwargs):
new_ou = FakeOrganizationalUnit(self.org, self.roots[0].id, **kwargs)
self.ou.append(new_ou)
return new_ou.describe()
def describe_organizational_unit(self, **kwargs):
ou = [
ou for ou in self.ou if ou.id == kwargs['OrganizationalUnitId']
].pop(0)
return ou.describe()
def create_account(self, **kwargs): def create_account(self, **kwargs):
new_account = FakeAccount(self.org, **kwargs) new_account = FakeAccount(self.org, **kwargs)
self.accounts.append(new_account) self.accounts.append(new_account)
return new_account.create_account_status return new_account.create_account_status
def describe_account(self, **kwargs): def describe_account(self, **kwargs):
account = [account for account in self.accounts account = [
if account.account_id == kwargs['AccountId']][0] account for account in self.accounts
if account.account_id == kwargs['AccountId']
].pop(0)
return account.describe() return account.describe()
def list_accounts(self): def list_accounts(self):

View File

@ -36,6 +36,16 @@ class OrganizationsResponse(BaseResponse):
self.organizations_backend.list_roots() self.organizations_backend.list_roots()
) )
def create_organizational_unit(self):
return json.dumps(
self.organizations_backend.create_organizational_unit(**self.request_params)
)
def describe_organizational_unit(self):
return json.dumps(
self.organizations_backend.describe_organizational_unit(**self.request_params)
)
def create_account(self): def create_account(self):
return json.dumps( return json.dumps(
self.organizations_backend.create_account(**self.request_params) self.organizations_backend.create_account(**self.request_params)

View File

@ -13,10 +13,12 @@ from moto.organizations.models import (
MASTER_ACCOUNT_ARN_FORMAT, MASTER_ACCOUNT_ARN_FORMAT,
ACCOUNT_ARN_FORMAT, ACCOUNT_ARN_FORMAT,
ROOT_ARN_FORMAT, ROOT_ARN_FORMAT,
OU_ARN_FORMAT,
) )
from .test_organizations_utils import ( from .test_organizations_utils import (
ORG_ID_REGEX, ORG_ID_REGEX,
ROOT_ID_REGEX, ROOT_ID_REGEX,
OU_ID_REGEX,
ACCOUNT_ID_REGEX, ACCOUNT_ID_REGEX,
CREATE_ACCOUNT_STATUS_ID_REGEX, CREATE_ACCOUNT_STATUS_ID_REGEX,
) )
@ -53,6 +55,18 @@ def validate_organization(response):
}]) }])
def validate_organizationa_unit(org, response):
response.should.have.key('OrganizationalUnit').should.be.a(dict)
ou = response['OrganizationalUnit']
ou.should.have.key('Id').should.match(OU_ID_REGEX)
ou.should.have.key('Arn').should.equal(OU_ARN_FORMAT.format(
org['MasterAccountId'],
org['Id'],
ou['Id'],
))
ou.should.have.key('Name').should.equal(ou_name)
def validate_account(org, account): def validate_account(org, account):
sorted(account.keys()).should.equal([ sorted(account.keys()).should.equal([
'Arn', 'Arn',
@ -113,6 +127,9 @@ def test_describe_organization():
#assert False #assert False
# Organizational Units
ou_name = 'ou01'
@mock_organizations @mock_organizations
def test_list_roots(): def test_list_roots():
client = boto3.client('organizations', region_name='us-east-1') client = boto3.client('organizations', region_name='us-east-1')
@ -135,6 +152,38 @@ def test_list_roots():
#assert False #assert False
@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']
response = client.create_organizational_unit(
ParentId=root_id,
Name=ou_name,
)
#print(yaml.dump(response, default_flow_style=False))
validate_organizationa_unit(org, response)
#assert False
@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=ou_name,
)['OrganizationalUnit']['Id']
response = client.describe_organizational_unit(
OrganizationalUnitId=ou_id,
)
print(yaml.dump(response, default_flow_style=False))
validate_organizationa_unit(org, response)
#assert False
# Accounts
mockname = 'mock-account' mockname = 'mock-account'
mockdomain = 'moto-example.org' mockdomain = 'moto-example.org'
mockemail = '@'.join([mockname, mockdomain]) mockemail = '@'.join([mockname, mockdomain])