Merge branch 'master' of https://github.com/spulec/moto into 0.4.1-threadsafe

* 'master' of https://github.com/spulec/moto: (25 commits)
  Add @zkourouma to authors.
  0.4.2
  Fix bug where listener certificate was not being saved correctly when creating an elb. Added test to cover that case.
  [dynamodb2] adds lookup method to Table class
  Add IAM list_groups and list_groups_for_user. Closes #343.
  Fix for deleting Route53 record sets with set identifiers. Closes #342.
  Use dummy date instead of an invalid date
  Adding support for comments on hosted zones.
  Add availability zone support to Subnets created via CloudFormation
  Make availability zone dynamic in Subnet Response templates
  Add filter "availabilityZone" to DescribeSubnets and add availability zone support too
  allow starting without reseting
  Fix bug with empty string for instance vpc_id. Closes #337.
  Fix default security group description.
  Update responses.py
  Add @mrucci to authors.
  Fix merge conflicts.
  Add support for ELB attributes.
  cast to int when doing math.
  General cleanup.
  ...
This commit is contained in:
Jeffrey Gelens 2015-05-29 11:35:14 +02:00
commit e722b67f36
33 changed files with 1381 additions and 167 deletions

View file

@ -6,6 +6,7 @@ from .utils import random_access_key, random_alphanumeric, random_resource_id
from datetime import datetime
import base64
class Role(object):
def __init__(self, role_id, name, assume_role_policy_document, path):
@ -212,16 +213,16 @@ class User(object):
access_key_2_last_rotated = date_created.strftime(date_format)
return '{0},{1},{2},{3},{4},{5},not_supported,false,{6},{7},{8},{9},false,N/A,false,N/A'.format(self.name,
self.arn,
date_created.strftime(date_format),
password_enabled,
password_last_used,
date_created.strftime(date_format),
access_key_1_active,
access_key_1_last_rotated,
access_key_2_active,
access_key_2_last_rotated
)
self.arn,
date_created.strftime(date_format),
password_enabled,
password_last_used,
date_created.strftime(date_format),
access_key_1_active,
access_key_1_last_rotated,
access_key_2_active,
access_key_2_last_rotated
)
class IAMBackend(BaseBackend):
@ -337,6 +338,18 @@ class IAMBackend(BaseBackend):
return group
def list_groups(self):
return self.groups.values()
def get_groups_for_user(self, user_name):
user = self.get_user(user_name)
groups = []
for group in self.list_groups():
if user in group.users:
groups.append(group)
return groups
def create_user(self, user_name, path='/'):
if user_name in self.users:
raise BotoServerError(409, 'Conflict')

View file

@ -131,6 +131,18 @@ class IamResponse(BaseResponse):
template = self.response_template(GET_GROUP_TEMPLATE)
return template.render(group=group)
def list_groups(self):
groups = iam_backend.list_groups()
template = self.response_template(LIST_GROUPS_TEMPLATE)
return template.render(groups=groups)
def list_groups_for_user(self):
user_name = self._get_param('UserName')
groups = iam_backend.get_groups_for_user(user_name)
template = self.response_template(LIST_GROUPS_FOR_USER_TEMPLATE)
return template.render(groups=groups)
def create_user(self):
user_name = self._get_param('UserName')
path = self._get_param('Path')
@ -502,6 +514,45 @@ GET_GROUP_TEMPLATE = """<GetGroupResponse>
</ResponseMetadata>
</GetGroupResponse>"""
LIST_GROUPS_TEMPLATE = """<ListGroupsResponse>
<ListGroupsResult>
<Groups>
{% for group in groups %}
<member>
<Path>{{ group.path }}</Path>
<GroupName>{{ group.name }}</GroupName>
<GroupId>{{ group.id }}</GroupId>
<Arn>arn:aws:iam::123456789012:group/{{ group.path }}</Arn>
</member>
{% endfor %}
</Groups>
<IsTruncated>false</IsTruncated>
</ListGroupsResult>
<ResponseMetadata>
<RequestId>7a62c49f-347e-4fc4-9331-6e8eEXAMPLE</RequestId>
</ResponseMetadata>
</ListGroupsResponse>"""
LIST_GROUPS_FOR_USER_TEMPLATE = """<ListGroupsForUserResponse>
<ListGroupsForUserResult>
<Groups>
{% for group in groups %}
<member>
<Path>{{ group.path }}</Path>
<GroupName>{{ group.name }}</GroupName>
<GroupId>{{ group.id }}</GroupId>
<Arn>arn:aws:iam::123456789012:group/{{ group.path }}</Arn>
</member>
{% endfor %}
</Groups>
<IsTruncated>false</IsTruncated>
</ListGroupsForUserResult>
<ResponseMetadata>
<RequestId>7a62c49f-347e-4fc4-9331-6e8eEXAMPLE</RequestId>
</ResponseMetadata>
</ListGroupsForUserResponse>"""
USER_TEMPLATE = """<{{ action }}UserResponse>
<{{ action }}UserResult>
<User>
@ -640,4 +691,4 @@ LIST_INSTANCE_PROFILES_FOR_ROLE_TEMPLATE = """<ListInstanceProfilesForRoleRespon
<ResponseMetadata>
<RequestId>6a8c3992-99f4-11e1-a4c3-27EXAMPLE804</RequestId>
</ResponseMetadata>
</ListInstanceProfilesForRoleResponse>"""
</ListInstanceProfilesForRoleResponse>"""