def events(stack_ref, region, w, watch, output): '''Show all Cloud Formation events for a single stack''' stack_refs = get_stack_refs(stack_ref) region = get_region(region) check_credentials(region) cf = boto.cloudformation.connect_to_region(region) for _ in watching(w, watch): rows = [] for stack in get_stacks(stack_refs, region): events = cf.describe_stack_events(stack.stack_name) for event in events: d = event.__dict__ d['stack_name'] = stack.name d['version'] = stack.version d['resource_type'] = format_resource_type(d['resource_type']) d['event_time'] = calendar.timegm(event.timestamp.timetuple()) rows.append(d) rows.sort(key=lambda x: x['event_time']) with OutputFormat(output): print_table( ('stack_name version resource_type logical_resource_id ' + 'resource_status resource_status_reason event_time').split(), rows, styles=STYLES, titles=TITLES, max_column_widths=MAX_COLUMN_WIDTHS)
def list_stacks(region, stack_ref, all, output, w, watch): """List Cloud Formation stacks""" region = get_region(region) check_credentials(region) stack_refs = get_stack_refs(stack_ref) for _ in watching(w, watch): rows = [] for stack in get_stacks(stack_refs, region, all=all): rows.append( { "stack_name": stack.name, "version": stack.version, "status": stack.stack_status, "creation_time": calendar.timegm(stack.creation_time.timetuple()), "description": stack.template_description, } ) rows.sort(key=lambda x: (x["stack_name"], x["version"])) with OutputFormat(output): print_table( "stack_name version status creation_time description".split(), rows, styles=STYLES, titles=TITLES )
def print_spilos(spilos): if len(spilos) == 0: return columns = [ 'cluster', 'dns', 'instance_id', 'private_ip', 'role', 'launch_time', ] if spilos[0].instances is None: columns = ['cluster', 'dns'] pretty_rows = list() for s in spilos: pretty_row = {'cluster': s.version} pretty_row['dns'] = ', '.join(s.dns or list()) if s.instances is not None: for i in s.instances: pretty_row.update(i) pretty_rows.append(pretty_row.copy()) # # Do not repeat general cluster information pretty_row = {'cluster': '', 'dns': ''} else: pretty_rows.append(pretty_row) print_table(columns, pretty_rows, styles=STYLES, titles=TITLES)
def events(stack_ref, region, w, watch, output): '''Show all Cloud Formation events for a single stack''' stack_refs = get_stack_refs(stack_ref) region = get_region(region) check_credentials(region) cf = boto3.client('cloudformation', region) for _ in watching(w, watch): rows = [] for stack in get_stacks(stack_refs, region): events = cf.describe_stack_events(StackName=stack.StackId)['StackEvents'] for event in events: d = event.copy() d['stack_name'] = stack.name d['version'] = stack.version d['resource_type'] = format_resource_type(d['ResourceType']) d['event_time'] = calendar.timegm(event['Timestamp'].timetuple()) rows.append(d) rows.sort(key=lambda x: x['event_time']) with OutputFormat(output): print_table(('stack_name version resource_type LogicalResourceId ' + 'ResourceStatus ResourceStatusReason event_time').split(), rows, styles=STYLES, titles=TITLES, max_column_widths=MAX_COLUMN_WIDTHS)
def output(output): '''Example for all possible Echo Formats You see the message only, if the Output TEXT ''' with OutputFormat(output): action('This is a ok:') ok() action('This is a ok with message:') ok('all is fine') action('This is a warning:') warning('please check this') with Action('Start with working..') as act: # save_the_world() act.progress() act.progress() act.progress() act.progress() print_table('id name'.split(), [{'id': 1, 'name': 'Test #1'}, {'id': 2, 'name': 'Test #2'}]) info('Only FYI') action('This is a error:') error('this is wrong, please fix') action('This is a fatal error:') fatal_error('this is a fuckup') info('I\'am not printed, the process a dead')
def resources(stack_ref, region, w, watch, output): '''Show all resources of a single Cloud Formation stack''' stack_refs = get_stack_refs(stack_ref) region = get_region(region) check_credentials(region) cf = boto.cloudformation.connect_to_region(region) for _ in watching(w, watch): rows = [] for stack in get_stacks(stack_refs, region): resources = cf.describe_stack_resources(stack.stack_name) for resource in resources: d = resource.__dict__ d['stack_name'] = stack.name d['version'] = stack.version d['resource_type'] = format_resource_type(d['resource_type']) d['creation_time'] = calendar.timegm(resource.timestamp.timetuple()) rows.append(d) rows.sort(key=lambda x: (x['stack_name'], x['version'], x['logical_resource_id'])) with OutputFormat(output): print_table('stack_name version logical_resource_id resource_type resource_status creation_time'.split(), rows, styles=STYLES, titles=TITLES)
def events(stack_ref, region, w, watch, output): '''Show all Cloud Formation events for a single stack''' stack_refs = get_stack_refs(stack_ref) region = get_region(region) check_credentials(region) cf = boto.cloudformation.connect_to_region(region) for _ in watching(w, watch): rows = [] for stack in get_stacks(stack_refs, region): events = cf.describe_stack_events(stack.stack_name) for event in events: d = event.__dict__ d['stack_name'] = stack.name d['version'] = stack.version d['resource_type'] = format_resource_type(d['resource_type']) d['event_time'] = calendar.timegm(event.timestamp.timetuple()) rows.append(d) rows.sort(key=lambda x: x['event_time']) with OutputFormat(output): print_table(('stack_name version resource_type logical_resource_id ' + 'resource_status resource_status_reason event_time').split(), rows, styles=STYLES, titles=TITLES, max_column_widths=MAX_COLUMN_WIDTHS)
def events(stack_ref, region, w, watch, output): '''Show all Cloud Formation events for a single stack''' stack_refs = get_stack_refs(stack_ref) region = get_region(region) check_credentials(region) cf = boto3.client('cloudformation', region) for _ in watching(w, watch): rows = [] for stack in get_stacks(stack_refs, region): events = cf.describe_stack_events( StackName=stack.StackId)['StackEvents'] for event in events: d = event.copy() d['stack_name'] = stack.name d['version'] = stack.version d['resource_type'] = format_resource_type(d['ResourceType']) d['event_time'] = calendar.timegm( event['Timestamp'].timetuple()) rows.append(d) rows.sort(key=lambda x: x['event_time']) with OutputFormat(output): print_table( ('stack_name version resource_type LogicalResourceId ' + 'ResourceStatus ResourceStatusReason event_time').split(), rows, styles=STYLES, titles=TITLES, max_column_widths=MAX_COLUMN_WIDTHS)
def resources(stack_ref, region, w, watch, output): '''Show all resources of a single Cloud Formation stack''' stack_refs = get_stack_refs(stack_ref) region = get_region(region) check_credentials(region) cf = boto3.client('cloudformation', region) for _ in watching(w, watch): rows = [] for stack in get_stacks(stack_refs, region): resources = cf.describe_stack_resources(StackName=stack.StackName)['StackResources'] for resource in resources: d = resource.copy() d['stack_name'] = stack.name d['version'] = stack.version d['resource_type'] = format_resource_type(d['ResourceType']) d['creation_time'] = calendar.timegm(resource['Timestamp'].timetuple()) rows.append(d) rows.sort(key=lambda x: (x['stack_name'], x['version'], x['LogicalResourceId'])) with OutputFormat(output): print_table('stack_name version LogicalResourceId resource_type ResourceStatus creation_time'.split(), rows, styles=STYLES, titles=TITLES)
def list_stacks(region, stack_ref, all, output, w, watch): '''List Cloud Formation stacks''' region = get_region(region) check_credentials(region) stack_refs = get_stack_refs(stack_ref) for _ in watching(w, watch): rows = [] for stack in get_stacks(stack_refs, region, all=all): rows.append({ 'stack_name': stack.name, 'version': stack.version, 'status': stack.StackStatus, 'creation_time': calendar.timegm(stack.CreationTime.timetuple()), 'description': stack.TemplateDescription }) rows.sort(key=lambda x: (x['stack_name'], x['version'])) with OutputFormat(output): print_table( 'stack_name version status creation_time description'.split(), rows, styles=STYLES, titles=TITLES)
def resources(stack_ref, region, w, watch, output): '''Show all resources of a single Cloud Formation stack''' stack_refs = get_stack_refs(stack_ref) region = get_region(region) check_credentials(region) cf = boto.cloudformation.connect_to_region(region) for _ in watching(w, watch): rows = [] for stack in get_stacks(stack_refs, region): resources = cf.describe_stack_resources(stack.stack_name) for resource in resources: d = resource.__dict__ d['stack_name'] = stack.name d['version'] = stack.version d['resource_type'] = format_resource_type(d['resource_type']) d['creation_time'] = calendar.timegm( resource.timestamp.timetuple()) rows.append(d) rows.sort(key=lambda x: (x['stack_name'], x['version'], x['logical_resource_id'])) with OutputFormat(output): print_table( 'stack_name version logical_resource_id resource_type resource_status creation_time' .split(), rows, styles=STYLES, titles=TITLES)
def resources(stack_ref, region, w, watch, output): '''Show all resources of a single Cloud Formation stack''' stack_refs = get_stack_refs(stack_ref) region = get_region(region) check_credentials(region) cf = boto3.client('cloudformation', region) for _ in watching(w, watch): rows = [] for stack in get_stacks(stack_refs, region): resources = cf.describe_stack_resources( StackName=stack.StackName)['StackResources'] for resource in resources: d = resource.copy() d['stack_name'] = stack.name d['version'] = stack.version d['resource_type'] = format_resource_type(d['ResourceType']) d['creation_time'] = calendar.timegm( resource['Timestamp'].timetuple()) rows.append(d) rows.sort(key=lambda x: (x['stack_name'], x['version'], x['LogicalResourceId'])) with OutputFormat(output): print_table( 'stack_name version LogicalResourceId resource_type ResourceStatus creation_time' .split(), rows, styles=STYLES, titles=TITLES)
def list_dummy_states(output, watch): '''Example for Listings''' states = ['ERROR', 'FINE', 'WARNING'] i = 0 for _ in watching(watch): i += 1 rows = [] for y in (1, 2, 3): id = i * y - i rows.append({ 'id': id, 'name': 'Column #{}'.format(id), 'state': states[id % len(states)], 'creation_time': 1444911300, 'desc': 'this is a ve' + 'r' * 50 + 'y long description', 'without_title': 'column without title', 'missing_column': 'Column are not in output' }) with OutputFormat(output): print_table( 'id name state creation_time desc without_title'.split(), rows, styles=STYLES, titles=TITLES, max_column_widths=MAX_COLUMN_WIDTHS)
def output(output): '''Example for all possible Echo Formats You see the message only, if the Output TEXT ''' with OutputFormat(output): action('This is a ok:') ok() action('This is a ok with message:') ok('all is fine') action('This is a warning:') warning('please check this') with Action('Start with working..') as act: # save_the_world() act.progress() act.progress() act.progress() act.progress() print_table('id name'.split(), [{ 'id': 1, 'name': 'Test #1' }, { 'id': 2, 'name': 'Test #2' }]) info('Only FYI') action('This is a error:') error('this is wrong, please fix') action('This is a fatal error:') fatal_error('this is a fuckup') info('I\'am not printed, the process a dead')
def instances(stack_ref, all, terminated, docker_image, region, output, w, watch): """List the stack's EC2 instances""" stack_refs = get_stack_refs(stack_ref) region = get_region(region) check_credentials(region) conn = boto.ec2.connect_to_region(region) elb = boto.ec2.elb.connect_to_region(region) if all: filters = None else: # filter out instances not part of any stack filters = {"tag-key": "aws:cloudformation:stack-name"} opt_docker_column = " docker_source" if docker_image else "" for _ in watching(w, watch): rows = [] for instance in conn.get_only_instances(filters=filters): cf_stack_name = instance.tags.get("aws:cloudformation:stack-name") stack_name = instance.tags.get("StackName") stack_version = instance.tags.get("StackVersion") if not stack_refs or matches_any(cf_stack_name, stack_refs): instance_health = get_instance_health(elb, cf_stack_name) if instance.state.upper() != "TERMINATED" or terminated: docker_source = get_instance_docker_image_source(instance) if docker_image else "" rows.append( { "stack_name": stack_name or "", "version": stack_version or "", "resource_id": instance.tags.get("aws:cloudformation:logical-id"), "instance_id": instance.id, "public_ip": instance.ip_address, "private_ip": instance.private_ip_address, "state": instance.state.upper().replace("-", "_"), "lb_status": instance_health.get(instance.id), "docker_source": docker_source, "launch_time": parse_time(instance.launch_time), } ) rows.sort(key=lambda r: (r["stack_name"], r["version"], r["instance_id"])) with OutputFormat(output): print_table( ( "stack_name version resource_id instance_id public_ip " + "private_ip state lb_status{} launch_time".format(opt_docker_column) ).split(), rows, styles=STYLES, titles=TITLES, )
def domains(stack_ref, region, output, w, watch): '''List the stack's Route53 domains''' stack_refs = get_stack_refs(stack_ref) region = get_region(region) check_credentials(region) cf = boto.cloudformation.connect_to_region(region) route53 = boto.route53.connect_to_region(region) records_by_name = {} for _ in watching(w, watch): rows = [] for stack in get_stacks(stack_refs, region): if stack.stack_status == 'ROLLBACK_COMPLETE': # performance optimization: do not call EC2 API for "dead" stacks continue resources = cf.describe_stack_resources(stack.stack_id) for res in resources: if res.resource_type == 'AWS::Route53::RecordSet': name = res.physical_resource_id if name not in records_by_name: zone_name = name.split('.', 1)[1] zone = route53.get_zone(zone_name) for rec in zone.get_records(): records_by_name[(rec.name.rstrip('.'), rec.identifier)] = rec record = records_by_name.get( (name, stack.stack_name)) or records_by_name.get( (name, None)) rows.append({ 'stack_name': stack.name, 'version': stack.version, 'resource_id': res.logical_resource_id, 'domain': res.physical_resource_id, 'weight': record.weight if record else None, 'type': record.type if record else None, 'value': ','.join(record.resource_records) if record else None, 'create_time': calendar.timegm(res.timestamp.timetuple()) }) with OutputFormat(output): print_table( 'stack_name version resource_id domain weight type value create_time' .split(), rows, styles=STYLES, titles=TITLES)
def main_clean(delete): repo_path = pygit2.discover_repository(os.getcwd()) repo = pygit2.Repository(repo_path) info = {} fill_branch_info(info, repo.branches, islocal=True) fill_branch_info(info, repo.branches, islocal=False) fill_merged_info(info, isremote=False) fill_merged_info(info, isremote=True) rows = [] issafe = True for name in info.keys(): data = info[name] if not data.gone: continue rows.append({ "flags": "{}local".format("*" if data.head else " "), "name": name, "log": first_line(repo[data.target].message), }) if data.head: issafe = False # end if not rows: print("No work to be done") return max_width, _ = os.get_terminal_size(0) used = 6 + 1 + 40 + 1 remaining = max_width - 1 - used WIDTHS = {"flags": 6, "name": 40, "log": remaining} with OutputFormat("text"): print_table(["flags", "name", "log"], rows, max_column_widths=WIDTHS) if delete: print("Deleting local branches...") if not issafe: print("Current checkout includes a branch to be deleted.") return click.confirm("Do you want to continue?", abort=True) for name in info.keys(): data = info[name] if not data.gone: continue repo.branches[data.key].delete()
def images(stack_ref, region, output, hide_older_than, show_instances): '''Show all used AMIs and available Taupage AMIs''' stack_refs = get_stack_refs(stack_ref) region = get_region(region) check_credentials(region) conn = boto.ec2.connect_to_region(region) instances_by_image = collections.defaultdict(list) for inst in conn.get_only_instances(): if inst.state == 'terminated': # do not count TERMINATED EC2 instances continue stack_name = inst.tags.get('aws:cloudformation:stack-name') if not stack_refs or matches_any(stack_name, stack_refs): instances_by_image[inst.image_id].append(inst) images = {} for image in conn.get_all_images( filters={'image-id': list(instances_by_image.keys())}): images[image.id] = image if not stack_refs: filters = {'name': '*Taupage-*', 'state': 'available'} for image in conn.get_all_images(filters=filters): images[image.id] = image rows = [] cutoff = datetime.datetime.now() - datetime.timedelta(days=hide_older_than) for image in images.values(): row = image.__dict__ creation_time = parse_time(image.creationDate) row['creation_time'] = creation_time row['instances'] = ', '.join( sorted(i.id for i in instances_by_image[image.id])) row['total_instances'] = len(instances_by_image[image.id]) stacks = set() for instance in instances_by_image[image.id]: stack_name = instance.tags.get('aws:cloudformation:stack-name') # EC2 instance might not be part of a CF stack if stack_name: stacks.add(stack_name) row['stacks'] = ', '.join(sorted(stacks)) # if creation_time > cutoff.timestamp() or row['total_instances']: rows.append(row) rows.sort(key=lambda x: x.get('name')) with OutputFormat(output): cols = 'id name owner_id description stacks total_instances creation_time' if show_instances: cols = cols.replace('total_instances', 'instances') print_table(cols.split(), rows, titles=TITLES, max_column_widths=MAX_COLUMN_WIDTHS)
def status(stack_ref, region, output, w, watch): '''Show stack status information''' stack_refs = get_stack_refs(stack_ref) region = get_region(region) check_credentials(region) conn = boto.ec2.connect_to_region(region) elb = boto.ec2.elb.connect_to_region(region) cf = boto.cloudformation.connect_to_region(region) for _ in watching(w, watch): rows = [] for stack in sorted(get_stacks(stack_refs, region)): instance_health = get_instance_health(elb, stack.stack_name) main_dns_resolves = False http_status = None resources = cf.describe_stack_resources(stack.stack_id) for res in resources: if res.resource_type == 'AWS::Route53::RecordSet': name = res.physical_resource_id if not name: # physical resource ID will be empty during stack creation continue if 'version' in res.logical_resource_id.lower(): try: requests.get('https://{}/'.format(name), timeout=2) http_status = 'OK' except: http_status = 'ERROR' else: try: answers = dns.resolver.query(name, 'CNAME') except: answers = [] for answer in answers: if answer.target.to_text().startswith('{}-'.format(stack.stack_name)): main_dns_resolves = True instances = conn.get_only_instances(filters={'tag:aws:cloudformation:stack-id': stack.stack_id}) rows.append({'stack_name': stack.name, 'version': stack.version, 'status': stack.stack_status, 'total_instances': len(instances), 'running_instances': len([i for i in instances if i.state == 'running']), 'healthy_instances': len([i for i in instance_health.values() if i == 'IN_SERVICE']), 'lb_status': ','.join(set(instance_health.values())), 'main_dns': main_dns_resolves, 'http_status': http_status }) with OutputFormat(output): print_table(('stack_name version status total_instances running_instances healthy_instances ' + 'lb_status http_status main_dns').split(), rows, styles=STYLES, titles=TITLES)
def instances(stack_ref, all, terminated, docker_image, piu, odd_host, region, output, w, watch): '''List the stack's EC2 instances''' stack_refs = get_stack_refs(stack_ref) region = get_region(region) check_credentials(region) ec2 = boto3.resource('ec2', region) elb = boto3.client('elb', region) if all: filters = [] else: # filter out instances not part of any stack filters = [{'Name': 'tag-key', 'Values': ['aws:cloudformation:stack-name']}] opt_docker_column = ' docker_source' if docker_image else '' for _ in watching(w, watch): rows = [] for instance in ec2.instances.filter(Filters=filters): cf_stack_name = get_tag(instance.tags, 'aws:cloudformation:stack-name') stack_name = get_tag(instance.tags, 'StackName') stack_version = get_tag(instance.tags, 'StackVersion') if not stack_refs or matches_any(cf_stack_name, stack_refs): instance_health = get_instance_health(elb, cf_stack_name) if instance.state['Name'].upper() != 'TERMINATED' or terminated: docker_source = get_instance_docker_image_source(instance) if docker_image else '' rows.append({'stack_name': stack_name or '', 'version': stack_version or '', 'resource_id': get_tag(instance.tags, 'aws:cloudformation:logical-id'), 'instance_id': instance.id, 'public_ip': instance.public_ip_address, 'private_ip': instance.private_ip_address, 'state': instance.state['Name'].upper().replace('-', '_'), 'lb_status': instance_health.get(instance.id), 'docker_source': docker_source, 'launch_time': instance.launch_time.timestamp()}) rows.sort(key=lambda r: (r['stack_name'], r['version'], r['instance_id'])) with OutputFormat(output): print_table(('stack_name version resource_id instance_id public_ip ' + 'private_ip state lb_status{} launch_time'.format(opt_docker_column)).split(), rows, styles=STYLES, titles=TITLES) if piu is not None: for row in rows: if row['private_ip'] is not None: call(['piu', 'request-access', row['private_ip'], '{} via senza'.format(piu), '-O', odd_host])
def images(stack_ref, region, output, hide_older_than, show_instances): '''Show all used AMIs and available Taupage AMIs''' stack_refs = get_stack_refs(stack_ref) region = get_region(region) check_credentials(region) conn = boto.ec2.connect_to_region(region) instances_by_image = collections.defaultdict(list) for inst in conn.get_only_instances(): if inst.state == 'terminated': # do not count TERMINATED EC2 instances continue stack_name = inst.tags.get('aws:cloudformation:stack-name') if not stack_refs or matches_any(stack_name, stack_refs): instances_by_image[inst.image_id].append(inst) images = {} for image in conn.get_all_images(filters={'image-id': list(instances_by_image.keys())}): images[image.id] = image if not stack_refs: filters = {'name': '*Taupage-*', 'state': 'available'} for image in conn.get_all_images(filters=filters): images[image.id] = image rows = [] cutoff = datetime.datetime.now() - datetime.timedelta(days=hide_older_than) for image in images.values(): row = image.__dict__ creation_time = parse_time(image.creationDate) row['creation_time'] = creation_time row['instances'] = ', '.join(sorted(i.id for i in instances_by_image[image.id])) row['total_instances'] = len(instances_by_image[image.id]) stacks = set() for instance in instances_by_image[image.id]: stack_name = instance.tags.get('aws:cloudformation:stack-name') # EC2 instance might not be part of a CF stack if stack_name: stacks.add(stack_name) row['stacks'] = ', '.join(sorted(stacks)) # if creation_time > cutoff.timestamp() or row['total_instances']: rows.append(row) rows.sort(key=lambda x: x.get('name')) with OutputFormat(output): cols = 'id name owner_id description stacks total_instances creation_time' if show_instances: cols = cols.replace('total_instances', 'instances') print_table(cols.split(), rows, titles=TITLES, max_column_widths=MAX_COLUMN_WIDTHS)
def domains(stack_ref, region, output, w, watch): """List the stack's Route53 domains""" stack_refs = get_stack_refs(stack_ref) region = get_region(region) check_credentials(region) cf = boto.cloudformation.connect_to_region(region) route53 = boto.route53.connect_to_region(region) records_by_name = {} for _ in watching(w, watch): rows = [] for stack in get_stacks(stack_refs, region): if stack.stack_status == "ROLLBACK_COMPLETE": # performance optimization: do not call EC2 API for "dead" stacks continue resources = cf.describe_stack_resources(stack.stack_id) for res in resources: if res.resource_type == "AWS::Route53::RecordSet": name = res.physical_resource_id if name not in records_by_name: zone_name = name.split(".", 1)[1] zone = route53.get_zone(zone_name) for rec in zone.get_records(): records_by_name[(rec.name.rstrip("."), rec.identifier)] = rec record = records_by_name.get((name, stack.stack_name)) or records_by_name.get((name, None)) rows.append( { "stack_name": stack.name, "version": stack.version, "resource_id": res.logical_resource_id, "domain": res.physical_resource_id, "weight": record.weight if record else None, "type": record.type if record else None, "value": ",".join(record.resource_records) if record else None, "create_time": calendar.timegm(res.timestamp.timetuple()), } ) with OutputFormat(output): print_table( "stack_name version resource_id domain weight type value create_time".split(), rows, styles=STYLES, titles=TITLES, )
def instances(stack_ref, all, terminated, docker_image, region, output, w, watch): '''List the stack's EC2 instances''' stack_refs = get_stack_refs(stack_ref) region = get_region(region) check_credentials(region) conn = boto.ec2.connect_to_region(region) elb = boto.ec2.elb.connect_to_region(region) if all: filters = None else: # filter out instances not part of any stack filters = {'tag-key': 'aws:cloudformation:stack-name'} opt_docker_column = ' docker_source' if docker_image else '' for _ in watching(w, watch): rows = [] for instance in conn.get_only_instances(filters=filters): cf_stack_name = instance.tags.get('aws:cloudformation:stack-name') stack_name = instance.tags.get('StackName') stack_version = instance.tags.get('StackVersion') if not stack_refs or matches_any(cf_stack_name, stack_refs): instance_health = get_instance_health(elb, cf_stack_name) if instance.state.upper() != 'TERMINATED' or terminated: docker_source = get_instance_docker_image_source(instance) if docker_image else '' rows.append({'stack_name': stack_name or '', 'version': stack_version or '', 'resource_id': instance.tags.get('aws:cloudformation:logical-id'), 'instance_id': instance.id, 'public_ip': instance.ip_address, 'private_ip': instance.private_ip_address, 'state': instance.state.upper().replace('-', '_'), 'lb_status': instance_health.get(instance.id), 'docker_source': docker_source, 'launch_time': parse_time(instance.launch_time)}) rows.sort(key=lambda r: (r['stack_name'], r['version'], r['instance_id'])) with OutputFormat(output): print_table(('stack_name version resource_id instance_id public_ip ' + 'private_ip state lb_status{} launch_time'.format(opt_docker_column)).split(), rows, styles=STYLES, titles=TITLES)
def stripped(ctx, fsyms, tsyms, json, verbose): TITLES = { 'pair': 'Pair', 'price': 'Price', } MAX_COLUMN_WIDTHS = { 'pair': 30, 'price': 50, } url = 'https://min-api.cryptocompare.com/data/pricemulti' if verbose == True and json == False: verbose_request_start(url) payload = {'fsyms': fsyms, 'tsyms': tsyms} try: r = requests.get(url, params=payload, stream=True) r.raise_for_status() if verbose == True and json == False: verbose_status_code(r.status_code, r.elapsed.total_seconds()) except requests.exceptions.HTTPError as e: verbose_status_code(r.status_code, r.elapsed.total_seconds()) return -1 except requests.exceptions.RequestException as e: #print('Connection error: {}'.format(e)) if verbose == True and json == False: verbose_status_code(r.status_code, 0) return -1 if json == True: click.echo(r.json()) else: for sym, sobj in r.json().items(): click.secho(' ' + sym + ' ', bg='black', fg='blue') rows = [] for key, value in sobj.items(): pair = sym + '-' + key rows.append({'pair': pair, 'price': str(value)}) print_table('pair price'.split(), rows, styles=STYLES, titles=TITLES, max_column_widths=MAX_COLUMN_WIDTHS)
def domains(stack_ref, region, output, w, watch): '''List the stack's Route53 domains''' stack_refs = get_stack_refs(stack_ref) region = get_region(region) check_credentials(region) cf = boto3.resource('cloudformation', region) records_by_name = {} for _ in watching(w, watch): rows = [] for stack in get_stacks(stack_refs, region): if stack.StackStatus == 'ROLLBACK_COMPLETE': # performance optimization: do not call EC2 API for "dead" stacks continue for res in cf.Stack(stack.StackId).resource_summaries.all(): if res.resource_type == 'AWS::Route53::RecordSet': name = res.physical_resource_id if name not in records_by_name: zone_name = name.split('.', 1)[1] for rec in get_records(zone_name): records_by_name[(rec['Name'].rstrip('.'), rec.get('SetIdentifier'))] = rec record = records_by_name.get((name, stack.StackName)) or records_by_name.get((name, None)) row = {'stack_name': stack.name, 'version': stack.version, 'resource_id': res.logical_id, 'domain': res.physical_resource_id, 'weight': None, 'type': None, 'value': None, 'create_time': calendar.timegm(res.last_updated_timestamp.timetuple())} if record: row.update({'weight': str(record.get('Weight', '')), 'type': record.get('Type'), 'value': ','.join([r['Value'] for r in record.get('ResourceRecords')])}) rows.append(row) with OutputFormat(output): print_table('stack_name version resource_id domain weight type value create_time'.split(), rows, styles=STYLES, titles=TITLES)
def list_dummy_states(output, watch): '''Example for Listings''' states = ['ERROR', 'FINE', 'WARNING'] i = 0 for _ in watching(watch): i += 1 rows = [] for y in (1, 2, 3): id = i * y - i rows.append({'id': id, 'name': 'Column #{}'.format(id), 'state': states[id % len(states)], 'creation_time': 1444911300, 'desc': 'this is a ve' + 'r' * 50 + 'y long description', 'without_title': 'column without title', 'missing_column': 'Column are not in output'}) with OutputFormat(output): print_table('id name state creation_time desc without_title'.split(), rows, styles=STYLES, titles=TITLES, max_column_widths=MAX_COLUMN_WIDTHS)
def list_tunnels(cluster): processes = get_my_processes() processes.sort(key=lambda k: k['cluster']) columns = [ 'pid', 'host', 'service', 'dsn', ] rows = list() if cluster is not None: for p in processes: if re.search(cluster, p['host']) or re.search(cluster, p.get('service', '')): rows.append(p) else: rows = processes print_table(columns, rows, styles=STYLES, titles=TITLES)
def list_stacks(region, stack_ref, all, output, watch): '''List Cloud Formation stacks''' region = get_region(region) stack_refs = get_stack_refs(stack_ref) for _ in watching(watch): rows = [] for stack in get_stacks(stack_refs, region, all=all): rows.append({'stack_name': stack.name, 'version': stack.version, 'status': stack.stack_status, 'creation_time': calendar.timegm(stack.creation_time.timetuple()), 'description': stack.template_description}) rows.sort(key=lambda x: (x['stack_name'], x['version'])) with OutputFormat(output): print_table('stack_name version status creation_time description'.split(), rows, styles=STYLES, titles=TITLES)
def list_tunnels(cluster): processes = get_my_processes() processes.sort(key=lambda k: k['cluster']) columns = [ 'pid', 'host', 'service', 'dsn', ] rows = list() if cluster is not None: for p in processes: if re.search(cluster, p['host']) or re.search( cluster, p.get('service', '')): rows.append(p) else: rows = processes print_table(columns, rows, styles=STYLES, titles=TITLES)
def instances(stack_ref, all, terminated, region, output, w, watch): '''List the stack's EC2 instances''' stack_refs = get_stack_refs(stack_ref) region = get_region(region) check_credentials(region) conn = boto.ec2.connect_to_region(region) elb = boto.ec2.elb.connect_to_region(region) if all: filters = None else: # filter out instances not part of any stack filters = {'tag-key': 'aws:cloudformation:stack-name'} for _ in watching(w, watch): rows = [] for instance in conn.get_only_instances(filters=filters): cf_stack_name = instance.tags.get('aws:cloudformation:stack-name') stack_name = instance.tags.get('StackName') stack_version = instance.tags.get('StackVersion') if not stack_refs or matches_any(cf_stack_name, stack_refs): instance_health = get_instance_health(elb, cf_stack_name) if instance.state.upper() != 'TERMINATED' or terminated: rows.append({'stack_name': stack_name or '', 'version': stack_version or '', 'resource_id': instance.tags.get('aws:cloudformation:logical-id'), 'instance_id': instance.id, 'public_ip': instance.ip_address, 'private_ip': instance.private_ip_address, 'state': instance.state.upper().replace('-', '_'), 'lb_status': instance_health.get(instance.id), 'launch_time': parse_time(instance.launch_time)}) rows.sort(key=lambda r: (r['stack_name'], r['version'], r['instance_id'])) with OutputFormat(output): print_table(('stack_name version resource_id instance_id public_ip ' + 'private_ip state lb_status launch_time').split(), rows, styles=STYLES, titles=TITLES)
def domains(stack_ref, region, output, watch): '''List the stack's Route53 domains''' stack_refs = get_stack_refs(stack_ref) region = get_region(region) cf = boto.cloudformation.connect_to_region(region) route53 = boto.route53.connect_to_region(region) records_by_name = {} for _ in watching(watch): rows = [] for stack in get_stacks(stack_refs, region): if stack.stack_status == 'ROLLBACK_COMPLETE': # performance optimization: do not call EC2 API for "dead" stacks continue resources = cf.describe_stack_resources(stack.stack_id) for res in resources: if res.resource_type == 'AWS::Route53::RecordSet': name = res.physical_resource_id if name not in records_by_name: zone_name = name.split('.', 1)[1] zone = route53.get_zone(zone_name) for rec in zone.get_records(): records_by_name[(rec.name.rstrip('.'), rec.identifier)] = rec record = records_by_name.get((name, stack.stack_name)) or records_by_name.get((name, None)) rows.append({'stack_name': stack.name, 'version': stack.version, 'resource_id': res.logical_resource_id, 'domain': res.physical_resource_id, 'weight': record.weight if record else None, 'type': record.type if record else None, 'value': ','.join(record.resource_records) if record else None, 'create_time': calendar.timegm(res.timestamp.timetuple())}) with OutputFormat(output): print_table('stack_name version resource_id domain weight type value create_time'.split(), rows, styles=STYLES, titles=TITLES)
def status(stack_ref, region, output, w, watch): """Show stack status information""" stack_refs = get_stack_refs(stack_ref) region = get_region(region) check_credentials(region) conn = boto.ec2.connect_to_region(region) elb = boto.ec2.elb.connect_to_region(region) cf = boto.cloudformation.connect_to_region(region) for _ in watching(w, watch): rows = [] for stack in sorted(get_stacks(stack_refs, region)): instance_health = get_instance_health(elb, stack.stack_name) main_dns_resolves = False http_status = None resources = cf.describe_stack_resources(stack.stack_id) for res in resources: if res.resource_type == "AWS::Route53::RecordSet": name = res.physical_resource_id if not name: # physical resource ID will be empty during stack creation continue if "version" in res.logical_resource_id.lower(): try: requests.get("https://{}/".format(name), timeout=2) http_status = "OK" except: http_status = "ERROR" else: try: answers = dns.resolver.query(name, "CNAME") except: answers = [] for answer in answers: if answer.target.to_text().startswith("{}-".format(stack.stack_name)): main_dns_resolves = True instances = conn.get_only_instances(filters={"tag:aws:cloudformation:stack-id": stack.stack_id}) rows.append( { "stack_name": stack.name, "version": stack.version, "status": stack.stack_status, "total_instances": len(instances), "running_instances": len([i for i in instances if i.state == "running"]), "healthy_instances": len([i for i in instance_health.values() if i == "IN_SERVICE"]), "lb_status": ",".join(set(instance_health.values())), "main_dns": main_dns_resolves, "http_status": http_status, } ) with OutputFormat(output): print_table( ( "stack_name version status total_instances running_instances healthy_instances " + "lb_status http_status main_dns" ).split(), rows, styles=STYLES, titles=TITLES, )
def main_list(local): ssh_agent_setup.setup() repo_path = pygit2.discover_repository(os.getcwd()) repo = pygit2.Repository(repo_path) prune = False # havn't got the cred callback working if prune: with Action("Pruning old remotes...") as action: for remote in repo.remotes: remote.fetch(prune=pygit2.GIT_FETCH_PRUNE, callbacks=SSHAgentCallbacks()) action.progress() # end # end print(repo.describe()) info = {} fill_branch_info(info, repo.branches, islocal=True) fill_branch_info(info, repo.branches, islocal=False) fill_merged_info(info, isremote=False) fill_merged_info(info, isremote=True) rows = [] for name in info.keys(): data = info[name] if local and not data.local: continue rows.append({ "flags": "{}{}{}{}.".format( "*" if data.head else " ", "M" if data.up2date or data.merged else ".", "P" if data.pushed else ".", "D" if data.gone else ".", ), "local": "local" if data.local else ".....", "remote": "remote" if data.remote else "......", "name": name, "log": first_line(repo[data.target].message), }) # end max_width, _ = os.get_terminal_size(0) used = 5 + 1 + 5 + 1 + 6 + 1 + 30 + 1 remaining = max_width - 1 - used WIDTHS = { "flags": 5, "local": 5, "remote": 6, "name": 30, "log": remaining } with OutputFormat("text"): print_table(["flags", "local", "remote", "name", "log"], rows, max_column_widths=WIDTHS) click.secho(" " * (max_width - 1), fg="black", bg="white") print("* = current checkout, M = branch is merged into master") print( "P = local has been pushed into it's remote, D = No matching upstream branch for local" )
def price(ctx, fsyms, tsyms, json, verbose, extra): TITLES = { 'label': 'Label', 'value': 'Value', } BANNED_COLUMNS = ['FROMSYMBOL', 'TOSYMBOL', 'LASTTRADEID', 'PRICE'] MAX_COLUMN_WIDTHS = { 'pair': 30, 'price': 50, } url = 'https://min-api.cryptocompare.com/data/pricemultifull' if verbose == True and json == False: verbose_request_start(url) payload = {'fsyms': fsyms, 'tsyms': tsyms} try: r = requests.get(url, params=payload, stream=True) r.raise_for_status() if verbose == True and json == False: verbose_status_code(500, r.elapsed.total_seconds()) except requests.exceptions.HTTPError as e: verbose_status_code(400, r.elapsed.total_seconds()) return -1 except requests.exceptions.RequestException as e: #print('Connection error: {}'.format(e)) if json == False: verbose_status_code(500, 0) return -1 if json == True: click.echo(r.json()) else: table = PrettyTable(['Pair', 'Price', 'Percentage']) table.align = 'r' for ckey, cvalue in r.json()['DISPLAY'].items(): rows = [] for key, value in cvalue.items(): col_pair = '' + ckey + '-' + key + ' ' if float(value['CHANGEPCT24HOUR']) > 0: col_price = fg(29, 139, 58) + ' ' + str( value['PRICE']) + rs.all col_percentage = fg.white + bg(29, 139, 58) + '+' + str( value['CHANGEPCT24HOUR']) + '% ' + ' ▲ ' + rs.all if float(value['CHANGEPCT24HOUR']) < 0: col_price = fg.red + ' ' + str(value['PRICE']) + rs.all col_percentage = fg.white + bg.red + str( value['CHANGEPCT24HOUR']) + '% ' + ' ▼ ' + rs.all if float(value['CHANGEPCT24HOUR']) == 0: col_price = fg.red + ' ' + str(value['PRICE']) + rs.all col_percentage = fg.white + bg.blue + str( value['CHANGEPCT24HOUR']) + '% ' + ' ◎ ' + rs.all table.add_row([col_pair, col_price, col_percentage]) if extra == True: click.secho(table.get_string()) table.clear_rows() for ikey, ivalue in value.items(): if ikey not in BANNED_COLUMNS: rows.append({'label': ikey, 'value': ivalue}) print_table('label value'.split(), rows, styles=STYLES, titles=TITLES, max_column_widths=MAX_COLUMN_WIDTHS) rows = [] #pair = sym + '-' + key #rows.append({'pair': pair, 'price': str(value)}) if extra == False: click.secho(table.get_string())
def if_vpc_empty(account: AccountData, region: str): ec2 = account.session.resource('ec2', region) ec2c = account.session.client('ec2', region) def instance_state(instance_id): if instance_id: return ec2.Instance(id=instance_id).state.get('Name') def if_stups_tool(ni: dict): instance_id = ni.get('Attachment', {}).get('InstanceId') if instance_id: instance = ec2.Instance(id=instance_id) availability_zones = get_az_names(account.session, region) stups_names = ('Odd (SSH Bastion Host)',) + tuple(['NAT {}'.format(x) for x in availability_zones]) if get_tag(instance.tags, 'Name') in stups_names: return True if get_tag(instance.tags, 'aws:cloudformation:logical-id') == 'OddServerInstance': return True allocation_id = ni.get('Association', {}).get('AllocationId') if allocation_id: for gateway in ec2c.describe_nat_gateways()['NatGateways']: if gateway.get('NatGatewayAddresses', {})[0].get('AllocationId') == allocation_id: return True return False account_is_free = True rows = [] for ni in ec2c.describe_network_interfaces()['NetworkInterfaces']: can_remove = if_stups_tool(ni) if not can_remove: account_is_free = False # print(' '.join([str(ni), str(ni.groups), str(ni.attachment), ni.description])) rows.append({'network_id': ni.get('NetworkInterfaceId'), 'group_name': ', '.join([group['GroupName'] for group in ni.get('Groups')]), 'description': ni.get('Description'), 'status': ni.get('Attachment', {}).get('Status'), 'instance_owner_id': ni.get('Attachment', {}).get('InstanceOwnerId'), 'instance_id': ni.get('Attachment', {}).get('InstanceId', ''), 'state': instance_state(ni.get('Attachment', {}).get('InstanceId')), 'allocation_id': ni.get('Association', {}).get('AllocationId'), 'account_name': account.name, 'can_remove': '✔' if can_remove else '✘' }) rows.sort(key=lambda x: (x['account_name'], x['group_name'], x['instance_id'])) with OutputFormat('text'): print_table(''' can_remove account_name network_id allocation_id description group_name status instance_owner_id instance_id state '''.split(), rows, styles={ 'running': {'fg': 'green'}, 'stopped': {'fg': 'red', 'bold': True}, '✔': {'bg': 'green'}, '✘': {'bg': 'red', 'bold': True}, }) return account_is_free
def domains(stack_ref, region, output, w, watch): '''List the stack's Route53 domains''' stack_refs = get_stack_refs(stack_ref) region = get_region(region) check_credentials(region) cf = boto3.resource('cloudformation', region) records_by_name = {} for _ in watching(w, watch): rows = [] for stack in get_stacks(stack_refs, region): if stack.StackStatus == 'ROLLBACK_COMPLETE': # performance optimization: do not call EC2 API for "dead" stacks continue for res in cf.Stack(stack.StackId).resource_summaries.all(): if res.resource_type == 'AWS::Route53::RecordSet': name = res.physical_resource_id if name not in records_by_name: zone_name = name.split('.', 1)[1] for rec in get_records(zone_name): records_by_name[(rec['Name'].rstrip('.'), rec.get('SetIdentifier'))] = rec record = records_by_name.get( (name, stack.StackName)) or records_by_name.get( (name, None)) row = { 'stack_name': stack.name, 'version': stack.version, 'resource_id': res.logical_id, 'domain': res.physical_resource_id, 'weight': None, 'type': None, 'value': None, 'create_time': calendar.timegm(res.last_updated_timestamp.timetuple()) } if record: row.update({ 'weight': str(record.get('Weight', '')), 'type': record.get('Type'), 'value': ','.join([ r['Value'] for r in record.get('ResourceRecords') ]) }) rows.append(row) with OutputFormat(output): print_table( 'stack_name version resource_id domain weight type value create_time' .split(), rows, styles=STYLES, titles=TITLES)
def instances(stack_ref, all, terminated, docker_image, piu, odd_host, region, output, w, watch): '''List the stack's EC2 instances''' stack_refs = get_stack_refs(stack_ref) region = get_region(region) check_credentials(region) ec2 = boto3.resource('ec2', region) elb = boto3.client('elb', region) if all: filters = [] else: # filter out instances not part of any stack filters = [{ 'Name': 'tag-key', 'Values': ['aws:cloudformation:stack-name'] }] opt_docker_column = ' docker_source' if docker_image else '' for _ in watching(w, watch): rows = [] for instance in ec2.instances.filter(Filters=filters): cf_stack_name = get_tag(instance.tags, 'aws:cloudformation:stack-name') stack_name = get_tag(instance.tags, 'StackName') stack_version = get_tag(instance.tags, 'StackVersion') if not stack_refs or matches_any(cf_stack_name, stack_refs): instance_health = get_instance_health(elb, cf_stack_name) if instance.state['Name'].upper( ) != 'TERMINATED' or terminated: docker_source = get_instance_docker_image_source( instance) if docker_image else '' rows.append({ 'stack_name': stack_name or '', 'version': stack_version or '', 'resource_id': get_tag(instance.tags, 'aws:cloudformation:logical-id'), 'instance_id': instance.id, 'public_ip': instance.public_ip_address, 'private_ip': instance.private_ip_address, 'state': instance.state['Name'].upper().replace('-', '_'), 'lb_status': instance_health.get(instance.id), 'docker_source': docker_source, 'launch_time': instance.launch_time.timestamp() }) rows.sort( key=lambda r: (r['stack_name'], r['version'], r['instance_id'])) with OutputFormat(output): print_table( ('stack_name version resource_id instance_id public_ip ' + 'private_ip state lb_status{} launch_time'.format( opt_docker_column)).split(), rows, styles=STYLES, titles=TITLES) if piu is not None: for row in rows: if row['private_ip'] is not None: call([ 'piu', 'request-access', row['private_ip'], '{} via senza'.format(piu), '-O', odd_host ])