Skip to content
Snippets Groups Projects
Commit 0ca81b39 authored by Ville Hallivuori's avatar Ville Hallivuori
Browse files

Update XR driver with changes needed to interoperate with newer IPM version

parent 898d74f9
No related branches found
No related tags found
2 merge requests!54Release 2.0.0,!35XR Device Driver update for newer IPM and update for tests to work with current Tera Flow version
......@@ -61,7 +61,14 @@ class HttpResult:
def __str__(self):
status_code = self.status_code if self.status_code is not None else "<not executed>"
return f"{self.method} {self.url} {self.params}, status {status_code}"
if self.text:
if len(self.text) > 1024:
body_text = self.text[:1024] + "..."
else:
body_text = self.text
else:
body_text = "NONE"
return f"{self.method} {self.url} {self.params}, status {status_code}, body {body_text}"
def process_http_response(self, response: requests.Response, permit_empty_body:bool = False):
LOGGER.info(f"process_http_response(): {self.method}: {self.url} qparams={self.params} ==> {response.status_code}") # FIXME: params
......
......@@ -79,6 +79,9 @@ class Connection:
state = from_json["state"]
self.name = state["name"] if "name" in state else None #Name is optional
self.serviceMode = state["serviceMode"]
# Implicit transport capacity is a string, where value "none" has special meaning.
# So "none" is correct value, not "None" for missing attribute
self.implicitTransportCapacity = config["implicitTransportCapacity"] if "implicitTransportCapacity" in config else "none"
self.mc = config["mc"] if "mc" in config else None
self.vlan_filter = state["outerVID"] if "outerVID" in state else None
self.href = from_json["href"]
......@@ -100,12 +103,15 @@ class Connection:
# VLANs to interface names. Correspondingly cm-cli user has to know
# to use VLANs on low level test APIs when using VTI mode.
self.serviceMode = self.__guess_service_mode_from_emulated_enpoints()
if self.serviceMode == "portMode":
if self.serviceMode == "XR-L1":
self.vlan_filter = None
self.mc = None
self.implicitTransportCapacity ="portMode"
else:
self.vlan_filter = str(self.__guess_vlan_id()) + " " # Needs to be in string format, can contain ranges, regexp is buggy, trailin space is needed for single VLAN
self.mc = "matchOuterVID"
# String "none" has a special meaning for implicitTransportCapacity
self.implicitTransportCapacity ="none"
self.cm_data = None
else:
......@@ -120,8 +126,8 @@ class Connection:
def __guess_service_mode_from_emulated_enpoints(self):
for ep in self.endpoints:
if ep.vlan is not None:
return "vtiP2pSymmetric"
return "portMode"
return "XR-VTI-P2P"
return "XR-L1"
def __guess_vlan_id(self) -> int:
vlans = []
......@@ -140,6 +146,7 @@ class Connection:
cfg = {}
set_optional_parameter(cfg, "name", self.name)
cfg["serviceMode"] = self.serviceMode
cfg["implicitTransportCapacity"] = self.implicitTransportCapacity
if self.endpoints:
cfg["endpoints"] = [ep.create_config() for ep in self.endpoints]
set_optional_parameter(cfg, "outerVID", self.vlan_filter)
......
......@@ -2,7 +2,8 @@
{
"config": {
"name": "FooBar123",
"serviceMode": "portMode"
"serviceMode": "XR-L1",
"implicitTransportCapacity": "portMode"
},
"endpoints": [
{
......@@ -141,12 +142,14 @@
"createdBy": "host",
"lifecycleState": "configured",
"name": "FooBar123",
"serviceMode": "portMode"
"serviceMode": "XR-L1",
"implicitTransportCapacity": "portMode"
}
},
{
"config": {
"serviceMode": "portMode"
"serviceMode": "XR-L1",
"implicitTransportCapacity": "portMode"
},
"endpoints": [
{
......@@ -284,7 +287,8 @@
"state": {
"createdBy": "host",
"lifecycleState": "configured",
"serviceMode": "portMode"
"serviceMode": "XR-L1",
"implicitTransportCapacity": "portMode"
}
}
]
\ No newline at end of file
[
{
"config": {
"implicitTransportCapacity": "portMode",
"name": "test2",
"serviceMode": "XR-L1"
},
"endpoints": [
{
"acs": [],
"config": {
"selector": {
"moduleIfSelectorByModuleName": {
"moduleClientIfAid": "XR-T2",
"moduleName": "XR HUB 1"
}
}
},
"href": "/network-connections/38675444-3f08-4dbe-a9c4-523ef309a518/endpoints/4801ecf5-fe37-4b8e-864f-2a0409210cb0",
"id": "4801ecf5-fe37-4b8e-864f-2a0409210cb0",
"parentId": "38675444-3f08-4dbe-a9c4-523ef309a518",
"rt": [
"cm.network-connection.endpoint"
],
"state": {
"capacity": 100,
"hostPort": {
"chassisId": "192.168.100.1",
"chassisIdSubtype": "networkAddress",
"name": "",
"portDescr": "et-1/0/0:1",
"portId": "et-1/0/0:1",
"portIdSubtype": "interfaceName",
"portSourceMAC": "58:00:BB:00:00:12",
"sysName": "SanJose"
},
"moduleIf": {
"clientIfAid": "XR-T2",
"clientIfColId": 2,
"clientIfPortSpeed": 100,
"currentRole": "hub",
"macAddress": "00:0B:F8:00:00:01",
"moduleId": "68c23c59-3bcf-4d35-7042-a4a2d8a73e3f",
"moduleName": "XR HUB 1",
"serialNumber": "000000009"
}
}
},
{
"acs": [],
"config": {
"selector": {
"moduleIfSelectorByModuleName": {
"moduleClientIfAid": "XR-T1",
"moduleName": "XR LEAF 2"
}
}
},
"href": "/network-connections/38675444-3f08-4dbe-a9c4-523ef309a518/endpoints/123fc228-59ed-423e-8537-c189f3434a38",
"id": "123fc228-59ed-423e-8537-c189f3434a38",
"parentId": "38675444-3f08-4dbe-a9c4-523ef309a518",
"rt": [
"cm.network-connection.endpoint"
],
"state": {
"capacity": 100,
"hostPort": {
"chassisId": "192.168.101.2",
"chassisIdSubtype": "networkAddress",
"name": "",
"portDescr": "et-0/0/0:0",
"portId": "et-0/0/0:0",
"portIdSubtype": "interfaceName",
"portSourceMAC": "58:00:BB:00:12:01",
"sysName": "Cupertino"
},
"moduleIf": {
"clientIfAid": "XR-T1",
"clientIfColId": 1,
"clientIfPortSpeed": 100,
"currentRole": "leaf",
"macAddress": "00:0B:F8:00:01:02",
"moduleId": "095a7a6b-1f69-4d2e-5581-cdffbb85e40f",
"moduleName": "XR LEAF 2",
"serialNumber": "00000000C"
}
}
}
],
"href": "/network-connections/38675444-3f08-4dbe-a9c4-523ef309a518",
"id": "38675444-3f08-4dbe-a9c4-523ef309a518",
"lcs": [
{
"config": {
"clientAid": "XR-T2",
"direction": "txRx",
"dscgAid": "XRCARRIERDSCG-3",
"moduleId": "68c23c59-3bcf-4d35-7042-a4a2d8a73e3f"
},
"href": "/lcs/0d5929d8-6498-4c54-b38b-43c6cb85a18b",
"id": "0d5929d8-6498-4c54-b38b-43c6cb85a18b",
"parentIds": [
"38675444-3f08-4dbe-a9c4-523ef309a518"
],
"rt": [
"cm.network-connection.local-connection"
],
"state": {
"clientAid": "XR-T2",
"colId": 2,
"direction": "txRx",
"dscgAid": "XRCARRIERDSCG-3",
"lcAid": "XRLC-3",
"lineAid": "",
"macAddress": "00:0B:F8:00:00:01",
"moduleId": "68c23c59-3bcf-4d35-7042-a4a2d8a73e3f",
"remoteClientId": "",
"remoteModuleId": ""
}
},
{
"config": {
"clientAid": "XR-T1",
"direction": "txRx",
"dscgAid": "XRCARRIERDSCG-3",
"moduleId": "095a7a6b-1f69-4d2e-5581-cdffbb85e40f"
},
"href": "/lcs/1d6cc8bf-de89-4950-a01d-4b4522c65f8c",
"id": "1d6cc8bf-de89-4950-a01d-4b4522c65f8c",
"parentIds": [
"38675444-3f08-4dbe-a9c4-523ef309a518"
],
"rt": [
"cm.network-connection.local-connection"
],
"state": {
"clientAid": "XR-T1",
"colId": 1,
"direction": "txRx",
"dscgAid": "XRCARRIERDSCG-3",
"lcAid": "XRLC-3",
"lineAid": "",
"macAddress": "00:0B:F8:00:01:02",
"moduleId": "095a7a6b-1f69-4d2e-5581-cdffbb85e40f",
"remoteClientId": "",
"remoteModuleId": ""
}
}
],
"rt": [
"cm.network-connection"
],
"state": {
"createdBy": "cm",
"lifecycleState": "configured",
"name": "test2",
"serviceMode": "XR-L1"
}
}
]
\ No newline at end of file
......@@ -29,21 +29,21 @@ def test_connection_json():
connection = Connection(j[0])
assert connection.name == "FooBar123"
assert "name: FooBar123, id: /network-connections/4505d5d3-b2f3-40b8-8ec2-4a5b28523c03, service-mode: portMode, end-points: [(XR LEAF 1|XR-T1, 0), (XR HUB 1|XR-T1, 0)]" == str(connection)
assert "name: FooBar123, id: /network-connections/4505d5d3-b2f3-40b8-8ec2-4a5b28523c03, service-mode: XR-L1, end-points: [(XR LEAF 1|XR-T1, 0), (XR HUB 1|XR-T1, 0)]" == str(connection)
config = connection.create_config()
expected_config = {'name': 'FooBar123', 'serviceMode': 'portMode', 'endpoints': [{'selector': {'ifSelectorByModuleName': {'moduleName': 'XR LEAF 1', 'moduleClientIfAid': 'XR-T1'}}}, {'selector': {'ifSelectorByModuleName': {'moduleName': 'XR HUB 1', 'moduleClientIfAid': 'XR-T1'}}}]}
expected_config = {'name': 'FooBar123', 'serviceMode': 'XR-L1', 'implicitTransportCapacity': 'portMode', 'endpoints': [{'selector': {'moduleIfSelectorByModuleName': {'moduleName': 'XR LEAF 1', 'moduleClientIfAid': 'XR-T1'}}}, {'selector': {'moduleIfSelectorByModuleName': {'moduleName': 'XR HUB 1', 'moduleClientIfAid': 'XR-T1'}}}]}
assert config == expected_config
# Remove mandatory key from leaf endpoint. It will not be parsed, but hub endpoint will
del j[0]["endpoints"][0]["state"]["moduleIf"]["clientIfAid"]
connection = Connection(j[0])
assert "name: FooBar123, id: /network-connections/4505d5d3-b2f3-40b8-8ec2-4a5b28523c03, service-mode: portMode, end-points: [(XR HUB 1|XR-T1, 0)]" == str(connection)
assert "name: FooBar123, id: /network-connections/4505d5d3-b2f3-40b8-8ec2-4a5b28523c03, service-mode: XR-L1, end-points: [(XR HUB 1|XR-T1, 0)]" == str(connection)
# Remove Name, it is optional (although TF will always configure it)
del j[0]["state"]["name"]
connection = Connection(j[0])
assert "name: <NO NAME>, id: /network-connections/4505d5d3-b2f3-40b8-8ec2-4a5b28523c03, service-mode: portMode, end-points: [(XR HUB 1|XR-T1, 0)]" == str(connection)
assert "name: <NO NAME>, id: /network-connections/4505d5d3-b2f3-40b8-8ec2-4a5b28523c03, service-mode: XR-L1, end-points: [(XR HUB 1|XR-T1, 0)]" == str(connection)
# Remove mandatory key, will raise an exception
del j[0]["state"]
......@@ -66,14 +66,14 @@ def test_connection_ep_change_compute():
new_connection = Connection(from_tf_service=TFService("FooBar123", "XR LEAF 1|XR-T1", "XR HUB 1|changed here", 0))
ep_deletes, ep_creates, ep_updates = new_connection.get_endpoint_updates(existing_connection)
assert ep_deletes == ['/network-connections/4505d5d3-b2f3-40b8-8ec2-4a5b28523c03/endpoints/1d58ba8f-4d51-4213-83e1-97a0e0bdd388']
assert ep_creates == [{'selector': {'ifSelectorByModuleName': {'moduleClientIfAid': 'changed here', 'moduleName': 'XR HUB 1'}}}]
assert ep_creates == [{'selector': {'moduleIfSelectorByModuleName': {'moduleClientIfAid': 'changed here', 'moduleName': 'XR HUB 1'}}}]
assert not ep_updates
# Change one of the endpoints and capacity
new_connection = Connection(from_tf_service=TFService("FooBar123", "XR LEAF 1|XR-T1", "XR HUB 1|changed here", 125))
ep_deletes, ep_creates, ep_updates = new_connection.get_endpoint_updates(existing_connection)
assert ep_deletes == ['/network-connections/4505d5d3-b2f3-40b8-8ec2-4a5b28523c03/endpoints/1d58ba8f-4d51-4213-83e1-97a0e0bdd388']
assert ep_creates == [{'selector': {'ifSelectorByModuleName': {'moduleClientIfAid': 'changed here', 'moduleName': 'XR HUB 1'}}, "capacity": 125}]
assert ep_creates == [{'selector': {'moduleIfSelectorByModuleName': {'moduleClientIfAid': 'changed here', 'moduleName': 'XR HUB 1'}}, "capacity": 125}]
assert ep_updates == [('/network-connections/4505d5d3-b2f3-40b8-8ec2-4a5b28523c03/endpoints/230516d0-7e38-44b1-b174-1ba7d4454ee6', {'capacity': 125})]
# No change at all
......@@ -93,13 +93,13 @@ def test_connection_ep_change_compute():
def test_connection_from_service():
# Port mode
connection = Connection(from_tf_service=TFService("FooBar123", "XR LEAF 1|XR-T1", "XR HUB 1|XR-T1", 0))
assert connection.create_config() == {'name': 'TF:FooBar123', 'serviceMode': 'portMode', 'endpoints': [{'selector': {'ifSelectorByModuleName': {'moduleName': 'XR LEAF 1', 'moduleClientIfAid': 'XR-T1'}}}, {'selector': {'ifSelectorByModuleName': {'moduleName': 'XR HUB 1', 'moduleClientIfAid': 'XR-T1'}}}]}
assert connection.create_config() == {'name': 'TF:FooBar123', 'serviceMode': 'XR-L1', 'implicitTransportCapacity': 'portMode', 'endpoints': [{'selector': {'moduleIfSelectorByModuleName': {'moduleName': 'XR LEAF 1', 'moduleClientIfAid': 'XR-T1'}}}, {'selector': {'moduleIfSelectorByModuleName': {'moduleName': 'XR HUB 1', 'moduleClientIfAid': 'XR-T1'}}}]}
# VTI mode
connection = Connection(from_tf_service=TFService("FooBar123", "XR LEAF 1|XR-T1.A", "XR HUB 1|XR-T1.100", 0))
# In endpoint selectors VLANs are note present (CM does not know about them, encoding them to aids is purely internal to Teraflow)
# However VLAN adds outerVID and some other fields
assert connection.create_config() == {'name': 'TF:FooBar123', 'serviceMode': 'vtiP2pSymmetric', 'endpoints': [{'selector': {'ifSelectorByModuleName': {'moduleName': 'XR LEAF 1', 'moduleClientIfAid': 'XR-T1'}}}, {'selector': {'ifSelectorByModuleName': {'moduleName': 'XR HUB 1', 'moduleClientIfAid': 'XR-T1'}}}], 'outerVID': '100 ', 'mc': 'matchOuterVID'}
assert connection.create_config() == {'name': 'TF:FooBar123', 'serviceMode': 'XR-VTI-P2P', 'implicitTransportCapacity': 'none', 'endpoints': [{'selector': {'moduleIfSelectorByModuleName': {'moduleName': 'XR LEAF 1', 'moduleClientIfAid': 'XR-T1'}}}, {'selector': {'moduleIfSelectorByModuleName': {'moduleName': 'XR HUB 1', 'moduleClientIfAid': 'XR-T1'}}}], 'outerVID': '100 ', 'mc': 'matchOuterVID'}
# Invalid configuration, differring VLANs on different sides
with pytest.raises(InconsistentVlanConfiguration) as _e_info:
......
......@@ -34,7 +34,7 @@ def test_transport_capacity_json():
assert str(tc) == "name: Transport capacity service example, id: /transport-capacities/6ce3aa86-2685-44b0-9f86-49e6a6c991a8, capacity-mode: dedicatedDownlinkSymmetric, end-points: [(XR Device|XR T1, 100), (XR Device 2|XR T1, 100)]"
config = tc.create_config()
assert config == {'config': {'name': 'Transport capacity service example'}, 'endpoints': [{'capacity': 100, 'selector': {'ifSelectorByModuleName': {'moduleName': 'XR Device', 'moduleClientIfAid': 'XR T1'}}}, {'capacity': 100, 'selector': {'ifSelectorByModuleName': {'moduleName': 'XR Device 2', 'moduleClientIfAid': 'XR T1'}}}]}
assert config == {'config': {'name': 'Transport capacity service example'}, 'endpoints': [{'capacity': 100, 'selector': {'moduleIfSelectorByModuleName': {'moduleName': 'XR Device', 'moduleClientIfAid': 'XR T1'}}}, {'capacity': 100, 'selector': {'moduleIfSelectorByModuleName': {'moduleName': 'XR Device 2', 'moduleClientIfAid': 'XR T1'}}}]}
def test_transport_capacity_comparison():
# Same content must compare same
......
......@@ -43,7 +43,7 @@ def ifname_to_module_aid_vlan(ifname: str) -> Tuple[str, str, Optional[str]]:
# state it has clientIfAid...
def make_selector(mod, aid, _vlan) -> Dict[str, Any]:
selector = {
"ifSelectorByModuleName": {
"moduleIfSelectorByModuleName": {
"moduleName": mod,
"moduleClientIfAid": aid,
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment