organizations: add endpoint list_roots
This commit is contained in:
parent
c40d2be646
commit
6c0c6148f1
@ -11,7 +11,7 @@ MASTER_ACCOUNT_EMAIL = 'fakeorg@moto-example.com'
|
|||||||
ORGANIZATION_ARN_FORMAT = 'arn:aws:organizations::{0}:organization/{1}'
|
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}'
|
||||||
|
|
||||||
class FakeOrganization(BaseModel):
|
class FakeOrganization(BaseModel):
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ class FakeOrganization(BaseModel):
|
|||||||
def master_account_arn(self):
|
def master_account_arn(self):
|
||||||
return MASTER_ACCOUNT_ARN_FORMAT.format(self.master_account_id, self.id)
|
return MASTER_ACCOUNT_ARN_FORMAT.format(self.master_account_id, self.id)
|
||||||
|
|
||||||
def _describe(self):
|
def describe(self):
|
||||||
return {
|
return {
|
||||||
'Organization': {
|
'Organization': {
|
||||||
'Id': self.id,
|
'Id': self.id,
|
||||||
@ -95,18 +95,80 @@ 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):
|
||||||
|
|
||||||
|
def __init__(self, organization, **kwargs):
|
||||||
|
self.organization_id = organization.id
|
||||||
|
self.master_account_id = organization.master_account_id
|
||||||
|
self.id = utils.make_random_root_id()
|
||||||
|
self.name = 'Root'
|
||||||
|
self.policy_types = [{
|
||||||
|
'Type': 'SERVICE_CONTROL_POLICY',
|
||||||
|
'Status': 'ENABLED'
|
||||||
|
}]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def arn(self):
|
||||||
|
return ROOT_ARN_FORMAT.format(
|
||||||
|
self.master_account_id,
|
||||||
|
self.organization_id,
|
||||||
|
self.id
|
||||||
|
)
|
||||||
|
|
||||||
|
def describe(self):
|
||||||
|
return {
|
||||||
|
'Id': self.id,
|
||||||
|
'Arn': self.arn,
|
||||||
|
'Name': self.name,
|
||||||
|
'PolicyTypes': self.policy_types
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class OrganizationsBackend(BaseBackend):
|
class OrganizationsBackend(BaseBackend):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.org = None
|
self.org = None
|
||||||
self.accounts = []
|
self.accounts = []
|
||||||
|
self.roots = []
|
||||||
|
|
||||||
def create_organization(self, **kwargs):
|
def create_organization(self, **kwargs):
|
||||||
self.org = FakeOrganization(kwargs['FeatureSet'])
|
self.org = FakeOrganization(kwargs['FeatureSet'])
|
||||||
return self.org._describe()
|
self.roots.append(FakeRoot(self.org))
|
||||||
|
return self.org.describe()
|
||||||
|
|
||||||
def describe_organization(self):
|
def describe_organization(self):
|
||||||
return self.org._describe()
|
return self.org.describe()
|
||||||
|
|
||||||
|
def list_roots(self):
|
||||||
|
return dict(
|
||||||
|
Roots=[root.describe() for root in self.roots]
|
||||||
|
)
|
||||||
|
|
||||||
def create_account(self, **kwargs):
|
def create_account(self, **kwargs):
|
||||||
new_account = FakeAccount(self.org, **kwargs)
|
new_account = FakeAccount(self.org, **kwargs)
|
||||||
|
@ -31,6 +31,11 @@ class OrganizationsResponse(BaseResponse):
|
|||||||
self.organizations_backend.describe_organization()
|
self.organizations_backend.describe_organization()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def list_roots(self):
|
||||||
|
return json.dumps(
|
||||||
|
self.organizations_backend.list_roots()
|
||||||
|
)
|
||||||
|
|
||||||
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)
|
||||||
|
@ -7,6 +7,7 @@ CHARSET = string.ascii_lowercase + string.digits
|
|||||||
ORG_ID_SIZE = 10
|
ORG_ID_SIZE = 10
|
||||||
ROOT_ID_SIZE = 4
|
ROOT_ID_SIZE = 4
|
||||||
ACCOUNT_ID_SIZE = 12
|
ACCOUNT_ID_SIZE = 12
|
||||||
|
OU_ID_SUFFIX_SIZE = 8
|
||||||
CREATE_ACCOUNT_STATUS_ID_SIZE = 8
|
CREATE_ACCOUNT_STATUS_ID_SIZE = 8
|
||||||
|
|
||||||
|
|
||||||
@ -24,6 +25,19 @@ def make_random_root_id():
|
|||||||
return 'r-' + ''.join(random.choice(CHARSET) for x in range(ROOT_ID_SIZE))
|
return 'r-' + ''.join(random.choice(CHARSET) for x in range(ROOT_ID_SIZE))
|
||||||
|
|
||||||
|
|
||||||
|
def make_random_ou_id(root_id):
|
||||||
|
# The regex pattern for an organizational unit ID string requires "ou-"
|
||||||
|
# followed by from 4 to 32 lower-case letters or digits (the ID of the root
|
||||||
|
# that contains the OU) followed by a second "-" dash and from 8 to 32
|
||||||
|
# additional lower-case letters or digits.
|
||||||
|
# e.g. ou-g8sd-5oe3bjaw
|
||||||
|
return '-'.join([
|
||||||
|
'ou',
|
||||||
|
root_id.partition('-')[2],
|
||||||
|
''.join(random.choice(CHARSET) for x in range(OU_ID_SUFFIX_SIZE)),
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
def make_random_account_id():
|
def make_random_account_id():
|
||||||
# The regex pattern for an account ID string requires exactly 12 digits.
|
# The regex pattern for an account ID string requires exactly 12 digits.
|
||||||
# e.g. '488633172133'
|
# e.g. '488633172133'
|
||||||
|
@ -9,9 +9,11 @@ from moto import organizations as orgs
|
|||||||
|
|
||||||
# utils
|
# utils
|
||||||
print(orgs.utils.make_random_org_id())
|
print(orgs.utils.make_random_org_id())
|
||||||
print(orgs.utils.make_random_root_id())
|
root_id = orgs.utils.make_random_root_id()
|
||||||
|
print(root_id)
|
||||||
|
print(orgs.utils.make_random_ou_id(root_id))
|
||||||
print(orgs.utils.make_random_account_id())
|
print(orgs.utils.make_random_account_id())
|
||||||
print(orgs.utils.make_random_create_account_id())
|
print(orgs.utils.make_random_create_account_status_id())
|
||||||
|
|
||||||
# models
|
# models
|
||||||
my_org = orgs.models.FakeOrganization(feature_set='ALL')
|
my_org = orgs.models.FakeOrganization(feature_set='ALL')
|
||||||
|
@ -3,6 +3,7 @@ from __future__ import unicode_literals
|
|||||||
import boto3
|
import boto3
|
||||||
import sure # noqa
|
import sure # noqa
|
||||||
import datetime
|
import datetime
|
||||||
|
import yaml
|
||||||
|
|
||||||
from moto import mock_organizations
|
from moto import mock_organizations
|
||||||
from moto.organizations.models import (
|
from moto.organizations.models import (
|
||||||
@ -11,6 +12,7 @@ from moto.organizations.models import (
|
|||||||
ORGANIZATION_ARN_FORMAT,
|
ORGANIZATION_ARN_FORMAT,
|
||||||
MASTER_ACCOUNT_ARN_FORMAT,
|
MASTER_ACCOUNT_ARN_FORMAT,
|
||||||
ACCOUNT_ARN_FORMAT,
|
ACCOUNT_ARN_FORMAT,
|
||||||
|
ROOT_ARN_FORMAT,
|
||||||
)
|
)
|
||||||
from .test_organizations_utils import (
|
from .test_organizations_utils import (
|
||||||
ORG_ID_REGEX,
|
ORG_ID_REGEX,
|
||||||
@ -111,6 +113,28 @@ def test_describe_organization():
|
|||||||
#assert False
|
#assert False
|
||||||
|
|
||||||
|
|
||||||
|
@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()
|
||||||
|
#print(yaml.dump(response, default_flow_style=False))
|
||||||
|
response.should.have.key('Roots').should.be.a(list)
|
||||||
|
response['Roots'].should_not.be.empty
|
||||||
|
root = response['Roots'][0]
|
||||||
|
root.should.have.key('Id').should.match(ROOT_ID_REGEX)
|
||||||
|
root.should.have.key('Arn').should.equal(ROOT_ARN_FORMAT.format(
|
||||||
|
org['MasterAccountId'],
|
||||||
|
org['Id'],
|
||||||
|
root['Id'],
|
||||||
|
))
|
||||||
|
root.should.have.key('Name').should.be.a(str)
|
||||||
|
root.should.have.key('PolicyTypes').should.be.a(list)
|
||||||
|
root['PolicyTypes'][0].should.have.key('Type').should.equal('SERVICE_CONTROL_POLICY')
|
||||||
|
root['PolicyTypes'][0].should.have.key('Status').should.equal('ENABLED')
|
||||||
|
#assert False
|
||||||
|
|
||||||
|
|
||||||
mockname = 'mock-account'
|
mockname = 'mock-account'
|
||||||
mockdomain = 'moto-example.org'
|
mockdomain = 'moto-example.org'
|
||||||
mockemail = '@'.join([mockname, mockdomain])
|
mockemail = '@'.join([mockname, mockdomain])
|
||||||
|
@ -5,6 +5,7 @@ from moto.organizations import utils
|
|||||||
|
|
||||||
ORG_ID_REGEX = r'o-[a-z0-9]{%s}' % utils.ORG_ID_SIZE
|
ORG_ID_REGEX = r'o-[a-z0-9]{%s}' % utils.ORG_ID_SIZE
|
||||||
ROOT_ID_REGEX = r'r-[a-z0-9]{%s}' % utils.ROOT_ID_SIZE
|
ROOT_ID_REGEX = r'r-[a-z0-9]{%s}' % utils.ROOT_ID_SIZE
|
||||||
|
OU_ID_REGEX = r'ou-[a-z0-9]{%s}-[a-z0-9]{%s}' % (utils.ROOT_ID_SIZE, utils.OU_ID_SUFFIX_SIZE)
|
||||||
ACCOUNT_ID_REGEX = r'[0-9]{%s}' % utils.ACCOUNT_ID_SIZE
|
ACCOUNT_ID_REGEX = r'[0-9]{%s}' % utils.ACCOUNT_ID_SIZE
|
||||||
CREATE_ACCOUNT_STATUS_ID_REGEX = r'car-[a-z0-9]{%s}' % utils.CREATE_ACCOUNT_STATUS_ID_SIZE
|
CREATE_ACCOUNT_STATUS_ID_REGEX = r'car-[a-z0-9]{%s}' % utils.CREATE_ACCOUNT_STATUS_ID_SIZE
|
||||||
|
|
||||||
@ -15,8 +16,14 @@ def test_make_random_org_id():
|
|||||||
|
|
||||||
|
|
||||||
def test_make_random_root_id():
|
def test_make_random_root_id():
|
||||||
org_id = utils.make_random_root_id()
|
root_id = utils.make_random_root_id()
|
||||||
org_id.should.match(ROOT_ID_REGEX)
|
root_id.should.match(ROOT_ID_REGEX)
|
||||||
|
|
||||||
|
|
||||||
|
def test_make_random_ou_id():
|
||||||
|
root_id = utils.make_random_root_id()
|
||||||
|
ou_id = utils.make_random_ou_id(root_id)
|
||||||
|
ou_id.should.match(OU_ID_REGEX)
|
||||||
|
|
||||||
|
|
||||||
def test_make_random_account_id():
|
def test_make_random_account_id():
|
||||||
|
Loading…
x
Reference in New Issue
Block a user