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

240 lines
8.1 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.
import copy
class Filter(object):
""" Filter class which provides data asked in a specific format.
This class mocks all rpc calls going from *aaS agent/driver to respective
*aaS plugin.
"""
def __init__(self, topic, default_version):
pass
def call(self, context, msg):
"""Returns data in specific format after applying filter on context
:param context
:param msg e.g {'args': {'key': value,..},'method': 'function_name'}}
Returns: data after applying filter on it
"""
filters = {}
try:
for fk, fv in list(msg['args'].items()):
if dict == type(fv):
filters = fv
break
if fv:
filters = {fk: fv}
break
method = getattr(self, '_%s' % (msg['method']))
return method(context, filters)
except Exception as e:
raise e
def make_msg(self, method, **kwargs):
""" Helper function needed to invoke Filter.call()
:param method - method name
:kwargs kwargs - filters to be used
Returns: dict
"""
return {'method': method,
'args': kwargs}
def apply_filter(self, data, filters):
""" Apply filters on data
:param filters e.g {k:[v],k:[v]}
:param data e.g [{k:v,k:v,k:v},
{k:v,k:v,k:v},
{k:v,k:v}]
Returns: data after applying filter on it
"""
for fk, fv in list(filters.items()):
for d in data[:]:
if d.get(fk) is None:
data.remove(d)
if fk in d and d[fk] != fv[0]:
data.remove(d)
return data
def get_record(self, data, key, value):
"""Get single record based on key and value
:param data
:praam key
:param value
Returns: record
"""
for d in data:
if key in d and d[key] == value:
return d
def _get_vpn_services(self, context, filters):
""" Get vpn service from context after applying filter
:param context - vpn related resources
e.g context = {'service_info':{'vpnservices': [vpnservices],
'ikepolicies': [ikepolicies],
'ipsecpolicies':[ipsecpolicies],
'ipsec_site_conns':
[ipsec_site_connections],
'routers': [routers],
'subnets': [subnets]
}
}
:param filters
e.g { 'ids' : [vpn service ids],
'filters': filters }
Returns: [vpn services]
"""
vpn_ids = None
if 'ids' in filters and filters['ids']:
vpn_ids = filters['ids']
service_info = context['service_info']
vpnservices = service_info['vpnservices']
filtered_vpns = []
if vpn_ids:
for vpn_id in vpn_ids:
filtered_vpns.append(
self.get_record(vpnservices, 'id', vpn_id))
return filtered_vpns
else:
return self.apply_filter(vpnservices, filters)
def _get_ipsec_conns(self, context, filters):
""" Get ipsec site conns from context after applying filter
:param context - vpn related resources
e.g context = {'service_info':{'vpnservices': [vpnservices],
'ikepolicies': [ikepolicies],
'ipsecpolicies':[ipsecpolicies],
'ipsec_site_conns':
[ipsec_site_connections],
'routers': [routers],
'subnets': [subnets]
}
}
:param filters e.g { 'tenant_id': [tenant_id],
'peer_address': [conn['peer_address']]
}
Returns: [ipsec site conns]
"""
service_info = context['service_info']
ipsec_conns = copy.deepcopy(service_info['ipsec_site_conns'])
return self.apply_filter(ipsec_conns, filters)
def _get_vpn_servicecontext(self, context, filters):
"""Get vpnservice context
:param context
:param filters
Returns IPSec site conns
"""
return self._get_ipsec_site2site_contexts(context, filters)
def _get_ipsec_site2site_contexts(self, context, filters=None):
""" Get ipsec site to site context
:param filters
e.g {'tenant_id': <value>,
'vpnservice_id': <value>,
'siteconn_id': <value>
}
'tenant_id' - To get s2s conns of that tenant
'vpnservice_id' - To get s2s conns of that vpn service
'siteconn_id' - To get a specific s2s conn
Returns: vpnservices
e.g { 'vpnserviceid':
{ 'service': <VPNService>,
'siteconns':[ {
'connection': <IPSECsiteconnections>,
'ikepolicy': <IKEPolicy>,
'ipsecpolicy': <IPSECPolicy>
}
]
}
}
"""
if not filters:
filters = {}
service_info = context['service_info']
vpnservices = {}
s_filters = {}
if 'tenant_id' in filters:
s_filters['tenant_id'] = [filters['tenant_id']]
if 'vpnservice_id' in filters:
s_filters['vpnservice_id'] = [filters['vpnservice_id']]
if 'siteconn_id' in filters:
s_filters['id'] = [filters['siteconn_id']]
if 'peer_address' in filters:
s_filters['peer_address'] = [filters['peer_address']]
ipsec_site_conns = self.apply_filter(service_info['ipsec_site_conns'],
s_filters)
for conn in ipsec_site_conns:
vpnservice = [vpn for vpn in service_info['vpnservices']
if vpn['id'] == conn['vpnservice_id']][0]
ikepolicy = [ikepolicy for ikepolicy in service_info['ikepolicies']
if ikepolicy['id'] == conn['ikepolicy_id']][0]
ipsecpolicy = [ipsecpolicy for ipsecpolicy in
service_info['ipsecpolicies']
if ipsecpolicy['id'] == conn['ipsecpolicy_id']][0]
"""
Get the local subnet cidr
"""
siteconn = {}
siteconn['connection'] = conn
siteconn['ikepolicy'] = ikepolicy
siteconn['ipsecpolicy'] = ipsecpolicy
vpnserviceid = vpnservice['id']
if vpnserviceid not in list(vpnservices.keys()):
vpnservices[vpnserviceid] = \
{'service': vpnservice, 'siteconns': []}
vpnservices[vpnserviceid]['siteconns'].append(siteconn)
site2site_context = self._make_vpnservice_context(vpnservices)
return site2site_context
def _make_vpnservice_context(self, vpnservices):
"""Generate vpnservice context from the dictionary of vpnservices.
See, if some values are not needed by agent-driver, do not pass them.
As of now, passing everything.
"""
return list(vpnservices.values())