Loading src/device/service/Tools.py +2 −3 Original line number Diff line number Diff line Loading @@ -332,9 +332,8 @@ def compute_rules_to_add_delete( elif config_rule_kind == 'ip_link': # resource management of "ip_link" rule device_uuid = config_rule.ip_link.endpoint_id.device_id.device_uuid.uuid endpoint_uuid = config_rule.ip_link.endpoint_id.endpoint_uuid.uuid ip_link_ruleset_name = config_rule.ip_link.rule_set.name IP_LINK_KEY_TEMPLATE = '/device[{:s}]/endpoint[{:s}]/ip_link_ruleset[{:s}]' key_or_path = IP_LINK_KEY_TEMPLATE.format(device_uuid, endpoint_uuid, ip_link_ruleset_name) IP_LINK_KEY_TEMPLATE = '/device[{:s}]/endpoint[{:s}]/ip_link_ruleset' key_or_path = IP_LINK_KEY_TEMPLATE.format(device_uuid, endpoint_uuid) request_config_rules.append(( config_rule.action, key_or_path, grpc_message_to_json(config_rule.ip_link) )) Loading src/device/service/drivers/openconfig/OpenConfigDriver.py +16 −4 Original line number Diff line number Diff line Loading @@ -30,7 +30,7 @@ from device.service.driver_api.Exceptions import UnsupportedResourceKeyException from device.service.driver_api._Driver import _Driver from device.service.driver_api.AnyTreeTools import TreeNode, get_subnode, set_subnode_value #dump_subtree #from .Tools import xml_pretty_print, xml_to_dict, xml_to_file from .templates import ALL_RESOURCE_KEYS, EMPTY_CONFIG, compose_config, get_filter, parse, cli_compose_config from .templates import ALL_RESOURCE_KEYS, EMPTY_CONFIG, compose_config, get_filter, parse, cli_compose_config, ufi_interface, cisco_interface from .RetryDecorator import retry DEBUG_MODE = False Loading Loading @@ -212,12 +212,24 @@ def edit_config( ): str_method = 'DeleteConfig' if delete else 'SetConfig' results = [] if "L2VSI" in resources[0][1] and netconf_handler.vendor == "CISCO": 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) for i,resource in enumerate(resources): results.append(True) else: for i,resource in enumerate(resources): str_resource_name = 'resources[#{:d}]'.format(i) Loading src/device/service/drivers/openconfig/templates/IP_LINK/IP_LINK_multivendor.py 0 → 100755 +59 −0 Original line number Diff line number Diff line # 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 src/device/service/drivers/openconfig/templates/Tools.py +8 −5 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ import json import lxml.etree as ET from typing import Collection, Dict, Any from .ACL.ACL_multivendor import acl_mgmt from .IP_LINK.IP_LINK_multivendor import ip_link_mgmt from .VPN.Network_instance_multivendor import create_NI, associate_virtual_circuit, associate_RP_to_NI, add_protocol_NI, create_table_conns, associate_If_to_NI from .VPN.Interfaces_multivendor import create_If_SubIf from .VPN.Routing_policy import create_rp_def, create_rp_statement Loading Loading @@ -70,7 +71,7 @@ def generate_templates(resource_key: str, resource_value: str, delete: bool,vend else: result_templates.append(create_NI(data,vendor,delete)) if "interface" in list_resource_key[1]: # interface rules management elif "interface" in list_resource_key[1]: # interface rules management data: Dict[str, Any] = json.loads(resource_value) #data['DEL'] = delete if "subinterface" in resource_key: Loading @@ -83,8 +84,10 @@ def generate_templates(resource_key: str, resource_value: str, delete: bool,vend result_templates.append(create_rp_def(data, delete)) else: result_templates.append(create_rp_statement(data, delete)) else: if "acl_ruleset" in resource_key: # acl rules management elif "acl_ruleset" in resource_key: # acl rules management result_templates.extend(acl_mgmt(resource_value,vendor, delete)) else: if "ip_link" in resource_key: result_templates.append(ip_link_mgmt(resource_value,vendor,delete)) return result_templates No newline at end of file src/device/service/drivers/openconfig/templates/__init__.py +119 −1 Original line number Diff line number Diff line Loading @@ -253,3 +253,121 @@ def cli_compose_config(resources, delete: bool, host: str, user: str, passw: str # Close the SSH client ssh_client.close() def ufi_interface(resources, delete: bool): #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 # 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='10.95.90.75', username='dnroot', password='dnroot', 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() 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) # 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 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 # Iterate through the resources and extract parameter values dynamically # 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='10.90.95.150', username='cisco', password='cisco123', 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() 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) # 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() Loading
src/device/service/Tools.py +2 −3 Original line number Diff line number Diff line Loading @@ -332,9 +332,8 @@ def compute_rules_to_add_delete( elif config_rule_kind == 'ip_link': # resource management of "ip_link" rule device_uuid = config_rule.ip_link.endpoint_id.device_id.device_uuid.uuid endpoint_uuid = config_rule.ip_link.endpoint_id.endpoint_uuid.uuid ip_link_ruleset_name = config_rule.ip_link.rule_set.name IP_LINK_KEY_TEMPLATE = '/device[{:s}]/endpoint[{:s}]/ip_link_ruleset[{:s}]' key_or_path = IP_LINK_KEY_TEMPLATE.format(device_uuid, endpoint_uuid, ip_link_ruleset_name) IP_LINK_KEY_TEMPLATE = '/device[{:s}]/endpoint[{:s}]/ip_link_ruleset' key_or_path = IP_LINK_KEY_TEMPLATE.format(device_uuid, endpoint_uuid) request_config_rules.append(( config_rule.action, key_or_path, grpc_message_to_json(config_rule.ip_link) )) Loading
src/device/service/drivers/openconfig/OpenConfigDriver.py +16 −4 Original line number Diff line number Diff line Loading @@ -30,7 +30,7 @@ from device.service.driver_api.Exceptions import UnsupportedResourceKeyException from device.service.driver_api._Driver import _Driver from device.service.driver_api.AnyTreeTools import TreeNode, get_subnode, set_subnode_value #dump_subtree #from .Tools import xml_pretty_print, xml_to_dict, xml_to_file from .templates import ALL_RESOURCE_KEYS, EMPTY_CONFIG, compose_config, get_filter, parse, cli_compose_config from .templates import ALL_RESOURCE_KEYS, EMPTY_CONFIG, compose_config, get_filter, parse, cli_compose_config, ufi_interface, cisco_interface from .RetryDecorator import retry DEBUG_MODE = False Loading Loading @@ -212,12 +212,24 @@ def edit_config( ): str_method = 'DeleteConfig' if delete else 'SetConfig' results = [] if "L2VSI" in resources[0][1] and netconf_handler.vendor == "CISCO": 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) for i,resource in enumerate(resources): results.append(True) else: for i,resource in enumerate(resources): str_resource_name = 'resources[#{:d}]'.format(i) Loading
src/device/service/drivers/openconfig/templates/IP_LINK/IP_LINK_multivendor.py 0 → 100755 +59 −0 Original line number Diff line number Diff line # 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
src/device/service/drivers/openconfig/templates/Tools.py +8 −5 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ import json import lxml.etree as ET from typing import Collection, Dict, Any from .ACL.ACL_multivendor import acl_mgmt from .IP_LINK.IP_LINK_multivendor import ip_link_mgmt from .VPN.Network_instance_multivendor import create_NI, associate_virtual_circuit, associate_RP_to_NI, add_protocol_NI, create_table_conns, associate_If_to_NI from .VPN.Interfaces_multivendor import create_If_SubIf from .VPN.Routing_policy import create_rp_def, create_rp_statement Loading Loading @@ -70,7 +71,7 @@ def generate_templates(resource_key: str, resource_value: str, delete: bool,vend else: result_templates.append(create_NI(data,vendor,delete)) if "interface" in list_resource_key[1]: # interface rules management elif "interface" in list_resource_key[1]: # interface rules management data: Dict[str, Any] = json.loads(resource_value) #data['DEL'] = delete if "subinterface" in resource_key: Loading @@ -83,8 +84,10 @@ def generate_templates(resource_key: str, resource_value: str, delete: bool,vend result_templates.append(create_rp_def(data, delete)) else: result_templates.append(create_rp_statement(data, delete)) else: if "acl_ruleset" in resource_key: # acl rules management elif "acl_ruleset" in resource_key: # acl rules management result_templates.extend(acl_mgmt(resource_value,vendor, delete)) else: if "ip_link" in resource_key: result_templates.append(ip_link_mgmt(resource_value,vendor,delete)) return result_templates No newline at end of file
src/device/service/drivers/openconfig/templates/__init__.py +119 −1 Original line number Diff line number Diff line Loading @@ -253,3 +253,121 @@ def cli_compose_config(resources, delete: bool, host: str, user: str, passw: str # Close the SSH client ssh_client.close() def ufi_interface(resources, delete: bool): #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 # 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='10.95.90.75', username='dnroot', password='dnroot', 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() 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) # 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 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 # Iterate through the resources and extract parameter values dynamically # 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='10.90.95.150', username='cisco', password='cisco123', 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() 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) # 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()