def test_attach_subscription_task_success(self, environ_get):
     """Test the ParseAttachedSubscriptionsTask."""
     # prepare mock proxies the task is expected to interact with
     rhsm_entitlement_proxy = Mock()
     rhsm_entitlement_proxy.GetPools.return_value = "foo"
     rhsm_syspurpose_proxy = Mock()
     rhsm_syspurpose_proxy.GetSyspurpose.return_value = "bar"
     task = ParseAttachedSubscriptionsTask(
         rhsm_entitlement_proxy=rhsm_entitlement_proxy,
         rhsm_syspurpose_proxy=rhsm_syspurpose_proxy)
     # mock the parsing methods
     subscription1 = AttachedSubscription()
     subscription2 = AttachedSubscription()
     task._parse_subscription_json = Mock()
     task._parse_subscription_json.return_value = [
         subscription1, subscription2
     ]
     system_purpose_data = SystemPurposeData()
     task._parse_system_purpose_json = Mock()
     task._parse_system_purpose_json.return_value = system_purpose_data
     # run the task
     result = task.run()
     # check DBus proxies were called as expected
     rhsm_entitlement_proxy.GetPools.assert_called_once_with(
         {'pool_subsets': get_variant(Str, "consumed")}, {}, "en_US.UTF-8")
     rhsm_syspurpose_proxy.GetSyspurpose.assert_called_once_with(
         "en_US.UTF-8")
     # check the parsing methods were called
     task._parse_subscription_json.assert_called_once_with("foo")
     task._parse_system_purpose_json.assert_called_once_with("bar")
     # check the result that has been returned is as expected
     self.assertEqual(result.attached_subscriptions,
                      [subscription1, subscription2])
     self.assertEqual(result.system_purpose_data, system_purpose_data)
Example #2
0
    def SystemPurposeData(self, system_purpose_data: Structure):
        """Set a new DBus structure holding system purpose data.

        :param system_purpose_data: DBus structure corresponding to SystemPurposeData
        """
        converted_data = SystemPurposeData.from_structure(system_purpose_data)
        self.implementation.set_system_purpose_data(converted_data)
Example #3
0
 def _set_system_purpose_data(self):
     """Set system purpose data to the Subscription DBus module."""
     self._subscription_module.SetSystemPurposeData(
         SystemPurposeData.to_structure(self.system_purpose_data)
     )
     # also apply the data (only applies when needed)
     self._apply_system_purpose_data()
Example #4
0
    def __init__(self):
        super().__init__()

        # system purpose

        self._valid_roles = []
        self._valid_slas = []
        self._valid_usage_types = []

        self._system_purpose_data = SystemPurposeData()
        self.system_purpose_data_changed = Signal()

        self._load_valid_system_purpose_values()

        # subscription request

        self._subscription_request = SubscriptionRequest()
        self.subscription_request_changed = Signal()

        # attached subscriptions
        self._attached_subscriptions = []
        self.attached_subscriptions_changed = Signal()

        # Insights

        # What are the defaults for Red Hat Insights ?
        # - during a kickstart installation, the user
        #   needs to opt-in by using the rhsm command
        #   with the --connect-to-insights option
        # - during a GUI interactive installation the
        #  "connect to Insights" checkbox is checked by default,
        #  making Insights opt-out
        # - in both cases the system also needs to be subscribed,
        #   or else the system can't be connected to Insights
        self._connect_to_insights = False
        self.connect_to_insights_changed = Signal()

        # registration status
        self.registered_changed = Signal()
        self._registered = False

        # subscription status
        self.subscription_attached_changed = Signal()
        self._subscription_attached = False

        # RHSM service startup and access
        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
        self._rhsm_config_defaults = None
Example #5
0
    def _parse_system_purpose_json(final_syspurpose_json):
        """Parse the JSON into a SystemPurposeData instance.

        The expected JSON is a simple three key dictionary listing the final
        System Purpose state after subscription/subscriptions have been attached.

        :param str final_syspurpose_json: JSON describing final syspurpose state
        :return: final system purpose data
        :rtype: SystemPurposeData instance
        """
        system_purpose_data = SystemPurposeData()

        try:
            syspurpose_json = json.loads(final_syspurpose_json)
        except json.decoder.JSONDecodeError:
            log.warning(
                "subscription: failed to parse GetSyspurpose() JSON output")
            # empty system purpose data is better than an installation ending crash
            return system_purpose_data

        system_purpose_data.role = syspurpose_json.get("role", "")
        system_purpose_data.sla = syspurpose_json.get(
            "service_level_agreement", "")
        system_purpose_data.usage = syspurpose_json.get("usage", "")
        system_purpose_data.addons = syspurpose_json.get("addons", [])
        return system_purpose_data
Example #6
0
    def __init__(self):
        super().__init__()

        # system purpose

        self._valid_roles = []
        self._valid_slas = []
        self._valid_usage_types = []

        self._system_purpose_data = SystemPurposeData()
        self.system_purpose_data_changed = Signal()

        self._load_valid_system_purpose_values()
    def ks_out_command_only_test(self):
        """Test with only syspurpose command being used."""
        ks_in = "syspurpose"
        ks_out = ""
        self._test_kickstart(ks_in, ks_out)

        # also test resulting module state
        structure = self.subscription_interface.SystemPurposeData
        system_purpose_data = SystemPurposeData.from_structure(structure)
        self.assertEqual(system_purpose_data.role, "")
        self.assertEqual(system_purpose_data.sla, "")
        self.assertEqual(system_purpose_data.usage, "")
        self.assertEqual(system_purpose_data.addons, [])
 def test_system_purpose_json_parsing(self):
     """Test the system purpose JSON parsing method of ParseAttachedSubscriptionsTask."""
     parse_method = ParseAttachedSubscriptionsTask._parse_system_purpose_json
     # the parsing method should be able to survive also getting an empty string
     expected_struct = {"role": "", "sla": "", "usage": "", "addons": []}
     struct = get_native(SystemPurposeData.to_structure(parse_method("")))
     self.assertEqual(struct, expected_struct)
     # try parsing expected complete system purpose data
     system_purpose_dict = {
         "role": "important",
         "service_level_agreement": "it will work just fine",
         "usage": "careful",
         "addons": ["red", "green", "blue"]
     }
     system_purpose_json = json.dumps(system_purpose_dict)
     expected_struct = {
         "role": "important",
         "sla": "it will work just fine",
         "usage": "careful",
         "addons": ["red", "green", "blue"]
     }
     struct = get_native(
         SystemPurposeData.to_structure(parse_method(system_purpose_json)))
     self.assertEqual(struct, expected_struct)
     # try also partial parsing, just in case
     system_purpose_dict = {
         "role": "important",
         "usage": "careful",
     }
     system_purpose_json = json.dumps(system_purpose_dict)
     expected_struct = {
         "role": "important",
         "sla": "",
         "usage": "careful",
         "addons": []
     }
     struct = get_native(
         SystemPurposeData.to_structure(parse_method(system_purpose_json)))
     self.assertEqual(struct, expected_struct)
    def ks_out_set_all_usage_test(self):
        """Check kickstart with all options being used."""
        ks_in = '''
        syspurpose --role="FOO" --sla="BAR" --usage="BAZ" --addon="F Product" --addon="B Feature"
        '''
        ks_out = '''
        # Intended system purpose
        syspurpose --role="FOO" --sla="BAR" --usage="BAZ" --addon="F Product" --addon="B Feature"
        '''
        self._test_kickstart(ks_in, ks_out)

        structure = self.subscription_interface.SystemPurposeData
        system_purpose_data = SystemPurposeData.from_structure(structure)
        self.assertEqual(system_purpose_data.role, 'FOO')
        self.assertEqual(system_purpose_data.sla, 'BAR')
        self.assertEqual(system_purpose_data.usage, 'BAZ')
        self.assertEqual(system_purpose_data.addons,
                         ["F Product", "B Feature"])
    def set_system_purpose_test(self):
        """Test if setting system purpose data from DBUS works correctly."""
        system_purpose_data = {
            "role": get_variant(Str, "foo"),
            "sla": get_variant(Str, "bar"),
            "usage": get_variant(Str, "baz"),
            "addons": get_variant(List[Str], ["a", "b", "c"])
        }

        self._test_dbus_property("SystemPurposeData", system_purpose_data)

        output_structure = self.subscription_interface.SystemPurposeData
        output_system_purpose_data = SystemPurposeData.from_structure(
            output_structure)

        self.assertEqual(output_system_purpose_data.role, "foo")
        self.assertEqual(output_system_purpose_data.sla, "bar")
        self.assertEqual(output_system_purpose_data.usage, "baz")
        self.assertEqual(output_system_purpose_data.addons, ["a", "b", "c"])
 def test_system_purpose_task(self, give_the_system_purpose):
     """Test the SystemPurposeConfigurationTask task - not yet set."""
     # prepare some system purpose data
     system_purpose_data = SystemPurposeData()
     system_purpose_data.role = "foo"
     system_purpose_data.sla = "bar"
     system_purpose_data.usage = "baz"
     system_purpose_data.addons = ["a", "b", "c"]
     task = SystemPurposeConfigurationTask(system_purpose_data)
     task.run()
     give_the_system_purpose.assert_called_once_with(sysroot="/",
                                                     role="foo",
                                                     sla="bar",
                                                     usage="baz",
                                                     addons=["a", "b", "c"])
 def system_purpose_task_test(self, give_the_system_purpose):
     """Test the SystemPurposeConfigurationTask task."""
     with tempfile.TemporaryDirectory() as sysroot:
         system_purpose_data = SystemPurposeData()
         system_purpose_data.role = "foo"
         system_purpose_data.sla = "bar"
         system_purpose_data.usage = "baz"
         system_purpose_data.addons = ["a", "b", "c"]
         task = SystemPurposeConfigurationTask(sysroot, system_purpose_data)
         task.run()
         give_the_system_purpose.assert_called_once_with(
             role="foo",
             sla="bar",
             usage="baz",
             addons=["a", "b", "c"],
             sysroot=sysroot)
    def system_purpose_data_test(self):
        """Test the SystemPurposeData DBus structure."""

        # create the SystemPurposeData structure
        system_purpose_data = SystemPurposeData()
        system_purpose_data.role = "foo"
        system_purpose_data.sla = "bar"
        system_purpose_data.usage = "baz"
        system_purpose_data.addons = ["a", "b", "c"]

        # create its expected representation
        expected_dict = {
            "role": get_variant(Str, "foo"),
            "sla": get_variant(Str, "bar"),
            "usage": get_variant(Str, "baz"),
            "addons": get_variant(List[Str], ["a", "b", "c"])
        }

        # compare the two
        self.assertEqual(SystemPurposeData.to_structure(system_purpose_data),
                         expected_dict)
 def test_system_purpose_task_already_set(self, give_the_system_purpose,
                                          check_set):
     """Test the SystemPurposeConfigurationTask task - already set."""
     # The task should still run give_the_system_purpose() even if system purpose
     # has already been set to make it possible to overwrite or clear existing data.
     check_set.return_value = True
     # prepare some system purpose data
     system_purpose_data = SystemPurposeData()
     system_purpose_data.role = "foo"
     system_purpose_data.sla = "bar"
     system_purpose_data.usage = "baz"
     system_purpose_data.addons = ["a", "b", "c"]
     task = SystemPurposeConfigurationTask(system_purpose_data)
     task.run()
     give_the_system_purpose.assert_called_once_with(sysroot="/",
                                                     role="foo",
                                                     sla="bar",
                                                     usage="baz",
                                                     addons=["a", "b", "c"])
Example #15
0
    def process_kickstart(self, data):
        """Process the kickstart data."""
        log.debug("Processing kickstart data...")

        # system purpose
        #
        # Try if any of the values in kickstart match a valid field.
        # If it does, write the valid field value instead of the value from kickstart.
        #
        # This way a value in kickstart that has a different case and/or trailing white space
        # can still be used to preselect a value in a UI instead of being marked as a custom
        # user specified value.
        system_purpose_data = SystemPurposeData()

        system_purpose_data.role = system_purpose.process_field(
            data.syspurpose.role,
            self.valid_roles,
            "role"
        )

        system_purpose_data.sla = system_purpose.process_field(
            data.syspurpose.sla,
            self.valid_slas,
            "sla"
        )

        system_purpose_data.usage = system_purpose.process_field(
            data.syspurpose.usage,
            self.valid_usage_types,
            "usage"
        )

        if data.syspurpose.addons:
            # As we do not have a list of valid addons available, we just use what was provided
            # by the user in kickstart verbatim.
            system_purpose_data.addons = data.syspurpose.addons

        self.set_system_purpose_data(system_purpose_data)
Example #16
0
    def process_kickstart(self, data):
        """Process the kickstart data."""
        log.debug("Processing kickstart data...")

        # system purpose
        #
        # Try if any of the values in kickstart match a valid field.
        # If it does, write the valid field value instead of the value from kickstart.
        #
        # This way a value in kickstart that has a different case and/or trailing white space
        # can still be used to preselect a value in a UI instead of being marked as a custom
        # user specified value.
        system_purpose_data = SystemPurposeData()

        system_purpose_data.role = system_purpose.process_field(
            data.syspurpose.role, self.valid_roles, "role")

        system_purpose_data.sla = system_purpose.process_field(
            data.syspurpose.sla, self.valid_slas, "sla")

        system_purpose_data.usage = system_purpose.process_field(
            data.syspurpose.usage, self.valid_usage_types, "usage")

        if data.syspurpose.addons:
            # As we do not have a list of valid addons available, we just use what was provided
            # by the user in kickstart verbatim.
            system_purpose_data.addons = data.syspurpose.addons

        self.set_system_purpose_data(system_purpose_data)

        # apply system purpose data, if any, so that it is all in place when we start
        # talking to the RHSM service
        if self.system_purpose_data.check_data_available():
            self._apply_syspurpose()

        # subscription request

        subscription_request = SubscriptionRequest()

        # credentials
        if data.rhsm.organization:
            subscription_request.organization = data.rhsm.organization
        if data.rhsm.activation_keys:
            subscription_request.activation_keys.set_secret(
                data.rhsm.activation_keys)

        # if org id and at least one activation key is set, switch authentication
        # type to ORG & KEY
        if data.rhsm.organization and data.rhsm.activation_keys:
            subscription_request.type = SUBSCRIPTION_REQUEST_TYPE_ORG_KEY

        # custom URLs
        if data.rhsm.server_hostname:
            subscription_request.server_hostname = data.rhsm.server_hostname
        if data.rhsm.rhsm_baseurl:
            subscription_request.rhsm_baseurl = data.rhsm.rhsm_baseurl

        # HTTP proxy
        if data.rhsm.proxy:
            # first try to parse the proxy string from kickstart
            try:
                proxy = ProxyString(data.rhsm.proxy)
                if proxy.host:
                    # ensure port is an integer and set to -1 if unknown
                    port = int(proxy.port) if proxy.port else -1

                    subscription_request.server_proxy_hostname = proxy.host
                    subscription_request.server_proxy_port = port

                    # ensure no username translates to the expected ""
                    # instead of the None returned by the ProxyString class
                    subscription_request.server_proxy_user = proxy.username or ""
                    subscription_request.server_proxy_password.set_secret(
                        proxy.password)
            except ProxyStringError as e:
                # should not be fatal, but definitely logged as error
                message = "Failed to parse proxy for the rhsm command: {}".format(
                    str(e))
                warnings.warn(message, KickstartParseWarning)

        # set the resulting subscription request
        self.set_subscription_request(subscription_request)

        # insights
        self.set_connect_to_insights(bool(data.rhsm.connect_to_insights))
Example #17
0
 def _get_system_purpose_data(self):
     """Get SystemPurposeData from the Subscription module."""
     struct = self._subscription_module.SystemPurposeData
     return SystemPurposeData.from_structure(struct)
Example #18
0
 def SystemPurposeData(self) -> Structure:
     """Return DBus structure holding current system purpose data."""
     return SystemPurposeData.to_structure(
         self.implementation.system_purpose_data)