group-based-policy/gbpservice/contrib/nfp/configurator/lib/demuxer.py

166 lines
5.9 KiB
Python

# 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 gbpservice.contrib.nfp.configurator.lib import constants as const
class ServiceAgentDemuxer(object):
"""Implements supporting methods for configurator module.
Provides methods that take configurator API request data and helps
configurator to de-multiplex the API calls to different service agents
and drivers.
Format of request data for network device configuration API:
request_data {
info {
version: <v1/v2/v3>
}
config [
{
'resource': <healthmonitor/routes/interfaces>,
'kwargs': <resource parameters>
},
{
'resource': <healthmonitor/routes/interfaces>,
'kwargs': <resource parameters>
}, ...
]
}
Format of request data for network service configuration API:
request_data {
info {
version: <v1/v2/v3>
type: <firewall/vpn/loadbalancer>
}
config [
{
'resource': <healthmonitor/routes/interfaces>,
'kwargs': <resource parameters>
},
{
'resource': <healthmonitor/routes/interfaces>,
'kwargs': <resource parameters>
}, ...
]
}
"""
def __init__(self):
pass
def get_service_type(self, request_data):
"""Retrieves service type from request data.
:param request_data: API input data (format specified at top of file)
Returns:
(1) "firewall"/"vpn"/"loadbalancer"
(2) "generic_config" if service_type field is absent in request_data
(3) "invalid" if any other service type is provided in request_data
"""
# Get service type based on the fact that for some request data
# formats the 'type' key is absent. Check for invalid types
service_type = request_data['info'].get('service_type').lower()
return service_type
def get_service_agent_info(self, operation, resource_type,
request_data, is_generic_config):
"""Prepares information for service agent consumption.
:param operation: create/delete/update
:param resource_type: firewall/vpn/loadbalancer/generic_config
:param request_data: API input data (format specified at top of file)
Returns: List with the following format.
sa_info_list [
{
'context': <context dictionary>
'resource_type': <firewall/vpn/loadbalancer/generic_config>
'method': <*aas RPC methods/generic configuration methods>
'kwargs' <kwargs taken from request data of API>
}
]
"""
sa_info_list = []
vendor_map = {const.FIREWALL: const.VYOS,
const.VPN: const.VYOS,
const.LOADBALANCERV2: const.HAPROXY_LBAASV2}
service_vendor = request_data['info']['service_vendor']
if str(service_vendor) == 'None':
service_vendor = vendor_map[resource_type]
service_feature = request_data['info'].get('service_feature')
if not service_feature:
service_feature = ''
for config_data in request_data['config']:
sa_info = {}
resource_type_to_method_map = {
const.FIREWALL: (operation + '_' + config_data['resource']),
const.VPN: ('vpnservice_updated'),
const.LOADBALANCERV2: (operation + '_' + config_data[
'resource']),
const.NFP_SERVICE: ('run' + '_' + const.NFP_SERVICE),
const.GENERIC_CONFIG: {
const.CREATE: ('configure_' + config_data[
'resource']),
const.UPDATE: ('update_' + config_data['resource']),
const.DELETE: ('clear_' + config_data['resource'])}}
context = request_data['info']['context']
data = config_data['resource_data']
if not data:
return None
resource = config_data['resource']
is_nfp_svc = True if resource in const.NFP_SERVICE_LIST else False
if is_generic_config:
method = resource_type_to_method_map[
const.GENERIC_CONFIG][operation]
else:
if is_nfp_svc:
resource_type = const.NFP_SERVICE
try:
method = resource_type_to_method_map[resource_type]
except Exception:
method = 'handle_config'
sa_info.update({'method': method,
'resource_data': data,
'agent_info': {
# This is the API context
'context': context,
'service_vendor': service_vendor.lower(),
'service_feature': service_feature,
'resource_type': resource_type.lower(),
'resource': resource.lower()},
'is_generic_config': is_generic_config})
sa_info_list.append(sa_info)
if is_nfp_svc:
resource_type = const.NFP_SERVICE
elif is_generic_config:
resource_type = const.GENERIC_CONFIG
return sa_info_list, resource_type