def run(self): """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. 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") 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, "")
def test_get_native_complicated_structure(self): data = self.ComplicatedData.from_structure({ 'dictionary': get_variant( Dict[Int, Str], {1: "1", 2: "2"} ), 'bool-list': get_variant( List[Bool], [True, False, False] ), 'very-long-property-name': get_variant( Str, "My String Value" ) }) structure = self.ComplicatedData.to_structure( data ) dictionary = { 'dictionary': {1: "1", 2: "2"}, 'bool-list': [True, False, False], 'very-long-property-name': "My String Value" } self.assertEqual(get_native(structure), dictionary) self.assertEqual(get_native(dictionary), dictionary)
def test_insecure(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 assert task.run() # check service was started correctly start_service.assert_called_once_with("rhsm.service") # check proxy was requested get_proxy.assert_called_once() # 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'), }, '' )
def test_report_changed(self): """Test reporting changed properties.""" test1 = self.Test1() callback = Mock() test1.PropertiesChanged.connect(callback) test1.flush_changes() callback.assert_not_called() test1.report_changed_property("A") test1.flush_changes() callback.assert_called_once_with("I1", {"A": get_variant(Int, 1)}, []) callback.reset_mock() test1.report_changed_property("B") test1.flush_changes() callback.assert_called_once_with("I1", {"B": get_variant(Int, 2)}, []) callback.reset_mock() test1.report_changed_property("B") test1.report_changed_property("A") test1.flush_changes() callback.assert_called_once_with("I1", { "A": get_variant(Int, 1), "B": get_variant(Int, 2) }, []) callback.reset_mock()
def test_apply_structure_with_invalid_type_variant(self): structure = get_variant(List[Structure], [{'x': get_variant(Int, 10)}]) with self.assertRaises(TypeError) as cm: self.SimpleData.from_structure_list(structure) self.assertEqual(str(cm.exception), "Invalid type 'Variant'.")
def realm_property_test(self): """Test the realm property.""" realm_in = { "name": "domain.example.com", "discover-options": ["--client-software=sssd"], "join-options": ["--one-time-password=password"], "discovered": True } realm_out = { "name": get_variant(Str, "domain.example.com"), "discover-options": get_variant(List[Str], ["--client-software=sssd"]), "join-options": get_variant(List[Str], ["--one-time-password=password"]), "discovered": get_variant(Bool, True), "required-packages": get_variant(List[Str], []) } self.security_interface.SetRealm(realm_in) self.assertEqual(realm_out, self.security_interface.Realm) self.callback.assert_called_once_with(SECURITY.interface_name, {'Realm': get_native(realm_out)}, [])
def test_skip_members(self): data = self.SkipData() structure = self.SkipData.to_structure(data) self.assertEqual(structure, {'x': get_variant(Int, 0)}) data = self.SkipData.from_structure({'x': get_variant(Int, 10)}) self.assertEqual(data.x, 10)
def give_the_system_purpose(sysroot, rhsm_syspurpose_proxy, role, sla, usage, addons): """Set system purpose for the installed system by calling the syspurpose tool. The tool is called in the specified system root, so this method should only be called once the given system root contains the syspurpose utility. :param str sysroot: system root path :param rhsm_syspurpose_proxy: com.redhat.RHSM1.Syspurpose proxy :type rhsm_syspurpose_proxy: dasbus DBus proxy object :param role: role of the system :type role: str or None :param sla: Service Level Agreement for the system :type sla: str or None :param usage: intended usage of the system :type usage: str or None :param list addons: any additional layered products or features """ # first check if system purpose data has already been set if check_system_purpose_set(sysroot): # Remove existing system purpose data. # # This is important, as otherwise it would be both not possible to # clear existing system purpose data if say a user sets all values # to "not specified" in the GUI after setting them to some values # previously. Also due to syspurpose setting one value at a time # one could end up with unwanted hybrid configuration combining # new and old date, if not all fields are set in the most recent # invocation. log.debug("subscription: clearing old system purpose data") syspurpose_path = join_paths(sysroot, RHSM_SYSPURPOSE_FILE_PATH) os.remove(syspurpose_path) if role or sla or usage or addons: # Construct a dictionary of values to feed to the SetSyspurpose DBus method. syspurpose_dict = {} if role: syspurpose_dict["role"] = get_variant(Str, role) if sla: syspurpose_dict["service_level_agreement"] = get_variant(Str, sla) if usage: syspurpose_dict["usage"] = get_variant(Str, usage) if addons: syspurpose_dict["addons"] = get_variant(List[Str], addons) log.debug("subscription: setting system purpose") try: locale = os.environ.get("LANG", "") rhsm_syspurpose_proxy.SetSyspurpose(syspurpose_dict, locale) log.debug("subscription: system purpose has been set") return True except DBusError as e: log.debug("subscription: failed to set system purpose: %s", str(e)) return False else: log.warning("subscription: not calling syspurpose as no fields have been provided") # doing nothing is still not a failure return True
def test_variant_invalid(self): """Test invalid variants.""" class UnknownType: pass with self.assertRaises(TypeError): get_variant(UnknownType, 1) with self.assertRaises(TypeError): get_variant(List[Int], True)
def configuration_test(self): """Test the configuration property.""" data = { "url": get_variant(Str, "http://my/image.img"), "proxy": get_variant(Str, "http://*****:*****@example.com/proxy"), "checksum": get_variant(Str, "1234567890"), "ssl-verification-enabled": get_variant(Bool, False) } self._check_dbus_property("Configuration", data)
def test_restore_rhsm_log_level_task(self): """Test the RestoreRHSMDefaultsTask task.""" mock_config_proxy = Mock() task = RestoreRHSMDefaultsTask(rhsm_config_proxy=mock_config_proxy) task.run() mock_config_proxy.SetAll.assert_called_once_with( { "logging.default_log_level": get_variant(Str, "INFO"), "server.insecure": get_variant(Str, "0") }, "")
def test_basic_native(self): """Test get_native with basic variants.""" self._test_native([ get_variant(Double, 1.2), get_variant(List[Int], [0, -1]), get_variant(Tuple[Bool, Bool], (True, False)), get_variant(Dict[Str, Int], {"key": 0}), ], [1.2, [0, -1], (True, False), { "key": 0 }])
def test_password_policies_property(self): """Test the password policies property.""" policy = { "min-quality": get_variant(UInt16, 10), "min-length": get_variant(UInt16, 20), "allow-empty": get_variant(Bool, True), "is-strict": get_variant(Bool, False) } self._check_dbus_property("PasswordPolicies", {"luks": policy})
def test_language_data(self): get_lang_data = self.localization_interface.GetLanguageData data = get_lang_data('en') english = { "english-name": get_variant(Str, "English"), "is-common": get_variant(Bool, True), "language-id": get_variant(Str, 'en'), "native-name": get_variant(Str, "English"), } assert data == english
def test_realmd_requirements(self): """Test that package requirements in realm data propagate correctly.""" realm = RealmData() realm.name = "domain.example.com" realm.discover_options = ["--client-software=sssd"] realm.join_options = ["--one-time-password=password"] realm.discovered = True realm.required_packages = ["realmd", "foo", "bar"] self.security_interface.SetRealm(RealmData.to_structure(realm)) # check that the teamd package is requested assert self.security_interface.CollectRequirements() == [{ "type": get_variant(Str, "package"), "name": get_variant(Str, "realmd"), "reason": get_variant(Str, "Needed to join a realm.") }, { "type": get_variant(Str, "package"), "name": get_variant(Str, "foo"), "reason": get_variant(Str, "Needed to join a realm.") }, { "type": get_variant(Str, "package"), "name": get_variant(Str, "bar"), "reason": get_variant(Str, "Needed to join a realm.") }]
def realmd_requirements_test(self): """Test that package requirements in realm data propagate correctly.""" realm_in = { "name": "domain.example.com", "discover-options": ["--client-software=sssd"], "join-options": ["--one-time-password=password"], "discovered": True, "required-packages" : ["realmd", "foo", "bar"] } self.security_interface.SetRealm(realm_in) # check that the teamd package is requested self.assertEqual(self.security_interface.CollectRequirements(), [ { "type": get_variant(Str, "package"), "name": get_variant(Str, "realmd"), "reason": get_variant(Str, "Needed to join a realm.") }, { "type": get_variant(Str, "package"), "name": get_variant(Str, "foo"), "reason": get_variant(Str, "Needed to join a realm.") }, { "type": get_variant(Str, "package"), "name": get_variant(Str, "bar"), "reason": get_variant(Str, "Needed to join a realm.") } ])
def groups_property_test(self): """Test the Groups property.""" group_1 = { "name": get_variant(Str, "group1"), "gid": get_variant(Int, 321), } group_2 = { "name": get_variant(Str, "group2"), "gid": get_variant(Int, 654), } self._check_dbus_property("Groups", [group_1, group_2])
def test_apply_simple_structure_list(self): s1 = {'x': get_variant(Int, 1)} s2 = {'x': get_variant(Int, 2)} s3 = {'x': get_variant(Int, 3)} data = self.SimpleData.from_structure_list([s1, s2, s3]) self.assertEqual(len(data), 3) self.assertEqual(data[0].x, 1) self.assertEqual(data[1].x, 2) self.assertEqual(data[2].x, 3)
def ssh_keys_property_test(self): """Test the SshKeys property.""" key_1 = { "key": get_variant(Str, "aaa"), "username": get_variant(Str, "user1"), } key_2 = { "key": get_variant(Str, "bbb"), "username": get_variant(Str, "user2"), } self._check_dbus_property("SshKeys", [key_1, key_2])
def test_fips_requirements(self, kernel_arguments_mock): """Test the package requirements for fips.""" kernel_arguments_mock.is_enabled.return_value = True assert self.security_interface.CollectRequirements() == [ { "type": get_variant(Str, "package"), "name": get_variant(Str, "/usr/bin/fips-mode-setup"), "reason": get_variant(Str, "Required for FIPS compliance.") } ] kernel_arguments_mock.is_enabled.assert_called_once_with("fips")
def test_locale_data(self): get_locale_data = self.localization_interface.GetLocaleData data = get_locale_data('en_US.UTF-8') english_us = { "english-name": get_variant(Str, "English (United States)"), "language-id": get_variant(Str, 'en'), "locale-id": get_variant(Str, 'en_US.UTF-8'), "native-name": get_variant(Str, "English (United States)"), } assert data == english_us
def test_get_simple_structure(self): data = self.SimpleData() self.assertEqual(data.x, 0) structure = self.SimpleData.to_structure(data) self.assertEqual(structure, {'x': get_variant(Int, 0)}) data.x = 10 self.assertEqual(data.x, 10) structure = self.SimpleData.to_structure(data) self.assertEqual(structure, {'x': get_variant(Int, 10)})
def run(self): log.debug("subscription: setting RHSM config values") # We will use the SetAll() dbus method and we need to # assemble a dictionary that we will feed to it. # Start by preparing a SubscriptionData property mapping # to the RHSM config keys. # # A note about constructing the dict: # - DBus API needs all values to be strings, so we need to convert the # port number to string # - all values need to be string variants # - proxy password is stored in SecretData instance and we need to retrieve # its value property_key_map = { self.CONFIG_KEY_SERVER_HOSTNAME: self._request.server_hostname, self.CONFIG_KEY_SERVER_PROXY_HOSTNAME: self._request.server_proxy_hostname, self.CONFIG_KEY_SERVER_PROXY_PORT: str(self._request.server_proxy_port), self.CONFIG_KEY_SERVER_PROXY_USER: self._request.server_proxy_user, self.CONFIG_KEY_SERVER_PROXY_PASSWORD: self._request.server_proxy_password.value, self.CONFIG_KEY_RHSM_BASEURL: self._request.rhsm_baseurl } # Then process the mapping into the final dict we will set to RHSM. This includes # checking if some values have been cleared by the user and should be restored to # the original values that have been in the RHSM config before we started # manipulating it. # # Also the RHSM DBus API requires a dict of variants, so we need to provide # that as well. config_dict = {} for key, value in property_key_map.items(): if value: # if value is present in request, use it config_dict[key] = get_variant(Str, value) else: # if no value is present in request, use # value from the original RHSM config state # (if any) log.debug( "subscription: restoring original value for RHSM config key %s", key) config_dict[key] = get_variant( Str, self._rhsm_config_defaults.get(key, "")) # and finally set the dict to RHSM via the DBus API self._rhsm_config_proxy.SetAll(config_dict, "")
def test_realm_property(self): """Test the realm property.""" realm = { "name": get_variant(Str, "domain.example.com"), "discover-options": get_variant(List[Str], ["--client-software=sssd"]), "join-options": get_variant(List[Str], ["--one-time-password=password"]), "discovered": get_variant(Bool, True), "required-packages": get_variant(List[Str], []) } self._check_dbus_property( "Realm", realm )
def test_configuration(self): """Test the configuration property.""" data = { "osname": get_variant(Str, "fedora-atomic"), "remote": get_variant(Str, "fedora-atomic-28"), "url": get_variant(Str, "https://kojipkgs.fedoraproject.org/atomic/repo"), "ref": get_variant(Str, "fedora/28/x86_64/atomic-host"), "gpg-verification-enabled": get_variant(Bool, False) } self._check_dbus_property( "Configuration", data )
def test_set_constraint(self): """Test SetConstraint.""" self.interface.SetConstraint(STORAGE_MIN_RAM, get_variant(Int, 987 * 1024 * 1024)) assert storage_checker.constraints[STORAGE_MIN_RAM] == Size("987 MiB") with pytest.raises(UnsupportedValueError) as cm: self.interface.SetConstraint(STORAGE_LUKS2_MIN_RAM, get_variant(Int, 987 * 1024 * 1024)) assert str(cm.value) == "Constraint 'luks2_min_ram' is not supported." assert storage_checker.constraints[STORAGE_LUKS2_MIN_RAM] == Size( "128 MiB")
def test_get_complicated_structure(self): data = self.ComplicatedData() data.dictionary = {1: "1", 2: "2"} data.bool_list = [True, False, False] data.very_long_property_name = "My String Value" self.assertEqual( { 'dictionary': get_variant(Dict[Int, Str], { 1: "1", 2: "2" }), 'bool-list': get_variant(List[Bool], [True, False, False]), 'very-long-property-name': get_variant(Str, "My String Value") }, self.ComplicatedData.to_structure(data))
def test_success(self, start_service, get_proxy): """Test StartRHSMTask - successful task.""" # create the task task = StartRHSMTask() # 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 assert 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( "com.redhat.RHSM1", "/com/redhat/RHSM1/Config", "com.redhat.RHSM1.Config", ) # check expected values were set on the RHSM config proxy # - 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'), }, '' )
def Value(self, value: Int): self._values.append(value) self.PropertiesChanged( "my.testing.Example", {"Value": get_variant(Int, value)}, ["Name"] )
def test_properties_changed(self): """Test the PropertiesChanged signal.""" self._set_service(ExampleInterface()) event = Event() callback = Mock() def test_1(): proxy = self._get_proxy() proxy.PropertiesChanged.connect(callback) event.set() def test_2(): event.wait() proxy = self._get_proxy() proxy.Value = 10 self._add_client(test_1) self._add_client(test_2) self._run_test() callback.assert_called_once_with( "my.testing.Example", {"Value": get_variant(Int, 10)}, ["Name"] )