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
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -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
+10 −3
Original line number Diff line number Diff line
@@ -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)
+8 −4
Original line number Diff line number Diff line
@@ -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
+160 −0
Original line number Diff line number Diff line
[
    {
        "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
+8 −8
Original line number Diff line number Diff line
@@ -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:
Loading