def ls(selectors, state): assert state in ['running', 'pending', 'stopped', 'terminated', None], f'bad state: {state}' if not selectors: instances = list( retry(resource('ec2').instances.filter)(Filters=[{ 'Name': 'instance-state-name', 'Values': [state] }] if state else [])) else: kind = 'tags' kind = 'dns-name' if selectors[0].endswith('.amazonaws.com') else kind kind = 'vpc-id' if selectors[0].startswith('vpc-') else kind kind = 'subnet-id' if selectors[0].startswith('subnet-') else kind kind = 'instance.group-id' if selectors[0].startswith('sg-') else kind kind = 'private-dns-name' if selectors[0].endswith( '.ec2.internal') else kind kind = 'ip-address' if all(x.isdigit() or x == '.' for x in selectors[0]) else kind kind = 'private-ip-address' if all( x.isdigit() or x == '.' for x in selectors[0]) and selectors[0].split( '.')[0] in ['10', '172'] else kind kind = 'instance-id' if selectors[0].startswith('i-') else kind if kind == 'tags' and '=' not in selectors[0]: # TODO allow passing multiple names, which are summed, and then tags, which are intersected selectors = f'Name={selectors[0]}', *selectors[ 1:] # auto add Name= to the first tag instances = [] for chunk in util.iter.chunk(selectors, 195): # 200 boto api limit filters = [{ 'Name': 'instance-state-name', 'Values': [state] }] if state else [] try: if kind == 'tags': filters += [{ 'Name': f'tag:{k}', 'Values': [v] } for t in chunk for k, v in [t.split('=')]] else: filters += [{'Name': kind, 'Values': chunk}] except: pprint.pprint(selectors) pprint.pprint(filters) raise instances += list( retry(resource('ec2').instances.filter)(Filters=filters)) instances = sorted(instances, key=lambda i: i.instance_id) instances = sorted(instances, key=lambda i: tags(i).get('name', 'no-name')) instances = sorted(instances, key=lambda i: i.meta.data['LaunchTime'], reverse=True) return instances
def ensure_bucket(name, acl='private', versioning=False, noencrypt=False, print_fn=stderr, preview=False): if preview: print_fn(' preview:', name) else: try: client('s3').create_bucket( ACL=acl, Bucket=name, CreateBucketConfiguration={'LocationConstraint': aws.region()}, ) except client('s3').exceptions.BucketAlreadyOwnedByYou: print_fn('', name) else: print_fn('', name) if acl == 'private': client('s3').put_public_access_block( Bucket=name, PublicAccessBlockConfiguration={ 'BlockPublicAcls': True, 'IgnorePublicAcls': True, 'BlockPublicPolicy': True, 'RestrictPublicBuckets': True }, ) if versioning: resource('s3').BucketVersioning(name).enable() else: resource('s3').BucketVersioning(name).suspend() if noencrypt: client('s3').delete_bucket_encryption(Bucket=name) else: client('s3').put_bucket_encryption( Bucket=name, ServerSideEncryptionConfiguration={ 'Rules': [{ 'ApplyServerSideEncryptionByDefault': { 'SSEAlgorithm': 'AES256' } }] }, )
def ensure_trigger_s3(name, arn_lambda, metadata, preview): events = ['s3:ObjectCreated:*', 's3:ObjectRemoved:*'] triggers = [] for trigger in metadata['trigger']: if trigger.split()[0] == 's3': kind, bucket, *_ = trigger.split() triggers.append(bucket) if triggers: stderr('\nensure triggers s3:') for bucket in triggers: if preview: stderr(' preview:', bucket) else: ensure_permission(name, 's3.amazonaws.com', f'arn:aws:s3:::{bucket}') confs = aws.resource('s3').BucketNotification(bucket).lambda_function_configurations or [] for conf in confs: if conf['LambdaFunctionArn'] == arn_lambda and conf['Events'] == events: stderr('', bucket) break else: confs.append({'LambdaFunctionArn': arn_lambda, 'Events': events}) stderr('', bucket) aws.resource('s3').BucketNotification(bucket).put(NotificationConfiguration={'LambdaFunctionConfigurations': confs})
def subnet(vpc, zone, print_fn=stderr): vpcs = list( resource('ec2').vpcs.filter( Filters=[{ 'Name': 'vpc-id' if vpc.startswith('vpc-') else 'tag:Name', 'Values': [vpc] }])) assert len(vpcs) == 1, 'no vpc named: %s' % vpc if zone: subnets = [ x for x in vpcs[0].subnets.all() if x.availability_zone == zone ] else: subnets = list(vpcs[0].subnets.all())[:1] assert len( subnets) == 1, 'no subnet for vpc=%(vpc)s zone=%(zone)s' % locals() subnet = subnets[0].id print_fn(f'using zone: {zone}, subnet: {subnet}, vpn: {vpc}') return subnet
def sgs(names=None): sgs = list(resource('ec2').security_groups.all()) if names: sgs = [x for x in sgs if x.group_name in names or x.group_id in names] return sgs