def action_status(args, cfg):
    if not cfg:
        cfg = config.UAConfig()
    if not cfg.is_attached:
        print(ua_status.MESSAGE_UNATTACHED)
        return
    contractInfo = cfg.machine_token['machineTokenInfo']['contractInfo']
    expiry = datetime.strptime(contractInfo['effectiveTo'],
                               '%Y-%m-%dT%H:%M:%SZ')

    status_content = []
    support_entitlement = cfg.entitlements.get('support')
    tech_support = ua_status.COMMUNITY
    if support_entitlement:
        tech_support = support_entitlement.get('affordances',
                                               {}).get('supportLevel',
                                                       ua_status.COMMUNITY)
    tech_support_txt = ua_status.STATUS_COLOR.get(
        tech_support) or ua_status.STATUS_COLOR[ua_status.COMMUNITY]
    account = cfg.accounts[0]
    status_content.append(
        STATUS_HEADER_TMPL.format(account=account['name'],
                                  subscription=contractInfo['name'],
                                  contract_expiry=expiry.date(),
                                  tech_support_level=tech_support_txt))

    for ent_cls in entitlements.ENTITLEMENT_CLASSES:
        ent = ent_cls(cfg)
        status_content.append(ua_status.format_entitlement_status(ent))
    status_content.append('\nEnable entitlements with `ua enable <service>`\n')
    print('\n'.join(status_content))
示例#2
0
 def test_can_enable_false_on_entitlement_active(self, m_getuid):
     """When operational status is ACTIVE, can_enable returns False."""
     tmp_dir = self.tmp_dir()
     cfg = config.UAConfig(cfg={'data_dir': tmp_dir})
     machineToken = {
         'machineToken': 'blah',
         'machineTokenInfo': {
             'contractInfo': {
                 'resourceEntitlements': [{
                     'type': 'testconcreteentitlement'
                 }]
             }
         }
     }
     cfg.write_cache('machine-token', machineToken)
     cfg.write_cache('machine-access-testconcreteentitlement',
                     {'entitlement': {
                         'entitled': True
                     }})
     entitlement = ConcreteTestEntitlement(
         cfg, operational_status=(status.ACTIVE, ''))
     with mock.patch('sys.stdout', new_callable=StringIO) as m_stdout:
         self.assertFalse(entitlement.can_enable())
     self.assertEqual(
         'Test Concrete Entitlement is already enabled.\nSee `ua status`\n',
         m_stdout.getvalue())
示例#3
0
    def test_enable_configures_apt_sources_and_auth_files(
            self, m_getuid, m_platform_info, m_subp):
        """When entitled, configure apt repo auth token, pinning and url."""
        m_platform_info.return_value = 'xenial'
        tmp_dir = self.tmp_dir()
        cfg = config.UAConfig(cfg={'data_dir': tmp_dir})
        cfg.write_cache('machine-token', CIS_MACHINE_TOKEN)
        cfg.write_cache('machine-access-cis-audit', CIS_RESOURCE_ENTITLED)
        entitlement = CISEntitlement(cfg)
        # Unset static affordance container check
        entitlement.static_affordances = ()

        with mock.patch('uaclient.apt.add_auth_apt_repo') as m_add_apt:
            with mock.patch('uaclient.apt.add_ppa_pinning') as m_add_pinning:
                self.assertTrue(entitlement.enable())

        add_apt_calls = [
            mock.call('/etc/apt/sources.list.d/ubuntu-cis-audit-xenial.list',
                      'http://CIS', 'TOKEN', None, 'APTKEY')]

        subp_apt_cmds = [
            mock.call(['apt-get', 'update'], capture=True),
            mock.call(['apt-get', 'install', 'ubuntu-cisbenchmark-16.04'])]

        assert add_apt_calls == m_add_apt.call_args_list
        # No apt pinning for cis-audit
        assert [] == m_add_pinning.call_args_list
        assert subp_apt_cmds == m_subp.call_args_list
示例#4
0
 def test_can_disable_false_on_unentitled(self, m_getuid):
     """When entitlement contract is not enabled, can_disable is False."""
     tmp_dir = self.tmp_dir()
     cfg = config.UAConfig(cfg={'data_dir': tmp_dir})
     machineToken = {
         'machineToken': 'blah',
         'machineTokenInfo': {
             'contractInfo': {
                 'resourceEntitlements': [{
                     'type': 'testconcreteentitlement'
                 }]
             }
         }
     }
     cfg.write_cache('machine-token', machineToken)
     cfg.write_cache('machine-access-testconcreteentitlement',
                     {'entitlement': {
                         'entitled': False
                     }})
     entitlement = ConcreteTestEntitlement(
         cfg, operational_status=(status.INACTIVE, ''))
     with mock.patch('sys.stdout', new_callable=StringIO) as m_stdout:
         self.assertFalse(entitlement.can_disable())
     self.assertEqual(
         'This subscription is not entitled to Test Concrete Entitlement.\n'
         'See `ua status` or https://ubuntu.com/advantage\n\n',
         m_stdout.getvalue())
示例#5
0
    def test_no_apt_config_removed_when_upgraded_from_trusty_to_xenial(
            self, m_add_apt, m_unlink, tmpdir):
        """No apt config when connected but no entitlements enabled."""

        # Make CC resource access report not entitled
        cc_unentitled = copy.deepcopy(dict(CC_RESOURCE_ENTITLED))
        cc_unentitled['entitlement']['entitled'] = False

        cfg = config.UAConfig({'data_dir': tmpdir.strpath})
        cfg.write_cache('machine-token', dict(CC_MACHINE_TOKEN))
        cfg.write_cache('machine-access-cc', cc_unentitled)

        orig_exists = os.path.exists

        apt_files = ['/etc/apt/sources.list.d/ubuntu-cc-trusty.list']

        def fake_apt_list_exists(path):
            if path in apt_files:
                return True
            return orig_exists(path)

        with mock.patch('uaclient.apt.os.path.exists') as m_exists:
            m_exists.side_effect = fake_apt_list_exists
            migrate_apt_sources(
                cfg=cfg,
                platform_info={'series': 'xenial', 'release': '16.04'})
        assert [] == m_add_apt.call_args_list
        # Only exists checks for for cfg.is_attached and can_enable
        assert [] == m_unlink.call_args_list  # remove nothing
        assert [] == m_exists.call_args_list
示例#6
0
def action_status(args, cfg):
    if not cfg:
        cfg = config.UAConfig()
    status = cfg.status()
    active_value = ua_status.UserFacingConfigStatus.ACTIVE.value
    config_active = bool(status["configStatus"] == active_value)
    if args and args.wait and config_active:
        while status["configStatus"] == active_value:
            print(".", end="")
            time.sleep(1)
            status = cfg.status()
        print("")
    if args and args.format == "json":
        if status["expires"] != ua_status.UserFacingStatus.INAPPLICABLE.value:
            status["expires"] = str(status["expires"])
        print(json.dumps(status))
    else:
        show_beta = args.all if args else False
        output = ua_status.format_tabular(cfg.status(show_beta))
        # Replace our Unicode dash with an ASCII dash if we aren't going to be
        # writing to a utf-8 output; see
        # https://github.com/CanonicalLtd/ubuntu-advantage-client/issues/859
        if (
            sys.stdout.encoding is None
            or "UTF-8" not in sys.stdout.encoding.upper()
        ):
            output = output.replace("\u2014", "-")
        print(output)
    return 0
示例#7
0
 def factory(
     *,
     entitled: bool,
     applicability_status: "Tuple[status.ApplicabilityStatus, str]" = None,
     application_status: "Tuple[status.ApplicationStatus, str]" = None
 ) -> ConcreteTestEntitlement:
     cfg = config.UAConfig(cfg={"data_dir": tmpdir.strpath})
     machineToken = {
         "machineToken": "blah",
         "machineTokenInfo": {
             "contractInfo": {
                 "resourceEntitlements": [{
                     "type": "testconcreteentitlement",
                     "entitled": entitled,
                 }]
             }
         },
     }
     cfg.write_cache("machine-token", machineToken)
     cfg.write_cache(
         "machine-access-testconcreteentitlement",
         {"entitlement": {
             "entitled": entitled
         }},
     )
     return ConcreteTestEntitlement(
         cfg,
         applicability_status=applicability_status,
         application_status=application_status,
     )
示例#8
0
    def test_enable_configures_apt_sources_and_auth_files(
            self, m_getuid, m_platform_info):
        """When entitled, configure apt repo auth token, pinning and url."""
        m_platform_info.return_value = 'xenial'
        tmp_dir = self.tmp_dir()
        cfg = config.UAConfig(cfg={'data_dir': tmp_dir})
        cfg.write_cache('machine-token', FIPS_MACHINE_TOKEN)
        cfg.write_cache('machine-access-fips', FIPS_RESOURCE_ENTITLED)
        entitlement = FIPSEntitlement(cfg)
        # Unset static affordance container check
        entitlement.static_affordances = ()

        with mock.patch('uaclient.apt.add_auth_apt_repo') as m_add_apt:
            with mock.patch('uaclient.apt.add_ppa_pinning') as m_add_pinning:
                self.assertTrue(entitlement.enable())

        add_apt_calls = [
            mock.call('/etc/apt/sources.list.d/ubuntu-fips-xenial.list',
                      'http://FIPS', 'TOKEN', None, 'APTKEY')
        ]
        apt_pinning_calls = [
            mock.call('/etc/apt/preferences.d/ubuntu-fips-xenial',
                      'http://FIPS', 1001)
        ]

        assert add_apt_calls == m_add_apt.call_args_list
        assert apt_pinning_calls == m_add_pinning.call_args_list
示例#9
0
 def test_can_disable_requires_root(self, m_getuid):
     """Non-root users receive False from UAEntitlement.can_disable."""
     cfg = config.UAConfig(cfg={})
     entitlement = ConcreteTestEntitlement(cfg)
     with mock.patch('sys.stdout', new_callable=StringIO) as m_stdout:
         self.assertFalse(entitlement.can_disable())
     self.assertEqual('This command must be run as root (try using sudo)\n',
                      m_stdout.getvalue())
示例#10
0
    def __init__(self, cfg=None):
        """Setup UAEntitlement instance

        @param config: Parsed configuration dictionary
        """
        if not cfg:
            cfg = config.UAConfig()
        self.cfg = cfg
 def test_contract_status_entitled(self, tmpdir):
     """The contract_status returns ENTITLED when entitled is True."""
     cfg = config.UAConfig(cfg={'data_dir': tmpdir.strpath})
     cfg.write_cache('machine-token', dict(LIVEPATCH_MACHINE_TOKEN))
     cfg.write_cache('machine-access-livepatch',
                     dict(LIVEPATCH_RESOURCE_ENTITLED))
     entitlement = LivepatchEntitlement(cfg)
     assert status.ENTITLED == entitlement.contract_status()
示例#12
0
def action_status(args, cfg):
    if not cfg:
        cfg = config.UAConfig()
    if args and args.format == 'json':
        status = cfg.status()
        if status['expires'] != ua_status.INAPPLICABLE:
            status['expires'] = str(status['expires'])
        print(json.dumps(status))
    else:
        print(ua_status.format_tabular(cfg.status()))
def entitlement(tmpdir):
    """
    A pytest fixture to create a RepoTestEntitlement with some default config

    (Uses the tmpdir fixture for the underlying config cache.)
    """
    cfg = config.UAConfig(cfg={'data_dir': tmpdir.strpath})
    cfg.write_cache('machine-token', dict(REPO_MACHINE_TOKEN))
    cfg.write_cache('machine-access-repotest', dict(REPO_RESOURCE_ENTITLED))
    return RepoTestEntitlement(cfg)
def action_status(args, cfg):
    if not cfg:
        cfg = config.UAConfig()
    if args and args.format == "json":
        status = cfg.status()
        if status["expires"] != ua_status.UserFacingStatus.INAPPLICABLE.value:
            status["expires"] = str(status["expires"])
        print(json.dumps(status))
    else:
        print(ua_status.format_tabular(cfg.status()))
    return 0
示例#15
0
 def test_can_disable_false_on_unattached_machine(self, m_getuid):
     """An unattached machine will return False from can_disable."""
     tmp_dir = self.tmp_dir()
     cfg = config.UAConfig(cfg={'data_dir': tmp_dir})
     entitlement = ConcreteTestEntitlement(cfg)
     with mock.patch('sys.stdout', new_callable=StringIO) as m_stdout:
         self.assertFalse(entitlement.can_disable())
     self.assertEqual(
         'This machine is not attached to a UA subscription.\n'
         'See `ua attach` or https://ubuntu.com/advantage\n\n',
         m_stdout.getvalue())
    def test_contract_status_unentitled(self, tmpdir):
        """The contract_status returns NONE when entitled is False."""
        livepatch_unentitled = copy.deepcopy(dict(LIVEPATCH_RESOURCE_ENTITLED))

        # Make livepatch resource access report not entitled
        livepatch_unentitled['entitlement']['entitled'] = False
        cfg = config.UAConfig(cfg={'data_dir': tmpdir.strpath})
        cfg.write_cache('machine-token', dict(LIVEPATCH_MACHINE_TOKEN))
        cfg.write_cache('machine-access-livepatch', livepatch_unentitled)
        entitlement = LivepatchEntitlement(cfg)
        assert status.NONE == entitlement.contract_status()
示例#17
0
    def __init__(
        self, cfg: "Optional[config.UAConfig]" = None, assume_yes: bool = False
    ) -> None:
        """Setup UAEntitlement instance

        @param config: Parsed configuration dictionary
        """
        if not cfg:
            cfg = config.UAConfig()
        self.cfg = cfg
        self.assume_yes = assume_yes
    def test_apt_config_migrated_when_enabled_upgraded_from_trusty_to_xenial(
            self, m_add_apt, m_unlink, m_platform_info, m_subp, tmpdir):
        """Apt config is migrated when connected and entitlement is enabled."""

        cfg = config.UAConfig({'data_dir': tmpdir.strpath})
        cfg.write_cache('machine-token', dict(CC_MACHINE_TOKEN))
        cfg.write_cache('machine-access-cc', dict(CC_RESOURCE_ENTITLED))

        orig_exists = os.path.exists

        glob_files = [
            '/etc/apt/sources.list.d/ubuntu-cc-trusty.list',
            '/etc/apt/sources.list.d/ubuntu-cc-xenial.list'
        ]

        def fake_platform_info(key=None):
            platform_data = {
                'arch': 'x86_64',
                'series': 'xenial',
                'release': '16.04'
            }
            if key:
                return platform_data[key]
            return platform_data

        def fake_apt_list_exists(path):
            if path in glob_files:
                return True
            return orig_exists(path)

        def fake_glob(regex):
            if regex == '/etc/apt/sources.list.d/ubuntu-cc-*.list':
                return glob_files
            return []

        repo_url = CC_RESOURCE_ENTITLED['entitlement']['directives']['aptURL']
        m_platform_info.side_effect = fake_platform_info
        m_subp.return_value = '500 %s' % repo_url, ''
        with mock.patch('uaclient.apt.glob.glob') as m_glob:
            with mock.patch('uaclient.apt.os.path.exists') as m_exists:
                m_glob.side_effect = fake_glob
                m_exists.side_effect = fake_apt_list_exists
                assert None is migrate_apt_sources(cfg=cfg)
        assert [] == m_add_apt.call_args_list
        # Only exists checks for for cfg.is_attached and can_enable
        exists_calls = [
            mock.call(tmpdir.join('machine-token.json').strpath),
            mock.call(tmpdir.join('machine-access-cc.json').strpath)
        ]
        unlink_calls = [
            mock.call('/etc/apt/sources.list.d/ubuntu-cc-trusty.list')
        ]
        assert unlink_calls == m_unlink.call_args_list  # remove nothing
        assert exists_calls == m_exists.call_args_list
示例#19
0
 def test_noop_apt_config_when_not_attached(
         self, m_add_apt, m_unlink, tmpdir):
     """Perform not apt config changes when not attached."""
     cfg = config.UAConfig({'data_dir': tmpdir.strpath})
     assert False is cfg.is_attached
     with mock.patch('uaclient.apt.os.path.exists') as m_exists:
         m_exists.return_value = False
         assert None is migrate_apt_sources(
             cfg=cfg,
             platform_info={'series': 'trusty', 'release': '14.04'})
     assert [] == m_add_apt.call_args_list
     assert [] == m_unlink.call_args_list
示例#20
0
 def test_can_enable_true_on_entitlement_inactive(self, m_getuid):
     """When operational status is INACTIVE, can_enable returns True."""
     tmp_dir = self.tmp_dir()
     cfg = config.UAConfig(cfg={'data_dir': tmp_dir})
     cfg.write_cache('machine-token', FIPS_MACHINE_TOKEN)
     cfg.write_cache('machine-access-fips', FIPS_RESOURCE_ENTITLED)
     entitlement = FIPSEntitlement(cfg)
     # Unset static affordance container check
     entitlement.static_affordances = ()
     with mock.patch('sys.stdout', new_callable=StringIO) as m_stdout:
         self.assertTrue(entitlement.can_enable())
     self.assertEqual('', m_stdout.getvalue())
def entitlement(request, tmpdir):
    """
    pytest fixture for a FIPS/FIPS Updates entitlement with some default config

    (Uses the tmpdir fixture for the underlying config cache.)
    """
    cls = request.param
    cfg = config.UAConfig(cfg={'data_dir': tmpdir.strpath})
    cfg.write_cache('machine-token', machine_token(cls.name))
    cfg.write_cache('machine-access-{}'.format(cls.name),
                    machine_access(cls.name))
    return cls(cfg)
 def test_enable_does_not_install_livepatch_snap_when_present(
         self, m_can_enable, m_which, m_subp, tmpdir):
     """Do not attempt to install livepatch snap when it is present."""
     cfg = config.UAConfig(cfg={'data_dir': tmpdir.strpath})
     cfg.write_cache('machine-token', dict(LIVEPATCH_MACHINE_TOKEN))
     cfg.write_cache('machine-access-livepatch',
                     dict(LIVEPATCH_RESOURCE_ENTITLED))
     entitlement = LivepatchEntitlement(cfg)
     with mock.patch('sys.stdout', new_callable=StringIO) as m_stdout:
         assert entitlement.enable()
     assert self.mocks_config == m_subp.call_args_list
     assert 'Canonical livepatch enabled.\n' == m_stdout.getvalue()
示例#23
0
    def test_enable_passes_silent_if_inapplicable_through(
            self, m_can_enable, caplog_text, tmpdir, silent_if_inapplicable):
        """When can_enable returns False enable returns False."""
        cfg = config.UAConfig(cfg={"data_dir": tmpdir.strpath})
        entitlement = RepoTestEntitlement(cfg)

        kwargs = {}
        if silent_if_inapplicable is not None:
            kwargs["silent_if_inapplicable"] = silent_if_inapplicable
        entitlement.enable(**kwargs)

        expected_call = mock.call(silent=bool(silent_if_inapplicable))
        assert [expected_call] == m_can_enable.call_args_list
示例#24
0
 def factory_func(cls, *, affordances=None, directives=None, suites=None):
     cfg = config.UAConfig(cfg={"data_dir": tmpdir.strpath})
     cfg.write_cache("machine-token", machine_token(cls.name))
     cfg.write_cache(
         "machine-access-{}".format(cls.name),
         machine_access(
             cls.name,
             affordances=affordances,
             directives=directives,
             suites=suites,
         ),
     )
     return cls(cfg)
示例#25
0
 def test_can_enable_true_on_entitlement_inactive(self, m_platform_info,
                                                  _m_subp, capsys, tmpdir):
     """When entitlement is INACTIVE, can_enable returns True."""
     m_platform_info.return_value = PLATFORM_INFO_SUPPORTED
     cfg = config.UAConfig(cfg={"data_dir": tmpdir.strpath})
     cfg.write_cache("machine-token", CC_MACHINE_TOKEN)
     entitlement = CommonCriteriaEntitlement(cfg)
     uf_status, uf_status_details = entitlement.user_facing_status()
     assert status.UserFacingStatus.INACTIVE == uf_status
     details = "{} is not configured".format(entitlement.title)
     assert details == uf_status_details
     assert True is entitlement.can_enable()
     assert ("", "") == capsys.readouterr()
示例#26
0
 def test_can_enable_true_on_entitlement_inactive(self, tmpdir):
     """When operational status is INACTIVE, can_enable returns True."""
     # Unset static affordance container check
     cfg = config.UAConfig(cfg={'data_dir': tmpdir.strpath})
     cfg.write_cache('machine-token', dict(FIPS_MACHINE_TOKEN))
     cfg.write_cache('machine-access-fips', dict(FIPS_RESOURCE_ENTITLED))
     entitlement = FIPSEntitlement(cfg)
     entitlement.static_affordances = ()
     with mock.patch('uaclient.entitlements.base.os.getuid') as m_getuid:
         with mock.patch('sys.stdout', new_callable=StringIO) as m_stdout:
             m_getuid.return_value = 0
             assert True is entitlement.can_enable()
     assert '' == m_stdout.getvalue()
示例#27
0
 def test_can_enable_true_on_entitlement_inactive(self, tmpdir):
     """When operational status is INACTIVE, can_enable returns True."""
     cfg = config.UAConfig(cfg={'data_dir': tmpdir.strpath})
     cfg.write_cache('machine-token', CIS_MACHINE_TOKEN)
     cfg.write_cache('machine-access-cis-audit', CIS_RESOURCE_ENTITLED)
     entitlement = CISEntitlement(cfg)
     # Unset static affordance container check
     entitlement.static_affordances = ()
     with mock.patch.object(entitlement,
                            'operational_status',
                            return_value=(status.INACTIVE, '')):
         with mock.patch('sys.stdout', new_callable=StringIO) as m_stdout:
             assert entitlement.can_enable()
     assert '' == m_stdout.getvalue()
示例#28
0
    def test_enable_configures_apt_sources_and_auth_files(
            self, m_platform_info, m_subp, tmpdir):
        """When entitled, configure apt repo auth token, pinning and url."""
        def fake_platform(key=None):
            info = {'series': 'xenial', 'kernel': '4.15.0-00-generic'}
            if key:
                return info[key]
            return info

        m_platform_info.side_effect = fake_platform
        m_subp.return_value = ('fakeout', '')
        cfg = config.UAConfig(cfg={'data_dir': tmpdir.strpath})
        cfg.write_cache('machine-token', CIS_MACHINE_TOKEN)
        cfg.write_cache('machine-access-cis-audit', CIS_RESOURCE_ENTITLED)
        entitlement = CISEntitlement(cfg)
        # Unset static affordance container check
        entitlement.static_affordances = ()

        with mock.patch('uaclient.entitlements.repo.os.path.exists',
                        mock.Mock(return_value=True)):
            with mock.patch('sys.stdout', new_callable=StringIO) as m_stdout:
                with mock.patch('uaclient.apt.add_auth_apt_repo') as m_add_apt:
                    with mock.patch(
                            'uaclient.apt.add_ppa_pinning') as m_add_pin:
                        assert entitlement.enable()

        add_apt_calls = [
            mock.call(
                '/etc/apt/sources.list.d/ubuntu-cis-audit-xenial.list',
                'http://CIS', 'TOKEN', ['xenial'],
                '/usr/share/keyrings/ubuntu-securitybenchmarks-keyring.gpg')
        ]

        subp_apt_cmds = [
            mock.call(['apt-cache', 'policy']),
            mock.call(['apt-get', 'update'], capture=True),
            mock.call(['apt-get', 'install', '--assume-yes'] +
                      entitlement.packages,
                      capture=True)
        ]

        assert add_apt_calls == m_add_apt.call_args_list
        # No apt pinning for cis-audit
        assert [] == m_add_pin.call_args_list
        assert subp_apt_cmds == m_subp.call_args_list
        expected_stdout = (
            'Updating package lists ...\n'
            'Installing Canonical CIS Benchmark Audit Tool packages ...\n'
            'Canonical CIS Benchmark Audit Tool enabled.\n')
        assert expected_stdout == m_stdout.getvalue()
示例#29
0
def main(sys_argv=None):
    if not sys_argv:
        sys_argv = sys.argv
    parser = get_parser()
    cli_arguments = sys_argv[1:]
    if not cli_arguments:
        parser.print_usage()
        print('Try \'ubuntu-advantage --help\' for more information.')
        sys.exit(1)
    args = parser.parse_args(args=cli_arguments)
    cfg = config.UAConfig()
    log_level = cfg.log_level
    console_level = logging.DEBUG if args.debug else logging.INFO
    setup_logging(console_level, log_level, cfg.log_file)
    return args.action(args, cfg)
示例#30
0
 def test_can_enable_true_on_entitlement_inactive(self, m_getuid,
                                                  m_platform_info, tmpdir):
     """When operational status is INACTIVE, can_enable returns True."""
     m_platform_info.return_value = PLATFORM_INFO_SUPPORTED
     cfg = config.UAConfig(cfg={'data_dir': tmpdir.strpath})
     cfg.write_cache('machine-token', CC_MACHINE_TOKEN)
     cfg.write_cache('machine-access-cc', CC_RESOURCE_ENTITLED)
     entitlement = CommonCriteriaEntitlement(cfg)
     op_status, op_status_details = entitlement.operational_status()
     assert status.INACTIVE == op_status
     details = '%s is not configured' % entitlement.title
     assert details == op_status_details
     with mock.patch('sys.stdout', new_callable=StringIO) as m_stdout:
         assert True is entitlement.can_enable()
     assert '' == m_stdout.getvalue()