Adds workaround for routing 169.254.x.x addresses
See: https://bugs.launchpad.net/quantum/+bug/1174657
This commit is contained in:
@@ -16,10 +16,12 @@
|
|||||||
|
|
||||||
import posixpath
|
import posixpath
|
||||||
import urllib2
|
import urllib2
|
||||||
|
import urlparse
|
||||||
|
|
||||||
from cloudbaseinit.metadata.services import base
|
from cloudbaseinit.metadata.services import base
|
||||||
from cloudbaseinit.openstack.common import cfg
|
from cloudbaseinit.openstack.common import cfg
|
||||||
from cloudbaseinit.openstack.common import log as logging
|
from cloudbaseinit.openstack.common import log as logging
|
||||||
|
from cloudbaseinit.osutils import factory as osutils_factory
|
||||||
|
|
||||||
opts = [
|
opts = [
|
||||||
cfg.StrOpt('metadata_base_url', default='http://169.254.169.254/',
|
cfg.StrOpt('metadata_base_url', default='http://169.254.169.254/',
|
||||||
@@ -37,8 +39,38 @@ class HttpService(base.BaseMetadataService):
|
|||||||
super(HttpService, self).__init__()
|
super(HttpService, self).__init__()
|
||||||
self._enable_retry = True
|
self._enable_retry = True
|
||||||
|
|
||||||
|
def _check_metadata_ip_route(self):
|
||||||
|
'''
|
||||||
|
Workaround for: https://bugs.launchpad.net/quantum/+bug/1174657
|
||||||
|
'''
|
||||||
|
osutils = osutils_factory.OSUtilsFactory().get_os_utils()
|
||||||
|
|
||||||
|
os_major_version = int(osutils.get_os_version().split('.')[0])
|
||||||
|
if os_major_version >= 6:
|
||||||
|
# 169.254.x.x addresses are not getting routed starting from
|
||||||
|
# Windows Vista / 2008
|
||||||
|
metadata_netloc = urlparse.urlparse(CONF.metadata_base_url).netloc
|
||||||
|
metadata_host = metadata_netloc.split(':')[0]
|
||||||
|
|
||||||
|
if metadata_host.startswith("169.254."):
|
||||||
|
if not osutils.check_static_route_exists(metadata_host):
|
||||||
|
(interface_index, gateway) = osutils.get_default_gateway()
|
||||||
|
if gateway:
|
||||||
|
try:
|
||||||
|
osutils.add_static_route(metadata_host,
|
||||||
|
"255.255.255.255",
|
||||||
|
gateway,
|
||||||
|
interface_index,
|
||||||
|
10)
|
||||||
|
except Exception, ex:
|
||||||
|
# Ignore it
|
||||||
|
LOG.exception(ex)
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
super(HttpService, self).load()
|
super(HttpService, self).load()
|
||||||
|
|
||||||
|
self._check_metadata_ip_route()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.get_meta_data('openstack')
|
self.get_meta_data('openstack')
|
||||||
return True
|
return True
|
||||||
|
|||||||
@@ -69,3 +69,16 @@ class BaseOSUtils(object):
|
|||||||
|
|
||||||
def terminate(self):
|
def terminate(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def get_default_gateway(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def check_static_route_exists(self, destination):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def add_static_route(self, destination, mask, next_hop, interface_index,
|
||||||
|
metric):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_os_version(self):
|
||||||
|
pass
|
||||||
|
|||||||
@@ -327,3 +327,48 @@ class WindowsUtils(base.BaseOSUtils):
|
|||||||
# is not enough
|
# is not enough
|
||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
self._stop_service(self._service_name)
|
self._stop_service(self._service_name)
|
||||||
|
|
||||||
|
def get_default_gateway(self):
|
||||||
|
conn = wmi.WMI(moniker='//./root/cimv2')
|
||||||
|
for net_adapter_config in conn.Win32_NetworkAdapterConfiguration():
|
||||||
|
if net_adapter_config.DefaultIPGateway:
|
||||||
|
return (net_adapter_config.InterfaceIndex,
|
||||||
|
net_adapter_config.DefaultIPGateway[0])
|
||||||
|
return (None, None)
|
||||||
|
|
||||||
|
def check_static_route_exists(self, destination):
|
||||||
|
conn = wmi.WMI(moniker='//./root/cimv2')
|
||||||
|
return len(conn.Win32_IP4RouteTable(Destination=destination)) > 0
|
||||||
|
|
||||||
|
def add_static_route(self, destination, mask, next_hop, interface_index,
|
||||||
|
metric):
|
||||||
|
args = ['ROUTE', 'ADD', destination, 'MASK', mask, next_hop]
|
||||||
|
(out, err, ret_val) = self.execute_process(args)
|
||||||
|
# Cannot use the return value to determine the outcome
|
||||||
|
if err:
|
||||||
|
raise Exception('Unable to add route: %(err)s' % locals())
|
||||||
|
|
||||||
|
# TODO(alexpilotti): The following code creates the route properly and
|
||||||
|
# "route print" shows the added route, but routing to the destination
|
||||||
|
# fails. This option would be preferable compared to spawning a
|
||||||
|
# "ROUTE ADD" process.
|
||||||
|
'''
|
||||||
|
ROUTE_PROTOCOL_NETMGMT = 3
|
||||||
|
ROUTE_TYPE_INDIRECT = 4
|
||||||
|
|
||||||
|
conn = wmi.WMI(moniker='//./root/cimv2')
|
||||||
|
|
||||||
|
route = conn.Win32_IP4RouteTable.SpawnInstance_()
|
||||||
|
route.Destination = destination
|
||||||
|
route.Mask = mask
|
||||||
|
route.NextHop = next_hop
|
||||||
|
route.InterfaceIndex = interface_index
|
||||||
|
route.Metric1 = metric
|
||||||
|
route.Protocol = self.ROUTE_PROTOCOL_NETMGMT
|
||||||
|
route.Type = self.ROUTE_TYPE_INDIRECT
|
||||||
|
route.Put_()
|
||||||
|
'''
|
||||||
|
|
||||||
|
def get_os_version(self):
|
||||||
|
conn = wmi.WMI(moniker='//./root/cimv2')
|
||||||
|
return conn.Win32_OperatingSystem()[0].Version
|
||||||
|
|||||||
Reference in New Issue
Block a user