Commits

Cameron Simpson  committed d41ba53

cs.app.aws: .reservations, .regions properties; report() method for testing; .connect() method to wrap EC2Connection using default settings as needed

  • Participants
  • Parent commits d252e96

Comments (0)

Files changed (1)

File lib/python/cs/app/aws.py

 #!/usr/bin/python
 #
 # Access Amazon AWS services.
-# Uses boto underneath, but boto is not awfully pythonic.
+# Uses boto underneath, but boto does not feel awfully pythonic.
 # In any case, this exercise will give me convenient AWS access and
 # an avenue to learn the boto interfaces.
 #       - Cameron Simpson <cs@zip.com.au> 17nov2012
 #
 
-from threading import Lock
+from threading import RLock
 from boto.ec2.connection import EC2Connection
+from cs.logutils import D
 from cs.threads import locked_property
 from cs.misc import O
 
   ''' Convenience wrapper for EC2 connections.
   '''
 
-  def __init__(self, access_key_id, access_key_secret):
+  def __init__(self, aws_access_key_id=None, aws_secret_access_key=None, region=None):
     ''' Initialise the EC2 with access id and secret.
     '''
-    self.access_key_id = access_key_id
-    self.access_key_secret = access_key_secret
-    self._lock = Lock()
+    self.aws = O()
+    self.aws.access_key_id = aws_access_key_id
+    self.aws.secret_access_key = aws_secret_access_key
+    self.aws.region = region
+    self._lock = RLock()
+    self._O_omit = ('conn', 'regions', 'instances')
 
-  def _EC2Connection(self):
-    return EC2Connection(self.access_key_id, self.access_key_secret)
+  def connect(self, **kwargs):
+    ''' Get a boto.ec2.connection.EC2Connection.
+        Missing `aws_access_key_id`, `aws_secret_access_key`, `region`
+        arguments come from the corresponding EC2 attributes.
+    '''
+    for kw in ('aws_access_key_id', 'aws_secret_access_key'):
+      if kw not in kwargs:
+        kwargs[kw] = getattr(self.aws, kw[4:], None)
+    for kw in ('region',):
+      if kw not in kwargs:
+        kwargs[kw] = getattr(self.aws, kw, None)
+    if isinstance(kwargs.get('region', None), (str, unicode)):
+      kwargs['region'] = self.region(kwargs['region'])
+    return EC2Connection(**kwargs)
 
   @locked_property
   def conn(self):
-    return self._EC2Connection()
+    return self.connect()
 
+  @locked_property
+  def regions(self):
+    ''' Return a mapping from Region name to Region.
+    '''
+    ec2 = self.connect(region=None)
+    RS = dict( [ (R.name, R) for R in ec2.get_all_regions() ] )
+    ec2.close()
+    return RS
+
+  def region(self, name):
+    ''' Return the Region with the specified `name`.
+    '''
+    return self.regions[name]
+
+  @property
+  def reservations(self):
+    return self.conn.get_all_instances()
+
+  def report(self):
+    yield str(self)
+    yield "  regions: " + str(self.regions)
+    yield "  reservations: " + str(self.reservations)
+    for R in self.reservations:
+      region = R.region
+      yield "    %s @ %s %s" % (R.id, R.region.name, dir(R))
+      for I in R.instances:
+        yield "      %s %s %s" % (I, I.public_dns_name, dir(I))