neutron/neutron/tests/fullstack/servers/placement.py

147 lines
4.8 KiB
Python
Executable File

#!/usr/bin/env python
# Copyright (c) 2019 Ericsson
#
# 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 copy
import sys
import uuid
from wsgiref import simple_server as wsgi_simple_server
from oslo_config import cfg
from oslo_config import types
from oslo_log import log as logging
from oslo_serialization import jsonutils
from six.moves import urllib
from neutron.common import config as common_config
LOG = logging.getLogger(__name__)
PortType = types.Integer(1, 65535)
placement_opts = [
cfg.Opt('placement_port', type=PortType)
]
cfg.CONF.register_opts(placement_opts)
class FakePlacement(object):
rp_template = {
"uuid": None,
"generation": 0,
"parent_provider_uuid": None,
"name": None,
}
def __init__(self):
self.host_rp_uuid = str(uuid.uuid4())
host_rp = copy.deepcopy(self.rp_template)
host_rp['uuid'] = self.host_rp_uuid
self.resource_providers = {
self.host_rp_uuid: host_rp
}
def get_resource_providers(self, **kwargs):
id = kwargs.get('id', None)
if not id:
return jsonutils.dumps(
{
'resource_providers':
[self.resource_providers[self.host_rp_uuid]]
})
else:
return jsonutils.dumps(self.resource_providers[id])
def put_traits(self, **kwargs):
# Return empty sting otherwise wsgiref goes mad
return ''
def put_resource_providers(self, **kwargs):
id = kwargs.get('id', None)
req_body = kwargs.get('body', None)
if id:
rp_dict = copy.deepcopy(self.rp_template)
rp_dict['uuid'] = id
rp_dict['parent_provider_uuid'] = req_body['parent_provider_uuid']
rp_dict['name'] = req_body['name']
self.resource_providers[rp_dict['uuid']] = rp_dict
return jsonutils.dumps(rp_dict)
def put_resource_providers_traits(self, **kwargs):
resp = kwargs['body']
resp['resource_provider_generation'] += 1
return jsonutils.dumps(resp)
def put_resource_providers_inventories(self, **kwargs):
resp = kwargs['body']
resp['resource_provider_generation'] += 1
return jsonutils.dumps(resp)
def build_method_name(self, action, path_info):
path_info = urllib.parse.urlparse(path_info).path
path_info_list = path_info.strip('/').split('/')
method_name = action.lower()
for path_chunk in path_info_list:
if any(s in path_chunk for s in ['placement', 'CUSTOM']):
continue
# If there is uuid in the path, that should be thrown out
try:
uuid.UUID(path_chunk)
except ValueError:
method_name += '_' + path_chunk
return method_name
def wsgi_app(self, env, start_response):
response_headers = [('Content-Type', 'application/json')]
http_status = '200 OK'
# Poor men's routing
meth_name = self.build_method_name(env['REQUEST_METHOD'],
env['PATH_INFO'])
params = {}
# Fetch params from url
try:
params['id'] = env['PATH_INFO'].split('/')[3]
except IndexError:
pass
# Fetch body
try:
request_body_size = int(env.get('CONTENT_LENGTH', 0))
if request_body_size > 0:
req_body = env['wsgi.input'].read(request_body_size)
params['body'] = jsonutils.loads(req_body.decode('utf-8'))
except ValueError:
pass
LOG.debug('Request on %s (%s) with body: %s',
env['PATH_INFO'], env['REQUEST_METHOD'], params)
response = getattr(self, meth_name)(**params)
LOG.debug('Response from %s: %s', meth_name, response)
response = response.encode('utf-8')
start_response(http_status, response_headers)
return [response]
if __name__ == "__main__":
common_config.init(sys.argv[1:])
common_config.setup_logging()
placement_port = cfg.CONF.placement_port
LOG.info("Placement fixture started on port: %s", placement_port)
mock_placement = FakePlacement()
wsgi_simple_server.make_server(
'', placement_port, mock_placement.wsgi_app).serve_forever()