Просмотр исходного кода

Fixed according to review comments for https://github.com/gvlproject/cloudbridge/pull/77

Nuwan Goonasekera 8 лет назад
Родитель
Сommit
ce09143a5f

+ 93 - 48
cloudbridge/cloud/providers/aws/helpers.py

@@ -10,7 +10,7 @@ from cloudbridge.cloud.base.resources import ServerPagedResultList
 
 
 
 
 def trim_empty_params(params_dict):
 def trim_empty_params(params_dict):
-    '''
+    """
     Given a dict containing potentially null values, trims out
     Given a dict containing potentially null values, trims out
     all the null values. This is to please Boto, which throws
     all the null values. This is to please Boto, which throws
     a parameter validation exception for NoneType arguments.
     a parameter validation exception for NoneType arguments.
@@ -25,23 +25,48 @@ def trim_empty_params(params_dict):
             'GroupName': 'abc',
             'GroupName': 'abc',
             'VpcId': 'xyz',
             'VpcId': 'xyz',
         }
         }
-    '''
+    """
     return {k: v for k, v in params_dict.items() if v is not None}
     return {k: v for k, v in params_dict.items() if v is not None}
 
 
 
 
+def find_tag_value(tags, key):
+    """
+    Finds the value associated with a given key from a list of AWS tags.
+
+    :type tags: list of ``dict``
+    :param tags: The AWS tag list to search through
+
+    :type key: ``str``
+    :param key: Name of the tag to search for
+    """
+    for tag in tags or []:
+        if tag.get('Key') == key:
+            return tag.get('Value')
+    return None
+
+
 class BotoGenericService(object):
 class BotoGenericService(object):
-    '''
+    """
     Generic implementation of a Boto3 AWS service. Uses Boto3
     Generic implementation of a Boto3 AWS service. Uses Boto3
     resource, collection and paging support to implement
     resource, collection and paging support to implement
     basic cloudbridge methods.
     basic cloudbridge methods.
-
-    :param AWSCloudProvider provider: CloudBridge AWS provider
-    :param CloudResource cb_iface: CloudBridge class to wrap results in
-    :param Boto3.Resource boto_conn: Boto top level service resource
-                                     (e.g. EC2, S3) connection.
-    :param str boto_collection_name: Boto collection name
-    '''
+    """
     def __init__(self, provider, cb_resource, boto_conn, boto_collection_name):
     def __init__(self, provider, cb_resource, boto_conn, boto_collection_name):
+        """
+        :type provider: :class:`AWSCloudProvider`
+        :param provider: CloudBridge AWS provider to use
+
+        :type cb_resource: :class:`CloudResource`
+        :param cb_resource: CloudBridge Resource class to wrap results in
+
+        :type boto_conn: :class:`Boto3.Resource`
+        :param boto_conn: Boto top level service resource (e.g. EC2, S3)
+                          connection.
+
+        :type boto_collection_name: ``str``
+        :param boto_collection_name: Boto collection name that corresponds
+                                    to the CloudBridge resource (e.g. key_pair)
+        """
         self.provider = provider
         self.provider = provider
         self.cb_resource = cb_resource
         self.cb_resource = cb_resource
         self.boto_conn = boto_conn
         self.boto_conn = boto_conn
@@ -67,12 +92,12 @@ class BotoGenericService(object):
         return getattr(self.boto_conn, resource_model.name)
         return getattr(self.boto_conn, resource_model.name)
 
 
     def get(self, resource_id):
     def get(self, resource_id):
-        '''
+        """
         Returns a single resource.
         Returns a single resource.
 
 
-        :param str resource_id: ID of the boto resource to fetch
-        :returns: CloudBridge object or None
-        '''
+        :type resource_id: ``str``
+        :param resource_id: ID of the boto resource to fetch
+        """
         try:
         try:
             log.debug("Retrieving resource: %s with id: %s",
             log.debug("Retrieving resource: %s with id: %s",
                       self.boto_collection_model.name, resource_id)
                       self.boto_collection_model.name, resource_id)
@@ -90,30 +115,30 @@ class BotoGenericService(object):
                 raise e
                 raise e
 
 
     def _get_list_operation(self):
     def _get_list_operation(self):
-        '''
+        """
         This function discovers the list operation for a particular resource
         This function discovers the list operation for a particular resource
         collection. For example, given the resource collection model for
         collection. For example, given the resource collection model for
         KeyPair, it returns the list operation for it, as describe_key_pairs.
         KeyPair, it returns the list operation for it, as describe_key_pairs.
-        '''
+        """
         return xform_name(self.boto_collection_model.request.operation)
         return xform_name(self.boto_collection_model.request.operation)
 
 
     def _to_boto_resource(self, collection, params, page):
     def _to_boto_resource(self, collection, params, page):
-        '''
+        """
         This function duplicates some of the logic of the pages() method in
         This function duplicates some of the logic of the pages() method in
         boto.resources.collection.ResourceCollection. It will convert a raw
         boto.resources.collection.ResourceCollection. It will convert a raw
         json response to the corresponding Boto resource. It's necessary
         json response to the corresponding Boto resource. It's necessary
         because paginators() return json responses, and there's no direct way
         because paginators() return json responses, and there's no direct way
         to convert a paginated json response to a Boto Resource.
         to convert a paginated json response to a Boto Resource.
-        '''
+        """
         return collection._handler(collection._parent, params, page)
         return collection._handler(collection._parent, params, page)
 
 
     def _resource_iterator(self, collection, params, pages, limit):
     def _resource_iterator(self, collection, params, pages, limit):
-        '''
+        """
         Iterates through the pages of a paginated result, converting the
         Iterates through the pages of a paginated result, converting the
         objects to BotoResources as necessary. This duplicates the logic in
         objects to BotoResources as necessary. This duplicates the logic in
         boto's ResourceCollection(). pending issue:
         boto's ResourceCollection(). pending issue:
         https://github.com/boto/boto3/issues/1268
         https://github.com/boto/boto3/issues/1268
-        '''
+        """
         count = 0
         count = 0
         for page in pages:
         for page in pages:
             for item in self._to_boto_resource(collection, params, page):
             for item in self._to_boto_resource(collection, params, page):
@@ -123,12 +148,12 @@ class BotoGenericService(object):
                 yield item
                 yield item
 
 
     def _get_paginated_results(self, limit, marker, collection):
     def _get_paginated_results(self, limit, marker, collection):
-        '''
+        """
         If a Boto Paginator is available, use it. The results
         If a Boto Paginator is available, use it. The results
         are converted back into BotoResources by directly accessing
         are converted back into BotoResources by directly accessing
         protected members of ResourceCollection. This logic can be removed
         protected members of ResourceCollection. This logic can be removed
         depending on issue: https://github.com/boto/boto3/issues/1268.
         depending on issue: https://github.com/boto/boto3/issues/1268.
-        '''
+        """
         cleaned_params = collection._params.copy()
         cleaned_params = collection._params.copy()
         cleaned_params.pop('limit', None)
         cleaned_params.pop('limit', None)
         cleaned_params.pop('page_size', None)
         cleaned_params.pop('page_size', None)
@@ -153,11 +178,11 @@ class BotoGenericService(object):
         return (resume_token, items)
         return (resume_token, items)
 
 
     def _make_query(self, collection, limit, marker):
     def _make_query(self, collection, limit, marker):
-        '''
+        """
         Decide between server or client pagination,
         Decide between server or client pagination,
         depending on the availability of a Boto Paginator.
         depending on the availability of a Boto Paginator.
         See issue: https://github.com/boto/boto3/issues/1268
         See issue: https://github.com/boto/boto3/issues/1268
-        '''
+        """
         client = self.boto_conn.meta.client
         client = self.boto_conn.meta.client
         list_op = self._get_list_operation()
         list_op = self._get_list_operation()
         if client.can_paginate(list_op):
         if client.can_paginate(list_op):
@@ -190,12 +215,15 @@ class BotoGenericService(object):
                                          limit=limit, marker=marker)
                                          limit=limit, marker=marker)
 
 
     def find(self, filter_name, filter_value, limit=None, marker=None):
     def find(self, filter_name, filter_value, limit=None, marker=None):
-        '''
+        """
         Returns a list of resources by filter
         Returns a list of resources by filter
 
 
-        :param str filter_name: Name of the filter to use
-        :param str filter_value: Value to filter with
-        '''
+        :type filter_name: ``str``
+        :param filter_name: Name of the filter to use
+
+        :type filter_value: ``str``
+        :param filter_value: Value to filter with
+        """
         collection = self.boto_collection
         collection = self.boto_collection
         collection = collection.filter(Filters=[{
         collection = collection.filter(Filters=[{
             'Name': filter_name,
             'Name': filter_name,
@@ -204,13 +232,15 @@ class BotoGenericService(object):
         return self.list(limit=limit, marker=marker, collection=collection)
         return self.list(limit=limit, marker=marker, collection=collection)
 
 
     def create(self, boto_method, **kwargs):
     def create(self, boto_method, **kwargs):
-        '''
+        """
         Creates a resource
         Creates a resource
 
 
-        :param str boto_method: AWS Service method to invoke
-        :param object kwargs: Arguments to be passed as-is to
-            the service method
-        '''
+        :type boto_method: ``str``
+        :param boto_method: AWS Service method to invoke
+
+        :type kwargs: ``dict``
+        :param kwargs: Arguments to be passed as-is to the service method
+        """
         trimmed_args = trim_empty_params(kwargs)
         trimmed_args = trim_empty_params(kwargs)
         result = getattr(self.boto_conn, boto_method)(**trimmed_args)
         result = getattr(self.boto_conn, boto_method)(**trimmed_args)
         if isinstance(result, list):
         if isinstance(result, list):
@@ -220,41 +250,56 @@ class BotoGenericService(object):
             return self.cb_resource(self.provider, result) if result else None
             return self.cb_resource(self.provider, result) if result else None
 
 
     def delete(self, resource_id):
     def delete(self, resource_id):
-        '''
+        """
         Deletes a resource by id
         Deletes a resource by id
 
 
-        :param str id: ID of the resource
-        '''
+        :type resource_id: ``str``
+        :param resource_id: ID of the resource
+        """
         res = self.get(resource_id)
         res = self.get(resource_id)
         if res:
         if res:
             res.delete()
             res.delete()
 
 
 
 
 class BotoEC2Service(BotoGenericService):
 class BotoEC2Service(BotoGenericService):
-    '''
+    """
     Boto EC2 service implementation
     Boto EC2 service implementation
-
-    :param AWSCloudProvider provider: CloudBridge AWS provider
-    :param CloudResource cb_iface: CloudBridge class to wrap results in
-    :param str boto_collection_name: Boto collection name (e.g. key_pairs)
-    '''
+    """
     def __init__(self, provider, cb_resource,
     def __init__(self, provider, cb_resource,
                  boto_collection_name):
                  boto_collection_name):
+        """
+        :type provider: :class:`AWSCloudProvider`
+        :param provider: CloudBridge AWS provider to use
+
+        :type cb_resource: :class:`CloudResource`
+        :param cb_resource: CloudBridge Resource class to wrap results in
+
+        :type boto_collection_name: ``str``
+        :param boto_collection_name: Boto collection name that corresponds
+                                    to the CloudBridge resource (e.g. key_pair)
+        """
         super(BotoEC2Service, self).__init__(
         super(BotoEC2Service, self).__init__(
             provider, cb_resource, provider.ec2_conn,
             provider, cb_resource, provider.ec2_conn,
             boto_collection_name)
             boto_collection_name)
 
 
 
 
 class BotoS3Service(BotoGenericService):
 class BotoS3Service(BotoGenericService):
-    '''
+    """
     Boto S3 service implementation
     Boto S3 service implementation
-
-    :param AWSCloudProvider provider: CloudBridge AWS provider
-    :param CloudResource cb_iface: CloudBridge class to wrap results in
-    :param str boto_collection_name: Boto collection name (e.g. key_pairs)
-    '''
+    """
     def __init__(self, provider, cb_resource,
     def __init__(self, provider, cb_resource,
                  boto_collection_name):
                  boto_collection_name):
+        """
+        :type provider: :class:`AWSCloudProvider`
+        :param provider: CloudBridge AWS provider to use
+
+        :type cb_resource: :class:`CloudResource`
+        :param cb_resource: CloudBridge Resource class to wrap results in
+
+        :type boto_collection_name: ``str``
+        :param boto_collection_name: Boto collection name that corresponds
+                                    to the CloudBridge resource (e.g. key_pair)
+        """
         super(BotoS3Service, self).__init__(
         super(BotoS3Service, self).__init__(
             provider, cb_resource, provider.s3_conn,
             provider, cb_resource, provider.s3_conn,
             boto_collection_name)
             boto_collection_name)

+ 13 - 39
cloudbridge/cloud/providers/aws/resources.py

@@ -36,6 +36,7 @@ from cloudbridge.cloud.interfaces.resources import SnapshotState
 from cloudbridge.cloud.interfaces.resources import SubnetState
 from cloudbridge.cloud.interfaces.resources import SubnetState
 from cloudbridge.cloud.interfaces.resources import VolumeState
 from cloudbridge.cloud.interfaces.resources import VolumeState
 
 
+from .helpers import find_tag_value
 from .helpers import trim_empty_params
 from .helpers import trim_empty_params
 
 
 
 
@@ -214,10 +215,7 @@ class AWSInstance(BaseInstance):
         """
         """
         .. note:: an instance must have a (case sensitive) tag ``Name``
         .. note:: an instance must have a (case sensitive) tag ``Name``
         """
         """
-        for tag in self._ec2_instance.tags or []:
-            if tag.get('Key') == 'Name':
-                return tag.get('Value')
-        return None
+        return find_tag_value(self._ec2_instance.tags, 'Name')
 
 
     @name.setter
     @name.setter
     # pylint:disable=arguments-differ
     # pylint:disable=arguments-differ
@@ -333,11 +331,11 @@ class AWSInstance(BaseInstance):
         try:
         try:
             self._ec2_instance.reload()
             self._ec2_instance.reload()
         except ClientError:
         except ClientError:
-            # The volume no longer exists and cannot be refreshed.
-            # set the status to unknown
+            # The instance no longer exists and cannot be refreshed.
+            # set the state to unknown
             self._ec2_instance.state = {'Name': InstanceState.UNKNOWN}
             self._ec2_instance.state = {'Name': InstanceState.UNKNOWN}
 
 
-    def wait_till_exists(self, timeout=None, interval=None):
+    def _wait_till_exists(self, timeout=None, interval=None):
         self._ec2_instance.wait_until_exists()
         self._ec2_instance.wait_until_exists()
 
 
 
 
@@ -365,10 +363,7 @@ class AWSVolume(BaseVolume):
 
 
     @property
     @property
     def name(self):
     def name(self):
-        for tag in self._volume.tags or []:
-            if tag.get('Key') == 'Name':
-                return tag.get('Value')
-        return None
+        return find_tag_value(self._volume.tags, 'Name')
 
 
     @name.setter
     @name.setter
     # pylint:disable=arguments-differ
     # pylint:disable=arguments-differ
@@ -378,10 +373,7 @@ class AWSVolume(BaseVolume):
 
 
     @property
     @property
     def description(self):
     def description(self):
-        for tag in self._volume.tags or []:
-            if tag.get('Key') == 'Description':
-                return tag.get('Value')
-        return None
+        return find_tag_value(self._volume.tags, 'Description')
 
 
     @description.setter
     @description.setter
     def description(self, value):
     def description(self, value):
@@ -479,10 +471,7 @@ class AWSSnapshot(BaseSnapshot):
 
 
     @property
     @property
     def name(self):
     def name(self):
-        for tag in self._snapshot.tags or list():
-            if tag.get('Key') == 'Name':
-                return tag.get('Value')
-        return None
+        return find_tag_value(self._snapshot.tags, 'Name')
 
 
     @name.setter
     @name.setter
     # pylint:disable=arguments-differ
     # pylint:disable=arguments-differ
@@ -492,10 +481,7 @@ class AWSSnapshot(BaseSnapshot):
 
 
     @property
     @property
     def description(self):
     def description(self):
-        for tag in self._snapshot.tags or list():
-            if tag.get('Key') == 'Description':
-                return tag.get('Value')
-        return None
+        return find_tag_value(self._snapshot.tags, 'Description')
 
 
     @description.setter
     @description.setter
     def description(self, value):
     def description(self, value):
@@ -862,10 +848,7 @@ class AWSNetwork(BaseNetwork):
 
 
     @property
     @property
     def name(self):
     def name(self):
-        for tag in self._vpc.tags or []:
-            if tag.get('Key') == 'Name':
-                return tag.get('Value')
-        return None
+        return find_tag_value(self._vpc.tags, 'Name')
 
 
     @name.setter
     @name.setter
     # pylint:disable=arguments-differ
     # pylint:disable=arguments-differ
@@ -932,10 +915,7 @@ class AWSSubnet(BaseSubnet):
 
 
     @property
     @property
     def name(self):
     def name(self):
-        for tag in self._subnet.tags or []:
-            if tag.get('Key') == 'Name':
-                return tag.get('Value')
-        return None
+        return find_tag_value(self._subnet.tags, 'Name')
 
 
     @name.setter
     @name.setter
     # pylint:disable=arguments-differ
     # pylint:disable=arguments-differ
@@ -1014,10 +994,7 @@ class AWSRouter(BaseRouter):
 
 
     @property
     @property
     def name(self):
     def name(self):
-        for tag in self._route_table.tags or []:
-            if tag.get('Key') == 'Name':
-                return tag.get('Value')
-        return None
+        return find_tag_value(self._route_table.tags, 'Name')
 
 
     @name.setter
     @name.setter
     # pylint:disable=arguments-differ
     # pylint:disable=arguments-differ
@@ -1083,10 +1060,7 @@ class AWSInternetGateway(BaseInternetGateway):
 
 
     @property
     @property
     def name(self):
     def name(self):
-        for tag in self._gateway.tags or []:
-            if tag.get('Key') == 'Name':
-                return tag.get('Value')
-        return None
+        return find_tag_value(self._gateway.tags, 'Name')
 
 
     @name.setter
     @name.setter
     # pylint:disable=arguments-differ
     # pylint:disable=arguments-differ

+ 112 - 114
cloudbridge/cloud/providers/aws/services.py

@@ -75,50 +75,50 @@ class AWSKeyPairService(BaseKeyPairService):
 
 
     def __init__(self, provider):
     def __init__(self, provider):
         super(AWSKeyPairService, self).__init__(provider)
         super(AWSKeyPairService, self).__init__(provider)
-        self.iface = BotoEC2Service(provider=self.provider,
-                                    cb_resource=AWSKeyPair,
-                                    boto_collection_name='key_pairs')
+        self.svc = BotoEC2Service(provider=self.provider,
+                                  cb_resource=AWSKeyPair,
+                                  boto_collection_name='key_pairs')
 
 
     def get(self, key_pair_id):
     def get(self, key_pair_id):
-        return self.iface.get(key_pair_id)
+        return self.svc.get(key_pair_id)
 
 
     def list(self, limit=None, marker=None):
     def list(self, limit=None, marker=None):
-        return self.iface.list(limit=limit, marker=marker)
+        return self.svc.list(limit=limit, marker=marker)
 
 
     def find(self, name, limit=None, marker=None):
     def find(self, name, limit=None, marker=None):
-        return self.iface.find(filter_name='key-name', filter_value=name,
-                               limit=limit, marker=marker)
+        return self.svc.find(filter_name='key-name', filter_value=name,
+                             limit=limit, marker=marker)
 
 
     def create(self, name):
     def create(self, name):
         AWSKeyPair.assert_valid_resource_name(name)
         AWSKeyPair.assert_valid_resource_name(name)
-        return self.iface.create('create_key_pair', KeyName=name)
+        return self.svc.create('create_key_pair', KeyName=name)
 
 
 
 
 class AWSSecurityGroupService(BaseSecurityGroupService):
 class AWSSecurityGroupService(BaseSecurityGroupService):
 
 
     def __init__(self, provider):
     def __init__(self, provider):
         super(AWSSecurityGroupService, self).__init__(provider)
         super(AWSSecurityGroupService, self).__init__(provider)
-        self.iface = BotoEC2Service(provider=self.provider,
-                                    cb_resource=AWSSecurityGroup,
-                                    boto_collection_name='security_groups')
+        self.svc = BotoEC2Service(provider=self.provider,
+                                  cb_resource=AWSSecurityGroup,
+                                  boto_collection_name='security_groups')
 
 
     def get(self, sg_id):
     def get(self, sg_id):
-        return self.iface.get(sg_id)
+        return self.svc.get(sg_id)
 
 
     def list(self, limit=None, marker=None):
     def list(self, limit=None, marker=None):
-        return self.iface.list(limit=limit, marker=marker)
+        return self.svc.list(limit=limit, marker=marker)
 
 
     def create(self, name, description, network_id):
     def create(self, name, description, network_id):
         AWSSecurityGroup.assert_valid_resource_name(name)
         AWSSecurityGroup.assert_valid_resource_name(name)
-        return self.iface.create('create_security_group', GroupName=name,
-                                 Description=description, VpcId=network_id)
+        return self.svc.create('create_security_group', GroupName=name,
+                               Description=description, VpcId=network_id)
 
 
     def find(self, name, limit=None, marker=None):
     def find(self, name, limit=None, marker=None):
-        return self.iface.find(filter_name='group-name', filter_value=name,
-                               limit=limit, marker=marker)
+        return self.svc.find(filter_name='group-name', filter_value=name,
+                             limit=limit, marker=marker)
 
 
     def delete(self, group_id):
     def delete(self, group_id):
-        sg = self.iface.get(group_id)
+        sg = self.svc.get(group_id)
         if sg:
         if sg:
             sg.delete()
             sg.delete()
 
 
@@ -145,19 +145,19 @@ class AWSVolumeService(BaseVolumeService):
 
 
     def __init__(self, provider):
     def __init__(self, provider):
         super(AWSVolumeService, self).__init__(provider)
         super(AWSVolumeService, self).__init__(provider)
-        self.iface = BotoEC2Service(provider=self.provider,
-                                    cb_resource=AWSVolume,
-                                    boto_collection_name='volumes')
+        self.svc = BotoEC2Service(provider=self.provider,
+                                  cb_resource=AWSVolume,
+                                  boto_collection_name='volumes')
 
 
     def get(self, volume_id):
     def get(self, volume_id):
-        return self.iface.get(volume_id)
+        return self.svc.get(volume_id)
 
 
     def find(self, name, limit=None, marker=None):
     def find(self, name, limit=None, marker=None):
-        return self.iface.find(filter_name='tag:Name', filter_value=name,
-                               limit=limit, marker=marker)
+        return self.svc.find(filter_name='tag:Name', filter_value=name,
+                             limit=limit, marker=marker)
 
 
     def list(self, limit=None, marker=None):
     def list(self, limit=None, marker=None):
-        return self.iface.list(limit=limit, marker=marker)
+        return self.svc.list(limit=limit, marker=marker)
 
 
     def create(self, name, size, zone, snapshot=None, description=None):
     def create(self, name, size, zone, snapshot=None, description=None):
         AWSVolume.assert_valid_resource_name(name)
         AWSVolume.assert_valid_resource_name(name)
@@ -166,9 +166,9 @@ class AWSVolumeService(BaseVolumeService):
         snapshot_id = snapshot.id if isinstance(
         snapshot_id = snapshot.id if isinstance(
             snapshot, AWSSnapshot) and snapshot else snapshot
             snapshot, AWSSnapshot) and snapshot else snapshot
 
 
-        cb_vol = self.iface.create('create_volume', Size=size,
-                                   AvailabilityZone=zone_id,
-                                   SnapshotId=snapshot_id)
+        cb_vol = self.svc.create('create_volume', Size=size,
+                                 AvailabilityZone=zone_id,
+                                 SnapshotId=snapshot_id)
         # Wait until ready to tag instance
         # Wait until ready to tag instance
         cb_vol.wait_till_ready()
         cb_vol.wait_till_ready()
         cb_vol.name = name
         cb_vol.name = name
@@ -181,19 +181,19 @@ class AWSSnapshotService(BaseSnapshotService):
 
 
     def __init__(self, provider):
     def __init__(self, provider):
         super(AWSSnapshotService, self).__init__(provider)
         super(AWSSnapshotService, self).__init__(provider)
-        self.iface = BotoEC2Service(provider=self.provider,
-                                    cb_resource=AWSSnapshot,
-                                    boto_collection_name='snapshots')
+        self.svc = BotoEC2Service(provider=self.provider,
+                                  cb_resource=AWSSnapshot,
+                                  boto_collection_name='snapshots')
 
 
     def get(self, snapshot_id):
     def get(self, snapshot_id):
-        return self.iface.get(snapshot_id)
+        return self.svc.get(snapshot_id)
 
 
     def find(self, name, limit=None, marker=None):
     def find(self, name, limit=None, marker=None):
-        return self.iface.find(filter_name='tag:Name', filter_value=name,
-                               limit=limit, marker=marker)
+        return self.svc.find(filter_name='tag:Name', filter_value=name,
+                             limit=limit, marker=marker)
 
 
     def list(self, limit=None, marker=None):
     def list(self, limit=None, marker=None):
-        return self.iface.list(limit=limit, marker=marker)
+        return self.svc.list(limit=limit, marker=marker)
 
 
     def create(self, name, volume, description=None):
     def create(self, name, volume, description=None):
         """
         """
@@ -203,8 +203,7 @@ class AWSSnapshotService(BaseSnapshotService):
 
 
         volume_id = volume.id if isinstance(volume, AWSVolume) else volume
         volume_id = volume.id if isinstance(volume, AWSVolume) else volume
 
 
-        cb_snap = self.iface.create('create_snapshot',
-                                    VolumeId=volume_id)
+        cb_snap = self.svc.create('create_snapshot', VolumeId=volume_id)
         # Wait until ready to tag instance
         # Wait until ready to tag instance
         cb_snap.wait_till_ready()
         cb_snap.wait_till_ready()
         cb_snap.name = name
         cb_snap.name = name
@@ -217,9 +216,9 @@ class AWSObjectStoreService(BaseObjectStoreService):
 
 
     def __init__(self, provider):
     def __init__(self, provider):
         super(AWSObjectStoreService, self).__init__(provider)
         super(AWSObjectStoreService, self).__init__(provider)
-        self.iface = BotoS3Service(provider=self.provider,
-                                   cb_resource=AWSBucket,
-                                   boto_collection_name='buckets')
+        self.svc = BotoS3Service(provider=self.provider,
+                                 cb_resource=AWSBucket,
+                                 boto_collection_name='buckets')
 
 
     def get(self, bucket_id):
     def get(self, bucket_id):
         """
         """
@@ -255,7 +254,7 @@ class AWSObjectStoreService(BaseObjectStoreService):
                                      limit=limit, marker=marker)
                                      limit=limit, marker=marker)
 
 
     def list(self, limit=None, marker=None):
     def list(self, limit=None, marker=None):
-        return self.iface.list(limit=limit, marker=marker)
+        return self.svc.list(limit=limit, marker=marker)
 
 
     def create(self, name, location=None):
     def create(self, name, location=None):
         AWSBucket.assert_valid_resource_name(name)
         AWSBucket.assert_valid_resource_name(name)
@@ -265,31 +264,31 @@ class AWSObjectStoreService(BaseObjectStoreService):
         # Therefore, it must be special-cased and omitted altogether.
         # Therefore, it must be special-cased and omitted altogether.
         # See: https://github.com/boto/boto3/issues/125
         # See: https://github.com/boto/boto3/issues/125
         if loc_constraint == 'us-east-1':
         if loc_constraint == 'us-east-1':
-            return self.iface.create('create_bucket', Bucket=name)
+            return self.svc.create('create_bucket', Bucket=name)
         else:
         else:
-            return self.iface.create('create_bucket', Bucket=name,
-                                     CreateBucketConfiguration={
-                                         'LocationConstraint': loc_constraint
-                                     })
+            return self.svc.create('create_bucket', Bucket=name,
+                                   CreateBucketConfiguration={
+                                       'LocationConstraint': loc_constraint
+                                    })
 
 
 
 
 class AWSImageService(BaseImageService):
 class AWSImageService(BaseImageService):
 
 
     def __init__(self, provider):
     def __init__(self, provider):
         super(AWSImageService, self).__init__(provider)
         super(AWSImageService, self).__init__(provider)
-        self.iface = BotoEC2Service(provider=self.provider,
-                                    cb_resource=AWSMachineImage,
-                                    boto_collection_name='images')
+        self.svc = BotoEC2Service(provider=self.provider,
+                                  cb_resource=AWSMachineImage,
+                                  boto_collection_name='images')
 
 
     def get(self, image_id):
     def get(self, image_id):
-        return self.iface.get(image_id)
+        return self.svc.get(image_id)
 
 
     def find(self, name, limit=None, marker=None):
     def find(self, name, limit=None, marker=None):
-        return self.iface.find(filter_name='name', filter_value=name,
-                               limit=limit, marker=marker)
+        return self.svc.find(filter_name='name', filter_value=name,
+                             limit=limit, marker=marker)
 
 
     def list(self, limit=None, marker=None):
     def list(self, limit=None, marker=None):
-        return self.iface.list(limit=limit, marker=marker)
+        return self.svc.list(limit=limit, marker=marker)
 
 
 
 
 class AWSComputeService(BaseComputeService):
 class AWSComputeService(BaseComputeService):
@@ -322,9 +321,9 @@ class AWSInstanceService(BaseInstanceService):
 
 
     def __init__(self, provider):
     def __init__(self, provider):
         super(AWSInstanceService, self).__init__(provider)
         super(AWSInstanceService, self).__init__(provider)
-        self.iface = BotoEC2Service(provider=self.provider,
-                                    cb_resource=AWSInstance,
-                                    boto_collection_name='instances')
+        self.svc = BotoEC2Service(provider=self.provider,
+                                  cb_resource=AWSInstance,
+                                  boto_collection_name='instances')
 
 
     def create(self, name, image, instance_type, subnet, zone=None,
     def create(self, name, image, instance_type, subnet, zone=None,
                key_pair=None, security_groups=None, user_data=None,
                key_pair=None, security_groups=None, user_data=None,
@@ -349,21 +348,21 @@ class AWSInstanceService(BaseInstanceService):
             self._resolve_launch_options(subnet, zone_id, security_groups)
             self._resolve_launch_options(subnet, zone_id, security_groups)
 
 
         placement = {'AvailabilityZone': zone_id} if zone_id else None
         placement = {'AvailabilityZone': zone_id} if zone_id else None
-        inst = self.iface.create('create_instances',
-                                 ImageId=image_id,
-                                 MinCount=1,
-                                 MaxCount=1,
-                                 KeyName=key_pair_name,
-                                 SecurityGroupIds=security_group_ids or None,
-                                 UserData=user_data,
-                                 InstanceType=instance_size,
-                                 Placement=placement,
-                                 BlockDeviceMappings=bdm,
-                                 SubnetId=subnet_id
-                                 )
+        inst = self.svc.create('create_instances',
+                               ImageId=image_id,
+                               MinCount=1,
+                               MaxCount=1,
+                               KeyName=key_pair_name,
+                               SecurityGroupIds=security_group_ids or None,
+                               UserData=user_data,
+                               InstanceType=instance_size,
+                               Placement=placement,
+                               BlockDeviceMappings=bdm,
+                               SubnetId=subnet_id
+                               )
         if inst and len(inst) == 1:
         if inst and len(inst) == 1:
             # Wait until the resource exists
             # Wait until the resource exists
-            inst[0].wait_till_exists()
+            inst[0]._wait_till_exists()
             # Tag the instance w/ the name
             # Tag the instance w/ the name
             inst[0].name = name
             inst[0].name = name
             return inst[0]
             return inst[0]
@@ -455,14 +454,14 @@ class AWSInstanceService(BaseInstanceService):
         return AWSLaunchConfig(self.provider)
         return AWSLaunchConfig(self.provider)
 
 
     def get(self, instance_id):
     def get(self, instance_id):
-        return self.iface.get(instance_id)
+        return self.svc.get(instance_id)
 
 
     def find(self, name, limit=None, marker=None):
     def find(self, name, limit=None, marker=None):
-        return self.iface.find(filter_name='tag:Name', filter_value=name,
-                               limit=limit, marker=marker)
+        return self.svc.find(filter_name='tag:Name', filter_value=name,
+                             limit=limit, marker=marker)
 
 
     def list(self, limit=None, marker=None):
     def list(self, limit=None, marker=None):
-        return self.iface.list(limit=limit, marker=marker)
+        return self.svc.list(limit=limit, marker=marker)
 
 
 
 
 class AWSInstanceTypesService(BaseInstanceTypesService):
 class AWSInstanceTypesService(BaseInstanceTypesService):
@@ -551,24 +550,24 @@ class AWSNetworkService(BaseNetworkService):
 
 
     def __init__(self, provider):
     def __init__(self, provider):
         super(AWSNetworkService, self).__init__(provider)
         super(AWSNetworkService, self).__init__(provider)
-        self.iface = BotoEC2Service(provider=self.provider,
-                                    cb_resource=AWSNetwork,
-                                    boto_collection_name='vpcs')
+        self.svc = BotoEC2Service(provider=self.provider,
+                                  cb_resource=AWSNetwork,
+                                  boto_collection_name='vpcs')
 
 
     def get(self, network_id):
     def get(self, network_id):
-        return self.iface.get(network_id)
+        return self.svc.get(network_id)
 
 
     def list(self, limit=None, marker=None):
     def list(self, limit=None, marker=None):
-        return self.iface.list(limit=limit, marker=marker)
+        return self.svc.list(limit=limit, marker=marker)
 
 
     def find(self, name, limit=None, marker=None):
     def find(self, name, limit=None, marker=None):
-        return self.iface.find(filter_name='tag:Name', filter_value=name,
-                               limit=limit, marker=marker)
+        return self.svc.find(filter_name='tag:Name', filter_value=name,
+                             limit=limit, marker=marker)
 
 
     def create(self, name, cidr_block):
     def create(self, name, cidr_block):
         AWSNetwork.assert_valid_resource_name(name)
         AWSNetwork.assert_valid_resource_name(name)
 
 
-        cb_net = self.iface.create('create_vpc', CidrBlock=cidr_block)
+        cb_net = self.svc.create('create_vpc', CidrBlock=cidr_block)
         # Wait until ready to tag instance
         # Wait until ready to tag instance
         cb_net.wait_till_ready()
         cb_net.wait_till_ready()
         if name:
         if name:
@@ -577,10 +576,10 @@ class AWSNetworkService(BaseNetworkService):
 
 
     @property
     @property
     def floating_ips(self):
     def floating_ips(self):
-        self.iface_fip = BotoEC2Service(provider=self.provider,
-                                        cb_resource=AWSFloatingIP,
-                                        boto_collection_name='vpc_addresses')
-        return self.iface_fip.list()
+        self.svc_fip = BotoEC2Service(provider=self.provider,
+                                      cb_resource=AWSFloatingIP,
+                                      boto_collection_name='vpc_addresses')
+        return self.svc_fip.list()
 
 
     def create_floating_ip(self):
     def create_floating_ip(self):
         ip = self.provider.ec2_conn.meta.client.allocate_address(
         ip = self.provider.ec2_conn.meta.client.allocate_address(
@@ -594,44 +593,44 @@ class AWSSubnetService(BaseSubnetService):
 
 
     def __init__(self, provider):
     def __init__(self, provider):
         super(AWSSubnetService, self).__init__(provider)
         super(AWSSubnetService, self).__init__(provider)
-        self.iface = BotoEC2Service(provider=self.provider,
-                                    cb_resource=AWSSubnet,
-                                    boto_collection_name='subnets')
+        self.svc = BotoEC2Service(provider=self.provider,
+                                  cb_resource=AWSSubnet,
+                                  boto_collection_name='subnets')
 
 
     def get(self, subnet_id):
     def get(self, subnet_id):
-        return self.iface.get(subnet_id)
+        return self.svc.get(subnet_id)
 
 
     def list(self, network=None, limit=None, marker=None):
     def list(self, network=None, limit=None, marker=None):
         network_id = network.id if isinstance(network, AWSNetwork) else network
         network_id = network.id if isinstance(network, AWSNetwork) else network
         if network_id:
         if network_id:
-            return self.iface.find(
+            return self.svc.find(
                 filter_name='VpcId', filter_value=network_id,
                 filter_name='VpcId', filter_value=network_id,
                 limit=limit, marker=marker)
                 limit=limit, marker=marker)
         else:
         else:
-            return self.iface.list(limit=limit, marker=marker)
+            return self.svc.list(limit=limit, marker=marker)
 
 
     def find(self, name, limit=None, marker=None):
     def find(self, name, limit=None, marker=None):
-        return self.iface.find(filter_name='tag:Name', filter_value=name,
-                               limit=limit, marker=marker)
+        return self.svc.find(filter_name='tag:Name', filter_value=name,
+                             limit=limit, marker=marker)
 
 
     def create(self, name, network, cidr_block, zone=None):
     def create(self, name, network, cidr_block, zone=None):
         AWSSubnet.assert_valid_resource_name(name)
         AWSSubnet.assert_valid_resource_name(name)
 
 
         network_id = network.id if isinstance(network, AWSNetwork) else network
         network_id = network.id if isinstance(network, AWSNetwork) else network
 
 
-        subnet = self.iface.create('create_subnet',
-                                   VpcId=network_id,
-                                   CidrBlock=cidr_block,
-                                   AvailabilityZone=zone)
+        subnet = self.svc.create('create_subnet',
+                                 VpcId=network_id,
+                                 CidrBlock=cidr_block,
+                                 AvailabilityZone=zone)
         if name:
         if name:
             subnet.name = name
             subnet.name = name
         return subnet
         return subnet
 
 
     def get_or_create_default(self, zone=None):
     def get_or_create_default(self, zone=None):
         if zone:
         if zone:
-            snl = self.iface.find('availabilityZone', zone)
+            snl = self.svc.find('availabilityZone', zone)
         else:
         else:
-            snl = self.iface.list()
+            snl = self.svc.list()
         for sn in snl:
         for sn in snl:
             # pylint:disable=protected-access
             # pylint:disable=protected-access
             if sn._subnet.default_for_az:
             if sn._subnet.default_for_az:
@@ -661,7 +660,7 @@ class AWSSubnetService(BaseSubnetService):
 
 
     def delete(self, subnet):
     def delete(self, subnet):
         subnet_id = subnet.id if isinstance(subnet, AWSSubnet) else subnet
         subnet_id = subnet.id if isinstance(subnet, AWSSubnet) else subnet
-        return self.iface.delete(subnet_id)
+        return self.svc.delete(subnet_id)
 
 
 
 
 class AWSRouterService(BaseRouterService):
 class AWSRouterService(BaseRouterService):
@@ -669,26 +668,26 @@ class AWSRouterService(BaseRouterService):
 
 
     def __init__(self, provider):
     def __init__(self, provider):
         super(AWSRouterService, self).__init__(provider)
         super(AWSRouterService, self).__init__(provider)
-        self.iface = BotoEC2Service(provider=self.provider,
-                                    cb_resource=AWSRouter,
-                                    boto_collection_name='route_tables')
+        self.svc = BotoEC2Service(provider=self.provider,
+                                  cb_resource=AWSRouter,
+                                  boto_collection_name='route_tables')
 
 
     def get(self, router_id):
     def get(self, router_id):
-        return self.iface.get(router_id)
+        return self.svc.get(router_id)
 
 
     def find(self, name, limit=None, marker=None):
     def find(self, name, limit=None, marker=None):
-        return self.iface.find(filter_name='tag:Name', filter_value=name,
-                               limit=limit, marker=marker)
+        return self.svc.find(filter_name='tag:Name', filter_value=name,
+                             limit=limit, marker=marker)
 
 
     def list(self, limit=None, marker=None):
     def list(self, limit=None, marker=None):
-        return self.iface.list(limit=limit, marker=marker)
+        return self.svc.list(limit=limit, marker=marker)
 
 
     def create(self, name, network):
     def create(self, name, network):
         AWSRouter.assert_valid_resource_name(name)
         AWSRouter.assert_valid_resource_name(name)
 
 
         network_id = network.id if isinstance(network, AWSNetwork) else network
         network_id = network.id if isinstance(network, AWSNetwork) else network
 
 
-        cb_router = self.iface.create('create_route_table', VpcId=network_id)
+        cb_router = self.svc.create('create_route_table', VpcId=network_id)
         if name:
         if name:
             cb_router.name = name
             cb_router.name = name
         return cb_router
         return cb_router
@@ -698,19 +697,18 @@ class AWSGatewayService(BaseGatewayService):
 
 
     def __init__(self, provider):
     def __init__(self, provider):
         super(AWSGatewayService, self).__init__(provider)
         super(AWSGatewayService, self).__init__(provider)
-        self.iface = BotoEC2Service(provider=self.provider,
-                                    cb_resource=AWSInternetGateway,
-                                    boto_collection_name='internet_gateways')
+        self.svc = BotoEC2Service(provider=self.provider,
+                                  cb_resource=AWSInternetGateway,
+                                  boto_collection_name='internet_gateways')
 
 
     def get_or_create_inet_gateway(self, name):
     def get_or_create_inet_gateway(self, name):
         AWSInternetGateway.assert_valid_resource_name(name)
         AWSInternetGateway.assert_valid_resource_name(name)
 
 
-        cb_gateway = self.iface.create('create_internet_gateway')
-        # self.iface_igws.wait_for_create(cb_gateway.id, 'internet-gateway-id')
+        cb_gateway = self.svc.create('create_internet_gateway')
         cb_gateway.name = name
         cb_gateway.name = name
         return cb_gateway
         return cb_gateway
 
 
     def delete(self, gateway_id):
     def delete(self, gateway_id):
-        gateway = self.iface.get(gateway_id)
+        gateway = self.svc.get(gateway_id)
         if gateway:
         if gateway:
             gateway.delete()
             gateway.delete()