diff --git a/src/device/service/drivers/openconfig/templates/VPN/Network_instance_multivendor.py b/src/device/service/drivers/openconfig/templates/VPN/Network_instance_multivendor.py index 761312c475973e9ef3034258dd8f5885b8e91bca..e2a17e8989869927c49528d44d94893461549ef8 100644 --- a/src/device/service/drivers/openconfig/templates/VPN/Network_instance_multivendor.py +++ b/src/device/service/drivers/openconfig/templates/VPN/Network_instance_multivendor.py @@ -68,12 +68,14 @@ def create_NI(parameters,vendor,DEL): with tag('router-id'):text(parameters['router_id']) if vendor is None or vendor == 'ADVA': with tag('type', 'xmlns:oc-ni-types="http://openconfig.net/yang/network-instance-types"'):text('oc-ni-types:',parameters['type']) + with tag('enable'):text('true') + with tag('enabled-address-families', 'xmlns:oc-types="http://openconfig.net/yang/openconfig-types"'):text('oc-types:IPV4') with tag('route-distinguisher'):text(parameters['route_distinguisher']) - if vendor is None or vendor == 'ADVA': - with tag('encapsulation'): - with tag('config'): - with tag('encapsulation-type', 'xmlns:oc-ni-types="http://openconfig.net/yang/network-instance-types"') :text('oc-ni-types:MPLS') - with tag('label-allocation-mode','xmlns:oc-ni-types="http://openconfig.net/yang/network-instance-types"'):text('oc-ni-types:INSTANCE_LABEL') + #if vendor is None or vendor == 'ADVA': + # with tag('encapsulation'): + # with tag('config'): + # with tag('encapsulation-type', 'xmlns:oc-ni-types="http://openconfig.net/yang/network-instance-types"') :text('oc-ni-types:MPLS') + # with tag('label-allocation-mode','xmlns:oc-ni-types="http://openconfig.net/yang/network-instance-types"'):text('oc-ni-types:INSTANCE_LABEL') result = indent( doc.getvalue(), @@ -148,7 +150,9 @@ def add_protocol_NI(parameters,vendor, DEL): with tag('afi-safis'): with tag('afi-safi', 'xmlns:oc-bgp-types="http://openconfig.net/yang/bgp-types"'): with tag('afi-safi-name'): text('oc-bgp-types:IPV4_UNICAST') - with tag('enabled'): text('true') + with tag('config'): + with tag('afi-safi-name'): text('oc-bgp-types:IPV4_UNICAST') + with tag('enabled'): text('true') with tag('config'): with tag('neighbor-address'): text(neighbor['ip_address']) with tag('enabled'): text('true') @@ -291,15 +295,23 @@ def associate_virtual_circuit(parameters): def associate_RP_to_NI(parameters): doc, tag, text = Doc().tagtext() with tag('network-instances',xmlns="http://openconfig.net/yang/network-instance"): - with tag('network-instance'): - with tag('name'):text(parameters['name']) - with tag('inter-instance-policies'): - with tag('apply-policy'): - with tag('config'): - if'import_policy' in parameters : - with tag('import-policy'):text(parameters['import_policy']) - elif 'export_policy' in parameters: - with tag('export-policy'):text(parameters['export_policy']) + with tag('network-instance'): + with tag('name'): text(parameters['name']) + with tag('inter-instance-policies'): + if 'import_policy' in parameters or 'export_policy' in parameters: + with tag('apply-policy'): + with tag('config'): + if 'import_policy' in parameters: + with tag('import-policy'): text(parameters['import_policy']) + if 'export_policy' in parameters: + with tag('export-policy'): text(parameters['export_policy']) + if 'import_route_target' in parameters or 'export_route_target' in parameters: + with tag('import-export-policy'): + with tag('config'): + if 'import_route_target' in parameters: + with tag('import-route-target'): text(parameters['import_route_target']) + if 'export_route_target' in parameters: + with tag('export-route-target'): text(parameters['export_route_target']) result = indent( doc.getvalue(), indentation = ' '*2, @@ -338,12 +350,12 @@ def create_table_conns(parameters,DEL): with tag('name'):text(parameters['name']) if DEL == True: with tag('table-connections'): - with tag('table-connection','xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="delete"'): - with tag('src-protocol','xmlns:oc-pol-types="http://openconfig.net/yang/policy-types"'): text('oc-pol-types:',parameters['src_protocol']) - with tag('dst-protocol','xmlns:oc-pol-types="http://openconfig.net/yang/policy-types"'): text('oc-pol-types:',parameters['dst_protocol']) + with tag('table-connection', 'xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="delete"'): + with tag('src-protocol', 'xmlns:oc-pol-types="http://openconfig.net/yang/policy-types"'): text('oc-pol-types:',parameters['src_protocol']) + with tag('dst-protocol', 'xmlns:oc-pol-types="http://openconfig.net/yang/policy-types"'): text('oc-pol-types:',parameters['dst_protocol']) with tag('address-family', 'xmlns:oc-types="http://openconfig.net/yang/openconfig-types"'):text('oc-types:',parameters['address_family']) else: - with tag('table-connections'): + with tag('table-connections', 'xmlns:oc-types="http://openconfig.net/yang/openconfig-types"'): with tag('table-connection'): with tag('src-protocol','xmlns:oc-pol-types="http://openconfig.net/yang/policy-types"'): text('oc-pol-types:',parameters['src_protocol']) with tag('dst-protocol','xmlns:oc-pol-types="http://openconfig.net/yang/policy-types"'): text('oc-pol-types:',parameters['dst_protocol']) diff --git a/src/device/service/drivers/openconfig/templates/interface/edit_config.xml b/src/device/service/drivers/openconfig/templates/interface/edit_config.xml index 220f062b5da09d26ff6ec271491d6d40cfd46669..372c5bc0ef53a268cbc8bcfd26dfceb03db64ab0 100644 --- a/src/device/service/drivers/openconfig/templates/interface/edit_config.xml +++ b/src/device/service/drivers/openconfig/templates/interface/edit_config.xml @@ -6,8 +6,16 @@ {{name}} ianaift:{{type}} - {{mtu}} + {% if mtu is defined %}{{mtu}}{% endif %} - {% endif %} + {% if auto_negotiate is defined or port_speed is defined %} + + + {% if auto_negotiate is defined %}{{auto_negotiate}}{% endif %} + {% if port_speed is defined %}{{port_speed}}{% endif %} + + + {% endif %} + {% endif %} diff --git a/src/device/service/drivers/openconfig/templates/interface/subinterface/edit_config.xml b/src/device/service/drivers/openconfig/templates/interface/subinterface/edit_config.xml index 2d8d3ee07b3a8df20a4b51be755e18b7aec982de..5d485eb07bc6967158b56d3da431237348da2f8f 100644 --- a/src/device/service/drivers/openconfig/templates/interface/subinterface/edit_config.xml +++ b/src/device/service/drivers/openconfig/templates/interface/subinterface/edit_config.xml @@ -5,9 +5,17 @@ {{name}} ianaift:{{type}} - {% if mtu is defined %}{{mtu}}{% endif%} + {% if mtu is defined %}{{mtu}}{% endif %} true + {% if auto_negotiate is defined or port_speed is defined %} + + + {% if auto_negotiate is defined %}{{auto_negotiate}}{% endif %} + {% if port_speed is defined %}{{port_speed}}{% endif %} + + + {% endif %} {{index}} @@ -18,21 +26,32 @@ true {% endif%} - {% if vlan_id is defined %} + {% if vlan_id is defined or vlan_ids is defined %} + {% if vlan_id is defined %} {{vlan_id}} + {% endif %} + {% if vlan_ids is defined %} + + + {% for vlan_id in vlan_ids %} + {{vlan_id}} + {% endfor %} + + + {% endif %} {% endif %} {% if address_ip is defined %} - {% if mtu is defined %}{{mtu}}{% endif%} + {% if mtu is defined %}{{mtu}}{% endif %}
diff --git a/src/device/service/drivers/openconfig/templates/network_instance/edit_config.xml b/src/device/service/drivers/openconfig/templates/network_instance/edit_config.xml index 6b6b733dab12a107bf0420907da9c9683173faeb..8f8ab3a5c6ab4e7421b72204d33c0a81de2ebdfe 100644 --- a/src/device/service/drivers/openconfig/templates/network_instance/edit_config.xml +++ b/src/device/service/drivers/openconfig/templates/network_instance/edit_config.xml @@ -8,6 +8,7 @@ {% if description is defined %}{{description}}{% endif %} true {% if type=='L3VRF' %} + oc-types:IPV4 {% if router_id is defined %}{{router_id}}{% endif %} {{route_distinguisher}} {% endif %} diff --git a/src/device/service/drivers/openconfig/templates/network_instance/inter_instance_policies/edit_config.xml b/src/device/service/drivers/openconfig/templates/network_instance/inter_instance_policies/edit_config.xml index b7c87c7ab13317b5bb2a15c43d241673196bf6d2..fdf6bc4c1aeafea83c80502664e9694f05bef164 100644 --- a/src/device/service/drivers/openconfig/templates/network_instance/inter_instance_policies/edit_config.xml +++ b/src/device/service/drivers/openconfig/templates/network_instance/inter_instance_policies/edit_config.xml @@ -3,12 +3,22 @@ {{name}} + {% if import_policy is defined or export_policy is defined %} {% if import_policy is defined %}{{import_policy}}{% endif%} {% if export_policy is defined %}{{export_policy}}{% endif%} + {% endif%} + {% if import_route_target is defined or export_route_target is defined %} + + + {% if import_route_target is defined %}{{import_route_target}}{% endif%} + {% if export_route_target is defined %}{{export_route_target}}{% endif%} + + + {% endif%} diff --git a/src/device/service/drivers/openconfig/templates/network_instance/interface/edit_config.xml b/src/device/service/drivers/openconfig/templates/network_instance/interface/edit_config.xml index e926796d039d54e30f6ba13eb5eb66bcec079c08..ab1c183bb9d68c4054df319ccdb4fadbe03911d3 100644 --- a/src/device/service/drivers/openconfig/templates/network_instance/interface/edit_config.xml +++ b/src/device/service/drivers/openconfig/templates/network_instance/interface/edit_config.xml @@ -1,10 +1,12 @@ {{name}} + {% if False %} {{name}} oc-ni-types:{{type}} + {% endif %} {{id}} diff --git a/src/device/service/drivers/openconfig/templates/network_instance/table_connections/edit_config.xml b/src/device/service/drivers/openconfig/templates/network_instance/table_connections/edit_config.xml index 35c535c6bd3f78e30fc2177ecc722b1115f54fc5..bd1dac1b326c9d14645d059bafefd73319497593 100644 --- a/src/device/service/drivers/openconfig/templates/network_instance/table_connections/edit_config.xml +++ b/src/device/service/drivers/openconfig/templates/network_instance/table_connections/edit_config.xml @@ -11,9 +11,7 @@ oc-pol-types:{{src_protocol}} oc-pol-types:{{dst_protocol}} oc-types:{{address_family}} - {% if False %} - {{as}} - {% endif %} + {{as}} {% if default_import_policy is defined %}{{default_import_policy}}{% endif %} {% endif %} diff --git a/src/device/tests/gnmi_openconfig/test_unitary_gnmi_oc_arista_l2vpn.py b/src/device/tests/gnmi_openconfig/test_unitary_gnmi_oc_arista_l2vpn.py index 2374cbad8bf37f1faef9b9648d49c851e17658af..7449377c69d020a0d5404406bc4ee009bf7c7caf 100644 --- a/src/device/tests/gnmi_openconfig/test_unitary_gnmi_oc_arista_l2vpn.py +++ b/src/device/tests/gnmi_openconfig/test_unitary_gnmi_oc_arista_l2vpn.py @@ -144,21 +144,21 @@ def test_configure(drivers : Dict[str, OpenConfigDriver]): #LOGGER.info('results_getconfig = {:s}'.format(str(results_getconfig))) csgw1_resources_to_set = [ - network_instance('ecoc24', 'L3VRF', '192.168.150.1', '65001:1'), - network_instance_add_protocol_direct('ecoc24', 'L3VRF'), - network_instance_add_protocol_static('ecoc24', 'L3VRF'), - network_instance_add_protocol_bgp('ecoc24', 'L3VRF', '192.168.150.1', '65001', neighbors=[ + network_instance('ofc25', 'L3VRF', '192.168.150.1', '65001:1'), + network_instance_add_protocol_direct('ofc25', 'L3VRF'), + network_instance_add_protocol_static('ofc25', 'L3VRF'), + network_instance_add_protocol_bgp('ofc25', 'L3VRF', '192.168.150.1', '65001', neighbors=[ ('192.168.150.2', '65001') ]), - network_instance_add_table_connection('ecoc24', 'DIRECTLY_CONNECTED', 'BGP', 'IPV4', 'ACCEPT_ROUTE', bgp_as='65001'), - network_instance_add_table_connection('ecoc24', 'STATIC', 'BGP', 'IPV4', 'ACCEPT_ROUTE', bgp_as='65001'), + network_instance_add_table_connection('ofc25', 'DIRECTLY_CONNECTED', 'BGP', 'IPV4', 'ACCEPT_ROUTE', bgp_as='65001'), + network_instance_add_table_connection('ofc25', 'STATIC', 'BGP', 'IPV4', 'ACCEPT_ROUTE', bgp_as='65001'), interface('ce1', 0, if_type='ethernetCsmacd', mtu=1500), - network_instance_interface('ecoc24', 'L3VRF', 'ce1', 0), + network_instance_interface('ofc25', 'L3VRF', 'ce1', 0), interface('ce1', 0, if_type='ethernetCsmacd', mtu=1500, ipv4_address_prefix=('192.168.10.1', 24), enabled=True), interface('xe5', 0, if_type='ethernetCsmacd', mtu=1500), - network_instance_interface('ecoc24', 'L3VRF', 'xe5', 0), + network_instance_interface('ofc25', 'L3VRF', 'xe5', 0), interface('xe5', 0, if_type='ethernetCsmacd', mtu=1500, ipv4_address_prefix=('192.168.150.1', 24), enabled=True), ] LOGGER.info('CSGW1 resources_to_set = {:s}'.format(str(csgw1_resources_to_set))) @@ -166,21 +166,21 @@ def test_configure(drivers : Dict[str, OpenConfigDriver]): LOGGER.info('CSGW1 results_setconfig = {:s}'.format(str(results_setconfig))) csgw2_resources_to_set = [ - network_instance('ecoc24', 'L3VRF', '192.168.150.2', '65001:1'), - network_instance_add_protocol_direct('ecoc24', 'L3VRF'), - network_instance_add_protocol_static('ecoc24', 'L3VRF'), - network_instance_add_protocol_bgp('ecoc24', 'L3VRF', '192.168.150.2', '65001', neighbors=[ + network_instance('ofc25', 'L3VRF', '192.168.150.2', '65001:1'), + network_instance_add_protocol_direct('ofc25', 'L3VRF'), + network_instance_add_protocol_static('ofc25', 'L3VRF'), + network_instance_add_protocol_bgp('ofc25', 'L3VRF', '192.168.150.2', '65001', neighbors=[ ('192.168.150.1', '65001') ]), - network_instance_add_table_connection('ecoc24', 'DIRECTLY_CONNECTED', 'BGP', 'IPV4', 'ACCEPT_ROUTE', bgp_as='65001'), - network_instance_add_table_connection('ecoc24', 'STATIC', 'BGP', 'IPV4', 'ACCEPT_ROUTE', bgp_as='65001'), + network_instance_add_table_connection('ofc25', 'DIRECTLY_CONNECTED', 'BGP', 'IPV4', 'ACCEPT_ROUTE', bgp_as='65001'), + network_instance_add_table_connection('ofc25', 'STATIC', 'BGP', 'IPV4', 'ACCEPT_ROUTE', bgp_as='65001'), interface('ce1', 0, if_type='ethernetCsmacd', mtu=1500), - network_instance_interface('ecoc24', 'L3VRF', 'ce1', 0), + network_instance_interface('ofc25', 'L3VRF', 'ce1', 0), interface('ce1', 0, if_type='ethernetCsmacd', mtu=1500, ipv4_address_prefix=('192.168.20.1', 24), enabled=True), interface('xe5', 0, if_type='ethernetCsmacd', mtu=1500), - network_instance_interface('ecoc24', 'L3VRF', 'xe5', 0), + network_instance_interface('ofc25', 'L3VRF', 'xe5', 0), interface('xe5', 0, if_type='ethernetCsmacd', mtu=1500, ipv4_address_prefix=('192.168.150.2', 24), enabled=True), ] LOGGER.info('CSGW2 resources_to_set = {:s}'.format(str(csgw2_resources_to_set))) @@ -188,22 +188,22 @@ def test_configure(drivers : Dict[str, OpenConfigDriver]): LOGGER.info('CSGW2 results_setconfig = {:s}'.format(str(results_setconfig))) csgw1_resources_to_delete = [ - network_instance_interface('ecoc24', 'L3VRF', 'ce1', 0), - network_instance_interface('ecoc24', 'L3VRF', 'xe5', 0), + network_instance_interface('ofc25', 'L3VRF', 'ce1', 0), + network_instance_interface('ofc25', 'L3VRF', 'xe5', 0), #interface('ce1', 0), #interface('xe5', 0), - network_instance('ecoc24', 'L3VRF'), + network_instance('ofc25', 'L3VRF'), ] LOGGER.info('CSGW1 resources_to_delete = {:s}'.format(str(csgw1_resources_to_delete))) results_deleteconfig = drivers['CSGW1'].DeleteConfig(csgw1_resources_to_delete) LOGGER.info('CSGW1 results_deleteconfig = {:s}'.format(str(results_deleteconfig))) csgw2_resources_to_delete = [ - network_instance_interface('ecoc24', 'L3VRF', 'ce1', 0), - network_instance_interface('ecoc24', 'L3VRF', 'xe5', 0), + network_instance_interface('ofc25', 'L3VRF', 'ce1', 0), + network_instance_interface('ofc25', 'L3VRF', 'xe5', 0), #interface('ce1', 0), #interface('xe5', 0), - network_instance('ecoc24', 'L3VRF'), + network_instance('ofc25', 'L3VRF'), ] LOGGER.info('CSGW2 resources_to_delete = {:s}'.format(str(csgw2_resources_to_delete))) results_deleteconfig = drivers['CSGW2'].DeleteConfig(csgw2_resources_to_delete) diff --git a/src/device/tests/test_unitary_openconfig_ocnos.py b/src/device/tests/test_unitary_openconfig_ocnos.py index fa034ff3a65dca4b8ccf59bd9f5202e91d7ce6a1..594d20d54f6837691ef47fed776467dab39c9e77 100644 --- a/src/device/tests/test_unitary_openconfig_ocnos.py +++ b/src/device/tests/test_unitary_openconfig_ocnos.py @@ -144,21 +144,21 @@ def test_configure(drivers : Dict[str, OpenConfigDriver]): #LOGGER.info('results_getconfig = {:s}'.format(str(results_getconfig))) csgw1_resources_to_set = [ - network_instance('ecoc24', 'L3VRF', '192.168.150.1', '65001:1'), - network_instance_add_protocol_direct('ecoc24', 'L3VRF'), - network_instance_add_protocol_static('ecoc24', 'L3VRF'), - network_instance_add_protocol_bgp('ecoc24', 'L3VRF', '192.168.150.1', '65001', neighbors=[ + network_instance('ofc25', 'L3VRF', '192.168.150.1', '65001:1'), + network_instance_add_protocol_direct('ofc25', 'L3VRF'), + network_instance_add_protocol_static('ofc25', 'L3VRF'), + network_instance_add_protocol_bgp('ofc25', 'L3VRF', '192.168.150.1', '65001', neighbors=[ ('192.168.150.2', '65001') ]), - network_instance_add_table_connection('ecoc24', 'DIRECTLY_CONNECTED', 'BGP', 'IPV4', 'ACCEPT_ROUTE', bgp_as='65001'), - network_instance_add_table_connection('ecoc24', 'STATIC', 'BGP', 'IPV4', 'ACCEPT_ROUTE', bgp_as='65001'), + network_instance_add_table_connection('ofc25', 'DIRECTLY_CONNECTED', 'BGP', 'IPV4', 'ACCEPT_ROUTE', bgp_as='65001'), + network_instance_add_table_connection('ofc25', 'STATIC', 'BGP', 'IPV4', 'ACCEPT_ROUTE', bgp_as='65001'), interface('ce1', 0, if_type='ethernetCsmacd', mtu=1500), - network_instance_interface('ecoc24', 'L3VRF', 'ce1', 0), + network_instance_interface('ofc25', 'L3VRF', 'ce1', 0), interface('ce1', 0, if_type='ethernetCsmacd', mtu=1500, ipv4_address_prefix=('192.168.10.1', 24), enabled=True), interface('xe5', 0, if_type='ethernetCsmacd', mtu=1500), - network_instance_interface('ecoc24', 'L3VRF', 'xe5', 0), + network_instance_interface('ofc25', 'L3VRF', 'xe5', 0), interface('xe5', 0, if_type='ethernetCsmacd', mtu=1500, ipv4_address_prefix=('192.168.150.1', 24), enabled=True), ] LOGGER.info('CSGW1 resources_to_set = {:s}'.format(str(csgw1_resources_to_set))) @@ -166,21 +166,21 @@ def test_configure(drivers : Dict[str, OpenConfigDriver]): LOGGER.info('CSGW1 results_setconfig = {:s}'.format(str(results_setconfig))) csgw2_resources_to_set = [ - network_instance('ecoc24', 'L3VRF', '192.168.150.2', '65001:1'), - network_instance_add_protocol_direct('ecoc24', 'L3VRF'), - network_instance_add_protocol_static('ecoc24', 'L3VRF'), - network_instance_add_protocol_bgp('ecoc24', 'L3VRF', '192.168.150.2', '65001', neighbors=[ + network_instance('ofc25', 'L3VRF', '192.168.150.2', '65001:1'), + network_instance_add_protocol_direct('ofc25', 'L3VRF'), + network_instance_add_protocol_static('ofc25', 'L3VRF'), + network_instance_add_protocol_bgp('ofc25', 'L3VRF', '192.168.150.2', '65001', neighbors=[ ('192.168.150.1', '65001') ]), - network_instance_add_table_connection('ecoc24', 'DIRECTLY_CONNECTED', 'BGP', 'IPV4', 'ACCEPT_ROUTE', bgp_as='65001'), - network_instance_add_table_connection('ecoc24', 'STATIC', 'BGP', 'IPV4', 'ACCEPT_ROUTE', bgp_as='65001'), + network_instance_add_table_connection('ofc25', 'DIRECTLY_CONNECTED', 'BGP', 'IPV4', 'ACCEPT_ROUTE', bgp_as='65001'), + network_instance_add_table_connection('ofc25', 'STATIC', 'BGP', 'IPV4', 'ACCEPT_ROUTE', bgp_as='65001'), interface('ce1', 0, if_type='ethernetCsmacd', mtu=1500), - network_instance_interface('ecoc24', 'L3VRF', 'ce1', 0), + network_instance_interface('ofc25', 'L3VRF', 'ce1', 0), interface('ce1', 0, if_type='ethernetCsmacd', mtu=1500, ipv4_address_prefix=('192.168.20.1', 24), enabled=True), interface('xe5', 0, if_type='ethernetCsmacd', mtu=1500), - network_instance_interface('ecoc24', 'L3VRF', 'xe5', 0), + network_instance_interface('ofc25', 'L3VRF', 'xe5', 0), interface('xe5', 0, if_type='ethernetCsmacd', mtu=1500, ipv4_address_prefix=('192.168.150.2', 24), enabled=True), ] LOGGER.info('CSGW2 resources_to_set = {:s}'.format(str(csgw2_resources_to_set))) @@ -188,22 +188,22 @@ def test_configure(drivers : Dict[str, OpenConfigDriver]): LOGGER.info('CSGW2 results_setconfig = {:s}'.format(str(results_setconfig))) csgw1_resources_to_delete = [ - network_instance_interface('ecoc24', 'L3VRF', 'ce1', 0), - network_instance_interface('ecoc24', 'L3VRF', 'xe5', 0), + network_instance_interface('ofc25', 'L3VRF', 'ce1', 0), + network_instance_interface('ofc25', 'L3VRF', 'xe5', 0), #interface('ce1', 0), #interface('xe5', 0), - network_instance('ecoc24', 'L3VRF'), + network_instance('ofc25', 'L3VRF'), ] LOGGER.info('CSGW1 resources_to_delete = {:s}'.format(str(csgw1_resources_to_delete))) results_deleteconfig = drivers['CSGW1'].DeleteConfig(csgw1_resources_to_delete) LOGGER.info('CSGW1 results_deleteconfig = {:s}'.format(str(results_deleteconfig))) csgw2_resources_to_delete = [ - network_instance_interface('ecoc24', 'L3VRF', 'ce1', 0), - network_instance_interface('ecoc24', 'L3VRF', 'xe5', 0), + network_instance_interface('ofc25', 'L3VRF', 'ce1', 0), + network_instance_interface('ofc25', 'L3VRF', 'xe5', 0), #interface('ce1', 0), #interface('xe5', 0), - network_instance('ecoc24', 'L3VRF'), + network_instance('ofc25', 'L3VRF'), ] LOGGER.info('CSGW2 resources_to_delete = {:s}'.format(str(csgw2_resources_to_delete))) results_deleteconfig = drivers['CSGW2'].DeleteConfig(csgw2_resources_to_delete) diff --git a/test_csgw/Config.py b/test_csgw/Config.py new file mode 100644 index 0000000000000000000000000000000000000000..cf9b7699995e7f83b30feaa1fe280c22e83fec74 --- /dev/null +++ b/test_csgw/Config.py @@ -0,0 +1,99 @@ +# Copyright 2022-2024 ETSI 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 .DataStructures import Bgp, Cidr, Ethernet, Interface, NetworkInstance, NetworkInstances, Router, SubInterface + +NETWORK_INSTANCES = NetworkInstances() + +NETWORK_INSTANCES.instances['vlink-1'] = NetworkInstance( + name = 'vlink-1', + bgp = Bgp(bgp_as=65000, bgp_number=1, rt_import_number=1, rt_export_number=1), + routers = { + 'IP1': Router( + routing_if = Interface( + name='xe1', ethernet=Ethernet(auto_negotiate=True, port_speed='SPEED_UNKNOWN'), + index=0, cidr=Cidr(address='1.1.1.1', prefix=30), mtu=1500 + ), + client_if = Interface( + name='ce1', ethernet=Ethernet(auto_negotiate=False, port_speed='SPEED_UNKNOWN'), + index=101, cidr=Cidr(address='192.168.101.1', prefix=24), mtu=1500, vlan_ids=[101] + ), + ), + 'IP2': Router( + routing_if = Interface( + name='xe1', ethernet=Ethernet(auto_negotiate=True, port_speed='SPEED_UNKNOWN'), + index=0, cidr=Cidr(address='1.1.1.2', prefix=30), mtu=1500 + ), + client_if = Interface( + name='ce1', ethernet=Ethernet(auto_negotiate=False, port_speed='SPEED_UNKNOWN'), + index=201, cidr=Cidr(address='192.168.201.1', prefix=24), mtu=1500, vlan_ids=[201] + ), + ), + } +) + +NETWORK_INSTANCES.instances['vlink-2'] = NetworkInstance( + name = 'vlink-2', + bgp = Bgp(bgp_as=65000, bgp_number=2, rt_import_number=2, rt_export_number=2), + routers = { + 'IP1': Router( + routing_if = Interface( + name='xe2', ethernet=Ethernet(auto_negotiate=True, port_speed='SPEED_UNKNOWN'), + index=0, cidr=Cidr(address='1.1.2.1', prefix=30), mtu=1500 + ), + client_if = Interface( + name='ce1', ethernet=Ethernet(auto_negotiate=False, port_speed='SPEED_UNKNOWN'), + index=102, cidr=Cidr(address='192.168.102.1', prefix=24), mtu=1500, vlan_ids=[102] + ), + ), + 'IP2': Router( + routing_if = Interface( + name='xe2', ethernet=Ethernet(auto_negotiate=True, port_speed='SPEED_UNKNOWN'), + index=0, cidr=Cidr(address='1.1.2.2', prefix=30), mtu=1500 + ), + client_if = Interface( + name='ce1', ethernet=Ethernet(auto_negotiate=False, port_speed='SPEED_UNKNOWN'), + index=202, cidr=Cidr(address='192.168.202.1', prefix=24), mtu=1500, vlan_ids=[202] + ), + ), + } +) + +NETWORK_INSTANCES.instances['vlink-3'] = NetworkInstance( + name = 'vlink-3', + bgp = Bgp(bgp_as=65000, bgp_number=3, rt_import_number=3, rt_export_number=3), + routers = { + 'IP1': Router( + routing_if = Interface( + name='xe3', ethernet=Ethernet(auto_negotiate=True, port_speed='SPEED_UNKNOWN'), + index=0, cidr=Cidr(address='1.1.3.1', prefix=30), mtu=1500 + ), + client_if = Interface( + name='ce1', ethernet=Ethernet(auto_negotiate=False, port_speed='SPEED_UNKNOWN'), + index=103, cidr=Cidr(address='192.168.103.1', prefix=24), mtu=1500, vlan_ids=[103] + ), + ), + 'IP2': Router( + routing_if = Interface( + name='xe3', index=0, ethernet=Ethernet(auto_negotiate=True, port_speed='SPEED_UNKNOWN'), + index=0, cidr=Cidr(address='1.1.3.2', prefix=30), mtu=1500 + ), + client_if = Interface( + name='ce1', ethernet=Ethernet(auto_negotiate=False, port_speed='SPEED_UNKNOWN'), + index=203, cidr=Cidr(address='192.168.203.1', prefix=24), mtu=1500, vlan_ids=[203] + ), + ), + } +) diff --git a/test_csgw/DataStructures.py b/test_csgw/DataStructures.py new file mode 100644 index 0000000000000000000000000000000000000000..51a03ac517f56fe9d078c640940732c1d67af2f2 --- /dev/null +++ b/test_csgw/DataStructures.py @@ -0,0 +1,90 @@ +# Copyright 2022-2024 ETSI 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 collections import defaultdict +from dataclasses import dataclass, field +from typing import Dict, List, Tuple + +@dataclass +class Bgp: + bgp_as : int = field(default=0) + bgp_number : int = field(default=0) + rt_import_number : int = field(default=0) + rt_export_number : int = field(default=0) + + def get_route_distinguisher(self) -> str: + return '{:d}:{:d}'.format(self.bgp_as, self.bgp_number) + + def get_route_target_import(self) -> str: + return '{:d}:{:d}'.format(self.bgp_as, self.rt_import_number) + + def get_route_target_export(self) -> str: + return '{:d}:{:d}'.format(self.bgp_as, self.rt_export_number) + +@dataclass +class Ethernet: + auto_negotiate : bool = field(default=False) + port_speed : str = field(default='SPEED_UNKNOWN') + +@dataclass +class Cidr: + address : str = field(default='0.0.0.0') + prefix : int = field(default=0) + + def as_tuple(self) -> Tuple[str, int]: + return (self.address, self.prefix) + +@dataclass +class Interface: + name : str = field(default='') + index : int = field(default=0) + ethernet : Ethernet = field(default_factory=Ethernet) + mtu : int = field(default=1500) + cidr : Cidr = field(default_factory=Cidr) + vlan_ids : List[int] = field(default_factory=list) + +@dataclass +class Router: + routing_if : Interface = field(default_factory=Interface) + client_if : Interface = field(default_factory=Interface) + +@dataclass +class NetworkInstance: + name : str + bgp : Bgp = field(default_factory=Bgp) + routers : Dict[str, Router] = field(default_factory=lambda: defaultdict(Router)) + + def get_router(self, name : str) -> Router: + if name not in self.routers: + MSG = 'Router({:s}) not found' + raise Exception(MSG.format(name)) + return self.routers[name] + + def get_neighbors_of(self, name : str) -> List[Router]: + return [ + router + for router_name, router in self.routers.items() + if router_name != name + ] + +@dataclass +class NetworkInstances: + instances : Dict[str, NetworkInstance] = field(default_factory=lambda: defaultdict(NetworkInstance)) + + def get(self, name : str) -> NetworkInstance: + if name not in self.instances: + MSG = 'NetworkInstance({:s}) not found' + raise Exception(MSG.format(name)) + return self.instances[name] diff --git a/test_csgw/DoConfiguration.py b/test_csgw/DoConfiguration.py new file mode 100644 index 0000000000000000000000000000000000000000..a6b77ddaa1a6009b6c935f25a56549968ae5f427 --- /dev/null +++ b/test_csgw/DoConfiguration.py @@ -0,0 +1,68 @@ +# Copyright 2022-2024 ETSI 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 json, os +from typing import Dict, List +from common.proto.context_pb2 import ConfigRule +from common.tools.context_queries.Device import get_device +from context.client.ContextClient import ContextClient +from device.client.DeviceClient import DeviceClient + +os.environ['DEVICE_EMULATED_ONLY'] = 'YES' + +# pylint: disable=wrong-import-position +from device.service.drivers.openconfig.OpenConfigDriver import OpenConfigDriver + + +DEVICE_DRIVER_PARAMETERS = { + 'IP1': {'address': '10.1.1.86', 'port': 830, 'settings': { + 'username': 'ocnos', 'password': 'ocnos', 'vendor': None, 'force_running': False, + 'hostkey_verify': False, 'look_for_keys': False, 'allow_agent': False, + 'commit_per_rule': True, 'device_params': {'name': 'default'}, 'manager_params': {'timeout' : 120}, + 'message_renderer': 'jinja' + }}, + 'IP2': {'address': '10.1.1.87', 'port': 830, 'settings': { + 'username': 'ocnos', 'password': 'ocnos', 'vendor': None, 'force_running': False, + 'hostkey_verify': False, 'look_for_keys': False, 'allow_agent': False, + 'commit_per_rule': True, 'device_params': {'name': 'default'}, 'manager_params': {'timeout' : 120}, + 'message_renderer': 'jinja' + }}, +} + +def configure_device_direct( + device_name : str, config_rules : List[ConfigRule], is_delete : bool = False +) -> None: + resources = [ + (config_rule.custom.resource_key, config_rule.custom.resource_value) + for config_rule in config_rules + ] + + driver_params = DEVICE_DRIVER_PARAMETERS[device_name] + driver = OpenConfigDriver(driver_params['address'], driver_params['port'], **(driver_params['settings'])) + driver.Connect() + method = driver.DeleteConfig if is_delete else driver.SetConfig + method(resources) + driver.Disconnect() + +def configure_device_normal(device_uuid : str, config_rules : List[Dict]) -> None: + context_client = ContextClient() + device_client = DeviceClient() + + device = get_device( + context_client, device_uuid, rw_copy=True, include_endpoints=False, + include_config_rules=False, include_components=False + ) + device.device_config.config_rules.extend(config_rules) + device_client.ConfigureDevice(device) diff --git a/test_csgw/RuleComposer.py b/test_csgw/RuleComposer.py new file mode 100644 index 0000000000000000000000000000000000000000..d9773235f7ea5ff563691a2bb3c35e138ec47838 --- /dev/null +++ b/test_csgw/RuleComposer.py @@ -0,0 +1,202 @@ +# Copyright 2022-2024 ETSI 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 hashlib, json +from typing import Dict, List, Optional +from common.proto.context_pb2 import ConfigRule +from common.tools.object_factory.ConfigRule import json_config_rule_set, json_config_rule_delete +from .DataStructures import NetworkInstance + + +def compose_config_rule(resource_key, resource_value, delete) -> Dict: + json_config_rule = json_config_rule_delete if delete else json_config_rule_set + return ConfigRule(**json_config_rule(resource_key, resource_value)) + +def network_instance(ni_name, ni_type, ni_router_id=None, ni_route_distinguisher=None, delete=False) -> Dict: + path = '/network_instance[{:s}]'.format(ni_name) + data = {'name': ni_name, 'type': ni_type} + if ni_router_id is not None: data['router_id'] = ni_router_id + if ni_route_distinguisher is not None: data['route_distinguisher'] = ni_route_distinguisher + return compose_config_rule(path, data, delete) + +def network_instance_add_protocol_bgp(ni_name, ni_type, ni_router_id, ni_bgp_as, neighbors=[], delete=False)-> Dict: + path = '/network_instance[{:s}]/protocols[BGP]'.format(ni_name) + data = { + 'name': ni_name, 'type': ni_type, 'router_id': ni_router_id, 'identifier': 'BGP', + 'protocol_name': ni_bgp_as, 'as': ni_bgp_as + } + if len(neighbors) > 0: + data['neighbors'] = [ + {'ip_address': neighbor_ip_address, 'remote_as': neighbor_remote_as} + for neighbor_ip_address, neighbor_remote_as in neighbors + ] + return compose_config_rule(path, data, delete) + +def network_instance_add_inter_instance_policy( + ni_name : str, + import_policy : Optional[str] = None, export_policy : Optional[str] = None, + import_route_target : Optional[str] = None, export_route_target : Optional[str] = None, + delete=False +)-> Dict: + data = dict() + if import_policy is not None: data['import_policy' ] = import_policy + if export_policy is not None: data['export_policy' ] = export_policy + if import_route_target is not None: data['import_route_target'] = import_route_target + if export_route_target is not None: data['export_route_target'] = export_route_target + str_policy_data = json.dumps(data, sort_keys=True) + full_policy_hash = hashlib.sha256(str_policy_data.encode()).digest() + policy_hash = full_policy_hash[:8].hex() + path = '/network_instance[{:s}]/inter_instance_policies[{:s}]'.format(ni_name, policy_hash) + data['name'] = ni_name + return compose_config_rule(path, data, delete) + +def network_instance_add_protocol_direct(ni_name, ni_type, delete=False) -> Dict: + path = '/network_instance[{:s}]/protocols[DIRECTLY_CONNECTED]'.format(ni_name) + data = { + 'name': ni_name, 'type': ni_type, 'identifier': 'DIRECTLY_CONNECTED', + 'protocol_name': 'DIRECTLY_CONNECTED' + } + return compose_config_rule(path, data, delete) + +def network_instance_add_protocol_static(ni_name, ni_type, delete=False) -> Dict: + path = '/network_instance[{:s}]/protocols[STATIC]'.format(ni_name) + data = { + 'name': ni_name, 'type': ni_type, 'identifier': 'STATIC', + 'protocol_name': 'STATIC' + } + return compose_config_rule(path, data, delete) + +def network_instance_add_table_connection( + ni_name, src_protocol, dst_protocol, address_family, default_import_policy, bgp_as=None, delete=False +) -> Dict: + path = '/network_instance[{:s}]/table_connections[{:s}][{:s}][{:s}]'.format( + ni_name, src_protocol, dst_protocol, address_family + ) + data = { + 'name': ni_name, 'src_protocol': src_protocol, 'dst_protocol': dst_protocol, + 'address_family': address_family, 'default_import_policy': default_import_policy, + } + if bgp_as is not None: data['as'] = bgp_as + return compose_config_rule(path, data, delete) + +def interface( + name, index, description=None, if_type=None, vlan_id=None, vlan_ids=None, mtu=None, ipv4_address_prefix=None, + enabled=None, delete=False +) -> Dict: + path = '/interface[{:s}]/subinterface[{:d}]'.format(name, index) + data = {'name': name, 'index': index} + if description is not None: data['description'] = description + if if_type is not None: data['type' ] = if_type + if mtu is not None: data['mtu' ] = mtu + if enabled is not None: data['enabled' ] = enabled + + if vlan_id is not None: data['vlan_id'] = vlan_id + + if vlan_ids is not None and len(vlan_ids) > 0: + data['vlan_ids'] = vlan_ids + + if ipv4_address_prefix is not None: + ipv4_address, ipv4_prefix = ipv4_address_prefix + data['address_ip' ] = ipv4_address + data['address_prefix'] = ipv4_prefix + return compose_config_rule(path, data, delete) + +def network_instance_interface(ni_name, ni_type, if_name, if_index, delete=False) -> Dict: + path = '/network_instance[{:s}]/interface[{:s}.{:d}]'.format(ni_name, if_name, if_index) + data = {'name': ni_name, 'type': ni_type, 'id': if_name, 'interface': if_name, 'subinterface': if_index} + return compose_config_rule(path, data, delete) + + +def compose_configure_rules(ni_data : NetworkInstance, router_name : str) -> List[Dict]: + ni_bgp = ni_data.bgp + ni_router = ni_data.get_router(router_name) + ni_neighbors = ni_data.get_neighbors_of(router_name) + + return [ + # Create network instance with BGP-support + network_instance( + ni_data.name, 'L3VRF', ni_router.router_id, ni_bgp.get_route_distinguisher() + ), + + # Configure routing protocols + network_instance_add_protocol_direct(ni_data.name, 'L3VRF'), + network_instance_add_protocol_static(ni_data.name, 'L3VRF'), + network_instance_add_protocol_bgp( + ni_data.name, 'L3VRF', ni_router.router_id, ni_bgp.bgp_as, neighbors=[ + (neighbor.routing_if.cidr.address, ni_bgp.bgp_as) for neighbor in ni_neighbors + ]), + + network_instance_add_inter_instance_policy( + ni_data.name, + import_route_target=ni_data.bgp.get_route_target_import(), + export_route_target=ni_data.bgp.get_route_target_export(), + ), + + # Configure routing protocol table exchanges + network_instance_add_table_connection( + ni_data.name, 'DIRECTLY_CONNECTED', 'BGP', 'IPV4', 'ACCEPT_ROUTE', bgp_as=ni_bgp.bgp_as + ), + network_instance_add_table_connection( + ni_data.name, 'STATIC', 'BGP', 'IPV4', 'ACCEPT_ROUTE', bgp_as=ni_bgp.bgp_as + ), + + # Configure routing interface + interface( + ni_router.routing_if.name, ni_router.routing_if.index, if_type='ethernetCsmacd', + mtu=ni_router.routing_if.mtu, vlan_ids=ni_router.routing_if.vlan_ids + ), + network_instance_interface( + ni_data.name, 'L3VRF', ni_router.routing_if.name, ni_router.routing_if.index + ), + interface( + ni_router.routing_if.name, ni_router.routing_if.index, if_type='ethernetCsmacd', + mtu=ni_router.routing_if.mtu, vlan_ids=ni_router.routing_if.vlan_ids, + ipv4_address_prefix=ni_router.routing_if.cidr.as_tuple(), enabled=True + ), + + # Configure client interface + interface( + ni_router.client_if.name, ni_router.client_if.index, if_type='ethernetCsmacd', + mtu=ni_router.client_if.mtu, vlan_ids=ni_router.client_if.vlan_ids + ), + network_instance_interface( + ni_data.name, 'L3VRF', ni_router.client_if.name, ni_router.client_if.index + ), + interface( + ni_router.client_if.name, ni_router.client_if.index, if_type='ethernetCsmacd', + mtu=ni_router.client_if.mtu, vlan_ids=ni_router.client_if.vlan_ids, + ipv4_address_prefix=ni_router.client_if.cidr.as_tuple(), enabled=True + ), + ] + +def compose_deconfigure_rules(ni_data : NetworkInstance, router_name : str) -> List[Dict]: + ni_router = ni_data.get_router(router_name) + + return [ + # Deconfigure client interface + network_instance_interface( + ni_data.name, 'L3VRF', ni_router.client_if.name, ni_router.client_if.index, delete=True + ), + interface(ni_router.client_if.name, ni_router.client_if.index, delete=True), + + # Deconfigure routing interface + network_instance_interface( + ni_data.name, 'L3VRF', ni_router.routing_if.name, ni_router.routing_if.index, delete=True + ), + interface(ni_router.routing_if.name, ni_router.routing_if.index, delete=True), + + # Remove network instance + network_instance(ni_data.name, 'L3VRF', delete=True), + ] diff --git a/test_csgw/__init__.py b/test_csgw/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..023830645e0fcb60e3f8583674a954810af222f2 --- /dev/null +++ b/test_csgw/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2022-2024 ETSI 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. diff --git a/test_csgw/__main__.py b/test_csgw/__main__.py new file mode 100644 index 0000000000000000000000000000000000000000..ff03280fb6bf6cc54543bac5c2bc4a6ba3b46a34 --- /dev/null +++ b/test_csgw/__main__.py @@ -0,0 +1,51 @@ +# Copyright 2022-2024 ETSI 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 .Config import NETWORK_INSTANCES +from .DoConfiguration import configure_device_direct +from .RuleComposer import compose_configure_rules, compose_deconfigure_rules + +logging.basicConfig(level=logging.DEBUG) +#logging.getLogger('ncclient.operations.rpc').setLevel(logging.INFO) +#logging.getLogger('ncclient.transport.parser').setLevel(logging.INFO) +LOGGER = logging.getLogger(__name__) + +def configure(router_a : str, router_b : str, ni_name : str) -> None: + ni_data = NETWORK_INSTANCES.get(ni_name) + + config_rules_a = compose_configure_rules(ni_data, router_a) + config_rules_b = compose_configure_rules(ni_data, router_b) + + configure_device_direct(router_a, config_rules_a, is_delete=False) + configure_device_direct(router_b, config_rules_b, is_delete=False) + +def deconfigure(router_a : str, router_b : str, ni_name : str) -> None: + ni_data = NETWORK_INSTANCES.get(ni_name) + + config_rules_a = compose_deconfigure_rules(ni_data, router_a) + config_rules_b = compose_deconfigure_rules(ni_data, router_b) + + configure_device_direct(router_a, config_rules_a, is_delete=True) + configure_device_direct(router_b, config_rules_b, is_delete=True) + + +if __name__ == '__main__': + configure('IP1', 'IP2', 'vlink-1') + #configure('IP1', 'IP2', 'vlink-2') + #configure('IP1', 'IP2', 'vlink-3') + + #deconfigure('IP1', 'IP2', 'vlink-1') + #deconfigure('IP1', 'IP2', 'vlink-2') + #deconfigure('IP1', 'IP2', 'vlink-3') diff --git a/test_csgw/config/csgws-works.conf b/test_csgw/config/csgws-works.conf new file mode 100644 index 0000000000000000000000000000000000000000..2d1b728e3c8fb9fbe1d629e684685e63e78d0765 --- /dev/null +++ b/test_csgw/config/csgws-works.conf @@ -0,0 +1,69 @@ +# Ref: https://docs.ipinfusion.com/service-provider-6.5/index.html#page/OcNOS_SP/BGP-Config/BGP_Configuration.html +# Ref: https://docs.ipinfusion.com/service-provider-6.5/index.html#page/OcNOS_SP/VRF-Lite-Config/BGP_configuration.html +# Ref: https://docs.ipinfusion.com/service-provider-6.5/index.html#page/OcNOS_SP/L3-Subif-Config/subinterface_config.html + +# CSGW1 +ip vrf vlink1 + rd 65000:1 + route-target import 65000:1 + route-target export 65000:1 + exit + +interface ce1 + ip address 192.168.10.1/24 + +interface ce1.101 + encapsulation dot1q 101 + ip vrf forwarding vlink1 + ip address 192.168.101.1/24 + +interface xe1 + transceiver 10gbase-sr + speed auto + ip vrf forwarding vlink1 + ip address 2.2.2.1/24 + exit + +router bgp 65000 + address-family ipv4 vrf vlink1 + redistribute connected + redistribute static + neighbor 2.2.2.2 remote-as 65000 + neighbor 2.2.2.2 activate + exit + exit + +commit + +# CSGW2 +ip vrf vlink1 + rd 65000:1 + route-target import 65000:1 + route-target export 65000:1 + exit + +interface ce1 + ip address 192.168.20.1/24 + +interface ce1.201 + encapsulation dot1q 201 + ip vrf forwarding vlink1 + ip address 192.168.201.1/24 + +interface xe1 + transceiver 10gbase-sr + speed auto + ip vrf forwarding vlink1 + ip address 2.2.2.2/24 + exit + +router bgp 65000 + address-family ipv4 vrf vlink1 + redistribute connected + redistribute static + neighbor 2.2.2.1 remote-as 65000 + neighbor 2.2.2.1 activate + exit + exit + +commit diff --git a/test_csgw/csgw-configs/manual-config-bgp-custom-vrf-csgw1.conf b/test_csgw/csgw-configs/manual-config-bgp-custom-vrf-csgw1.conf new file mode 100644 index 0000000000000000000000000000000000000000..d0335a1e340a7d12205ce362a730e7d83e933c04 --- /dev/null +++ b/test_csgw/csgw-configs/manual-config-bgp-custom-vrf-csgw1.conf @@ -0,0 +1,20 @@ +ip vrf ecoc24 + rd 65001:1 + route-target both 65001:1 + +interface ce1 + ip vrf forwarding ecoc24 + ip address 192.168.10.1/24 + mtu 1500 + +interface xe5 + ip vrf forwarding ecoc24 + ip address 192.168.150.1/24 + mtu 1500 + +router bgp 65001 + address-family ipv4 vrf ecoc24 + network 192.168.10.0/24 + neighbor 192.168.150.2 remote-as 65001 + neighbor 192.168.150.2 activate + exit-address-family diff --git a/test_csgw/csgw-configs/manual-config-bgp-custom-vrf-csgw2.conf b/test_csgw/csgw-configs/manual-config-bgp-custom-vrf-csgw2.conf new file mode 100644 index 0000000000000000000000000000000000000000..e8abac09d42698fcb58c922a7e22442502c98b3e --- /dev/null +++ b/test_csgw/csgw-configs/manual-config-bgp-custom-vrf-csgw2.conf @@ -0,0 +1,20 @@ +ip vrf ecoc24 + rd 65001:1 + route-target both 65001:1 + +interface ce1 + ip vrf forwarding ecoc24 + ip address 192.168.20.1/24 + mtu 1500 + +interface xe5 + ip vrf forwarding ecoc24 + ip address 192.168.150.2/24 + mtu 1500 + +router bgp 65001 + address-family ipv4 vrf ecoc24 + network 192.168.20.0/24 + neighbor 192.168.150.1 remote-as 65001 + neighbor 192.168.150.1 activate + exit-address-family diff --git a/test_csgw/csgw-configs/manual-config-bgp-custom-vrf-ecmp-csgw1.conf b/test_csgw/csgw-configs/manual-config-bgp-custom-vrf-ecmp-csgw1.conf new file mode 100644 index 0000000000000000000000000000000000000000..c062a8dfe5ff3f4077e5494cb41a5050e40e4861 --- /dev/null +++ b/test_csgw/csgw-configs/manual-config-bgp-custom-vrf-ecmp-csgw1.conf @@ -0,0 +1,28 @@ +ip vrf ecoc24 + rd 65001:1 + +interface ce1 + ip vrf forwarding ecoc24 + ip address 192.168.10.1/24 + mtu 1500 + +interface xe4 + ip vrf forwarding ecoc24 + ip address 192.168.150.1/24 + mtu 1500 + +interface xe5 + ip vrf forwarding ecoc24 + ip address 192.168.151.1/24 + mtu 1500 + +router bgp 65001 + bgp router-id 10.1.1.86 + address-family ipv4 vrf ecoc24 + max-paths ibgp 2 + network 192.168.10.0/24 + neighbor 192.168.150.2 remote-as 65001 + neighbor 192.168.150.2 activate + neighbor 192.168.151.2 remote-as 65001 + neighbor 192.168.151.2 activate + exit-address-family diff --git a/test_csgw/csgw-configs/manual-config-bgp-custom-vrf-ecmp-csgw2.conf b/test_csgw/csgw-configs/manual-config-bgp-custom-vrf-ecmp-csgw2.conf new file mode 100644 index 0000000000000000000000000000000000000000..05ff62175e30a8242d394306bbcebf545c61edaa --- /dev/null +++ b/test_csgw/csgw-configs/manual-config-bgp-custom-vrf-ecmp-csgw2.conf @@ -0,0 +1,28 @@ +ip vrf ecoc24 + rd 65001:1 + +interface ce1 + ip vrf forwarding ecoc24 + ip address 192.168.20.1/24 + mtu 1500 + +interface xe4 + ip vrf forwarding ecoc24 + ip address 192.168.150.2/24 + mtu 1500 + +interface xe5 + ip vrf forwarding ecoc24 + ip address 192.168.151.2/24 + mtu 1500 + +router bgp 65001 + bgp router-id 10.1.1.87 + address-family ipv4 vrf ecoc24 + max-paths ibgp 2 + network 192.168.20.0/24 + neighbor 192.168.150.1 remote-as 65001 + neighbor 192.168.150.1 activate + neighbor 192.168.151.1 remote-as 65001 + neighbor 192.168.151.1 activate + exit-address-family diff --git a/test_csgw/csgw-configs/manual-config-bgp-default-vrf-csgw1.conf b/test_csgw/csgw-configs/manual-config-bgp-default-vrf-csgw1.conf new file mode 100644 index 0000000000000000000000000000000000000000..596e3e51a02fbc27cd213d6e43a1f3f4fb10b2dc --- /dev/null +++ b/test_csgw/csgw-configs/manual-config-bgp-default-vrf-csgw1.conf @@ -0,0 +1,15 @@ +interface ce1 + ip address 192.168.10.1/24 + mtu 1500 + +interface xe5 + ip address 192.168.150.1/24 + mtu 1500 + +router bgp 65001 + bgp router-id 192.168.150.1 + neighbor 192.168.150.2 remote-as 65001 + address-family ipv4 unicast + network 192.168.10.0/24 + neighbor 192.168.150.2 activate + exit-address-family diff --git a/test_csgw/csgw-configs/manual-config-bgp-default-vrf-csgw2.conf b/test_csgw/csgw-configs/manual-config-bgp-default-vrf-csgw2.conf new file mode 100644 index 0000000000000000000000000000000000000000..341cfeebc08861953c4b6a9f48f79e33384b1c4e --- /dev/null +++ b/test_csgw/csgw-configs/manual-config-bgp-default-vrf-csgw2.conf @@ -0,0 +1,15 @@ +interface ce1 + ip address 192.168.20.1/24 + mtu 1500 + +interface xe5 + ip address 192.168.150.2/24 + mtu 1500 + +router bgp 65000 + bgp router-id 192.168.150.2 + neighbor 192.168.150.1 remote-as 65000 + address-family ipv4 unicast + network 192.168.20.0/24 + neighbor 192.168.150.1 activate + exit-address-family diff --git a/test_csgw/csgw-configs/manual-config-static-routing-csgw1.conf b/test_csgw/csgw-configs/manual-config-static-routing-csgw1.conf new file mode 100644 index 0000000000000000000000000000000000000000..6e5f98f0f7398dca154f5b3e772287e2df61aba4 --- /dev/null +++ b/test_csgw/csgw-configs/manual-config-static-routing-csgw1.conf @@ -0,0 +1,9 @@ +interface ce1 + ip address 192.168.10.1/24 + mtu 1500 + +interface xe5 + ip address 192.168.150.1/24 + mtu 1500 + +ip route 192.168.20.0/24 192.168.150.2 diff --git a/test_csgw/csgw-configs/manual-config-static-routing-csgw2.conf b/test_csgw/csgw-configs/manual-config-static-routing-csgw2.conf new file mode 100644 index 0000000000000000000000000000000000000000..a32394cb496a3b69fc9e587ed94a5329d4ca0771 --- /dev/null +++ b/test_csgw/csgw-configs/manual-config-static-routing-csgw2.conf @@ -0,0 +1,9 @@ +interface ce1 + ip address 192.168.20.1/24 + mtu 1500 + +interface xe5 + ip address 192.168.150.2/24 + mtu 1500 + +ip route 192.168.10.0/24 192.168.150.1 diff --git a/test_csgw/csgw-configs/tfs-configured-bgp-csgw1.cfg b/test_csgw/csgw-configs/tfs-configured-bgp-csgw1.cfg new file mode 100644 index 0000000000000000000000000000000000000000..7efd17cb050309f1dfe45ef3600af742f98c64ad --- /dev/null +++ b/test_csgw/csgw-configs/tfs-configured-bgp-csgw1.cfg @@ -0,0 +1,29 @@ +ip vrf ecoc24 + router-id 192.168.150.1 + rd 65001:1 + +mpls label mode all-afs vrf ecoc24 per-vrf + +interface ce1 + ip vrf forwarding ecoc24 + ip address 192.168.10.1/24 + mtu 1500 + +interface lo.ecoc24 + ip vrf forwarding ecoc24 + ip address 127.0.0.1/8 + ipv6 address ::1/128 + +interface xe5 + ip vrf forwarding ecoc24 + ip address 192.168.150.1/24 + mtu 1500 + +router bgp 65001 + bgp router-id 192.168.150.1 + address-family ipv4 vrf ecoc24 + redistribute connected + redistribute static + neighbor 192.168.150.2 remote-as 65001 + neighbor 192.168.150.2 activate + exit-address-family diff --git a/test_csgw/csgw-configs/tfs-configured-bgp-csgw2.cfg b/test_csgw/csgw-configs/tfs-configured-bgp-csgw2.cfg new file mode 100644 index 0000000000000000000000000000000000000000..2aaeb1427eec908a83e611bf1eadcdfba6c5275d --- /dev/null +++ b/test_csgw/csgw-configs/tfs-configured-bgp-csgw2.cfg @@ -0,0 +1,29 @@ +ip vrf ecoc24 + router-id 192.168.150.2 + rd 65001:1 + +mpls label mode all-afs vrf ecoc24 per-vrf + +interface ce1 + ip vrf forwarding ecoc24 + ip address 192.168.20.1/24 + mtu 1500 + +interface lo.ecoc24 + ip vrf forwarding ecoc24 + ip address 127.0.0.1/8 + ipv6 address ::1/128 + +interface xe5 + ip vrf forwarding ecoc24 + ip address 192.168.150.2/24 + mtu 1500 + +router bgp 65001 + bgp router-id 192.168.150.2 + address-family ipv4 vrf ecoc24 + redistribute connected + redistribute static + neighbor 192.168.150.1 remote-as 65001 + neighbor 192.168.150.1 activate + exit-address-family diff --git a/test_csgw/csgw-configs/tfs-ip-topology.json b/test_csgw/csgw-configs/tfs-ip-topology.json new file mode 100644 index 0000000000000000000000000000000000000000..e9d89eaa5b5267b4b04041a6ef62aedbad697663 --- /dev/null +++ b/test_csgw/csgw-configs/tfs-ip-topology.json @@ -0,0 +1,34 @@ +{ + "contexts": [ + {"context_id": {"context_uuid": {"uuid": "admin"}}} + ], + "topologies": [ + {"topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}} + ], + "devices": [ + { + "device_id": {"device_uuid": {"uuid": "CSGW1"}}, "device_type": "packet-router", "device_drivers": ["DEVICEDRIVER_OPENCONFIG"], + "device_config": {"config_rules": [ + {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/address", "resource_value": "10.1.1.86"}}, + {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/port", "resource_value": "830"}}, + {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/settings", "resource_value": { + "username": "ocnos", "password": "ocnos", "force_running": false, "hostkey_verify": false, + "look_for_keys": false, "allow_agent": false, "commit_per_rule": true, + "device_params": {"name": "default"}, "manager_params": {"timeout" : 120} + }}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "CSGW2"}}, "device_type": "packet-router", "device_drivers": ["DEVICEDRIVER_OPENCONFIG"], + "device_config": {"config_rules": [ + {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/address", "resource_value": "10.1.1.87"}}, + {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/port", "resource_value": "830"}}, + {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/settings", "resource_value": { + "username": "ocnos", "password": "ocnos", "force_running": false, "hostkey_verify": false, + "look_for_keys": false, "allow_agent": false, "commit_per_rule": true, + "device_params": {"name": "default"}, "manager_params": {"timeout" : 120} + }}} + ]} + } + ] +} diff --git a/test_csgw/get_config/get_config.py b/test_csgw/get_config/get_config.py new file mode 100644 index 0000000000000000000000000000000000000000..ed26938d5b32d690f176863163b32327f61df264 --- /dev/null +++ b/test_csgw/get_config/get_config.py @@ -0,0 +1,40 @@ +# Copyright 2022-2024 ETSI 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 Optional +from ncclient.manager import Manager, connect_ssh + +def _filter(str_filter : Optional[str] = None) -> str: + return "{:s}".format(str_filter or '') + +#str_filter_components = _filter('') + +def get_config(host : str, out_file : str, str_filter : Optional[str] = None) -> None: + manager : Manager = connect_ssh( + host=host, port=830, username='ocnos', password='ocnos', + device_params={'name': 'huaweiyang'}, manager_params={'timeout': 120}, + key_filename=None, hostkey_verify=False, allow_agent=False, + look_for_keys=False + ) + data = manager.get_config('running', filter=str_filter, with_defaults=None).data_xml + with open(out_file, 'w', encoding='utf-8') as f: + f.write(data) + manager.close_session() + +def main() -> None: + get_config('10.1.1.86', 'csgw1_all.xml', str_filter=None) + get_config('10.1.1.87', 'csgw2_all.xml', str_filter=None) + +if __name__ == '__main__': + main() diff --git a/test_csgw/run.sh b/test_csgw/run.sh new file mode 100644 index 0000000000000000000000000000000000000000..8cc73b78b9fb8a99309b1c9823256d205404cda8 --- /dev/null +++ b/test_csgw/run.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +PYTHONPATH=./src +python -m test_csgw