Commit 4a4abba5 authored by Pablo Armingol's avatar Pablo Armingol
Browse files

Bug fix and provisional alternative to pyangbind

parent 3f935135
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -207,11 +207,11 @@ def edit_config(
    format='xml' # pylint: disable=redefined-builtin
):
    str_method = 'DeleteConfig' if delete else 'SetConfig'
    results = []
    if "L2VSI" in resources[0][1] and netconf_handler.vendor == "CISCO":
        #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)        
        results = []
        for i,resource in enumerate(resources):
            results.append(True)
    else:
@@ -234,12 +234,15 @@ def edit_config(
                        test_option=test_option, error_option=error_option, format=format)
                    if commit_per_rule:
                        netconf_handler.commit()                                                                               # configuration commit
                results[i] = True
                
                #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[i] = e # if validation fails, store the exception
                results.append(e)

        if not commit_per_rule:
            try:
+157 −0
Original line number Diff line number Diff line
from yattag import Doc, indent

def acl_set_mng(data, DEL):
    doc, tag, text = Doc().tagtext()

    type     = ["ACL_UNDEFINED", "ACL_IPV4","ACL_IPV6","ACL_L2","ACL_MPLS","ACL_MIXED"]
    f_action = ["UNDEFINED", "DROP","ACCEPT","REJECT"]
    l_action = ["UNDEFINED", "LOG_NONE","LOG_SYSLOG"]
    
    Acl_data    = data["rule_set"]
    Acl_name    = Acl_data['name']
    Acl_type    = type[Acl_data['type']]
    Acl_desc    = Acl_data['description']
    Acl_entries = Acl_data['entries']
    with tag('acl', xmlns="http://openconfig.net/yang/acl"):
        if DEL == True:
            with tag('acl-sets' ,'xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="delete"'):
                with tag('acl-set'):
                    with tag('name'):text(Acl_name)
                    with tag('type'):text(Acl_type)
                    with tag('acl-entries'):
                            for entry in Acl_entries:
                                ID     = entry['sequence_id']
                                desc   = entry['description']
                                match  = entry['match']
                                action = entry['action']
                                with tag('acl-entry'): 
                                    with tag('sequence-id'):text(ID)
        else:
            with tag('acl-sets'):
                with tag('acl-set'):
                    with tag('name'):text(Acl_name)
                    with tag('type'):text(Acl_type)
                    with tag('config'):
                        with tag('name'): text(Acl_name)
                        with tag('type'): text(Acl_type)
                        with tag('description'):text(Acl_desc)
                        with tag('acl-entries'):
                            for entry in Acl_entries:
                                ID     = entry['sequence_id']
                                desc   = entry['description']
                                match  = entry['match']
                                action = entry['action']
                                with tag('acl-entry'): 
                                    with tag('sequence-id'):text(ID)
                                    with tag('config'):
                                        with tag('acl-entry'):   text(ID)
                                        with tag('description'): text(desc)
                                    # Configuration per type
                                    if "L2" in Acl_type:
                                        with tag('l2'):
                                            for key, value in match.items():
                                                if   "src_address"     in key and len(value) != 0: 
                                                    with tag('source-mac'):text(value)
                                                elif "dst_address"     in key and len(value) != 0:
                                                    with tag('destination-mac'):text(value)   
                                    elif "IPV4" in Acl_type:
                                        with tag('ipv4'):
                                            for key, value in match.items():
                                                if   "src_address"       in key and len(value) != 0:
                                                    with tag('source-address'):text(value)
                                                elif "dst_address"       in key and len(value) != 0:
                                                    with tag('destination-address'):text(value)
                                                elif "protocol"          in key                    :
                                                    with tag('protocol'):text(value)
                                                elif "hop_limit"         in key                    : 
                                                    with tag('hop-limit'):text(value)
                                                elif "dscp"              in key                    : 
                                                    with tag('dscp'):text(value)
                                        with tag('transport'):
                                            for key, value in match.items():
                                                if   "src_port"     in key : 
                                                    with tag('source-port'):text(value)
                                                elif "dst_port"     in key : 
                                                    with tag('destination-port'):text(value)
                                                elif "tcp_flags"    in key : 
                                                    with tag('tcp-flags'):text(value)        
                                    elif "IPV6" in Acl_type:
                                        with tag('ipv6'):
                                            for key, value in match.items():
                                                if   "src_address"       in key and len(value) != 0:
                                                    with tag('source-address'):text(value)
                                                elif "dst_address"       in key and len(value) != 0:
                                                    with tag('destination-address'):text(value)
                                                elif "protocol"          in key                    :
                                                    with tag('protocol'):text(value)
                                                elif "hop_limit"         in key                    : 
                                                    with tag('hop-limit'):text(value)
                                                elif "dscp"              in key                    : 
                                                    with tag('dscp'):text(value)
                                    with tag('actions'):
                                        for key, value in action.items():
                                            if "forward_action" in key : 
                                                with tag('forward-action'):text(l_action[value])
                                            elif "log_action"     in key :
                                                with tag('log-action'):text(f_action[value])
    result = indent(
        doc.getvalue(),
        indentation = ' '*2,
        newline = '\r\n'
    )
    return result

def acl_interface(data,vendor, DEL):
    doc, tag, text = Doc().tagtext()

    type      = ["ACL_UNDEFINED", "ACL_IPV4","ACL_IPV6","ACL_L2","ACL_MPLS","ACL_MIXED"]
    ID        = data['endpoint_id']['endpoint_uuid']['uuid']
    Acl_data  = data["rule_set"]
    Acl_name  = Acl_data['name']
    Acl_type  = type[Acl_data['type']]

    with tag('acl', xmlns="http://openconfig.net/yang/acl"):
            with tag('interfaces'):
                with tag('interface'):
                    with tag('id'):text(ID)
                    with tag('config'):
                        with tag('id'):text(ID)
                    with tag('interface-ref'):
                        with tag('config'):
                            with tag('interface'):text(ID)
                            if vendor == 'ADVA': 
                                with tag('subinterface'): text(0)
                            else:
                                with tag('subinterface'): text('subinterface')
                    with tag('ingress-acl-sets'):
                        with tag('ingress-acl-set'):
                            with tag('set-name'):text(Acl_name)
                            with tag('type'):text(Acl_type)
    result = indent(
        doc.getvalue(),
        indentation = ' '*2,
        newline = '\r\n'
    )
    return result

# TESTING
'''
data = {'endpoint_id':{'device_id': {'device_uuid': {'uuid': 'R155'}},'endpoint_uuid':{'uuid':'eth-1/0/21.999'}},
        'rule_set':{'name':"ACL_L4",'type':1,'description':'acl ipv4','entries':[{'sequence_id': 1, 'description': 'IPv4_ACL', 'match': {'dst_address': '172.16.4.4', 'dscp': 0, 'protocol': 6, 'src_address': '172.16.5.5', 'src_port': 0, 'dst_port': 0, 'start_mpls_label': 0, 'end_mpls_label': 0}, 'action': {'forward_action': 1, 'log_action': 1}},
                                                                                 {'sequence_id': 2, 'description': 'L2_ACL', 'match': {'dst_address': '', 'dscp': 0, 'protocol': 0, 'src_address': '', 'src_port': 52, 'dst_port': 950, 'start_mpls_label': 0, 'end_mpls_label': 0}, 'action': {'forward_action': 1, 'log_action': 1}}]}}

print('\t\tACL')
print(acl_set_mng(data, False))
print('\t\tACL')
print(acl_set_mng(data, True))

print('\n\n\t\tInterfaz')
print(acl_interface(data,'ADVA', False))
print('\n\n\t\tInterfaz')
print(acl_interface(data,'ADVA', True))

'''
'''
OLD - VERSION

from .openconfig_acl import openconfig_acl
from pyangbind.lib.serialise import pybindIETFXMLEncoder
from common.tools.grpc.Tools import grpc_message_to_json
@@ -115,3 +271,4 @@ def acl_interface(parameters,vendor):
    acl_set = acl_set.replace('<acl>','<acl xmlns="http://openconfig.net/yang/acl">')           
    acl_set = acl_set.replace('</openconfig-acl>','')                                           
    return(acl_set)
'''
 No newline at end of file
+14 −14
Original line number Diff line number Diff line
@@ -15,8 +15,8 @@
import json
import lxml.etree as ET
from typing import Collection, Dict, Any
from .ACL.ACL_multivendor              import acl_mgmt        
from .VPN.Network_instance_multivendor import create_network_instance, associate_virtual_circuit, associate_RP_to_NI, add_protocol_NI, create_table_conns, associate_If_to_NI
from .ACL.ACL_multivendor              import acl_set_mng        
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

@@ -55,35 +55,35 @@ def generate_templates(resource_key: str, resource_value: str, delete: bool,vend
    list_resource_key = resource_key.split("/")                                         # the rule resource key management
    if "network_instance" in list_resource_key[1]:                                      # network instance rules management
        data: Dict[str, Any] = json.loads(resource_value)
        data['DEL'] = delete
        #data['DEL'] = delete
        if "connection_point" in resource_key:
            result_templates.append(associate_virtual_circuit(data))
        elif "inter_instance_policies" in resource_key:
            result_templates.append(associate_RP_to_NI(data))
        elif "protocols" in resource_key:
            if vendor == "ADVA": result_templates.append(add_protocol_NI(data))
            if vendor == "ADVA": result_templates.append(add_protocol_NI(data, vendor, delete))
        elif "table_connections" in resource_key:
            result_templates.append(create_table_conns(data))
            result_templates.append(create_table_conns(data, delete))
        elif "interface" in resource_key:
            result_templates.append(associate_If_to_NI(data))
            result_templates.append(associate_If_to_NI(data,delete))
        else:
            result_templates.append(create_network_instance(data,vendor))
            result_templates.append(create_NI(data,vendor,delete))

    elif "interface" in list_resource_key[1]:                                           # interface rules management
    if "interface" in list_resource_key[1]:                                           # interface rules management
        data: Dict[str, Any] = json.loads(resource_value)
        data['DEL'] = delete
        #data['DEL'] = delete
        if "subinterface" in resource_key:
            result_templates.append(create_If_SubIf(data))
            result_templates.append(create_If_SubIf(data, vendor, delete))

    elif "routing_policy" in list_resource_key[1]:                                      # routing policy rules management
        data: Dict[str, Any] = json.loads(resource_value)
        data['DEL'] = delete
        #data['DEL'] = delete
        if "bgp_defined_set" in resource_key:
            result_templates.append(create_rp_def(data))
            result_templates.append(create_rp_def(data, delete))
        else:
            result_templates.append(create_rp_statement(data))
            result_templates.append(create_rp_statement(data, delete))
    else:
        if "acl_ruleset" in resource_key:                                               # acl rules management
            result_templates.extend(acl_mgmt(resource_value,vendor))
            result_templates.extend(acl_set_mng(resource_value, delete))

    return result_templates
 No newline at end of file
+89 −0
Original line number Diff line number Diff line
from yattag import Doc, indent
"""
# Method Name: create_If_SubIf
  
# Parameters:
  - Interface_name:     [str]  Variable to set the name of the Interface that will be configured. [Mandatory parameter in all cases].
  - DEL:                [bool] Variable that determines if the template will be for creating (DEL = False) or for deleting (DEL = True) a configuration [Mandatory parameter in all cases].
  - Interface_type:     [str]  Variable that specifies the type of interface, can take the value "l2vlan" or "l3ipvlan" [Only mandatory if DEL = False].
  - SubInterface_Index: [int]  Variable to set the index of the subinterface.[Only mandatory if DEL = False].
  - Description:        [str]  Variable for adding a description to the Interface   [Only mandatory if DEL = False].

# Functionality:
  This method generates the template of an Interface with subinterface, used both for L2 and L3 VPNs.
  This template will be generated for configuring a device, making use of pyangbind. 
  To generate the template the following steps are performed:
  1) Checks if the DEL variable is true (Template for deleting a existent Interface or) or false (Template for creating a new Interface with Subinterface).
  2) Create the template correspondent in each case, assigning the correspondent parameters with their value.
  3) Make the correspondent replaces for the unssuported configurations by pyangbind.
  
# Return:
  [str] The newly generated template according to the specified parameters.
"""
def create_If_SubIf(data,vendor, DEL):
    doc, tag, text = Doc().tagtext()

    with tag('interfaces', xmlns="http://openconfig.net/yang/interfaces"):
        if DEL == True: 
            with tag('interface' ,'xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="delete"'):
                with tag('name'):text(data['name'])
        else:
            with tag('interface'):
                with tag('name'):text(data['name'])
                with tag('config'):
                    with tag('name'):text(data['name'])
                    with tag('type', 'xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type"'):text('ianaift:',data['type'])
                    if 'description' in data:
                        with tag('description'):text(data['description'])
                    if 'mtu' in data:
                        with tag('mtu'):text(data['mtu'])
                    with tag('enabled'):text('true')    
                with tag('subinterfaces'):
                    with tag('subinterface'):
                        if vendor == 'ADVA':
                            with tag('index'): text('0')
                        with tag('config'):
                            with tag('index'): text('0')
                            if vendor == 'ADVA' and len(data['vlan_id'] == 0): 
                                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_id'])
                        if "l3ipvlan" in data['type']: 
                            with tag('ipv4',  xmlns="http://openconfig.net/yang/interfaces/ip"):
                                with tag('addresses'):
                                    with tag('address'):
                                        with tag('ip'):text(data['address_ip'])
                                        with tag('config'):
                                            with tag('ip'):text(data['address_ip'])
                                            with tag('prefix-length'):text(data['address_prefix'])
    result = indent(
        doc.getvalue(),
        indentation = ' '*2,
        newline = '\r\n'
    )
    return result

#TESTING
'''
data = {'name'          : 'eth-1/0/22.222',
        'type'          : 'l3ipvlan',
        'mtu'           : '3000',
        'index'         : '0',
        'description'   : 'Interfaz con subinterfaz', 
        'vlan_id'       : '222',
        'address_ip'    : '172.16.55.55', 
        'address_prefix': '24'}

print('\n\t\tINTERFAZ - Create')
print(create_If_SubIf(data,'ADVA', False))
print('\n\t\tINTERFAZ - Delete')
print(create_If_SubIf(data,'ADVA', True))
'''


'''
from .openconfig_interfaces import openconfig_interfaces
from pyangbind.lib.serialise import pybindIETFXMLEncoder

@@ -141,3 +228,5 @@ def create_If_SubIf(parameters): #[L2/L3] Creates
        InterfaceInstance_set = InterfaceInstance_set.replace('</openconfig-interfaces>','')

    return (InterfaceInstance_set) 
  
'''
+423 −0

File changed.

Preview size limit exceeded, changes collapsed.

Loading