Merge "Accept new orchestrator config bucket"
This commit is contained in:
commit
20d413d654
|
@ -39,8 +39,11 @@ METADATA_DEST_ADDRESS = '169.254.169.254'
|
|||
# port for internal network metadata proxy
|
||||
BASE_METADATA_PORT = 9600
|
||||
|
||||
# port for rug metadata service
|
||||
RUG_META_PORT = 9697
|
||||
# default address of orchestrator metadata service
|
||||
ORCHESTRATOR_METADATA_ADDRESS = 'fdca:3ba5:a17a:acda::1'
|
||||
|
||||
# default port for orchestrator metadata service
|
||||
ORCHESTRATOR_METADATA_PORT = 9697
|
||||
|
||||
|
||||
def internal_metadata_port(ifname):
|
||||
|
|
|
@ -196,7 +196,8 @@ class IPTablesManager(base.Manager):
|
|||
|
||||
# Open SSH, the HTTP API (5000) and the Nova metadata proxy (9697)
|
||||
for port in (
|
||||
defaults.SSH, defaults.API_SERVICE, defaults.RUG_META_PORT
|
||||
defaults.SSH, defaults.API_SERVICE,
|
||||
defaults.ORCHESTRATOR_METADATA_PORT
|
||||
):
|
||||
rules.append(Rule(
|
||||
'-A INPUT -i %s -p tcp -m tcp --dport %s -j ACCEPT' % (
|
||||
|
|
|
@ -41,7 +41,7 @@ class MetadataManager(base.Manager):
|
|||
"""
|
||||
super(MetadataManager, self).__init__(root_helper)
|
||||
|
||||
def networks_have_changed(self, config):
|
||||
def should_restart(self, config):
|
||||
"""
|
||||
This function determines if the networks have changed since <config>
|
||||
was initialized.
|
||||
|
@ -59,8 +59,14 @@ class MetadataManager(base.Manager):
|
|||
except:
|
||||
# If we can't read the file, assume networks were added/removed
|
||||
return True
|
||||
config_dict.pop('tenant_id')
|
||||
return net_ids != set(config_dict.keys())
|
||||
|
||||
orchestrator_addr = config_dict.get('orchestrator_metadata_address')
|
||||
orchestrator_port = config_dict.get('orchestrator_metadata_port')
|
||||
|
||||
return (
|
||||
net_ids != set(config_dict.get('networks', {}).keys()) or
|
||||
orchestrator_addr != config.metadata_address or
|
||||
orchestrator_port != config.metadata_port)
|
||||
|
||||
def save_config(self, config):
|
||||
"""
|
||||
|
@ -108,7 +114,7 @@ def build_config(config):
|
|||
:param config:
|
||||
:rtype: astara_router.models.Configuration
|
||||
"""
|
||||
config_data = {}
|
||||
network_data = {}
|
||||
|
||||
for net in config.networks:
|
||||
if not net.is_tenant_network:
|
||||
|
@ -119,10 +125,14 @@ def build_config(config):
|
|||
for ip in a.ip_addresses:
|
||||
ip_instance_map[ip] = a.device_id
|
||||
|
||||
config_data[net.id] = {
|
||||
network_data[net.id] = {
|
||||
'listen_port': internal_metadata_port(net.interface.ifname),
|
||||
'ip_instance_map': ip_instance_map
|
||||
}
|
||||
|
||||
config_data['tenant_id'] = config.tenant_id
|
||||
return config_data
|
||||
return {
|
||||
'tenant_id': config.tenant_id,
|
||||
'orchestrator_metadata_address': config.metadata_address,
|
||||
'orchestrator_metadata_port': config.metadata_port,
|
||||
'networks': network_data,
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ class RouterManager(ServiceManagerBase):
|
|||
|
||||
def update_metadata(self):
|
||||
mgr = metadata.MetadataManager()
|
||||
should_restart = mgr.networks_have_changed(self._config)
|
||||
should_restart = mgr.should_restart(self._config)
|
||||
mgr.save_config(self._config)
|
||||
if should_restart:
|
||||
mgr.restart()
|
||||
|
|
|
@ -31,9 +31,6 @@ import requests
|
|||
from werkzeug import exceptions
|
||||
from werkzeug import wrappers
|
||||
|
||||
from astara_router import defaults
|
||||
from astara_router.drivers import ip
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
@ -48,8 +45,18 @@ class NetworkMetadataProxyHandler(object):
|
|||
self.network_id = network_id
|
||||
self.config_file = config_file
|
||||
self.config_mtime = 0
|
||||
self._config_dict = {}
|
||||
self._ip_instance_map = {}
|
||||
|
||||
@property
|
||||
def config_dict(self):
|
||||
config_mtime = os.stat(self.config_file).st_mtime
|
||||
if config_mtime > self.config_mtime:
|
||||
LOG.debug("Metadata proxy configuration has changed; reloading...")
|
||||
self._config_dict = json.load(open(self.config_file))
|
||||
self.config_mtime = config_mtime
|
||||
return self._config_dict
|
||||
|
||||
def __call__(self, environ, start_response):
|
||||
request = wrappers.Request(environ)
|
||||
|
||||
|
@ -68,16 +75,16 @@ class NetworkMetadataProxyHandler(object):
|
|||
|
||||
@property
|
||||
def ip_instance_map(self):
|
||||
config_mtime = os.stat(self.config_file).st_mtime
|
||||
if config_mtime > self.config_mtime:
|
||||
LOG.debug("Metadata proxy configuration has changed; reloading...")
|
||||
config_dict = json.load(open(self.config_file))
|
||||
self._ip_instance_map = config_dict[
|
||||
self.network_id
|
||||
]['ip_instance_map']
|
||||
self.config_mtime = config_mtime
|
||||
self._ip_instance_map = self.config_dict['networks'][
|
||||
self.network_id]['ip_instance_map']
|
||||
return self._ip_instance_map
|
||||
|
||||
@property
|
||||
def orchestrator_loc(self):
|
||||
addr = self.config_dict['orchestrator_metadata_address']
|
||||
port = self.config_dict['orchestrator_metadata_port']
|
||||
return '[%s]:%d' % (addr, port)
|
||||
|
||||
def _proxy_request(self, remote_address, path_info, query_string):
|
||||
headers = {
|
||||
'X-Forwarded-For': remote_address,
|
||||
|
@ -88,7 +95,7 @@ class NetworkMetadataProxyHandler(object):
|
|||
|
||||
url = urlparse.urlunsplit((
|
||||
'http',
|
||||
'[%s]:%d' % (ip.get_rug_address(), defaults.RUG_META_PORT),
|
||||
self.orchestrator_loc,
|
||||
path_info,
|
||||
query_string,
|
||||
''))
|
||||
|
@ -172,7 +179,7 @@ def main():
|
|||
pool = eventlet.GreenPool(1000)
|
||||
|
||||
tenant_id = config_dict.pop('tenant_id')
|
||||
for network_id, config in config_dict.items():
|
||||
for network_id, config in config_dict['networks'].items():
|
||||
app = NetworkMetadataProxyHandler(tenant_id,
|
||||
network_id,
|
||||
args.config_file)
|
||||
|
|
|
@ -20,6 +20,8 @@ import re
|
|||
|
||||
import netaddr
|
||||
|
||||
from astara_router import defaults
|
||||
|
||||
GROUP_NAME_LENGTH = 15
|
||||
DEFAULT_AS = 64512
|
||||
|
||||
|
@ -715,6 +717,12 @@ class RouterConfiguration(SystemConfiguration):
|
|||
Label(name, cidr) for name, cidr in
|
||||
conf_dict.get('labels', {}).iteritems()]
|
||||
|
||||
orchestrator_conf = conf_dict.get('orchestrator', {})
|
||||
self.metadata_address = orchestrator_conf.get(
|
||||
'address', defaults.ORCHESTRATOR_METADATA_ADDRESS)
|
||||
self.metadata_port = orchestrator_conf.get(
|
||||
'metadata_port', defaults.ORCHESTRATOR_METADATA_PORT)
|
||||
|
||||
self.floating_ips = [
|
||||
FloatingIP.from_dict(fip)
|
||||
for fip in conf_dict.get('floating_ips', [])
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
# Copyright 2014 DreamHost, LLC
|
||||
#
|
||||
# Author: DreamHost, LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import __builtin__
|
||||
|
||||
import json
|
||||
import mock
|
||||
|
||||
from unittest2 import TestCase
|
||||
|
||||
from astara_router.drivers import metadata
|
||||
|
||||
CONFIG = mock.Mock()
|
||||
CONFIG.hostname = 'astara'
|
||||
CONFIG.management_address = 'fdca:3ba5:a17a:acda:f816:3eff:fe66:33b6'
|
||||
|
||||
|
||||
class HostnameTestCase(TestCase):
|
||||
"""
|
||||
"""
|
||||
def setUp(self):
|
||||
self.mgr = metadata.MetadataManager()
|
||||
self.config_dict = {
|
||||
'networks': {'tenant_net_id': [], 'public_net_id': []},
|
||||
'orchestrator_metadata_address': '10.0.0.1',
|
||||
'orchestrator_metadata_port': '5000',
|
||||
}
|
||||
|
||||
tenant_net = mock.Mock(
|
||||
is_tenant_network=mock.Mock(return_value=True),
|
||||
id='tenant_net_id',
|
||||
)
|
||||
public_net = mock.Mock(
|
||||
is_tenant_network=mock.Mock(return_value=False),
|
||||
id='public_net_id',
|
||||
)
|
||||
|
||||
self.config = mock.Mock()
|
||||
self.config.networks = [tenant_net, public_net]
|
||||
self.config.metadata_address = '10.0.0.1'
|
||||
self.config.metadata_port = '5000'
|
||||
|
||||
def _test_should_restart(self, exp_result):
|
||||
config_json = json.dumps(self.config_dict)
|
||||
with mock.patch.object(
|
||||
__builtin__, 'open', mock.mock_open(read_data=config_json)):
|
||||
self.assertEqual(
|
||||
self.mgr.should_restart(self.config), exp_result)
|
||||
|
||||
def test_should_restart_false(self):
|
||||
self._test_should_restart(False)
|
||||
|
||||
def test_should_restart_true_networks_change(self):
|
||||
self.config_dict['networks'] = {
|
||||
'foo_net_id': [], 'public_net_id': []}
|
||||
self._test_should_restart(True)
|
||||
|
||||
def test_should_restart_true_metadata_addr_change(self):
|
||||
self.config_dict['orchestrator_metadata_address'] = '11.1.1.1'
|
||||
self._test_should_restart(True)
|
||||
|
||||
def test_should_restart_true_metadata_port_change(self):
|
||||
self.config_dict['orchestrator_metadata_port'] = '6000'
|
||||
self._test_should_restart(True)
|
||||
|
||||
def test_should_restart_true_config_read_err(self):
|
||||
with mock.patch.object(
|
||||
__builtin__, 'open', mock.mock_open()) as _o:
|
||||
_o.side_effect = IOError()
|
||||
self.assertEqual(
|
||||
self.mgr.should_restart(self.config), True)
|
|
@ -11,8 +11,14 @@ from astara_router import metadata_proxy
|
|||
|
||||
config = json.dumps({
|
||||
"tenant_id": "ABC123",
|
||||
"net1": {"listen_port": 9602, 'ip_instance_map': {'10.10.10.2': 'VM1'}},
|
||||
"net2": {"listen_port": 9603, 'ip_instance_map': {'10.10.10.2': 'VM2'}},
|
||||
"orchestrator_metadata_address": "192.168.25.30",
|
||||
"orchestrator_metadata_port": 9697,
|
||||
"networks": {
|
||||
"net1": {
|
||||
"listen_port": 9602, 'ip_instance_map': {'10.10.10.2': 'VM1'}},
|
||||
"net2": {
|
||||
"listen_port": 9603, 'ip_instance_map': {'10.10.10.2': 'VM2'}},
|
||||
}
|
||||
})
|
||||
|
||||
class TestMetadataProxy(unittest.TestCase):
|
||||
|
@ -66,7 +72,7 @@ class TestMetadataProxy(unittest.TestCase):
|
|||
get.return_value.status_code = 200
|
||||
wsgi._proxy_request('10.10.10.2', '/', '')
|
||||
get.assert_called_once_with(
|
||||
'http://[fdca:3ba5:a17a:acda::1]:9697/',
|
||||
'http://[192.168.25.30]:9697/',
|
||||
headers={
|
||||
'X-Quantum-Network-ID': 'net1',
|
||||
'X-Forwarded-For': '10.10.10.2',
|
||||
|
|
|
@ -23,7 +23,7 @@ import netaddr
|
|||
|
||||
from unittest2 import TestCase
|
||||
|
||||
from astara_router import models
|
||||
from astara_router import defaults, models
|
||||
from test.unit import fakes
|
||||
|
||||
|
||||
|
@ -439,6 +439,23 @@ class RouterConfigurationTestCase(TestCase):
|
|||
self.assertEqual(len(c.anchors[0].rules), 1)
|
||||
self.assertEqual(c.anchors[0].rules[0].action, 'block')
|
||||
|
||||
def test_init_metadata_config(self):
|
||||
c = models.RouterConfiguration({
|
||||
'orchestrator': {
|
||||
'address': '192.168.25.30',
|
||||
'metadata_port': 9697,
|
||||
}
|
||||
})
|
||||
self.assertEqual(c.metadata_address, '192.168.25.30')
|
||||
self.assertEqual(c.metadata_port, 9697)
|
||||
|
||||
def test_init_metadata_config_missing(self):
|
||||
c = models.RouterConfiguration({})
|
||||
self.assertEqual(
|
||||
c.metadata_address, defaults.ORCHESTRATOR_METADATA_ADDRESS)
|
||||
self.assertEqual(
|
||||
c.metadata_port, defaults.ORCHESTRATOR_METADATA_PORT)
|
||||
|
||||
def test_asn_default(self):
|
||||
c = models.RouterConfiguration({'networks': []})
|
||||
self.assertEqual(c.asn, 64512)
|
||||
|
|
Loading…
Reference in New Issue