From 959a50da8fc31ea4489d758990e0513bb19c3b20 Mon Sep 17 00:00:00 2001 From: Martin Kolman Date: Aug 19 2020 11:09:52 +0000 Subject: Merge pull request #2784 from M4rtinK/rhel-8-forward_noverifyssl_to_rhsm Propagate verify_ssl to RHSM --- diff --git a/pyanaconda/modules/subscription/initialization.py b/pyanaconda/modules/subscription/initialization.py index 76867db..ef7f738 100644 --- a/pyanaconda/modules/subscription/initialization.py +++ b/pyanaconda/modules/subscription/initialization.py @@ -38,6 +38,19 @@ class StartRHSMTask(Task): RHSM_SYSTEMD_UNIT_NAME = "rhsm.service" + def __init__(self, verify_ssl=True): + """Create a new task for starting the RHSM DBus service. + + :param bool verify_ssl: True if RHSM should be configured to verify SSL certificates, + False if RHSM should be set to *not* verify SSL certificates + + NOTE: If RHSM SSL verification is disabled, this is install time only, as we will + always turn it back on unconditionally at the same time we roll back the RHSM + log level change. + """ + super().__init__() + self._verify_ssl = verify_ssl + @property def name(self): return "Start RHSM DBus service" @@ -71,7 +84,15 @@ class StartRHSMTask(Task): # set RHSM log levels to debug # - otherwise the RHSM log output is not usable for debugging subscription issues log.debug("subscription: setting RHSM log level to DEBUG") - rhsm_config_proxy.Set("logging.default_log_level", get_variant(Str, "DEBUG"), "") + config_dict = {"logging.default_log_level": get_variant(Str, "DEBUG")} + # turn OFF SSL certificate validation (if requested) + if not self._verify_ssl: + log.debug("subscription: disabling RHSM SSL certificate validation") + config_dict["server.insecure"] = get_variant(Str, "1") + + # set all the values at once atomically + rhsm_config_proxy.SetAll(config_dict, "") + # all seems fine log.debug("subscription: RHSM service start successfully.") return True diff --git a/pyanaconda/modules/subscription/installation.py b/pyanaconda/modules/subscription/installation.py index 195bcf6..f8afe14 100644 --- a/pyanaconda/modules/subscription/installation.py +++ b/pyanaconda/modules/subscription/installation.py @@ -81,8 +81,14 @@ class ConnectToInsightsTask(Task): raise InsightsConnectError("Connecting to Red Hat Insights failed.") -class RestoreRHSMLogLevelTask(Task): - """Restore RHSM log level back to INFO.""" +class RestoreRHSMDefaultsTask(Task): + """Restore RHSM defaults we changed for install time purposes. + + At the moment this means setting the RHSM log level back to INFO + from DEBUG and making sure SSL certificate validation is enabled + (as we might turn it off for the installation run if requested by + the user). + """ def __init__(self, rhsm_config_proxy): """Create a new task. @@ -93,21 +99,31 @@ class RestoreRHSMLogLevelTask(Task): @property def name(self): - return "Restoring subscription manager log level" + return "Restoring subscription manager defaults" def run(self): - """Set RHSM log level back to INFO. + """Restore RHSM defaults we changed. We previously set the RHSM log level to DEBUG, which is also reflected in rhsm.conf. This would mean RHSM would continue to log in debug mode also on the system once rhsm.conf has been copied over to the target system. - So set the log level back to INFO before we copy the config file. + The same thing needs to be done for the server.insecure key + that we migh set to "1" previously on user request. + + So set the log level back to INFO before we copy the config file + and make sure server.insecure is equal to "0". """ log.debug("subscription: setting RHSM log level back to INFO") - self._rhsm_config_proxy.Set("logging.default_log_level", - get_variant(Str, "INFO"), "") + log.debug("subscription: making sure RHSM SSL certificate validation is enabled") + config_dict = { + "logging.default_log_level": get_variant(Str, "INFO"), + "server.insecure": get_variant(Str, "0") + } + + # set all the values at once atomically + self._rhsm_config_proxy.SetAll(config_dict, "") class TransferSubscriptionTokensTask(Task): diff --git a/pyanaconda/modules/subscription/subscription.py b/pyanaconda/modules/subscription/subscription.py index c0c72a8..7ceb491 100644 --- a/pyanaconda/modules/subscription/subscription.py +++ b/pyanaconda/modules/subscription/subscription.py @@ -45,7 +45,7 @@ from pyanaconda.modules.subscription import system_purpose from pyanaconda.modules.subscription.kickstart import SubscriptionKickstartSpecification from pyanaconda.modules.subscription.subscription_interface import SubscriptionInterface from pyanaconda.modules.subscription.installation import ConnectToInsightsTask, \ - RestoreRHSMLogLevelTask, TransferSubscriptionTokensTask + RestoreRHSMDefaultsTask, TransferSubscriptionTokensTask from pyanaconda.modules.subscription.initialization import StartRHSMTask from pyanaconda.modules.subscription.runtime import SetRHSMConfigurationTask, \ RegisterWithUsernamePasswordTask, RegisterWithOrganizationKeyTask, \ @@ -109,7 +109,7 @@ class SubscriptionService(KickstartService): self._subscription_attached = False # RHSM service startup and access - self._rhsm_startup_task = StartRHSMTask() + self._rhsm_startup_task = StartRHSMTask(verify_ssl=conf.payload.verify_ssl) self._rhsm_observer = RHSMObserver(self._rhsm_startup_task.is_service_available) # RHSM config default values cache @@ -523,7 +523,7 @@ class SubscriptionService(KickstartService): :returns: list of installation tasks """ return [ - RestoreRHSMLogLevelTask( + RestoreRHSMDefaultsTask( rhsm_config_proxy=self.rhsm_observer.get_proxy(RHSM_CONFIG) ), TransferSubscriptionTokensTask( diff --git a/tests/nosetests/pyanaconda_tests/module_subscription_tasks_tests.py b/tests/nosetests/pyanaconda_tests/module_subscription_tasks_tests.py index fb09885..81bf0d8 100644 --- a/tests/nosetests/pyanaconda_tests/module_subscription_tasks_tests.py +++ b/tests/nosetests/pyanaconda_tests/module_subscription_tasks_tests.py @@ -41,7 +41,7 @@ from pyanaconda.modules.common.constants.services import RHSM from pyanaconda.modules.common.constants.objects import RHSM_REGISTER from pyanaconda.modules.subscription.installation import ConnectToInsightsTask, \ - RestoreRHSMLogLevelTask, TransferSubscriptionTokensTask + RestoreRHSMDefaultsTask, TransferSubscriptionTokensTask from pyanaconda.modules.subscription.runtime import SetRHSMConfigurationTask, \ RHSMPrivateBus, RegisterWithUsernamePasswordTask, RegisterWithOrganizationKeyTask, \ @@ -280,17 +280,18 @@ class SetRHSMConfigurationTaskTestCase(unittest.TestCase): mock_config_proxy.SetAll.assert_called_once_with(expected_dict, "") -class RestoreRHSMLogLevelTaskTestCase(unittest.TestCase): - """Test the RestoreRHSMLogLevelTask task.""" +class RestoreRHSMDefaultsTaskTestCase(unittest.TestCase): + """Test the RestoreRHSMDefaultsTask task.""" def restore_rhsm_log_level_task_test(self): - """Test the RestoreRHSMLogLevelTask task.""" + """Test the RestoreRHSMDefaultsTask task.""" mock_config_proxy = Mock() - task = RestoreRHSMLogLevelTask(rhsm_config_proxy=mock_config_proxy) + task = RestoreRHSMDefaultsTask(rhsm_config_proxy=mock_config_proxy) task.run() - mock_config_proxy.Set.assert_called_once_with("logging.default_log_level", - get_variant(Str, "INFO"), - "") + mock_config_proxy.SetAll.assert_called_once_with({ + "logging.default_log_level": get_variant(Str, "INFO"), + "server.insecure": get_variant(Str, "0") + }, "") class TransferSubscriptionTokensTaskTestCase(unittest.TestCase): diff --git a/tests/nosetests/pyanaconda_tests/module_subscription_tests.py b/tests/nosetests/pyanaconda_tests/module_subscription_tests.py index f707d55..cdad5f0 100644 --- a/tests/nosetests/pyanaconda_tests/module_subscription_tests.py +++ b/tests/nosetests/pyanaconda_tests/module_subscription_tests.py @@ -39,7 +39,7 @@ from pyanaconda.modules.subscription.subscription_interface import SubscriptionI from pyanaconda.modules.subscription.system_purpose import get_valid_fields, _normalize_field, \ _match_field, process_field, give_the_system_purpose, SYSPURPOSE_UTILITY_PATH from pyanaconda.modules.subscription.installation import ConnectToInsightsTask, \ - RestoreRHSMLogLevelTask, TransferSubscriptionTokensTask + RestoreRHSMDefaultsTask, TransferSubscriptionTokensTask from pyanaconda.modules.subscription.runtime import SetRHSMConfigurationTask, \ RegisterWithUsernamePasswordTask, RegisterWithOrganizationKeyTask, \ UnregisterTask, AttachSubscriptionTask, SystemPurposeConfigurationTask, \ @@ -1407,14 +1407,14 @@ class SubscriptionInterfaceTestCase(unittest.TestCase): observer.get_proxy.return_value = config_proxy task_classes = [ - RestoreRHSMLogLevelTask, + RestoreRHSMDefaultsTask, TransferSubscriptionTokensTask, ConnectToInsightsTask ] task_paths = self.subscription_interface.InstallWithTasks() task_objs = check_task_creation_list(self, task_paths, publisher, task_classes) - # RestoreRHSMLogLevelTask + # RestoreRHSMDefaultsTask obj = task_objs[0] self.assertEqual(obj.implementation._rhsm_config_proxy, config_proxy) @@ -1442,14 +1442,14 @@ class SubscriptionInterfaceTestCase(unittest.TestCase): observer.get_proxy.return_value = config_proxy task_classes = [ - RestoreRHSMLogLevelTask, + RestoreRHSMDefaultsTask, TransferSubscriptionTokensTask, ConnectToInsightsTask ] task_paths = self.subscription_interface.InstallWithTasks() task_objs = check_task_creation_list(self, task_paths, publisher, task_classes) - # RestoreRHSMLogLevelTask + # RestoreRHSMDefaultsTask obj = task_objs[0] self.assertEqual(obj.implementation._rhsm_config_proxy, config_proxy) diff --git a/tests/nosetests/pyanaconda_tests/rhsm_observer_test.py b/tests/nosetests/pyanaconda_tests/rhsm_observer_test.py index 08e4cec..b009608 100644 --- a/tests/nosetests/pyanaconda_tests/rhsm_observer_test.py +++ b/tests/nosetests/pyanaconda_tests/rhsm_observer_test.py @@ -55,9 +55,42 @@ class StartRHSMTaskTestCase(unittest.TestCase): # check proxy was requested get_proxy.assert_called_once_with() # check expected values were set on the RHSM config proxy - config_proxy.Set.assert_called_once_with( - 'logging.default_log_level', - get_variant(Str, 'DEBUG'), + # - logging should be always set to DEBUG + # - SSL certificate validation should be enabled by default + # (insecure == 0) + config_proxy.SetAll.assert_called_once_with( + { + 'logging.default_log_level': get_variant(Str, 'DEBUG'), + }, + '' + ) + + @patch("pyanaconda.modules.subscription.initialization.get_rhsm_configuration_proxy") + @patch("pyanaconda.core.util.start_service") + def insecure_test(self, start_service, get_proxy): + """Test StartRHSMTask - setting the server.insecure RHSM config key.""" + # create the task & disable SSL certificate validation + task = StartRHSMTask(verify_ssl=False) + # simulate successful systemd service start + start_service.return_value = 0 + # return mock proxy + config_proxy = Mock() + get_proxy.return_value = config_proxy + # run the task and expect it to succeed + self.assertTrue(task.run()) + # check service was started correctly + start_service.assert_called_once_with("rhsm.service") + # check proxy was requested + get_proxy.assert_called_once_with() + # check expected values were set on the RHSM config proxy + # - logging should be always set to DEBUG + # - SSL certificate validation should be disabled if requested + # (insecure == 1) + config_proxy.SetAll.assert_called_once_with( + { + 'logging.default_log_level': get_variant(Str, 'DEBUG'), + 'server.insecure': get_variant(Str, '1'), + }, '' )