Skip to content
Snippets Groups Projects
Commit b3e60dfc authored by Lluis Gifre Renom's avatar Lluis Gifre Renom
Browse files

Pre-merge code cleanup

parent 5db023b9
No related branches found
No related tags found
2 merge requests!294Release TeraFlowSDN 4.0,!284Resolve: "(CNIT) Multi-Granular Optical Nodes and Optical Transpoders management"
...@@ -15,10 +15,8 @@ ...@@ -15,10 +15,8 @@
import json import json
import logging, pytz, queue, re, threading import logging, pytz, queue, re, threading
#import lxml.etree as ET #import lxml.etree as ET
from typing import Any, List, Tuple, Union from typing import Any, List, Tuple, Union
from apscheduler.executors.pool import ThreadPoolExecutor from apscheduler.executors.pool import ThreadPoolExecutor
from apscheduler.jobstores.memory import MemoryJobStore from apscheduler.jobstores.memory import MemoryJobStore
from apscheduler.schedulers.background import BackgroundScheduler from apscheduler.schedulers.background import BackgroundScheduler
from ncclient.manager import Manager, connect_ssh from ncclient.manager import Manager, connect_ssh
...@@ -30,16 +28,16 @@ from device.service.driver_api._Driver import _Driver ...@@ -30,16 +28,16 @@ from device.service.driver_api._Driver import _Driver
from device.service.driver_api.AnyTreeTools import TreeNode from device.service.driver_api.AnyTreeTools import TreeNode
from .templates.VPN.common import seperate_port_config from .templates.VPN.common import seperate_port_config
#from .Tools import xml_pretty_print, xml_to_dict, xml_to_file #from .Tools import xml_pretty_print, xml_to_dict, xml_to_file
from .templates.VPN.roadms import (
from .templates.VPN.roadms import (create_media_channel,create_optical_band, disable_media_channel create_optical_band, disable_media_channel, delete_optical_band, create_media_channel_v2
, delete_optical_band,create_media_channel_v2) )
from .templates.VPN.transponder import (edit_optical_channel ,change_optical_channel_status) from .templates.VPN.transponder import edit_optical_channel, change_optical_channel_status
from .RetryDecorator import retry from .RetryDecorator import retry
from context.client.ContextClient import ContextClient from context.client.ContextClient import ContextClient
from common.proto.context_pb2 import ( from common.proto.context_pb2 import OpticalConfig
OpticalConfig) from .templates.descovery_tool.transponders import transponder_values_extractor
from .templates.descovery_tool.transponders import transponder_values_extractor from .templates.descovery_tool.roadms import roadm_values_extractor, openroadm_values_extractor
from .templates.descovery_tool.roadms import roadm_values_extractor ,openroadm_values_extractor,extract_media_channels
DEBUG_MODE = False DEBUG_MODE = False
logging.getLogger('ncclient.manager').setLevel(logging.DEBUG if DEBUG_MODE else logging.WARNING) logging.getLogger('ncclient.manager').setLevel(logging.DEBUG if DEBUG_MODE else logging.WARNING)
logging.getLogger('ncclient.transport.ssh').setLevel(logging.DEBUG if DEBUG_MODE else logging.WARNING) logging.getLogger('ncclient.transport.ssh').setLevel(logging.DEBUG if DEBUG_MODE else logging.WARNING)
...@@ -56,13 +54,14 @@ RE_GET_ENDPOINT_FROM_INTERFACE_XPATH = re.compile(r".*interface\[oci\:name\='([^ ...@@ -56,13 +54,14 @@ RE_GET_ENDPOINT_FROM_INTERFACE_XPATH = re.compile(r".*interface\[oci\:name\='([^
SAMPLE_EVICTION_SECONDS = 30.0 # seconds SAMPLE_EVICTION_SECONDS = 30.0 # seconds
SAMPLE_RESOURCE_KEY = 'interfaces/interface/state/counters' SAMPLE_RESOURCE_KEY = 'interfaces/interface/state/counters'
transponder_filter_fields= ["frequency","target-output-power","operational-mode","line-port","admin-state"] transponder_filter_fields = ["frequency", "target-output-power", "operational-mode", "line-port", "admin-state"]
MAX_RETRIES = 15 MAX_RETRIES = 15
DELAY_FUNCTION = delay_exponential(initial=0.01, increment=2.0, maximum=5.0) DELAY_FUNCTION = delay_exponential(initial=0.01, increment=2.0, maximum=5.0)
RETRY_DECORATOR = retry(max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') RETRY_DECORATOR = retry(max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect')
context_client= ContextClient() context_client= ContextClient()
port_xml_filter=f"/components/component[state[type='oc-platform-types:PORT']]/*" port_xml_filter=f"/components/component[state[type='oc-platform-types:PORT']]/*"
transceiver_xml_filter="/components/component[state[type='oc-platform-types:TRANSCEIVER']]/*" transceiver_xml_filter="/components/component[state[type='oc-platform-types:TRANSCEIVER']]/*"
class NetconfSessionHandler: class NetconfSessionHandler:
def __init__(self, address : str, port : int, **settings) -> None: def __init__(self, address : str, port : int, **settings) -> None:
self.__lock = threading.RLock() self.__lock = threading.RLock()
...@@ -110,10 +109,10 @@ class NetconfSessionHandler: ...@@ -110,10 +109,10 @@ class NetconfSessionHandler:
@property @property
def vendor(self): return self.__vendor def vendor(self): return self.__vendor
@property @property
def version(self): return self.__version def version(self): return self.__version
@property @property
def message_renderer(self): return self.__message_renderer def message_renderer(self): return self.__message_renderer
...@@ -121,7 +120,6 @@ class NetconfSessionHandler: ...@@ -121,7 +120,6 @@ class NetconfSessionHandler:
def get(self, filter=None, with_defaults=None): # pylint: disable=redefined-builtin def get(self, filter=None, with_defaults=None): # pylint: disable=redefined-builtin
with self.__lock: with self.__lock:
config=self.__manager.get(filter=filter, with_defaults=with_defaults) config=self.__manager.get(filter=filter, with_defaults=with_defaults)
return config return config
@RETRY_DECORATOR @RETRY_DECORATOR
...@@ -129,21 +127,16 @@ class NetconfSessionHandler: ...@@ -129,21 +127,16 @@ class NetconfSessionHandler:
self, config, target='running', default_operation=None, test_option=None, self, config, target='running', default_operation=None, test_option=None,
error_option=None, format='xml' # pylint: disable=redefined-builtin error_option=None, format='xml' # pylint: disable=redefined-builtin
): ):
response = None response = None
with self.__lock: with self.__lock:
response= self.__manager.edit_config( response= self.__manager.edit_config(
config, target=target, default_operation=default_operation, test_option=test_option, config, target=target, default_operation=default_operation, test_option=test_option,
error_option=error_option, format=format) error_option=error_option, format=format)
str_respones = str(response) str_respones = str(response)
if re.search(r'<ok/>', str_respones): if re.search(r'<ok/>', str_respones):
return True return True
return False
return False
@RETRY_DECORATOR @RETRY_DECORATOR
def locked(self, target): def locked(self, target):
...@@ -152,7 +145,7 @@ class NetconfSessionHandler: ...@@ -152,7 +145,7 @@ class NetconfSessionHandler:
@RETRY_DECORATOR @RETRY_DECORATOR
def commit(self, confirmed=False, timeout=None, persist=None, persist_id=None): def commit(self, confirmed=False, timeout=None, persist=None, persist_id=None):
return self.__manager.commit(confirmed=confirmed, timeout=timeout, persist=persist, persist_id=persist_id) return self.__manager.commit(confirmed=confirmed, timeout=timeout, persist=persist, persist_id=persist_id)
DRIVER_NAME = 'oc' DRIVER_NAME = 'oc'
METRICS_POOL = MetricsPool('Device', 'Driver', labels={'driver': DRIVER_NAME}) METRICS_POOL = MetricsPool('Device', 'Driver', labels={'driver': DRIVER_NAME})
def edit_config( # edit the configuration of openconfig devices def edit_config( # edit the configuration of openconfig devices
...@@ -175,8 +168,8 @@ def edit_config( ...@@ -175,8 +168,8 @@ def edit_config(
else : else :
#roadm media-channel #roadm media-channel
str_config_messages=create_media_channel_v2(resources) str_config_messages=create_media_channel_v2(resources)
#Disabling of the Configuration #Disabling of the Configuration
else : else:
# Device type is Transponder # Device type is Transponder
if (conditions['edit_type'] == "optical-channel"): if (conditions['edit_type'] == "optical-channel"):
_,ports,_=seperate_port_config(resources) _,ports,_=seperate_port_config(resources)
...@@ -187,35 +180,27 @@ def edit_config( ...@@ -187,35 +180,27 @@ def edit_config(
str_config_messages=delete_optical_band(resources) str_config_messages=delete_optical_band(resources)
else : else :
str_config_messages=disable_media_channel(resources) str_config_messages=disable_media_channel(resources)
for str_config_message in str_config_messages: for str_config_message in str_config_messages:
# configuration of the received templates # configuration of the received templates
if str_config_message is None: raise UnsupportedResourceKeyException("CONFIG") if str_config_message is None: raise UnsupportedResourceKeyException("CONFIG")
result= netconf_handler.edit_config( # configure the device
result= netconf_handler.edit_config( # configure the device config=str_config_message, target=target, default_operation=default_operation,
config=str_config_message, target=target, default_operation=default_operation, test_option=test_option, error_option=error_option, format=format)
test_option=test_option, error_option=error_option, format=format) if commit_per_rule:
if commit_per_rule: netconf_handler.commit() # configuration commit
netconf_handler.commit() # configuration commit
#results[i] = True #results[i] = True
results.append(result) results.append(result)
return results return results
class OCDriver(_Driver): class OCDriver(_Driver):
def __init__(self, address : str, port : int,device_uuid=None, **settings) -> None: def __init__(self, address : str, port : int,device_uuid=None, **settings) -> None:
super().__init__(DRIVER_NAME, address, port, **settings) super().__init__(DRIVER_NAME, address, port, **settings)
self.__logger = logging.getLogger('{:s}:[{:s}:{:s}]'.format(str(__name__), str(self.address), str(self.port))) self.__logger = logging.getLogger('{:s}:[{:s}:{:s}]'.format(str(__name__), str(self.address), str(self.port)))
self.__lock = threading.Lock() self.__lock = threading.Lock()
self.__subscriptions = TreeNode('.')
self.__started = threading.Event() self.__started = threading.Event()
self.__terminate = threading.Event() self.__terminate = threading.Event()
self.__scheduler = BackgroundScheduler(daemon=True) self.__scheduler = BackgroundScheduler(daemon=True)
...@@ -225,31 +210,24 @@ class OCDriver(_Driver): ...@@ -225,31 +210,24 @@ class OCDriver(_Driver):
job_defaults = {'coalesce': False, 'max_instances': 3}, job_defaults = {'coalesce': False, 'max_instances': 3},
timezone=pytz.utc) timezone=pytz.utc)
self._temp_address=f"{address}{port}" self._temp_address=f"{address}{port}"
self.__out_samples = queue.Queue()
self.__netconf_handler = NetconfSessionHandler(self.address, self.port, **(self.settings)) self.__netconf_handler = NetconfSessionHandler(self.address, self.port, **(self.settings))
self.__type = self.settings.get("type","optical-transponder") self.__type = self.settings.get("type","optical-transponder")
self.__device_uuid=device_uuid self.__device_uuid = device_uuid
self.__pending_tasks=[]
self.Connect() self.Connect()
def Connect(self) -> bool: def Connect(self) -> bool:
with self.__lock: with self.__lock:
if self.__started.is_set(): return True if self.__started.is_set(): return True
self.__netconf_handler.connect() self.__netconf_handler.connect()
self.__scheduler.start() self.__scheduler.start()
self.__started.set() self.__started.set()
return True return True
def Disconnect(self) -> bool: def Disconnect(self) -> bool:
with self.__lock: with self.__lock:
self.__terminate.set() self.__terminate.set()
if not self.__started.is_set(): return True if not self.__started.is_set(): return True
self.__scheduler.shutdown() self.__scheduler.shutdown()
self.__netconf_handler.disconnect() self.__netconf_handler.disconnect()
return True return True
...@@ -261,95 +239,90 @@ class OCDriver(_Driver): ...@@ -261,95 +239,90 @@ class OCDriver(_Driver):
@metered_subclass_method(METRICS_POOL) @metered_subclass_method(METRICS_POOL)
def GetConfig(self, resource_keys : List[str] = []) -> List[Tuple[str, Union[Any, None, Exception]]]: def GetConfig(self, resource_keys : List[str] = []) -> List[Tuple[str, Union[Any, None, Exception]]]:
chk_type('resources', resource_keys, list) chk_type('resources', resource_keys, list)
results = [] results = []
opticalConfig= OpticalConfig() opticalConfig= OpticalConfig()
with self.__lock:
config={}
transceivers={}
oc_values={}
ports_result=[]
oc_values["type"]=self.__type
try:
with self.__lock:
config = {}
transceivers = {}
oc_values = {}
ports_result = []
oc_values["type"] = self.__type
try:
xml_data = self.__netconf_handler.get().data_xml xml_data = self.__netconf_handler.get().data_xml
if self.__type == "optical-transponder":
if (self.__type == "optical-transponder"): extracted_values = transponder_values_extractor(
data_xml=xml_data, resource_keys=transponder_filter_fields, dic=config
extracted_values=transponder_values_extractor(data_xml=xml_data,resource_keys=transponder_filter_fields,dic=config) )
transceivers,optical_channels_params,channel_namespace,endpoints,ports_result=extracted_values transceivers, optical_channels_params, channel_namespace, endpoints, ports_result = extracted_values
oc_values["channels"]=optical_channels_params oc_values["channels"] = optical_channels_params
oc_values["transceivers"]=transceivers oc_values["transceivers"] = transceivers
oc_values["channel_namespace"]=channel_namespace oc_values["channel_namespace"] = channel_namespace
oc_values["endpoints"]=endpoints oc_values["endpoints"] = endpoints
oc_values["ports"]=ports_result oc_values["ports"] = ports_result
elif (self.__type =='openroadm') : elif (self.__type =='openroadm'):
extracted_values=openroadm_values_extractor(data_xml=xml_data,resource_keys=[],dic=oc_values) extracted_values=openroadm_values_extractor(data_xml=xml_data, resource_keys=[], dic=oc_values)
ports_result = extracted_values[1] ports_result = extracted_values[1]
else:
extracted_values = roadm_values_extractor(data_xml=xml_data, resource_keys=[], dic=config)
else :
extracted_values=roadm_values_extractor(data_xml=xml_data,resource_keys=[],dic=config)
ports_result = extracted_values[0] ports_result = extracted_values[0]
oc_values['optical_bands']=extracted_values[1] oc_values['optical_bands']=extracted_values[1]
oc_values['media_channels']=extracted_values[2] oc_values['media_channels']=extracted_values[2]
#results.append((resource_key, e)) # if validation fails, store the exception #results.append((resource_key, e)) # if validation fails, store the exception
#///////////////////////// store optical configurtaion //////////////////////////////////////////////////////// #///////////////////////// store optical configurtaion ////////////////////////////////////////////////////////
opticalConfig.config=json.dumps(oc_values) opticalConfig.config=json.dumps(oc_values)
if self.__device_uuid is not None: if self.__device_uuid is not None:
opticalConfig.device_id.device_uuid.uuid=self.__device_uuid opticalConfig.device_id.device_uuid.uuid=self.__device_uuid
results.append((f"/opticalconfigs/opticalconfig/{self.__device_uuid}",{"opticalconfig":opticalConfig})) results.append((f"/opticalconfigs/opticalconfig/{self.__device_uuid}",{"opticalconfig":opticalConfig}))
# context_client.connect() # context_client.connect()
# config_id=context_client.SetOpticalConfig(opticalConfig) # config_id=context_client.SetOpticalConfig(opticalConfig)
# context_client.close() # context_client.close()
except Exception as e: # pylint: disable=broad-except except Exception as e: # pylint: disable=broad-except
MSG = 'Exception retrieving {:s}' MSG = 'Exception retrieving {:s}'
self.__logger.info("error from getConfig %s",e) self.__logger.info("error from getConfig %s",e)
self.__logger.exception(MSG.format(e)) self.__logger.exception(MSG.format(e))
if(len(ports_result)>0) : results.extend(ports_result)
if len(ports_result) > 0: results.extend(ports_result)
return results return results
@metered_subclass_method(METRICS_POOL) @metered_subclass_method(METRICS_POOL)
def SetConfig(self, resources : List[Tuple[str, Any]],conditions:dict) -> List[Union[bool, Exception]]: def SetConfig(self, resources : List[Tuple[str, Any]],conditions:dict) -> List[Union[bool, Exception]]:
if len(resources) == 0: return [] if len(resources) == 0: return []
results=[] results = []
with self.__lock: with self.__lock:
if self.__netconf_handler.use_candidate: if self.__netconf_handler.use_candidate:
with self.__netconf_handler.locked(target='candidate'): with self.__netconf_handler.locked(target='candidate'):
results = edit_config( results = edit_config(
self.__netconf_handler, self.__logger, resources,conditions, target='candidate', self.__netconf_handler, self.__logger, resources, conditions, target='candidate',
commit_per_rule=self.__netconf_handler.commit_per_rule commit_per_rule=self.__netconf_handler.commit_per_rule
,) )
else: else:
results = edit_config(self.__netconf_handler, self.__logger, resources,conditions=conditions results = edit_config(
) self.__netconf_handler, self.__logger, resources, conditions=conditions
)
return results return results
@metered_subclass_method(METRICS_POOL) @metered_subclass_method(METRICS_POOL)
def DeleteConfig(self, resources : List[Tuple[str, Any]],conditions:dict,optical_device_configuration=None) -> List[Union[bool, Exception]]: def DeleteConfig(
self, resources : List[Tuple[str, Any]], conditions : dict,
optical_device_configuration = None
) -> List[Union[bool, Exception]]:
chk_type('resources', resources, list) chk_type('resources', resources, list)
if len(resources) == 0: return [] if len(resources) == 0: return []
with self.__lock: with self.__lock:
if self.__netconf_handler.use_candidate: if self.__netconf_handler.use_candidate:
with self.__netconf_handler.locked(target='candidate'): with self.__netconf_handler.locked(target='candidate'):
results = edit_config( results = edit_config(
self.__netconf_handler, self.__logger, resources, target='candidate', delete=True, self.__netconf_handler, self.__logger, resources, target='candidate', delete=True,
commit_per_rule=self.__netconf_handler.commit_per_rule,conditions=conditions) commit_per_rule=self.__netconf_handler.commit_per_rule, conditions=conditions
)
else: else:
results = edit_config(self.__netconf_handler, self.__logger, resources, delete=True,conditions=conditions) results = edit_config(
self.__netconf_handler, self.__logger, resources, delete=True, conditions=conditions
)
return results return results
# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
#
# 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 typing import Dict, List
from common.tools.object_factory.ConfigRule import json_config_rule_delete, json_config_rule_set
from service.service.service_handler_api.AnyTreeTools import TreeNode
def setup_config_rules(
service_uuid : str, connection_uuid : str, device_uuid : str, endpoint_uuid : str, endpoint_name : str,
service_settings : TreeNode, endpoint_settings : TreeNode
) -> List[Dict]:
if service_settings is None: return []
if endpoint_settings is None: return []
json_settings : Dict = service_settings.value
json_endpoint_settings : Dict = endpoint_settings.value
service_short_uuid = service_uuid.split('-')[-1]
network_instance_name = '{:s}-NetInst'.format(service_short_uuid)
network_interface_desc = '{:s}-NetIf'.format(service_uuid)
network_subinterface_desc = '{:s}-NetSubIf'.format(service_uuid)
mtu = json_settings.get('mtu', 1450 ) # 1512
#address_families = json_settings.get('address_families', [] ) # ['IPV4']
bgp_as = json_settings.get('bgp_as', 0 ) # 65000
bgp_route_target = json_settings.get('bgp_route_target', '0:0') # 65000:333
#router_id = json_endpoint_settings.get('router_id', '0.0.0.0') # '10.95.0.10'
route_distinguisher = json_endpoint_settings.get('route_distinguisher', '0:0' ) # '60001:801'
sub_interface_index = json_endpoint_settings.get('sub_interface_index', 0 ) # 1
vlan_id = json_endpoint_settings.get('vlan_id', 1 ) # 400
address_ip = json_endpoint_settings.get('address_ip', '0.0.0.0') # '2.2.2.1'
address_prefix = json_endpoint_settings.get('address_prefix', 24 ) # 30
if_subif_name = '{:s}.{:d}'.format(endpoint_name, vlan_id)
json_config_rules = [
json_config_rule_set(
'/network_instance[{:s}]'.format(network_instance_name), {
'name': network_instance_name, 'description': network_interface_desc, 'type': 'L3VRF',
'route_distinguisher': route_distinguisher,
#'router_id': router_id, 'address_families': address_families,
}),
json_config_rule_set(
'/interface[{:s}]'.format(endpoint_name), {
'name': endpoint_name, 'description': network_interface_desc, 'mtu': mtu,
}),
json_config_rule_set(
'/interface[{:s}]/subinterface[{:d}]'.format(endpoint_name, sub_interface_index), {
'name': endpoint_name, 'index': sub_interface_index,
'description': network_subinterface_desc, 'vlan_id': vlan_id,
'address_ip': address_ip, 'address_prefix': address_prefix,
}),
json_config_rule_set(
'/network_instance[{:s}]/interface[{:s}]'.format(network_instance_name, if_subif_name), {
'name': network_instance_name, 'id': if_subif_name, 'interface': endpoint_name,
'subinterface': sub_interface_index,
}),
json_config_rule_set(
'/network_instance[{:s}]/protocols[BGP]'.format(network_instance_name), {
'name': network_instance_name, 'identifier': 'BGP', 'protocol_name': 'BGP', 'as': bgp_as,
}),
json_config_rule_set(
'/network_instance[{:s}]/table_connections[STATIC][BGP][IPV4]'.format(network_instance_name), {
'name': network_instance_name, 'src_protocol': 'STATIC', 'dst_protocol': 'BGP',
'address_family': 'IPV4', #'default_import_policy': 'REJECT_ROUTE',
}),
json_config_rule_set(
'/network_instance[{:s}]/table_connections[DIRECTLY_CONNECTED][BGP][IPV4]'.format(
network_instance_name), {
'name': network_instance_name, 'src_protocol': 'DIRECTLY_CONNECTED', 'dst_protocol': 'BGP',
'address_family': 'IPV4', #'default_import_policy': 'REJECT_ROUTE',
}),
json_config_rule_set(
'/routing_policy/bgp_defined_set[{:s}_rt_import]'.format(network_instance_name), {
'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
}),
json_config_rule_set(
'/routing_policy/bgp_defined_set[{:s}_rt_import][route-target:{:s}]'.format(
network_instance_name, bgp_route_target), {
'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
'ext_community_member' : 'route-target:{:s}'.format(bgp_route_target),
}),
json_config_rule_set(
'/routing_policy/policy_definition[{:s}_import]'.format(network_instance_name), {
'policy_name': '{:s}_import'.format(network_instance_name),
}),
json_config_rule_set(
'/routing_policy/policy_definition[{:s}_import]/statement[{:s}]'.format(
network_instance_name, '3'), {
'policy_name': '{:s}_import'.format(network_instance_name), 'statement_name': '3',
'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
'match_set_options': 'ANY', 'policy_result': 'ACCEPT_ROUTE',
}),
json_config_rule_set(
# pylint: disable=duplicate-string-formatting-argument
'/network_instance[{:s}]/inter_instance_policies[{:s}_import]'.format(
network_instance_name, network_instance_name), {
'name': network_instance_name, 'import_policy': '{:s}_import'.format(network_instance_name),
}),
json_config_rule_set(
'/routing_policy/bgp_defined_set[{:s}_rt_export]'.format(network_instance_name), {
'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
}),
json_config_rule_set(
'/routing_policy/bgp_defined_set[{:s}_rt_export][route-target:{:s}]'.format(
network_instance_name, bgp_route_target), {
'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
'ext_community_member' : 'route-target:{:s}'.format(bgp_route_target),
}),
json_config_rule_set(
'/routing_policy/policy_definition[{:s}_export]'.format(network_instance_name), {
'policy_name': '{:s}_export'.format(network_instance_name),
}),
json_config_rule_set(
'/routing_policy/policy_definition[{:s}_export]/statement[{:s}]'.format(
network_instance_name, '3'), {
'policy_name': '{:s}_export'.format(network_instance_name), 'statement_name': '3',
'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
'match_set_options': 'ANY', 'policy_result': 'ACCEPT_ROUTE',
}),
json_config_rule_set(
# pylint: disable=duplicate-string-formatting-argument
'/network_instance[{:s}]/inter_instance_policies[{:s}_export]'.format(
network_instance_name, network_instance_name), {
'name': network_instance_name, 'export_policy': '{:s}_export'.format(network_instance_name),
}),
]
return json_config_rules
def teardown_config_rules(
service_uuid : str, connection_uuid : str, device_uuid : str, endpoint_uuid : str, endpoint_name : str,
service_settings : TreeNode, endpoint_settings : TreeNode
) -> List[Dict]:
if service_settings is None: return []
if endpoint_settings is None: return []
json_settings : Dict = service_settings.value
json_endpoint_settings : Dict = endpoint_settings.value
#mtu = json_settings.get('mtu', 1450 ) # 1512
#address_families = json_settings.get('address_families', [] ) # ['IPV4']
#bgp_as = json_settings.get('bgp_as', 0 ) # 65000
bgp_route_target = json_settings.get('bgp_route_target', '0:0') # 65000:333
#router_id = json_endpoint_settings.get('router_id', '0.0.0.0') # '10.95.0.10'
#route_distinguisher = json_endpoint_settings.get('route_distinguisher', '0:0' ) # '60001:801'
sub_interface_index = json_endpoint_settings.get('sub_interface_index', 0 ) # 1
vlan_id = json_endpoint_settings.get('vlan_id', 1 ) # 400
#address_ip = json_endpoint_settings.get('address_ip', '0.0.0.0') # '2.2.2.1'
#address_prefix = json_endpoint_settings.get('address_prefix', 24 ) # 30
if_subif_name = '{:s}.{:d}'.format(endpoint_name, vlan_id)
service_short_uuid = service_uuid.split('-')[-1]
network_instance_name = '{:s}-NetInst'.format(service_short_uuid)
#network_interface_desc = '{:s}-NetIf'.format(service_uuid)
#network_subinterface_desc = '{:s}-NetSubIf'.format(service_uuid)
json_config_rules = [
json_config_rule_delete(
'/network_instance[{:s}]/interface[{:s}]'.format(network_instance_name, if_subif_name), {
'name': network_instance_name, 'id': if_subif_name,
}),
json_config_rule_delete(
'/interface[{:s}]/subinterface[{:d}]'.format(endpoint_name, sub_interface_index), {
'name': endpoint_name, 'index': sub_interface_index,
}),
json_config_rule_delete(
'/interface[{:s}]'.format(endpoint_name), {
'name': endpoint_name,
}),
json_config_rule_delete(
'/network_instance[{:s}]/table_connections[DIRECTLY_CONNECTED][BGP][IPV4]'.format(
network_instance_name), {
'name': network_instance_name, 'src_protocol': 'DIRECTLY_CONNECTED', 'dst_protocol': 'BGP',
'address_family': 'IPV4',
}),
json_config_rule_delete(
'/network_instance[{:s}]/table_connections[STATIC][BGP][IPV4]'.format(network_instance_name), {
'name': network_instance_name, 'src_protocol': 'STATIC', 'dst_protocol': 'BGP',
'address_family': 'IPV4',
}),
json_config_rule_delete(
'/network_instance[{:s}]/protocols[BGP]'.format(network_instance_name), {
'name': network_instance_name, 'identifier': 'BGP', 'protocol_name': 'BGP',
}),
json_config_rule_delete(
# pylint: disable=duplicate-string-formatting-argument
'/network_instance[{:s}]/inter_instance_policies[{:s}_import]'.format(
network_instance_name, network_instance_name), {
'name': network_instance_name,
}),
json_config_rule_delete(
'/routing_policy/policy_definition[{:s}_import]/statement[{:s}]'.format(
network_instance_name, '3'), {
'policy_name': '{:s}_import'.format(network_instance_name), 'statement_name': '3',
}),
json_config_rule_delete(
'/routing_policy/policy_definition[{:s}_import]'.format(network_instance_name), {
'policy_name': '{:s}_import'.format(network_instance_name),
}),
json_config_rule_delete(
'/routing_policy/bgp_defined_set[{:s}_rt_import][route-target:{:s}]'.format(
network_instance_name, bgp_route_target), {
'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
'ext_community_member' : 'route-target:{:s}'.format(bgp_route_target),
}),
json_config_rule_delete(
'/routing_policy/bgp_defined_set[{:s}_rt_import]'.format(network_instance_name), {
'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
}),
json_config_rule_delete(
# pylint: disable=duplicate-string-formatting-argument
'/network_instance[{:s}]/inter_instance_policies[{:s}_export]'.format(
network_instance_name, network_instance_name), {
'name': network_instance_name,
}),
json_config_rule_delete(
'/routing_policy/policy_definition[{:s}_export]/statement[{:s}]'.format(
network_instance_name, '3'), {
'policy_name': '{:s}_export'.format(network_instance_name), 'statement_name': '3',
}),
json_config_rule_delete(
'/routing_policy/policy_definition[{:s}_export]'.format(network_instance_name), {
'policy_name': '{:s}_export'.format(network_instance_name),
}),
json_config_rule_delete(
'/routing_policy/bgp_defined_set[{:s}_rt_export][route-target:{:s}]'.format(
network_instance_name, bgp_route_target), {
'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
'ext_community_member' : 'route-target:{:s}'.format(bgp_route_target),
}),
json_config_rule_delete(
'/routing_policy/bgp_defined_set[{:s}_rt_export]'.format(network_instance_name), {
'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
}),
json_config_rule_delete(
'/network_instance[{:s}]'.format(network_instance_name), {
'name': network_instance_name
}),
]
return json_config_rules
...@@ -13,19 +13,20 @@ ...@@ -13,19 +13,20 @@
# limitations under the License. # limitations under the License.
import json, logging import json, logging
from anytree import RenderTree
from typing import Any, List, Optional, Tuple, Union from typing import Any, List, Optional, Tuple, Union
from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method
from common.proto.context_pb2 import ConfigRule, DeviceId, Service from common.proto.context_pb2 import DeviceId, Service
from common.tools.object_factory.Device import json_device_id from common.tools.object_factory.Device import json_device_id
from common.type_checkers.Checkers import chk_type from common.type_checkers.Checkers import chk_type
from common.DeviceTypes import DeviceTypeEnum from common.DeviceTypes import DeviceTypeEnum
from service.service.service_handler_api.Tools import get_device_endpoint_uuids, get_endpoint_matching from service.service.service_handler_api.Tools import get_endpoint_matching
from service.service.service_handler_api._ServiceHandler import _ServiceHandler from service.service.service_handler_api._ServiceHandler import _ServiceHandler
from service.service.service_handler_api.SettingsHandler import SettingsHandler from service.service.service_handler_api.SettingsHandler import SettingsHandler
from service.service.task_scheduler.TaskExecutor import TaskExecutor from service.service.task_scheduler.TaskExecutor import TaskExecutor
from .ConfigRules import setup_config_rules, teardown_config_rules from .OCTools import (
from .OCTools import convert_endpoints_to_flows, endpoints_to_flows, handle_flows_names , check_media_channel_existance convert_endpoints_to_flows, endpoints_to_flows,
#handle_flows_names, check_media_channel_existance
)
LOGGER = logging.getLogger(__name__) LOGGER = logging.getLogger(__name__)
...@@ -51,11 +52,9 @@ class OCServiceHandler(_ServiceHandler): ...@@ -51,11 +52,9 @@ class OCServiceHandler(_ServiceHandler):
settings=None settings=None
if self.__settings_handler.get('/settings-ob_{}'.format(connection_uuid)): if self.__settings_handler.get('/settings-ob_{}'.format(connection_uuid)):
is_opticalband=True is_opticalband=True
settings = self.__settings_handler.get('/settings-ob_{}'.format(connection_uuid)) settings = self.__settings_handler.get('/settings-ob_{}'.format(connection_uuid))
else: else:
settings = self.__settings_handler.get('/settings') settings = self.__settings_handler.get('/settings')
bidir = settings.value.get("bidir") bidir = settings.value.get("bidir")
...@@ -64,62 +63,44 @@ class OCServiceHandler(_ServiceHandler): ...@@ -64,62 +63,44 @@ class OCServiceHandler(_ServiceHandler):
#flow is the new variable that stores input-output relationship #flow is the new variable that stores input-output relationship
#flows = convert_endpoints_to_flows(endpoints) #flows = convert_endpoints_to_flows(endpoints)
flows = endpoints_to_flows(endpoints, bidir, is_opticalband) flows = endpoints_to_flows(endpoints, bidir, is_opticalband)
#handled_flows=handle_flows_names(flows=flows,task_executor=self.__task_executor) #handled_flows=handle_flows_names(flows=flows,task_executor=self.__task_executor)
results = [] results = []
#new cycle for setting optical devices
for device_uuid in flows.keys(): #new cycle for setting optical devices
for device_uuid, dev_flows in flows.items():
try: try:
dev_flows = flows[device_uuid]
device_obj = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid))) device_obj = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid)))
if settings:
if (settings):
self.__task_executor.configure_optical_device(device_obj, settings, dev_flows, is_opticalband) self.__task_executor.configure_optical_device(device_obj, settings, dev_flows, is_opticalband)
results.append(True) results.append(True)
except Exception as e: # pylint: disable=broad-except except Exception as e: # pylint: disable=broad-except
LOGGER.exception('Unable to configure Device({:s})'.format(str(device_uuid))) LOGGER.exception('Unable to configure Device({:s})'.format(str(device_uuid)))
results.append(e) results.append(e)
return results return results
@metered_subclass_method(METRICS_POOL) @metered_subclass_method(METRICS_POOL)
def DeleteEndpoint( def DeleteEndpoint(
self, endpoints : List[Tuple[str, str, Optional[str]]], connection_uuid : Optional[str] = None self, endpoints : List[Tuple[str, str, Optional[str]]], connection_uuid : Optional[str] = None
) -> List[Union[bool, Exception]]: ) -> List[Union[bool, Exception]]:
is_opticalband =False is_opticalband =False
flows = convert_endpoints_to_flows(endpoints) flows = convert_endpoints_to_flows(endpoints)
chk_type('endpoints', endpoints, list) chk_type('endpoints', endpoints, list)
if len(endpoints) == 0: return [] if len(endpoints) == 0: return []
if self.__settings_handler.get('/settings-ob_{}'.format(connection_uuid)): if self.__settings_handler.get('/settings-ob_{}'.format(connection_uuid)):
is_opticalband =True is_opticalband =True
settings = self.__settings_handler.get('/settings-ob_{}'.format(connection_uuid)) settings = self.__settings_handler.get('/settings-ob_{}'.format(connection_uuid))
else: else:
settings = self.__settings_handler.get('/settings') settings = self.__settings_handler.get('/settings')
dev_flows=[]
results = [] results = []
for device_uuid in flows.keys(): for device_uuid, dev_flows in flows.items():
try: try:
channel_indexes= [] channel_indexes= []
dev_flows = flows[device_uuid]
device_obj = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid))) device_obj = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid)))
if (device_obj.device_type == DeviceTypeEnum.OPTICAL_TRANSPONDER._value_): if (device_obj.device_type == DeviceTypeEnum.OPTICAL_TRANSPONDER._value_):
...@@ -134,21 +115,19 @@ class OCServiceHandler(_ServiceHandler): ...@@ -134,21 +115,19 @@ class OCServiceHandler(_ServiceHandler):
dst_endpoint_obj = get_endpoint_matching(device_obj, dst) dst_endpoint_obj = get_endpoint_matching(device_obj, dst)
dist_enpoint_name=dst_endpoint_obj.name dist_enpoint_name=dst_endpoint_obj.name
channel_indexes.append((src_enpoint_name,dist_enpoint_name)) channel_indexes.append((src_enpoint_name,dist_enpoint_name))
else : else:
if not is_opticalband: if not is_opticalband:
if 'flow_id' in settings.value: if 'flow_id' in settings.value:
channel_indexes.append(settings.value["flow_id"])
channel_indexes.append(settings.value["flow_id"]) elif is_opticalband:
elif is_opticalband: if "ob_id" in settings.value:
if "ob_id" in settings.value: channel_indexes.append(settings.value["ob_id"])
channel_indexes.append(settings.value["ob_id"])
if len(channel_indexes) > 0:
if len(channel_indexes)>0: errors = self.__task_executor.deconfigure_optical_device(
errors=self.__task_executor.deconfigure_optical_device(device=device_obj device=device_obj, channel_indexes=channel_indexes,
,channel_indexes=channel_indexes is_opticalband=is_opticalband, dev_flow=dev_flows
,is_opticalband=is_opticalband )
,dev_flow=dev_flows)
# if (len(errors)==0): # if (len(errors)==0):
# service_id =self.__service.service_id # service_id =self.__service.service_id
# if not is_opticalband : # if not is_opticalband :
...@@ -199,29 +178,21 @@ class OCServiceHandler(_ServiceHandler): ...@@ -199,29 +178,21 @@ class OCServiceHandler(_ServiceHandler):
def DeleteConfig(self, resources : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: def DeleteConfig(self, resources : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]:
chk_type('resources', resources, list) chk_type('resources', resources, list)
if len(resources) == 0: return [] if len(resources) == 0: return []
service_id =self.__service.service_id service_id = self.__service.service_id
results = [] results = []
for resource in resources: for resource in resources:
try: try:
self.__settings_handler.delete(resource[0]) self.__settings_handler.delete(resource[0])
# self.__task_executor.delete_setting(service_id,"/settings","value") # self.__task_executor.delete_setting(service_id,"/settings","value")
except Exception as e: # pylint: disable=broad-except except Exception as e: # pylint: disable=broad-except
LOGGER.exception('Unable to DeleteConfig({:s})'.format(str(resource))) LOGGER.exception('Unable to DeleteConfig({:s})'.format(str(resource)))
results.append(e) results.append(e)
return results return results
def check_media_channel(self,connection_uuid): def check_media_channel(self,connection_uuid):
if self.__settings_handler.get('/settings-ob_{}'.format(connection_uuid)): if self.__settings_handler.get('/settings-ob_{}'.format(connection_uuid)):
return False
return False
else: else:
return True
return True
\ No newline at end of file
...@@ -12,11 +12,11 @@ ...@@ -12,11 +12,11 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
from service.service.service_handler_api.Tools import get_device_endpoint_uuids, get_endpoint_matching import logging, json
from typing import Dict, Any, List, Optional, Tuple from typing import Dict, List, Optional, Tuple
import logging , json from common.proto.context_pb2 import DeviceId, Service
from common.proto.context_pb2 import ConfigRule, DeviceId, Service
from common.tools.object_factory.Device import json_device_id from common.tools.object_factory.Device import json_device_id
from service.service.service_handler_api.Tools import get_endpoint_matching
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
...@@ -286,7 +286,6 @@ def conn_flows(endpoints : List[Tuple[str, str, Optional[str]]], bidir : int): ...@@ -286,7 +286,6 @@ def conn_flows(endpoints : List[Tuple[str, str, Optional[str]]], bidir : int):
entries[device_uuid].append(entry_tuple) entries[device_uuid].append(entry_tuple)
i = i + 2 i = i + 2
else: else:
return {} return {}
#rx tp #rx tp
endpoint = endpoints[i] endpoint = endpoints[i]
...@@ -296,51 +295,48 @@ def conn_flows(endpoints : List[Tuple[str, str, Optional[str]]], bidir : int): ...@@ -296,51 +295,48 @@ def conn_flows(endpoints : List[Tuple[str, str, Optional[str]]], bidir : int):
entry_tuple = endpoint_uuid, "0", entry_tuple = endpoint_uuid, "0",
entries[device_uuid].append(entry_tuple) entries[device_uuid].append(entry_tuple)
return entries return entries
def endpoints_to_flows(endpoints : List[Tuple[str, str, Optional[str]]], bidir : int, is_ob: bool)->Dict: def endpoints_to_flows(endpoints : List[Tuple[str, str, Optional[str]]], bidir : int, is_ob: bool)->Dict:
if is_ob: if is_ob:
entries = ob_flows(endpoints, bidir) entries = ob_flows(endpoints, bidir)
else: else:
entries = conn_flows(endpoints, bidir) entries = conn_flows(endpoints, bidir)
return entries return entries
def get_device_endpint_name (endpoint_uuid:str,device_uuid:str,task_executor)->Tuple: def get_device_endpint_name(endpoint_uuid : str, device_uuid : str, task_executor) -> Tuple:
device_obj = task_executor.get_device(DeviceId(**json_device_id(device_uuid))) device_obj = task_executor.get_device(DeviceId(**json_device_id(device_uuid)))
endpoint_obj = get_endpoint_matching(device_obj, endpoint_uuid) endpoint_obj = get_endpoint_matching(device_obj, endpoint_uuid)
endpoint_name = endpoint_obj.name endpoint_name = endpoint_obj.name
return (device_obj.name, endpoint_name) return (device_obj.name, endpoint_name)
def handle_flows_names (task_executor,flows:dict)->Dict : def handle_flows_names(task_executor, flows : dict) -> Dict:
new_flows={} new_flows = {}
for index,( device_uuid_key , device_endpoints_list) in enumerate(flows.items()): for index, (device_uuid_key, device_endpoints_list) in enumerate(flows.items()):
for endpoint_tupple in device_endpoints_list: for endpoint_tupple in device_endpoints_list:
source_port=None source_port = None
destination_port=None destination_port = None
device_name="" device_name = ""
source_endpoint,destination_endpoint =endpoint_tupple source_endpoint, destination_endpoint = endpoint_tupple
if (source_endpoint !='0'): if source_endpoint != '0':
if get_device_endpint_name(source_endpoint,device_uuid_key,task_executor) is not None: if get_device_endpint_name(source_endpoint, device_uuid_key, task_executor) is not None:
device_name,source_port=get_device_endpint_name(source_endpoint,device_uuid_key,task_executor) device_name, source_port = get_device_endpint_name(
if (destination_endpoint !='0'): source_endpoint, device_uuid_key, task_executor
if get_device_endpint_name(destination_endpoint,device_uuid_key,task_executor) is not None: )
device_name,destination_port=get_device_endpint_name(destination_endpoint,device_uuid_key,task_executor) if destination_endpoint != '0':
if (device_name not in new_flows): if get_device_endpint_name(destination_endpoint, device_uuid_key, task_executor) is not None:
new_flows[device_name]=[] device_name, destination_port = get_device_endpint_name(
new_flows[device_name].append((source_port,destination_port)) destination_endpoint, device_uuid_key, task_executor
)
if device_name not in new_flows:
new_flows[device_name] = []
new_flows[device_name].append((source_port, destination_port))
return new_flows return new_flows
def check_media_channel_existance(service : Service):
def check_media_channel_existance (service:Service): has_media_channel = False
has_media_channel=False
for config_rule in service.service_config.config_rules: for config_rule in service.service_config.config_rules:
if isinstance(config_rule.custom.resource_value, str):
if isinstance(config_rule.custom.resource_value,str): settings = json.dumps(config_rule.custom.resource_value)
settings=json.dumps(config_rule.custom.resource_value) if "flow_id" in settings:
if "flow_id" in settings : has_media_channel = True
has_media_channel=True
return has_media_channel return has_media_channel
\ No newline at end of file
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
<h1>Link {{ link.name }} ({{ link.link_id.link_uuid.uuid }})</h1> <h1>Link {{ link.name }} ({{ link.link_id.link_uuid.uuid }})</h1>
<div class="row mb-3"> <div class="row mb-3">
<div class="col-sm-3"> <div class="col-sm-3">
<button type="button" class="btn btn-success" onclick="window.location.href='{{ url_for('optical_link.home') }}'"> <button type="button" class="btn btn-success" onclick="window.location.href='{{ url_for('link.home') }}'">
<i class="bi bi-box-arrow-in-left"></i> <i class="bi bi-box-arrow-in-left"></i>
Back to link list Back to link list
</button> </button>
...@@ -102,7 +102,6 @@ ...@@ -102,7 +102,6 @@
</table> </table>
<!-- Modal --> <!-- Modal -->
<div class="modal fade" id="deleteModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" <div class="modal fade" id="deleteModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1"
aria-labelledby="staticBackdropLabel" aria-hidden="true"> aria-labelledby="staticBackdropLabel" aria-hidden="true">
......
...@@ -78,7 +78,7 @@ ...@@ -78,7 +78,7 @@
</td> </td>
<td> <td>
<a href="{{ url_for('optical_link.detail', link_uuid=link.link_id.link_uuid.uuid) }}"> <a href="{{ url_for('link.detail', link_uuid=link.link_id.link_uuid.uuid) }}">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-eye" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-eye" viewBox="0 0 16 16">
<path d="M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8zM1.173 8a13.133 13.133 0 0 1 1.66-2.043C4.12 4.668 5.88 3.5 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.133 13.133 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755C11.879 11.332 10.119 12.5 8 12.5c-2.12 0-3.879-1.168-5.168-2.457A13.134 13.134 0 0 1 1.172 8z"/> <path d="M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8zM1.173 8a13.133 13.133 0 0 1 1.66-2.043C4.12 4.668 5.88 3.5 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.133 13.133 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755C11.879 11.332 10.119 12.5 8 12.5c-2.12 0-3.879-1.168-5.168-2.457A13.134 13.134 0 0 1 1.172 8z"/>
<path d="M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0z"/> <path d="M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0z"/>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment