almahmoud пре 7 година
родитељ
комит
1109a8d560

+ 23 - 10
cloudbridge/cloud/providers/aws/resources.py

@@ -234,6 +234,7 @@ class AWSInstance(BaseInstance):
     def __init__(self, provider, ec2_instance):
     def __init__(self, provider, ec2_instance):
         super(AWSInstance, self).__init__(provider)
         super(AWSInstance, self).__init__(provider)
         self._ec2_instance = ec2_instance
         self._ec2_instance = ec2_instance
+        self._unknown_state = False
 
 
     @property
     @property
     def id(self):
     def id(self):
@@ -368,6 +369,8 @@ class AWSInstance(BaseInstance):
 
 
     @property
     @property
     def state(self):
     def state(self):
+        if self._unknown_state:
+            return InstanceState.UNKNOWN
         try:
         try:
             return AWSInstance.INSTANCE_STATE_MAP.get(
             return AWSInstance.INSTANCE_STATE_MAP.get(
                 self._ec2_instance.state['Name'], InstanceState.UNKNOWN)
                 self._ec2_instance.state['Name'], InstanceState.UNKNOWN)
@@ -381,7 +384,7 @@ class AWSInstance(BaseInstance):
         except ClientError:
         except ClientError:
             # The instance no longer exists and cannot be refreshed.
             # The instance no longer exists and cannot be refreshed.
             # set the state to unknown
             # set the state to unknown
-            self._ec2_instance.state = {'Name': InstanceState.UNKNOWN}
+            self._unknown_state = True
 
 
     # pylint:disable=unused-argument
     # pylint:disable=unused-argument
     def _wait_till_exists(self, timeout=None, interval=None):
     def _wait_till_exists(self, timeout=None, interval=None):
@@ -405,6 +408,7 @@ class AWSVolume(BaseVolume):
     def __init__(self, provider, volume):
     def __init__(self, provider, volume):
         super(AWSVolume, self).__init__(provider)
         super(AWSVolume, self).__init__(provider)
         self._volume = volume
         self._volume = volume
+        self._unknown_state = False
 
 
     @property
     @property
     def id(self):
     def id(self):
@@ -497,6 +501,8 @@ class AWSVolume(BaseVolume):
 
 
     @property
     @property
     def state(self):
     def state(self):
+        if self._unknown_state:
+            return VolumeState.UNKNOWN
         try:
         try:
             return AWSVolume.VOLUME_STATE_MAP.get(
             return AWSVolume.VOLUME_STATE_MAP.get(
                 self._volume.state, VolumeState.UNKNOWN)
                 self._volume.state, VolumeState.UNKNOWN)
@@ -510,7 +516,7 @@ class AWSVolume(BaseVolume):
         except ClientError:
         except ClientError:
             # The volume no longer exists and cannot be refreshed.
             # The volume no longer exists and cannot be refreshed.
             # set the status to unknown
             # set the status to unknown
-            self._volume.state = VolumeState.UNKNOWN
+            self._unknown_state = True
 
 
 
 
 class AWSSnapshot(BaseSnapshot):
 class AWSSnapshot(BaseSnapshot):
@@ -527,6 +533,7 @@ class AWSSnapshot(BaseSnapshot):
     def __init__(self, provider, snapshot):
     def __init__(self, provider, snapshot):
         super(AWSSnapshot, self).__init__(provider)
         super(AWSSnapshot, self).__init__(provider)
         self._snapshot = snapshot
         self._snapshot = snapshot
+        self._unknown_state = False
 
 
     @property
     @property
     def id(self):
     def id(self):
@@ -574,6 +581,8 @@ class AWSSnapshot(BaseSnapshot):
 
 
     @property
     @property
     def state(self):
     def state(self):
+        if self._unknown_state:
+            return SnapshotState.UNKNOWN
         try:
         try:
             return AWSSnapshot.SNAPSHOT_STATE_MAP.get(
             return AWSSnapshot.SNAPSHOT_STATE_MAP.get(
                 self._snapshot.state, SnapshotState.UNKNOWN)
                 self._snapshot.state, SnapshotState.UNKNOWN)
@@ -587,7 +596,7 @@ class AWSSnapshot(BaseSnapshot):
         except ClientError:
         except ClientError:
             # The snapshot no longer exists and cannot be refreshed.
             # The snapshot no longer exists and cannot be refreshed.
             # set the status to unknown
             # set the status to unknown
-            self._snapshot.state = SnapshotState.UNKNOWN
+            self._unknown_state = True
 
 
     def delete(self):
     def delete(self):
         self._snapshot.delete()
         self._snapshot.delete()
@@ -962,6 +971,7 @@ class AWSNetwork(BaseNetwork):
         super(AWSNetwork, self).__init__(provider)
         super(AWSNetwork, self).__init__(provider)
         self._vpc = network
         self._vpc = network
         self._gtw_container = AWSGatewayContainer(provider, self)
         self._gtw_container = AWSGatewayContainer(provider, self)
+        self._unknown_state = False
 
 
     @property
     @property
     def id(self):
     def id(self):
@@ -991,6 +1001,8 @@ class AWSNetwork(BaseNetwork):
 
 
     @property
     @property
     def state(self):
     def state(self):
+        if self._unknown_state:
+            return NetworkState.UNKNOWN
         try:
         try:
             return AWSNetwork._NETWORK_STATE_MAP.get(
             return AWSNetwork._NETWORK_STATE_MAP.get(
                 self._vpc.state, NetworkState.UNKNOWN)
                 self._vpc.state, NetworkState.UNKNOWN)
@@ -1015,7 +1027,7 @@ class AWSNetwork(BaseNetwork):
         except ClientError:
         except ClientError:
             # The network no longer exists and cannot be refreshed.
             # The network no longer exists and cannot be refreshed.
             # set the status to unknown
             # set the status to unknown
-            self._vpc.state = NetworkState.UNKNOWN
+            self._unknown_state = True
 
 
     def wait_till_ready(self, timeout=None, interval=None):
     def wait_till_ready(self, timeout=None, interval=None):
         self._provider.ec2_conn.meta.client.get_waiter('vpc_available').wait(
         self._provider.ec2_conn.meta.client.get_waiter('vpc_available').wait(
@@ -1038,6 +1050,7 @@ class AWSSubnet(BaseSubnet):
     def __init__(self, provider, subnet):
     def __init__(self, provider, subnet):
         super(AWSSubnet, self).__init__(provider)
         super(AWSSubnet, self).__init__(provider)
         self._subnet = subnet
         self._subnet = subnet
+        self._unknown_state = False
 
 
     @property
     @property
     def id(self):
     def id(self):
@@ -1075,6 +1088,8 @@ class AWSSubnet(BaseSubnet):
 
 
     @property
     @property
     def state(self):
     def state(self):
+        if self._unknown_state:
+            return SubnetState.UNKNOWN
         try:
         try:
             return self._SUBNET_STATE_MAP.get(
             return self._SUBNET_STATE_MAP.get(
                 self._subnet.state, SubnetState.UNKNOWN)
                 self._subnet.state, SubnetState.UNKNOWN)
@@ -1083,13 +1098,11 @@ class AWSSubnet(BaseSubnet):
             return SubnetState.UNKNOWN
             return SubnetState.UNKNOWN
 
 
     def refresh(self):
     def refresh(self):
-        subnet = self._provider.networking.subnets.get(self.id)
-        if subnet:
-            # pylint:disable=protected-access
-            self._subnet = subnet._subnet
-        else:
+        try:
+            self._subnet.reload()
+        except ClientError:
             # subnet no longer exists
             # subnet no longer exists
-            self._subnet.state = SubnetState.UNKNOWN
+            self._unknown_state = True
 
 
 
 
 class AWSFloatingIPContainer(BaseFloatingIPContainer):
 class AWSFloatingIPContainer(BaseFloatingIPContainer):

+ 20 - 12
cloudbridge/cloud/providers/aws/services.py

@@ -141,7 +141,6 @@ class AWSVMFirewallService(BaseVMFirewallService):
         obj = self.svc.create('create_security_group', GroupName=name,
         obj = self.svc.create('create_security_group', GroupName=name,
                               Description=description or name,
                               Description=description or name,
                               VpcId=network_id)
                               VpcId=network_id)
-        obj.wait_till_ready()
         obj.label = label
         obj.label = label
         return obj
         return obj
 
 
@@ -739,12 +738,15 @@ class AWSSubnetService(BaseSubnetService):
                   label, network, cidr_block, zone)
                   label, network, cidr_block, zone)
         AWSSubnet.assert_valid_resource_label(label)
         AWSSubnet.assert_valid_resource_label(label)
 
 
+        zone_name = zone.name if isinstance(
+            zone, AWSPlacementZone) else zone
+
         network_id = network.id if isinstance(network, AWSNetwork) else network
         network_id = network.id if isinstance(network, AWSNetwork) else network
 
 
         subnet = self.svc.create('create_subnet',
         subnet = self.svc.create('create_subnet',
                                  VpcId=network_id,
                                  VpcId=network_id,
                                  CidrBlock=cidr_block,
                                  CidrBlock=cidr_block,
-                                 AvailabilityZone=zone)
+                                 AvailabilityZone=zone_name)
         if label:
         if label:
             subnet.label = label
             subnet.label = label
         return subnet
         return subnet
@@ -764,17 +766,23 @@ class AWSSubnetService(BaseSubnetService):
             # pylint:disable=protected-access
             # pylint:disable=protected-access
             if sn._subnet.default_for_az:
             if sn._subnet.default_for_az:
                 return sn
                 return sn
-        # No provider-default Subnet exists, look for a library-default one
-        for sn in snl:
-            # pylint:disable=protected-access
-            for tag in sn._subnet.tags or {}:
-                if (tag.get('Key') == 'Name' and
-                        tag.get('Value') == AWSSubnet.CB_DEFAULT_SUBNET_LABEL):
-                    return sn
+
+        # Refresh the list for the default label
+        snl = self.find(label=AWSSubnet.CB_DEFAULT_SUBNET_LABEL)
+
+        if len(snl) > 0:
+            return snl[0]
+
         # No provider-default Subnet exists, try to create it (net + subnets)
         # No provider-default Subnet exists, try to create it (net + subnets)
-        default_net = self.provider.networking.networks.create(
-            label=AWSNetwork.CB_DEFAULT_NETWORK_LABEL,
-            cidr_block='10.0.0.0/16')
+        # Check if default net exists
+        default_nets = self.provider.networking.networks.find(
+            label=AWSNetwork.CB_DEFAULT_NETWORK_LABEL)
+        if len(default_nets) > 0:
+            default_net = default_nets[0]
+        else:
+            default_net = self.provider.networking.networks.create(
+                label=AWSNetwork.CB_DEFAULT_NETWORK_LABEL,
+                cidr_block='10.0.0.0/16')
         # Create a subnet in each of the region's zones
         # Create a subnet in each of the region's zones
         region = self.provider.compute.regions.get(self.provider.region_name)
         region = self.provider.compute.regions.get(self.provider.region_name)
         default_sn = None
         default_sn = None

+ 4 - 4
test/helpers/standard_interface_tests.py

@@ -41,9 +41,9 @@ def check_obj_properties(test, obj):
     check_obj_label(test, obj)
     check_obj_label(test, obj)
 
 
 
 
-@tenacity.retry(stop=tenacity.stop_after_attempt(3),
+@tenacity.retry(stop=tenacity.stop_after_attempt(10),
                 retry=tenacity.retry_if_exception_type(AssertionError),
                 retry=tenacity.retry_if_exception_type(AssertionError),
-                wait=tenacity.wait_fixed(5),
+                wait=tenacity.wait_fixed(10),
                 reraise=True)
                 reraise=True)
 def check_list(test, service, obj):
 def check_list(test, service, obj):
     list_objs = service.list()
     list_objs = service.list()
@@ -118,9 +118,9 @@ def check_get_non_existent(test, service):
         % (type(service).__name__, get_objs))
         % (type(service).__name__, get_objs))
 
 
 
 
-@tenacity.retry(stop=tenacity.stop_after_attempt(3),
+@tenacity.retry(stop=tenacity.stop_after_attempt(10),
                 retry=tenacity.retry_if_exception_type(AssertionError),
                 retry=tenacity.retry_if_exception_type(AssertionError),
-                wait=tenacity.wait_fixed(5),
+                wait=tenacity.wait_fixed(10),
                 reraise=True)
                 reraise=True)
 def check_delete(test, service, obj, perform_delete=False):
 def check_delete(test, service, obj, perform_delete=False):
     if perform_delete:
     if perform_delete:

+ 6 - 12
test/test_network_service.py

@@ -87,7 +87,8 @@ class CloudNetworkServiceTestCase(ProviderTestBase):
     def test_crud_subnet(self):
     def test_crud_subnet(self):
         # Late binding will make sure that create_subnet gets the
         # Late binding will make sure that create_subnet gets the
         # correct value
         # correct value
-        net = None
+        sn = helpers.get_or_create_default_subnet(self.provider)
+        net = sn.network
 
 
         def create_subnet(label):
         def create_subnet(label):
             return self.provider.networking.subnets.create(
             return self.provider.networking.subnets.create(
@@ -99,15 +100,8 @@ class CloudNetworkServiceTestCase(ProviderTestBase):
             if subnet:
             if subnet:
                 self.provider.networking.subnets.delete(subnet=subnet)
                 self.provider.networking.subnets.delete(subnet=subnet)
 
 
-        net_label = 'cb-crudsubnet-{0}'.format(helpers.get_uuid())
-        net = self.provider.networking.networks.create(
-            label=net_label, cidr_block='10.0.0.0/16')
-        with helpers.cleanup_action(
-            lambda:
-                self.provider.networking.networks.delete(network_id=net.id)
-        ):
-            sit.check_crud(self, self.provider.networking.subnets, Subnet,
-                           "cb-crudsubnet", create_subnet, cleanup_subnet)
+        sit.check_crud(self, self.provider.networking.subnets, Subnet,
+                       "cb-crudsubnet", create_subnet, cleanup_subnet)
 
 
     def test_crud_floating_ip(self):
     def test_crud_floating_ip(self):
         gw = helpers.get_test_gateway(
         gw = helpers.get_test_gateway(
@@ -155,8 +149,8 @@ class CloudNetworkServiceTestCase(ProviderTestBase):
     def test_crud_router(self):
     def test_crud_router(self):
 
 
         def _cleanup(net, subnet, router, gateway):
         def _cleanup(net, subnet, router, gateway):
-            with helpers.cleanup_action(lambda: router.delete()):
-                with helpers.cleanup_action(lambda: net.delete()):
+            with helpers.cleanup_action(lambda: net.delete()):
+                with helpers.cleanup_action(lambda: router.delete()):
                     with helpers.cleanup_action(lambda: subnet.delete()):
                     with helpers.cleanup_action(lambda: subnet.delete()):
                         with helpers.cleanup_action(lambda: gateway.delete()):
                         with helpers.cleanup_action(lambda: gateway.delete()):
                             router.detach_subnet(subnet)
                             router.detach_subnet(subnet)