Merge pull request #806 from kernelkit/put-config-dicts

Put config dicts
This commit is contained in:
Mattias Walström
2024-11-06 20:54:55 +01:00
committed by GitHub
5 changed files with 574 additions and 511 deletions
+195 -192
View File
@@ -46,208 +46,211 @@ with infamy.Test() as test:
with test.step("Configure device"):
dut1.put_config_dict("ietf-interfaces",
dut1.put_config_dicts(
{
"ietf-interfaces": {
"interfaces": {
"interface": [
{
"interfaces": {
"interface": [
{
"name": d1send,
"enabled": True,
"bridge-port": {
"bridge": "br0",
"pvid": 55
}
},
{
"name": d1receiver,
"enabled": True,
"bridge-port": {
"bridge": "br0",
"pvid": 77
}
},
{
"name": d1trunk,
"enabled": True,
"bridge-port": {
"bridge": "br0"
}
},
{
"name": "vlan55",
"enabled": True,
"type": "infix-if-type:vlan",
"ipv4": {
"address": [
{
"ip": "10.0.1.1",
"prefix-length": 24
}
]
},
"vlan": {
"id": 55,
"lower-layer-if": "br0"
}
},
{
"name": "vlan77",
"enabled": True,
"type": "infix-if-type:vlan",
"ipv4": {
"address": [
{
"ip": "10.0.2.1",
"prefix-length": 24
}
]
},
"vlan": {
"id": 77,
"lower-layer-if": "br0"
}
},
{
"name": "br0",
"enabled": True,
"type": "infix-if-type:bridge",
"bridge": {
"vlans": {
"vlan": [
{
"vid": 55,
"untagged": [ d1send ],
"tagged": [ d1trunk, "br0" ],
"multicast": {
"snooping": True
}
},
{
"vid": 77,
"untagged": [ d1receiver ],
"tagged": [ d1trunk, "br0" ],
"multicast": {
"snooping": True
}
}
]
}
}
}
]
"name": d1send,
"enabled": True,
"bridge-port": {
"bridge": "br0",
"pvid": 55
}
})
dut1.put_config_dict("ietf-system", {
"system": {
"hostname": "dut1"
}
})
dut2.put_config_dict("ietf-interfaces",
},
{
"interfaces": {
"interface": [
{
"name": d2receive,
"enabled": True,
"bridge-port": {
"bridge": "br0",
"pvid": 55
}
},
"name": d1receiver,
"enabled": True,
"bridge-port": {
"bridge": "br0",
"pvid": 77
}
},
{
"name": d1trunk,
"enabled": True,
"bridge-port": {
"bridge": "br0"
}
},
{
"name": "vlan55",
"enabled": True,
"type": "infix-if-type:vlan",
"ipv4": {
"address": [
{
"name": d2sender,
"enabled": True,
"bridge-port": {
"bridge": "br0",
"pvid": 77
}
},
{
"name": d2trunk,
"enabled": True,
"bridge-port": {
"bridge": "br0"
}
},
{
"name": "vlan55",
"enabled": True,
"type": "infix-if-type:vlan",
"ipv4": {
"address": [
{
"ip": "10.0.1.2",
"prefix-length": 24
}
]
},
"vlan": {
"id": 55,
"lower-layer-if": "br0"
}
},
{
"name": "vlan77",
"enabled": True,
"type": "infix-if-type:vlan",
"ipv4": {
"address": [
{
"ip": "10.0.2.2",
"prefix-length": 24
}
]
},
"vlan": {
"id": 77,
"lower-layer-if": "br0"
}
},
{
"name": "br0",
"enabled": True,
"type": "infix-if-type:bridge",
"bridge": {
"vlans": {
"vlan": [
{
"vid": 55,
"untagged": [ d2receive ],
"tagged": [ d2trunk, "br0" ],
"multicast": {
"snooping": True
}
},
{
"vid": 77,
"untagged": [ d2sender ],
"tagged": [ d2trunk, "br0" ],
"multicast": {
"snooping": True
}
}
]
}
}
"ip": "10.0.1.1",
"prefix-length": 24
}
]
},
"vlan": {
"id": 55,
"lower-layer-if": "br0"
}
})
dut2.put_config_dict("ietf-system", {
"system": {
"hostname": "dut2"
},
{
"name": "vlan77",
"enabled": True,
"type": "infix-if-type:vlan",
"ipv4": {
"address": [
{
"ip": "10.0.2.1",
"prefix-length": 24
}
]
},
"vlan": {
"id": 77,
"lower-layer-if": "br0"
}
},
{
"name": "br0",
"enabled": True,
"type": "infix-if-type:bridge",
"bridge": {
"vlans": {
"vlan": [
{
"vid": 55,
"untagged": [ d1send ],
"tagged": [ d1trunk, "br0" ],
"multicast": {
"snooping": True
}
},
{
"vid": 77,
"untagged": [ d1receiver ],
"tagged": [ d1trunk, "br0" ],
"multicast": {
"snooping": True
}
}
]
}
}
}
]
}
},
"ietf-system": {
"system": {
"hostname": "dut1"
}
}
}
})
)
dut2.put_config_dicts(
{
"ietf-interfaces": {
"interfaces": {
"interface": [
{
"name": d2receive,
"enabled": True,
"bridge-port": {
"bridge": "br0",
"pvid": 55
}
},
{
"name": d2sender,
"enabled": True,
"bridge-port": {
"bridge": "br0",
"pvid": 77
}
},
{
"name": d2trunk,
"enabled": True,
"bridge-port": {
"bridge": "br0"
}
},
{
"name": "vlan55",
"enabled": True,
"type": "infix-if-type:vlan",
"ipv4": {
"address": [
{
"ip": "10.0.1.2",
"prefix-length": 24
}
]
},
"vlan": {
"id": 55,
"lower-layer-if": "br0"
}
},
{
"name": "vlan77",
"enabled": True,
"type": "infix-if-type:vlan",
"ipv4": {
"address": [
{
"ip": "10.0.2.2",
"prefix-length": 24
}
]
},
"vlan": {
"id": 77,
"lower-layer-if": "br0"
}
},
{
"name": "br0",
"enabled": True,
"type": "infix-if-type:bridge",
"bridge": {
"vlans": {
"vlan": [
{
"vid": 55,
"untagged": [ d2receive ],
"tagged": [ d2trunk, "br0" ],
"multicast": {
"snooping": True
}
},
{
"vid": 77,
"untagged": [ d2sender ],
"tagged": [ d2trunk, "br0" ],
"multicast": {
"snooping": True
}
}
]
}
}
}
]
}
},
"ietf-system": {
"system": {
"hostname": "dut2"
}
}
})
with infamy.IsolatedMacVlan(hsendd1) as d1send_ns, \
infamy.IsolatedMacVlan(hreceived1) as d1receive_ns, \
+2 -2
View File
@@ -161,8 +161,8 @@ with infamy.Test() as test:
with test.step("Wait for R1 and R2 to peer"):
print("Waiting for R1 and R2 to peer")
until(lambda: route.ipv4_route_exist(R1, "192.168.20.0/24", proto="ietf-ospf:ospfv2"), attempts=200)
until(lambda: route.ipv4_route_exist(R2, "192.168.10.0/24", proto="ietf-ospf:ospfv2"), attempts=200)
until(lambda: route.ipv4_route_exist(R1, "192.168.20.0/24", "192.168.100.2", proto="ietf-ospf:ospfv2"), attempts=200)
until(lambda: route.ipv4_route_exist(R2, "192.168.10.0/24", "192.168.100.1", proto="ietf-ospf:ospfv2"), attempts=200)
with test.step("Verify connectivity from PC:src to PC:dst via fast link"):
h1net.must_reach("192.168.20.2")
+352 -311
View File
@@ -54,7 +54,8 @@ import infamy
import infamy.route as route
from infamy.util import until, parallel
def config_target1(target, ring1, ring2, cross):
target.put_config_dict("ietf-interfaces", {
target.put_config_dicts({
"ietf-interfaces": {
"interfaces": {
"interface": [
{
@@ -65,7 +66,8 @@ def config_target1(target, ring1, ring2, cross):
"address": [{
"ip": "10.0.12.1",
"prefix-length": 30
}]}
}]
}
},
{
"name": ring2,
@@ -75,7 +77,8 @@ def config_target1(target, ring1, ring2, cross):
"address": [{
"ip": "10.0.41.2",
"prefix-length": 30
}]}
}]
}
},
{
"name": cross,
@@ -92,93 +95,103 @@ def config_target1(target, ring1, ring2, cross):
"name": "lo",
"enabled": True,
"ipv4": {
"address": [{
"address": [
{
"ip": "11.0.8.1",
"prefix-length": 24
},
{
"ip": "10.0.0.1",
"prefix-length": 32
}]
},
{
"ip": "10.0.0.1",
"prefix-length": 32
}
]
}
}
]
}
})
target.put_config_dict("ietf-routing", {
"routing": {
"control-plane-protocols": {
"control-plane-protocol": [{
"type": "infix-routing:ospfv2",
"name": "default",
"ospf": {
"explicit-router-id": "10.0.0.1",
"areas": {
"area": [{
"area-id": "0.0.0.0",
"interfaces":
{
"interface": [{
"bfd": {
"enabled": True
},
"ietf-routing": {
"routing": {
"control-plane-protocols": {
"control-plane-protocol": [
{
"type": "infix-routing:ospfv2",
"name": "default",
"ospf": {
"explicit-router-id": "10.0.0.1",
"areas": {
"area": [
{
"area-id": "0.0.0.0",
"interfaces": {
"interface": [
{
"bfd": {
"enabled": True
},
"name": ring1,
"hello-interval": 1,
"enabled": True
}
]
}
},
"name": ring1,
"hello-interval": 1,
"enabled": True
}]
}
},{
"area-id": "0.0.0.1",
"area-type": "nssa-area",
"summary": False,
"interfaces":
{
"interface": [{
"bfd": {
"enabled": True
{
"area-id": "0.0.0.1",
"area-type": "nssa-area",
"summary": False,
"interfaces": {
"interface": [
{
"bfd": {
"enabled": True
},
"name": cross,
"hello-interval": 1,
"enabled": True,
"cost": 2000
},
{
"name": "lo",
"enabled": True
}
]
}
},
"name": cross,
"hello-interval": 1,
"enabled": True,
"cost": 2000
},
{
"name": "lo",
"enabled": True
}]
{
"area-id": "0.0.0.2",
"interfaces": {
"interface": [
{
"bfd": {
"enabled": True
},
"name": ring2,
"hello-interval": 1,
"enabled": True,
"interface-type": "point-to-point"
}
]
}
}
]
}
},{
"area-id": "0.0.0.2",
"interfaces":
{
"interface": [{
"bfd": {
"enabled": True
},
"name": ring2,
"hello-interval": 1,
"enabled": True,
"interface-type": "point-to-point"
}]
}
}]
}
}
}
}]
]
}
}
}
})
target.put_config_dict("ietf-system", {
},
"ietf-system": {
"system": {
"hostname": "R1"
}
})
}
})
def config_target2(target, ring1, ring2, cross):
target.put_config_dict("ietf-interfaces", {
target.put_config_dicts({
"ietf-interfaces": {
"interfaces": {
"interface": [
{
@@ -189,7 +202,8 @@ def config_target2(target, ring1, ring2, cross):
"address": [{
"ip": "10.0.23.1",
"prefix-length": 30
}]}
}]
}
},
{
"name": ring2,
@@ -199,7 +213,8 @@ def config_target2(target, ring1, ring2, cross):
"address": [{
"ip": "10.0.12.2",
"prefix-length": 30
}]}
}]
}
},
{
"name": cross,
@@ -209,212 +224,238 @@ def config_target2(target, ring1, ring2, cross):
"address": [{
"ip": "10.0.24.1",
"prefix-length": 30
}]}
}]
}
},
{
"name": "lo",
"enabled": True,
"ipv4": {
"address": [
{
"ip": "10.0.0.2",
"prefix-length": 32
},
{
"ip": "11.0.9.1",
"prefix-length": 24
},
{
"ip": "11.0.10.1",
"prefix-length": 24
},
{
"ip": "11.0.11.1",
"prefix-length": 24
},
{
"ip": "11.0.12.1",
"prefix-length": 24
},
{
"ip": "11.0.13.1",
"prefix-length": 24
},
{
"ip": "11.0.14.1",
"prefix-length": 24
},
{
"ip": "11.0.15.1",
"prefix-length": 24
}
]
}
}
]
}
},
"ietf-system": {
"system": {
"hostname": "R2"
}
},
"ietf-routing": {
"routing": {
"control-plane-protocols": {
"control-plane-protocol": [
{
"type": "infix-routing:ospfv2",
"name": "default",
"ospf": {
"explicit-router-id": "1.1.1.1",
"areas": {
"area": [
{
"area-id": "0.0.0.0",
"interfaces": {
"interface": [
{
"bfd": {
"enabled": True
},
"name": ring2,
"hello-interval": 1,
"enabled": True
},
{
"name": "lo",
"enabled": True
}
]
}
},
{
"area-id": "0.0.0.1",
"area-type": "nssa-area",
"summary": False,
"interfaces": {
"interface": [
{
"bfd": {
"enabled": True
},
"name": ring1,
"hello-interval": 1,
"enabled": True
}
]
}
},
{
"area-id": "0.0.0.2",
"interfaces": {
"interface": [
{
"bfd": {
"enabled": True
},
"name": cross,
"hello-interval": 1,
"cost": 2000,
"enabled": True
}
]
}
}
]
}
}
}
]
}
}
}
})
def config_target3(target, ring2, cross, link):
target.put_config_dicts({
"ietf-interfaces": {
"interfaces": {
"interface": [
{
"name": ring2,
"enabled": True,
"ipv4": {
"forwarding": True,
"address": [{
"ip": "10.0.23.2",
"prefix-length": 30
}]
}
},
{
"name": link,
"enabled": True,
"ipv4": {
"forwarding": True,
"address": [{
"ip": "192.168.3.1",
"prefix-length": 24
}]
}
},
{
"name": cross,
"enabled": True,
"ipv4": {
"forwarding": True,
"address": [{
"ip": "10.0.13.2",
"prefix-length": 30
}]
}
},
{
"name": "lo",
"enabled": True,
"ipv4": {
"address": [{
"ip": "10.0.0.2",
"ip": "10.0.0.3",
"prefix-length": 32
}, {
"ip": "11.0.9.1",
"prefix-length": 24
}, {
"ip": "11.0.10.1",
"prefix-length": 24
}, {
"ip": "11.0.11.1",
"prefix-length": 24
}, {
"ip": "11.0.12.1",
"prefix-length": 24
}, {
"ip": "11.0.13.1",
"prefix-length": 24
}, {
"ip": "11.0.14.1",
"prefix-length": 24
}, {
"ip": "11.0.15.1",
"prefix-length": 24
}]
}
}
]
}
})
target.put_config_dict("ietf-system", {
"system": {
"hostname": "R2"
}
})
target.put_config_dict("ietf-routing", {
"routing": {
"control-plane-protocols": {
"control-plane-protocol": [{
"type": "infix-routing:ospfv2",
"name": "default",
"ospf": {
"explicit-router-id": "1.1.1.1",
"areas": {
"area": [{
"area-id": "0.0.0.0",
"interfaces": {
"interface": [{
"bfd": {
"enabled": True
},
"name": ring2,
"hello-interval": 1,
"enabled": True
}, {
"name": "lo",
"enabled": True
}]
}
}, {
"area-id": "0.0.0.1",
"area-type": "nssa-area",
"summary": False,
"interfaces": {
"interface": [{
"bfd": {
"enabled": True
},
"name": ring1,
"hello-interval": 1,
}]
}
}, {
"area-id": "0.0.0.2",
"interfaces": {
"interface": [{
"bfd": {
"enabled": True
},
"name": cross,
"hello-interval": 1,
"cost": 2000
}]
}
}]
}
}
}]
}
}
})
def config_target3(target, ring2, cross, link):
target.put_config_dict("ietf-interfaces", {
"interfaces": {
"interface": [
{
"name": ring2,
"enabled": True,
"ipv4": {
"forwarding": True,
"address": [{
"ip": "10.0.23.2",
"prefix-length": 30
}]
}
},
{
"name": link,
"enabled": True,
"ipv4": {
"forwarding": True,
"address": [{
"ip": "192.168.3.1",
"prefix-length": 24
}]
}
},
{
"name": cross,
"enabled": True,
"ipv4": {
"forwarding": True,
"address": [{
"ip": "10.0.13.2",
"prefix-length": 30
}]
}
},
{
"name": "lo",
"enabled": True,
"ipv4": {
"address": [{
"ip": "10.0.0.3",
"prefix-length": 32
}]
}
}
]
}
})
target.put_config_dict("ietf-system", {
"system": {
"hostname": "R3"
}
})
target.put_config_dict("ietf-routing", {
"routing": {
"control-plane-protocols": {
"control-plane-protocol": [{
"type": "infix-routing:ospfv2",
"name": "default",
"ospf": {
"areas": {
"area": [{
"area-id": "0.0.0.1",
"area-type": "nssa-area",
"summary": False,
"interfaces": {
"interface": [{
"bfd": {
]
}
},
"ietf-system": {
"system": {
"hostname": "R3"
}
},
"ietf-routing": {
"routing": {
"control-plane-protocols": {
"control-plane-protocol": [{
"type": "infix-routing:ospfv2",
"name": "default",
"ospf": {
"explicit-router-id": "10.0.0.3",
"areas": {
"area": [{
"area-id": "0.0.0.1",
"area-type": "nssa-area",
"summary": False,
"interfaces": {
"interface": [{
"bfd": {
"enabled": True
},
"name": cross,
"hello-interval": 1,
"enabled": True,
"cost": 2000
}, {
"bfd": {
"enabled": True
},
"name": ring2,
"hello-interval": 1,
"enabled": True
},
"name": cross,
"hello-interval": 1,
"enabled": True,
"cost": 2000
}, {
"bfd": {
}, {
"name": link,
"enabled": True,
"passive": True
}, {
"name": "lo",
"enabled": True
},
"name": ring2,
"hello-interval": 1,
"enabled": True
}, {
"name": link,
"enabled": True,
"passive": True
}, {
"name": "lo",
"enabled": True
}]
}
}]
}]
}
}]
}
}
}
}]
}]
}
}
}
})
def config_target4(target, ring1, cross, link):
target.put_config_dict("ietf-interfaces", {
"interfaces": {
target.put_config_dicts({
"ietf-interfaces": {
"interfaces": {
"interface": [
{
"name": ring1,
@@ -459,57 +500,57 @@ def config_target4(target, ring1, cross, link):
}
]
}
})
target.put_config_dict("ietf-system", {
"system": {
"hostname": "R4"
}
})
target.put_config_dict("ietf-routing", {
"routing": {
"control-plane-protocols": {
"control-plane-protocol": [
{
"type": "infix-routing:ospfv2",
"name": "default",
"ospf": {
"redistribute": {
"redistribute": [{
"protocol": "connected"
}]
},
"areas": {
"area": [{
"area-id": "0.0.0.2",
"interfaces": {
"interface": [{
"bfd": {
"enabled": True
},
"name": ring1,
"hello-interval": 1,
"enabled": True,
"interface-type": "point-to-point"
}, {
"bfd": {
"enabled": True
},
"name": cross,
"hello-interval": 1,
"enabled": True,
"cost": 5000
}, {
"name": "lo",
"enabled": True
},
"ietf-system": {
"system": {
"hostname": "R4"
}
},
"ietf-routing": {
"routing": {
"control-plane-protocols": {
"control-plane-protocol": [
{
"type": "infix-routing:ospfv2",
"name": "default",
"ospf": {
"explicit-router-id": "10.0.0.4",
"redistribute": {
"redistribute": [{
"protocol": "connected"
}]
}
}]
},
"areas": {
"area": [{
"area-id": "0.0.0.2",
"interfaces": {
"interface": [{
"bfd": {
"enabled": True
},
"name": ring1,
"hello-interval": 1,
"enabled": True,
"interface-type": "point-to-point"
}, {
"bfd": {
"enabled": True
},
"name": cross,
"hello-interval": 1,
"enabled": True,
"cost": 5000
}, {
"name": "lo",
"enabled": True
}]
}
}]
}
}
}
}
]
]
}
}
}
})
+13 -5
View File
@@ -214,7 +214,7 @@ class Device(Transport):
else:
return f"<filter type=\"xpath\" select=\"{xpath}\" {xmlns} />"
return None
def _parse_response(self, response, parse):
"""Helper function to handle XML response parsing."""
if not response:
@@ -273,10 +273,10 @@ class Device(Transport):
xpath_filter = self._build_xpath_filter(xpath, get_data_xpath=True)
response = self.ncc.get_data(datastore="ds:operational", filter=xpath_filter)
parsed_data = self._parse_response(response, parse)
if parse and parsed_data:
return parsed_data.print_dict()
return parsed_data
def get_config(self, xpath):
@@ -313,6 +313,15 @@ class Device(Transport):
continue
break
def put_config_dicts(self, models):
config = ""
for model in models.keys():
mod = self.ly.get_module(model)
lyd = mod.parse_data_dict(models[model], no_state=True, validate=False)
config+=lyd.print_mem("xml", with_siblings=True, pretty=False)+"\n"
return self.put_config(config)
def put_config_dict(self, modname, edit):
"""Convert Python dictionary to XMl and send as configuration"""
mod = self.ly.get_module(modname)
@@ -344,8 +353,8 @@ class Device(Transport):
def get_schemas_list(self):
schemas = []
data = self.get_dict("/netconf-state")
for d in data["netconf-state"]["schemas"]["schema"]:
schema = {}
schema["identifier"] = d['identifier']
@@ -428,4 +437,3 @@ class Device(Transport):
return current_datetime.text
else:
raise ValueError("current-datetime element not found in the response")
+12 -1
View File
@@ -244,7 +244,7 @@ class Device(Transport):
# Directly pass the dictionary without using json.dumps
response = requests_workaround_put(
f"{self.restconf_url}/ds/ietf-datastores:{datastore}/",
f"{self.restconf_url}/ds/ietf-datastores:{datastore}",
json=data,
headers=self.headers,
auth=self.auth,
@@ -262,6 +262,17 @@ class Device(Transport):
for k, v in ds.items():
return {container: v}
def put_config_dicts(self, models):
running = self.get_running()
for model in models.keys():
mod = self.lyctx.get_module(model)
lyd = mod.parse_data_dict(models[model], no_state=True, validate=False)
running.merge(lyd)
return self.put_datastore("running", json.loads(running.print_mem("json", with_siblings=True, pretty=False)))
def put_config_dict(self, modname, edit):
"""Add @edit to running config and put the whole configuration"""