class EventsBus: '''Class to manage EventBridge Events''' def __init__(self, region_name=None, role_arn=None): self.accounts = [] self.event_bus = 'event-bus/default' self.events = Session(region_name, role_arn).get_client('events') def add_accounts(self, ou=None): '''add accounts to the broadcast list''' # get the accounts for an ou if ou is defined def create_event(self, account, source, detail): '''Create an event that cen be written to an event-bus''' # account and target can be used to build a resource string region = self.events.get_region() resource_arn = ':'.join('arn', 'aws', 'events', region, account, self.event_bus) event = Events() event.add_resources(resource_arn) event.create_event(account) def set_event_bus(self, bus_name='default'): '''describes and event bus''' self.event_bus = '/'.join(['event-bus', bus_name]) def send_event(self, event): self.events.put_events(Entries=[event]) def broadcast_event(self): '''Send an event to multiple event buses''' for account in self.accounts: self.end_event(self.create_event(account))
def __init__(self, role_arn=None, region_name=None): self.org_id = None self.org_arn = None self.master_acct_arn = None self.master_acct_email = None self.master_acct_id = None self.org = Session(role_arn=role_arn, region_name=region_name).get_client('organizations')
def __init__(self, role_arn=None, region_name=None): self.master_account = None self.org_root = None self.org_unit = None self.org_units = {} self.accounts = {} self.org = Session(role_arn=role_arn, region_name=region_name).get_client('organizations')
def __init__(self, client=None, region_name=None): self.bucket_name = None self.key_name = None self.session = Session(region_name=region_name) if client: self.s3 = client else: self.s3 = self.session.get_client('s3')
def test_client_with_service(sts, cc): session = Session() chk = session.get_client('project-grand-slam') assert chk == 'boto!' cc.assert_called_with(ANY, 'project-grand-slam', aws_access_key_id=None, aws_secret_access_key=None, aws_session_token=None, region_name=None) sts.assert_not_called()
class SQS(): def __init__(self, region_name=None, role_arn=None): self.sqs_url = None self.sqs = Session(region_name, role_arn).get_client('sqs') self.messages = [] def queue_url(self, qname): 'given the queue name, get the associated URL' if qname: try: self.sqs_url = self.sqs.get_queue_url( QueueName=qname)['QueueUrl'] except Exception as e: raise Exception('Could not find SQS Queue', e) return self.sqs_url def send_to_sqs(self, message): 'send a message to a queue' response = self.sqs.send_message(QueueUrl=self.sqs_url, MessageBody=message) return response def send_to_sqs_fifo(self, message, dedup_id, group_id='standard'): 'send a message to a FIFO queue' response = self.sqs.send_message(QueueUrl=self.sqs_url, MessageBody=message, MessageDeduplicationId=dedup_id, MessageGroupId=group_id) return response def read_from_sqs(self, waittime=1): 'set a waittime to enable long polling' max_messages = 1 response = self.sqs.receive_message(QueueUrl=self.sqs_url, AttributeNames=['All'], MaxNumberOfMessages=max_messages, WaitTimeSeconds=waittime) status = None if 'Messages' in response: status = len(response['Messages']) for msg in response['Messages']: self.messages.append(RequestQueueItem(msg)) return status def remove_from_sqs(self, receipt_handle): 'remove a message from a queue' response = self.sqs.delete_message(QueueUrl=self.sqs_url, ReceiptHandle=receipt_handle) return response
def test_session(): session = Session() assert session.session is None assert session.region_name is None assert session.role_arn is None inspect.isclass(Session) assert isinstance(session, Session)
def test_get_client_with_role(sts, cc): sts.assume_role.return_value = 20 sts().aws_access_key_id = 'my_access_key' sts().aws_secret_access_key = 'my_secret_key' sts().aws_session_token = 'my_session_token' test_role_arn = 'arn:aws:iam::111111111:role/net.dilex.some.test.role' session = Session(role_arn=test_role_arn) chk = session.get_client('project-grand-slam') assert chk == 'boto!' cc.assert_called_once() cc.assert_called_with(ANY, 'project-grand-slam', aws_access_key_id='my_access_key', aws_secret_access_key='my_secret_key', aws_session_token='my_session_token', region_name=None)
def test_session_region_env(): session = Session() assert session.get_region() is None os.environ['AWS_REGION'] = 'us-least-7' session.set_region() assert session.region_name == 'us-least-7' assert session.get_region() == 'us-least-7' os.environ.pop('AWS_REGION')
class Organizations: def __init__(self, role_arn=None, region_name=None): self.org_id = None self.org_arn = None self.master_acct_arn = None self.master_acct_email = None self.master_acct_id = None self.org = Session(role_arn=role_arn, region_name=region_name).get_client('organizations') def get_organization_info(self): try: org_details = self.org.describe_organization()['Organization'] except Exception as e: raise Exception('Could not get organization details', e) self.org_id = org_details['Id'] self.org_arn = org_details['Arn'] self.master_acct_arn = org_details['MasterAccountArn'] self.master_acct_email = org_details['MasterAccountEmail'] self.master_acct_id = org_details['MasterAccountId']
def test_init_with_role_and_region(): test_region_name = 'us-least-5' test_role_arn = 'arn:aws:iam::111111111:role/net.dilex.some.test.role' session = Session(role_arn=test_role_arn, region_name=test_region_name) assert session.role_arn == 'arn:aws:iam::111111111:role/net.dilex.some.test.role' assert session.region_name == 'us-least-5'
def __init__(self, region_name=None, role_arn=None): self.accounts = [] self.event_bus = 'event-bus/default' self.events = Session(region_name, role_arn).get_client('events')
def test_get_region(): session = Session() session.set_region(region_name='us-least-6') assert session.region_name == 'us-least-6' assert session.get_region() == 'us-least-6'
def test_set_region(): session = Session() session.set_region('us-least-8') assert session.region_name == 'us-least-8'
def test_session_region(): session = Session(region_name='us-least-9') assert session.region_name == 'us-least-9'
def __init__(self, region_name=None, role_arn=None): self.sqs_url = None self.sqs = Session(region_name, role_arn).get_client('sqs') self.messages = []
class S3(): def __init__(self, client=None, region_name=None): self.bucket_name = None self.key_name = None self.session = Session(region_name=region_name) if client: self.s3 = client else: self.s3 = self.session.get_client('s3') def set_key_name(self, key_name): """set the key name property (i.e., the s3 'file' name)""" self.key_name = key_name def set_bucket_name(self, bucket_name): """sets the bucket_name property for class. CHecks that bucket exists""" try: response = self.s3.head_bucket(Bucket=bucket_name) print('Response:', response) except Exception as e: raise Exception("Bucket: " + bucket_name + " not available " + str(e)) self.bucket_name = bucket_name return self.bucket_name def put_data_object(self, data): """store a data structure - like an array or dict""" enc_data = json.dumps(data) try: res = self.s3.put_object( Body=enc_data, Bucket=self.bucket_name, Key=self.key_name ) except Exception as e: raise Exception('Error saving to S3: ' + str(e)) return res def put_file_object(self, data): """store binary info - an image, encrypted data, word doc, etc""" try: res = self.s3.put_object( Body=data, Bucket=self.bucket_name, Key=self.key_name ) except Exception as e: raise Exception('Error saving to S3: ' + str(e)) return res def get_data_object(self): try: obj = self.s3.get_object( Bucket=self.bucket_name, Key=self.key_name ) except Exception as e: raise Exception('Error reading from S3: ' + str(e)) return json.loads(obj['Body']) def get_file_object(self): try: obj = self.s3.get_object( Bucket=self.bucket_name, Key=self.key_name ) except Exception as e: raise Exception('Error reading from S3: ' + str(e)) return obj['Body'] def get_streaming_file_object(self): ''' for reading objects from s3 retutns a binary object which can be decoded with decode('utf-8') for example ''' try: obj = self.s3.get_object( Bucket=self.bucket_name, Key=self.key_name ) except Exception as e: raise Exception('Error reading from S3: ' + str(e)) return obj['Body'].read()
class Accounts: def __init__(self, role_arn=None, region_name=None): self.master_account = None self.org_root = None self.org_unit = None self.org_units = {} self.accounts = {} self.org = Session(role_arn=role_arn, region_name=region_name).get_client('organizations') def list_accounts(self): 'get a listing of all accounts - index by account id' try: self._set_master_account() except Exception as e: raise Exception('Could not establish account root', e) res = self.org.list_accounts() for acc in res['Accounts']: self.accounts[acc['Id']] = acc return self.accounts def list_ous(self): 'get a list of top level organizational units (OUs)' try: self._set_root() except Exception as e: raise Exception('Unable to find organization root', e) res = self.org.list_organizational_units_for_parent( ParentId=self.org_root) for ou in res['OrganizationalUnits']: self.org_units[ou['Name']] = ou def list_ou_accounts(self, ou_name): 'get a list of accounts for an organizational unit' try: self.list_accounts() self.list_ous() parent_id = self.org_units[ou_name]['Id'] res = self.org.list_children(ParentId=parent_id, ChildType='ACCOUNT') except Exception as e: raise Exception('Could not find OU:', ou_name, e) accs = [] for acc in res['Children']: accs.append(self.accounts[acc['Id']]) return accs '''This works but I'm not sure how useful it is to have in here - probably better to just do this from the CLI or in the console''' # def create_account(self, account_name, account_email, # account_role='OrganizationAccountAccessRole'): # 'create a new account and assign it to an ou' # # try: # res = self.org.create_account(Email=account_email, # AccountName=account_name, # RoleName=account_role) # except Exception as e: # raise Exception('Error initializing create account', e) # # # Now we are going to hang out and wait for the account to # # be created - takes a few minutes... # # request_id = res.get('CreateAccountStatus').get('Id') # print('Account creation started, request_id:', request_id) # status = 'IN_PROGRESS' # status_response = None # while status == 'IN_PROGRESS': # status_response = self.org.describe_create_account_status( # CreateAccountRequestId=request_id) # status = status_response.get('CreateAccountStatus').get('State') # print('Create account status', status) # time.sleep(10) # # if status == 'SUCCEEDED': # acc_id = status_response.get('CreateAccountStatus').get('AccountId') # self.account_id = acc_id # else: # reason = status_response.get('CreateAccountStatus').get('FailureReason') # print('Account creation failed', reason) def _set_master_account(self, account_number=None): 'set the AWS Organization master account number' try: env = Env() sts = Sts() acc_num = sts.get_account_id() self.master_account = acc_num or account_number or env.get_env( 'AW_MASTER') except Exception as e: raise Exception('Could not find master account info', e) if self.master_account is None: raise Exception('Master Account not set, check AW_MASTER') def _set_root(self): 'get the root identifier for this account' # if org_root is not set, try setting it if self.org_root is None: res = self.org.list_roots() self.org_root = res['Roots'][0]['Id']
def test_init_with_role_none(): test_role_arn = None session = Session(role_arn=test_role_arn) assert session.role_arn is None
def __init__(self, region_name=None): self.enc_regions = [] self.master_keys = [] self.key_provider = None self.kms = Session(region_name).get_client('kms')
def get_ssm(self): if self.ssm is None: self.ssm = Session(self.region_name, self.role_arn).get_client('ssm') return self.ssm