Skip to content
Snippets Groups Projects
Commit 39b800e1 authored by Pablo Armingol's avatar Pablo Armingol
Browse files

integration of IP-link service in OCdriver

parent 8f5b56cc
No related branches found
No related tags found
2 merge requests!341Draft: Resolve "optical bandwidth expansion",!239Draft: Resolve "(TID) Creation of IP link with supporting coherent pluggable to pluggable connection"
...@@ -12,9 +12,9 @@ ...@@ -12,9 +12,9 @@
# 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.
import time
import json import json
import logging, pytz, queue, re, threading import logging, pytz, re, threading
#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
...@@ -22,12 +22,11 @@ from apscheduler.schedulers.background import BackgroundScheduler ...@@ -22,12 +22,11 @@ from apscheduler.schedulers.background import BackgroundScheduler
from ncclient.manager import Manager, connect_ssh from ncclient.manager import Manager, connect_ssh
from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method
from common.tools.client.RetryDecorator import delay_exponential from common.tools.client.RetryDecorator import delay_exponential
from common.type_checkers.Checkers import chk_type from common.type_checkers.Checkers import chk_length, chk_string, chk_type
from device.service.driver_api.Exceptions import UnsupportedResourceKeyException from device.service.driver_api.Exceptions import UnsupportedResourceKeyException
from device.service.driver_api._Driver import _Driver from device.service.driver_api._Driver import _Driver
from device.service.driver_api.AnyTreeTools import TreeNode from .templates import compose_config, cli_compose_config, ufi_interface, cisco_interface
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 .templates.VPN.roadms import ( from .templates.VPN.roadms import (
create_optical_band, disable_media_channel, delete_optical_band, create_media_channel_v2 create_optical_band, disable_media_channel, delete_optical_band, create_media_channel_v2
) )
...@@ -36,11 +35,10 @@ from .RetryDecorator import retry ...@@ -36,11 +35,10 @@ from .RetryDecorator import retry
from context.client.ContextClient import ContextClient from context.client.ContextClient import ContextClient
from common.proto.context_pb2 import OpticalConfig from common.proto.context_pb2 import OpticalConfig
from .templates.discovery_tool.transponders import transponder_values_extractor from .templates.discovery_tool.transponders import transponder_values_extractor
from .templates.discovery_tool.roadms import roadm_values_extractor, extract_media_channels from .templates.discovery_tool.roadms import roadm_values_extractor
from .templates.discovery_tool.open_roadm import openroadm_values_extractor from .templates.discovery_tool.open_roadm import openroadm_values_extractor
from .templates.VPN.openroadm import network_media_channel_handler from .templates.VPN.openroadm import network_media_channel_handler
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)
...@@ -51,9 +49,6 @@ logging.getLogger('monitoring-client').setLevel(logging.INFO if DEBUG_MODE else ...@@ -51,9 +49,6 @@ logging.getLogger('monitoring-client').setLevel(logging.INFO if DEBUG_MODE else
RE_GET_ENDPOINT_FROM_INTERFACE_KEY = re.compile(r'.*interface\[([^\]]+)\].*') RE_GET_ENDPOINT_FROM_INTERFACE_KEY = re.compile(r'.*interface\[([^\]]+)\].*')
RE_GET_ENDPOINT_FROM_INTERFACE_XPATH = re.compile(r".*interface\[oci\:name\='([^\]]+)'\].*") RE_GET_ENDPOINT_FROM_INTERFACE_XPATH = re.compile(r".*interface\[oci\:name\='([^\]]+)'\].*")
# Collection of samples through NetConf is very slow and each request collects all the data.
# Populate a cache periodically (when first interface is interrogated).
# Evict data after some seconds, when data is considered as outdated
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'
...@@ -200,6 +195,65 @@ def edit_config( ...@@ -200,6 +195,65 @@ def edit_config(
#results[i] = True #results[i] = True
results.append(result) results.append(result)
if netconf_handler.vendor == "CISCO":
if "L2VSI" in resources[0][1]:
#Configure by CLI
logger.warning("CLI Configuration")
cli_compose_config(resources, delete=delete, host= netconf_handler._NetconfSessionHandler__address, user=netconf_handler._NetconfSessionHandler__username, passw=netconf_handler._NetconfSessionHandler__password)
for i,resource in enumerate(resources):
results.append(True)
else:
logger.warning("CLI Configuration CISCO INTERFACE")
cisco_interface(resources, delete=delete, host= netconf_handler._NetconfSessionHandler__address, user=netconf_handler._NetconfSessionHandler__username, passw=netconf_handler._NetconfSessionHandler__password)
for i,resource in enumerate(resources):
results.append(True)
elif netconf_handler.vendor == "UFISPACE":
#Configure by CLI
logger.warning("CLI Configuration: {:s}".format(resources))
ufi_interface(resources, delete=delete, host= netconf_handler._NetconfSessionHandler__address, user=netconf_handler._NetconfSessionHandler__username, passw=netconf_handler._NetconfSessionHandler__password)
for i,resource in enumerate(resources):
results.append(True)
else:
for i,resource in enumerate(resources):
str_resource_name = 'resources[#{:d}]'.format(i)
try:
logger.debug('[{:s}] resource = {:s}'.format(str_method, str(resource)))
chk_type(str_resource_name, resource, (list, tuple))
chk_length(str_resource_name, resource, min_length=2, max_length=2)
resource_key,resource_value = resource
chk_string(str_resource_name + '.key', resource_key, allow_empty=False)
str_config_messages = compose_config( # get template for configuration
resource_key, resource_value, delete=delete, vendor=netconf_handler.vendor, message_renderer=netconf_handler.message_renderer)
for str_config_message in str_config_messages: # configuration of the received templates
if str_config_message is None: raise UnsupportedResourceKeyException(resource_key)
logger.debug('[{:s}] str_config_message[{:d}] = {:s}'.format(
str_method, len(str_config_message), str(str_config_message)))
netconf_handler.edit_config( # configure the device
config=str_config_message, target=target, default_operation=default_operation,
test_option=test_option, error_option=error_option, format=format)
if commit_per_rule:
netconf_handler.commit() # configuration commit
if 'table_connections' in resource_key:
time.sleep(5) # CPU usage might exceed critical level after route redistribution, BGP daemon needs time to reload
#results[i] = True
results.append(True)
except Exception as e: # pylint: disable=broad-except
str_operation = 'preparing' if target == 'candidate' else ('deleting' if delete else 'setting')
msg = '[{:s}] Exception {:s} {:s}: {:s}'
logger.exception(msg.format(str_method, str_operation, str_resource_name, str(resource)))
#results[i] = e # if validation fails, store the exception
results.append(e)
if not commit_per_rule:
try:
netconf_handler.commit()
except Exception as e: # pylint: disable=broad-except
msg = '[{:s}] Exception committing: {:s}'
str_operation = 'preparing' if target == 'candidate' else ('deleting' if delete else 'setting')
logger.exception(msg.format(str_method, str_operation, str(resources)))
results = [e for _ in resources] # if commit fails, set exception in each resource
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 yattag import Doc, indent
def ip_link_mgmt(data,vendor, delete):
doc, tag, text = Doc().tagtext()
ID = data['endpoint_id']['endpoint_uuid']['uuid']
DATA = data["rule_set"]
with tag('interfaces', xmlns="http://openconfig.net/yang/interfaces"):
if delete == True:
with tag('interface' ,'xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="delete"'):
with tag('name'):text(ID)
else:
with tag('interface'):
with tag('name'):text(ID)
with tag('config'):
with tag('name'):text(ID)
with tag('type', 'xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type"'):text('ianaift:l3ipvlan')
with tag('enabled'):text('true')
with tag('subinterfaces'):
with tag('subinterface'):
if vendor is None or vendor == 'ADVA':
with tag('index'): text('0')
with tag('config'):
with tag('index'): text('0')
if vendor == 'ADVA' and not 'vlan'in data:
with tag('untagged-allowed', 'xmlns="http://www.advaoptical.com/cim/adva-dnos-oc-interfaces"'):text('true')
with tag('vlan', xmlns="http://openconfig.net/yang/vlan"):
with tag('match'):
with tag('single-tagged'):
with tag('config'):
with tag('vlan-id'):text(DATA['vlan'])
with tag('ipv4', xmlns="http://openconfig.net/yang/interfaces/ip"):
with tag('addresses'):
with tag('address'):
with tag('ip'):text(DATA['ip'])
with tag('config'):
with tag('ip'):text(DATA['ip'])
with tag('prefix-length'):text(DATA['mask'])
result = indent(
doc.getvalue(),
indentation = ' '*2,
newline = '\r\n'
)
return result
\ No newline at end of file
...@@ -13,12 +13,10 @@ ...@@ -13,12 +13,10 @@
# limitations under the License. # limitations under the License.
import re,logging import re,logging
import json
import lxml.etree as ET import lxml.etree as ET
from typing import Collection, Dict, Any from typing import Collection, Dict
from .IP_LINK.IP_LINK_multivendor import ip_link_mgmt
from yattag import Doc, indent
from .VPN.physical import create_optical_channel
def add_value_from_tag(target : Dict, field_name: str, field_value : ET.Element, cast=None) -> None: def add_value_from_tag(target : Dict, field_name: str, field_value : ET.Element, cast=None) -> None:
if isinstance(field_value,str) or field_value is None or field_value.text is None: return if isinstance(field_value,str) or field_value is None or field_value.text is None: return
...@@ -49,14 +47,12 @@ def add_value_from_collection(target : Dict, field_name: str, field_value : Coll ...@@ -49,14 +47,12 @@ def add_value_from_collection(target : Dict, field_name: str, field_value : Coll
# Return: # Return:
[dict] Set of templates generated according to the configuration rule [dict] Set of templates generated according to the configuration rule
""" """
def generate_templates(resource_key: str, resource_value: str, channel:str) -> str: # template management to be configured def generate_templates(resource_key: str, resource_value: str, delete: bool,vendor:str) -> str: # template management to be configured
result_templates = [] result_templates = []
data={} list_resource_key = resource_key.split("/") # the rule resource key management
data['name']=channel if "ip_link" in list_resource_key[1]: # network instance rules management
data['resource_key']=resource_key result_templates.append(ip_link_mgmt(resource_value,vendor,delete))
data['value']=resource_value
#result_templates.append(create_physical_config(data))
return result_templates return result_templates
......
...@@ -12,3 +12,288 @@ ...@@ -12,3 +12,288 @@
# 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.
import json, logging, lxml.etree as ET, re
import time
from typing import Any, Dict, Optional
from jinja2 import Environment, PackageLoader, select_autoescape
import paramiko
from .Tools import generate_templates
LOGGER = logging.getLogger(__name__)
LOGGER = logging.getLogger(__name__)
RE_REMOVE_FILTERS = re.compile(r'\[[^\]]+\]')
RE_REMOVE_FILTERS_2 = re.compile(r'\/[a-z]+:')
EMPTY_CONFIG = '<config></config>'
EMPTY_FILTER = '<filter></filter>'
JINJA_ENV = Environment(loader=PackageLoader('device.service.drivers.openconfig'), autoescape=select_autoescape())
"""
# Method Name: compose_config
# Parameters:
- resource_key: [str] Variable to identify the rule to be executed.
- resource_value: [str] Variable with the configuration parameters of the rule to be executed.
- delete: [bool] Variable to identify whether to create or delete the rule.
- vendor: [str] Variable to identify the vendor of the equipment to be configured.
- message_renderer [str] Variable to dientify template generation method. Can be "jinja" or "pyangbind".
# Functionality:
This method calls the function obtains the equipment configuration template according to the value of the variable "message_renderer".
Depending on the value of this variable, it gets the template with "jinja" or "pyangbind".
# Return:
[dict] Set of templates obtained according to the configuration method
"""
def compose_config( # template generation
resource_key : str, resource_value : str, delete : bool = False, vendor : Optional[str] = None, message_renderer = str
) -> str:
if (message_renderer == "pyangbind"):
templates = (generate_templates(resource_key, resource_value, delete, vendor))
return [
'<config>{:s}</config>'.format(template) # format correction
for template in templates
]
elif (message_renderer == "jinja"):
templates = []
template_name = '{:s}/edit_config.xml'.format(RE_REMOVE_FILTERS.sub('', resource_key))
templates.append(JINJA_ENV.get_template(template_name))
data : Dict[str, Any] = json.loads(resource_value)
operation = 'delete' if delete else 'merge' # others
#operation = 'delete' if delete else '' # ipinfusion?
return [
'<config>{:s}</config>'.format(
template.render(**data, operation=operation, vendor=vendor).strip())
for template in templates
]
else:
raise ValueError('Invalid message_renderer value: {}'.format(message_renderer))
"""
# Method Name: cli_compose_config
# Parameters:
- resource_key: [str] Variable to identify the rule to be executed.
- resource_value: [str] Variable with the configuration parameters of the rule to be executed.
- delete: [bool] Variable to identify whether to create or delete the rule.
- vendor: [str] Variable to identify the vendor of the equipment to be configured.
- message_renderer [str] Variable to dientify template generation method. Can be "jinja" or "pyangbind".
# Functionality:
This method calls the function obtains the equipment configuration template according to the value of the variable "message_renderer".
Depending on the value of this variable, it gets the template with "jinja" or "pyangbind".
# Return:
[dict] Set of templates obtained according to the configuration method
"""
def cli_compose_config(resources, delete: bool, host: str, user: str, passw: str): #Method used for configuring via CLI directly L2VPN in CISCO devices
key_value_data = {}
for path, json_str in resources:
key_value_data[path] = json_str
# Iterate through the resources and extract parameter values dynamically
for path, json_str in resources:
data = json.loads(json_str)
if 'VC_ID' in data: vc_id = data['VC_ID']
if 'connection_point' in data: connection_point = data['connection_point']
if 'remote_system' in data: remote_system = data['remote_system']
if 'interface' in data:
interface = data['interface']
interface = interface.split("-") #New Line To Avoid Bad Endpoint Name In CISCO
interface = interface[1]
if 'vlan_id' in data: vlan_id = data['vlan_id']
if 'name' in data: ni_name = data['name']
if 'type' in data: ni_type = data['type']
if 'index' in data: subif_index = data['index']
if 'description' in data: description = data['description']
else: description = " "
# initialize the SSH client
ssh_client = paramiko.SSHClient()
ssh_client.load_system_host_keys()
# add to known hosts
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
ssh_client.connect(hostname=host, username=user, password=passw, look_for_keys=False)
#print("Connection successful")
LOGGER.warning("Connection successful")
except:
#print("[!] Cannot connect to the SSH Server")
LOGGER.warning("[!] Cannot connect to the SSH Server")
exit()
try:
# Open an SSH shell
channel = ssh_client.invoke_shell()
channel.send('enable\n')
time.sleep(1)
channel.send('conf term\n')
time.sleep(0.1)
channel.send(f"interface {interface} l2transport\n")
time.sleep(0.1)
channel.send('description l2vpn_vpws_example\n')
time.sleep(0.1)
channel.send(f"encapsulation dot1q {vlan_id}\n")
time.sleep(0.1)
channel.send('mtu 9088\n')
time.sleep(0.1)
channel.send('commit\n')
time.sleep(0.1)
channel.send('l2vpn\n')
time.sleep(0.1)
channel.send('load-balancing flow src-dst-ip\n')
time.sleep(0.1)
channel.send('pw-class l2vpn_vpws_profile_example\n')
time.sleep(0.1)
channel.send('encapsulation mpls\n')
time.sleep(0.1)
channel.send('transport-mode vlan passthrough\n')
time.sleep(0.1)
channel.send('control-word\n')
time.sleep(0.1)
channel.send('exit\n')
time.sleep(0.1)
channel.send('l2vpn\n')
time.sleep(0.1)
channel.send('xconnect group l2vpn_vpws_group_example\n')
time.sleep(0.1)
channel.send(f"p2p {ni_name}\n")
time.sleep(0.1)
channel.send(f"interface {interface}\n") #Ignore the VlanID because the interface already includes the vlanid tag
time.sleep(0.1)
channel.send(f"neighbor ipv4 {remote_system} pw-id {vc_id}\n")
time.sleep(0.1)
channel.send('pw-class l2vpn_vpws_profile_example\n')
time.sleep(0.1)
channel.send('exit\n')
time.sleep(0.1)
channel.send(f"description {description}\n")
time.sleep(0.1)
channel.send('commit\n')
time.sleep(0.1)
# Capturar la salida del comando
output = channel.recv(65535).decode('utf-8')
#print(output)
LOGGER.warning(output)
# Close the SSH shell
channel.close()
except Exception as e:
LOGGER.exception(f"Error with the CLI configuration: {e}")
# Close the SSH client
ssh_client.close()
def ufi_interface(resources, delete: bool, host: str, user: str, passw: str): #Method used for configuring via CLI directly L2VPN in CISCO devices
key_value_data = {}
for path, json_str in resources:
key_value_data[path] = json_str
# initialize the SSH client
ssh_client = paramiko.SSHClient()
ssh_client.load_system_host_keys()
# add to known hosts
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
ssh_client.connect(hostname=host, username=user, password=passw, look_for_keys=False)
LOGGER.warning("Connection successful")
except:
LOGGER.warning("[!] Cannot connect to the SSH Server")
exit()
interface = 'ge100-0/0/3/1'
ip = '1.1.1.1'
mask = '24'
vlan = '1212'
try:
# Open an SSH shell
channel = ssh_client.invoke_shell()
time.sleep(5)
channel.send('config\n')
time.sleep(1)
channel.send(f'interfaces {interface} \n')
time.sleep(1)
channel.send('admin-state enabled \n')
time.sleep(1)
channel.send(f'ipv4-address {ip}/{mask} \n')
time.sleep(1)
channel.send(f'vlan-id {vlan} \n')
time.sleep(1)
channel.send('commit\n')
time.sleep(1)
output = channel.recv(65535).decode('utf-8')
LOGGER.warning(output)
# Close the SSH shell
channel.close()
except Exception as e:
LOGGER.exception(f"Error with the CLI configuration: {e}")
# Close the SSH client
ssh_client.close()
def cisco_interface(resources, delete: bool, host: str, user: str, passw: str): #Method used for configuring via CLI directly L2VPN in CISCO devices
key_value_data = {}
for path, json_str in resources:
key_value_data[path] = json_str
# initialize the SSH client
ssh_client = paramiko.SSHClient()
ssh_client.load_system_host_keys()
# add to known hosts
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
ssh_client.connect(hostname=host, username=user, password=passw, look_for_keys=False)
LOGGER.warning("Connection successful")
except:
LOGGER.warning("[!] Cannot connect to the SSH Server")
exit()
interface = 'FourHundredGigE0/0/0/10.1212'
ip = '1.1.1.1'
mask = '24'
vlan = '1212'
try:
# Open an SSH shell
channel = ssh_client.invoke_shell()
time.sleep(1)
channel.send('config\n')
time.sleep(0.1)
channel.send(f'interface {interface} \n')
time.sleep(0.1)
channel.send('no shutdown\n')
time.sleep(0.1)
channel.send(f'ipv4 address {ip}/{mask} \n')
time.sleep(0.1)
channel.send(f'encapsulation dot1q {vlan} \n')
time.sleep(0.1)
channel.send('commit\n')
time.sleep(0.1)
output = channel.recv(65535).decode('utf-8')
LOGGER.warning(output)
# Close the SSH shell
channel.close()
except Exception as e:
LOGGER.exception(f"Error with the CLI configuration: {e}")
# Close the SSH client
ssh_client.close()
...@@ -115,6 +115,12 @@ SERVICE_HANDLERS = [ ...@@ -115,6 +115,12 @@ SERVICE_HANDLERS = [
FilterFieldEnum.DEVICE_DRIVER : DeviceDriverEnum.DEVICEDRIVER_OPENCONFIG, FilterFieldEnum.DEVICE_DRIVER : DeviceDriverEnum.DEVICEDRIVER_OPENCONFIG,
} }
]), ]),
(IP_LinkServiceHandler, [
{
FilterFieldEnum.SERVICE_TYPE : ServiceTypeEnum.SERVICETYPE_IPLINK,
FilterFieldEnum.DEVICE_DRIVER : DeviceDriverEnum.DEVICEDRIVER_OC,
}
]),
(QKDServiceHandler, [ (QKDServiceHandler, [
{ {
FilterFieldEnum.SERVICE_TYPE : ServiceTypeEnum.SERVICETYPE_QKD, FilterFieldEnum.SERVICE_TYPE : ServiceTypeEnum.SERVICETYPE_QKD,
......
...@@ -43,9 +43,6 @@ class IP_LinkServiceHandler(_ServiceHandler): ...@@ -43,9 +43,6 @@ class IP_LinkServiceHandler(_ServiceHandler):
chk_type('endpoints', endpoints, list) chk_type('endpoints', endpoints, list)
if len(endpoints) == 0: return [] if len(endpoints) == 0: return []
service_uuid = self.__service.service_id.service_uuid.uuid
settings = self.__settings_handler.get('/settings')
results = [] results = []
for endpoint in endpoints: for endpoint in endpoints:
try: try:
......
# 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.
import logging
from typing import Any, Dict, List, Optional, Tuple
from service.service.service_handler_api.AnyTreeTools import TreeNode
LOGGER = logging.getLogger(__name__)
def get_value(field_name : str, *containers, default=None) -> Optional[Any]:
if len(containers) == 0: raise Exception('No containers specified')
for container in containers:
if field_name not in container: continue
return container[field_name]
return default
def setup_config_rules(
endpoint_name : str, endpoint_ip_link : List [Tuple]
) -> List[Dict]:
json_config_rules = [
]
for res_key, res_value in endpoint_ip_link:
json_config_rules.append(
{'action': 1, 'ip_link': res_value}
)
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, device_settings : TreeNode, endpoint_settings : TreeNode
) -> List[Dict]:
if service_settings is None: return []
if device_settings is None: return []
if endpoint_settings is None: return []
json_settings : Dict = service_settings.value
json_device_settings : Dict = device_settings.value
json_endpoint_settings : Dict = endpoint_settings.value
settings = (json_settings, json_endpoint_settings, json_device_settings)
json_config_rules = []
return json_config_rules
...@@ -15,16 +15,17 @@ ...@@ -15,16 +15,17 @@
import json, logging import json, logging
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 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 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_endpoint_matching from service.service.service_handler_api.Tools import get_device_endpoint_uuids, 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, convert_endpoints_to_flows
#handle_flows_names, check_media_channel_existance #handle_flows_names, check_media_channel_existance
) )
...@@ -68,6 +69,28 @@ class OCServiceHandler(_ServiceHandler): ...@@ -68,6 +69,28 @@ class OCServiceHandler(_ServiceHandler):
#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 = []
for endpoint in endpoints:
try:
device_uuid, endpoint_uuid = get_device_endpoint_uuids(endpoint)
device_obj = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid)))
endpoint_obj = get_endpoint_matching(device_obj, endpoint_uuid)
endpoint_ip_link = self.__settings_handler.get_endpoint_ip_link(device_obj, endpoint_obj)
endpoint_name = endpoint_obj.name
json_config_rules = setup_config_rules(
endpoint_name, endpoint_ip_link)
if len(json_config_rules) > 0:
del device_obj.device_config.config_rules[:]
for json_config_rule in json_config_rules:
device_obj.device_config.config_rules.append(ConfigRule(**json_config_rule))
self.__task_executor.configure_device(device_obj)
results.append(True)
except Exception as e: # pylint: disable=broad-except
LOGGER.exception('Unable to SetEndpoint({:s})'.format(str(endpoint)))
results.append(e)
LOGGER.info(f"flows {flows} ") LOGGER.info(f"flows {flows} ")
LOGGER.info(f"settings {settings} ") LOGGER.info(f"settings {settings} ")
...@@ -102,6 +125,32 @@ class OCServiceHandler(_ServiceHandler): ...@@ -102,6 +125,32 @@ class OCServiceHandler(_ServiceHandler):
settings = self.__settings_handler.get('/settings') settings = self.__settings_handler.get('/settings')
results = [] results = []
for endpoint in endpoints:
try:
device_uuid, endpoint_uuid = get_device_endpoint_uuids(endpoint)
device_obj = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid)))
device_settings = self.__settings_handler.get_device_settings(device_obj)
endpoint_obj = get_endpoint_matching(device_obj, endpoint_uuid)
endpoint_settings = self.__settings_handler.get_endpoint_settings(device_obj, endpoint_obj)
endpoint_name = endpoint_obj.name
json_config_rules = teardown_config_rules(
service_uuid, connection_uuid, device_uuid, endpoint_uuid, endpoint_name,
settings, device_settings, endpoint_settings)
if len(json_config_rules) > 0:
del device_obj.device_config.config_rules[:]
for json_config_rule in json_config_rules:
device_obj.device_config.config_rules.append(ConfigRule(**json_config_rule))
self.__task_executor.configure_device(device_obj)
results.append(True)
except Exception as e: # pylint: disable=broad-except
LOGGER.exception('Unable to DeleteEndpoint({:s})'.format(str(endpoint)))
results.append(e)
for device_uuid, dev_flows in flows.items(): for device_uuid, dev_flows in flows.items():
try: try:
channel_indexes= [] channel_indexes= []
......
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