Skip to content
# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 re
from typing import List
from ..gnmi.gnmi_pb2 import Path, PathElem
RE_PATH_SPLIT = re.compile(r'/(?=(?:[^\[\]]|\[[^\[\]]+\])*$)')
RE_PATH_KEYS = re.compile(r'\[(.*?)\]')
def path_from_string(path='/'):
if not path: return Path(elem=[])
if path[0] == '/':
if path[-1] == '/':
path_list = RE_PATH_SPLIT.split(path)[1:-1]
else:
path_list = RE_PATH_SPLIT.split(path)[1:]
else:
if path[-1] == '/':
path_list = RE_PATH_SPLIT.split(path)[:-1]
else:
path_list = RE_PATH_SPLIT.split(path)
path = []
for elem in path_list:
elem_name = elem.split('[', 1)[0]
elem_keys = RE_PATH_KEYS.findall(elem)
dict_keys = dict(x.split('=', 1) for x in elem_keys)
path.append(PathElem(name=elem_name, key=dict_keys))
return Path(elem=path)
def path_to_string(path : Path) -> str:
path_parts = list()
for elem in path.elem:
kv_list = list()
for key in elem.key:
value = elem.key[key]
kv = '{:s}={:s}'.format(key, value)
kv_list.append(kv)
path_part_name = elem.name
if len(kv_list) == 0:
path_parts.append(path_part_name)
else:
str_kv = ', '.join(kv_list)
path_part = '{:s}[{:s}]'.format(path_part_name, str_kv)
path_parts.append(path_part)
str_path = '/{:s}'.format('/'.join(path_parts))
return str_path
def parse_xpath(xpath : str) -> str:
xpath = xpath.replace('//', '/')
xpath = xpath.replace('oci:interface[', 'interface[')
xpath = xpath.replace('/oci', '/openconfig-interfaces')
xpath = re.sub(r"\[oci:name='(.*?)'\]", r"[name=\1]", xpath)
# Eliminar el contador del final
xpath = '/'.join(xpath.split('/')[:-1]) + '/'
return xpath
def split_resource_key(path):
pattern = r'/state/counters/(.*)'
match = re.search(pattern, path)
if match is None: return None
return match.group(1)
def dict_to_xpath(d: dict) -> str:
xpath = '/'
for item in d['elem']:
name = item.get('name')
if name == 'interface':
key = item.get('key')
interface_name = key.get('name')
xpath += f"/oci:interface[oci:name='{interface_name}']"
else:
xpath += f"/{name}"
xpath = xpath.replace('openconfig-interfaces', 'oci')
return xpath
def compose_path(base_path : str, path_filters : List[str] = []):
new_path = '' if base_path is None else str(base_path)
for path_filter in path_filters:
if path_filter == '': continue
new_path = '{:s}[{:s}]'.format(new_path, path_filter)
return new_path
# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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.
# Collection of samples through NetConf is very slow and each request collects all the data.
# Populate a cache periodically (when first interface is interrogated).
# Evict data after some seconds, when data is considered as outdated
import anytree
from typing import Any, List
from device.service.driver_api.AnyTreeTools import TreeNode, get_subnode, set_subnode_value
class Subscriptions:
def __init__(self) -> None:
self.__resolver = anytree.Resolver(pathattr='name')
self.__subscriptions = TreeNode('.')
def add(
self, resource_path : List[str], sampling_duration : float, sampling_interval : float, value : Any
) -> None:
subscription_path = resource_path + ['{:.3f}:{:.3f}'.format(sampling_duration, sampling_interval)]
set_subnode_value(self.__resolver, self.__subscriptions, subscription_path, value)
def get(
self, resource_path : List[str], sampling_duration : float, sampling_interval : float
) -> TreeNode:
subscription_path = resource_path + ['{:.3f}:{:.3f}'.format(sampling_duration, sampling_interval)]
value = get_subnode(self.__resolver, self.__subscriptions, subscription_path)
return value
def delete(
self, reference : TreeNode
) -> None:
parent : TreeNode = reference.parent
children = list(parent.children)
children.remove(reference)
parent.children = tuple(children)
# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 base64, json
from typing import Any
from ..gnmi.gnmi_pb2 import TypedValue
def decode_value(value : TypedValue) -> Any:
encoding = value.WhichOneof('value')
if encoding == 'json_val':
value = value.json_val
#mdl, cls = self._classes[className]
#obj = json.loads(strObj)
#if isinstance(obj, (list,)):
# obj = map(lambda n: pybindJSON.loads(n, mdl, cls.__name__), obj)
# data = map(lambda n: json.loads(pybindJSON.dumps(n, mode='default')), obj)
#else:
# obj = pybindJSON.loads(obj, mdl, cls.__name__)
# data = json.loads(pybindJSON.dumps(obj, mode='default'))
raise NotImplementedError()
#return value
elif encoding == 'json_ietf_val':
value : str = value.json_ietf_val
try:
return json.loads(value)
except json.decoder.JSONDecodeError:
# Assume is Base64-encoded
b_b64_value = value.encode('UTF-8')
b_value = base64.b64decode(b_b64_value, validate=True)
value = b_value.decode('UTF-8')
return json.loads(value)
else:
MSG = 'Unsupported Encoding({:s}) in Value({:s})'
# pylint: disable=broad-exception-raised
raise Exception(MSG.format(str(encoding), str(value)))
def value_exists(value) -> bool:
if value is None: return False
if isinstance(value, Exception): return False
if issubclass(type(value), Exception): return False
return True
# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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.
{
"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": "spine1"}}, "device_type": "packet-router", "device_drivers": [9],
"device_operational_status": 1, "device_config": {"config_rules": [
{"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "172.20.20.101"}},
{"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "57400"}},
{"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {
"protocol": "gnmi", "username": "admin", "password": "NokiaSrl1!", "use_tls": true
}}}
]}
},
{
"device_id": {"device_uuid": {"uuid": "leaf1"}}, "device_type": "packet-router", "device_drivers": [9],
"device_operational_status": 1, "device_config": {"config_rules": [
{"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "172.20.20.102"}},
{"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "57400"}},
{"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {
"protocol": "gnmi", "username": "admin", "password": "NokiaSrl1!", "use_tls": true
}}}
]}
},
{
"device_id": {"device_uuid": {"uuid": "leaf2"}}, "device_type": "packet-router", "device_drivers": [9],
"device_operational_status": 1, "device_config": {"config_rules": [
{"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "172.20.20.103"}},
{"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "57400"}},
{"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {
"protocol": "gnmi", "username": "admin", "password": "NokiaSrl1!", "use_tls": true
}}}
]}
},
{
"device_id": {"device_uuid": {"uuid": "srv1"}}, "device_type": "emu-datacenter", "device_drivers": [0],
"device_config": {"config_rules": [
{"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}},
{"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}},
{"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [
{"uuid": "eth1", "type": "copper"}, {"uuid": "int", "type": "copper"}
]}}}
]}
},
{
"device_id": {"device_uuid": {"uuid": "srv2"}}, "device_type": "emu-datacenter", "device_drivers": [0],
"device_config": {"config_rules": [
{"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}},
{"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}},
{"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [
{"uuid": "eth1", "type": "copper"}, {"uuid": "int", "type": "copper"}
]}}}
]}
}
]
}
{
"links": [
{
"link_id": {"link_uuid": {"uuid": "leaf1/ethernet-1/49==spine1/ethernet-1/1"}},
"link_endpoint_ids": [
{"device_id": {"device_uuid": {"uuid": "leaf1"}}, "endpoint_uuid": {"uuid": "ethernet-1/49"}},
{"device_id": {"device_uuid": {"uuid": "spine1"}}, "endpoint_uuid": {"uuid": "ethernet-1/1"}}
]
},
{
"link_id": {"link_uuid": {"uuid": "spine1/ethernet-1/1==leaf1/ethernet-1/49"}},
"link_endpoint_ids": [
{"device_id": {"device_uuid": {"uuid": "spine1"}}, "endpoint_uuid": {"uuid": "ethernet-1/1"}},
{"device_id": {"device_uuid": {"uuid": "leaf1"}}, "endpoint_uuid": {"uuid": "ethernet-1/49"}}
]
},
{
"link_id": {"link_uuid": {"uuid": "spine1/ethernet-1/2==leaf2/ethernet-1/49"}},
"link_endpoint_ids": [
{"device_id": {"device_uuid": {"uuid": "spine1"}}, "endpoint_uuid": {"uuid": "ethernet-1/2"}},
{"device_id": {"device_uuid": {"uuid": "leaf2"}}, "endpoint_uuid": {"uuid": "ethernet-1/49"}}
]
},
{
"link_id": {"link_uuid": {"uuid": "leaf2/ethernet-1/2==spine1/ethernet-1/49"}},
"link_endpoint_ids": [
{"device_id": {"device_uuid": {"uuid": "leaf2"}}, "endpoint_uuid": {"uuid": "ethernet-1/49"}},
{"device_id": {"device_uuid": {"uuid": "spine1"}}, "endpoint_uuid": {"uuid": "ethernet-1/2"}}
]
},
{
"link_id": {"link_uuid": {"uuid": "srv1/eth1==leaf1/ethernet-1/1"}},
"link_endpoint_ids": [
{"device_id": {"device_uuid": {"uuid": "srv1"}}, "endpoint_uuid": {"uuid": "eth1"}},
{"device_id": {"device_uuid": {"uuid": "leaf1"}}, "endpoint_uuid": {"uuid": "ethernet-1/1"}}
]
},
{
"link_id": {"link_uuid": {"uuid": "leaf1/ethernet-1/1==srv1/eth1"}},
"link_endpoint_ids": [
{"device_id": {"device_uuid": {"uuid": "leaf1"}}, "endpoint_uuid": {"uuid": "ethernet-1/1"}},
{"device_id": {"device_uuid": {"uuid": "srv1"}}, "endpoint_uuid": {"uuid": "eth1"}}
]
},
{
"link_id": {"link_uuid": {"uuid": "srv2/eth1==leaf2/ethernet-1/1"}},
"link_endpoint_ids": [
{"device_id": {"device_uuid": {"uuid": "srv2"}}, "endpoint_uuid": {"uuid": "eth1"}},
{"device_id": {"device_uuid": {"uuid": "leaf2"}}, "endpoint_uuid": {"uuid": "ethernet-1/1"}}
]
},
{
"link_id": {"link_uuid": {"uuid": "leaf2/ethernet-1/1==srv2/eth1"}},
"link_endpoint_ids": [
{"device_id": {"device_uuid": {"uuid": "leaf2"}}, "endpoint_uuid": {"uuid": "ethernet-1/1"}},
{"device_id": {"device_uuid": {"uuid": "srv2"}}, "endpoint_uuid": {"uuid": "eth1"}}
]
}
]
}
{
"devices": [
{
"device_id": {"device_uuid": {"uuid": "leaf1"}}, "device_type": "packet-router", "device_drivers": [9],
"device_operational_status": 2, "device_config": {"config_rules": [
{"action": 1, "custom": {"resource_key": "/interface[name=ethernet-1/49]", "resource_value": {
"name" : "ethernet-1/49",
"admin_state" : true,
"sub_index" : 0,
"sub_ipv4_admin_state":true,
"sub_ipv4_address" : "192.168.11.1",
"sub_ipv4_prefix" : "30"
}}},
{"action": 1, "custom": {"resource_key": "/routing-policy", "resource_value": {
"name" : "all",
"policy_result": "accept"
}}}
,{"action": 1, "custom": {"resource_key": "/network-instance[name=default]", "resource_value": {
"name" : "default",
"interface1" : "ethernet-1/49.0",
"interface2" : "system0.0",
"admin_state_bgp" : true,
"afi_safi_name_bgp" : "ipv4-unicast",
"autonomous_system_bgp" : 101,
"export_policy" : "all",
"group_name" : "eBGP-underlay",
"import_policy" : "all",
"peer_as" : 201,
"admin_state_group" : true,
"afi_safi_name_group" : "evpn",
"admin_state_group_2" : false,
"afi_safi_name_group_2" : "ipv4-unicast",
"export_policy_2" : "all",
"group_name_2" : "iBGP-overlay",
"import_policy_2" : "all",
"as_number" : 100,
"peer_as_2" : 100,
"minimum_advertisement_interval" : 1,
"admin_state_neighbor" : true,
"peer_address_neighbor" : "10.0.0.2",
"peer_group_neighbor" : "iBGP-overlay",
"local_address_neighbor" : "10.0.0.1",
"peer_address_neighbor_2" : "192.168.11.2",
"peer_group_neighbor_2" : "eBGP-underlay",
"router_id" : "10.0.0.1"
}}},
{"action": 1, "custom": {"resource_key": "/interface[name=system0]", "resource_value": {
"name" : "system0",
"admin_state" : true,
"sub_index" : 0,
"sub_ipv4_admin_state":true,
"sub_ipv4_address" : "10.0.0.1",
"sub_ipv4_prefix" : "32"
}}},
{"action": 1, "custom": {"resource_key": "/interface[name=ethernet-1/1]", "resource_value": {
"name" : "ethernet-1/1",
"vlan_tagging" : true,
"sub_index" : 0,
"sub_type" : "bridged",
"sub_vlan_admin_state" : true,
"sub_vlan_encap":"untagged"
}}},
{"action": 1, "custom": {"resource_key": "/network-instance[name=vrf-1]", "resource_value": {
"name" : "vrf-1",
"type" : "mac-vrf",
"admin_state_vrf" : true,
"interface1_name" : "ethernet-1/1.0",
"vxlaninterface_name" : "vxlan1.1",
"bgp_evpn_instance_id":1,
"bgp_evpn_instance_admin_state":true,
"bgp_evpn_instance_vxlan_interface":"vxlan1.1",
"bgp_evpn_instance_evi":111,
"bgp_vpn_instance_id":1,
"bgp_vpn_instance_export_rt":"target:100:111",
"bgp_vpn_instance_import_rt":"target:100:111"
}}},
{"action": 1, "custom": {"resource_key": "/tunnel-interface[name=vxlan1]", "resource_value": {
"name" : "vxlan1",
"index" : 1,
"type_tunnel" :"bridged",
"vni_tunnel" : 1
}}}
]}
},
{
"device_id": {"device_uuid": {"uuid": "leaf2"}}, "device_type": "packet-router", "device_drivers": [9],
"device_operational_status": 2, "device_config": {"config_rules": [
{"action": 1, "custom": {"resource_key": "/interface[name=ethernet-1/49]", "resource_value": {
"name" : "ethernet-1/49",
"admin_state" : true,
"sub_index" : 0,
"sub_ipv4_admin_state":true,
"sub_ipv4_address" : "192.168.12.1",
"sub_ipv4_prefix" : "30"
}}},
{"action": 1, "custom": {"resource_key": "/routing-policy", "resource_value": {
"name" : "all",
"policy_result": "accept"
}}}
,{"action": 1, "custom": {"resource_key": "/network-instance[name=default]", "resource_value": {
"name" : "default",
"interface1" : "ethernet-1/49.0",
"interface2" : "system0.0",
"admin_state_bgp" : true,
"afi_safi_name_bgp" : "ipv4-unicast",
"autonomous_system_bgp" : 102,
"export_policy" : "all",
"group_name" : "eBGP-underlay",
"import_policy" : "all",
"peer_as" : 201,
"admin_state_group" : true,
"afi_safi_name_group" : "evpn",
"admin_state_group_2" : false,
"afi_safi_name_group_2" : "ipv4-unicast",
"export_policy_2" : "all",
"group_name_2" : "iBGP-overlay",
"import_policy_2" : "all",
"as_number" : 100,
"peer_as_2" : 100,
"minimum_advertisement_interval" : 1,
"admin_state_neighbor" : true,
"peer_address_neighbor" : "10.0.0.1",
"peer_group_neighbor" : "iBGP-overlay",
"local_address_neighbor" : "10.0.0.2",
"peer_address_neighbor_2" : "192.168.12.2",
"peer_group_neighbor_2" : "eBGP-underlay",
"router_id" : "10.0.0.2"
}}},
{"action": 1, "custom": {"resource_key": "/interface[name=system0]", "resource_value": {
"name" : "system0",
"admin_state" : true,
"sub_index" : 0,
"sub_ipv4_admin_state":true,
"sub_ipv4_address" : "10.0.0.2",
"sub_ipv4_prefix" : "32"
}}},
{"action": 1, "custom": {"resource_key": "/interface[name=ethernet-1/1]", "resource_value": {
"name" : "ethernet-1/1",
"vlan_tagging" : true,
"sub_index" : 0,
"sub_type" : "bridged",
"sub_vlan_admin_state" : true,
"sub_vlan_encap":"untagged"
}}},
{"action": 1, "custom": {"resource_key": "/network-instance[name=vrf-1]", "resource_value": {
"name" : "vrf-1",
"type" : "mac-vrf",
"admin_state_vrf" : true,
"interface1_name" : "ethernet-1/1.0",
"vxlaninterface_name" : "vxlan1.1",
"bgp_evpn_instance_id":1,
"bgp_evpn_instance_admin_state":true,
"bgp_evpn_instance_vxlan_interface":"vxlan1.1",
"bgp_evpn_instance_evi":111,
"bgp_vpn_instance_id":1,
"bgp_vpn_instance_export_rt":"target:100:111",
"bgp_vpn_instance_import_rt":"target:100:111"
}}},
{"action": 1, "custom": {"resource_key": "/tunnel-interface[name=vxlan1]", "resource_value": {
"name" : "vxlan1",
"index" : 1,
"type_tunnel" :"bridged",
"vni_tunnel" : 1
}}}
]}
},
{
"device_id": {"device_uuid": {"uuid": "spine1"}}, "device_type": "packet-router", "device_drivers": [9],
"device_operational_status": 2, "device_config": {"config_rules": [
{"action": 1, "custom": {"resource_key": "/interface[name=ethernet-1/49]", "resource_value": {
"name" : "ethernet-1/1",
"admin_state" : true,
"sub_index" : 0,
"sub_ipv4_admin_state":true,
"sub_ipv4_address" : "192.168.11.2",
"sub_ipv4_prefix" : "30"
}}},
{"action": 1, "custom": {"resource_key": "/interface[name=ethernet-1/49]", "resource_value": {
"name" : "ethernet-1/2",
"admin_state" : true,
"sub_index" : 0,
"sub_ipv4_admin_state":true,
"sub_ipv4_address" : "192.168.12.2",
"sub_ipv4_prefix" : "30"
}}},
{"action": 1, "custom": {"resource_key": "/network-instance[name=default]", "resource_value": {
"interface1_spine" : "ethernet-1/1.0",
"interface2_spine" : "ethernet-1/2.0",
"interface3_spine" : "system0.0",
"name" : "default",
"admin_state_spine" : true,
"afi_safi_name_bgp_spine" : "ipv4-unicast",
"autonomous_system_bgp_spine" : 201,
"export_policy_spine" : "all",
"group_name_spine" : "eBGP-underlay",
"import_policy_spine" : "all",
"peer_address_neighbor_spine" : "192.168.11.1",
"peeras_group_neighbor_spine" : 101,
"peer_group_neighbor_spine" : "eBGP-underlay",
"peer_address2_neighbor_spine" : "192.168.12.1",
"peeras_group_neighbor2_spine" : 102,
"peer_group_neighbor2_spine" : "eBGP-underlay",
"router_id_spine":"10.0.1.1"
}}},
{"action": 1, "custom": {"resource_key": "/interface[name=ethernet-1/49]", "resource_value": {
"name" : "system0",
"admin_state" : true,
"sub_index" : 0,
"sub_ipv4_admin_state":true,
"sub_ipv4_address" : "10.0.1.1",
"sub_ipv4_prefix" : 32
}}},
{"action": 1, "custom": {"resource_key": "/routing-policy", "resource_value": {
"name" : "all",
"policy_result": "accept"
}}}
]}
}
]
}
#!/bin/bash
# address for our topology example here in cttc test
TOPOLOGY_FILE="evpn01.clab.yml"
# Ensure you get elevated privileges
sudo true
# Check if the topology exists and destroy it to build our new topology again
sudo containerlab destroy --topo $TOPOLOGY_FILE
echo "Topology destroyed successfully."
sudo rm -rf clab-evpn01 .evpn01.clab.yml.bak
# Build the new topology
sudo containerlab deploy --topo $TOPOLOGY_FILE
echo "Topology deployed successfully."
name: evpn01
topology:
kinds:
srl:
image: ghcr.io/nokia/srlinux:23.10.1
linux:
image: ghcr.io/hellt/network-multitool
nodes:
spine1:
kind: srl
type: ixrd3
mgmt-ipv4: 172.20.20.101
leaf1:
kind: srl
type: ixrd2
mgmt-ipv4: 172.20.20.102
leaf2:
kind: srl
type: ixrd2
mgmt-ipv4: 172.20.20.103
srv1:
kind: linux
exec:
- ip link set address 00:c1:ab:00:00:01 dev eth1
- ip addr add 192.168.0.1/24 dev eth1
srv2:
kind: linux
exec:
- ip link set address 00:c1:ab:00:00:02 dev eth1
- ip addr add 192.168.0.2/24 dev eth1
links:
# inter-switch links
- endpoints: ["leaf1:e1-49", "spine1:e1-1"]
- endpoints: ["leaf2:e1-49", "spine1:e1-2"]
# server links
- endpoints: ["srv1:eth1", "leaf1:e1-1"]
- endpoints: ["srv2:eth1", "leaf2:e1-1"]
\ No newline at end of file
# Ref: https://github.com/aristanetworks/openmgmt/blob/main/src/pygnmi/update.py
# Ref: https://github.com/aristanetworks/openmgmt/blob/main/src/pygnmi/delete.py
# Ref: https://yang.srlinux.dev/release/v23.3.2/
from pygnmi.client import gNMIclient
host = {
"ip_address": "172.20.20.102",
"port": 57400,
"username": "admin",
"password": "NokiaSrl1!"
}
if __name__ == "__main__":
with gNMIclient(
target=(host["ip_address"], host["port"]), username=host["username"], password=host["password"],
insecure=False, debug=True
) as gc:
updates = [
('/interface[name=ethernet-1/49]',
{
"admin-state": "enable",
"subinterface": [
{
"index": 0,
"ipv4": {
"admin-state": "enable",
"address": [
{
"ip-prefix": "192.168.11.1/30"
}
]
}
}
]
}
),
('/network-instance[name=default]',
{
"interface": [
{"name": "ethernet-1/49.0"},
{"name": "system0.0"}
],
"name": "default",
"protocols": {
"bgp": {
"afi-safi": [
{
"admin-state": "enable",
"afi-safi-name": "ipv4-unicast"
}
],
"autonomous-system": 101,
"group": [
{
"export-policy": "all",
"group-name": "eBGP-underlay",
"import-policy": "all",
"peer-as": 201
},
{
"afi-safi": [
{
"admin-state": "enable",
"afi-safi-name": "evpn"
},
{
"admin-state": "disable",
"afi-safi-name": "ipv4-unicast"
}
],
"export-policy": "all",
"group-name": "iBGP-overlay",
"import-policy": "all",
"local-as": {
"as-number": 100
},
"peer-as": 100,
"timers": {
"minimum-advertisement-interval": 1
}
}
],
"neighbor": [
{
"admin-state": "enable",
"peer-address": "10.0.0.2",
"peer-group": "iBGP-overlay",
"transport": {
"local-address": "10.0.0.1"
}
},
{
"peer-address": "192.168.11.2",
"peer-group": "eBGP-underlay"
}
],
"router-id": "10.0.0.1"
}
},
}
),
('/routing-policy',
{
"policy": [
{
"name": "all",
"default-action": {
"policy-result": "accept"
}
}
]
}
),
('/interface[name=system0]',
{
"name": "system0",
"admin-state": "enable",
"subinterface": [
{
"index": 0,
"ipv4": {
"admin-state": "enable",
"address": [
{
"ip-prefix": "10.0.0.1/32"
}
]
}
}
]
}
),
('/interface[name=ethernet-1/1]',
{
"vlan-tagging": True,
"subinterface": [ {
"index": 0,
"type": "bridged",
"admin-state": "enable",
"vlan": {
"encap": {
"untagged": {}
}
}
}
]
}
),
('/network-instance[name=vrf-1]',
{
"name": "vrf-1",
"type": "mac-vrf",
"admin-state": "enable",
"interface": [
{"name": "ethernet-1/1.0"}
],
"vxlan-interface": [
{"name": "vxlan1.1"}
],
"protocols": {
"bgp-evpn": {
"bgp-instance": [
{
"id": 1,
"admin-state": "enable",
"vxlan-interface": "vxlan1.1",
"evi": 111
}
]
},
"bgp-vpn": {
"bgp-instance": [
{
"id": 1,
"route-target": {
"export-rt": "target:100:111",
"import-rt": "target:100:111"
}
}
]
}
}
}
),
('/tunnel-interface[name=vxlan1]',
{"vxlan-interface": [
{
"index": "1",
"type": "bridged",
"ingress": {
"vni": 1
}
}
]
}
)
]
result = gc.set(update=updates, encoding='json_ietf')
print(result)
\ No newline at end of file
# Ref: https://github.com/aristanetworks/openmgmt/blob/main/src/pygnmi/update.py
# Ref: https://github.com/aristanetworks/openmgmt/blob/main/src/pygnmi/delete.py
# Ref: https://yang.srlinux.dev/release/v23.3.2/
from pygnmi.client import gNMIclient
host = {
"ip_address": "172.20.20.103",
"port": 57400,
"username": "admin",
"password": "NokiaSrl1!"
}
if __name__ == "__main__":
with gNMIclient(
target=(host["ip_address"], host["port"]), username=host["username"], password=host["password"],
insecure=False
) as gc:
updates = [
('/interface[name=ethernet-1/49]',
{
"admin-state": "enable",
"subinterface": [
{
"index": 0,
"ipv4": {
"admin-state": "enable",
"address": [
{
"ip-prefix": "192.168.12.1/30"
}
]
}
}
]
}
),
('/network-instance[name=default]',
{
"interface": [
{"name": "ethernet-1/49.0"},
{"name": "system0.0"}
],
"name": "default",
"protocols": {
"bgp": {
"afi-safi": [
{
"admin-state": "enable",
"afi-safi-name": "ipv4-unicast"
}
],
"autonomous-system": 102,
"group": [
{
"export-policy": "all",
"group-name": "eBGP-underlay",
"import-policy": "all",
"peer-as": 201
},
{
"afi-safi": [
{
"admin-state": "enable",
"afi-safi-name": "evpn"
},
{
"admin-state": "disable",
"afi-safi-name": "ipv4-unicast"
}
],
"export-policy": "all",
"group-name": "iBGP-overlay",
"import-policy": "all",
"local-as": {
"as-number": 100
},
"peer-as": 100,
"timers": {
"minimum-advertisement-interval": 1
}
}
],
"neighbor": [
{
"admin-state": "enable",
"peer-address": "10.0.0.1",
"peer-group": "iBGP-overlay",
"transport": {
"local-address": "10.0.0.2"
}
},
{
"peer-address": "192.168.12.2",
"peer-group": "eBGP-underlay"
}
],
"router-id": "10.0.0.2"
}
},
}
),
('/routing-policy',
{
"policy": [
{
"name": "all",
"default-action": {
"policy-result": "accept"
}
}
]
}
),
('/interface[name=system0]',
{
"name": "system0",
"admin-state": "enable",
"subinterface": [
{
"index": 0,
"ipv4": {
"admin-state": "enable",
"address": [
{
"ip-prefix": "10.0.0.2/32"
}
]
}
}
]
}
),
('/interface[name=ethernet-1/1]',
{
"vlan-tagging": True,
"subinterface": {
"index": 0,
"type": "bridged",
"admin-state": "enable",
"vlan": {
"encap": {
"untagged": {}
}
}
}
}
),
('/network-instance[name=vrf-1]',
{
"name": "vrf-1",
"type": "mac-vrf",
"admin-state": "enable",
"interface": [
{"name": "ethernet-1/1.0"}
],
"vxlan-interface": [
{"name": "vxlan1.1"}
],
"protocols": {
"bgp-evpn": {
"bgp-instance": [
{
"id": 1,
"admin-state": "enable",
"vxlan-interface": "vxlan1.1",
"evi": 111
}
]
},
"bgp-vpn": {
"bgp-instance": [
{
"id": 1,
"route-target": {
"export-rt": "target:100:111",
"import-rt": "target:100:111"
}
}
]
}
}
}
),
('/tunnel-interface[name=vxlan1]',
{"vxlan-interface": [
{
"index": "1",
"type": "bridged",
"ingress": {
"vni": 1
}
}
]
}
)
]
result = gc.set(update=updates, encoding='json_ietf')
print(result)
\ No newline at end of file
from pygnmi.client import gNMIclient
host1 = {"ip_address": "172.20.20.101", "port": 57400, "username": "admin", "password": "NokiaSrl1!"}
if __name__ == "__main__":
with gNMIclient(
target=(host1["ip_address"], host1["port"]), username=host1["username"], password=host1["password"],
insecure=False
) as gc:
updates = [
('/interface[name=ethernet-1/1]', { #interfaces
"admin-state": "enable",
"subinterface": [
{
"index": 0,
"ipv4": {
"admin-state": "enable",
"address": [
{
"ip-prefix": "192.168.11.2/30"
}
]
}
}
]
}),
('/interface[name=ethernet-1/2]', {
"admin-state": "enable",
"subinterface": [
{
"index": 0,
"ipv4": {
"admin-state": "enable",
"address": [
{
"ip-prefix": "192.168.12.2/30"
}
]
}
}
]
}),
('/network-instance[name=default]', { #default network instance
"interface": [
{"name": "ethernet-1/1.0"},
{"name": "ethernet-1/2.0"},
{"name": "system0.0"}
],
"name": "default",
"protocols": {
"bgp": {
"afi-safi": [
{
"admin-state": "enable",
"afi-safi-name": "ipv4-unicast"
}
],
"autonomous-system": 201,
"group": [
{
"export-policy": "all",
"group-name": "eBGP-underlay",
"import-policy": "all",
}
],
"neighbor": [
{
"peer-address": "192.168.11.1",
"peer-as": 101,
"peer-group": "eBGP-underlay",
},
{
"peer-address": "192.168.12.1",
"peer-as": 102,
"peer-group": "eBGP-underlay",
}
],
"router-id": "10.0.1.1"
}
},
}),
('/interface[name=system0]', {
"name": "system0",
"admin-state": "enable",
"subinterface": [
{
"index": 0,
"ipv4": {
"admin-state": "enable",
"address": [
{
"ip-prefix": "10.0.1.1/32"
}
]
}
}
]
}
),
('/routing-policy', { #routing policy
"policy": {
"name": "all",
"default-action": {
"policy-result": "accept"
}
}
}
),
]
result = gc.set(update=updates, encoding='json_ietf')
print(result)
#first redeploy on /home/cttc/evpn01/deploy.sh
#Run the set scripts for the 2 leafs and spine together for setting the configurations
#Try to ping from server 1 to server 2 after redeploying and configuring
# server one is on 192.168.01 while server 2 ip is 192.168.0.2
#when trying to ping the first time it fail to ping server 2
#cancel and try again it will succesfully ping
#Hashtag the set commands and only keep the below which is concerned with the parse function
# resources_to_get_leaf1 = [RESOURCE_INTERFACES]
# LOGGER.info('resources_to_get = {:s}'.format(str(resources_to_get_leaf1)))
# results_getconfig_leaf1 = dev1_driver.GetConfig(resources_to_get_leaf1)
# LOGGER.info('results_getconfig = {:s}'.format(str(results_getconfig_leaf1)))
# except Exception as e:
#
# logging.exception("Exception occurred", exc_info=True)
# After running so , therse is an error related to the path
\ No newline at end of file
# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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, os, sys, time
from typing import Dict, Tuple
os.environ['DEVICE_EMULATED_ONLY'] = 'YES'
from device.service.drivers.gnmi_openconfig.GnmiOpenConfigDriver import GnmiOpenConfigDriver # pylint: disable=wrong-import-position
#from device.service.driver_api._Driver import (
# RESOURCE_ENDPOINTS, RESOURCE_INTERFACES, RESOURCE_NETWORK_INSTANCES, RESOURCE_ROUTING_POLICIES, RESOURCE_SERVICES
#)
logging.basicConfig(level=logging.DEBUG)
LOGGER = logging.getLogger(__name__)
LOGGER.setLevel(logging.DEBUG)
# +---+---------------------------+--------------+---------------------------------+-------+---------+--------------------+--------------+
# | # | Name | Container ID | Image | Kind | State | IPv4 Address | IPv6 Address |
# +---+---------------------------+--------------+---------------------------------+-------+---------+--------------------+--------------+
# | 1 | clab-tfs-scenario-client1 | a8d48ec3265a | ghcr.io/hellt/network-multitool | linux | running | 172.100.100.201/24 | N/A |
# | 2 | clab-tfs-scenario-client2 | fc88436d2b32 | ghcr.io/hellt/network-multitool | linux | running | 172.100.100.202/24 | N/A |
# | 3 | clab-tfs-scenario-srl1 | b995b9bdadda | ghcr.io/nokia/srlinux | srl | running | 172.100.100.101/24 | N/A |
# | 4 | clab-tfs-scenario-srl2 | aacfc38cc376 | ghcr.io/nokia/srlinux | srl | running | 172.100.100.102/24 | N/A |
# +---+---------------------------+--------------+---------------------------------+-------+---------+--------------------+--------------+
def interface(if_name, sif_index, ipv4_address, ipv4_prefix, enabled) -> Tuple[str, Dict]:
str_path = '/interface[{:s}]'.format(if_name)
str_data = {'name': if_name, 'enabled': enabled, 'sub_if_index': sif_index, 'sub_if_enabled': enabled,
'sub_if_ipv4_enabled': enabled, 'sub_if_ipv4_address': ipv4_address, 'sub_if_ipv4_prefix': ipv4_prefix}
return str_path, str_data
def network_instance(ni_name, ni_type) -> Tuple[str, Dict]:
str_path = '/network_instance[{:s}]'.format(ni_name)
str_data = {'name': ni_name, 'type': ni_type}
return str_path, str_data
def network_instance_static_route(ni_name, prefix, next_hop, next_hop_index=0) -> Tuple[str, Dict]:
str_path = '/network_instance[{:s}]/static_route[{:s}]'.format(ni_name, prefix)
str_data = {'name': ni_name, 'prefix': prefix, 'next_hop': next_hop, 'next_hop_index': next_hop_index}
return str_path, str_data
def network_instance_interface(ni_name, if_name, sif_index) -> Tuple[str, Dict]:
str_path = '/network_instance[{:s}]/interface[{:s}.{:d}]'.format(ni_name, if_name, sif_index)
str_data = {'name': ni_name, 'if_name': if_name, 'sif_index': sif_index}
return str_path, str_data
def main():
driver_settings = {
'protocol': 'gnmi',
'username': 'admin',
'password': 'NokiaSrl1!',
'use_tls' : True,
}
driver = GnmiOpenConfigDriver('172.100.100.102', 57400, **driver_settings)
driver.Connect()
#resources_to_get = []
#resources_to_get = [RESOURCE_ENDPOINTS]
#resources_to_get = [RESOURCE_INTERFACES]
#resources_to_get = [RESOURCE_NETWORK_INSTANCES]
#resources_to_get = [RESOURCE_ROUTING_POLICIES]
#resources_to_get = [RESOURCE_SERVICES]
#LOGGER.info('resources_to_get = {:s}'.format(str(resources_to_get)))
#results_getconfig = driver.GetConfig(resources_to_get)
#LOGGER.info('results_getconfig = {:s}'.format(str(results_getconfig)))
#resources_to_set = [
# network_instance('test-svc', 'L3VRF'),
#
# interface('ethernet-1/1', 0, '172.16.0.1', 24, True),
# network_instance_interface('test-svc', 'ethernet-1/1', 0),
#
# interface('ethernet-1/2', 0, '172.0.0.1', 24, True),
# network_instance_interface('test-svc', 'ethernet-1/2', 0),
#
# network_instance_static_route('test-svc', '172.0.0.0/24', '172.16.0.2'),
# network_instance_static_route('test-svc', '172.2.0.0/24', '172.16.0.3'),
#]
#LOGGER.info('resources_to_set = {:s}'.format(str(resources_to_set)))
#results_setconfig = driver.SetConfig(resources_to_set)
#LOGGER.info('results_setconfig = {:s}'.format(str(results_setconfig)))
resources_to_delete = [
#network_instance_static_route('d35fc1d9', '172.0.0.0/24', '172.16.0.2'),
#network_instance_static_route('d35fc1d9', '172.2.0.0/24', '172.16.0.3'),
#network_instance_interface('d35fc1d9', 'ethernet-1/1', 0),
#network_instance_interface('d35fc1d9', 'ethernet-1/2', 0),
interface('ethernet-1/1', 0, '172.16.1.1', 24, True),
interface('ethernet-1/2', 0, '172.0.0.2', 24, True),
network_instance('20f66fb5', 'L3VRF'),
]
LOGGER.info('resources_to_delete = {:s}'.format(str(resources_to_delete)))
results_deleteconfig = driver.DeleteConfig(resources_to_delete)
LOGGER.info('results_deleteconfig = {:s}'.format(str(results_deleteconfig)))
time.sleep(1)
driver.Disconnect()
return 0
if __name__ == '__main__':
sys.exit(main())
# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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, os, time
os.environ['DEVICE_EMULATED_ONLY'] = 'YES'
#pylint: disable=wrong-import-position
from device.service.drivers.gnmi_nokia_srlinux.GnmiNokiaSrLinuxDriver import GnmiNokiaSrLinuxDriver
from device.service.driver_api._Driver import RESOURCE_INTERFACES , RESOURCE_NETWORK_INSTANCES,RESOURCE_TUNNEL_INTERFACE,RESOURCE_ROUTING_POLICY,RESOURCE_ENDPOINTS
#from test_gnmi_nokia_srlinux import interface,routing_policy,network_instance_default,vlan_interface,network_instance_vrf,tunnel_interface
logging.basicConfig(level=logging.DEBUG)
LOGGER = logging.getLogger(__name__)
LOGGER.setLevel(logging.DEBUG)
#
#def test_gnmi_nokia_srlinux():
# driver_settings_leaf1 = {
# 'protocol': 'gnmi',
# 'username': 'admin',
# 'password': 'NokiaSrl1!',
# 'use_tls': True,
# }
# dev1_driver = GnmiNokiaSrLinuxDriver('172.20.20.102', 57400, **driver_settings_leaf1)
# dev1_driver.Connect()
# resources_to_get_leaf1 = [RESOURCE_INTERFACES,RESOURCE_NETWORK_INSTANCES,RESOURCE_TUNNEL_INTERFACE,RESOURCE_ROUTING_POLICY]
# #resources_to_get_leaf1 = [RESOURCE_NETWORK_INSTANCES]
# LOGGER.info('resources_to_get = {:s}'.format(str(resources_to_get_leaf1)))
# results_getconfig_leaf1 = dev1_driver.GetConfig(resources_to_get_leaf1)
# LOGGER.info('results_getconfig = {:s}'.format(str(results_getconfig_leaf1)))
# time.sleep(1)
# dev1_driver.Disconnect()
#time computing:
import logging
import time
# Assuming GnmiNokiaSrLinuxDriver and other required functions are imported correctly
# Replace LOGGER with logging to maintain consistency
#
#logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
#
#def test_gnmi_nokia_srlinux():
# driver_settings_leaf1 = {
# 'protocol': 'gnmi',
# 'username': 'admin',
# 'password': 'NokiaSrl1!',
# 'use_tls': True,
# }
# driver_settings_leaf2 = {
# 'protocol': 'gnmi',
# 'username': 'admin',
# 'password': 'NokiaSrl1!',
# 'use_tls': True,
# }
# driver_settings_spine = {
# 'protocol': 'gnmi',
# 'username': 'admin',
# 'password': 'NokiaSrl1!',
# 'use_tls': True,
# }
#
# dev1_driver = GnmiNokiaSrLinuxDriver('172.20.20.102', 57400, **driver_settings_leaf1)
# dev2_driver = GnmiNokiaSrLinuxDriver('172.20.20.103', 57400, **driver_settings_leaf2)
# spine_driver = GnmiNokiaSrLinuxDriver('172.20.20.101', 57400, **driver_settings_spine)
#
# dev1_driver.Connect()
# dev2_driver.Connect()
# spine_driver.Connect()
#
# # Resources to get for all devices
# resources_to_get = [RESOURCE_INTERFACES, RESOURCE_NETWORK_INSTANCES, RESOURCE_TUNNEL_INTERFACE, RESOURCE_ROUTING_POLICY]
#
# # Initialize lists to store elapsed times for each device
# elapsed_times_leaf1 = []
# elapsed_times_leaf2 = []
# elapsed_times_spine = []
#
# for i in range(10): # Run the test 10 times
# t0_iteration = time.time()
#
# # Measure time for GetConfig on Leaf 1
# t0_leaf1 = time.time()
# results_getconfig_leaf1 = dev1_driver.GetConfig(resources_to_get)
# logging.info('Results of GetConfig on Leaf 1 in iteration %d: %s', i, results_getconfig_leaf1)
# time.sleep(1)
# t1_leaf1 = time.time()
# elapsed_time_leaf1 = t1_leaf1 - t0_leaf1
# elapsed_times_leaf1.append(elapsed_time_leaf1)
# logging.info("Elapsed time for GetConfig on Leaf 1 in iteration %d: %.2f seconds", i, elapsed_time_leaf1)
#
# # Measure time for GetConfig on Leaf 2
# t0_leaf2 = time.time()
# results_getconfig_leaf2 = dev2_driver.GetConfig(resources_to_get)
# logging.info('Results of GetConfig on Leaf 2 in iteration %d: %s', i, results_getconfig_leaf2)
# time.sleep(1)
# t1_leaf2 = time.time()
# elapsed_time_leaf2 = t1_leaf2 - t0_leaf2
# elapsed_times_leaf2.append(elapsed_time_leaf2)
# logging.info("Elapsed time for GetConfig on Leaf 2 in iteration %d: %.2f seconds", i, elapsed_time_leaf2)
#
# # Measure time for GetConfig on Spine
# t0_spine = time.time()
# results_getconfig_spine = spine_driver.GetConfig(resources_to_get)
# logging.info('Results of GetConfig on Spine in iteration %d: %s', i, results_getconfig_spine)
# time.sleep(1)
# t1_spine = time.time()
# elapsed_time_spine = t1_spine - t0_spine
# elapsed_times_spine.append(elapsed_time_spine)
# logging.info("Elapsed time for GetConfig on Spine in iteration %d: %.2f seconds", i, elapsed_time_spine)
#
# # Measure the end time for the iteration
# t1_iteration = time.time()
# elapsed_time_iteration = t1_iteration - t0_iteration
# logging.info("Total elapsed time for iteration %d: %.2f seconds", i, elapsed_time_iteration)
#
# # Log the elapsed times for each device after all iterations
# logging.info("Elapsed times for Leaf 1: %s", elapsed_times_leaf1)
# logging.info("Elapsed times for Leaf 2: %s", elapsed_times_leaf2)
# logging.info("Elapsed times for Spine: %s", elapsed_times_spine)
#
# # Disconnect from devices
# dev1_driver.Disconnect()
# dev2_driver.Disconnect()
# spine_driver.Disconnect()
#
# return elapsed_times_leaf1, elapsed_times_leaf2, elapsed_times_spine
import logging
import time
# Assuming GnmiNokiaSrLinuxDriver and other required functions are imported correctly
# Replace LOGGER with logging to maintain consistency
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
def test_gnmi_nokia_srlinux():
driver_settings_leaf1 = {
'protocol': 'gnmi',
'username': 'admin',
'password': 'NokiaSrl1!',
'use_tls': True,
}
driver_settings_leaf2 = {
'protocol': 'gnmi',
'username': 'admin',
'password': 'NokiaSrl1!',
'use_tls': True,
}
driver_settings_spine = {
'protocol': 'gnmi',
'username': 'admin',
'password': 'NokiaSrl1!',
'use_tls': True,
}
dev1_driver = GnmiNokiaSrLinuxDriver('172.20.20.102', 57400, **driver_settings_leaf1)
dev2_driver = GnmiNokiaSrLinuxDriver('172.20.20.103', 57400, **driver_settings_leaf2)
spine_driver = GnmiNokiaSrLinuxDriver('172.20.20.101', 57400, **driver_settings_spine)
dev1_driver.Connect()
dev2_driver.Connect()
spine_driver.Connect()
# Resources to get for all devices
resources = [RESOURCE_INTERFACES, RESOURCE_NETWORK_INSTANCES, RESOURCE_TUNNEL_INTERFACE, RESOURCE_ROUTING_POLICY]
# Initialize dictionaries to store timing information for each resource and device
timing_info_leaf1 = {resource: [] for resource in resources}
timing_info_leaf2 = {resource: [] for resource in resources}
timing_info_spine = {resource: [] for resource in resources}
for resource in resources:
logging.info("Checking resource: %s", resource)
for i in range(1000): # Run the test 10 times
t0_iteration = time.time()
# Measure time for GetConfig on Leaf 1
t0_leaf1 = time.time()
results_getconfig_leaf1 = dev1_driver.GetConfig([resource])
t1_leaf1 = time.time()
elapsed_time_leaf1 = t1_leaf1 - t0_leaf1
timing_info_leaf1[resource].append(elapsed_time_leaf1)
# Measure time for GetConfig on Leaf 2
t0_leaf2 = time.time()
results_getconfig_leaf2 = dev2_driver.GetConfig([resource])
t1_leaf2 = time.time()
elapsed_time_leaf2 = t1_leaf2 - t0_leaf2
timing_info_leaf2[resource].append(elapsed_time_leaf2)
# Measure time for GetConfig on Spine
t0_spine = time.time()
results_getconfig_spine = spine_driver.GetConfig([resource])
t1_spine = time.time()
elapsed_time_spine = t1_spine - t0_spine
timing_info_spine[resource].append(elapsed_time_spine)
# Measure the end time for the iteration
t1_iteration = time.time()
elapsed_time_iteration = t1_iteration - t0_iteration
logging.info("Total elapsed time for resource %s in iteration %d: %.2f seconds", resource, i, elapsed_time_iteration)
# Log the timing information for each resource and device at the end
for resource in resources:
logging.info("Timing information for resource %s on Leaf 1: %s", resource, timing_info_leaf1[resource])
logging.info("Timing information for resource %s on Leaf 2: %s", resource, timing_info_leaf2[resource])
logging.info("Timing information for resource %s on Spine: %s", resource, timing_info_spine[resource])
import csv
# Assume timing_info_leaf1, timing_info_leaf2, and timing_info_spine are dictionaries containing your timing data
with open('timing_results.csv', 'w', newline='') as csvfile:
fieldnames = ['Resource', 'Leaf1_Times', 'Leaf2_Times', 'Spine_Times']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
for resource in resources:
writer.writerow({
'Resource': resource,
'Leaf1_Times': timing_info_leaf1[resource],
'Leaf2_Times': timing_info_leaf2[resource],
'Spine_Times': timing_info_spine[resource]
})
# Disconnect from devices
dev1_driver.Disconnect()
dev2_driver.Disconnect()
spine_driver.Disconnect()
# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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, os, sys, time,csv
from typing import Dict, Tuple
import logging
import numpy as np
import matplotlib.pyplot as plt
os.environ['DEVICE_EMULATED_ONLY'] = 'YES'
from device.service.drivers.gnmi_nokia_srlinux.GnmiNokiaSrLinuxDriver import GnmiNokiaSrLinuxDriver # pylint: disable=wrong-import-position
from device.service.driver_api._Driver import (
RESOURCE_ENDPOINTS, RESOURCE_INTERFACES, RESOURCE_NETWORK_INSTANCES, RESOURCE_ROUTING_POLICIES, RESOURCE_SERVICES
)
logging.basicConfig(level=logging.DEBUG)
LOGGER = logging.getLogger(__name__)
LOGGER.setLevel(logging.DEBUG)
#+---+-----------------+----------+--------------------+--------------+---------------------------------+-------+---------+------------------+----------------------+
#| # | Topo Path | Lab Name | Name | Container ID | Image | Kind | State | IPv4 Address | IPv6 Address |
#+---+-----------------+----------+--------------------+--------------+---------------------------------+-------+---------+------------------+----------------------+
#| 1 | evpn01.clab.yml | evpn01 | clab-evpn01-leaf1 | 8e8e6611e681 | ghcr.io/nokia/srlinux:23.10.1 | srl | running | 172.20.20.102/24 | 2001:172:20:20::2/64 |
#| 2 | | | clab-evpn01-leaf2 | 26180fc54efe | ghcr.io/nokia/srlinux:23.10.1 | srl | running | 172.20.20.103/24 | 2001:172:20:20::3/64 |
#| 3 | | | clab-evpn01-spine1 | 981ef9d27d62 | ghcr.io/nokia/srlinux:23.10.1 | srl | running | 172.20.20.101/24 | 2001:172:20:20::4/64 |
#| 4 | | | clab-evpn01-srv1 | 9a730d7b6ac3 | ghcr.io/hellt/network-multitool | linux | running | 172.20.20.2/24 | 2001:172:20:20::5/64 |
#| 5 | | | clab-evpn01-srv2 | b90c423c4f23 | ghcr.io/hellt/network-multitool | linux | running | 172.20.20.3/24 | 2001:172:20:20::6/64 |
#+---+-----------------+----------+--------------------+--------------+---------------------------------+-------+---------+----
def interface(name, admin_state, sub_index, sub_ipv4_admin_state, sub_ipv4_address, sub_ipv4_prefix ) -> Tuple[str, Dict]:
str_path = f'/interface[name={name}]'
str_data = {
'name': name,
'admin_state': admin_state,
'sub_index': sub_index,
'sub_ipv4_admin_state': sub_ipv4_admin_state,
'sub_ipv4_address': sub_ipv4_address,
'sub_ipv4_prefix': sub_ipv4_prefix,
}
return str_path, str_data
def vlan_interface(name, vlan_tagging, sub_index, sub_type, sub_vlan_admin_state, sub_vlan_encap) -> Tuple[str, Dict]:
str_path = f'/interface[name={name}]'
str_data = { 'name':name,
'vlan_tagging': vlan_tagging,
'sub_index': sub_index,
'sub_type': sub_type,
'sub_vlan_admin_state': sub_vlan_admin_state,
'sub_vlan_encap': sub_vlan_encap,
}
return str_path, str_data
def routing_policy(name, policy_result) -> Tuple[str, Dict]:
str_path = f'/routing-policy'
str_data = {'name': name,'if_policy_result': policy_result}
return str_path, str_data
def network_instance_default(name, interface1, interface2, admin_state_bgp, afi_safi_name_bgp, autonomous_system_bgp, export_policy, group_name, import_policy, peer_as, admin_state_group, afi_safi_name_group, admin_state_group_2, afi_safi_name_group_2, export_policy_2, group_name_2, import_policy_2, as_number, peer_as_2, minimum_advertisement_interval, admin_state_neighbor, peer_address_neighbor, peer_group_neighbor, local_address_neighbor, peer_address_neighbor_2, peer_group_neighbor_2, router_id) -> Tuple[str, Dict]:
str_path = f'/network-instance[name={name}]'
str_data = {
'name': name,
'interface1': interface1,
'interface2': interface2,
'admin_state_bgp': admin_state_bgp,
'afi_safi_name_bgp': afi_safi_name_bgp,
'autonomous_system_bgp': autonomous_system_bgp,
'export_policy': export_policy,
'group_name': group_name,
'import_policy':import_policy,
'peer_as': peer_as,
'admin_state_group': admin_state_group,
'afi_safi_name_group': afi_safi_name_group,
'admin_state_group_2': admin_state_group_2,
'afi_safi_name_group_2': afi_safi_name_group_2,
'export_policy_2': export_policy_2,
'group_name_2': group_name_2,
'import_policy_2': import_policy_2,
'as_number': as_number,
'peer_as_2': peer_as_2,
'minimum_advertisement_interval': minimum_advertisement_interval,
'admin_state_neighbor': admin_state_neighbor,
'peer_address_neighbor': peer_address_neighbor,
'peer_group_neighbor': peer_group_neighbor,
'local_address_neighbor': local_address_neighbor,
'peer_address_neighbor_2': peer_address_neighbor_2,
'peer_group_neighbor_2': peer_group_neighbor_2,
'router_id': router_id,
}
return str_path, str_data
def network_instance_vrf(name, type, admin_state_vrf, interface1_name, vxlaninterface_name, bgp_evpn_instance_id, bgp_evpn_instance_admin_state, bgp_evpn_instance_vxlan_interface, bgp_evpn_instance_evi, bgp_vpn_instance_id, bgp_vpn_instance_export_rt, bgp_vpn_instance_import_rt) -> Tuple[str, Dict]:
str_path = f'/network-instance[name={name}]'
str_data = {'name': name,
'type': type,
'admin_state_vrf': admin_state_vrf,
'interface1_name': interface1_name,
'vxlaninterface_name': vxlaninterface_name,
'bgp_evpn_instance_id': bgp_evpn_instance_id,
'bgp_evpn_instance_admin_state': bgp_evpn_instance_admin_state,
'bgp_evpn_instance_vxlan_interface': bgp_evpn_instance_vxlan_interface,
'bgp_evpn_instance_evi': bgp_evpn_instance_evi,
'bgp_vpn_instance_id': bgp_vpn_instance_id,
'bgp_vpn_instance_export_rt': bgp_vpn_instance_export_rt,
'bgp_vpn_instance_import_rt': bgp_vpn_instance_import_rt }
return str_path, str_data
def tunnel_interface(name, index, type_tunnel, vni_tunnel) -> Tuple[str, Dict]:
str_path = f'/tunnel-interface[name={name}]'
str_data = {'name': name,
'index': index,
'type_tunnel': type_tunnel,
'vni_tunnel': vni_tunnel }
return str_path, str_data
def network_instance_interface(ni_name, name)-> Tuple[str, Dict]:
str_path=f'/network-instance[name={ni_name} /interface{name}'
str_data = {'name': ni_name,'name': name}
return str_path, str_data
def network_instance_Vxlaninterface(ni_name, name)-> Tuple[str, Dict]:
str_path=f'/network-instance[name={ni_name} /vxlan-interface{name}'
str_data = {'name': ni_name, 'name': name}
return str_path, str_data
def network_instance_default_spine(interface1_spine, interface2_spine, interface3_spine, name, admin_state_spine, afi_safi_name_bgp_spine, autonomous_system_bgp_spine, export_policy_spine, group_name_spine, import_policy_spine, peer_address_neighbor_spine, peeras_group_neighbor_spine, peer_group_neighbor_spine, peer_address2_neighbor_spine, peeras_group_neighbor2_spine, peer_group_neighbor2_spine, router_id_spine)-> Tuple[str, Dict]:
str_path = f'/network-instance[name={name}]'
str_data = {'interface1_spine': interface1_spine,
'interface2_spine': interface2_spine,
'interface3_spine': interface3_spine,
'name': name,
'admin_state_spine': admin_state_spine,
'afi_safi_name_bgp_spine': afi_safi_name_bgp_spine,
'autonomous_system_bgp_spine': autonomous_system_bgp_spine,
'export_policy_spine': export_policy_spine,
'group_name_spine': group_name_spine,
'import_policy_spine': import_policy_spine,
'peer_address_neighbor_spine': peer_address_neighbor_spine,
'peeras_group_neighbor_spine': peeras_group_neighbor_spine,
'peer_group_neighbor_spine': peer_group_neighbor_spine,
'peer_address2_neighbor_spine': peer_address2_neighbor_spine,
'peeras_group_neighbor2_spine': peeras_group_neighbor2_spine,
'peer_group_neighbor2_spine': peer_group_neighbor2_spine,
'router_id_spine': router_id_spine}
return str_path, str_data
#######setting computing:
import logging
import time
# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
def test_gnmi_nokia_srlinux():
driver_settings_leaf1 = {
'protocol': 'gnmi',
'username': 'admin',
'password': 'NokiaSrl1!',
'use_tls': True,
}
driver_settings_leaf2 = {
'protocol': 'gnmi',
'username': 'admin',
'password': 'NokiaSrl1!',
'use_tls': True,
}
driver_settings_spine = {
'protocol': 'gnmi',
'username': 'admin',
'password': 'NokiaSrl1!',
'use_tls': True,
}
devices = {
'leaf1': GnmiNokiaSrLinuxDriver('172.20.20.102', 57400, **driver_settings_leaf1),
'leaf2': GnmiNokiaSrLinuxDriver('172.20.20.103', 57400, **driver_settings_leaf2),
'spine': GnmiNokiaSrLinuxDriver('172.20.20.101', 57400, **driver_settings_spine)
}
for device in devices.values():
device.Connect()
resources = {
'leaf1': [
('routing_policy', routing_policy('', '')),
('interface', interface('ethernet-1/49', True, 0, True, '192.168.11.1', '30')),
('network_instance', network_instance_default('default', 'ethernet-1/49.0', 'system0.0', True, 'ipv4-unicast', 101, 'all', 'eBGP-underlay', 'all', 201, True, 'evpn', False, 'ipv4-unicast', 'all', 'iBGP-overlay', 'all', 100, 100, 1, True, '10.0.0.2', 'iBGP-overlay', '10.0.0.1', '192.168.11.2', 'eBGP-underlay', '10.0.0.1')),
('interface', interface('system0', True, 0, True, '10.0.0.1', '32')),
('vlan_interface', vlan_interface('ethernet-1/1', True, 0, 'bridged', True, 'untagged')),
('network_instance_vrf', network_instance_vrf('vrf-1', 'mac-vrf', True, 'ethernet-1/1.0', 'vxlan1.1', 1, True, 'vxlan1.1', 111, 1, 'target:100:111', 'target:100:111')),
('tunnel_interface', tunnel_interface('vxlan1', 1, 'bridged', 1)),
],
'leaf2': [
('routing_policy', routing_policy('', '')),
('interface', interface('ethernet-1/49', True, 0, True, '192.168.12.1', '30')),
('network_instance', network_instance_default('default', 'ethernet-1/49.0', 'system0.0', True, 'ipv4-unicast', 102, 'all', 'eBGP-underlay', 'all', 201, True, 'evpn', False, 'ipv4-unicast', 'all', 'iBGP-overlay', 'all', 100, 100, 1, True, '10.0.0.1', 'iBGP-overlay', '10.0.0.2', '192.168.12.2', 'eBGP-underlay', '10.0.0.2')),
('interface', interface('system0', True, 0, True, '10.0.0.2', '32')),
('vlan_interface', vlan_interface('ethernet-1/1', True, 0, 'bridged', True, 'untagged')),
('network_instance_vrf', network_instance_vrf('vrf-1', 'mac-vrf', True, 'ethernet-1/1.0', 'vxlan1.1', 1, True, 'vxlan1.1', 111, 1, 'target:100:111', 'target:100:111')),
('tunnel_interface', tunnel_interface('vxlan1', 1, 'bridged', 1)),
],
'spine': [
('routing_policy', routing_policy('', '')),
('interface', interface('ethernet-1/1', True, 0, True, '192.168.11.2', '30')),
('interface', interface('ethernet-1/2', True, 0, True, '192.168.12.2', '30')),
('network_instance', network_instance_default_spine('ethernet-1/1.0', 'ethernet-1/2.0', 'system0.0', 'default', True, 'ipv4-unicast', 201, 'all', 'eBGP-underlay', 'all', '192.168.11.1', 101, 'eBGP-underlay', '192.168.12.1', 102, 'eBGP-underlay', '10.0.1.1')),
('interface', interface('system0', True, 0, True, '10.0.1.1', 32)),
]
}
# Initialize dictionary to store timing information
timing_info = {device: {resource[0]: [] for resource in resources[device]} for device in resources}
# Perform the configuration 10 times and measure time for each configuration set
for device_name, device_resources in resources.items():
for i in range(1000):
for resource_name, resource in device_resources:
start_time = time.time()
devices[device_name].DeleteConfig([resource])
end_time = time.time()
elapsed_time = end_time - start_time
timing_info[device_name][resource_name].append(elapsed_time)
logging.info(f"Iteration {i+1} for {resource_name} on {device_name}: {elapsed_time:.2f} seconds")
# Log final timing information
for device_name, resource_timings in timing_info.items():
for resource_name, times in resource_timings.items():
logging.info(f"Timing information for {resource_name} on {device_name}: {times}")
with open('timing_information_delete.csv', mode='w', newline='') as file:
writer = csv.writer(file)
writer.writerow(['Device', 'Resource', 'Time(seconds)'])
for device_name, resource_timings in timing_info.items():
for resource_name, times in resource_timings.items():
for time_taken in times:
writer.writerow([device_name, resource_name, f"{time_taken:.6f}"])
for device in devices.values():
device.Disconnect()
\ No newline at end of file
import logging, os, time
os.environ['DEVICE_EMULATED_ONLY'] = 'YES'
# pylint: disable=wrong-import-position
from device.service.drivers.gnmi_nokia_srlinux.GnmiNokiaSrLinuxDriver import GnmiNokiaSrLinuxDriver
from device.service.driver_api._Driver import RESOURCE_INTERFACES , RESOURCE_NETWORK_INSTANCES,RESOURCE_TUNNEL_INTERFACE,RESOURCE_ROUTING_POLICY,RESOURCE_ENDPOINTS
from test_gnmi_nokia_srlinux import interface,routing_policy,network_instance_default,vlan_interface,network_instance_vrf,tunnel_interface
logging.basicConfig(level=logging.DEBUG)
LOGGER = logging.getLogger(__name__)
LOGGER.setLevel(logging.DEBUG)
def test_gnmi_nokia_srlinux():
driver_settings_leaf1 = {
'protocol': 'gnmi',
'username': 'admin',
'password': 'NokiaSrl1!',
'use_tls': True,
}
dev1_driver = GnmiNokiaSrLinuxDriver('172.20.20.102', 57400, **driver_settings_leaf1)
dev1_driver.Connect()
resources_to_delete = [
####LEAF1#####
interface('ethernet-1/49',True,0,True,'192.168.11.1','30'),
routing_policy('all','accept'),
network_instance_default('default','ethernet-1/49.0','system0.0',True,'ipv4-unicast',101,'all','eBGP-underlay','all',201,True,'evpn',False,'ipv4-unicast','all','iBGP-overlay','all',100,100,1,True,'10.0.0.2','iBGP-overlay','10.0.0.1','192.168.11.2','eBGP-underlay','10.0.0.1'),
interface('system0',True,0,True,'10.0.0.1','32'),
vlan_interface('ethernet-1/1',True,0,'bridged',True,'untagged'),
network_instance_vrf('vrf-1','mac-vrf',True,'ethernet-1/1.0','vxlan1.1',1,True,'vxlan1.1',111,1,'target:100:111','target:100:111'),
tunnel_interface('vxlan1', 1, 'bridged', 1),
]
LOGGER.info('resources_to_delete = {:s}'.format(str(resources_to_delete)))
results_deleteconfig_leaf1 = dev1_driver.DeleteConfig(resources_to_delete)
LOGGER.info('results_delete = {:s}'.format(str(results_deleteconfig_leaf1)))
time.sleep(1)
dev1_driver.Disconnect()
\ No newline at end of file
...@@ -37,6 +37,7 @@ DEVICE_DRIVER_VALUES = { ...@@ -37,6 +37,7 @@ DEVICE_DRIVER_VALUES = {
DeviceDriverEnum.DEVICEDRIVER_XR, DeviceDriverEnum.DEVICEDRIVER_XR,
DeviceDriverEnum.DEVICEDRIVER_IETF_L2VPN, DeviceDriverEnum.DEVICEDRIVER_IETF_L2VPN,
DeviceDriverEnum.DEVICEDRIVER_GNMI_OPENCONFIG, DeviceDriverEnum.DEVICEDRIVER_GNMI_OPENCONFIG,
DeviceDriverEnum.DEVICEDRIVER_GNMI_NOKIA_SRLINUX,
} }
# Map allowed filter fields to allowed values per Filter field. If no restriction (free text) None is specified # Map allowed filter fields to allowed values per Filter field. If no restriction (free text) None is specified
......
...@@ -31,6 +31,7 @@ class AddDeviceForm(FlaskForm): ...@@ -31,6 +31,7 @@ class AddDeviceForm(FlaskForm):
device_drivers_xr = BooleanField('XR') device_drivers_xr = BooleanField('XR')
device_drivers_ietf_l2vpn = BooleanField('IETF L2VPN') device_drivers_ietf_l2vpn = BooleanField('IETF L2VPN')
device_drivers_gnmi_openconfig = BooleanField('GNMI OPENCONFIG') device_drivers_gnmi_openconfig = BooleanField('GNMI OPENCONFIG')
device_drivers_gnmi_nokia_srlinux = BooleanField('GNMI NOKIA SR LINUX')
device_config_address = StringField('connect/address',default='127.0.0.1',validators=[DataRequired(), Length(min=5)]) device_config_address = StringField('connect/address',default='127.0.0.1',validators=[DataRequired(), Length(min=5)])
device_config_port = StringField('connect/port',default='0',validators=[DataRequired(), Length(min=1)]) device_config_port = StringField('connect/port',default='0',validators=[DataRequired(), Length(min=1)])
......
...@@ -125,6 +125,8 @@ def add(): ...@@ -125,6 +125,8 @@ def add():
device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_IETF_L2VPN) device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_IETF_L2VPN)
if form.device_drivers_gnmi_openconfig.data: if form.device_drivers_gnmi_openconfig.data:
device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_GNMI_OPENCONFIG) device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_GNMI_OPENCONFIG)
if form.device_drivers_gnmi_nokia_srlinux.data:
device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_GNMI_NOKIA_SRLINUX)
device_obj.device_drivers.extend(device_drivers) # pylint: disable=no-member device_obj.device_drivers.extend(device_drivers) # pylint: disable=no-member
try: try:
......