class Roles(object): def __init__(self): self.session = Session() self.iam_client = self.session.client('iam') self.iam_resource = self.session.resource('iam') @client_error_ignore('NoSuchEntity') def find(self, name): aro = self.iam_resource.Role(name) aro.create_date return aro.arn def create(self, path, name, base_trust_policy): try: response = self.iam_client.create_role( Path='/{}/'.format(path), RoleName=name, AssumeRolePolicyDocument=base_trust_policy, Description='Assumed by resources provisioned by products \ associated with Service Catalog Portfolio {}'.format(name)) logger.debug('Role created: {}'.format(name)) return response['Role']['Arn'] except ClientError as err: if err.response['Error']['Code'] == 'EntityAlreadyExists': return self.find(name) else: raise err
class Policy(object): def __init__(self, arn): self.session = Session() self.iam_client = self.session.client('iam') self.iam_resource = self.session.resource('iam') self.arn = arn self.name = arn_to_name(self.arn) self.aro = self.iam_resource.Policy(self.arn) def delete_non_default_versions(self): for policy_version in self.aro.versions.all(): if not policy_version.is_default_version: policy_version.delete() def detach_roles(self): for rol in self.aro.attached_roles.all(): rol.detach_policy(PolicyArn=self.arn) @client_error_retry('LimitExceeded', delete_non_default_versions) def update_document(self, document): self.iam_client.create_policy_version( PolicyArn=self.arn, PolicyDocument=json.dumps(document), SetAsDefault=True) logger.info('Policy document updated: {}'.format(document)) @client_error_retry('DeleteConflict', detach_roles) @client_error_retry('DeleteConflict', delete_non_default_versions) def delete(self): self.aro.delete()
class Table(): def __init__(self, name): self.session = Session() self.dynamodb_client = self.session.client('dynamodb') self.dynamodb_resource = self.session.resource('dynamodb') self.name = name self.aro = self.dynamodb_resource.Table(self.name) def add(self, items): with self.aro.batch_writer() as batch: for item in items: batch.put_item(Item=item) def remove(self, items): with self.aro.batch_writer() as batch: for item in items: print('item: {}'.format(item)) batch.delete_item(Key=item)
class Role(object): def __init__(self, arn): self.session = Session() self.iam_client = self.session.client('iam') self.iam_resource = self.session.resource('iam') self.arn = arn self.name = arn_to_name(self.arn) self.aro = self.iam_resource.Role(self.name) def attach_policy(self, policy_arn): self.aro.attach_policy(PolicyArn=policy_arn) def update_trust_document(self, service_name): policy = self.aro.AssumeRolePolicy() policy_doc = self.aro.assume_role_policy_document principal_service = jmespath.search("Statement[].Principal.Service", policy_doc) principal_service = jmespath.search("[][][]", principal_service) if service_name not in principal_service: principal_service.append(service_name) policy_doc['Statement'] = [{ 'Action': 'sts:AssumeRole', 'Effect': 'Allow', 'Principal': { 'Service': principal_service } }] policy.update(PolicyDocument=json.dumps(policy_doc)) logger.debug("Trust policy updated: {}".format(policy_doc)) def _stop_being_assumed(self): pass def _detach_policy(self): pass # TODO implement the resolver methods @client_error_retry('DeleteConflict', _stop_being_assumed) @client_error_retry('DeleteConflict', _detach_policy) def delete(self): self.aro.delete()
class Policies(object): def __init__(self): self.session = Session() self.iam_client = self.session.client('iam') self.iam_resource = self.session.resource('iam') def find(self, path, name): paginator = self.iam_client.get_paginator('list_policies') response_iterator = paginator.paginate( Scope='Local', OnlyAttached=False, PathPrefix='/{}/'.format(path), PaginationConfig={ 'MaxItems': 123, 'PageSize': 123 } ) result = [] for response in response_iterator: result += jmespath.search( "Policies[?PolicyName=='{}'].Arn".format(name), response ) return jmespath.search("[0]", result) def create(self, path, name, base_policy): try: response = self.iam_client.create_policy( Path='/{}/'.format(path), PolicyName=name, PolicyDocument=base_policy, Description='Set the access to resources provisioned by products \ associated with Service Catalog Portfolio {}'.format(name) ) logger.info('Policy created: {}'.format(name)) return response['Policy']['Arn'] except ClientError as e: if e.response['Error']['Code'] == 'EntityAlreadyExists': return self.find(path, name)
class Base(object): def __init__(self, physical_id, **kwargs): self.physical_id = physical_id self._session = Session() self._client = self._session.client(self._service_name()) self._resource = self._resource() self._iam_client = self._session.client('iam') self._iam_resource = self._session.resource('iam') self.arn = self._arn() self.service_name = self._service_name() self.access_to = self._access_to() self.access_from = self._access_from() self.assumed_role = self._assumed_role() self.trust_relationship_service = self._trust_relationship_service() self.statement_id = self._statement_id() self.actions = kwargs.get('actions', self._actions()) def __str__(self): return "Resource id: {} Arn: {}".format(self.physical_id, self.arn) @catch_error(ResourceNotExistsError) def _resource(self): return self._session.resource(self._service_name()) def _arn(self): return None def _service_name(self): return None def _access_to(self): return False def _access_from(self): return False def _assumed_role(self): return None def _trust_relationship_service(self): return None def _statement_id(self): return None def _actions(self): return None def attach_policy(self, policy): if not self.assumed_role: return role_name = convertor.arn_to_name(self.assumed_role) self._iam_client.attach_role_policy(RoleName=role_name, PolicyArn=policy) def assume_role(self, role): pass def detach_policy(self, policy): if not self.assumed_role: return role_name = convertor.arn_to_name(self.assumed_role) self._iam_client.detach_role_policy(RoleName=role_name, PolicyArn=policy) def stop_assume_role(self, role): pass