diff --git a/landscape/client/broker/tests/test_transport.py b/landscape/client/broker/tests/test_transport.py index dd65ba43..fece3b0f 100644 --- a/landscape/client/broker/tests/test_transport.py +++ b/landscape/client/broker/tests/test_transport.py @@ -66,7 +66,7 @@ def request_with_payload(self, payload): transport.exchange, payload, computer_id="34", - exchange_token="abcd-efgh", + exchange_token=b"abcd-efgh", message_api=b"X.Y", ) diff --git a/landscape/client/broker/transport.py b/landscape/client/broker/transport.py index 3b59a84c..05ad0868 100644 --- a/landscape/client/broker/transport.py +++ b/landscape/client/broker/transport.py @@ -33,7 +33,7 @@ def exchange( self, payload: dict, computer_id: Optional[str] = None, - exchange_token: Optional[str] = None, + exchange_token: Optional[bytes] = None, message_api: bytes = SERVER_API, ) -> Union[dict, None]: """Exchange message data with the server. @@ -59,7 +59,16 @@ def exchange( except Exception: return None - return asdict(response) + # Return `ServerResponse` as a dictionary + # converting the field names back to kebab case + # which (imo) is better than mixing snake_case & kebab-case + # in landscape.client.broker.exchange.MessageExchange. + return asdict( + response, + dict_factory=lambda data: { + k.replace("_", "-"): v for k, v in data + }, + ) class FakeTransport: diff --git a/landscape/client/exchange.py b/landscape/client/exchange.py index b9301241..72421d89 100644 --- a/landscape/client/exchange.py +++ b/landscape/client/exchange.py @@ -23,8 +23,12 @@ class ServerResponse: """The HTTP response from the server after a message exchange.""" - server_uuid: str + server_api: str + server_uuid: bytes messages: List[Dict[str, Any]] + client_accepted_types_hash: Optional[bytes] = None + next_exchange_token: Optional[bytes] = None + next_expected_sequence: Optional[int] = None def exchange_messages( @@ -33,7 +37,7 @@ def exchange_messages( *, cainfo: Optional[str] = None, computer_id: Optional[str] = None, - exchange_token: Optional[str] = None, + exchange_token: Optional[bytes] = None, server_api: str = SERVER_API.decode(), ) -> ServerResponse: """Sends `payload` via HTTP(S) to `server_url`, parsing and returning the @@ -61,7 +65,7 @@ def exchange_messages( headers["X-Computer-ID"] = computer_id if exchange_token: - headers["X-Exchange-Token"] = exchange_token + headers["X-Exchange-Token"] = exchange_token.decode() curl = pycurl.Curl() @@ -91,4 +95,11 @@ def exchange_messages( logging.debug(f"Received payload:\n{pformat(response)}") - return ServerResponse(response["server-uuid"], response["messages"]) + return ServerResponse( + response["server-api"], + response["server-uuid"], + response["messages"], + response.get("client-accepted-types-hash"), + response.get("next-exchange-token"), + response.get("next-expected-sequence"), + ) diff --git a/landscape/client/tests/test_exchange.py b/landscape/client/tests/test_exchange.py index 36e64e3b..76a6820a 100644 --- a/landscape/client/tests/test_exchange.py +++ b/landscape/client/tests/test_exchange.py @@ -29,7 +29,8 @@ def test_success(self): payload = {"messages": [{"type": "my-message-type", "some-value": 5}]} mock_response = { - "server-uuid": "my-server-uuid", + "server-api": "3.2", + "server-uuid": b"my-server-uuid", "messages": [{"type": "my-server-message-type", "other-value": 6}] } @@ -40,10 +41,11 @@ def test_success(self): "https://my-server.local/message-system", cainfo="mycainfo", computer_id="my-secure-id", - exchange_token="my-exchange-token", + exchange_token=b"my-exchange-token", ) - self.assertEqual(server_response.server_uuid, "my-server-uuid") + self.assertEqual(server_response.server_api, "3.2") + self.assertEqual(server_response.server_uuid, b"my-server-uuid") self.assertEqual( server_response.messages, [{"type": "my-server-message-type", "other-value": 6}] diff --git a/landscape/client/tests/test_registration.py b/landscape/client/tests/test_registration.py index f11d0539..d8b40143 100644 --- a/landscape/client/tests/test_registration.py +++ b/landscape/client/tests/test_registration.py @@ -35,7 +35,8 @@ def test_success(self): ) self.exchange_messages_mock.return_value = ServerResponse( - "thisisaserveruuid", + "3.2", + b"thisisaserveruuid", [{"type": "set-id", "id": "mysecureid", "insecure-id": 1}], ) registration_info = register( @@ -45,7 +46,7 @@ def test_success(self): self.assertEqual(registration_info.insecure_id, 1) self.assertEqual(registration_info.secure_id, "mysecureid") - self.assertEqual(registration_info.server_uuid, "thisisaserveruuid") + self.assertEqual(registration_info.server_uuid, b"thisisaserveruuid") def test_exchange_http_code_error_404(self): """If a 404 is raised during the message exchange, a @@ -129,7 +130,8 @@ def test_no_messages(self): ) self.exchange_messages_mock.return_value = ServerResponse( - server_uuid="thisisaserveruuid", + "3.2", + server_uuid=b"thisisaserveruuid", messages=[], ) @@ -149,7 +151,8 @@ def test_no_set_id_message(self): ) self.exchange_messages_mock.return_value = ServerResponse( - server_uuid="thisisaserveruuid", + "3.2", + server_uuid=b"thisisaserveruuid", messages=[{"type": "unknown-message-type"}], )