summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOleksii Chuprykov <ochuprykov@mirantis.com>2014-09-30 18:25:26 +0300
committerOleksii Chuprykov <ochuprykov@mirantis.com>2014-11-18 17:40:50 +0200
commited9a695564822004336d4551ca8a23d79bdeb568 (patch)
tree4a7b83f7bfbafccd978699d0d5e734bd7778b6d6
parent760dbc7420b393b4919011ba007973a9a73125e2 (diff)
downloadoslo-utils-ed9a695564822004336d4551ca8a23d79bdeb568.tar.gz
Add get_my_ip()
At the moment function _get_my_ip() exists (at least) in Cinder, Ironic, Neutron, Nova and Tuskar, so there is a sense to keep it in common code. Change-Id: I3c37d6ea3e8bef7b8a5e21baedd1b2b94369515f
-rw-r--r--oslo/utils/netutils.py33
-rw-r--r--requirements.txt1
-rw-r--r--tests/test_netutils.py37
3 files changed, 70 insertions, 1 deletions
diff --git a/oslo/utils/netutils.py b/oslo/utils/netutils.py
index 3d2af67..ecb8d7d 100644
--- a/oslo/utils/netutils.py
+++ b/oslo/utils/netutils.py
@@ -21,8 +21,10 @@ import logging
import socket
import netaddr
+import netifaces
from six.moves.urllib import parse
+from oslo.utils._i18n import _LI
from oslo.utils._i18n import _LW
LOG = logging.getLogger(__name__)
@@ -112,6 +114,37 @@ def is_valid_ip(address):
return is_valid_ipv4(address) or is_valid_ipv6(address)
+def get_my_ipv4():
+ """Returns the actual ipv4 of the local machine.
+
+ This code figures out what source address would be used if some traffic
+ were to be sent out to some well known address on the Internet. In this
+ case, IP from RFC5737 is used, but the specific address does not
+ matter much. No traffic is actually sent.
+ """
+ try:
+ csock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ csock.connect(('192.0.2.0', 80))
+ (addr, port) = csock.getsockname()
+ csock.close()
+ return addr
+ except socket.error:
+ return _get_my_ipv4_address()
+
+
+def _get_my_ipv4_address():
+ """Figure out the best ipv4
+ """
+ LOCALHOST = '127.0.0.1'
+ gtw = netifaces.gateways()
+ try:
+ interface = gtw['default'][netifaces.AF_INET][1]
+ return netifaces.ifaddresses(interface)[netifaces.AF_INET][0]['addr']
+ except Exception:
+ LOG.info(_LI("Couldn't get IPv4"))
+ return LOCALHOST
+
+
class _ModifiedSplitResult(parse.SplitResult):
"""Split results class for urlsplit."""
diff --git a/requirements.txt b/requirements.txt
index 1f1f75f..c31aca4 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -7,3 +7,4 @@ six>=1.7.0
iso8601>=0.1.9
oslo.i18n>=1.0.0 # Apache-2.0
netaddr>=0.7.12
+netifaces>=0.10.4
diff --git a/tests/test_netutils.py b/tests/test_netutils.py
index 12df992..cd4b23a 100644
--- a/tests/test_netutils.py
+++ b/tests/test_netutils.py
@@ -16,6 +16,8 @@
import socket
import mock
+from mock import patch
+import netifaces
from oslotest import base as test_base
from oslo.utils import netutils
@@ -174,4 +176,37 @@ class NetworkUtilsTest(test_base.BaseTestCase):
self.assertFalse(netutils.is_valid_ip('::1.2.3.'))
- self.assertFalse(netutils.is_valid_ip('')) \ No newline at end of file
+ self.assertFalse(netutils.is_valid_ip(''))
+
+ def test_get_my_ip(self):
+ sock_attrs = {
+ 'return_value.getsockname.return_value': ['1.2.3.4', '']}
+ with mock.patch('socket.socket', **sock_attrs):
+ addr = netutils.get_my_ipv4()
+ self.assertEqual(addr, '1.2.3.4')
+
+ @mock.patch('socket.socket')
+ @mock.patch('oslo.utils.netutils._get_my_ipv4_address')
+ def test_get_my_ip_socket_error(self, ip, mock_socket):
+ mock_socket.side_effect = socket.error
+ ip.return_value = '1.2.3.4'
+ addr = netutils.get_my_ipv4()
+ self.assertEqual(addr, '1.2.3.4')
+
+ @mock.patch('netifaces.gateways')
+ @mock.patch('netifaces.ifaddresses')
+ def test_get_my_ipv4_address_with_default_route(
+ self, ifaddr, gateways):
+ with patch.dict(netifaces.__dict__, {'AF_INET': '0'}):
+ ifaddr.return_value = {'0': [{'addr': '172.18.204.1'}]}
+ addr = netutils._get_my_ipv4_address()
+ self.assertEqual('172.18.204.1', addr)
+
+ @mock.patch('netifaces.gateways')
+ @mock.patch('netifaces.ifaddresses')
+ def test_get_my_ipv4_address_without_default_route(
+ self, ifaddr, gateways):
+ with patch.dict(netifaces.__dict__, {'AF_INET': '0'}):
+ ifaddr.return_value = {}
+ addr = netutils._get_my_ipv4_address()
+ self.assertEqual('127.0.0.1', addr)