ipa_client_automount.py and ipactl.py: fix codestyle

Updating ipa_client_automount.py and ipactl.py's codestyle is
mandatory to make pylint pass as these are considered new files.

Fixes: https://pagure.io/freeipa/issue/7984
Signed-off-by: François Cami <fcami@redhat.com>
Reviewed-By: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
This commit is contained in:
François Cami
2019-06-26 18:03:17 +02:00
parent c0cf65c4f7
commit b49c627aa6
2 changed files with 345 additions and 165 deletions

View File

@@ -1,9 +1,8 @@
#!/usr/bin/python3
# #
# Authors: # Authors:
# Rob Crittenden <rcritten@redhat.com> # Rob Crittenden <rcritten@redhat.com>
# #
# Copyright (C) 2012 Red Hat # Copyright (C) 2012, 2019 Red Hat
# see file 'COPYING' for use and warranty information # see file 'COPYING' for use and warranty information
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
@@ -30,18 +29,23 @@ import shutil
import time import time
import tempfile import tempfile
import gssapi import gssapi
try: try:
from xml.etree import cElementTree as etree from xml.etree import cElementTree as etree
except ImportError: except ImportError:
from xml.etree import ElementTree as etree from xml.etree import ElementTree as etree
import SSSDConfig import SSSDConfig
# pylint: disable=import-error # pylint: disable=import-error
from six.moves.urllib.parse import urlsplit from six.moves.urllib.parse import urlsplit
# pylint: enable=import-error # pylint: enable=import-error
from optparse import OptionParser # pylint: disable=deprecated-module from optparse import OptionParser # pylint: disable=deprecated-module
from ipaclient.install import ipachangeconf, ipadiscovery from ipaclient.install import ipachangeconf, ipadiscovery
from ipaclient.install.client import (CLIENT_NOT_CONFIGURED, from ipaclient.install.client import (
CLIENT_ALREADY_CONFIGURED) CLIENT_NOT_CONFIGURED,
CLIENT_ALREADY_CONFIGURED,
)
from ipalib import api, errors from ipalib import api, errors
from ipalib.install import sysrestore from ipalib.install import sysrestore
from ipalib.install.kinit import kinit_keytab from ipalib.install.kinit import kinit_keytab
@@ -62,38 +66,54 @@ logger = logging.getLogger(os.path.basename(__file__))
def parse_options(): def parse_options():
usage = "%prog [options]\n" usage = "%prog [options]\n"
parser = OptionParser(usage=usage) parser = OptionParser(usage=usage)
parser.add_option("--server", dest="server", help="FQDN of IPA server")
parser.add_option( parser.add_option(
"--server", dest="server", help="FQDN of IPA server" "--location",
dest="location",
default="default",
help="Automount location",
) )
parser.add_option( parser.add_option(
"--location", dest="location", default="default", "-S",
help="Automount location" "--no-sssd",
dest="sssd",
action="store_false",
default=True,
help="Do not configure the client to use SSSD for automount",
) )
parser.add_option( parser.add_option(
"-S", "--no-sssd", dest="sssd", action="store_false", default=True, "--idmap-domain",
help="Do not configure the client to use SSSD for automount" dest="idmapdomain",
default=None,
help="nfs domain for idmap.conf",
) )
parser.add_option( parser.add_option(
"--idmap-domain", dest="idmapdomain", default=None, "--debug",
help="nfs domain for idmap.conf" dest="debug",
) action="store_true",
parser.add_option(
"--debug", dest="debug", action="store_true", default=False,
help="enable debugging"
)
parser.add_option(
"-U", "--unattended", dest="unattended", action="store_true",
default=False, default=False,
help="unattended installation never prompts the user" help="enable debugging",
) )
parser.add_option( parser.add_option(
"--uninstall", dest="uninstall", action="store_true", default=False, "-U",
help="Unconfigure automount" "--unattended",
dest="unattended",
action="store_true",
default=False,
help="unattended installation never prompts the user",
)
parser.add_option(
"--uninstall",
dest="uninstall",
action="store_true",
default=False,
help="Unconfigure automount",
) )
options, args = parser.parse_args() options, args = parser.parse_args()
return options, args return options, args
def wait_for_sssd(): def wait_for_sssd():
""" """
It takes a bit for sssd to get going, lets loop until it is It takes a bit for sssd to get going, lets loop until it is
@@ -114,11 +134,17 @@ def wait_for_sssd():
# This should never happen but if it does, may as well warn the user # This should never happen but if it does, may as well warn the user
if not found: if not found:
err_msg = ("Unable to find 'admin' user with " err_msg = (
"'getent passwd admin@%s'!" % api.env.realm) "Unable to find 'admin' user with "
"'getent passwd admin@%s'!" % api.env.realm
)
logger.debug('%s', err_msg) logger.debug('%s', err_msg)
print(err_msg) print(err_msg)
print("This may mean that sssd didn't re-start properly after the configuration changes.") print(
"This may mean that sssd didn't re-start properly after "
"the configuration changes."
)
def configure_xml(fstore): def configure_xml(fstore):
authconf = paths.AUTOFS_LDAP_AUTH_CONF authconf = paths.AUTOFS_LDAP_AUTH_CONF
@@ -150,6 +176,7 @@ def configure_xml(fstore):
else: else:
print("Configured %s" % authconf) print("Configured %s" % authconf)
def configure_nsswitch(fstore, options): def configure_nsswitch(fstore, options):
""" """
Point automount to ldap in nsswitch.conf. This function is for non-SSSD Point automount to ldap in nsswitch.conf. This function is for non-SSSD
@@ -162,13 +189,21 @@ def configure_nsswitch(fstore, options):
nss_value = ' files ldap' nss_value = ' files ldap'
opts = [{'name':'automount', 'type':'option', 'action':'set', 'value':nss_value}, opts = [
{'name':'empty', 'type':'empty'}] {
'name': 'automount',
'type': 'option',
'action': 'set',
'value': nss_value,
},
{'name': 'empty', 'type': 'empty'},
]
conf.changeConf(paths.NSSWITCH_CONF, opts) conf.changeConf(paths.NSSWITCH_CONF, opts)
print("Configured %s" % paths.NSSWITCH_CONF) print("Configured %s" % paths.NSSWITCH_CONF)
def configure_autofs_sssd(fstore, statestore, autodiscover, options): def configure_autofs_sssd(fstore, statestore, autodiscover, options):
try: try:
sssdconfig = SSSDConfig.SSSDConfig() sssdconfig = SSSDConfig.SSSDConfig()
@@ -185,9 +220,11 @@ def configure_autofs_sssd(fstore, statestore, autodiscover, options):
logger.error("Unable to activate the Autofs service in SSSD config.") logger.error("Unable to activate the Autofs service in SSSD config.")
logger.info( logger.info(
"Please make sure you have SSSD built with autofs support " "Please make sure you have SSSD built with autofs support "
"installed.") "installed."
)
logger.info( logger.info(
"Configure autofs support manually in /etc/sssd/sssd.conf.") "Configure autofs support manually in /etc/sssd/sssd.conf."
)
sys.exit("Cannot create the autofs service in sssd.conf") sys.exit("Cannot create the autofs service in sssd.conf")
sssdconfig.activate_service('autofs') sssdconfig.activate_service('autofs')
@@ -221,6 +258,7 @@ def configure_autofs_sssd(fstore, statestore, autodiscover, options):
print("Restarting sssd, waiting for it to become available.") print("Restarting sssd, waiting for it to become available.")
wait_for_sssd() wait_for_sssd()
def configure_autofs(fstore, statestore, autodiscover, server, options): def configure_autofs(fstore, statestore, autodiscover, server, options):
""" """
fstore: the FileStore to back up files in fstore: the FileStore to back up files in
@@ -232,7 +270,13 @@ def configure_autofs(fstore, statestore, autodiscover, server, options):
else: else:
ldap_uri = "ldap:///%s" % api.env.basedn ldap_uri = "ldap:///%s" % api.env.basedn
search_base = str(DN(('cn', options.location), api.env.container_automount, api.env.basedn)) search_base = str(
DN(
('cn', options.location),
api.env.container_automount,
api.env.basedn,
)
)
replacevars = { replacevars = {
'MAP_OBJECT_CLASS': 'automountMap', 'MAP_OBJECT_CLASS': 'automountMap',
'ENTRY_OBJECT_CLASS': 'automount', 'ENTRY_OBJECT_CLASS': 'automount',
@@ -243,13 +287,15 @@ def configure_autofs(fstore, statestore, autodiscover, server, options):
'LDAP_URI': ldap_uri, 'LDAP_URI': ldap_uri,
} }
ipautil.backup_config_and_replace_variables(fstore, ipautil.backup_config_and_replace_variables(
paths.SYSCONFIG_AUTOFS, replacevars=replacevars) fstore, paths.SYSCONFIG_AUTOFS, replacevars=replacevars
)
tasks.restore_context(paths.SYSCONFIG_AUTOFS) tasks.restore_context(paths.SYSCONFIG_AUTOFS)
statestore.backup_state('autofs', 'sssd', False) statestore.backup_state('autofs', 'sssd', False)
print("Configured %s" % paths.SYSCONFIG_AUTOFS) print("Configured %s" % paths.SYSCONFIG_AUTOFS)
def configure_autofs_common(fstore, statestore, options): def configure_autofs_common(fstore, statestore, options):
autofs = services.knownservices.autofs autofs = services.knownservices.autofs
statestore.backup_state('autofs', 'enabled', autofs.is_enabled()) statestore.backup_state('autofs', 'enabled', autofs.is_enabled())
@@ -262,28 +308,37 @@ def configure_autofs_common(fstore, statestore, options):
try: try:
autofs.enable() autofs.enable()
except Exception as e: except Exception as e:
print("Failed to configure automatic startup of the %s daemon" % (autofs.service_name)) print(
logger.error("Failed to enable automatic startup of the %s daemon: %s", "Failed to configure automatic startup of the %s daemon"
autofs.service_name, str(e)) % (autofs.service_name)
)
logger.error(
"Failed to enable automatic startup of the %s daemon: %s",
autofs.service_name,
str(e),
)
def uninstall(fstore, statestore): def uninstall(fstore, statestore):
RESTORE_FILES=[ RESTORE_FILES = [
paths.SYSCONFIG_AUTOFS, paths.SYSCONFIG_AUTOFS,
paths.NSSWITCH_CONF, paths.NSSWITCH_CONF,
paths.AUTOFS_LDAP_AUTH_CONF, paths.AUTOFS_LDAP_AUTH_CONF,
paths.SYSCONFIG_NFS, paths.SYSCONFIG_NFS,
paths.IDMAPD_CONF, paths.IDMAPD_CONF,
] ]
STATES=['autofs', 'rpcidmapd', 'rpcgssd'] STATES = ['autofs', 'rpcidmapd', 'rpcgssd']
# automount only touches /etc/nsswitch.conf if LDAP is # automount only touches /etc/nsswitch.conf if LDAP is
# used. Don't restore it otherwise. # used. Don't restore it otherwise.
if (statestore.get_state('authconfig', 'sssd') or if statestore.get_state('authconfig', 'sssd') or (
(statestore.get_state('authselect', 'profile') == 'sssd')): statestore.get_state('authselect', 'profile') == 'sssd'
):
RESTORE_FILES.remove(paths.NSSWITCH_CONF) RESTORE_FILES.remove(paths.NSSWITCH_CONF)
if (not any(fstore.has_file(f) for f in RESTORE_FILES) or if not any(fstore.has_file(f) for f in RESTORE_FILES) or not any(
not any(statestore.has_state(s) for s in STATES)): statestore.has_state(s) for s in STATES
):
print("IPA automount is not configured on this system") print("IPA automount is not configured on this system")
return CLIENT_NOT_CONFIGURED return CLIENT_NOT_CONFIGURED
@@ -325,15 +380,16 @@ def uninstall(fstore, statestore):
except Exception as e: except Exception as e:
print('Unable to restore SSSD configuration: %s' % str(e)) print('Unable to restore SSSD configuration: %s' % str(e))
logger.debug( logger.debug(
'Unable to restore SSSD configuration: %s', str(e)) 'Unable to restore SSSD configuration: %s', str(e)
)
# rpcidmapd and rpcgssd are static units now # rpcidmapd and rpcgssd are static units now
if statestore.has_state('rpcidmapd'): if statestore.has_state('rpcidmapd'):
statestore.delete_state('rpcidmapd','enabled') statestore.delete_state('rpcidmapd', 'enabled')
statestore.delete_state('rpcidmapd','running') statestore.delete_state('rpcidmapd', 'running')
if statestore.has_state('rpcgssd'): if statestore.has_state('rpcgssd'):
statestore.delete_state('rpcgssd','enabled') statestore.delete_state('rpcgssd', 'enabled')
statestore.delete_state('rpcgssd','running') statestore.delete_state('rpcgssd', 'running')
nfsutils = services.knownservices['nfs-utils'] nfsutils = services.knownservices['nfs-utils']
try: try:
@@ -343,6 +399,7 @@ def uninstall(fstore, statestore):
return 1 return 1
return 0 return 0
def configure_nfs(fstore, statestore, options): def configure_nfs(fstore, statestore, options):
""" """
Configure secure NFS Configure secure NFS
@@ -350,11 +407,10 @@ def configure_nfs(fstore, statestore, options):
# Newer Fedora releases ship /etc/nfs.conf instead of /etc/sysconfig/nfs # Newer Fedora releases ship /etc/nfs.conf instead of /etc/sysconfig/nfs
# and do not require changes there. On these, SECURE_NFS_VAR == None # and do not require changes there. On these, SECURE_NFS_VAR == None
if constants.SECURE_NFS_VAR: if constants.SECURE_NFS_VAR:
replacevars = { replacevars = {constants.SECURE_NFS_VAR: 'yes'}
constants.SECURE_NFS_VAR: 'yes', ipautil.backup_config_and_replace_variables(
} fstore, paths.SYSCONFIG_NFS, replacevars=replacevars
ipautil.backup_config_and_replace_variables(fstore, )
paths.SYSCONFIG_NFS, replacevars=replacevars)
tasks.restore_context(paths.SYSCONFIG_NFS) tasks.restore_context(paths.SYSCONFIG_NFS)
print("Configured %s" % paths.SYSCONFIG_NFS) print("Configured %s" % paths.SYSCONFIG_NFS)
@@ -395,7 +451,8 @@ def configure_nfs(fstore, statestore, options):
except Exception as e: except Exception as e:
logger.error("Failed to restart nfs client services (%s)", str(e)) logger.error("Failed to restart nfs client services (%s)", str(e))
def main():
def configure_automount():
try: try:
check_client_configuration() check_client_configuration()
except ScriptError as e: except ScriptError as e:
@@ -408,8 +465,12 @@ def main():
options, _args = parse_options() options, _args = parse_options()
standard_logging_setup( standard_logging_setup(
paths.IPACLIENT_INSTALL_LOG, verbose=False, debug=options.debug, paths.IPACLIENT_INSTALL_LOG,
filemode='a', console_format='%(message)s') verbose=False,
debug=options.debug,
filemode='a',
console_format='%(message)s',
)
cfg = dict( cfg = dict(
context='cli_installer', context='cli_installer',
@@ -447,9 +508,13 @@ def main():
else: else:
autodiscover = True autodiscover = True
if not ds.servers: if not ds.servers:
sys.exit('Autodiscovery was successful but didn\'t return a server') sys.exit(
logger.debug('Autodiscovery success, possible servers %s', 'Autodiscovery was successful but didn\'t return a server'
','.join(ds.servers)) )
logger.debug(
'Autodiscovery success, possible servers %s',
','.join(ds.servers),
)
server = ds.servers[0] server = ds.servers[0]
else: else:
server = options.server server = options.server
@@ -458,7 +523,10 @@ def main():
if ldapret[0] == ipadiscovery.NO_ACCESS_TO_LDAP: if ldapret[0] == ipadiscovery.NO_ACCESS_TO_LDAP:
print("Anonymous access to the LDAP server is disabled.") print("Anonymous access to the LDAP server is disabled.")
print("Proceeding without strict verification.") print("Proceeding without strict verification.")
print("Note: This is not an error if anonymous access has been explicitly restricted.") print(
"Note: This is not an error if anonymous access has been "
"explicitly restricted."
)
elif ldapret[0] == ipadiscovery.NO_TLS_LDAP: elif ldapret[0] == ipadiscovery.NO_TLS_LDAP:
logger.warning("Unencrypted access to LDAP is not supported.") logger.warning("Unencrypted access to LDAP is not supported.")
elif ldapret[0] != 0: elif ldapret[0] != 0:
@@ -502,13 +570,20 @@ def main():
except errors.VersionError as e: except errors.VersionError as e:
sys.exit('This client is incompatible: ' + str(e)) sys.exit('This client is incompatible: ' + str(e))
except errors.NotFound: except errors.NotFound:
sys.exit("Automount location '%s' does not exist" % options.location) sys.exit(
"Automount location '%s' does not exist" % options.location
)
except errors.PublicError as e: except errors.PublicError as e:
sys.exit("Cannot connect to the server due to generic error: %s" % str(e)) sys.exit(
"Cannot connect to the server due to generic error: %s"
% str(e)
)
finally: finally:
shutil.rmtree(ccache_dir) shutil.rmtree(ccache_dir)
if not options.unattended and not ipautil.user_input("Continue to configure the system with these values?", False): if not options.unattended and not ipautil.user_input(
"Continue to configure the system with these values?", False
):
sys.exit("Installation aborted") sys.exit("Installation aborted")
try: try:
@@ -519,7 +594,9 @@ def main():
configure_autofs_sssd(fstore, statestore, autodiscover, options) configure_autofs_sssd(fstore, statestore, autodiscover, options)
else: else:
configure_xml(fstore) configure_xml(fstore)
configure_autofs(fstore, statestore, autodiscover, server, options) configure_autofs(
fstore, statestore, autodiscover, server, options
)
configure_autofs_common(fstore, statestore, options) configure_autofs_common(fstore, statestore, options)
except Exception as e: except Exception as e:
logger.debug('Raised exception %s', e) logger.debug('Raised exception %s', e)
@@ -529,14 +606,15 @@ def main():
return 0 return 0
try:
if not os.geteuid()==0:
sys.exit("\nMust be run as root\n")
sys.exit(main()) def main():
except SystemExit as e: try:
if not os.geteuid() == 0:
sys.exit("\nMust be run as root\n")
configure_automount()
except SystemExit as e:
sys.exit(e) sys.exit(e)
except RuntimeError as e: except RuntimeError as e:
sys.exit(e) sys.exit(e)
except (KeyboardInterrupt, EOFError): except (KeyboardInterrupt, EOFError):
sys.exit(1) sys.exit(1)

View File

@@ -1,7 +1,6 @@
#!/usr/bin/python3
# Authors: Simo Sorce <ssorce@redhat.com> # Authors: Simo Sorce <ssorce@redhat.com>
# #
# Copyright (C) 2008-2010 Red Hat # Copyright (C) 2008-2019 Red Hat
# see file 'COPYING' for use and warranty information # see file 'COPYING' for use and warranty information
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
@@ -49,11 +48,16 @@ MSG_HINT_IGNORE_SERVICE_FAILURE = (
class IpactlError(ScriptError): class IpactlError(ScriptError):
pass pass
def check_IPA_configuration(): def check_IPA_configuration():
if not is_ipa_configured(): if not is_ipa_configured():
# LSB status code 6: program is not configured # LSB status code 6: program is not configured
raise IpactlError("IPA is not configured " + raise IpactlError(
"(see man pages of ipa-server-install for help)", 6) "IPA is not configured "
"(see man pages of ipa-server-install for help)",
6,
)
def deduplicate(lst): def deduplicate(lst):
"""Remove duplicates and preserve order. """Remove duplicates and preserve order.
@@ -68,6 +72,7 @@ def deduplicate(lst):
return new_lst return new_lst
def is_dirsrv_debugging_enabled(): def is_dirsrv_debugging_enabled():
""" """
Check the 389-ds instance to see if debugging is enabled. Check the 389-ds instance to see if debugging is enabled.
@@ -80,48 +85,68 @@ def is_dirsrv_debugging_enabled():
dselist = [config_dirname(serverid)] dselist = [config_dirname(serverid)]
for dse in dselist: for dse in dselist:
try: try:
fd = open(dse + 'dse.ldif', 'r') fd = open(dse + "dse.ldif", "r")
except IOError: except IOError:
continue continue
lines = fd.readlines() lines = fd.readlines()
fd.close() fd.close()
for line in lines: for line in lines:
if line.lower().startswith('nsslapd-errorlog-level'): if line.lower().startswith("nsslapd-errorlog-level"):
_option, value = line.split(':') _option, value = line.split(":")
if int(value) > 0: if int(value) > 0:
debugging = True debugging = True
return debugging return debugging
def get_capture_output(service, debug): def get_capture_output(service, debug):
""" """
We want to display any output of a start/stop command with the We want to display any output of a start/stop command with the
exception of 389-ds when debugging is enabled because it outputs exception of 389-ds when debugging is enabled because it outputs
tons and tons of information. tons and tons of information.
""" """
if service == 'dirsrv' and not debug and is_dirsrv_debugging_enabled(): if service == "dirsrv" and not debug and is_dirsrv_debugging_enabled():
print(' debugging enabled, suppressing output.') print(" debugging enabled, suppressing output.")
return True return True
else: else:
return False return False
def parse_options(): def parse_options():
usage = "%prog start|stop|restart|status\n" usage = "%prog start|stop|restart|status\n"
parser = config.IPAOptionParser(usage=usage, parser = config.IPAOptionParser(
formatter=config.IPAFormatter()) usage=usage, formatter=config.IPAFormatter()
)
parser.add_option("-d", "--debug", action="store_true", dest="debug", parser.add_option(
help="Display debugging information") "-d",
parser.add_option("-f", "--force", action="store_true", dest="force", "--debug",
action="store_true",
dest="debug",
help="Display debugging information",
)
parser.add_option(
"-f",
"--force",
action="store_true",
dest="force",
help="Force IPA to start. Combine options " help="Force IPA to start. Combine options "
"--skip-version-check and --ignore-service-failures") "--skip-version-check and --ignore-service-failures",
parser.add_option("--ignore-service-failures", action="store_true", )
parser.add_option(
"--ignore-service-failures",
action="store_true",
dest="ignore_service_failures", dest="ignore_service_failures",
help="If any service start fails, do not rollback the " help="If any service start fails, do not rollback the "
"services, continue with the operation") "services, continue with the operation",
parser.add_option("--skip-version-check", action="store_true", )
dest="skip_version_check", default=False, parser.add_option(
help="skip version check") "--skip-version-check",
action="store_true",
dest="skip_version_check",
default=False,
help="skip version check",
)
options, args = parser.parse_args() options, args = parser.parse_args()
safe_options = parser.get_safe_opts(options) safe_options = parser.get_safe_opts(options)
@@ -132,62 +157,85 @@ def parse_options():
return safe_options, options, args return safe_options, options, args
def emit_err(err): def emit_err(err):
sys.stderr.write(err + '\n') sys.stderr.write(err + "\n")
def version_check(): def version_check():
try: try:
installutils.check_version() installutils.check_version()
except (installutils.UpgradeMissingVersionError, except (
installutils.UpgradeDataOlderVersionError) as exc: installutils.UpgradeMissingVersionError,
installutils.UpgradeDataOlderVersionError,
) as exc:
emit_err("IPA version error: %s" % exc) emit_err("IPA version error: %s" % exc)
except installutils.UpgradeVersionError as e: except installutils.UpgradeVersionError as e:
emit_err("IPA version error: %s" % e) emit_err("IPA version error: %s" % e)
else: else:
return return
emit_err("Automatically running upgrade, for details see {}".format( emit_err(
paths.IPAUPGRADE_LOG)) "Automatically running upgrade, for details see {}".format(
paths.IPAUPGRADE_LOG
)
)
emit_err("Be patient, this may take a few minutes.") emit_err("Be patient, this may take a few minutes.")
# Fork out to call ipa-server-upgrade so that logging is sane. # Fork out to call ipa-server-upgrade so that logging is sane.
result = run([paths.IPA_SERVER_UPGRADE], raiseonerr=False, result = run(
capture_error=True) [paths.IPA_SERVER_UPGRADE], raiseonerr=False, capture_error=True
)
if result.returncode != 0: if result.returncode != 0:
emit_err("Automatic upgrade failed: %s" % result.error_output) emit_err("Automatic upgrade failed: %s" % result.error_output)
emit_err("See the upgrade log for more details and/or run {} again". emit_err(
format(paths.IPA_SERVER_UPGRADE)) "See the upgrade log for more details and/or run {} again".format(
paths.IPA_SERVER_UPGRADE
)
)
raise IpactlError("Aborting ipactl") raise IpactlError("Aborting ipactl")
def get_config(dirsrv): def get_config(dirsrv):
base = DN(('cn', api.env.host), ('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn) base = DN(
("cn", api.env.host),
("cn", "masters"),
("cn", "ipa"),
("cn", "etc"),
api.env.basedn,
)
srcfilter = LDAPClient.combine_filters( srcfilter = LDAPClient.combine_filters(
[ [
LDAPClient.make_filter({'objectClass': 'ipaConfigObject'}), LDAPClient.make_filter({"objectClass": "ipaConfigObject"}),
LDAPClient.make_filter( LDAPClient.make_filter(
{'ipaConfigString': [ENABLED_SERVICE, HIDDEN_SERVICE]}, {"ipaConfigString": [ENABLED_SERVICE, HIDDEN_SERVICE]},
rules=LDAPClient.MATCH_ANY rules=LDAPClient.MATCH_ANY,
), ),
], ],
rules=LDAPClient.MATCH_ALL rules=LDAPClient.MATCH_ALL,
) )
attrs = ['cn', 'ipaConfigString'] attrs = ["cn", "ipaConfigString"]
if not dirsrv.is_running(): if not dirsrv.is_running():
raise IpactlError("Failed to get list of services to probe status:\n" + raise IpactlError(
"Directory Server is stopped", 3) "Failed to get list of services to probe status:\n"
"Directory Server is stopped",
3,
)
try: try:
# The start/restart functions already wait for the server to be # The start/restart functions already wait for the server to be
# started. What we are doing with this wait is really checking to see # started. What we are doing with this wait is really checking to see
# if the server is listening at all. # if the server is listening at all.
lurl = ldapurl.LDAPUrl(api.env.ldap_uri) lurl = ldapurl.LDAPUrl(api.env.ldap_uri)
if lurl.urlscheme == 'ldapi': if lurl.urlscheme == "ldapi":
wait_for_open_socket(lurl.hostport, timeout=api.env.startup_timeout) wait_for_open_socket(
lurl.hostport, timeout=api.env.startup_timeout
)
else: else:
(host, port) = lurl.hostport.split(':') (host, port) = lurl.hostport.split(":")
wait_for_open_ports(host, [int(port)], timeout=api.env.startup_timeout) wait_for_open_ports(
host, [int(port)], timeout=api.env.startup_timeout
)
con = LDAPClient(api.env.ldap_uri) con = LDAPClient(api.env.ldap_uri)
con.external_bind() con.external_bind()
res = con.get_entries( res = con.get_entries(
@@ -195,42 +243,59 @@ def get_config(dirsrv):
filter=srcfilter, filter=srcfilter,
attrs_list=attrs, attrs_list=attrs,
scope=con.SCOPE_SUBTREE, scope=con.SCOPE_SUBTREE,
time_limit=10) time_limit=10,
)
except errors.NetworkError: except errors.NetworkError:
# LSB status code 3: program is not running # LSB status code 3: program is not running
raise IpactlError("Failed to get list of services to probe status:\n" + raise IpactlError(
"Directory Server is stopped", 3) "Failed to get list of services to probe status:\n"
"Directory Server is stopped",
3,
)
except errors.NotFound: except errors.NotFound:
masters_list = [] masters_list = []
dn = DN(('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn) dn = DN(
attrs = ['cn'] ("cn", "masters"), ("cn", "ipa"), ("cn", "etc"), api.env.basedn
)
attrs = ["cn"]
try: try:
entries = con.get_entries(dn, con.SCOPE_ONELEVEL, attrs_list=attrs) entries = con.get_entries(
dn, con.SCOPE_ONELEVEL, attrs_list=attrs
)
except Exception as e: except Exception as e:
masters_list.append("No master found because of error: %s" % str(e)) masters_list.append(
"No master found because of error: %s" % str(e)
)
else: else:
for master_entry in entries: for master_entry in entries:
masters_list.append(master_entry.single_value['cn']) masters_list.append(master_entry.single_value["cn"])
masters = "\n".join(masters_list) masters = "\n".join(masters_list)
raise IpactlError("Failed to get list of services to probe status!\n" raise IpactlError(
"Configured hostname '%s' does not match any master server in LDAP:\n%s" "Failed to get list of services to probe status!\n"
% (api.env.host, masters)) "Configured hostname '%s' does not match any master server in "
"LDAP:\n%s"
% (api.env.host, masters)
)
except Exception as e: except Exception as e:
raise IpactlError("Unknown error when retrieving list of services from LDAP: " + str(e)) raise IpactlError(
"Unknown error when retrieving list of services from LDAP: %s"
% str(e)
)
svc_list = [] svc_list = []
for entry in res: for entry in res:
name = entry.single_value['cn'] name = entry.single_value["cn"]
for p in entry['ipaConfigString']: for p in entry["ipaConfigString"]:
if p.startswith('startOrder '): if p.startswith("startOrder "):
try: try:
order = int(p.split()[1]) order = int(p.split()[1])
except ValueError: except ValueError:
raise IpactlError("Expected order as integer in: %s:%s" % ( raise IpactlError(
name, p)) "Expected order as integer in: %s:%s" % (name, p)
)
svc_list.append([order, name]) svc_list.append([order, name])
ordered_list = [] ordered_list = []
@@ -239,15 +304,19 @@ def get_config(dirsrv):
ordered_list.append(service.SERVICE_LIST[svc].systemd_name) ordered_list.append(service.SERVICE_LIST[svc].systemd_name)
return deduplicate(ordered_list) return deduplicate(ordered_list)
def get_config_from_file(): def get_config_from_file():
svc_list = [] svc_list = []
try: try:
f = open(tasks.get_svc_list_file(), 'r') f = open(tasks.get_svc_list_file(), "r")
svc_list = json.load(f) svc_list = json.load(f)
except Exception as e: except Exception as e:
raise IpactlError("Unknown error when retrieving list of services from file: " + str(e)) raise IpactlError(
"Unknown error when retrieving list of services from file: %s"
% str(e)
)
# the framework can start/stop a number of related services we are not # the framework can start/stop a number of related services we are not
# authoritative for, so filter the list through SERVICES_LIST and order it # authoritative for, so filter the list through SERVICES_LIST and order it
@@ -302,7 +371,9 @@ def ipa_start(options):
dirsrv = services.knownservices.dirsrv dirsrv = services.knownservices.dirsrv
try: try:
print("Starting Directory Service") print("Starting Directory Service")
dirsrv.start(capture_output=get_capture_output('dirsrv', options.debug)) dirsrv.start(
capture_output=get_capture_output("dirsrv", options.debug)
)
except Exception as e: except Exception as e:
raise IpactlError("Failed to start Directory Service: " + str(e)) raise IpactlError("Failed to start Directory Service: " + str(e))
@@ -329,13 +400,19 @@ def ipa_start(options):
svchandle = services.service(svc, api=api) svchandle = services.service(svc, api=api)
try: try:
print("Starting %s Service" % svc) print("Starting %s Service" % svc)
svchandle.start(capture_output=get_capture_output(svc, options.debug)) svchandle.start(
capture_output=get_capture_output(svc, options.debug)
)
except Exception: except Exception:
emit_err("Failed to start %s Service" % svc) emit_err("Failed to start %s Service" % svc)
# if ignore_service_failures is specified, skip rollback and # if ignore_service_failures is specified, skip rollback and
# continue with the next service # continue with the next service
if options.ignore_service_failures: if options.ignore_service_failures:
emit_err("Forced start, ignoring %s Service, continuing normal operation" % svc) emit_err(
"Forced start, ignoring %s Service, "
"continuing normal operation"
% svc
)
continue continue
emit_err("Shutting down") emit_err("Shutting down")
@@ -345,6 +422,7 @@ def ipa_start(options):
emit_err(MSG_HINT_IGNORE_SERVICE_FAILURE) emit_err(MSG_HINT_IGNORE_SERVICE_FAILURE)
raise IpactlError("Aborting ipactl") raise IpactlError("Aborting ipactl")
def ipa_stop(options): def ipa_stop(options):
dirsrv = services.knownservices.dirsrv dirsrv = services.knownservices.dirsrv
try: try:
@@ -406,7 +484,9 @@ def ipa_restart(options):
if not dirsrv.is_running(): if not dirsrv.is_running():
try: try:
print("Starting Directory Service") print("Starting Directory Service")
dirsrv.start(capture_output=get_capture_output('dirsrv', options.debug)) dirsrv.start(
capture_output=get_capture_output("dirsrv", options.debug)
)
dirsrv_restart = False dirsrv_restart = False
except Exception as e: except Exception as e:
raise IpactlError("Failed to start Directory Service: " + str(e)) raise IpactlError("Failed to start Directory Service: " + str(e))
@@ -440,7 +520,7 @@ def ipa_restart(options):
if s in old_svc_list: if s in old_svc_list:
svc_list.append(s) svc_list.append(s)
#remove commons # remove commons
for s in svc_list: for s in svc_list:
if s in old_svc_list: if s in old_svc_list:
old_svc_list.remove(s) old_svc_list.remove(s)
@@ -461,7 +541,9 @@ def ipa_restart(options):
try: try:
if dirsrv_restart: if dirsrv_restart:
print("Restarting Directory Service") print("Restarting Directory Service")
dirsrv.restart(capture_output=get_capture_output('dirsrv', options.debug)) dirsrv.restart(
capture_output=get_capture_output("dirsrv", options.debug)
)
except Exception as e: except Exception as e:
emit_err("Failed to restart Directory Service: " + str(e)) emit_err("Failed to restart Directory Service: " + str(e))
emit_err("Shutting down") emit_err("Shutting down")
@@ -478,13 +560,19 @@ def ipa_restart(options):
svchandle = services.service(svc, api=api) svchandle = services.service(svc, api=api)
try: try:
print("Restarting %s Service" % svc) print("Restarting %s Service" % svc)
svchandle.restart(capture_output=get_capture_output(svc, options.debug)) svchandle.restart(
capture_output=get_capture_output(svc, options.debug)
)
except Exception: except Exception:
emit_err("Failed to restart %s Service" % svc) emit_err("Failed to restart %s Service" % svc)
# if ignore_service_failures is specified, # if ignore_service_failures is specified,
# skip rollback and continue with the next service # skip rollback and continue with the next service
if options.ignore_service_failures: if options.ignore_service_failures:
emit_err("Forced restart, ignoring %s Service, continuing normal operation" % svc) emit_err(
"Forced restart, ignoring %s Service, "
"continuing normal operation"
% svc
)
continue continue
emit_err("Shutting down") emit_err("Shutting down")
@@ -500,13 +588,19 @@ def ipa_restart(options):
svchandle = services.service(svc, api=api) svchandle = services.service(svc, api=api)
try: try:
print("Starting %s Service" % svc) print("Starting %s Service" % svc)
svchandle.start(capture_output=get_capture_output(svc, options.debug)) svchandle.start(
capture_output=get_capture_output(svc, options.debug)
)
except Exception: except Exception:
emit_err("Failed to start %s Service" % svc) emit_err("Failed to start %s Service" % svc)
# if ignore_service_failures is specified, skip rollback and # if ignore_service_failures is specified, skip rollback and
# continue with the next service # continue with the next service
if options.ignore_service_failures: if options.ignore_service_failures:
emit_err("Forced start, ignoring %s Service, continuing normal operation" % svc) emit_err(
"Forced start, ignoring %s Service, "
"continuing normal operation"
% svc
)
continue continue
emit_err("Shutting down") emit_err("Shutting down")
@@ -516,6 +610,7 @@ def ipa_restart(options):
emit_err(MSG_HINT_IGNORE_SERVICE_FAILURE) emit_err(MSG_HINT_IGNORE_SERVICE_FAILURE)
raise IpactlError("Aborting ipactl") raise IpactlError("Aborting ipactl")
def ipa_status(options): def ipa_status(options):
try: try:
@@ -530,7 +625,9 @@ def ipa_status(options):
else: else:
svc_list = [] svc_list = []
except Exception as e: except Exception as e:
raise IpactlError("Failed to get list of services to probe status: " + str(e)) raise IpactlError(
"Failed to get list of services to probe status: " + str(e)
)
dirsrv = services.knownservices.dirsrv dirsrv = services.knownservices.dirsrv
try: try:
@@ -539,9 +636,13 @@ def ipa_status(options):
else: else:
print("Directory Service: STOPPED") print("Directory Service: STOPPED")
if len(svc_list) == 0: if len(svc_list) == 0:
print(("Directory Service must be running in order to " + print(
"obtain status of other services")) (
except: "Directory Service must be running in order to "
"obtain status of other services"
)
)
except Exception as e:
raise IpactlError("Failed to get Directory Service status") raise IpactlError("Failed to get Directory Service status")
if len(svc_list) == 0: if len(svc_list) == 0:
@@ -557,6 +658,7 @@ def ipa_status(options):
except Exception: except Exception:
emit_err("Failed to get %s Service status" % svc) emit_err("Failed to get %s Service status" % svc)
def main(): def main():
if not os.getegid() == 0: if not os.getegid() == 0:
# LSB status code 4: user had insufficient privilege # LSB status code 4: user had insufficient privilege
@@ -567,7 +669,7 @@ def main():
if len(args) != 1: if len(args) != 1:
# LSB status code 2: invalid or excess argument(s) # LSB status code 2: invalid or excess argument(s)
raise IpactlError("You must specify one action", 2) raise IpactlError("You must specify one action", 2)
elif args[0] != "start" and args[0] != "stop" and args[0] != "restart" and args[0] != "status": elif args[0] not in ("start", "stop", "restart", "status"):
raise IpactlError("Unrecognized action [" + args[0] + "]", 2) raise IpactlError("Unrecognized action [" + args[0] + "]", 2)
# check if IPA is configured at all # check if IPA is configured at all
@@ -584,15 +686,19 @@ def main():
else: else:
raise e raise e
api.bootstrap(in_server=True, api.bootstrap(
context='ipactl', in_server=True,
context="ipactl",
confdir=paths.ETC_IPA, confdir=paths.ETC_IPA,
debug=options.debug) debug=options.debug,
)
api.finalize() api.finalize()
if '.' not in api.env.host: if "." not in api.env.host:
raise IpactlError("Invalid hostname '%s' in IPA configuration!\n" raise IpactlError(
"The hostname must be fully-qualified" % api.env.host) "Invalid hostname '%s' in IPA configuration!\n"
"The hostname must be fully-qualified" % api.env.host
)
if args[0].lower() == "start": if args[0].lower() == "start":
ipa_start(options) ipa_start(options)
@@ -602,7 +708,3 @@ def main():
ipa_restart(options) ipa_restart(options)
elif args[0].lower() == "status": elif args[0].lower() == "status":
ipa_status(options) ipa_status(options)
if __name__ == '__main__':
installutils.run_script(main, operation_name='ipactl')