i use botocore for AWS. works great for me. here is my list-instances command. this is a newer script that should have no tabs to mess up the indenting but just in case i also put a copy on my website at:
http://stratusrelay.com/phil/list-instances.py.txt
http://stratusrelay.com/phil/list-instances.py (c0a9dbaad45c44a2896e013390130228)
this script also uses multiprocessing to get info from each region in parallel (faster that way). the command line arguments are the regions to be listed, defaulting to all regions. if you want to actually run this script you will need the aws_regions module and set up your own .boto file.
http://stratusrelay.com/phil/aws_regions.py.txt
http://stratusrelay.com/phil/aws_regions.py (369f3bd36c65529f5fcbcbb12ed2d826)
and i attached those files
oh... and this also needs pyutils
http://stratusrelay.com/free/pyutils.py.txt
http://stratusrelay.com/free/pyutils.py (76d7e080645a69fceb38526eee192db1)
nice... separate attachments are merged. i hope they transfer correctly.
i downloaded the attachments and the md5 checksums match, so it looks like attachments do norget corrupted.
http://stratusrelay.com/phil/list-instances.py.txt
http://stratusrelay.com/phil/list-instances.py (c0a9dbaad45c44a2896e013390130228)
this script also uses multiprocessing to get info from each region in parallel (faster that way). the command line arguments are the regions to be listed, defaulting to all regions. if you want to actually run this script you will need the aws_regions module and set up your own .boto file.
http://stratusrelay.com/phil/aws_regions.py.txt
http://stratusrelay.com/phil/aws_regions.py (369f3bd36c65529f5fcbcbb12ed2d826)
#!/usr/bin/env python #----------------------------------------------------------------------------- # Copyright (C) 2016, by Phil D. Howard - all other rights reserved # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # # The author may be contacted using the short first name, middle initial, # and last name, separated by periods, with gmail dot com as the host part # of an email address. #----------------------------------------------------------------------------- # audience linux and unix users # script list-instances.py # purpose show instances # syntax python list-instances.py [ region ... ] # alternate python list-running-instances.py [ region ... ] # note copy or symlink so the command for list-running-instances.py runs list-instances.py to list only running (and pending) instances #----------------------------------------------------------------------------- from __future__ import division, print_function """ show instances """ import botocore.session from aws_regions import aws_regions_list_long, aws_regions_any_to_long from multiprocessing import Pipe, Process from os import getpid, remove from pickle import dump, load from pyutils import eprint, plural pipe = None region = None run = None #----------------------------------------------------------------------------- # function print_instance # purpose print one line describing one instance #----------------------------------------------------------------------------- def print_instance( region, instance ): if instance == None: return None s = region + ' ' + instance['InstanceId'] n = region + '_' if 'State' in instance: s += ' ' s += instance['State']['Name'] if 'ImageId' in instance: s += ' ' s += instance['ImageId'] n += instance['ImageId'] if 'Placement' in instance: if 'AvailabilityZone' in instance['Placement']: s += ' ' s += instance['Placement']['AvailabilityZone'][-1] if 'InstanceType' in instance: s += ' ' s += instance['InstanceType'] if 'VpcId' in instance: s += ' ' s += instance['VpcId'] if 'PublicIpAddress' in instance: s += ' ' s += instance['PublicIpAddress'] if 'PrivateIpAddress' in instance: s += ' ( ' s += instance['PrivateIpAddress'] s += ' )' if 'Tags' in instance: tags = sorted([(tag['Key'], tag['Value']) for tag in instance['Tags']],cmptag) for tag in tags: s += ' ' s += tag[0] s += '=' s += repr(tag[1]) try: print( s ) except IOError: pass return s #----------------------------------------------------------------------------- # function cmptag # purpose compare logic for sort() so 'Name' collates lowest #----------------------------------------------------------------------------- def cmptag(a,b): if a == 'Name': return -1 if b == 'Name': return 1 if a < b: return -1 if a > b: return 1 return 0 #----------------------------------------------------------------------------- # function lookup # purpose run as a child process per region to get instance info # pickle the info from the describe_instances method # pipe this info to the parent using pickle format # note the pipe is inherited from the parent #----------------------------------------------------------------------------- def lookup(): session = botocore.session.get_session() client = session.create_client( 'ec2', region_name=region ) paginator = client.get_paginator( 'describe_instances' ) page_iterator = paginator.paginate() pipe[0].close() for page in page_iterator: for resv in page[ 'Reservations' ]: for instance in resv[ 'Instances' ]: if run and 'State' in instance: if instance['State']['Name'][1:] != 'unning': continue pipe[1].send( instance ) pipe[1].send( None ) pipe[1].close() # send EOF return #----------------------------------------------------------------------------- # function main #----------------------------------------------------------------------------- def main( args ): global pipe, region, run # passing as globals instead of args errors = 0 # arguments are regions region_list = [] if 'run' in args[0]: run = True else: run = False #----------------------------------------------------------------------------- for arg in args[1:]: if arg in ('-r','+r','--run','++run'): run = True continue if arg.lower() in aws_regions_any_to_long: region = aws_regions_any_to_long[ arg.lower() ] if region in region_list: print( 'region', region, 'already specified', file=stderr ) errors += 1 else: region_list += [ region ] else: print( 'argument', repr(arg), 'is not a valid region', file=stderr ) errors += 1 if errors > 0: return 'aborting due to '+repr( errors )+'error'+plural( errors ) if len( region_list ) == 0: region_list = list( aws_regions_list_long ) region_list.sort() region_count = len( region_list ) #----------------------------------------------------------------------------- # setup, record, and start all the processes #----------------------------------------------------------------------------- plist = [] for region in region_list: pipe = Pipe( False ) process = Process( target = lookup ) # child inherits pipe and region, so no args needed. plist += [ ( region, process, pipe ) ] process.start() #----------------------------------------------------------------------------- # read all the results of each process. # so what if we delay on the first ones, we have to wait on all the data. #----------------------------------------------------------------------------- for this_region, this_process, this_pipe in plist: pipe[1].close() # close the parent copy of the send side of the pipe. while True: try: if print_instance( this_region, this_pipe[0].recv() ) == None: break except EOFError: break #----------------------------------------------------------------------------- # wait up to 6 minutes for all of them to finish #----------------------------------------------------------------------------- for this_region, this_process, this_pipe in plist: this_process.join( 360 ) #----------------------------------------------------------------------------- # all done #----------------------------------------------------------------------------- return 0 #----------------------------------------------------------------------------- if __name__ == '__main__': from sys import argv, stderr, stdout result = main( argv ) stdout.flush() try: exit( int( result ) ) except ValueError: print( str( result ), file=stderr ) exit( 1 ) except TypeError: if result == None: exit( 0 ) exit( 254 ) except: exit( 255 ) #----------------------------------------------------------------------------- # EOF
and i attached those files
oh... and this also needs pyutils
http://stratusrelay.com/free/pyutils.py.txt
http://stratusrelay.com/free/pyutils.py (76d7e080645a69fceb38526eee192db1)
nice... separate attachments are merged. i hope they transfer correctly.
i downloaded the attachments and the md5 checksums match, so it looks like attachments do norget corrupted.
Attached Files
Tradition is peer pressure from dead people
What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.