rhsm modules: cleanly fail when not run as root (#6211)
subscription-manager on RHEL installs a symlink in /usr/bin to console-helper (part of usermode), which triggers an interactive prompt for root credentials when run as user. It seems that console-helper does not handle well non-interactive contexts (e.g. without a TTY for input), and thus it will hang waiting for input when run as user in an Ansible task. Since subscription-manager requires root already anyway (and it will fail when explicitly run as user), then apply the same logic locally on all the modules that interact with it: redhat_subscription, rhsm_release, and rhsm_repository.pull/5664/head
parent
512bf4b77f
commit
9f67cbbe36
|
@ -0,0 +1,6 @@
|
||||||
|
bugfixes:
|
||||||
|
- redhat_subscription, rhsm_release, rhsm_repository - cleanly fail when not running as root,
|
||||||
|
rather than hanging on an interactive ``console-helper`` prompt; they all interact with
|
||||||
|
``subscription-manager``, which already requires to be run as root
|
||||||
|
(https://github.com/ansible-collections/community.general/issues/734,
|
||||||
|
https://github.com/ansible-collections/community.general/pull/6211).
|
|
@ -24,6 +24,8 @@ notes:
|
||||||
I(server_proxy_hostname), I(server_proxy_port), I(server_proxy_user) and
|
I(server_proxy_hostname), I(server_proxy_port), I(server_proxy_user) and
|
||||||
I(server_proxy_password) are no longer taken from the C(/etc/rhsm/rhsm.conf)
|
I(server_proxy_password) are no longer taken from the C(/etc/rhsm/rhsm.conf)
|
||||||
config file and default to None.
|
config file and default to None.
|
||||||
|
- It is possible to interact with C(subscription-manager) only as root,
|
||||||
|
so root permissions are required to successfully run this module.
|
||||||
requirements:
|
requirements:
|
||||||
- subscription-manager
|
- subscription-manager
|
||||||
- Optionally the C(dbus) Python library; this is usually included in the OS
|
- Optionally the C(dbus) Python library; this is usually included in the OS
|
||||||
|
@ -291,7 +293,7 @@ subscribed_pool_ids:
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from os.path import isfile
|
from os.path import isfile
|
||||||
from os import unlink
|
from os import getuid, unlink
|
||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
import tempfile
|
import tempfile
|
||||||
|
@ -1074,6 +1076,11 @@ def main():
|
||||||
required_if=[['state', 'present', ['username', 'activationkey', 'token'], True]],
|
required_if=[['state', 'present', ['username', 'activationkey', 'token'], True]],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if getuid() != 0:
|
||||||
|
module.fail_json(
|
||||||
|
msg="Interacting with subscription-manager requires root permissions ('become: true')"
|
||||||
|
)
|
||||||
|
|
||||||
rhsm.module = module
|
rhsm.module = module
|
||||||
state = module.params['state']
|
state = module.params['state']
|
||||||
username = module.params['username']
|
username = module.params['username']
|
||||||
|
|
|
@ -18,6 +18,8 @@ notes:
|
||||||
- This module will fail on an unregistered system.
|
- This module will fail on an unregistered system.
|
||||||
Use the C(redhat_subscription) module to register a system
|
Use the C(redhat_subscription) module to register a system
|
||||||
prior to setting the RHSM release.
|
prior to setting the RHSM release.
|
||||||
|
- It is possible to interact with C(subscription-manager) only as root,
|
||||||
|
so root permissions are required to successfully run this module.
|
||||||
requirements:
|
requirements:
|
||||||
- Red Hat Enterprise Linux 6+ with subscription-manager installed
|
- Red Hat Enterprise Linux 6+ with subscription-manager installed
|
||||||
extends_documentation_fragment:
|
extends_documentation_fragment:
|
||||||
|
@ -63,6 +65,7 @@ current_release:
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
|
||||||
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
||||||
# Matches release-like values such as 7.2, 5.10, 6Server, 8
|
# Matches release-like values such as 7.2, 5.10, 6Server, 8
|
||||||
|
@ -109,6 +112,11 @@ def main():
|
||||||
supports_check_mode=True
|
supports_check_mode=True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if os.getuid() != 0:
|
||||||
|
module.fail_json(
|
||||||
|
msg="Interacting with subscription-manager requires root permissions ('become: true')"
|
||||||
|
)
|
||||||
|
|
||||||
target_release = module.params['release']
|
target_release = module.params['release']
|
||||||
|
|
||||||
# sanity check: the target release at least looks like a valid release
|
# sanity check: the target release at least looks like a valid release
|
||||||
|
|
|
@ -19,6 +19,8 @@ author: Giovanni Sciortino (@giovannisciortino)
|
||||||
notes:
|
notes:
|
||||||
- In order to manage RHSM repositories the system must be already registered
|
- In order to manage RHSM repositories the system must be already registered
|
||||||
to RHSM manually or using the Ansible C(redhat_subscription) module.
|
to RHSM manually or using the Ansible C(redhat_subscription) module.
|
||||||
|
- It is possible to interact with C(subscription-manager) only as root,
|
||||||
|
so root permissions are required to successfully run this module.
|
||||||
|
|
||||||
requirements:
|
requirements:
|
||||||
- subscription-manager
|
- subscription-manager
|
||||||
|
@ -100,9 +102,7 @@ def run_subscription_manager(module, arguments):
|
||||||
lang_env = dict(LANG='C', LC_ALL='C', LC_MESSAGES='C')
|
lang_env = dict(LANG='C', LC_ALL='C', LC_MESSAGES='C')
|
||||||
rc, out, err = module.run_command("%s %s" % (rhsm_bin, " ".join(arguments)), environ_update=lang_env)
|
rc, out, err = module.run_command("%s %s" % (rhsm_bin, " ".join(arguments)), environ_update=lang_env)
|
||||||
|
|
||||||
if rc == 1 and (err == 'The password you typed is invalid.\nPlease try again.\n' or os.getuid() != 0):
|
if rc == 0 and out == 'This system has no repositories available through subscriptions.\n':
|
||||||
module.fail_json(msg='The executable file subscription-manager must be run using root privileges')
|
|
||||||
elif rc == 0 and out == 'This system has no repositories available through subscriptions.\n':
|
|
||||||
module.fail_json(msg='This system has no repositories available through subscriptions')
|
module.fail_json(msg='This system has no repositories available through subscriptions')
|
||||||
elif rc == 1:
|
elif rc == 1:
|
||||||
module.fail_json(msg='subscription-manager failed with the following error: %s' % err)
|
module.fail_json(msg='subscription-manager failed with the following error: %s' % err)
|
||||||
|
@ -243,6 +243,12 @@ def main():
|
||||||
),
|
),
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if os.getuid() != 0:
|
||||||
|
module.fail_json(
|
||||||
|
msg="Interacting with subscription-manager requires root permissions ('become: true')"
|
||||||
|
)
|
||||||
|
|
||||||
name = module.params['name']
|
name = module.params['name']
|
||||||
state = module.params['state']
|
state = module.params['state']
|
||||||
purge = module.params['purge']
|
purge = module.params['purge']
|
||||||
|
|
|
@ -29,6 +29,8 @@ def patch_redhat_subscription(mocker):
|
||||||
return_value='/testbin/subscription-manager')
|
return_value='/testbin/subscription-manager')
|
||||||
mocker.patch('ansible_collections.community.general.plugins.modules.redhat_subscription.Rhsm._can_connect_to_dbus',
|
mocker.patch('ansible_collections.community.general.plugins.modules.redhat_subscription.Rhsm._can_connect_to_dbus',
|
||||||
return_value=False)
|
return_value=False)
|
||||||
|
mocker.patch('ansible_collections.community.general.plugins.modules.redhat_subscription.getuid',
|
||||||
|
return_value=0)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('patch_ansible_module', [{}], indirect=['patch_ansible_module'])
|
@pytest.mark.parametrize('patch_ansible_module', [{}], indirect=['patch_ansible_module'])
|
||||||
|
|
|
@ -30,9 +30,16 @@ class RhsmRepositoryReleaseModuleTestCase(ModuleTestCase):
|
||||||
self.get_bin_path = self.mock_get_bin_path.start()
|
self.get_bin_path = self.mock_get_bin_path.start()
|
||||||
self.get_bin_path.return_value = '/testbin/subscription-manager'
|
self.get_bin_path.return_value = '/testbin/subscription-manager'
|
||||||
|
|
||||||
|
# subscription-manager needs to be run as root
|
||||||
|
self.mock_os_getuid = patch('ansible_collections.community.general.plugins.modules.rhsm_release.'
|
||||||
|
'os.getuid')
|
||||||
|
self.os_getuid = self.mock_os_getuid.start()
|
||||||
|
self.os_getuid.return_value = 0
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
self.mock_run_command.stop()
|
self.mock_run_command.stop()
|
||||||
self.mock_get_bin_path.stop()
|
self.mock_get_bin_path.stop()
|
||||||
|
self.mock_os_getuid.stop()
|
||||||
super(RhsmRepositoryReleaseModuleTestCase, self).tearDown()
|
super(RhsmRepositoryReleaseModuleTestCase, self).tearDown()
|
||||||
|
|
||||||
def module_main(self, exit_exc):
|
def module_main(self, exit_exc):
|
||||||
|
|
Loading…
Reference in New Issue