From 8e1138566664d1fe1e10bdbfe1303bf3b73177af Mon Sep 17 00:00:00 2001 From: Bill Kronholm Date: Mon, 21 Oct 2024 16:05:40 -0700 Subject: [PATCH] feat: add optional installation_request_id parameter to registration messages --- landscape/client/broker/config.py | 7 +++- landscape/client/broker/registration.py | 4 ++ landscape/client/broker/tests/test_config.py | 29 +++++++++++++ .../client/broker/tests/test_registration.py | 41 +++++++++++++++++++ landscape/client/registration.py | 2 + landscape/message_schemas/server_bound.py | 2 + 6 files changed, 84 insertions(+), 1 deletion(-) diff --git a/landscape/client/broker/config.py b/landscape/client/broker/config.py index 0709a7ef0..69fc0b1de 100644 --- a/landscape/client/broker/config.py +++ b/landscape/client/broker/config.py @@ -1,5 +1,4 @@ """Configuration class for the broker.""" - import os from landscape.client.deployment import Configuration @@ -101,6 +100,12 @@ def make_parser(self): "managed by Landscape, in which case set it to be the uid that " "Landscape assigned to the host machine.", ) + parser.add_argument( + "--installation-request-id", + help="Only set this value if this computer is a child instance " + "managed by Landscape, in which case set it to be the request id " + "that Landscape assigned to the host machine.", + ) return parser diff --git a/landscape/client/broker/registration.py b/landscape/client/broker/registration.py index 6162afd1b..6cf9842ee 100644 --- a/landscape/client/broker/registration.py +++ b/landscape/client/broker/registration.py @@ -77,6 +77,7 @@ class Identity: tags = config_property("tags") access_group = config_property("access_group") hostagent_uid = config_property("hostagent_uid") + installation_request_id = config_property("installation_request_id") def __init__(self, config, persist): self._config = config @@ -192,6 +193,7 @@ def _handle_pre_exchange(self): group = identity.access_group registration_key = identity.registration_key hostagent_uid = identity.hostagent_uid + installation_request_id = identity.installation_request_id self._message_store.delete_all_messages() @@ -221,6 +223,8 @@ def _handle_pre_exchange(self): message["access_group"] = group if hostagent_uid: message["hostagent_uid"] = hostagent_uid + if installation_request_id: + message["installation_request_id"] = installation_request_id server_api = self._message_store.get_server_api() # If we have juju data to send and if the server is recent enough to diff --git a/landscape/client/broker/tests/test_config.py b/landscape/client/broker/tests/test_config.py index db0370118..2f425258d 100644 --- a/landscape/client/broker/tests/test_config.py +++ b/landscape/client/broker/tests/test_config.py @@ -159,3 +159,32 @@ def test_missing_hostagent_uid_is_none(self): configuration.load(["--config", filename, "--url", "whatever"]) self.assertIsNone(configuration.hostagent_uid) + + def test_installation_request_id_handling(self): + """ + The 'installation_request_id' value specified in the configuration + file is passed through. + """ + filename = self.makeFile( + "[client]\ninstallation_request_id = installed-according-to-plan", + ) + + configuration = BrokerConfiguration() + configuration.load(["--config", filename, "--url", "whatever"]) + + self.assertEqual( + configuration.installation_request_id, + "installed-according-to-plan", + ) + + def test_missing_ninstallation_request_id_is_none(self): + """ + Test that if we don't explicitly pass a installation_request_id, + then this value is None. + """ + filename = self.makeFile("[client]\n") + + configuration = BrokerConfiguration() + configuration.load(["--config", filename, "--url", "whatever"]) + + self.assertIsNone(configuration.installation_request_id) diff --git a/landscape/client/broker/tests/test_registration.py b/landscape/client/broker/tests/test_registration.py index 39010479d..06b312b36 100644 --- a/landscape/client/broker/tests/test_registration.py +++ b/landscape/client/broker/tests/test_registration.py @@ -427,6 +427,47 @@ def test_queue_message_on_exchange_with_none_hostagent_uid(self): messages = self.mstore.get_pending_messages() self.assertNotIn("hostagent_uid", messages[0]) + def test_queue_message_on_exchange_with_installation_request_id(self): + """ + If the admin has defined a installation_request_id for this computer, + we send it to the server. + """ + self.mstore.set_accepted_types(["register"]) + self.mstore.set_server_api(b"3.3") + self.config.account_name = "account_name" + self.config.installation_request_id = "installed-according-to-plan" + self.config.tags = "server,london" + self.reactor.fire("pre-exchange") + messages = self.mstore.get_pending_messages() + self.assertEqual( + "installed-according-to-plan", + messages[0]["installation_request_id"], + ) + + def test_queue_message_on_exchange_and_empty_installation_request_id(self): + """ + If the installation_request_id is "", then the outgoing message + does not define an "installation_request_id" key. + """ + self.mstore.set_accepted_types(["register"]) + self.mstore.set_server_api(b"3.3") + self.config.installation_request_id = "" + self.reactor.fire("pre-exchange") + messages = self.mstore.get_pending_messages() + self.assertNotIn("installation_request_id", messages[0]) + + def test_queue_message_on_exchange_with_none_installation_request_id(self): + """ + If the installation_request_id is None, then the outgoing message + does not define an "installation_request_id" key. + """ + self.mstore.set_accepted_types(["register"]) + self.mstore.set_server_api(b"3.3") + self.config.installation_request_id = None + self.reactor.fire("pre-exchange") + messages = self.mstore.get_pending_messages() + self.assertNotIn("installation_request_id", messages[0]) + def test_queueing_registration_message_resets_message_store(self): """ When a registration message is queued, the store is reset diff --git a/landscape/client/registration.py b/landscape/client/registration.py index 299b2b8fb..afb584f0f 100644 --- a/landscape/client/registration.py +++ b/landscape/client/registration.py @@ -36,6 +36,7 @@ class ClientRegistrationInfo: container_info: Optional[str] = None hostagent_uid: Optional[str] = None + installation_request_id: Optional[str] = None hostname: Optional[str] = None juju_info: None = None # We don't send Juju info currently. registration_password: Optional[str] = None @@ -54,6 +55,7 @@ def from_identity( identity.computer_title, container_info=get_container_info(), hostagent_uid=identity.hostagent_uid, + installation_request_id=identity.installation_request_id, hostname=get_fqdn(), registration_password=identity.registration_key, tags=identity.tags, diff --git a/landscape/message_schemas/server_bound.py b/landscape/message_schemas/server_bound.py index d82260ef4..bcab1af58 100644 --- a/landscape/message_schemas/server_bound.py +++ b/landscape/message_schemas/server_bound.py @@ -362,6 +362,7 @@ "clone_secure_id": Any(Unicode(), Constant(None)), "ubuntu_pro_info": Unicode(), "hostagent_uid": Unicode(), + "installation_request_id": Unicode(), }, api=b"3.3", optional=[ @@ -375,6 +376,7 @@ "clone_secure_id", "ubuntu_pro_info", "hostagent_uid", + "installation_request_id", ], )