Pārlūkot izejas kodu

Add subnet_id property to Instance object.

Resolves #92
Enis Afgan 7 gadi atpakaļ
vecāks
revīzija
6bc54d2936

+ 10 - 0
cloudbridge/cloud/interfaces/resources.py

@@ -528,6 +528,16 @@ class Instance(ObjectLifeCycleMixin, CloudResource):
         """
         pass
 
+    @abstractproperty
+    def subnet_id(self):
+        """
+        Get the subnet ID where this instance is placed.
+
+        :rtype: ``str``
+        :return: Subnet ID to which this instance is connected.
+        """
+        pass
+
 #     @abstractproperty
 #     def mac_address(self):
 #         """

+ 4 - 0
cloudbridge/cloud/providers/aws/resources.py

@@ -268,6 +268,10 @@ class AWSInstance(BaseInstance):
     def zone_id(self):
         return self._ec2_instance.placement.get('AvailabilityZone')
 
+    @property
+    def subnet_id(self):
+        return self._ec2_instance.subnet_id
+
     @property
     def vm_firewalls(self):
         return [

+ 15 - 1
cloudbridge/cloud/providers/azure/resources.py

@@ -1254,7 +1254,7 @@ class AzureInstance(BaseInstance):
     @property
     def image_id(self):
         """
-        Get the image ID for this insance.
+        Get the image ID for this instance.
         """
         return self._vm.storage_profile.image_reference.id
 
@@ -1265,6 +1265,20 @@ class AzureInstance(BaseInstance):
         """
         return self._vm.location
 
+    @property
+    def subnet_id(self):
+        """
+        Return the first subnet id associated with the first network iface.
+
+        An Azure instance can have multiple network interfaces attached with
+        each interface having at most one subnet. This method will return only
+        the subnet of the first attached network interface.
+        """
+        for nic_id in self._nic_ids:
+            nic = self._provider.azure_client.get_nic(nic_id)
+            for ipc in nic.ip_configurations:
+                return ipc.subnet.id
+
     @property
     def vm_firewalls(self):
         return [self._provider.security.vm_firewalls.get(group_id)

+ 29 - 0
cloudbridge/cloud/providers/openstack/resources.py

@@ -366,6 +366,35 @@ class OpenStackInstance(BaseInstance):
         """
         return getattr(self._os_instance, 'OS-EXT-AZ:availability_zone', None)
 
+    @property
+    def subnet_id(self):
+        """
+        Extract (one) subnet id associated with this instance.
+
+        In OpenStack, instances are associated with ports instead of
+        instances so we need to dig through several connections to retrieve
+        the subnet_id. Further, there can potentially be several ports
+        connected to to different subnets. This implementation retrieves one
+        subnet, the one corresponding to port associated with the first
+        private IP associated with the instance.
+        """
+        # MAC address can be used to identify a port so extract the MAC
+        # address corresponding to the (first) private IP associated with the
+        # instance.
+        for net in self._os_instance.to_dict().get('addresses').keys():
+            for iface in self._os_instance.to_dict().get('addresses')[net]:
+                if iface.get('OS-EXT-IPS:type') == 'fixed':
+                    port = iface.get('OS-EXT-IPS-MAC:mac_addr')
+                    addr = iface.get('addr')
+                    break
+        # Now get a handle to a port with the given MAC address and get the
+        # subnet to which the private IP is connected as the desired id.
+        for prt in self._provider.neutron.list_ports().get('ports'):
+            if prt.get('mac_address') == port:
+                for ip in prt.get('fixed_ips'):
+                    if ip.get('ip_address') == addr:
+                        return ip.get('subnet_id')
+
     @property
     def vm_firewalls(self):
         return [