Commit e597be50 authored by Lluis Gifre Renom's avatar Lluis Gifre Renom
Browse files

Merge branch 'fix/tid-openconfig-acls' into 'develop'

Fixes on OpenConfig and ACLs

See merge request !139
parents 280a4771 c8dafe29
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -288,7 +288,7 @@ def compute_rules_to_add_delete(
            acl_ruleset_name = config_rule.acl.rule_set.name                     # get the acl name
            acl_ruleset_name = config_rule.acl.rule_set.name                     # get the acl name
            ACL_KEY_TEMPLATE = '/device[{:s}]/endpoint[{:s}]/acl_ruleset[{:s}]'
            ACL_KEY_TEMPLATE = '/device[{:s}]/endpoint[{:s}]/acl_ruleset[{:s}]'
            key_or_path = ACL_KEY_TEMPLATE.format(device_uuid, endpoint_uuid, acl_ruleset_name)            
            key_or_path = ACL_KEY_TEMPLATE.format(device_uuid, endpoint_uuid, acl_ruleset_name)            
            context_config_rules[key_or_path] = config_rule.acl                  # get the resource value of the acl
            context_config_rules[key_or_path] = grpc_message_to_json(config_rule.acl)    # get the resource value of the acl
 
 
    request_config_rules = []
    request_config_rules = []
    for config_rule in request.device_config.config_rules:
    for config_rule in request.device_config.config_rules:
@@ -304,7 +304,7 @@ def compute_rules_to_add_delete(
            ACL_KEY_TEMPLATE = '/device[{:s}]/endpoint[{:s}]/acl_ruleset[{:s}]'
            ACL_KEY_TEMPLATE = '/device[{:s}]/endpoint[{:s}]/acl_ruleset[{:s}]'
            key_or_path = ACL_KEY_TEMPLATE.format(device_uuid, endpoint_uuid, acl_ruleset_name) 
            key_or_path = ACL_KEY_TEMPLATE.format(device_uuid, endpoint_uuid, acl_ruleset_name) 
            request_config_rules.append((
            request_config_rules.append((
                config_rule.action, key_or_path, config_rule.acl
                config_rule.action, key_or_path, grpc_message_to_json(config_rule.acl)
            ))
            ))


    resources_to_set    : List[Tuple[str, Any]] = [] # key, value
    resources_to_set    : List[Tuple[str, Any]] = [] # key, value
+66 −33
Original line number Original line Diff line number Diff line
@@ -14,20 +14,38 @@


from yattag import Doc, indent
from yattag import Doc, indent


def acl_set_mng(data, DEL):
RULE_TYPE_MAPPING = {
    'ACLRULETYPE_UNDEFINED': 'ACL_UNDEFINED',
    'ACLRULETYPE_IPV4'     : 'ACL_IPV4',
    'ACLRULETYPE_IPV6'     : 'ACL_IPV6',
    'ACLRULETYPE_L2'       : 'ACL_L2',
    'ACLRULETYPE_MPLS'     : 'ACL_MPLS',
    'ACLRULETYPE_MIXED'    : 'ACL_MIXED',
}

FORWARDING_ACTION_MAPPING = {
    'ACLFORWARDINGACTION_UNDEFINED': 'UNDEFINED',
    'ACLFORWARDINGACTION_DROP'     : 'DROP',
    'ACLFORWARDINGACTION_ACCEPT'   : 'ACCEPT',
    'ACLFORWARDINGACTION_REJECT'   : 'REJECT',
}

LOG_ACTION_MAPPING = {
    'ACLLOGACTION_UNDEFINED': 'UNDEFINED',
    'ACLLOGACTION_NOLOG'    : 'LOG_NONE',
    'ACLLOGACTION_SYSLOG'   : 'LOG_SYSLOG',
}

def acl_set_mng(data,vendor, delete):
    doc, tag, text = Doc().tagtext()
    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_data    = data["rule_set"]
    Acl_name    = Acl_data['name']
    Acl_name    = Acl_data['name']
    Acl_type    = type[Acl_data['type']]
    Acl_type    = RULE_TYPE_MAPPING[Acl_data['type']]
    Acl_desc    = Acl_data['description']
    Acl_desc    = Acl_data['description']
    Acl_entries = Acl_data['entries']
    Acl_entries = Acl_data['entries']
    with tag('acl', xmlns="http://openconfig.net/yang/acl"):
    with tag('acl', xmlns="http://openconfig.net/yang/acl"):
        if DEL == True:
        if delete:
            with tag('acl-sets' ,'xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="delete"'):
            with tag('acl-sets' ,'xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="delete"'):
                with tag('acl-set'):
                with tag('acl-set'):
                    with tag('name'):text(Acl_name)
                    with tag('name'):text(Acl_name)
@@ -58,11 +76,12 @@ def acl_set_mng(data, DEL):
                            with tag('acl-entry'): 
                            with tag('acl-entry'): 
                                with tag('sequence-id'):text(ID)
                                with tag('sequence-id'):text(ID)
                                with tag('config'):
                                with tag('config'):
                                        with tag('acl-entry'):   text(ID)
                                    with tag('sequence-id'):   text(ID)
                                    with tag('description'): text(desc)
                                    with tag('description'): text(desc)
                                # Configuration per type
                                # Configuration per type
                                if "L2" in Acl_type:
                                if "L2" in Acl_type:
                                    with tag('l2'):
                                    with tag('l2'):
                                        with tag('config'):
                                            for key, value in match.items():
                                            for key, value in match.items():
                                                if   "src_address"     in key and len(value) != 0: 
                                                if   "src_address"     in key and len(value) != 0: 
                                                    with tag('source-mac'):text(value)
                                                    with tag('source-mac'):text(value)
@@ -70,6 +89,7 @@ def acl_set_mng(data, DEL):
                                                    with tag('destination-mac'):text(value)   
                                                    with tag('destination-mac'):text(value)   
                                elif "IPV4" in Acl_type:
                                elif "IPV4" in Acl_type:
                                    with tag('ipv4'):
                                    with tag('ipv4'):
                                        with tag('config'):
                                            for key, value in match.items():
                                            for key, value in match.items():
                                                if   "src_address"       in key and len(value) != 0:
                                                if   "src_address"       in key and len(value) != 0:
                                                    with tag('source-address'):text(value)
                                                    with tag('source-address'):text(value)
@@ -82,6 +102,7 @@ def acl_set_mng(data, DEL):
                                                elif "dscp"              in key                    : 
                                                elif "dscp"              in key                    : 
                                                    with tag('dscp'):text(value)
                                                    with tag('dscp'):text(value)
                                    with tag('transport'):
                                    with tag('transport'):
                                        with tag('config'):
                                            for key, value in match.items():
                                            for key, value in match.items():
                                                if   "src_port"     in key : 
                                                if   "src_port"     in key : 
                                                    with tag('source-port'):text(value)
                                                    with tag('source-port'):text(value)
@@ -91,6 +112,7 @@ def acl_set_mng(data, DEL):
                                                    with tag('tcp-flags'):text(value)        
                                                    with tag('tcp-flags'):text(value)        
                                elif "IPV6" in Acl_type:
                                elif "IPV6" in Acl_type:
                                    with tag('ipv6'):
                                    with tag('ipv6'):
                                        with tag('config'):
                                            for key, value in match.items():
                                            for key, value in match.items():
                                                if   "src_address"       in key and len(value) != 0:
                                                if   "src_address"       in key and len(value) != 0:
                                                    with tag('source-address'):text(value)
                                                    with tag('source-address'):text(value)
@@ -103,11 +125,12 @@ def acl_set_mng(data, DEL):
                                                elif "dscp"              in key                    : 
                                                elif "dscp"              in key                    : 
                                                    with tag('dscp'):text(value)
                                                    with tag('dscp'):text(value)
                                with tag('actions'):
                                with tag('actions'):
                                    with tag('config'):
                                        for key, value in action.items():
                                        for key, value in action.items():
                                            if "forward_action" in key : 
                                            if "forward_action" in key : 
                                                with tag('forward-action'):text(l_action[value])
                                                with tag('forwarding-action'):text(FORWARDING_ACTION_MAPPING[value])
                                            elif "log_action"     in key :
                                            elif "log_action"     in key :
                                                with tag('log-action'):text(f_action[value])
                                                with tag('log-action'):text(LOG_ACTION_MAPPING[value])
    result = indent(
    result = indent(
        doc.getvalue(),
        doc.getvalue(),
        indentation = ' '*2,
        indentation = ' '*2,
@@ -115,14 +138,14 @@ def acl_set_mng(data, DEL):
    )
    )
    return result
    return result


def acl_interface(data,vendor, DEL):

def acl_interface(data,vendor, delete):
    doc, tag, text = Doc().tagtext()
    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']
    ID        = data['endpoint_id']['endpoint_uuid']['uuid']
    Acl_data  = data["rule_set"]
    Acl_data  = data["rule_set"]
    Acl_name  = Acl_data['name']
    Acl_name  = Acl_data['name']
    Acl_type  = type[Acl_data['type']]
    Acl_type  = RULE_TYPE_MAPPING[Acl_data['type']]


    with tag('acl', xmlns="http://openconfig.net/yang/acl"):
    with tag('acl', xmlns="http://openconfig.net/yang/acl"):
            with tag('interfaces'):
            with tag('interfaces'):
@@ -141,6 +164,9 @@ def acl_interface(data,vendor, DEL):
                        with tag('ingress-acl-set'):
                        with tag('ingress-acl-set'):
                            with tag('set-name'):text(Acl_name)
                            with tag('set-name'):text(Acl_name)
                            with tag('type'):text(Acl_type)
                            with tag('type'):text(Acl_type)
                            with tag('config'):
                                with tag('set-name'):text(Acl_name)
                                with tag('type'):text(Acl_type)
    result = indent(
    result = indent(
        doc.getvalue(),
        doc.getvalue(),
        indentation = ' '*2,
        indentation = ' '*2,
@@ -148,6 +174,13 @@ def acl_interface(data,vendor, DEL):
    )
    )
    return result
    return result



def acl_mgmt(parameters,vendor,delete):
    acl   = []
    acl.append(acl_set_mng(  parameters,vendor,delete))
    acl.append(acl_interface(parameters,vendor,delete))
    return acl

# TESTING
# TESTING
'''
'''
data = {'endpoint_id':{'device_id': {'device_uuid': {'uuid': 'R155'}},'endpoint_uuid':{'uuid':'eth-1/0/21.999'}},
data = {'endpoint_id':{'device_id': {'device_uuid': {'uuid': 'R155'}},'endpoint_uuid':{'uuid':'eth-1/0/21.999'}},
+2 −2
Original line number Original line Diff line number Diff line
@@ -15,7 +15,7 @@
import json
import json
import lxml.etree as ET
import lxml.etree as ET
from typing import Collection, Dict, Any
from typing import Collection, Dict, Any
from .ACL.ACL_multivendor              import acl_set_mng        
from .ACL.ACL_multivendor              import acl_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.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.Interfaces_multivendor       import create_If_SubIf  
from .VPN.Routing_policy               import create_rp_def, create_rp_statement
from .VPN.Routing_policy               import create_rp_def, create_rp_statement
@@ -84,6 +84,6 @@ def generate_templates(resource_key: str, resource_value: str, delete: bool,vend
            result_templates.append(create_rp_statement(data, delete))
            result_templates.append(create_rp_statement(data, delete))
    else:
    else:
        if "acl_ruleset" in resource_key:                                               # acl rules management
        if "acl_ruleset" in resource_key:                                               # acl rules management
            result_templates.extend(acl_set_mng(resource_value, delete))
            result_templates.extend(acl_mgmt(resource_value,vendor, delete))


    return result_templates
    return result_templates
 No newline at end of file
+1 −1
Original line number Original line Diff line number Diff line
@@ -58,7 +58,7 @@ def create_If_SubIf(data,vendor, DEL):
                            with tag('index'): text('0')
                            with tag('index'): text('0')
                        with tag('config'):
                        with tag('config'):
                            with tag('index'): text('0')
                            with tag('index'): text('0')
                            if vendor == 'ADVA' and len(data['vlan_id'] == 0): 
                            if vendor == 'ADVA' and not 'vlan_id'in data: 
                                with tag('untagged-allowed', 'xmlns="http://www.advaoptical.com/cim/adva-dnos-oc-interfaces"'):text('true')
                                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('vlan',  xmlns="http://openconfig.net/yang/vlan"):
                            with tag('match'):
                            with tag('match'):
+59 −16
Original line number Original line Diff line number Diff line
@@ -12,11 +12,14 @@
# 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 itertools, json, re
import itertools, json, logging, re
from typing import Dict, List, Optional, Tuple
from typing import Dict, List, Optional, Tuple
from common.proto.context_pb2 import ConfigRule
from common.proto.context_pb2 import ConfigRule
from common.tools.grpc.Tools import grpc_message_to_json_string
from common.tools.object_factory.ConfigRule import json_config_rule_set
from common.tools.object_factory.ConfigRule import json_config_rule_set


LOGGER = logging.getLogger(__name__)

SETTINGS_RULE_NAME = '/settings'
SETTINGS_RULE_NAME = '/settings'


DEVICE_SETTINGS = re.compile(r'\/device\[([^\]]+)\]\/settings')
DEVICE_SETTINGS = re.compile(r'\/device\[([^\]]+)\]\/settings')
@@ -76,6 +79,10 @@ def compose_device_config_rules(
    config_rules : List, subservice_config_rules : List, path_hops : List,
    config_rules : List, subservice_config_rules : List, path_hops : List,
    device_name_mapping : Dict[str, str], endpoint_name_mapping : Dict[Tuple[str, str], str]
    device_name_mapping : Dict[str, str], endpoint_name_mapping : Dict[Tuple[str, str], str]
) -> None:
) -> None:
    LOGGER.debug('[compose_device_config_rules] begin')

    LOGGER.debug('[compose_device_config_rules] device_name_mapping={:s}'.format(str(device_name_mapping)))
    LOGGER.debug('[compose_device_config_rules] endpoint_name_mapping={:s}'.format(str(endpoint_name_mapping)))


    devices_traversed = set()
    devices_traversed = set()
    endpoints_traversed = set()
    endpoints_traversed = set()
@@ -85,8 +92,40 @@ def compose_device_config_rules(
        endpoints_traversed.add((device_uuid_or_name, path_hop['ingress_ep']))
        endpoints_traversed.add((device_uuid_or_name, path_hop['ingress_ep']))
        endpoints_traversed.add((device_uuid_or_name, path_hop['egress_ep']))
        endpoints_traversed.add((device_uuid_or_name, path_hop['egress_ep']))


    LOGGER.debug('[compose_device_config_rules] devices_traversed={:s}'.format(str(devices_traversed)))
    LOGGER.debug('[compose_device_config_rules] endpoints_traversed={:s}'.format(str(endpoints_traversed)))

    for config_rule in config_rules:
    for config_rule in config_rules:
        if config_rule.WhichOneof('config_rule') != 'custom': continue
        LOGGER.debug('[compose_device_config_rules] processing config_rule: {:s}'.format(
            grpc_message_to_json_string(config_rule)))

        if config_rule.WhichOneof('config_rule') == 'acl':
            LOGGER.debug('[compose_device_config_rules]   is acl')
            endpoint_id = config_rule.acl.endpoint_id
            device_uuid_or_name = endpoint_id.device_id.device_uuid.uuid
            LOGGER.debug('[compose_device_config_rules]   device_uuid_or_name={:s}'.format(str(device_uuid_or_name)))
            device_name_or_uuid = device_name_mapping.get(device_uuid_or_name, device_uuid_or_name)
            LOGGER.debug('[compose_device_config_rules]   device_name_or_uuid={:s}'.format(str(device_name_or_uuid)))
            device_keys = {device_uuid_or_name, device_name_or_uuid}
            if len(device_keys.intersection(devices_traversed)) == 0: continue

            endpoint_uuid = endpoint_id.endpoint_uuid.uuid
            LOGGER.debug('[compose_device_config_rules]   endpoint_uuid={:s}'.format(str(endpoint_uuid)))
            # given endpoint uuids link 'eth-1/0/20.533', remove last part after the '.'
            endpoint_uuid_or_name = (endpoint_uuid[::-1].split('.', maxsplit=1)[-1])[::-1]
            LOGGER.debug('[compose_device_config_rules]   endpoint_uuid_or_name={:s}'.format(str(endpoint_uuid_or_name)))
            endpoint_name_or_uuid_1 = endpoint_name_mapping[(device_uuid_or_name, endpoint_uuid_or_name)]
            endpoint_name_or_uuid_2 = endpoint_name_mapping[(device_name_or_uuid, endpoint_uuid_or_name)]
            endpoint_keys = {endpoint_uuid_or_name, endpoint_name_or_uuid_1, endpoint_name_or_uuid_2}

            device_endpoint_keys = set(itertools.product(device_keys, endpoint_keys))
            if len(device_endpoint_keys.intersection(endpoints_traversed)) == 0: continue
            
            LOGGER.debug('[compose_device_config_rules]   adding acl config rule')
            subservice_config_rules.append(config_rule)

        elif config_rule.WhichOneof('config_rule') == 'custom':
            LOGGER.debug('[compose_device_config_rules]   is custom')


            match = DEVICE_SETTINGS.match(config_rule.custom.resource_key)
            match = DEVICE_SETTINGS.match(config_rule.custom.resource_key)
            if match is not None:
            if match is not None:
@@ -111,3 +150,7 @@ def compose_device_config_rules(
                device_endpoint_keys = set(itertools.product(device_keys, endpoint_keys))
                device_endpoint_keys = set(itertools.product(device_keys, endpoint_keys))
                if len(device_endpoint_keys.intersection(endpoints_traversed)) == 0: continue
                if len(device_endpoint_keys.intersection(endpoints_traversed)) == 0: continue
                subservice_config_rules.append(config_rule)
                subservice_config_rules.append(config_rule)
        else:
            continue

    LOGGER.debug('[compose_device_config_rules] end')
Loading