mirror of
https://github.com/freeipa/ansible-freeipa.git
synced 2026-06-23 09:14:43 +00:00
ipaclient: Add support for IPA 4.7 (4.6.90-pre2)
With IPA 4.7 bigger changes have been introduced Changes: - Use of timeconf and chrony instead of ntpconf and ntpd. - A new option ntp_pool has been introduced.
This commit is contained in:
@@ -160,9 +160,24 @@ if NUM_VERSION >= 40400:
|
|||||||
unicode = str
|
unicode = str
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from ipaclient.install import ntpconf
|
from ipaclient.install import timeconf
|
||||||
|
time_service = "chronyd"
|
||||||
except ImportError:
|
except ImportError:
|
||||||
from ipaclient import ntpconf
|
try:
|
||||||
|
from ipaclient.install import ntpconf as timeconf
|
||||||
|
except ImportError:
|
||||||
|
from ipaclient import ntpconf as timeconf
|
||||||
|
time_service = "ntpd"
|
||||||
|
|
||||||
|
try:
|
||||||
|
from ipaclient.install.client import sync_time
|
||||||
|
except ImportError:
|
||||||
|
sync_time = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
from ipaclient.install.client import check_ldap_conf
|
||||||
|
except ImportError:
|
||||||
|
check_ldap_conf = None
|
||||||
|
|
||||||
logger = logging.getLogger("ipa-client-install")
|
logger = logging.getLogger("ipa-client-install")
|
||||||
|
|
||||||
|
|||||||
@@ -63,12 +63,23 @@ options:
|
|||||||
required: false
|
required: false
|
||||||
type: list
|
type: list
|
||||||
default: []
|
default: []
|
||||||
|
ntp_pool:
|
||||||
|
description: ntp server pool to use
|
||||||
|
required: false
|
||||||
no_ntp:
|
no_ntp:
|
||||||
description: Do not sync time and do not detect time servers
|
description: Do not sync time and do not detect time servers
|
||||||
required: false
|
required: false
|
||||||
default: false
|
default: false
|
||||||
type: bool
|
type: bool
|
||||||
default: no
|
default: no
|
||||||
|
no_nisdomain:
|
||||||
|
description: Do not configure NIS domain name
|
||||||
|
required: false
|
||||||
|
type: bool
|
||||||
|
default: no
|
||||||
|
nisdomain:
|
||||||
|
description: NIS domain name
|
||||||
|
required: false
|
||||||
author:
|
author:
|
||||||
- Thomas Woerner
|
- Thomas Woerner
|
||||||
'''
|
'''
|
||||||
@@ -223,20 +234,30 @@ def main():
|
|||||||
ca_cert_file=dict(required=False),
|
ca_cert_file=dict(required=False),
|
||||||
on_master=dict(required=False, type='bool', default=False),
|
on_master=dict(required=False, type='bool', default=False),
|
||||||
ntp_servers=dict(required=False, type='list', default=[]),
|
ntp_servers=dict(required=False, type='list', default=[]),
|
||||||
|
ntp_pool=dict(required=False),
|
||||||
no_ntp=dict(required=False, type='bool', default=False),
|
no_ntp=dict(required=False, type='bool', default=False),
|
||||||
|
#no_nisdomain=dict(required=False, type='bool', default='no'),
|
||||||
|
#nisdomain=dict(required=False),
|
||||||
),
|
),
|
||||||
supports_check_mode = True,
|
supports_check_mode = True,
|
||||||
)
|
)
|
||||||
|
|
||||||
module._ansible_debug = True
|
module._ansible_debug = True
|
||||||
opt_domain = module.params.get('domain')
|
options.domain = module.params.get('domain')
|
||||||
opt_servers = module.params.get('servers')
|
options.servers = module.params.get('servers')
|
||||||
opt_realm = module.params.get('realm')
|
options.realm = module.params.get('realm')
|
||||||
opt_hostname = module.params.get('hostname')
|
options.hostname = module.params.get('hostname')
|
||||||
opt_ca_cert_file = module.params.get('ca_cert_file')
|
options.ca_cert_file = module.params.get('ca_cert_file')
|
||||||
opt_on_master = module.params.get('on_master')
|
options.on_master = module.params.get('on_master')
|
||||||
opt_ntp_servers = module.params.get('ntp_servers')
|
options.ntp_servers = module.params.get('ntp_servers')
|
||||||
opt_no_ntp = module.params.get('no_ntp')
|
options.ntp_pool = module.params.get('ntp_pool')
|
||||||
|
options.no_ntp = module.params.get('no_ntp')
|
||||||
|
options.conf_ntp = not options.no_ntp
|
||||||
|
#options.no_nisdomain = module.params.get('no_nisdomain')
|
||||||
|
#options.nisdomain = module.params.get('nisdomain')
|
||||||
|
#options.ip_addresses
|
||||||
|
#options.all_ip_addresses
|
||||||
|
#options.enable_dns_updates
|
||||||
|
|
||||||
hostname = None
|
hostname = None
|
||||||
hostname_source = None
|
hostname_source = None
|
||||||
@@ -248,8 +269,34 @@ def main():
|
|||||||
client_domain = None
|
client_domain = None
|
||||||
cli_basedn = None
|
cli_basedn = None
|
||||||
|
|
||||||
if opt_hostname:
|
fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
|
||||||
hostname = opt_hostname
|
statestore = sysrestore.StateFile(paths.IPA_CLIENT_SYSRESTORE)
|
||||||
|
|
||||||
|
if options.ntp_servers and options.no_ntp:
|
||||||
|
module.fail_json(
|
||||||
|
"--ntp-server cannot be used together with --no-ntp")
|
||||||
|
|
||||||
|
if options.ntp_pool and options.no_ntp:
|
||||||
|
module.fail_json(
|
||||||
|
"--ntp-pool cannot be used together with --no-ntp")
|
||||||
|
|
||||||
|
#if options.no_nisdomain and options.nisdomain:
|
||||||
|
# module.fail_json(
|
||||||
|
# "--no-nisdomain cannot be used together with --nisdomain")
|
||||||
|
|
||||||
|
#if options.ip_addresses:
|
||||||
|
# if options.enable_dns_updates:
|
||||||
|
# module.fail_json(
|
||||||
|
# "--ip-addresses cannot be used together with"
|
||||||
|
# " --enable-dns-updates")
|
||||||
|
|
||||||
|
# if options.all_ip_addresses:
|
||||||
|
# module.fail_json(
|
||||||
|
# "--ip-address cannot be used together with"
|
||||||
|
# "--all-ip-addresses")
|
||||||
|
|
||||||
|
if options.hostname:
|
||||||
|
hostname = options.hostname
|
||||||
hostname_source = 'Provided as option'
|
hostname_source = 'Provided as option'
|
||||||
else:
|
else:
|
||||||
hostname = socket.getfqdn()
|
hostname = socket.getfqdn()
|
||||||
@@ -263,25 +310,25 @@ def main():
|
|||||||
msg="Invalid hostname, '%s' must not be used." % hostname)
|
msg="Invalid hostname, '%s' must not be used." % hostname)
|
||||||
|
|
||||||
# Get domain from first server if domain is not set, but there are servers
|
# Get domain from first server if domain is not set, but there are servers
|
||||||
if opt_domain is None and len(opt_servers) > 0:
|
if options.domain is None and len(options.servers) > 0:
|
||||||
opt_domain = opt_servers[0][opt_servers[0].find(".")+1:]
|
options.domain = options.servers[0][options.servers[0].find(".")+1:]
|
||||||
|
|
||||||
# Create the discovery instance
|
# Create the discovery instance
|
||||||
ds = ipadiscovery.IPADiscovery()
|
ds = ipadiscovery.IPADiscovery()
|
||||||
|
|
||||||
ret = ds.search(
|
ret = ds.search(
|
||||||
domain=opt_domain,
|
domain=options.domain,
|
||||||
servers=opt_servers,
|
servers=options.servers,
|
||||||
realm=opt_realm,
|
realm=options.realm,
|
||||||
hostname=hostname,
|
hostname=hostname,
|
||||||
ca_cert_path=get_cert_path(opt_ca_cert_file))
|
ca_cert_path=get_cert_path(options.ca_cert_file))
|
||||||
|
|
||||||
if opt_servers and ret != 0:
|
if options.servers and ret != 0:
|
||||||
# There is no point to continue with installation as server list was
|
# There is no point to continue with installation as server list was
|
||||||
# passed as a fixed list of server and thus we cannot discover any
|
# passed as a fixed list of server and thus we cannot discover any
|
||||||
# better result
|
# better result
|
||||||
module.fail_json(msg="Failed to verify that %s is an IPA Server." % \
|
module.fail_json(msg="Failed to verify that %s is an IPA Server." % \
|
||||||
', '.join(opt_servers))
|
', '.join(options.servers))
|
||||||
|
|
||||||
if ret == ipadiscovery.BAD_HOST_CONFIG:
|
if ret == ipadiscovery.BAD_HOST_CONFIG:
|
||||||
module.fail_json(msg="Can't get the fully qualified name of this host")
|
module.fail_json(msg="Can't get the fully qualified name of this host")
|
||||||
@@ -301,8 +348,8 @@ def main():
|
|||||||
module.log("No IPA server found")
|
module.log("No IPA server found")
|
||||||
else:
|
else:
|
||||||
module.log("Domain not found")
|
module.log("Domain not found")
|
||||||
if opt_domain:
|
if options.domain:
|
||||||
cli_domain = opt_domain
|
cli_domain = options.domain
|
||||||
cli_domain_source = 'Provided as option'
|
cli_domain_source = 'Provided as option'
|
||||||
else:
|
else:
|
||||||
module.fail_json(
|
module.fail_json(
|
||||||
@@ -310,9 +357,9 @@ def main():
|
|||||||
|
|
||||||
ret = ds.search(
|
ret = ds.search(
|
||||||
domain=cli_domain,
|
domain=cli_domain,
|
||||||
servers=opt_servers,
|
servers=options.servers,
|
||||||
hostname=hostname,
|
hostname=hostname,
|
||||||
ca_cert_path=get_cert_path(opt_ca_cert_file))
|
ca_cert_path=get_cert_path(options.ca_cert_file))
|
||||||
|
|
||||||
if not cli_domain:
|
if not cli_domain:
|
||||||
if ds.domain:
|
if ds.domain:
|
||||||
@@ -325,8 +372,8 @@ def main():
|
|||||||
if ret in (ipadiscovery.NO_LDAP_SERVER, ipadiscovery.NOT_IPA_SERVER) \
|
if ret in (ipadiscovery.NO_LDAP_SERVER, ipadiscovery.NOT_IPA_SERVER) \
|
||||||
or not ds.server:
|
or not ds.server:
|
||||||
module.debug("IPA Server not found")
|
module.debug("IPA Server not found")
|
||||||
if opt_servers:
|
if options.servers:
|
||||||
cli_server = opt_servers
|
cli_server = options.servers
|
||||||
cli_server_source = 'Provided as option'
|
cli_server_source = 'Provided as option'
|
||||||
else:
|
else:
|
||||||
module.fail_json(msg="Unable to find IPA Server to join")
|
module.fail_json(msg="Unable to find IPA Server to join")
|
||||||
@@ -335,12 +382,12 @@ def main():
|
|||||||
domain=cli_domain,
|
domain=cli_domain,
|
||||||
servers=cli_server,
|
servers=cli_server,
|
||||||
hostname=hostname,
|
hostname=hostname,
|
||||||
ca_cert_path=get_cert_path(opt_ca_cert_file))
|
ca_cert_path=get_cert_path(options.ca_cert_file))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Only set dnsok to True if we were not passed in one or more servers
|
# Only set dnsok to True if we were not passed in one or more servers
|
||||||
# and if DNS discovery actually worked.
|
# and if DNS discovery actually worked.
|
||||||
if not opt_servers:
|
if not options.servers:
|
||||||
(server, domain) = ds.check_domain(
|
(server, domain) = ds.check_domain(
|
||||||
ds.domain, set(), "Validating DNS Discovery")
|
ds.domain, set(), "Validating DNS Discovery")
|
||||||
if server and domain:
|
if server and domain:
|
||||||
@@ -353,11 +400,11 @@ def main():
|
|||||||
"Using servers from command line, disabling DNS discovery")
|
"Using servers from command line, disabling DNS discovery")
|
||||||
|
|
||||||
if not cli_server:
|
if not cli_server:
|
||||||
if opt_servers:
|
if options.servers:
|
||||||
cli_server = ds.servers
|
cli_server = ds.servers
|
||||||
cli_server_source = 'Provided as option'
|
cli_server_source = 'Provided as option'
|
||||||
module.debug(
|
module.debug(
|
||||||
"will use provided server: %s" % ', '.join(opt_servers))
|
"will use provided server: %s" % ', '.join(options.servers))
|
||||||
elif ds.server:
|
elif ds.server:
|
||||||
cli_server = ds.servers
|
cli_server = ds.servers
|
||||||
cli_server_source = ds.server_source
|
cli_server_source = ds.server_source
|
||||||
@@ -392,11 +439,11 @@ def main():
|
|||||||
cli_realm_source = ds.realm_source
|
cli_realm_source = ds.realm_source
|
||||||
module.debug("will use discovered realm: %s" % cli_realm)
|
module.debug("will use discovered realm: %s" % cli_realm)
|
||||||
|
|
||||||
if opt_realm and opt_realm != cli_realm:
|
if options.realm and options.realm != cli_realm:
|
||||||
module.fail_json(
|
module.fail_json(
|
||||||
msg=
|
msg=
|
||||||
"The provided realm name [%s] does not match discovered one [%s]" %
|
"The provided realm name [%s] does not match discovered one [%s]" %
|
||||||
(opt_realm, cli_realm))
|
(options.realm, cli_realm))
|
||||||
|
|
||||||
cli_basedn = str(ds.basedn)
|
cli_basedn = str(ds.basedn)
|
||||||
cli_basedn_source = ds.basedn_source
|
cli_basedn_source = ds.basedn_source
|
||||||
@@ -432,14 +479,33 @@ def main():
|
|||||||
"installation may fail.")
|
"installation may fail.")
|
||||||
break
|
break
|
||||||
|
|
||||||
if not opt_on_master and not opt_no_ntp:
|
ntp_servers = [ ]
|
||||||
if len(opt_ntp_servers) < 1:
|
if sync_time is not None:
|
||||||
|
if options.conf_ntp:
|
||||||
|
# Attempt to configure and sync time with NTP server (chrony).
|
||||||
|
sync_time(options, fstore, statestore)
|
||||||
|
elif options.on_master:
|
||||||
|
# If we're on master skipping the time sync here because it was done
|
||||||
|
# in ipa-server-install
|
||||||
|
logger.info("Skipping attempt to configure and synchronize time with"
|
||||||
|
" chrony server as it has been already done on master.")
|
||||||
|
else:
|
||||||
|
logger.info("Skipping chrony configuration")
|
||||||
|
|
||||||
|
elif not options.on_master and options.conf_ntp:
|
||||||
|
# Attempt to sync time with IPA server.
|
||||||
|
# If we're skipping NTP configuration, we also skip the time sync here.
|
||||||
|
# We assume that NTP servers are discoverable through SRV records
|
||||||
|
# in the DNS.
|
||||||
|
# If that fails, we try to sync directly with IPA server,
|
||||||
|
# assuming it runs NTP
|
||||||
|
if len(options.ntp_servers) < 1:
|
||||||
# Detect NTP servers
|
# Detect NTP servers
|
||||||
ds = ipadiscovery.IPADiscovery()
|
ds = ipadiscovery.IPADiscovery()
|
||||||
ntp_servers = ds.ipadns_search_srv(cli_domain, '_ntp._udp',
|
ntp_servers = ds.ipadns_search_srv(cli_domain, '_ntp._udp',
|
||||||
None, break_on_first=False)
|
None, break_on_first=False)
|
||||||
else:
|
else:
|
||||||
ntp_servers = opt_ntp_servers
|
ntp_servers = options.ntp_servers
|
||||||
|
|
||||||
# Attempt to sync time:
|
# Attempt to sync time:
|
||||||
# At first with given or dicovered time servers. If no ntp
|
# At first with given or dicovered time servers. If no ntp
|
||||||
@@ -449,15 +515,13 @@ def main():
|
|||||||
synced_ntp = False
|
synced_ntp = False
|
||||||
# use user specified NTP servers if there are any
|
# use user specified NTP servers if there are any
|
||||||
for s in ntp_servers:
|
for s in ntp_servers:
|
||||||
synced_ntp = ntpconf.synconce_ntp(s, False)
|
synced_ntp = timconf.synconce_ntp(s, False)
|
||||||
if synced_ntp:
|
if synced_ntp:
|
||||||
break
|
break
|
||||||
if not synced_ntp and not ntp_servers:
|
if not synced_ntp and not ntp_servers:
|
||||||
synced_ntp = ntpconf.synconce_ntp(cli_server[0], False)
|
synced_ntp = timeconf.synconce_ntp(cli_server[0], False)
|
||||||
if not synced_ntp:
|
if not synced_ntp:
|
||||||
module.warn("Unable to sync time with NTP server")
|
module.warn("Unable to sync time with NTP server")
|
||||||
else:
|
|
||||||
ntp_servers = [ ]
|
|
||||||
|
|
||||||
# Check if ipa client is already configured
|
# Check if ipa client is already configured
|
||||||
if is_client_configured():
|
if is_client_configured():
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
ca_cert_file: "{{ ipaclient_ca_cert_file | default(omit) }}"
|
ca_cert_file: "{{ ipaclient_ca_cert_file | default(omit) }}"
|
||||||
on_master: "{{ ipaclient_on_master }}"
|
on_master: "{{ ipaclient_on_master }}"
|
||||||
ntp_servers: "{{ ipaclient_ntp_servers | default([]) }}"
|
ntp_servers: "{{ ipaclient_ntp_servers | default([]) }}"
|
||||||
|
ntp_pool: "{{ ipaclient_ntp_pool | default(omit) }}"
|
||||||
no_ntp: "{{ ipaclient_no_ntp }}"
|
no_ntp: "{{ ipaclient_no_ntp }}"
|
||||||
register: ipadiscovery
|
register: ipadiscovery
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user