فهرست منبع

Fixed public and private ip properties for openstack

nuwan_ag 10 سال پیش
والد
کامیت
e17073a0e0
3فایلهای تغییر یافته به همراه33 افزوده شده و 11 حذف شده
  1. 13 2
      cloudbridge/providers/openstack/resources.py
  2. 6 1
      setup.py
  3. 14 8
      test/test_compute_service.py

+ 13 - 2
cloudbridge/providers/openstack/resources.py

@@ -3,6 +3,7 @@ DataTypes used by this provider
 """
 import shutil
 
+import ipaddress
 from swiftclient.exceptions import ClientException
 
 from cloudbridge.providers.base import BaseInstance
@@ -200,14 +201,24 @@ class OpenStackInstance(BaseInstance):
         """
         Get all the public IP addresses for this instance.
         """
-        return self._os_instance.networks['public']
+        # Openstack doesn't provide an easy way to figure our whether an ip is
+        # public or private, since the returned ips are grouped by an arbitrary
+        # network label. Therefore, it's necessary to parse the address and
+        # determine whether it's public or private
+        return [address
+                for addresses in self._os_instance.networks.itervalues()
+                for address in addresses
+                if not ipaddress.ip_address(address).is_private]
 
     @property
     def private_ips(self):
         """
         Get all the private IP addresses for this instance.
         """
-        return self._os_instance.networks['private']
+        return [address
+                for addresses in self._os_instance.networks.itervalues()
+                for address in addresses
+                if ipaddress.ip_address(address).is_private]
 
     @property
     def instance_type(self):

+ 6 - 1
setup.py

@@ -1,5 +1,10 @@
+import sys
 from setuptools import setup, find_packages
 
+if sys.version_info[0] == 2:
+    backports = ["py2-ipaddress"]
+else:
+    backports = []
 
 setup(name='cloudbridge',
       version=0.1,
@@ -10,7 +15,7 @@ setup(name='cloudbridge',
       url='http://cloudbridge.readthedocs.org/',
       install_requires=['bunch>=1.00', 'six>=1.9.0', 'python-keystoneclient',
                         'python-novaclient', 'python-cinderclient',
-                        'python-swiftclient', 'boto', 'retrying'],
+                        'python-swiftclient', 'boto', 'retrying'] + backports,
       packages=find_packages(),
       license='MIT',
       classifiers=[

+ 14 - 8
test/test_compute_service.py

@@ -1,5 +1,5 @@
-import socket
 import uuid
+import ipaddress
 
 from cloudbridge.providers.interfaces import InstanceState
 from test.helpers import ProviderTestBase
@@ -38,12 +38,9 @@ class ProviderComputeServiceTestCase(ProviderTestBase):
 
     def _is_valid_ip(self, address):
         try:
-            socket.inet_pton(socket.AF_INET, address)
-        except socket.error:  # not a valid address
-            try:
-                socket.inet_pton(socket.AF_INET, address)
-            except socket.error:  # still not a valid address
-                return False
+            ipaddress.ip_address(address)
+        except ValueError:
+            return False
         return True
 
     def test_instance_properties(self):
@@ -63,5 +60,14 @@ class ProviderComputeServiceTestCase(ProviderTestBase):
                              " {1}".format(test_instance.image_id, image_id))
             self.assertIsInstance(test_instance.public_ips, list)
             self.assertIsInstance(test_instance.private_ips, list)
+            # Must have either a public or a private ip
+            ip_private = test_instance.private_ips[0] \
+                if test_instance.private_ips else None
+            ip_address = test_instance.public_ips[0] \
+                if test_instance.public_ips else ip_private
+            self.assertIsNotNone(
+                ip_address,
+                "Instance must have either a public IP or a private IP")
             self.assertTrue(
-                self._is_valid_ip(self.test_instance.private_ips[0]))
+                self._is_valid_ip(ip_address),
+                "Instance must have a valid IP address")