Browse Source

Distinguish the source of requests

1. What is the problem?
When receiving a request, we don't know whether the request
comes from  'Central Neutron' or 'Local Neutron'.

2. What is the solution to the problem?
In order to determine the source of requests, we add a
filter to get the source message in the header of requests.
Next step we tag the source message into the context. When
deploy the WSGI app, we checkout the User-Agent in the
request's headers and tag the requests.

3. What the features need to be implemented to the Tricircle
to realize the solution?

Change-Id: I990fa46e887cc0822b8e6d74d199d92e39df0bd6
lyman-xu 3 years ago
5 changed files with 67 additions and 0 deletions
  1. +8
  2. +8
  3. +47
  4. +2
  5. +2

+ 8
- 0
devstack/ View File

@ -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
# default value of bridge_network_type is vxlan
if [ "$TRICIRCLE_ENABLE_QOS" == "True" ]; then

+ 8
- 0
tricircle/common/ View File

@ -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'

+ 47
- 0
tricircle/common/ View File

@ -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
# 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
def __call__(self, req):
response = req.get_response(self.application)
return response

+ 2
- 0
tricircle/network/ View File

@ -60,6 +60,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
@ -184,6 +185,7 @@ class TricirclePlugin(db_base_plugin_v2.NeutronDbPluginV2,
self.helper = helper.NetworkHelper(self)
neutronclient.USER_AGENT = t_constants.CENTRAL
def _setup_rpc(self):

+ 2
- 0
tricircle/network/ View File

@ -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):
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()