Merge pull request #2061 from rubelw/master
Update kms, iam and lambda to work with terraform
This commit is contained in:
commit
7f0b1d6795
@ -500,6 +500,11 @@ class LambdaStorage(object):
|
||||
except ValueError:
|
||||
return self._functions[name]['latest']
|
||||
|
||||
def list_versions_by_function(self, name):
|
||||
if name not in self._functions:
|
||||
return None
|
||||
return [self._functions[name]['latest']]
|
||||
|
||||
def get_arn(self, arn):
|
||||
return self._arns.get(arn, None)
|
||||
|
||||
@ -607,6 +612,9 @@ class LambdaBackend(BaseBackend):
|
||||
def get_function(self, function_name, qualifier=None):
|
||||
return self._lambdas.get_function(function_name, qualifier)
|
||||
|
||||
def list_versions_by_function(self, function_name):
|
||||
return self._lambdas.list_versions_by_function(function_name)
|
||||
|
||||
def get_function_by_arn(self, function_arn):
|
||||
return self._lambdas.get_arn(function_arn)
|
||||
|
||||
|
@ -52,7 +52,11 @@ class LambdaResponse(BaseResponse):
|
||||
self.setup_class(request, full_url, headers)
|
||||
if request.method == 'GET':
|
||||
# This is ListVersionByFunction
|
||||
raise ValueError("Cannot handle request")
|
||||
|
||||
path = request.path if hasattr(request, 'path') else path_url(request.url)
|
||||
function_name = path.split('/')[-2]
|
||||
return self._list_versions_by_function(function_name)
|
||||
|
||||
elif request.method == 'POST':
|
||||
return self._publish_function(request, full_url, headers)
|
||||
else:
|
||||
@ -151,6 +155,19 @@ class LambdaResponse(BaseResponse):
|
||||
|
||||
return 200, {}, json.dumps(result)
|
||||
|
||||
def _list_versions_by_function(self, function_name):
|
||||
result = {
|
||||
'Versions': []
|
||||
}
|
||||
|
||||
functions = self.lambda_backend.list_versions_by_function(function_name)
|
||||
if functions:
|
||||
for fn in functions:
|
||||
json_data = fn.get_configuration()
|
||||
result['Versions'].append(json_data)
|
||||
|
||||
return 200, {}, json.dumps(result)
|
||||
|
||||
def _create_function(self, request, full_url, headers):
|
||||
try:
|
||||
fn = self.lambda_backend.create_function(self.json_body)
|
||||
|
@ -134,6 +134,7 @@ class Role(BaseModel):
|
||||
self.managed_policies = {}
|
||||
self.create_date = datetime.now(pytz.utc)
|
||||
self.tags = {}
|
||||
self.description = ""
|
||||
|
||||
@classmethod
|
||||
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
|
||||
@ -473,6 +474,16 @@ class IAMBackend(BaseBackend):
|
||||
policy = arns[policy_arn]
|
||||
policy.attach_to(self.get_role(role_name))
|
||||
|
||||
def update_role_description(self, role_name, role_description):
|
||||
role = self.get_role(role_name)
|
||||
role.description = role_description
|
||||
return role
|
||||
|
||||
def update_role(self, role_name, role_description):
|
||||
role = self.get_role(role_name)
|
||||
role.description = role_description
|
||||
return role
|
||||
|
||||
def detach_role_policy(self, policy_arn, role_name):
|
||||
arns = dict((p.arn, p) for p in self.managed_policies.values())
|
||||
try:
|
||||
@ -881,6 +892,16 @@ class IAMBackend(BaseBackend):
|
||||
|
||||
return users
|
||||
|
||||
def list_roles(self, path_prefix, marker, max_items):
|
||||
roles = None
|
||||
try:
|
||||
roles = self.roles.values()
|
||||
except KeyError:
|
||||
raise IAMNotFoundException(
|
||||
"Users {0}, {1}, {2} not found".format(path_prefix, marker, max_items))
|
||||
|
||||
return roles
|
||||
|
||||
def upload_signing_certificate(self, user_name, body):
|
||||
user = self.get_user(user_name)
|
||||
cert_id = random_resource_id(size=32)
|
||||
|
@ -107,6 +107,69 @@ class IamResponse(BaseResponse):
|
||||
template = self.response_template(LIST_POLICIES_TEMPLATE)
|
||||
return template.render(policies=policies, marker=marker)
|
||||
|
||||
def list_entities_for_policy(self):
|
||||
policy_arn = self._get_param('PolicyArn')
|
||||
|
||||
# Options 'User'|'Role'|'Group'|'LocalManagedPolicy'|'AWSManagedPolicy
|
||||
entity = self._get_param('EntityFilter')
|
||||
path_prefix = self._get_param('PathPrefix')
|
||||
# policy_usage_filter = self._get_param('PolicyUsageFilter')
|
||||
marker = self._get_param('Marker')
|
||||
max_items = self._get_param('MaxItems')
|
||||
|
||||
entity_roles = []
|
||||
entity_groups = []
|
||||
entity_users = []
|
||||
|
||||
if entity == 'User':
|
||||
users = iam_backend.list_users(path_prefix, marker, max_items)
|
||||
if users:
|
||||
for user in users:
|
||||
for p in user.managed_policies:
|
||||
if p == policy_arn:
|
||||
entity_users.append(user.name)
|
||||
|
||||
elif entity == 'Role':
|
||||
roles = iam_backend.list_roles(path_prefix, marker, max_items)
|
||||
if roles:
|
||||
for role in roles:
|
||||
for p in role.managed_policies:
|
||||
if p == policy_arn:
|
||||
entity_roles.append(role.name)
|
||||
|
||||
elif entity == 'Group':
|
||||
groups = iam_backend.list_groups()
|
||||
if groups:
|
||||
for group in groups:
|
||||
for p in group.managed_policies:
|
||||
if p == policy_arn:
|
||||
entity_groups.append(group.name)
|
||||
|
||||
elif entity == 'LocalManagedPolicy' or entity == 'AWSManagedPolicy':
|
||||
users = iam_backend.list_users(path_prefix, marker, max_items)
|
||||
if users:
|
||||
for user in users:
|
||||
for p in user.managed_policies:
|
||||
if p == policy_arn:
|
||||
entity_users.append(user.name)
|
||||
|
||||
roles = iam_backend.list_roles(path_prefix, marker, max_items)
|
||||
if roles:
|
||||
for role in roles:
|
||||
for p in role.managed_policies:
|
||||
if p == policy_arn:
|
||||
entity_roles.append(role.name)
|
||||
|
||||
groups = iam_backend.list_groups()
|
||||
if groups:
|
||||
for group in groups:
|
||||
for p in group.managed_policies:
|
||||
if p == policy_arn:
|
||||
entity_groups.append(group.name)
|
||||
|
||||
template = self.response_template(LIST_ENTITIES_FOR_POLICY_TEMPLATE)
|
||||
return template.render(roles=entity_roles, users=entity_users, groups=entity_groups)
|
||||
|
||||
def create_role(self):
|
||||
role_name = self._get_param('RoleName')
|
||||
path = self._get_param('Path')
|
||||
@ -169,6 +232,20 @@ class IamResponse(BaseResponse):
|
||||
template = self.response_template(GENERIC_EMPTY_TEMPLATE)
|
||||
return template.render(name="UpdateAssumeRolePolicyResponse")
|
||||
|
||||
def update_role_description(self):
|
||||
role_name = self._get_param('RoleName')
|
||||
description = self._get_param('Description')
|
||||
role = iam_backend.update_role_description(role_name, description)
|
||||
template = self.response_template(UPDATE_ROLE_DESCRIPTION_TEMPLATE)
|
||||
return template.render(role=role)
|
||||
|
||||
def update_role(self):
|
||||
role_name = self._get_param('RoleName')
|
||||
description = self._get_param('Description')
|
||||
role = iam_backend.update_role(role_name, description)
|
||||
template = self.response_template(UPDATE_ROLE_TEMPLATE)
|
||||
return template.render(role=role)
|
||||
|
||||
def create_policy_version(self):
|
||||
policy_arn = self._get_param('PolicyArn')
|
||||
policy_document = self._get_param('PolicyDocument')
|
||||
@ -655,6 +732,37 @@ class IamResponse(BaseResponse):
|
||||
return template.render()
|
||||
|
||||
|
||||
LIST_ENTITIES_FOR_POLICY_TEMPLATE = """<ListEntitiesForPolicyResponse>
|
||||
<ListEntitiesForPolicyResult>
|
||||
<PolicyRoles>
|
||||
{% for role in roles %}
|
||||
<member>
|
||||
<RoleName>{{ role }}</RoleName>
|
||||
</member>
|
||||
{% endfor %}
|
||||
</PolicyRoles>
|
||||
<PolicyGroups>
|
||||
{% for group in groups %}
|
||||
<member>
|
||||
<GroupName>{{ group }}</GroupName>
|
||||
</member>
|
||||
{% endfor %}
|
||||
</PolicyGroups>
|
||||
<IsTruncated>false</IsTruncated>
|
||||
<PolicyUsers>
|
||||
{% for user in users %}
|
||||
<member>
|
||||
<UserName>{{ user }}</UserName>
|
||||
</member>
|
||||
{% endfor %}
|
||||
</PolicyUsers>
|
||||
</ListEntitiesForPolicyResult>
|
||||
<ResponseMetadata>
|
||||
<RequestId>eb358e22-9d1f-11e4-93eb-190ecEXAMPLE</RequestId>
|
||||
</ResponseMetadata>
|
||||
</ListEntitiesForPolicyResponse>"""
|
||||
|
||||
|
||||
ATTACH_ROLE_POLICY_TEMPLATE = """<AttachRolePolicyResponse>
|
||||
<ResponseMetadata>
|
||||
<RequestId>7a62c49f-347e-4fc4-9331-6e8eEXAMPLE</RequestId>
|
||||
@ -898,6 +1006,40 @@ GET_ROLE_POLICY_TEMPLATE = """<GetRolePolicyResponse xmlns="https://iam.amazonaw
|
||||
</ResponseMetadata>
|
||||
</GetRolePolicyResponse>"""
|
||||
|
||||
UPDATE_ROLE_TEMPLATE = """<UpdateRoleResponse xmlns="https://iam.amazonaws.com/doc/2010-05-08/">
|
||||
<UpdateRoleResult>
|
||||
</UpdateRoleResult>
|
||||
<ResponseMetadata>
|
||||
<RequestId>df37e965-9967-11e1-a4c3-270EXAMPLE04</RequestId>
|
||||
</ResponseMetadata>
|
||||
</UpdateRoleResponse>"""
|
||||
|
||||
UPDATE_ROLE_DESCRIPTION_TEMPLATE = """<UpdateRoleDescriptionResponse xmlns="https://iam.amazonaws.com/doc/2010-05-08/">
|
||||
<UpdateRoleDescriptionResult>
|
||||
<Role>
|
||||
<Path>{{ role.path }}</Path>
|
||||
<Arn>{{ role.arn }}</Arn>
|
||||
<RoleName>{{ role.name }}</RoleName>
|
||||
<AssumeRolePolicyDocument>{{ role.assume_role_policy_document }}</AssumeRolePolicyDocument>
|
||||
<CreateDate>{{ role.create_date.isoformat() }}</CreateDate>
|
||||
<RoleId>{{ role.id }}</RoleId>
|
||||
{% if role.tags %}
|
||||
<Tags>
|
||||
{% for tag in role.get_tags() %}
|
||||
<member>
|
||||
<Key>{{ tag['Key'] }}</Key>
|
||||
<Value>{{ tag['Value'] }}</Value>
|
||||
</member>
|
||||
{% endfor %}
|
||||
</Tags>
|
||||
{% endif %}
|
||||
</Role>
|
||||
</UpdateRoleDescriptionResult>
|
||||
<ResponseMetadata>
|
||||
<RequestId>df37e965-9967-11e1-a4c3-270EXAMPLE04</RequestId>
|
||||
</ResponseMetadata>
|
||||
</UpdateRoleDescriptionResponse>"""
|
||||
|
||||
GET_ROLE_TEMPLATE = """<GetRoleResponse xmlns="https://iam.amazonaws.com/doc/2010-05-08/">
|
||||
<GetRoleResult>
|
||||
<Role>
|
||||
|
@ -21,6 +21,7 @@ class Key(BaseModel):
|
||||
self.account_id = "0123456789012"
|
||||
self.key_rotation_status = False
|
||||
self.deletion_date = None
|
||||
self.tags = {}
|
||||
|
||||
@property
|
||||
def physical_resource_id(self):
|
||||
@ -35,7 +36,7 @@ class Key(BaseModel):
|
||||
"KeyMetadata": {
|
||||
"AWSAccountId": self.account_id,
|
||||
"Arn": self.arn,
|
||||
"CreationDate": "2015-01-01 00:00:00",
|
||||
"CreationDate": datetime.strftime(datetime.utcnow(), "%Y-%m-%dT%H:%M:%SZ"),
|
||||
"Description": self.description,
|
||||
"Enabled": self.enabled,
|
||||
"KeyId": self.id,
|
||||
@ -63,7 +64,6 @@ class Key(BaseModel):
|
||||
)
|
||||
key.key_rotation_status = properties['EnableKeyRotation']
|
||||
key.enabled = properties['Enabled']
|
||||
|
||||
return key
|
||||
|
||||
def get_cfn_attribute(self, attribute_name):
|
||||
@ -84,6 +84,18 @@ class KmsBackend(BaseBackend):
|
||||
self.keys[key.id] = key
|
||||
return key
|
||||
|
||||
def update_key_description(self, key_id, description):
|
||||
key = self.keys[self.get_key_id(key_id)]
|
||||
key.description = description
|
||||
|
||||
def tag_resource(self, key_id, tags):
|
||||
key = self.keys[self.get_key_id(key_id)]
|
||||
key.tags = tags
|
||||
|
||||
def list_resource_tags(self, key_id):
|
||||
key = self.keys[self.get_key_id(key_id)]
|
||||
return key.tags
|
||||
|
||||
def delete_key(self, key_id):
|
||||
if key_id in self.keys:
|
||||
if key_id in self.key_to_aliases:
|
||||
|
@ -38,6 +38,28 @@ class KmsResponse(BaseResponse):
|
||||
policy, key_usage, description, self.region)
|
||||
return json.dumps(key.to_dict())
|
||||
|
||||
def update_key_description(self):
|
||||
key_id = self.parameters.get('KeyId')
|
||||
description = self.parameters.get('Description')
|
||||
|
||||
self.kms_backend.update_key_description(key_id, description)
|
||||
return json.dumps(None)
|
||||
|
||||
def tag_resource(self):
|
||||
key_id = self.parameters.get('KeyId')
|
||||
tags = self.parameters.get('Tags')
|
||||
self.kms_backend.tag_resource(key_id, tags)
|
||||
return json.dumps({})
|
||||
|
||||
def list_resource_tags(self):
|
||||
key_id = self.parameters.get('KeyId')
|
||||
tags = self.kms_backend.list_resource_tags(key_id)
|
||||
return json.dumps({
|
||||
"Tags": tags,
|
||||
"NextMarker": None,
|
||||
"Truncated": False,
|
||||
})
|
||||
|
||||
def describe_key(self):
|
||||
key_id = self.parameters.get('KeyId')
|
||||
try:
|
||||
|
@ -1113,4 +1113,4 @@ def httprettified(test):
|
||||
|
||||
if isinstance(test, ClassTypes):
|
||||
return decorate_class(test)
|
||||
return decorate_callable(test)
|
||||
return decorate_callable(test)
|
@ -29,7 +29,6 @@ import re
|
||||
from .compat import BaseClass
|
||||
from .utils import decode_utf8
|
||||
|
||||
|
||||
STATUSES = {
|
||||
100: "Continue",
|
||||
101: "Switching Protocols",
|
||||
|
@ -12,6 +12,8 @@ import sure # noqa
|
||||
|
||||
from freezegun import freeze_time
|
||||
from moto import mock_lambda, mock_s3, mock_ec2, mock_sns, mock_logs, settings
|
||||
from nose.tools import assert_raises
|
||||
from botocore.exceptions import ClientError
|
||||
|
||||
_lambda_region = 'us-west-2'
|
||||
|
||||
@ -397,6 +399,11 @@ def test_get_function():
|
||||
result = conn.get_function(FunctionName='testFunction', Qualifier='$LATEST')
|
||||
result['Configuration']['Version'].should.equal('$LATEST')
|
||||
|
||||
# Test get function when can't find function name
|
||||
with assert_raises(ClientError):
|
||||
conn.get_function(FunctionName='junk', Qualifier='$LATEST')
|
||||
|
||||
|
||||
|
||||
@mock_lambda
|
||||
@mock_s3
|
||||
@ -819,3 +826,87 @@ def get_function_policy():
|
||||
assert isinstance(response['Policy'], str)
|
||||
res = json.loads(response['Policy'])
|
||||
assert res['Statement'][0]['Action'] == 'lambda:InvokeFunction'
|
||||
|
||||
|
||||
@mock_lambda
|
||||
@mock_s3
|
||||
def test_list_versions_by_function():
|
||||
s3_conn = boto3.client('s3', 'us-west-2')
|
||||
s3_conn.create_bucket(Bucket='test-bucket')
|
||||
|
||||
zip_content = get_test_zip_file2()
|
||||
s3_conn.put_object(Bucket='test-bucket', Key='test.zip', Body=zip_content)
|
||||
conn = boto3.client('lambda', 'us-west-2')
|
||||
|
||||
conn.create_function(
|
||||
FunctionName='testFunction',
|
||||
Runtime='python2.7',
|
||||
Role='test-iam-role',
|
||||
Handler='lambda_function.lambda_handler',
|
||||
Code={
|
||||
'S3Bucket': 'test-bucket',
|
||||
'S3Key': 'test.zip',
|
||||
},
|
||||
Description='test lambda function',
|
||||
Timeout=3,
|
||||
MemorySize=128,
|
||||
Publish=True,
|
||||
)
|
||||
|
||||
conn.publish_version(FunctionName='testFunction')
|
||||
|
||||
versions = conn.list_versions_by_function(FunctionName='testFunction')
|
||||
|
||||
assert versions['Versions'][0]['FunctionArn'] == 'arn:aws:lambda:us-west-2:123456789012:function:testFunction:$LATEST'
|
||||
|
||||
|
||||
@mock_lambda
|
||||
@mock_s3
|
||||
def test_create_function_with_already_exists():
|
||||
s3_conn = boto3.client('s3', 'us-west-2')
|
||||
s3_conn.create_bucket(Bucket='test-bucket')
|
||||
|
||||
zip_content = get_test_zip_file2()
|
||||
s3_conn.put_object(Bucket='test-bucket', Key='test.zip', Body=zip_content)
|
||||
conn = boto3.client('lambda', 'us-west-2')
|
||||
|
||||
conn.create_function(
|
||||
FunctionName='testFunction',
|
||||
Runtime='python2.7',
|
||||
Role='test-iam-role',
|
||||
Handler='lambda_function.lambda_handler',
|
||||
Code={
|
||||
'S3Bucket': 'test-bucket',
|
||||
'S3Key': 'test.zip',
|
||||
},
|
||||
Description='test lambda function',
|
||||
Timeout=3,
|
||||
MemorySize=128,
|
||||
Publish=True,
|
||||
)
|
||||
|
||||
response = conn.create_function(
|
||||
FunctionName='testFunction',
|
||||
Runtime='python2.7',
|
||||
Role='test-iam-role',
|
||||
Handler='lambda_function.lambda_handler',
|
||||
Code={
|
||||
'S3Bucket': 'test-bucket',
|
||||
'S3Key': 'test.zip',
|
||||
},
|
||||
Description='test lambda function',
|
||||
Timeout=3,
|
||||
MemorySize=128,
|
||||
Publish=True,
|
||||
)
|
||||
|
||||
assert response['FunctionName'] == 'testFunction'
|
||||
|
||||
|
||||
@mock_lambda
|
||||
@mock_s3
|
||||
def test_list_versions_by_function_for_nonexistent_function():
|
||||
conn = boto3.client('lambda', 'us-west-2')
|
||||
versions = conn.list_versions_by_function(FunctionName='testFunction')
|
||||
|
||||
assert len(versions['Versions']) == 0
|
||||
|
@ -323,6 +323,54 @@ def test_create_job_queue():
|
||||
resp.should.contain('jobQueues')
|
||||
len(resp['jobQueues']).should.equal(0)
|
||||
|
||||
# Create job queue which already exists
|
||||
try:
|
||||
resp = batch_client.create_job_queue(
|
||||
jobQueueName='test_job_queue',
|
||||
state='ENABLED',
|
||||
priority=123,
|
||||
computeEnvironmentOrder=[
|
||||
{
|
||||
'order': 123,
|
||||
'computeEnvironment': arn
|
||||
},
|
||||
]
|
||||
)
|
||||
|
||||
except ClientError as err:
|
||||
err.response['Error']['Code'].should.equal('ClientException')
|
||||
|
||||
|
||||
# Create job queue with incorrect state
|
||||
try:
|
||||
resp = batch_client.create_job_queue(
|
||||
jobQueueName='test_job_queue2',
|
||||
state='JUNK',
|
||||
priority=123,
|
||||
computeEnvironmentOrder=[
|
||||
{
|
||||
'order': 123,
|
||||
'computeEnvironment': arn
|
||||
},
|
||||
]
|
||||
)
|
||||
|
||||
except ClientError as err:
|
||||
err.response['Error']['Code'].should.equal('ClientException')
|
||||
|
||||
# Create job queue with no compute env
|
||||
try:
|
||||
resp = batch_client.create_job_queue(
|
||||
jobQueueName='test_job_queue3',
|
||||
state='JUNK',
|
||||
priority=123,
|
||||
computeEnvironmentOrder=[
|
||||
|
||||
]
|
||||
)
|
||||
|
||||
except ClientError as err:
|
||||
err.response['Error']['Code'].should.equal('ClientException')
|
||||
|
||||
@mock_ec2
|
||||
@mock_ecs
|
||||
@ -397,6 +445,17 @@ def test_update_job_queue():
|
||||
len(resp['jobQueues']).should.equal(1)
|
||||
resp['jobQueues'][0]['priority'].should.equal(5)
|
||||
|
||||
batch_client.update_job_queue(
|
||||
jobQueue='test_job_queue',
|
||||
priority=5
|
||||
)
|
||||
|
||||
resp = batch_client.describe_job_queues()
|
||||
resp.should.contain('jobQueues')
|
||||
len(resp['jobQueues']).should.equal(1)
|
||||
resp['jobQueues'][0]['priority'].should.equal(5)
|
||||
|
||||
|
||||
|
||||
@mock_ec2
|
||||
@mock_ecs
|
||||
|
@ -1,5 +1,4 @@
|
||||
import random
|
||||
|
||||
import boto3
|
||||
import json
|
||||
|
||||
@ -7,7 +6,6 @@ from moto.events import mock_events
|
||||
from botocore.exceptions import ClientError
|
||||
from nose.tools import assert_raises
|
||||
|
||||
|
||||
RULES = [
|
||||
{'Name': 'test1', 'ScheduleExpression': 'rate(5 minutes)'},
|
||||
{'Name': 'test2', 'ScheduleExpression': 'rate(1 minute)'},
|
||||
@ -109,6 +107,13 @@ def test_enable_disable_rule():
|
||||
rule = client.describe_rule(Name=rule_name)
|
||||
assert(rule['State'] == 'ENABLED')
|
||||
|
||||
# Test invalid name
|
||||
try:
|
||||
client.enable_rule(Name='junk')
|
||||
|
||||
except ClientError as ce:
|
||||
assert ce.response['Error']['Code'] == 'ResourceNotFoundException'
|
||||
|
||||
|
||||
@mock_events
|
||||
def test_list_rule_names_by_target():
|
||||
|
@ -1151,3 +1151,118 @@ def test_untag_role():
|
||||
# With a role that doesn't exist:
|
||||
with assert_raises(ClientError):
|
||||
conn.untag_role(RoleName='notarole', TagKeys=['somevalue'])
|
||||
|
||||
|
||||
@mock_iam()
|
||||
def test_update_role_description():
|
||||
conn = boto3.client('iam', region_name='us-east-1')
|
||||
|
||||
with assert_raises(ClientError):
|
||||
conn.delete_role(RoleName="my-role")
|
||||
|
||||
conn.create_role(RoleName="my-role", AssumeRolePolicyDocument="some policy", Path="/my-path/")
|
||||
response = conn.update_role_description(RoleName="my-role", Description="test")
|
||||
|
||||
assert response['Role']['RoleName'] == 'my-role'
|
||||
|
||||
@mock_iam()
|
||||
def test_update_role():
|
||||
conn = boto3.client('iam', region_name='us-east-1')
|
||||
|
||||
with assert_raises(ClientError):
|
||||
conn.delete_role(RoleName="my-role")
|
||||
|
||||
conn.create_role(RoleName="my-role", AssumeRolePolicyDocument="some policy", Path="/my-path/")
|
||||
response = conn.update_role_description(RoleName="my-role", Description="test")
|
||||
assert response['Role']['RoleName'] == 'my-role'
|
||||
|
||||
@mock_iam()
|
||||
def test_update_role():
|
||||
conn = boto3.client('iam', region_name='us-east-1')
|
||||
|
||||
with assert_raises(ClientError):
|
||||
conn.delete_role(RoleName="my-role")
|
||||
|
||||
conn.create_role(RoleName="my-role", AssumeRolePolicyDocument="some policy", Path="/my-path/")
|
||||
response = conn.update_role(RoleName="my-role", Description="test")
|
||||
assert len(response.keys()) == 1
|
||||
|
||||
|
||||
@mock_iam()
|
||||
def test_list_entities_for_policy():
|
||||
import json
|
||||
test_policy = json.dumps({
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Action": "s3:ListBucket",
|
||||
"Resource": "*",
|
||||
"Effect": "Allow",
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
conn = boto3.client('iam', region_name='us-east-1')
|
||||
conn.create_role(RoleName="my-role", AssumeRolePolicyDocument="some policy", Path="/my-path/")
|
||||
conn.create_user(Path='/', UserName='testUser')
|
||||
conn.create_group(Path='/', GroupName='testGroup')
|
||||
conn.create_policy(
|
||||
PolicyName='testPolicy',
|
||||
Path='/',
|
||||
PolicyDocument=test_policy,
|
||||
Description='Test Policy'
|
||||
)
|
||||
|
||||
# Attach things to the user and group:
|
||||
conn.put_user_policy(UserName='testUser', PolicyName='testPolicy', PolicyDocument=test_policy)
|
||||
conn.put_group_policy(GroupName='testGroup', PolicyName='testPolicy', PolicyDocument=test_policy)
|
||||
|
||||
conn.attach_user_policy(UserName='testUser', PolicyArn='arn:aws:iam::123456789012:policy/testPolicy')
|
||||
conn.attach_group_policy(GroupName='testGroup', PolicyArn='arn:aws:iam::123456789012:policy/testPolicy')
|
||||
|
||||
conn.add_user_to_group(UserName='testUser', GroupName='testGroup')
|
||||
|
||||
# Add things to the role:
|
||||
conn.create_instance_profile(InstanceProfileName='ipn')
|
||||
conn.add_role_to_instance_profile(InstanceProfileName='ipn', RoleName='my-role')
|
||||
conn.tag_role(RoleName='my-role', Tags=[
|
||||
{
|
||||
'Key': 'somekey',
|
||||
'Value': 'somevalue'
|
||||
},
|
||||
{
|
||||
'Key': 'someotherkey',
|
||||
'Value': 'someothervalue'
|
||||
}
|
||||
])
|
||||
conn.put_role_policy(RoleName='my-role', PolicyName='test-policy', PolicyDocument=test_policy)
|
||||
conn.attach_role_policy(RoleName='my-role', PolicyArn='arn:aws:iam::123456789012:policy/testPolicy')
|
||||
|
||||
response = conn.list_entities_for_policy(
|
||||
PolicyArn='arn:aws:iam::123456789012:policy/testPolicy',
|
||||
EntityFilter='Role'
|
||||
)
|
||||
assert response['PolicyRoles'] == [{'RoleName': 'my-role'}]
|
||||
|
||||
response = conn.list_entities_for_policy(
|
||||
PolicyArn='arn:aws:iam::123456789012:policy/testPolicy',
|
||||
EntityFilter='User',
|
||||
)
|
||||
assert response['PolicyUsers'] == [{'UserName': 'testUser'}]
|
||||
|
||||
response = conn.list_entities_for_policy(
|
||||
PolicyArn='arn:aws:iam::123456789012:policy/testPolicy',
|
||||
EntityFilter='Group',
|
||||
)
|
||||
assert response['PolicyGroups'] == [{'GroupName': 'testGroup'}]
|
||||
|
||||
response = conn.list_entities_for_policy(
|
||||
PolicyArn='arn:aws:iam::123456789012:policy/testPolicy',
|
||||
EntityFilter='LocalManagedPolicy',
|
||||
)
|
||||
assert response['PolicyGroups'] == [{'GroupName': 'testGroup'}]
|
||||
assert response['PolicyUsers'] == [{'UserName': 'testUser'}]
|
||||
assert response['PolicyRoles'] == [{'RoleName': 'my-role'}]
|
||||
|
||||
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
from __future__ import unicode_literals
|
||||
import os, re
|
||||
|
||||
import boto3
|
||||
import boto.kms
|
||||
from boto.exception import JSONResponseError
|
||||
@ -717,3 +716,60 @@ def test_cancel_key_deletion():
|
||||
assert result["KeyMetadata"]["Enabled"] == False
|
||||
assert result["KeyMetadata"]["KeyState"] == 'Disabled'
|
||||
assert 'DeletionDate' not in result["KeyMetadata"]
|
||||
|
||||
|
||||
@mock_kms
|
||||
def test_update_key_description():
|
||||
client = boto3.client('kms', region_name='us-east-1')
|
||||
key = client.create_key(Description='old_description')
|
||||
key_id = key['KeyMetadata']['KeyId']
|
||||
|
||||
result = client.update_key_description(KeyId=key_id, Description='new_description')
|
||||
assert 'ResponseMetadata' in result
|
||||
|
||||
|
||||
@mock_kms
|
||||
def test_tag_resource():
|
||||
client = boto3.client('kms', region_name='us-east-1')
|
||||
key = client.create_key(Description='cancel-key-deletion')
|
||||
response = client.schedule_key_deletion(
|
||||
KeyId=key['KeyMetadata']['KeyId']
|
||||
)
|
||||
|
||||
keyid = response['KeyId']
|
||||
response = client.tag_resource(
|
||||
KeyId=keyid,
|
||||
Tags=[
|
||||
{
|
||||
'TagKey': 'string',
|
||||
'TagValue': 'string'
|
||||
},
|
||||
]
|
||||
)
|
||||
|
||||
# Shouldn't have any data, just header
|
||||
assert len(response.keys()) == 1
|
||||
|
||||
|
||||
@mock_kms
|
||||
def test_list_resource_tags():
|
||||
client = boto3.client('kms', region_name='us-east-1')
|
||||
key = client.create_key(Description='cancel-key-deletion')
|
||||
response = client.schedule_key_deletion(
|
||||
KeyId=key['KeyMetadata']['KeyId']
|
||||
)
|
||||
|
||||
keyid = response['KeyId']
|
||||
response = client.tag_resource(
|
||||
KeyId=keyid,
|
||||
Tags=[
|
||||
{
|
||||
'TagKey': 'string',
|
||||
'TagValue': 'string'
|
||||
},
|
||||
]
|
||||
)
|
||||
|
||||
response = client.list_resource_tags(KeyId=keyid)
|
||||
assert response['Tags'][0]['TagKey'] == 'string'
|
||||
assert response['Tags'][0]['TagValue'] == 'string'
|
||||
|
8
tests/test_packages/__init__.py
Normal file
8
tests/test_packages/__init__.py
Normal file
@ -0,0 +1,8 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import logging
|
||||
# Disable extra logging for tests
|
||||
logging.getLogger('boto').setLevel(logging.CRITICAL)
|
||||
logging.getLogger('boto3').setLevel(logging.CRITICAL)
|
||||
logging.getLogger('botocore').setLevel(logging.CRITICAL)
|
||||
logging.getLogger('nose').setLevel(logging.CRITICAL)
|
37
tests/test_packages/test_httpretty.py
Normal file
37
tests/test_packages/test_httpretty.py
Normal file
@ -0,0 +1,37 @@
|
||||
# #!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
import mock
|
||||
|
||||
from moto.packages.httpretty.core import HTTPrettyRequest, fake_gethostname, fake_gethostbyname
|
||||
|
||||
|
||||
def test_parse_querystring():
|
||||
|
||||
core = HTTPrettyRequest(headers='test test HTTP/1.1')
|
||||
|
||||
qs = 'test test'
|
||||
response = core.parse_querystring(qs)
|
||||
|
||||
assert response == {}
|
||||
|
||||
def test_parse_request_body():
|
||||
core = HTTPrettyRequest(headers='test test HTTP/1.1')
|
||||
|
||||
qs = 'test'
|
||||
response = core.parse_request_body(qs)
|
||||
|
||||
assert response == 'test'
|
||||
|
||||
def test_fake_gethostname():
|
||||
|
||||
response = fake_gethostname()
|
||||
|
||||
assert response == 'localhost'
|
||||
|
||||
def test_fake_gethostbyname():
|
||||
|
||||
host = 'test'
|
||||
response = fake_gethostbyname(host=host)
|
||||
|
||||
assert response == '127.0.0.1'
|
Loading…
Reference in New Issue
Block a user