Merge pull request #2360 from ashleygould/issue_2355
[Resolves #2355] - create_organization(): add master account, default…
This commit is contained in:
commit
fa07d4973b
@ -2,6 +2,7 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
import re
|
import re
|
||||||
|
import json
|
||||||
|
|
||||||
from moto.core import BaseBackend, BaseModel
|
from moto.core import BaseBackend, BaseModel
|
||||||
from moto.core.exceptions import RESTError
|
from moto.core.exceptions import RESTError
|
||||||
@ -151,7 +152,6 @@ class FakeRoot(FakeOrganizationalUnit):
|
|||||||
class FakeServiceControlPolicy(BaseModel):
|
class FakeServiceControlPolicy(BaseModel):
|
||||||
|
|
||||||
def __init__(self, organization, **kwargs):
|
def __init__(self, organization, **kwargs):
|
||||||
self.type = 'POLICY'
|
|
||||||
self.content = kwargs.get('Content')
|
self.content = kwargs.get('Content')
|
||||||
self.description = kwargs.get('Description')
|
self.description = kwargs.get('Description')
|
||||||
self.name = kwargs.get('Name')
|
self.name = kwargs.get('Name')
|
||||||
@ -197,7 +197,38 @@ class OrganizationsBackend(BaseBackend):
|
|||||||
|
|
||||||
def create_organization(self, **kwargs):
|
def create_organization(self, **kwargs):
|
||||||
self.org = FakeOrganization(kwargs['FeatureSet'])
|
self.org = FakeOrganization(kwargs['FeatureSet'])
|
||||||
self.ou.append(FakeRoot(self.org))
|
root_ou = FakeRoot(self.org)
|
||||||
|
self.ou.append(root_ou)
|
||||||
|
master_account = FakeAccount(
|
||||||
|
self.org,
|
||||||
|
AccountName='master',
|
||||||
|
Email=self.org.master_account_email,
|
||||||
|
)
|
||||||
|
master_account.id = self.org.master_account_id
|
||||||
|
self.accounts.append(master_account)
|
||||||
|
default_policy = FakeServiceControlPolicy(
|
||||||
|
self.org,
|
||||||
|
Name='FullAWSAccess',
|
||||||
|
Description='Allows access to every operation',
|
||||||
|
Type='SERVICE_CONTROL_POLICY',
|
||||||
|
Content=json.dumps(
|
||||||
|
{
|
||||||
|
"Version": "2012-10-17",
|
||||||
|
"Statement": [
|
||||||
|
{
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": "*",
|
||||||
|
"Resource": "*"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
default_policy.id = utils.DEFAULT_POLICY_ID
|
||||||
|
default_policy.aws_managed = True
|
||||||
|
self.policies.append(default_policy)
|
||||||
|
self.attach_policy(PolicyId=default_policy.id, TargetId=root_ou.id)
|
||||||
|
self.attach_policy(PolicyId=default_policy.id, TargetId=master_account.id)
|
||||||
return self.org.describe()
|
return self.org.describe()
|
||||||
|
|
||||||
def describe_organization(self):
|
def describe_organization(self):
|
||||||
@ -216,6 +247,7 @@ class OrganizationsBackend(BaseBackend):
|
|||||||
def create_organizational_unit(self, **kwargs):
|
def create_organizational_unit(self, **kwargs):
|
||||||
new_ou = FakeOrganizationalUnit(self.org, **kwargs)
|
new_ou = FakeOrganizationalUnit(self.org, **kwargs)
|
||||||
self.ou.append(new_ou)
|
self.ou.append(new_ou)
|
||||||
|
self.attach_policy(PolicyId=utils.DEFAULT_POLICY_ID, TargetId=new_ou.id)
|
||||||
return new_ou.describe()
|
return new_ou.describe()
|
||||||
|
|
||||||
def get_organizational_unit_by_id(self, ou_id):
|
def get_organizational_unit_by_id(self, ou_id):
|
||||||
@ -258,6 +290,7 @@ class OrganizationsBackend(BaseBackend):
|
|||||||
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)
|
||||||
|
self.attach_policy(PolicyId=utils.DEFAULT_POLICY_ID, TargetId=new_account.id)
|
||||||
return new_account.create_account_status
|
return new_account.create_account_status
|
||||||
|
|
||||||
def get_account_by_id(self, account_id):
|
def get_account_by_id(self, account_id):
|
||||||
@ -358,8 +391,7 @@ class OrganizationsBackend(BaseBackend):
|
|||||||
|
|
||||||
def attach_policy(self, **kwargs):
|
def attach_policy(self, **kwargs):
|
||||||
policy = next((p for p in self.policies if p.id == kwargs['PolicyId']), None)
|
policy = next((p for p in self.policies if p.id == kwargs['PolicyId']), None)
|
||||||
if (re.compile(utils.ROOT_ID_REGEX).match(kwargs['TargetId']) or
|
if (re.compile(utils.ROOT_ID_REGEX).match(kwargs['TargetId']) or re.compile(utils.OU_ID_REGEX).match(kwargs['TargetId'])):
|
||||||
re.compile(utils.OU_ID_REGEX).match(kwargs['TargetId'])):
|
|
||||||
ou = next((ou for ou in self.ou if ou.id == kwargs['TargetId']), None)
|
ou = next((ou for ou in self.ou if ou.id == kwargs['TargetId']), None)
|
||||||
if ou is not None:
|
if ou is not None:
|
||||||
if ou not in ou.attached_policies:
|
if ou not in ou.attached_policies:
|
||||||
|
@ -4,7 +4,8 @@ import random
|
|||||||
import string
|
import string
|
||||||
|
|
||||||
MASTER_ACCOUNT_ID = '123456789012'
|
MASTER_ACCOUNT_ID = '123456789012'
|
||||||
MASTER_ACCOUNT_EMAIL = 'fakeorg@moto-example.com'
|
MASTER_ACCOUNT_EMAIL = 'master@example.com'
|
||||||
|
DEFAULT_POLICY_ID = 'p-FullAWSAccess'
|
||||||
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}'
|
||||||
@ -26,7 +27,7 @@ ROOT_ID_REGEX = r'r-[a-z0-9]{%s}' % ROOT_ID_SIZE
|
|||||||
OU_ID_REGEX = r'ou-[a-z0-9]{%s}-[a-z0-9]{%s}' % (ROOT_ID_SIZE, OU_ID_SUFFIX_SIZE)
|
OU_ID_REGEX = r'ou-[a-z0-9]{%s}-[a-z0-9]{%s}' % (ROOT_ID_SIZE, OU_ID_SUFFIX_SIZE)
|
||||||
ACCOUNT_ID_REGEX = r'[0-9]{%s}' % ACCOUNT_ID_SIZE
|
ACCOUNT_ID_REGEX = r'[0-9]{%s}' % ACCOUNT_ID_SIZE
|
||||||
CREATE_ACCOUNT_STATUS_ID_REGEX = r'car-[a-z0-9]{%s}' % CREATE_ACCOUNT_STATUS_ID_SIZE
|
CREATE_ACCOUNT_STATUS_ID_REGEX = r'car-[a-z0-9]{%s}' % CREATE_ACCOUNT_STATUS_ID_SIZE
|
||||||
SCP_ID_REGEX = r'p-[a-z0-9]{%s}' % SCP_ID_SIZE
|
SCP_ID_REGEX = r'%s|p-[a-z0-9]{%s}' % (DEFAULT_POLICY_ID, SCP_ID_SIZE)
|
||||||
|
|
||||||
|
|
||||||
def make_random_org_id():
|
def make_random_org_id():
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import six
|
import six
|
||||||
import sure # noqa
|
|
||||||
import datetime
|
import datetime
|
||||||
from moto.organizations import utils
|
from moto.organizations import utils
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ from __future__ import unicode_literals
|
|||||||
import boto3
|
import boto3
|
||||||
import json
|
import json
|
||||||
import six
|
import six
|
||||||
import sure # noqa
|
|
||||||
from botocore.exceptions import ClientError
|
from botocore.exceptions import ClientError
|
||||||
from nose.tools import assert_raises
|
from nose.tools import assert_raises
|
||||||
|
|
||||||
@ -27,6 +26,25 @@ def test_create_organization():
|
|||||||
validate_organization(response)
|
validate_organization(response)
|
||||||
response['Organization']['FeatureSet'].should.equal('ALL')
|
response['Organization']['FeatureSet'].should.equal('ALL')
|
||||||
|
|
||||||
|
response = client.list_accounts()
|
||||||
|
len(response['Accounts']).should.equal(1)
|
||||||
|
response['Accounts'][0]['Name'].should.equal('master')
|
||||||
|
response['Accounts'][0]['Id'].should.equal(utils.MASTER_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')
|
||||||
|
|
||||||
|
|
||||||
@mock_organizations
|
@mock_organizations
|
||||||
def test_describe_organization():
|
def test_describe_organization():
|
||||||
@ -177,11 +195,11 @@ def test_list_accounts():
|
|||||||
response = client.list_accounts()
|
response = client.list_accounts()
|
||||||
response.should.have.key('Accounts')
|
response.should.have.key('Accounts')
|
||||||
accounts = response['Accounts']
|
accounts = response['Accounts']
|
||||||
len(accounts).should.equal(5)
|
len(accounts).should.equal(6)
|
||||||
for account in accounts:
|
for account in accounts:
|
||||||
validate_account(org, account)
|
validate_account(org, account)
|
||||||
accounts[3]['Name'].should.equal(mockname + '3')
|
accounts[4]['Name'].should.equal(mockname + '3')
|
||||||
accounts[2]['Email'].should.equal(mockname + '2' + '@' + mockdomain)
|
accounts[3]['Email'].should.equal(mockname + '2' + '@' + mockdomain)
|
||||||
|
|
||||||
|
|
||||||
@mock_organizations
|
@mock_organizations
|
||||||
@ -291,8 +309,10 @@ def test_list_children():
|
|||||||
response02 = client.list_children(ParentId=root_id, ChildType='ORGANIZATIONAL_UNIT')
|
response02 = client.list_children(ParentId=root_id, ChildType='ORGANIZATIONAL_UNIT')
|
||||||
response03 = client.list_children(ParentId=ou01_id, ChildType='ACCOUNT')
|
response03 = client.list_children(ParentId=ou01_id, ChildType='ACCOUNT')
|
||||||
response04 = client.list_children(ParentId=ou01_id, ChildType='ORGANIZATIONAL_UNIT')
|
response04 = client.list_children(ParentId=ou01_id, ChildType='ORGANIZATIONAL_UNIT')
|
||||||
response01['Children'][0]['Id'].should.equal(account01_id)
|
response01['Children'][0]['Id'].should.equal(utils.MASTER_ACCOUNT_ID)
|
||||||
response01['Children'][0]['Type'].should.equal('ACCOUNT')
|
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]['Id'].should.equal(ou01_id)
|
||||||
response02['Children'][0]['Type'].should.equal('ORGANIZATIONAL_UNIT')
|
response02['Children'][0]['Type'].should.equal('ORGANIZATIONAL_UNIT')
|
||||||
response03['Children'][0]['Id'].should.equal(account02_id)
|
response03['Children'][0]['Id'].should.equal(account02_id)
|
||||||
@ -591,4 +611,3 @@ def test_list_targets_for_policy_exception():
|
|||||||
ex.operation_name.should.equal('ListTargetsForPolicy')
|
ex.operation_name.should.equal('ListTargetsForPolicy')
|
||||||
ex.response['Error']['Code'].should.equal('400')
|
ex.response['Error']['Code'].should.equal('400')
|
||||||
ex.response['Error']['Message'].should.contain('InvalidInputException')
|
ex.response['Error']['Message'].should.contain('InvalidInputException')
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user