diff --git a/devstack/plugin.sh b/devstack/plugin.sh index 3e5e6415..5c9add66 100644 --- a/devstack/plugin.sh +++ b/devstack/plugin.sh @@ -327,6 +327,14 @@ function start_central_neutron_server { iniset $NEUTRON_CONF.$server_index tricircle type_drivers $type_drivers iniset $NEUTRON_CONF.$server_index tricircle tenant_network_types $tenant_network_types iniset $NEUTRON_CONF.$server_index tricircle enable_api_gateway False + + # reconfigure api-paste.ini in central neutron server + local API_PASTE_INI=$NEUTRON_CONF_DIR/api-paste.ini + sudo sed -e " + /^keystone.*neutronapiapp/s/neutronapiapp/request_source &/; + /app:neutronapiapp/i\[filter:request_source]\npaste.filter_factory = tricircle.common.request_source:RequestSource.factory\n + " -i $API_PASTE_INI + # default value of bridge_network_type is vxlan if [ "$TRICIRCLE_ENABLE_QOS" == "True" ]; then diff --git a/tricircle/common/constants.py b/tricircle/common/constants.py index 82d249c4..3c350d35 100644 --- a/tricircle/common/constants.py +++ b/tricircle/common/constants.py @@ -218,3 +218,11 @@ job_primary_resource_map = { # admin API request path ROUTING_PATH = '/v1.0/routings' JOB_PATH = '/v1.0/jobs' + +USER_AGENT = 'User-Agent' +# The name of the source flag when the request is from central Neutron +CENTRAL = 'central-neutronclient' +# The name of the source flag when the request is from local Neutron +LOCAL = 'local-neutronclient' + +REQUEST_SOURCE_TYPE = set([CENTRAL, LOCAL]) diff --git a/tricircle/common/request_source.py b/tricircle/common/request_source.py new file mode 100644 index 00000000..93227c84 --- /dev/null +++ b/tricircle/common/request_source.py @@ -0,0 +1,47 @@ +# 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. +from oslo_log import log as logging +from oslo_middleware import base +import webob + +import constants as cons + +LOG = logging.getLogger(__name__) + + +class RequestSource(base.ConfigurableMiddleware): + """RequestSource Middleware + + This middleware distinguishes the source of the requests. It can find out + which request is from central Neutron and which is from local Neutron. + + This middleware updates the context to put the source of requests + extracted from headers. + + In order to make RequestSource Middleware work, this middleware should + place after keystoneContext(in etc/neutron/api-paste.ini). + """ + + def distinguish_requests_source(self, req): + source_header = req.headers.get(cons.USER_AGENT, "") + + if source_header in cons.REQUEST_SOURCE_TYPE: + ctx = req.environ['neutron.context'] + ctx.USER_AGENT = source_header + req.environ['neutron.context'] = ctx + + @webob.dec.wsgify + def __call__(self, req): + self.distinguish_requests_source(req) + + response = req.get_response(self.application) + return response diff --git a/tricircle/network/central_plugin.py b/tricircle/network/central_plugin.py index 503d9487..63932870 100644 --- a/tricircle/network/central_plugin.py +++ b/tricircle/network/central_plugin.py @@ -61,6 +61,7 @@ from neutron_lib import constants from neutron_lib import exceptions from neutron_lib.exceptions import availability_zone as az_exc from neutron_lib.plugins import directory +import neutronclient.client as neutronclient import neutronclient.common.exceptions as q_cli_exceptions from sqlalchemy import sql @@ -185,6 +186,7 @@ class TricirclePlugin(db_base_plugin_v2.NeutronDbPluginV2, self.extension_manager.initialize() self.type_manager.initialize() self.helper = helper.NetworkHelper(self) + neutronclient.USER_AGENT = t_constants.CENTRAL qos_driver.register() def _setup_rpc(self): diff --git a/tricircle/network/local_plugin.py b/tricircle/network/local_plugin.py index 3fc48214..fc0e90c7 100644 --- a/tricircle/network/local_plugin.py +++ b/tricircle/network/local_plugin.py @@ -26,6 +26,7 @@ import neutron_lib.constants as q_constants import neutron_lib.exceptions as q_exceptions from neutron_lib.plugins import directory from neutron_lib.utils import runtime +import neutronclient.client as neutronclient from neutron.common import utils import neutron.extensions.securitygroup as ext_sg @@ -78,6 +79,7 @@ class TricirclePlugin(plugin.Ml2Plugin): cfg.CONF.tricircle.central_neutron_url self.on_trunk_create = {} self.on_subnet_delete = {} + neutronclient.USER_AGENT = t_constants.LOCAL def start_rpc_listeners(self): return self.core_plugin.start_rpc_listeners()