def main(): ansible_module = AnsibleModule( argument_spec=dict( # server setup_kra=dict(required=False, type='bool'), # certificate system subject_base=dict(required=True), # ad trust enable_compat=dict(required=False, type='bool', default=False), rid_base=dict(required=False, type='int'), secondary_rid_base=dict(required=False, type='int'), # additional adtrust_netbios_name=dict(required=True), adtrust_reset_netbios_name=dict(required=True, type='bool'), # additional ccache=dict(required=True), _top_dir=dict(required=True), setup_ca=dict(required=True), config_master_host_name=dict(required=True), ), supports_check_mode=True, ) ansible_module._ansible_debug = True setup_logging() ansible_log = AnsibleModuleLog(ansible_module) # get parameters # options = installer # server options.setup_kra = ansible_module.params.get('setup_kra') # certificate system options.subject_base = ansible_module.params.get('subject_base') if options.subject_base is not None: options.subject_base = DN(options.subject_base) # ad trust options.enable_compat = ansible_module.params.get('enable_compat') options.rid_base = ansible_module.params.get('rid_base') options.secondary_rid_base = ansible_module.params.get( 'secondary_rid_base') # additional ccache = ansible_module.params.get('ccache') os.environ['KRB5CCNAME'] = ccache options._top_dir = ansible_module.params.get('_top_dir') options.setup_ca = ansible_module.params.get('setup_ca') config_master_host_name = ansible_module.params.get( 'config_master_host_name') adtrust.netbios_name = ansible_module.params.get('adtrust_netbios_name') adtrust.reset_netbios_name = ansible_module.params.get( 'adtrust_reset_netbios_name') # init # fstore = sysrestore.FileStore(paths.SYSRESTORE) ansible_log.debug("== INSTALL ==") env = gen_env_boostrap_finalize_core(paths.ETC_IPA, constants.DEFAULT_CONFIG) api_bootstrap_finalize(env) config = gen_ReplicaConfig() config.subject_base = options.subject_base config.master_host_name = config_master_host_name remote_api = gen_remote_api(config.master_host_name, paths.ETC_IPA) installer._remote_api = remote_api ccache = os.environ['KRB5CCNAME'] api.Backend.ldap2.connect() with redirect_stdout(ansible_log): ansible_log.debug("-- INSTALL ADTRUST --") adtrust.install(False, options, fstore, api) # done # ansible_module.exit_json(changed=True)
def main(): ansible_module = AnsibleModule( argument_spec=dict( ### basic ### force=dict(required=False, type='bool', default=False), dm_password=dict(required=True, no_log=True), password=dict(required=True, no_log=True), master_password=dict(required=False, no_log=True), ip_addresses=dict(required=False, type='list', default=[]), domain=dict(required=False), realm=dict(required=False), hostname=dict(required=False), ca_cert_files=dict(required=False, type='list', default=[]), no_host_dns=dict(required=False, type='bool', default=False), ### server ### setup_adtrust=dict(required=False, type='bool', default=False), setup_kra=dict(required=False, type='bool', default=False), setup_dns=dict(required=False, type='bool', default=False), idstart=dict(required=False, type='int'), idmax=dict(required=False, type='int'), # no_hbac_allow no_pkinit=dict(required=False, type='bool', default=False), # no_ui_redirect dirsrv_config_file=dict(required=False), ### ssl certificate ### dirsrv_cert_files=dict(required=False, type='list', default=[]), http_cert_files=dict(required=False, type='list', default=[]), pkinit_cert_files=dict(required=False, type='list', default=[]), # dirsrv_pin # http_pin # pkinit_pin # dirsrv_name # http_name # pkinit_name ### client ### # mkhomedir no_ntp=dict(required=False, type='bool', default=False), # ssh_trust_dns # no_ssh # no_sshd # no_dns_sshfp ### certificate system ### external_ca=dict(required=False, type='bool', default=False), external_ca_type=dict(required=False), external_cert_files=dict(required=False, type='list', default=[]), subject_base=dict(required=False), ca_subject=dict(required=False), # ca_signing_algorithm ### dns ### allow_zone_overlap=dict(required=False, type='bool', default=False), reverse_zones=dict(required=False, type='list', default=[]), no_reverse=dict(required=False, type='bool', default=False), auto_reverse=dict(required=False, type='bool', default=False), zonemgr=dict(required=False), forwarders=dict(required=False, type='list', default=[]), no_forwarders=dict(required=False, type='bool', default=False), auto_forwarders=dict(required=False, type='bool', default=False), forward_policy=dict(default=None, choices=['first', 'only']), no_dnssec_validation=dict(required=False, type='bool', default=False), ### ad trust ### enable_compat=dict(required=False, type='bool', default=False), netbios_name=dict(required=False), rid_base=dict(required=False, type='int', default=1000), secondary_rid_base=dict(required=False, type='int', default=100000000), ### additional ### ), supports_check_mode=True, ) ansible_module._ansible_debug = True ansible_log = AnsibleModuleLog(ansible_module) # set values ############################################################ ### basic ### options.force = ansible_module.params.get('force') options.dm_password = ansible_module.params.get('dm_password') options.admin_password = ansible_module.params.get('password') options.master_password = ansible_module.params.get('master_password') options.ip_addresses = ansible_module_get_parsed_ip_addresses( ansible_module) options.domain_name = ansible_module.params.get('domain') options.realm_name = ansible_module.params.get('realm') options.host_name = ansible_module.params.get('hostname') options.ca_cert_files = ansible_module.params.get('ca_cert_files') options.no_host_dns = ansible_module.params.get('no_host_dns') ### server ### options.setup_adtrust = ansible_module.params.get('setup_adtrust') options.setup_dns = ansible_module.params.get('setup_dns') options.setup_kra = ansible_module.params.get('setup_kra') options.idstart = ansible_module.params.get('idstart') options.idmax = ansible_module.params.get('idmax') # no_hbac_allow options.no_pkinit = ansible_module.params.get('no_pkinit') # no_ui_redirect options.dirsrv_config_file = ansible_module.params.get( 'dirsrv_config_file') ### ssl certificate ### options.dirsrv_cert_files = ansible_module.params.get('dirsrv_cert_files') options.http_cert_files = ansible_module.params.get('http_cert_files') options.pkinit_cert_files = ansible_module.params.get('pkinit_cert_files') # dirsrv_pin # http_pin # pkinit_pin # dirsrv_name # http_name # pkinit_name ### client ### # mkhomedir options.no_ntp = ansible_module.params.get('no_ntp') # ssh_trust_dns # no_ssh # no_sshd # no_dns_sshfp ### certificate system ### options.external_ca = ansible_module.params.get('external_ca') options.external_ca_type = ansible_module.params.get('external_ca_type') options.external_cert_files = ansible_module.params.get( 'external_cert_files') options.subject_base = ansible_module.params.get('subject_base') options.ca_subject = ansible_module.params.get('ca_subject') # ca_signing_algorithm ### dns ### options.allow_zone_overlap = ansible_module.params.get( 'allow_zone_overlap') options.reverse_zones = ansible_module.params.get('reverse_zones') options.no_reverse = ansible_module.params.get('no_reverse') options.auto_reverse = ansible_module.params.get('auto_reverse') options.zonemgr = ansible_module.params.get('zonemgr') options.forwarders = ansible_module.params.get('forwarders') options.no_forwarders = ansible_module.params.get('no_forwarders') options.auto_forwarders = ansible_module.params.get('auto_forwarders') options.forward_policy = ansible_module.params.get('forward_policy') options.no_dnssec_validation = ansible_module.params.get( 'no_dnssec_validation') ### ad trust ### options.enable_compat = ansible_module.params.get('enable_compat') options.netbios_name = ansible_module.params.get('netbios_name') options.rid_base = ansible_module.params.get('rid_base') options.secondary_rid_base = ansible_module.params.get( 'secondary_rid_base') ### additional ### options.kasp_db_file = None # version specific ###################################################### if options.setup_adtrust and not adtrust_imported: #if "adtrust" not in options._allow_missing: ansible_module.fail_json(msg="adtrust can not be imported") #else: # options.setup_adtrust = False # ansible_module.warn(msg="adtrust is not supported, disabling") if options.setup_kra and not kra_imported: #if "kra" not in options._allow_missing: ansible_module.fail_json(msg="kra can not be imported") #else: # options.setup_kra = False # ansible_module.warn(msg="kra is not supported, disabling") # validation ############################################################# if options.dm_password is None: ansible_module.fail_json(msg="Directory Manager password required") if options.admin_password is None: ansible_module.fail_json(msg="IPA admin password required") # This will override any settings passed in on the cmdline if os.path.isfile(paths.ROOT_IPA_CACHE): # dm_password check removed, checked already try: cache_vars = read_cache(options.dm_password) options.__dict__.update(cache_vars) if cache_vars.get('external_ca', False): options.external_ca = False options.interactive = False except Exception as e: ansible_module.fail_json(msg="Cannot process the cache file: %s" % str(e)) # default values ######################################################## # idstart and idmax if options.idstart is None: options.idstart = random.randint(1, 10000) * 200000 if options.idmax is None or options.idmax == 0: options.idmax = options.idstart + 199999 # validation ############################################################ # domain_level if options.domain_level < MIN_DOMAIN_LEVEL: ansible_module.fail_json(msg="Domain Level cannot be lower than %d" % MIN_DOMAIN_LEVEL) elif options.domain_level > MAX_DOMAIN_LEVEL: ansible_module.fail_json(msg="Domain Level cannot be higher than %d" % MAX_DOMAIN_LEVEL) # dirsrv_config_file if options.dirsrv_config_file is not None: if not os.path.exists(options.dirsrv_config_file): ansible_module.fail_json(msg="File %s does not exist." % options.dirsrv_config_file) # domain_name if (options.setup_dns and not options.allow_zone_overlap and \ options.domain_name is not None): try: check_zone_overlap(options.domain_name, False) except ValueError as e: ansible_module.fail_json(msg=str(e)) # dm_password with redirect_stdout(ansible_log): validate_dm_password(options.dm_password) # admin_password with redirect_stdout(ansible_log): validate_admin_password(options.admin_password) # pkinit is not supported on DL0, don't allow related options # replica install: if not self.replica_file is None: if (not options._replica_install and \ not options.domain_level > DOMAIN_LEVEL_0) or \ (options._replica_install and self.replica_file is not None): if (options.no_pkinit or options.pkinit_cert_files is not None or options.pkinit_pin is not None): ansible_module.fail_json( msg="pkinit on domain level 0 is not supported. Please " "don't use any pkinit-related options.") options.no_pkinit = True # If any of the key file options are selected, all are required. cert_file_req = (options.dirsrv_cert_files, options.http_cert_files) cert_file_opt = (options.pkinit_cert_files, ) if not options.no_pkinit: cert_file_req += cert_file_opt if options.no_pkinit and options.pkinit_cert_files: ansible_module.fail_json( msg="no-pkinit and pkinit-cert-file cannot be specified together") if any(cert_file_req + cert_file_opt) and not all(cert_file_req): ansible_module.fail_json( msg="dirsrv-cert-file, http-cert-file, and pkinit-cert-file " "or no-pkinit are required if any key file options are used.") if not options.interactive: if options.dirsrv_cert_files and options.dirsrv_pin is None: ansible_module.fail_json( msg="You must specify dirsrv-pin with dirsrv-cert-file") if options.http_cert_files and options.http_pin is None: ansible_module.fail_json( msg="You must specify http-pin with http-cert-file") if options.pkinit_cert_files and options.pkinit_pin is None: ansible_module.fail_json( msg="You must specify pkinit-pin with pkinit-cert-file") if not options.setup_dns: # lists for x in ["forwarders", "reverse_zones"]: if len(getattr(options, x)) > 1: ansible_module.fail_json( msg="You cannot specify %s without setting setup-dns" % x) # bool and str values for x in [ "auto_forwarders", "no_forwarders", "auto_reverse", "no_reverse", "no_dnssec_validation", "forward_policy" ]: if getattr(options, x) == True: ansible_module.fail_json( msg="You cannot specify %s without setting setup-dns" % x) elif len(options.forwarders) > 0 and options.no_forwarders: ansible_module.fail_json( msg="You cannot specify forwarders together with no-forwarders") elif options.auto_forwarders and options.no_forwarders: ansible_module.fail_json( msg="You cannot specify auto-forwarders together with no-forwarders" ) elif len(options.reverse_zones) > 0 and options.no_reverse: ansible_module.fail_json( msg="You cannot specify reverse-zones together with no-reverse") elif options.auto_reverse and options.no_reverse: ansible_module.fail_json( msg="You cannot specify auto-reverse together with no-reverse") if not options._replica_install: if options.external_cert_files and options.dirsrv_cert_files: ansible_module.fail_json( msg="Service certificate file options cannot be used with the " "external CA options.") if options.external_ca_type and not options.external_ca: ansible_module.fail_json( msg="You cannot specify external-ca-type without external-ca") #if options.uninstalling: # if (options.realm_name or options.admin_password or # options.master_password): # ansible_module.fail_json( # msg="In uninstall mode, -a, -r and -P options are not " # "allowed") #elif not options.interactive: # if (not options.realm_name or not options.dm_password or # not options.admin_password): # ansible_module.fail_json(msg= # "In unattended mode you need to provide at least -r, " # "-p and -a options") # if options.setup_dns: # if (not options.forwarders and # not options.no_forwarders and # not options.auto_forwarders): # ansible_module.fail_json(msg= # "You must specify at least one of --forwarder, " # "--auto-forwarders, or --no-forwarders options") if (not options.realm_name or not options.dm_password or not options.admin_password): ansible_module.fail_json( msg="You need to provide at least realm_name, dm_password " "and admin_password") if options.setup_dns: if len(options.forwarders) < 1 and not options.no_forwarders and \ not options.auto_forwarders: ansible_module.fail_json( msg="You must specify at least one of forwarders, " "auto-forwarders or no-forwarders") #any_ignore_option_true = any( # [options.ignore_topology_disconnect, options.ignore_last_of_role]) #if any_ignore_option_true and not options.uninstalling: # ansible_module.fail_json( # msg="ignore-topology-disconnect and ignore-last-of-role " # "can be used only during uninstallation") if options.idmax < options.idstart: ansible_module.fail_json( msg="idmax (%s) cannot be smaller than idstart (%s)" % (options.idmax, options.idstart)) else: # replica install if options.replica_file is None: if options.servers and not options.domain_name: ansible_module.fail_json( msg="servers cannot be used without providing domain") else: if not os.path.isfile(options.replica_file): ansible_module.fail_json(msg="Replica file %s does not exist" % options.replica_file) if any(cert_file_req + cert_file_opt): ansible_module.fail_json( msg="You cannot specify dirsrv-cert-file, http-cert-file, " "or pkinit-cert-file together with replica file") conflicting = { "realm": options.realm_name, "domain": options.domain_name, "hostname": options.host_name, "servers": options.servers, "principal": options.principal } conflicting_names = [ name for name in conflicting if conflicting[name] is not None ] if len(conflicting_names) > 0: ansible_module.fail_json( msg="You cannot specify %s option(s) with replica file." % \ ", ".join(conflicting_names)) if options.setup_dns: if len(options.forwarders) < 1 and not options.no_forwarders and \ not options.auto_forwarders: ansible_module.fail_json( msg="You must specify at least one of forwarders, " "auto-forwarders or no-forwarders") if NUM_VERSION >= 40200 and options.master_password: ansible_module.warn("Specifying master-password is deprecated") options._installation_cleanup = True if not options.external_ca and len(options.external_cert_files) < 1 and \ is_ipa_configured(): options._installation_cleanup = False ansible_module.log( "IPA server is already configured on this system. If you want " "to reinstall the IPA server, please uninstall it first.") ansible_module.exit_json(changed=False, server_already_configured=True) client_fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE) if client_fstore.has_files(): options._installation_cleanup = False ansible_module.log( "IPA client is already configured on this system. " "Please uninstall it before configuring the IPA server.") ansible_module.exit_json(changed=False, client_already_configured=True) # validate reverse_zones if not options.allow_zone_overlap: for zone in options.reverse_zones: with redirect_stdout(ansible_log): check_zone_overlap(zone) # validate zonemgr if options.zonemgr: try: # IDNA support requires unicode encoding = getattr(sys.stdin, 'encoding', None) if encoding is None: encoding = 'utf-8' value = options.zonemgr.decode(encoding) with redirect_stdout(ansible_log): bindinstance.validate_zonemgr_str(value) except ValueError as e: # FIXME we can do this in better way # https://fedorahosted.org/freeipa/ticket/4804 # decode to proper stderr encoding stderr_encoding = getattr(sys.stderr, 'encoding', None) if stderr_encoding is None: stderr_encoding = 'utf-8' error = unicode(e).encode(stderr_encoding) ansible_module.fail_json(msg=error) # external cert file paths are absolute for path in options.external_cert_files: if not os.path.isabs(path): ansible_module.fail_json( msg="External cert file '%s' must use an absolute path" % path) options.setup_ca = True # We only set up the CA if the PKCS#12 options are not given. if options.dirsrv_cert_files and len(options.dirsrv_cert_files) > 0: options.setup_ca = False else: options.setup_ca = True if not options.setup_ca and options.ca_subject: ansible_module.fail_json( msg="--ca-subject cannot be used with CA-less installation") if not options.setup_ca and options.subject_base: ansible_module.fail_json( msg="--subject-base cannot be used with CA-less installation") if not options.setup_ca and options.setup_kra: ansible_module.fail_json( msg="--setup-kra cannot be used with CA-less installation") # ca_subject if options.ca_subject: ca.subject_validator(ca.VALID_SUBJECT_ATTRS, options.ca_subject) # IPv6 and SELinux check tasks.check_ipv6_stack_enabled() tasks.check_selinux_status() if check_ldap_conf is not None: check_ldap_conf() _installation_cleanup = True if not options.external_ca and not options.external_cert_files and \ is_ipa_configured(): _installation_cleanup = False ansible_module.fail_json( msg="IPA server is already configured on this system.") if not options.no_ntp: try: timeconf.check_timedate_services() except timeconf.NTPConflictingService as e: ansible_module.log("Conflicting time&date synchronization service '%s'" " will be disabled in favor of %s" % \ (e.conflicting_service, time_service)) except timeconf.NTPConfigurationError: pass if hasattr(httpinstance, "httpd_443_configured"): # Check to see if httpd is already configured to listen on 443 if httpinstance.httpd_443_configured(): ansible_module.fail_json( msg="httpd is already configured to listen on 443.") if not options.external_cert_files: # Make sure the 389-ds ports are available try: check_dirsrv(True) except ScriptError as e: ansible_module.fail_json(msg=e) # check bind packages are installed if options.setup_dns: # Don't require an external DNS to say who we are if we are # setting up a local DNS server. options.no_host_dns = True # host name if options.host_name: options.host_default = options.host_name else: options.host_default = get_fqdn() try: verify_fqdn(options.host_default, options.no_host_dns) options.host_name = options.host_default except BadHostError as e: ansible_module.fail_json(msg=e) options.host_name = options.host_name.lower() if not options.domain_name: options.domain_name = options.host_name[options.host_name.find(".") + 1:] try: validate_domain_name(options.domain_name) except ValueError as e: ansible_module.fail_json(msg="Invalid domain name: %s" % unicode(e)) options.domain_name = options.domain_name.lower() if not options.realm_name: options.realm_name = options.domain_name options.realm_name = options.realm_name.upper() argspec = inspect.getargspec(validate_domain_name) if "entity" in argspec.args: # NUM_VERSION >= 40690: try: validate_domain_name(options.realm_name, entity="realm") except ValueError as e: raise ScriptError("Invalid realm name: {}".format(unicode(e))) if not options.setup_adtrust: # If domain name and realm does not match, IPA server will not be able # to establish trust with Active Directory. Fail. if options.domain_name.upper() != options.realm_name: ansible_module.warn( "Realm name does not match the domain name: " "You will not be able to establish trusts with Active " "Directory.") ######################################################################### http_pkcs12_file = None http_pkcs12_info = None http_ca_cert = None dirsrv_pkcs12_file = None dirsrv_pkcs12_info = None dirsrv_ca_cert = None pkinit_pkcs12_file = None pkinit_pkcs12_info = None pkinit_ca_cert = None if options.http_cert_files: if options.http_pin is None: ansible_module.fail_json( msg="Apache Server private key unlock password required") http_pkcs12_file, http_pin, http_ca_cert = load_pkcs12( cert_files=options.http_cert_files, key_password=options.http_pin, key_nickname=options.http_cert_name, ca_cert_files=options.ca_cert_files, host_name=options.host_name) http_pkcs12_info = (http_pkcs12_file.name, options.http_pin) if options.dirsrv_cert_files: if options.dirsrv_pin is None: ansible_module.fail_json( msg="Directory Server private key unlock password required") dirsrv_pkcs12_file, dirsrv_pin, dirsrv_ca_cert = load_pkcs12( cert_files=options.dirsrv_cert_files, key_password=options.dirsrv_pin, key_nickname=options.dirsrv_cert_name, ca_cert_files=options.ca_cert_files, host_name=options.host_name) dirsrv_pkcs12_info = (dirsrv_pkcs12_file.name, options.dirsrv_pin) if options.pkinit_cert_files: if options.pkinit_pin is None: ansible_module.fail_json( msg="Kerberos KDC private key unlock password required") pkinit_pkcs12_file, pkinit_pin, pkinit_ca_cert = load_pkcs12( cert_files=options.pkinit_cert_files, key_password=options.pkinit_pin, key_nickname=options.pkinit_cert_name, ca_cert_files=options.ca_cert_files, realm_name=options.realm_name) pkinit_pkcs12_info = (pkinit_pkcs12_file.name, options.pkinit_pin) if (options.http_cert_files and options.dirsrv_cert_files and http_ca_cert != dirsrv_ca_cert): ansible_module.fail_json( msg="Apache Server SSL certificate and Directory Server SSL " "certificate are not signed by the same CA certificate") if (options.http_cert_files and options.pkinit_cert_files and http_ca_cert != pkinit_ca_cert): ansible_module.fail_json( msg="Apache Server SSL certificate and PKINIT KDC " "certificate are not signed by the same CA certificate") # subject_base if not options.subject_base: options.subject_base = str(default_subject_base(options.realm_name)) # set options.subject for old ipa releases options.subject = options.subject_base if not options.ca_subject: options.ca_subject = str(default_ca_subject_dn(options.subject_base)) # temporary ipa configuration ########################################### ipa_tempdir = tempfile.mkdtemp(prefix="ipaconf") try: # Configuration for ipalib, we will bootstrap and finalize later, after # we are sure we have the configuration file ready. cfg = dict( context='installer', confdir=ipa_tempdir, in_server=True, # make sure host name specified by user is used instead of default host=options.host_name, ) if options.setup_ca: # we have an IPA-integrated CA cfg['ca_host'] = options.host_name # Create the management framework config file and finalize api target_fname = "%s/default.conf" % ipa_tempdir fd = open(target_fname, "w") fd.write("[global]\n") fd.write("host=%s\n" % options.host_name) fd.write("basedn=%s\n" % ipautil.realm_to_suffix(options.realm_name)) fd.write("realm=%s\n" % options.realm_name) fd.write("domain=%s\n" % options.domain_name) fd.write("xmlrpc_uri=https://%s/ipa/xml\n" % ipautil.format_netloc(options.host_name)) fd.write("ldap_uri=ldapi://%%2fvar%%2frun%%2fslapd-%s.socket\n" % installutils.realm_to_serverid(options.realm_name)) if options.setup_ca: fd.write("enable_ra=True\n") fd.write("ra_plugin=dogtag\n") fd.write("dogtag_version=10\n") else: fd.write("enable_ra=False\n") fd.write("ra_plugin=none\n") fd.write("mode=production\n") fd.close() # Must be readable for everyone os.chmod(target_fname, 0o644) api.bootstrap(**cfg) api.finalize() # install checks #################################################### if options.setup_ca: ca.install_check(False, None, options) if options.setup_kra: kra.install_check(api, None, options) if options.setup_dns: with redirect_stdout(ansible_log): dns.install_check(False, api, False, options, options.host_name) ip_addresses = dns.ip_addresses else: ip_addresses = get_server_ip_address(options.host_name, False, False, options.ip_addresses) # check addresses here, dns ansible_module is doing own check no_matching_interface_for_ip_address_warning(ip_addresses) options.ip_addresses = ip_addresses options.reverse_zones = dns.reverse_zones instance_name = "-".join(options.realm_name.split(".")) dirsrv = services.knownservices.dirsrv if (options.external_cert_files and dirsrv.is_installed(instance_name) and not dirsrv.is_running(instance_name)): logger.debug('Starting Directory Server') services.knownservices.dirsrv.start(instance_name) if options.setup_adtrust: adtrust.install_check(False, options, api) except (RuntimeError, ValueError, ScriptError) as e: ansible_module.fail_json(msg=str(e)) finally: try: shutil.rmtree(ipa_tempdir, ignore_errors=True) except OSError: ansible_module.fail_json(msg="Could not remove %s" % ipa_tempdir) # Always set _host_name_overridden options._host_name_overridden = bool(options.host_name) # done ################################################################## ansible_module.exit_json( changed=False, ipa_python_version=IPA_PYTHON_VERSION, ### basic ### domain=options.domain_name, realm=options.realm_name, ip_addresses=[str(ip) for ip in ip_addresses], hostname=options.host_name, _hostname_overridden=options._host_name_overridden, no_host_dns=options.no_host_dns, ### server ### setup_adtrust=options.setup_adtrust, setup_kra=options.setup_kra, setup_ca=options.setup_ca, idstart=options.idstart, idmax=options.idmax, no_pkinit=options.no_pkinit, ### ssl certificate ### _dirsrv_pkcs12_file=dirsrv_pkcs12_file, _dirsrv_pkcs12_info=dirsrv_pkcs12_info, _dirsrv_ca_cert=dirsrv_ca_cert, _http_pkcs12_file=http_pkcs12_file, _http_pkcs12_info=http_pkcs12_info, _http_ca_cert=http_ca_cert, _pkinit_pkcs12_file=pkinit_pkcs12_file, _pkinit_pkcs12_info=pkinit_pkcs12_info, _pkinit_ca_cert=pkinit_ca_cert, ### certificate system ### subject_base=options.subject_base, _subject_base=options._subject_base, ca_subject=options.ca_subject, _ca_subject=options._ca_subject, ### dns ### reverse_zones=options.reverse_zones, forward_policy=options.forward_policy, forwarders=options.forwarders, no_dnssec_validation=options.no_dnssec_validation, ### ad trust ### rid_base=options.rid_base, secondary_rid_base=options.secondary_rid_base, ### additional ### _installation_cleanup=_installation_cleanup, domainlevel=options.domainlevel, dns_ip_addresses=[str(ip) for ip in dns.ip_addresses], dns_reverse_zones=dns.reverse_zones, adtrust_netbios_name=adtrust.netbios_name, adtrust_reset_netbios_name=adtrust.reset_netbios_name)
def main(): ansible_module = AnsibleModule( argument_spec=dict( # general ipaadmin_principal=dict(type="str", default="admin"), ipaadmin_password=dict(type="str", required=False, no_log=True), name=dict(type="list", aliases=["cn", "service"], default=None, required=True), # present description=dict(type="str", default=None), # state state=dict(type="str", default="present", choices=["present", "absent"]), ), supports_check_mode=True, ) ansible_module._ansible_debug = True # Get parameters # general ipaadmin_principal = ansible_module.params.get("ipaadmin_principal") ipaadmin_password = ansible_module.params.get("ipaadmin_password") names = ansible_module.params.get("name") # present description = ansible_module.params.get("description") # state state = ansible_module.params.get("state") # Check parameters if state == "present": if len(names) != 1: ansible_module.fail_json( msg="Only one hbacsvc can be set at a time.") if state == "absent": if len(names) < 1: ansible_module.fail_json(msg="No name given.") invalid = ["description"] for x in invalid: if vars()[x] is not None: ansible_module.fail_json( msg="Argument '%s' can not be used with state '%s'" % (x, state)) # Init changed = False exit_args = {} ccache_dir = None ccache_name = None try: if not valid_creds(ansible_module, ipaadmin_principal): ccache_dir, ccache_name = temp_kinit(ipaadmin_principal, ipaadmin_password) api_connect() commands = [] for name in names: # Try to find hbacsvc res_find = find_hbacsvc(ansible_module, name) # Create command if state == "present": # Generate args args = gen_args(description) # Found the hbacsvc if res_find is not None: # For all settings is args, check if there are # different settings in the find result. # If yes: modify if not compare_args_ipa(ansible_module, args, res_find): commands.append([name, "hbacsvc_mod", args]) else: commands.append([name, "hbacsvc_add", args]) elif state == "absent": if res_find is not None: commands.append([name, "hbacsvc_del", {}]) else: ansible_module.fail_json(msg="Unkown state '%s'" % state) # Check mode exit if ansible_module.check_mode: ansible_module.exit_json(changed=len(commands) > 0, **exit_args) # Execute commands for name, command, args in commands: try: api_command(ansible_module, command, to_text(name), args) changed = True except Exception as e: ansible_module.fail_json(msg="%s: %s: %s" % (command, name, str(e))) except Exception as e: ansible_module.fail_json(msg=str(e)) finally: temp_kdestroy(ccache_dir, ccache_name) # Done ansible_module.exit_json(changed=changed, **exit_args)
def main(): ansible_module = AnsibleModule( argument_spec=dict( # general ipaadmin_principal=dict(type="str", default="admin"), ipaadmin_password=dict(type="str", required=False, no_log=True), name=dict(type="list", aliases=["cn"], default=None, required=True), # present description=dict(type="str", default=None), usercategory=dict(type="str", default=None, aliases=["usercat"], choices=["all"]), hostcategory=dict(type="str", default=None, aliases=["hostcat"], choices=["all"]), servicecategory=dict(type="str", default=None, aliases=["servicecat"], choices=["all"]), nomembers=dict(required=False, type='bool', default=None), host=dict(required=False, type='list', default=None), hostgroup=dict(required=False, type='list', default=None), hbacsvc=dict(required=False, type='list', default=None), hbacsvcgroup=dict(required=False, type='list', default=None), user=dict(required=False, type='list', default=None), group=dict(required=False, type='list', default=None), action=dict(type="str", default="hbacrule", choices=["member", "hbacrule"]), # state state=dict(type="str", default="present", choices=["present", "absent", "enabled", "disabled"]), ), supports_check_mode=True, ) ansible_module._ansible_debug = True # Get parameters # general ipaadmin_principal = module_params_get(ansible_module, "ipaadmin_principal") ipaadmin_password = module_params_get(ansible_module, "ipaadmin_password") names = module_params_get(ansible_module, "name") # present description = module_params_get(ansible_module, "description") usercategory = module_params_get(ansible_module, "usercategory") hostcategory = module_params_get(ansible_module, "hostcategory") servicecategory = module_params_get(ansible_module, "servicecategory") nomembers = module_params_get(ansible_module, "nomembers") host = module_params_get(ansible_module, "host") hostgroup = module_params_get(ansible_module, "hostgroup") hbacsvc = module_params_get(ansible_module, "hbacsvc") hbacsvcgroup = module_params_get(ansible_module, "hbacsvcgroup") user = module_params_get(ansible_module, "user") group = module_params_get(ansible_module, "group") action = module_params_get(ansible_module, "action") # state state = module_params_get(ansible_module, "state") # Check parameters if state == "present": if len(names) != 1: ansible_module.fail_json( msg="Only one hbacrule can be added at a time.") if action == "member": invalid = [ "description", "usercategory", "hostcategory", "servicecategory", "nomembers" ] for x in invalid: if vars()[x] is not None: ansible_module.fail_json( msg="Argument '%s' can not be used with action " "'%s'" % (x, action)) elif state == "absent": if len(names) < 1: ansible_module.fail_json(msg="No name given.") invalid = [ "description", "usercategory", "hostcategory", "servicecategory", "nomembers" ] if action == "hbacrule": invalid.extend([ "host", "hostgroup", "hbacsvc", "hbacsvcgroup", "user", "group" ]) for x in invalid: if vars()[x] is not None: ansible_module.fail_json( msg="Argument '%s' can not be used with state '%s'" % (x, state)) elif state in ["enabled", "disabled"]: if len(names) < 1: ansible_module.fail_json(msg="No name given.") if action == "member": ansible_module.fail_json( msg="Action member can not be used with states enabled and " "disabled") invalid = [ "description", "usercategory", "hostcategory", "servicecategory", "nomembers", "host", "hostgroup", "hbacsvc", "hbacsvcgroup", "user", "group" ] for x in invalid: if vars()[x] is not None: ansible_module.fail_json( msg="Argument '%s' can not be used with state '%s'" % (x, state)) else: ansible_module.fail_json(msg="Invalid state '%s'" % state) # Init changed = False exit_args = {} ccache_dir = None ccache_name = None try: if not valid_creds(ansible_module, ipaadmin_principal): ccache_dir, ccache_name = temp_kinit(ipaadmin_principal, ipaadmin_password) api_connect() commands = [] for name in names: # Make sure hbacrule exists res_find = find_hbacrule(ansible_module, name) # Create command if state == "present": # Generate args args = gen_args(description, usercategory, hostcategory, servicecategory, nomembers) if action == "hbacrule": # Found the hbacrule if res_find is not None: # For all settings is args, check if there are # different settings in the find result. # If yes: modify if not compare_args_ipa(ansible_module, args, res_find): commands.append([name, "hbacrule_mod", args]) else: commands.append([name, "hbacrule_add", args]) # Set res_find to empty dict for next step res_find = {} # Generate addition and removal lists host_add = list( set(host or []) - set(res_find.get("member_host", []))) host_del = list( set(res_find.get("member_host", [])) - set(host or [])) hostgroup_add = list( set(hostgroup or []) - set(res_find.get("member_hostgroup", []))) hostgroup_del = list( set(res_find.get("member_hostgroup", [])) - set(hostgroup or [])) hbacsvc_add = list( set(hbacsvc or []) - set(res_find.get("member_hbacsvc", []))) hbacsvc_del = list( set(res_find.get("member_hbacsvc", [])) - set(hbacsvc or [])) hbacsvcgroup_add = list( set(hbacsvcgroup or []) - set(res_find.get("member_hbacsvcgroup", []))) hbacsvcgroup_del = list( set(res_find.get("member_hbacsvcgroup", [])) - set(hbacsvcgroup or [])) user_add = list( set(user or []) - set(res_find.get("member_user", []))) user_del = list( set(res_find.get("member_user", [])) - set(user or [])) group_add = list( set(group or []) - set(res_find.get("member_group", []))) group_del = list( set(res_find.get("member_group", [])) - set(group or [])) # Add hosts and hostgroups if len(host_add) > 0 or len(hostgroup_add) > 0: commands.append([ name, "hbacrule_add_host", { "host": host_add, "hostgroup": hostgroup_add, } ]) # Remove hosts and hostgroups if len(host_del) > 0 or len(hostgroup_del) > 0: commands.append([ name, "hbacrule_remove_host", { "host": host_del, "hostgroup": hostgroup_del, } ]) # Add hbacsvcs and hbacsvcgroups if len(hbacsvc_add) > 0 or len(hbacsvcgroup_add) > 0: commands.append([ name, "hbacrule_add_service", { "hbacsvc": hbacsvc_add, "hbacsvcgroup": hbacsvcgroup_add, } ]) # Remove hbacsvcs and hbacsvcgroups if len(hbacsvc_del) > 0 or len(hbacsvcgroup_del) > 0: commands.append([ name, "hbacrule_remove_service", { "hbacsvc": hbacsvc_del, "hbacsvcgroup": hbacsvcgroup_del, } ]) # Add users and groups if len(user_add) > 0 or len(group_add) > 0: commands.append([ name, "hbacrule_add_user", { "user": user_add, "group": group_add, } ]) # Remove users and groups if len(user_del) > 0 or len(group_del) > 0: commands.append([ name, "hbacrule_remove_user", { "user": user_del, "group": group_del, } ]) elif action == "member": if res_find is None: ansible_module.fail_json(msg="No hbacrule '%s'" % name) # Add hosts and hostgroups if host is not None or hostgroup is not None: commands.append([ name, "hbacrule_add_host", { "host": host, "hostgroup": hostgroup, } ]) # Add hbacsvcs and hbacsvcgroups if hbacsvc is not None or hbacsvcgroup is not None: commands.append([ name, "hbacrule_add_service", { "hbacsvc": hbacsvc, "hbacsvcgroup": hbacsvcgroup, } ]) # Add users and groups if user is not None or group is not None: commands.append([ name, "hbacrule_add_user", { "user": user, "group": group, } ]) elif state == "absent": if action == "hbacrule": if res_find is not None: commands.append([name, "hbacrule_del", {}]) elif action == "member": if res_find is None: ansible_module.fail_json(msg="No hbacrule '%s'" % name) # Remove hosts and hostgroups if host is not None or hostgroup is not None: commands.append([ name, "hbacrule_remove_host", { "host": host, "hostgroup": hostgroup, } ]) # Remove hbacsvcs and hbacsvcgroups if hbacsvc is not None or hbacsvcgroup is not None: commands.append([ name, "hbacrule_remove_service", { "hbacsvc": hbacsvc, "hbacsvcgroup": hbacsvcgroup, } ]) # Remove users and groups if user is not None or group is not None: commands.append([ name, "hbacrule_remove_user", { "user": user, "group": group, } ]) elif state == "enabled": if res_find is None: ansible_module.fail_json(msg="No hbacrule '%s'" % name) # hbacrule_enable is not failing on an enabled hbacrule # Therefore it is needed to have a look at the ipaenabledflag # in res_find. if "ipaenabledflag" not in res_find or \ res_find["ipaenabledflag"][0] != "TRUE": commands.append([name, "hbacrule_enable", {}]) elif state == "disabled": if res_find is None: ansible_module.fail_json(msg="No hbacrule '%s'" % name) # hbacrule_disable is not failing on an disabled hbacrule # Therefore it is needed to have a look at the ipaenabledflag # in res_find. if "ipaenabledflag" not in res_find or \ res_find["ipaenabledflag"][0] != "FALSE": commands.append([name, "hbacrule_disable", {}]) else: ansible_module.fail_json(msg="Unkown state '%s'" % state) # Execute commands errors = [] for name, command, args in commands: try: result = api_command(ansible_module, command, name, args) if "completed" in result: if result["completed"] > 0: changed = True else: changed = True except Exception as e: ansible_module.fail_json(msg="%s: %s: %s" % (command, name, str(e))) # Get all errors # All "already a member" and "not a member" failures in the # result are ignored. All others are reported. if "failed" in result and len(result["failed"]) > 0: for item in result["failed"]: failed_item = result["failed"][item] for member_type in failed_item: for member, failure in failed_item[member_type]: if "already a member" in failure \ or "not a member" in failure: continue errors.append( "%s: %s %s: %s" % (command, member_type, member, failure)) if len(errors) > 0: ansible_module.fail_json(msg=", ".join(errors)) except Exception as e: ansible_module.fail_json(msg=str(e)) finally: temp_kdestroy(ccache_dir, ccache_name) # Done ansible_module.exit_json(changed=changed, **exit_args)
def main(): ansible_module = AnsibleModule( argument_spec=dict( ### server ### setup_kra=dict(required=False, type='bool'), ### certificate system ### subject_base=dict(required=True), ### additional ### ccache=dict(required=True), _top_dir=dict(required=True), config_setup_ca=dict(required=True, type='bool'), config_master_host_name=dict(required=True), ), supports_check_mode=True, ) ansible_module._ansible_debug = True ansible_log = AnsibleModuleLog(ansible_module) # get parameters # options = installer ### server ### options.setup_kra = ansible_module.params.get('setup_kra') ### certificate system ### options.subject_base = ansible_module.params.get('subject_base') if options.subject_base is not None: options.subject_base = DN(options.subject_base) ### additional ### ccache = ansible_module.params.get('ccache') os.environ['KRB5CCNAME'] = ccache options._top_dir = ansible_module.params.get('_top_dir') config_setup_ca = ansible_module.params.get('config_setup_ca') installer.setup_ca = config_setup_ca config_master_host_name = ansible_module.params.get( 'config_master_host_name') # init # fstore = sysrestore.FileStore(paths.SYSRESTORE) sstore = sysrestore.StateFile(paths.SYSRESTORE) ansible_log.debug("== INSTALL ==") promote = installer.promote env = gen_env_boostrap_finalize_core(paths.ETC_IPA, constants.DEFAULT_CONFIG) api_bootstrap_finalize(env) config = gen_ReplicaConfig() config.subject_base = options.subject_base config.setup_ca = config_setup_ca config.master_host_name = config_master_host_name remote_api = gen_remote_api(config.master_host_name, paths.ETC_IPA) installer._remote_api = remote_api conn = remote_api.Backend.ldap2 ccache = os.environ['KRB5CCNAME'] with redirect_stdout(ansible_log): ansible_log.debug("-- PROMOTE SSSD --") promote_sssd(config.host_name) # done # ansible_module.exit_json(changed=True)
def main(): ansible_module = AnsibleModule( argument_spec=dict( ### basic ### dm_password=dict(required=True, no_log=True), password=dict(required=True, no_log=True), master_password=dict(required=True, no_log=True), ip_addresses=dict(required=False, type='list', default=[]), domain=dict(required=True), realm=dict(required=True), hostname=dict(required=False), no_host_dns=dict(required=False, type='bool', default=False), ### server ### setup_adtrust=dict(required=False, type='bool', default=False), setup_kra=dict(required=False, type='bool', default=False), setup_dns=dict(required=False, type='bool', default=False), setup_ca=dict(required=False, type='bool', default=False), idstart=dict(required=True, type='int'), idmax=dict(required=True, type='int'), no_hbac_allow=dict(required=False, type='bool', default=False), no_pkinit=dict(required=False, type='bool', default=False), dirsrv_config_file=dict(required=False), dirsrv_cert_files=dict(required=False), _dirsrv_pkcs12_info=dict(required=False), ### certificate system ### external_ca=dict(required=False, type='bool', default=False), external_cert_files=dict(required=False, type='list', default=[]), subject_base=dict(required=False), _subject_base=dict(required=False), ca_subject=dict(required=False), _ca_subject=dict(required=False), ca_signing_algorithm=dict(required=False), ### dns ### reverse_zones=dict(required=False, type='list', default=[]), no_reverse=dict(required=False, type='bool', default=False), auto_forwarders=dict(required=False, type='bool', default=False), ### additional ### domainlevel=dict(required=False, type='int'), _http_ca_cert=dict(required=False), ), ) ansible_module._ansible_debug = True ansible_log = AnsibleModuleLog(ansible_module) # set values ############################################################ ### basic ### options.dm_password = ansible_module.params.get('dm_password') options.admin_password = ansible_module.params.get('password') options.master_password = ansible_module.params.get('master_password') options.ip_addresses = ansible_module_get_parsed_ip_addresses( ansible_module) options.domain_name = ansible_module.params.get('domain') options.realm_name = ansible_module.params.get('realm') options.host_name = ansible_module.params.get('hostname') options.no_host_dns = ansible_module.params.get('no_host_dns') ### server ### options.setup_adtrust = ansible_module.params.get('setup_adtrust') options.setup_kra = ansible_module.params.get('setup_kra') options.setup_dns = ansible_module.params.get('setup_dns') options.setup_ca = ansible_module.params.get('setup_ca') options.idstart = ansible_module.params.get('idstart') options.idmax = ansible_module.params.get('idmax') options.no_hbac_allow = ansible_module.params.get('no_hbac_allow') options.no_pkinit = ansible_module.params.get('no_pkinit') options.dirsrv_config_file = ansible_module.params.get( 'dirsrv_config_file') options.dirsrv_cert_files = ansible_module.params.get('dirsrv_cert_files') options._dirsrv_pkcs12_info = ansible_module.params.get( '_dirsrv_pkcs12_info') ### certificate system ### options.external_ca = ansible_module.params.get('external_ca') options.external_cert_files = ansible_module.params.get( 'external_cert_files') options.subject_base = ansible_module.params.get('subject_base') options._subject_base = ansible_module.params.get('_subject_base') options.ca_subject = ansible_module.params.get('ca_subject') options._ca_subject = ansible_module.params.get('_ca_subject') options.ca_signing_algorithm = ansible_module.params.get( 'ca_signing_algorithm') ### dns ### options.reverse_zones = ansible_module.params.get('reverse_zones') options.no_reverse = ansible_module.params.get('no_reverse') options.auto_forwarders = ansible_module.params.get('auto_forwarders') ### additional ### options.domainlevel = ansible_module.params.get('domainlevel') options._http_ca_cert = ansible_module.params.get('_http_ca_cert') #options._update_hosts_file = ansible_module.params.get('update_hosts_file') # init ################################################################# fstore = sysrestore.FileStore(paths.SYSRESTORE) api_Backend_ldap2(options.host_name, options.setup_ca, connect=True) ds = ds_init_info(ansible_log, fstore, options.domainlevel, options.dirsrv_config_file, options.realm_name, options.host_name, options.domain_name, options.dm_password, options.idstart, options.idmax, options.subject_base, options.ca_subject, options.no_hbac_allow, options._dirsrv_pkcs12_info, options.no_pkinit) # setup CA ############################################################## with redirect_stdout(ansible_log): if options.setup_ca: if not options.external_cert_files and options.external_ca: # stage 1 of external CA installation cache_vars = { n: options.__dict__[n] for o, n in options.knobs() if n in options.__dict__ } write_cache(cache_vars) ca.install_step_0(False, None, options) else: # Put the CA cert where other instances expect it x509.write_certificate(options._http_ca_cert, paths.IPA_CA_CRT) os.chmod(paths.IPA_CA_CRT, 0o444) if not options.no_pkinit: x509.write_certificate(options._http_ca_cert, paths.KDC_CA_BUNDLE_PEM) else: with open(paths.KDC_CA_BUNDLE_PEM, 'w'): pass os.chmod(paths.KDC_CA_BUNDLE_PEM, 0o444) x509.write_certificate(options._http_ca_cert, paths.CA_BUNDLE_PEM) os.chmod(paths.CA_BUNDLE_PEM, 0o444) with redirect_stdout(ansible_log): # we now need to enable ssl on the ds ds.enable_ssl() if options.setup_ca: with redirect_stdout(ansible_log): ca.install_step_1(False, None, options) ansible_module.exit_json(changed=True)
def main(): ansible_module = AnsibleModule( argument_spec=dict( ### basic ### dm_password=dict(required=False, no_log=True), password=dict(required=False, no_log=True), ip_addresses=dict(required=False, type='list', default=[]), domain=dict(required=False), realm=dict(required=False), hostname=dict(required=False), ca_cert_files=dict(required=False, type='list', default=[]), no_host_dns=dict(required=False, type='bool', default=False), ### server ### setup_adtrust=dict(required=False, type='bool'), setup_ca=dict(required=False, type='bool'), setup_kra=dict(required=False, type='bool'), setup_dns=dict(required=False, type='bool'), ### ssl certificate ### dirsrv_cert_files=dict(required=False, type='list', default=[]), ### client ### force_join=dict(required=False, type='bool'), ### certificate system ### subject_base=dict(required=True), ### additional ### server=dict(required=True), config_master_host_name=dict(required=True), ccache=dict(required=True), installer_ccache=dict(required=True), _ca_enabled=dict(required=False, type='bool'), _kra_enabled=dict(required=False, type='bool'), _dirsrv_pkcs12_info=dict(required=False), _http_pkcs12_info=dict(required=False), _pkinit_pkcs12_info=dict(required=False), _top_dir=dict(required=True), _add_to_ipaservers=dict(required=True, type='bool'), _ca_subject=dict(required=True), _subject_base=dict(required=True), dirman_password=dict(required=True, no_log=True), ), supports_check_mode=True, ) ansible_module._ansible_debug = True ansible_log = AnsibleModuleLog(ansible_module) # get parameters # options = installer options.dm_password = ansible_module.params.get('dm_password') options.password = options.dm_password options.admin_password = ansible_module.params.get('password') options.ip_addresses = ansible_module_get_parsed_ip_addresses( ansible_module) options.domain_name = ansible_module.params.get('domain') options.realm_name = ansible_module.params.get('realm') options.host_name = ansible_module.params.get('hostname') options.ca_cert_files = ansible_module.params.get('ca_cert_files') options.no_host_dns = ansible_module.params.get('no_host_dns') ### server ### options.setup_adtrust = ansible_module.params.get('setup_adtrust') options.setup_ca = ansible_module.params.get('setup_ca') options.setup_kra = ansible_module.params.get('setup_kra') options.setup_dns = ansible_module.params.get('setup_dns') ### ssl certificate ### options.dirsrv_cert_files = ansible_module.params.get('dirsrv_cert_files') ### client ### options.force_join = ansible_module.params.get('force_join') ### certificate system ### options.external_ca = ansible_module.params.get('external_ca') options.external_cert_files = ansible_module.params.get( 'external_cert_files') options.subject_base = ansible_module.params.get('subject_base') if options.subject_base is not None: options.subject_base = DN(options.subject_base) options.ca_subject = ansible_module.params.get('ca_subject') ### additional ### #options._host_name_overridden = ansible_module.params.get( # '_hostname_overridden') options.server = ansible_module.params.get('server') master_host_name = ansible_module.params.get('config_master_host_name') ccache = ansible_module.params.get('ccache') os.environ['KRB5CCNAME'] = ccache #os.environ['KRB5CCNAME'] = ansible_module.params.get('installer_ccache') installer._ccache = ansible_module.params.get('installer_ccache') ca_enabled = ansible_module.params.get('_ca_enabled') kra_enabled = ansible_module.params.get('_kra_enabled') dirsrv_pkcs12_info = ansible_module.params.get('_dirsrv_pkcs12_info') http_pkcs12_info = ansible_module.params.get('_http_pkcs12_info') pkinit_pkcs12_info = ansible_module.params.get('_pkinit_pkcs12_info') options.subject_base = ansible_module.params.get('subject_base') if options.subject_base is not None: options.subject_base = DN(options.subject_base) options._top_dir = ansible_module.params.get('_top_dir') options._add_to_ipaservers = ansible_module.params.get( '_add_to_ipaservers') options._ca_subject = ansible_module.params.get('_ca_subject') options._subject_base = ansible_module.params.get('_subject_base') dirman_password = ansible_module.params.get('dirman_password') # init # fstore = sysrestore.FileStore(paths.SYSRESTORE) sstore = sysrestore.StateFile(paths.SYSRESTORE) # prepare (install prepare, install checks) # ansible_log.debug("== INSTALL ==") options = installer promote = installer.promote env = gen_env_boostrap_finalize_core(paths.ETC_IPA, constants.DEFAULT_CONFIG) api_bootstrap_finalize(env) config = gen_ReplicaConfig() config.subject_base = options.subject_base config.dirman_password = dirman_password remote_api = gen_remote_api(master_host_name, paths.ETC_IPA) installer._remote_api = remote_api conn = remote_api.Backend.ldap2 ccache = os.environ['KRB5CCNAME'] cafile = paths.IPA_CA_CRT if promote: ansible_log.debug("-- CREATE_IPA_CONF --") # Create the management framework config file. Do this irregardless # of the state of DS installation. Even if it fails, # we need to have master-like configuration in order to perform a # successful uninstallation # The configuration creation has to be here otherwise previous call # To config certmonger would try to connect to local server create_ipa_conf(fstore, config, ca_enabled) # done # ansible_module.exit_json(changed=True)
def main(): ansible_module = AnsibleModule( argument_spec=dict( # general ipaadmin_principal=dict(type="str", default="admin"), ipaadmin_password=dict(type="str", required=False, no_log=True), inclusive=dict(type="list", aliases=["automemberinclusiveregex"], default=None), exclusive=dict(type="list", aliases=["automemberexclusiveregex"], default=None), name=dict(type="list", aliases=["cn"], default=None, required=True), description=dict(type="str", default=None), automember_type=dict(type='str', required=False, choices=['group', 'hostgroup']), action=dict(type="str", default="service", choices=["member", "service"]), state=dict(type="str", default="present", choices=["present", "absent", "rebuild"]), users=dict(type="list", default=None), hosts=dict(type="list", default=None), ), supports_check_mode=True, ) ansible_module._ansible_debug = True # Get parameters # general ipaadmin_principal = ansible_module.params.get("ipaadmin_principal") ipaadmin_password = ansible_module.params.get("ipaadmin_password") names = ansible_module.params.get("name") # present description = ansible_module.params.get("description") # conditions inclusive = ansible_module.params.get("inclusive") exclusive = ansible_module.params.get("exclusive") # action action = ansible_module.params.get("action") # state state = ansible_module.params.get("state") # grouping/type automember_type = ansible_module.params.get("automember_type") rebuild_users = ansible_module.params.get("users") rebuild_hosts = ansible_module.params.get("hosts") if (rebuild_hosts or rebuild_users) and state != "rebuild": ansible_module.fail_json( msg="'hosts' and 'users' are only valid with state: rebuild") if not automember_type and state != "rebuild": ansible_module.fail_json( msg="'automember_type' is required unless state: rebuild") # Init changed = False exit_args = {} ccache_dir = None ccache_name = None res_find = None try: if not valid_creds(ansible_module, ipaadmin_principal): ccache_dir, ccache_name = temp_kinit(ipaadmin_principal, ipaadmin_password) api_connect() commands = [] for name in names: # Make sure automember rule exists res_find = find_automember(ansible_module, name, automember_type) # Create command if state == 'present': args = gen_args(description, automember_type) if action == "service": if res_find is not None: if not compare_args_ipa( ansible_module, args, res_find, ignore=['type']): commands.append([name, 'automember_mod', args]) else: commands.append([name, 'automember_add', args]) res_find = {} inclusive_add, inclusive_del = gen_add_del_lists( transform_conditions(inclusive or []), res_find.get("automemberinclusiveregex", [])) exclusive_add, exclusive_del = gen_add_del_lists( transform_conditions(exclusive or []), res_find.get("automemberexclusiveregex", [])) elif action == "member": if res_find is None: ansible_module.fail_json(msg="No service '%s'" % name) inclusive_add = transform_conditions(inclusive or []) inclusive_del = [] exclusive_add = transform_conditions(exclusive or []) exclusive_del = [] for _inclusive in inclusive_add: key, regex = _inclusive.split("=", 1) condition_args = gen_condition_args(automember_type, key, inclusiveregex=regex) commands.append( [name, 'automember_add_condition', condition_args]) for _inclusive in inclusive_del: key, regex = _inclusive.split("=", 1) condition_args = gen_condition_args(automember_type, key, inclusiveregex=regex) commands.append( [name, 'automember_remove_condition', condition_args]) for _exclusive in exclusive_add: key, regex = _exclusive.split("=", 1) condition_args = gen_condition_args(automember_type, key, exclusiveregex=regex) commands.append( [name, 'automember_add_condition', condition_args]) for _exclusive in exclusive_del: key, regex = _exclusive.split("=", 1) condition_args = gen_condition_args(automember_type, key, exclusiveregex=regex) commands.append( [name, 'automember_remove_condition', condition_args]) elif state == 'absent': if action == "service": if res_find is not None: commands.append([ name, 'automember_del', { 'type': to_text(automember_type) } ]) elif action == "member": if res_find is None: ansible_module.fail_json(msg="No service '%s'" % name) if inclusive is not None: for _inclusive in transform_conditions(inclusive): key, regex = _inclusive.split("=", 1) condition_args = gen_condition_args( automember_type, key, inclusiveregex=regex) commands.append([ name, 'automember_remove_condition', condition_args ]) if exclusive is not None: for _exclusive in transform_conditions(exclusive): key, regex = _exclusive.split("=", 1) condition_args = gen_condition_args( automember_type, key, exclusiveregex=regex) commands.append([ name, 'automember_remove_condition', condition_args ]) elif state == "rebuild": if automember_type: commands.append([ None, 'automember_rebuild', { "type": to_text(automember_type) } ]) if rebuild_users: commands.append([ None, 'automember_rebuild', { "users": [to_text(_u) for _u in rebuild_users] } ]) if rebuild_hosts: commands.append([ None, 'automember_rebuild', { "hosts": [to_text(_h) for _h in rebuild_hosts] } ]) # Check mode exit if ansible_module.check_mode: ansible_module.exit_json(changed=len(commands) > 0, **exit_args) errors = [] for name, command, args in commands: try: if name is None: result = api_command_no_name(ansible_module, command, args) else: result = api_command(ansible_module, command, to_text(name), args) if "completed" in result: if result["completed"] > 0: changed = True else: changed = True except Exception as ex: ansible_module.fail_json(msg="%s: %s: %s" % (command, name, str(ex))) # Get all errors if "failed" in result and len(result["failed"]) > 0: for item in result["failed"]: failed_item = result["failed"][item] for member_type in failed_item: for member, failure in failed_item[member_type]: errors.append( "%s: %s %s: %s" % (command, member_type, member, failure)) if len(errors) > 0: ansible_module.fail_json(msg=", ".join(errors)) except Exception as e: ansible_module.fail_json(msg=str(e)) finally: temp_kdestroy(ccache_dir, ccache_name) # Done ansible_module.exit_json(changed=changed, **exit_args)
def main(): ansible_module = AnsibleModule( argument_spec=dict( # general ipaadmin_principal=dict(type="str", default="admin"), ipaadmin_password=dict(type="str", required=False, no_log=True), name=dict(type="list", aliases=["cn"], default=None, required=True), # present description=dict(type="str", default=None), nomembers=dict(required=False, type='bool', default=None), host=dict(required=False, type='list', default=None), hostgroup=dict(required=False, type='list', default=None), membermanager_user=dict(required=False, type='list', default=None), membermanager_group=dict(required=False, type='list', default=None), action=dict(type="str", default="hostgroup", choices=["member", "hostgroup"]), # state state=dict(type="str", default="present", choices=["present", "absent"]), ), supports_check_mode=True, ) ansible_module._ansible_debug = True # Get parameters # general ipaadmin_principal = module_params_get(ansible_module, "ipaadmin_principal") ipaadmin_password = module_params_get(ansible_module, "ipaadmin_password") names = module_params_get(ansible_module, "name") # present description = module_params_get(ansible_module, "description") nomembers = module_params_get(ansible_module, "nomembers") host = module_params_get(ansible_module, "host") hostgroup = module_params_get(ansible_module, "hostgroup") membermanager_user = module_params_get(ansible_module, "membermanager_user") membermanager_group = module_params_get(ansible_module, "membermanager_group") action = module_params_get(ansible_module, "action") # state state = module_params_get(ansible_module, "state") # Check parameters if state == "present": if len(names) != 1: ansible_module.fail_json( msg="Only one hostgroup can be added at a time.") if action == "member": invalid = ["description", "nomembers"] for x in invalid: if vars()[x] is not None: ansible_module.fail_json( msg="Argument '%s' can not be used with action " "'%s'" % (x, action)) if state == "absent": if len(names) < 1: ansible_module.fail_json(msg="No name given.") invalid = ["description", "nomembers"] if action == "hostgroup": invalid.extend(["host", "hostgroup"]) for x in invalid: if vars()[x] is not None: ansible_module.fail_json( msg="Argument '%s' can not be used with state '%s'" % (x, state)) # Init changed = False exit_args = {} ccache_dir = None ccache_name = None try: if not valid_creds(ansible_module, ipaadmin_principal): ccache_dir, ccache_name = temp_kinit(ipaadmin_principal, ipaadmin_password) api_connect() has_add_membermanager = api_check_command( "hostgroup_add_member_manager") if ((membermanager_user is not None or membermanager_group is not None) and not has_add_membermanager): ansible_module.fail_json( msg="Managing a membermanager user or group is not supported " "by your IPA version") commands = [] for name in names: # Make sure hostgroup exists res_find = find_hostgroup(ansible_module, name) # Create command if state == "present": # Generate args args = gen_args(description, nomembers) if action == "hostgroup": # Found the hostgroup if res_find is not None: # For all settings is args, check if there are # different settings in the find result. # If yes: modify if not compare_args_ipa(ansible_module, args, res_find): commands.append([name, "hostgroup_mod", args]) else: commands.append([name, "hostgroup_add", args]) # Set res_find to empty dict for next step res_find = {} member_args = gen_member_args(host, hostgroup) if not compare_args_ipa(ansible_module, member_args, res_find): # Generate addition and removal lists host_add, host_del = gen_add_del_lists( host, res_find.get("member_host")) hostgroup_add, hostgroup_del = gen_add_del_lists( hostgroup, res_find.get("member_hostgroup")) # Add members if len(host_add) > 0 or len(hostgroup_add) > 0: commands.append([ name, "hostgroup_add_member", { "host": host_add, "hostgroup": hostgroup_add, } ]) # Remove members if len(host_del) > 0 or len(hostgroup_del) > 0: commands.append([ name, "hostgroup_remove_member", { "host": host_del, "hostgroup": hostgroup_del, } ]) membermanager_user_add, membermanager_user_del = \ gen_add_del_lists( membermanager_user, res_find.get("membermanager_user") ) membermanager_group_add, membermanager_group_del = \ gen_add_del_lists( membermanager_group, res_find.get("membermanager_group") ) if has_add_membermanager: # Add membermanager users and groups if len(membermanager_user_add) > 0 or \ len(membermanager_group_add) > 0: commands.append([ name, "hostgroup_add_member_manager", { "user": membermanager_user_add, "group": membermanager_group_add, } ]) # Remove member manager if len(membermanager_user_del) > 0 or \ len(membermanager_group_del) > 0: commands.append([ name, "hostgroup_remove_member_manager", { "user": membermanager_user_del, "group": membermanager_group_del, } ]) elif action == "member": if res_find is None: ansible_module.fail_json(msg="No hostgroup '%s'" % name) # Ensure members are present commands.append([ name, "hostgroup_add_member", { "host": host, "hostgroup": hostgroup, } ]) if has_add_membermanager: # Add membermanager users and groups if membermanager_user is not None or \ membermanager_group is not None: commands.append([ name, "hostgroup_add_member_manager", { "user": membermanager_user, "group": membermanager_group, } ]) elif state == "absent": if action == "hostgroup": if res_find is not None: commands.append([name, "hostgroup_del", {}]) elif action == "member": if res_find is None: ansible_module.fail_json(msg="No hostgroup '%s'" % name) # Ensure members are absent commands.append([ name, "hostgroup_remove_member", { "host": host, "hostgroup": hostgroup, } ]) if has_add_membermanager: # Remove membermanager users and groups if membermanager_user is not None or \ membermanager_group is not None: commands.append([ name, "hostgroup_remove_member_manager", { "user": membermanager_user, "group": membermanager_group, } ]) else: ansible_module.fail_json(msg="Unkown state '%s'" % state) # Execute commands for name, command, args in commands: try: result = api_command(ansible_module, command, name, args) if "completed" in result: if result["completed"] > 0: changed = True else: changed = True except Exception as e: ansible_module.fail_json(msg="%s: %s: %s" % (command, name, str(e))) # Get all errors # All "already a member" and "not a member" failures in the # result are ignored. All others are reported. errors = [] for failed_item in result.get("failed", []): failed = result["failed"][failed_item] for member_type in failed: for member, failure in failed[member_type]: if "already a member" in failure \ or "not a member" in failure: continue errors.append("%s: %s %s: %s" % (command, member_type, member, failure)) if len(errors) > 0: ansible_module.fail_json(msg=", ".join(errors)) except Exception as e: ansible_module.fail_json(msg=str(e)) finally: temp_kdestroy(ccache_dir, ccache_name) # Done ansible_module.exit_json(changed=changed, **exit_args)
def main(): ansible_module = AnsibleModule( argument_spec=dict( # server setup_ca=dict(required=False, type='bool'), setup_kra=dict(required=False, type='bool'), no_pkinit=dict(required=False, type='bool'), dirsrv_config_file=dict(required=False), # certificate system subject_base=dict(required=True), # additional config_master_host_name=dict(required=True), ccache=dict(required=True), _ca_enabled=dict(required=False, type='bool'), _ca_file=dict(required=False), _dirsrv_pkcs12_info=dict(required=False, type='list'), _pkinit_pkcs12_info=dict(required=False, type='list'), _top_dir=dict(required=True), dirman_password=dict(required=True, no_log=True), ds_ca_subject=dict(required=True), ), supports_check_mode=True, ) ansible_module._ansible_debug = True setup_logging() ansible_log = AnsibleModuleLog(ansible_module) # get parameters # options = installer # server options.setup_ca = ansible_module.params.get('setup_ca') options.setup_kra = ansible_module.params.get('setup_kra') options.no_pkinit = ansible_module.params.get('no_pkinit') options.dirsrv_config_file = ansible_module.params.get( 'dirsrv_config_file') # certificate system options.subject_base = ansible_module.params.get('subject_base') if options.subject_base is not None: options.subject_base = DN(options.subject_base) # additional master_host_name = ansible_module.params.get('config_master_host_name') ccache = ansible_module.params.get('ccache') os.environ['KRB5CCNAME'] = ccache # os.environ['KRB5CCNAME'] = ansible_module.params.get('installer_ccache') # installer._ccache = ansible_module.params.get('installer_ccache') ca_enabled = ansible_module.params.get('_ca_enabled') options._dirsrv_pkcs12_info = ansible_module.params.get( '_dirsrv_pkcs12_info') options._pkinit_pkcs12_info = ansible_module.params.get( '_pkinit_pkcs12_info') options._top_dir = ansible_module.params.get('_top_dir') dirman_password = ansible_module.params.get('dirman_password') ds_ca_subject = ansible_module.params.get('ds_ca_subject') # init # ansible_log.debug("== INSTALL ==") options = installer promote = installer.promote env = gen_env_boostrap_finalize_core(paths.ETC_IPA, constants.DEFAULT_CONFIG) api_bootstrap_finalize(env) config = gen_ReplicaConfig() config.dirman_password = dirman_password config.subject_base = options.subject_base remote_api = gen_remote_api(master_host_name, paths.ETC_IPA) # installer._remote_api = remote_api conn = remote_api.Backend.ldap2 ccache = os.environ['KRB5CCNAME'] # There is a api.Backend.ldap2.connect call somewhere in ca, ds, dns or # ntpinstance api.Backend.ldap2.connect() conn.connect(ccache=ccache) with redirect_stdout(ansible_log): ds = replica_ds_init_info(ansible_log, config, options, ca_enabled, remote_api, ds_ca_subject, ca_file=paths.IPA_CA_CRT, promote=promote, pkcs12_info=installer._dirsrv_pkcs12_info) ansible_log.debug("-- DS.ENABLE_SSL --") # we now need to enable ssl on the ds ds.enable_ssl() # done # ansible_module.exit_json(changed=True)
def main(): module = AnsibleModule( argument_spec = dict( servers=dict(required=True, type='list'), realm=dict(required=True), hostname=dict(required=True), debug=dict(required=False, type='bool', default="false") ), supports_check_mode = True, ) module._ansible_debug = True realm = module.params.get('realm') hostname = module.params.get('hostname') servers = module.params.get('servers') debug = module.params.get('debug') fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE) statestore = sysrestore.StateFile(paths.IPA_CLIENT_SYSRESTORE) host_principal = 'host/%s@%s' % (hostname, realm) os.environ['KRB5CCNAME'] = paths.IPA_DNS_CCACHE ca_certs = x509.load_certificate_list_from_file(paths.IPA_CA_CRT) if NUM_VERSION >= 40500 and NUM_VERSION < 40590: ca_certs = [ cert.public_bytes(serialization.Encoding.DER) for cert in ca_certs ] elif NUM_VERSION < 40500: ca_certs = [ cert.der_data for cert in ca_certs ] with certdb.NSSDatabase() as tmp_db: api.bootstrap(context='cli_installer', confdir=paths.ETC_IPA, debug=debug, delegate=False, nss_dir=tmp_db.secdir) if 'config_loaded' not in api.env: module.fail_json(msg="Failed to initialize IPA API.") # Clear out any current session keyring information try: delete_persistent_client_session_data(host_principal) except ValueError: pass # Add CA certs to a temporary NSS database argspec = inspect.getargspec(tmp_db.create_db) try: if NUM_VERSION > 40404: tmp_db.create_db() for i, cert in enumerate(ca_certs): tmp_db.add_cert(cert, 'CA certificate %d' % (i + 1), certdb.EXTERNAL_CA_TRUST_FLAGS) else: pwd_file = write_tmp_file(ipa_generate_password()) tmp_db.create_db(pwd_file.name) for i, cert in enumerate(ca_certs): tmp_db.add_cert(cert, 'CA certificate %d' % (i + 1), 'C,,') except CalledProcessError as e: module.fail_json(msg="Failed to add CA to temporary NSS database.") api.finalize() # Now, let's try to connect to the server's RPC interface connected = False try: api.Backend.rpcclient.connect() connected = True module.debug("Try RPC connection") api.Backend.rpcclient.forward('ping') except errors.KerberosError as e: if connected: api.Backend.rpcclient.disconnect() module.log( "Cannot connect to the server due to Kerberos error: %s. " "Trying with delegate=True" % e) try: api.Backend.rpcclient.connect(delegate=True) module.debug("Try RPC connection") api.Backend.rpcclient.forward('ping') module.log("Connection with delegate=True successful") # The remote server is not capable of Kerberos S4U2Proxy # delegation. This features is implemented in IPA server # version 2.2 and higher module.warn( "Target IPA server has a lower version than the enrolled " "client") module.warn( "Some capabilities including the ipa command capability " "may not be available") except errors.PublicError as e2: module.fail_json( msg="Cannot connect to the IPA server RPC interface: %s" % e2) except errors.PublicError as e: module.fail_json( msg="Cannot connect to the server due to generic error: %s" % e) # Use the RPC directly so older servers are supported try: result = api.Backend.rpcclient.forward( 'ca_is_enabled', version=u'2.107', ) ca_enabled = result['result'] except (errors.CommandError, errors.NetworkError): result = api.Backend.rpcclient.forward( 'env', server=True, version=u'2.0', ) ca_enabled = result['result']['enable_ra'] if not ca_enabled: disable_ra() # Get subject base from ipa server try: config = api.Command['config_show']()['result'] subject_base = str(DN(config['ipacertificatesubjectbase'][0])) except errors.PublicError as e: module.fail_json(msg="Cannot get subject base from server: %s" % e) module.exit_json(changed=True, ca_enabled=ca_enabled, subject_base=subject_base)
def main(): module = AnsibleModule( argument_spec=dict( servers=dict(required=True, type='list'), domain=dict(required=True), ntp=dict(required=False, type='bool', default='no'), force_ntpd=dict(required=False, type='bool', default='no'), ntp_servers=dict(required=False, type='list'), ssh=dict(required=False, type='bool', default='yes'), sssd=dict(required=False, type='bool', default='yes'), trust_sshfp=dict(required=False, type='bool', default='yes'), sshd=dict(required=False, type='bool', default='yes'), automount_location=dict(required=False), firefox=dict(required=False, type='bool', default='no'), firefox_dir=dict(required=False), no_nisdomain=dict(required=False, type='bool', default='no'), nisdomain=dict(required=False), on_master=dict(required=False, type='bool', default='no'), ), supports_check_mode=True, ) module._ansible_debug = True servers = module.params.get('servers') domain = module.params.get('domain') ntp = module.params.get('ntp') force_ntpd = module.params.get('force_ntpd') ntp_servers = module.params.get('ntp_servers') ssh = module.params.get('ssh') sssd = module.params.get('sssd') trust_sshfp = module.params.get('trust_sshfp') sshd = module.params.get('sshd') automount_location = module.params.get('automount_location') firefox = module.params.get('firefox') firefox_dir = module.params.get('firefox_dir') no_nisdomain = module.params.get('no_nisdomain') nisdomain = module.params.get('nisdomain') on_master = module.params.get('on_master') fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE) statestore = sysrestore.StateFile(paths.IPA_CLIENT_SYSRESTORE) logger = logging.getLogger("ipa-client-install") os.environ['KRB5CCNAME'] = CCACHE_FILE class Object(object): pass options = Object() options.sssd = sssd options.trust_sshfp = trust_sshfp options.location = automount_location options.server = servers options.firefox_dir = firefox_dir options.nisdomain = nisdomain if ntp and not on_master: # disable other time&date services first if force_ntpd: ntpconf.force_ntpd(statestore) ntpconf.config_ntp(ntp_servers, fstore, statestore) module.log("NTP enabled") if ssh: configure_ssh_config(fstore, options) if sshd: configure_sshd_config(fstore, options) if automount_location: configure_automount(options) if firefox: configure_firefox(options, statestore, domain) if not no_nisdomain: configure_nisdomain(options=options, domain=domain, statestore=statestore) # Cleanup: Remove CCACHE_FILE try: os.remove(CCACHE_FILE) except Exception: pass module.exit_json(changed=True)
def main(): ansible_module = AnsibleModule( argument_spec = dict( ### basic ### #dm_password=dict(required=False, no_log=True), #password=dict(required=False, no_log=True), ip_addresses=dict(required=False, type='list', default=[]), domain=dict(required=False), servers=dict(required=False, type='list', default=[]), realm=dict(required=False), hostname=dict(required=False), ca_cert_files=dict(required=False, type='list', default=[]), ### server ### setup_adtrust=dict(required=False, type='bool', default=False), setup_kra=dict(required=False, type='bool', default=False), setup_dns=dict(required=False, type='bool', default=False), no_pkinit=dict(required=False, type='bool', default=False), dirsrv_config_file=dict(required=False), ### ssl certificate ### dirsrv_cert_files=dict(required=False, type='list', default=[]), http_cert_files=dict(required=False, type='list', default=[]), pkinit_cert_files=dict(required=False, type='list', default=[]), ### client ### no_ntp=dict(required=False, type='bool', default=False), ntp_servers=dict(required=False, type='list', default=[]), ntp_pool=dict(required=False), ### dns ### no_reverse=dict(required=False, type='bool', default=False), auto_reverse=dict(required=False, type='bool', default=False), forwarders=dict(required=False, type='list', default=[]), no_forwarders=dict(required=False, type='bool', default=False), auto_forwarders=dict(required=False, type='bool', default=False), forward_policy=dict(default=None, choices=['first', 'only']), no_dnssec_validation=dict(required=False, type='bool', default=False), ), ) ansible_module._ansible_debug = True ansible_log = AnsibleModuleLog(ansible_module) # get parameters # ### basic ### #options.dm_password = ansible_module.params.get('dm_password') ##options.password = ansible_module.params.get('password') #options.password = options.dm_password options.ip_addresses = ansible_module_get_parsed_ip_addresses( ansible_module) options.domain_name = ansible_module.params.get('domain') options.servers = ansible_module.params.get('servers') options.realm_name = ansible_module.params.get('realm') options.host_name = ansible_module.params.get('hostname') options.ca_cert_files = ansible_module.params.get('ca_cert_files') ### server ### options.setup_adtrust = ansible_module.params.get('setup_adtrust') options.setup_kra = ansible_module.params.get('setup_kra') options.setup_dns = ansible_module.params.get('setup_dns') options.no_pkinit = ansible_module.params.get('no_pkinit') options.dirsrv_config_file = ansible_module.params.get('dirsrv_config_file') ### ssl certificate ### options.dirsrv_cert_files = ansible_module.params.get('dirsrv_cert_files') options.http_cert_files = ansible_module.params.get('http_cert_files') options.pkinit_cert_files = ansible_module.params.get('pkinit_cert_files') ### client ### options.no_ntp = ansible_module.params.get('no_ntp') options.ntp_servers = ansible_module.params.get('ntp_servers') options.ntp_pool = ansible_module.params.get('ntp_pool') ### dns ### options.no_reverse = ansible_module.params.get('no_reverse') options.auto_reverse = ansible_module.params.get('auto_reverse') options.forwarders = ansible_module.params.get('forwarders') options.no_forwarders = ansible_module.params.get('no_forwarders') options.auto_forwarders = ansible_module.params.get('auto_forwarders') options.forward_policy = ansible_module.params.get('forward_policy') options.no_dnssec_validation = ansible_module.params.get( 'no_dnssec_validation') ########################################################################## # replica init ########################################################### ########################################################################## if installer.servers: installer.server = installer.servers[0] else: installer.server = None # TODO: Kills ipa-client-install #if installer.replica_file is None: # installer.password = installer.admin_password #else: # installer.password = installer.dm_password #installer._ccache = os.environ.get('KRB5CCNAME') # If not defined, set domain from server name if installer.domain_name is None and installer.server is not None: installer.domain_name = installer.server[installer.server.find(".")+1:] # If not defined, set realm from domain name if installer.realm_name is None and installer.domain_name is not None: installer.realm_name = installer.domain_name.upper() ########################################################################## # other checks ########################################################### ########################################################################## # version specific tests # #if options.setup_adtrust and not adtrust_imported: # #if "adtrust" not in options._allow_missing: # ansible_module.fail_json(msg="adtrust can not be imported") # #else: # # options.setup_adtrust = False # # ansible_module.warn(msg="adtrust is not supported, disabling") #if options.setup_kra and not kra_imported: # #if "kra" not in options._allow_missing: # ansible_module.fail_json(msg="kra can not be imported") # #else: # # options.setup_kra = False # # ansible_module.warn(msg="kra is not supported, disabling") # From ipa installer classes # pkinit is not supported on DL0, don't allow related options if installer.replica_file is not None: ansible_module.fail_json( msg="Replica installation using a replica file is not supported") # If any of the key file options are selected, all are required. cert_file_req = (installer.dirsrv_cert_files, installer.http_cert_files) cert_file_opt = (installer.pkinit_cert_files,) if not installer.no_pkinit: cert_file_req += cert_file_opt if installer.no_pkinit and installer.pkinit_cert_files: ansible_module.fail_json( msg="--no-pkinit and --pkinit-cert-file cannot be specified " "together") if any(cert_file_req + cert_file_opt) and not all(cert_file_req): ansible_module.fail_json( msg="--dirsrv-cert-file, --http-cert-file, and --pkinit-cert-file " "or --no-pkinit are required if any key file options are used.") if not installer.setup_dns: if installer.forwarders: ansible_module.fail_json( msg="You cannot specify a --forwarder option without the " "--setup-dns option") if installer.auto_forwarders: ansible_module.fail_json( msg="You cannot specify a --auto-forwarders option without " "the --setup-dns option") if installer.no_forwarders: ansible_module.fail_json( msg="You cannot specify a --no-forwarders option without the " "--setup-dns option") if installer.forward_policy: ansible_module.fail_json( msg="You cannot specify a --forward-policy option without the " "--setup-dns option") if installer.reverse_zones: ansible_module.fail_json( msg="You cannot specify a --reverse-zone option without the " "--setup-dns option") if installer.auto_reverse: ansible_module.fail_json( msg="You cannot specify a --auto-reverse option without the " "--setup-dns option") if installer.no_reverse: ansible_module.fail_json( msg="You cannot specify a --no-reverse option without the " "--setup-dns option") if installer.no_dnssec_validation: ansible_module.fail_json( msg="You cannot specify a --no-dnssec-validation option " "without the --setup-dns option") elif installer.forwarders and installer.no_forwarders: ansible_module.fail_json( msg="You cannot specify a --forwarder option together with " "--no-forwarders") elif installer.auto_forwarders and installer.no_forwarders: ansible_module.fail_json( msg="You cannot specify a --auto-forwarders option together with " "--no-forwarders") elif installer.reverse_zones and installer.no_reverse: ansible_module.fail_json( msg="You cannot specify a --reverse-zone option together with " "--no-reverse") elif installer.auto_reverse and installer.no_reverse: ansible_module.fail_json( msg="You cannot specify a --auto-reverse option together with " "--no-reverse") # replica installers if installer.servers and not installer.domain_name: ansible_module.fail_json( msg="The --server option cannot be used without providing " "domain via the --domain option") if installer.setup_dns: if (not installer.forwarders and not installer.no_forwarders and not installer.auto_forwarders): ansible_module.fail_json( msg="You must specify at least one of --forwarder, " "--auto-forwarders, or --no-forwarders options") if installer.dirsrv_config_file is not None and not os.path.exists(installer.dirsrv_config_file): ansible_module.fail_json(msg="File %s does not exist." % installer.dirsrv_config_file) if installer.ca_cert_files is not None: if not isinstance(installer.ca_cert_files, list): ansible_module.fail_json(msg="Expected list, got {!r}".format(installer.ca_cert_files)) for cert in installer.ca_cert_files: if not os.path.exists(cert): ansible_module.fail_json(msg="'%s' does not exist" % cert) if not os.path.isfile(cert): ansible_module.fail_json(msg="'%s' is not a file" % cert) if not os.path.isabs(cert): ansible_module.fail_json(msg="'%s' is not an absolute file path" % cert) try: x509.load_certificate_from_file(cert) except Exception: ansible_module.fail_json(msg="'%s' is not a valid certificate file" % cert) if installer.ip_addresses is not None: for value in installer.ip_addresses: try: CheckedIPAddress(value) except Exception as e: ansible_module.fail_json(msg="invalid IP address {0}: {1}".format( value, e)) if installer.domain_name is not None: validate_domain_name(installer.domain_name) ########################################################################## # replica promote_check excerpts ######################################### ########################################################################## # check selinux status, http and DS ports, NTP conflicting services try: with redirect_stdout(ansible_log): common_check(options.no_ntp) except Exception as msg: #ScriptError as msg: _msg = str(msg) if "server is already configured" in _msg: ansible_module.exit_json(changed=False, server_already_configured=True) else: ansible_module.fail_json(msg=_msg) # TODO: Check ntp_servers and ntp_pool # client enrolled? client_fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE) client_enrolled = client_fstore.has_files() if not client_enrolled: ## One-step replica installation #if options.dm_password and options.password: # ansible_module.fail_json( # msg="--password and --admin-password options are " # "mutually exclusive") pass else: # The NTP configuration can not be touched on pre-installed client: if options.no_ntp or options.ntp_servers or options.ntp_pool: ansible_module.fail_json( msg="NTP configuration cannot be updated during promotion") # done # ansible_module.exit_json(changed=False, ipa_python_version=IPA_PYTHON_VERSION, ### basic ### domain=options.domain_name, realm=options.realm_name, hostname=options.host_name, ### server ### setup_adtrust=options.setup_adtrust, setup_kra=options.setup_kra, server=options.server, ### additional ### client_enrolled=client_enrolled, )
def main(): ansible_module = AnsibleModule( argument_spec=dict( # general ipaadmin_principal=dict(type="str", default="admin"), ipaadmin_password=dict(type="str", required=False, no_log=True), realm=dict(type="str", default=None, required=True), # state state=dict(type="str", default="present", choices=["present", "absent"]), # present trust_type=dict(type="str", default="ad", required=False), admin=dict(type="str", default=None, required=False), password=dict(type="str", default=None, required=False, no_log=True), server=dict(type="str", default=None, required=False), trust_secret=dict(type="str", default=None, required=False, no_log=True), base_id=dict(type="int", default=None, required=False), range_size=dict(type="int", default=200000, required=False), range_type=dict(type="str", default="ipa-ad-trust", required=False, choices=["ipa-ad-trust-posix", "ipa-ad-trust"]), two_way=dict(type="bool", default=False, required=False), external=dict(type="bool", default=False, required=False), ), mutually_exclusive=[["trust_secret", "admin"]], required_together=[["admin", "password"]], supports_check_mode=True) ansible_module._ansible_debug = True # general ipaadmin_principal = module_params_get(ansible_module, "ipaadmin_principal") ipaadmin_password = module_params_get(ansible_module, "ipaadmin_password") realm = module_params_get(ansible_module, "realm") # state state = module_params_get(ansible_module, "state") # trust trust_type = module_params_get(ansible_module, "trust_type") admin = module_params_get(ansible_module, "admin") password = module_params_get(ansible_module, "password") server = module_params_get(ansible_module, "server") trust_secret = module_params_get(ansible_module, "trust_secret") base_id = module_params_get(ansible_module, "base_id") range_size = module_params_get(ansible_module, "range_size") range_type = module_params_get(ansible_module, "range_type") two_way = module_params_get(ansible_module, "two_way") external = module_params_get(ansible_module, "external") changed = False exit_args = {} ccache_dir = None ccache_name = None try: if not valid_creds(ansible_module, ipaadmin_principal): ccache_dir, ccache_name = temp_kinit(ipaadmin_principal, ipaadmin_password) api_connect() res_find = find_trust(ansible_module, realm) if state == "absent": if res_find is not None: del_trust(ansible_module, realm) changed = True elif res_find is None: if admin is None and trust_secret is None: ansible_module.fail_json( msg="one of admin or trust_secret is required when state " "is present") else: args = gen_args(trust_type, admin, password, server, trust_secret, base_id, range_size, range_type, two_way, external) add_trust(ansible_module, realm, args) changed = True except Exception as e: ansible_module.fail_json(msg=str(e)) finally: temp_kdestroy(ccache_dir, ccache_name) # Done ansible_module.exit_json(changed=changed, **exit_args)
def main(): ansible_module = AnsibleModule( argument_spec=dict( # general ipaadmin_principal=dict(type="str", default="admin"), ipaadmin_password=dict(type="str", required=False, no_log=True), name=dict(type="list", aliases=["cn"], default=None, required=True), # present description=dict(required=False, type="str", default=None), usercategory=dict(required=False, type="str", default=None, choices=["all", ""], aliases=['usercat']), hostcategory=dict(required=False, type="str", default=None, choices=["all", ""], aliases=['hostcat']), nomembers=dict(required=False, type='bool', default=None), host=dict(required=False, type='list', default=None), hostgroup=dict(required=False, type='list', default=None), user=dict(required=False, type='list', default=None), group=dict(required=False, type='list', default=None), allow_sudocmd=dict(required=False, type="list", default=None), deny_sudocmd=dict(required=False, type="list", default=None), allow_sudocmdgroup=dict(required=False, type="list", default=None), deny_sudocmdgroup=dict(required=False, type="list", default=None), cmdcategory=dict(required=False, type="str", default=None, choices=["all", ""], aliases=['cmdcat']), runasusercategory=dict(required=False, type="str", default=None, choices=["all", ""], aliases=['runasusercat']), runasgroupcategory=dict(required=False, type="str", default=None, choices=["all", ""], aliases=['runasgroupcat']), runasuser=dict(required=False, type="list", default=None), runasgroup=dict(required=False, type="list", default=None), order=dict(type="int", required=False, aliases=['sudoorder']), sudooption=dict(required=False, type='list', default=None, aliases=["options"]), action=dict(type="str", default="sudorule", choices=["member", "sudorule"]), # state state=dict(type="str", default="present", choices=["present", "absent", "enabled", "disabled"]), ), supports_check_mode=True, ) ansible_module._ansible_debug = True # Get parameters # general ipaadmin_principal = module_params_get(ansible_module, "ipaadmin_principal") ipaadmin_password = module_params_get(ansible_module, "ipaadmin_password") names = module_params_get(ansible_module, "name") # present # The 'noqa' variables are not used here, but required for vars(). # The use of 'noqa' ensures flake8 does not complain about them. description = module_params_get(ansible_module, "description") # noqa cmdcategory = module_params_get(ansible_module, 'cmdcategory') # noqa usercategory = module_params_get(ansible_module, "usercategory") # noqa hostcategory = module_params_get(ansible_module, "hostcategory") # noqa runasusercategory = module_params_get( ansible_module, # noqa "runasusercategory") runasgroupcategory = module_params_get( ansible_module, # noqa "runasgroupcategory") hostcategory = module_params_get(ansible_module, "hostcategory") # noqa nomembers = module_params_get(ansible_module, "nomembers") # noqa host = module_params_get(ansible_module, "host") hostgroup = module_params_get(ansible_module, "hostgroup") user = module_params_get(ansible_module, "user") group = module_params_get(ansible_module, "group") allow_sudocmd = module_params_get(ansible_module, 'allow_sudocmd') allow_sudocmdgroup = module_params_get(ansible_module, 'allow_sudocmdgroup') deny_sudocmd = module_params_get(ansible_module, 'deny_sudocmd') deny_sudocmdgroup = module_params_get(ansible_module, 'deny_sudocmdgroup') sudooption = module_params_get(ansible_module, "sudooption") order = module_params_get(ansible_module, "order") runasuser = module_params_get(ansible_module, "runasuser") runasgroup = module_params_get(ansible_module, "runasgroup") action = module_params_get(ansible_module, "action") # state state = module_params_get(ansible_module, "state") # Check parameters if state == "present": if len(names) != 1: ansible_module.fail_json( msg="Only one sudorule can be added at a time.") if action == "member": invalid = [ "description", "usercategory", "hostcategory", "cmdcategory", "runasusercategory", "runasgroupcategory", "order", "nomembers" ] for arg in invalid: if arg in vars() and vars()[arg] is not None: ansible_module.fail_json( msg="Argument '%s' can not be used with action " "'%s'" % (arg, action)) else: if hostcategory == 'all' and any([host, hostgroup]): ansible_module.fail_json( msg="Hosts cannot be added when host category='all'") if usercategory == 'all' and any([user, group]): ansible_module.fail_json( msg="Users cannot be added when user category='all'") if cmdcategory == 'all' \ and any([allow_sudocmd, allow_sudocmdgroup]): ansible_module.fail_json( msg="Commands cannot be added when command category='all'") elif state == "absent": if len(names) < 1: ansible_module.fail_json(msg="No name given.") invalid = [ "description", "usercategory", "hostcategory", "cmdcategory", "runasusercategory", "runasgroupcategory", "nomembers", "order" ] if action == "sudorule": invalid.extend([ "host", "hostgroup", "user", "group", "runasuser", "runasgroup", "allow_sudocmd", "allow_sudocmdgroup", "deny_sudocmd", "deny_sudocmdgroup", "sudooption" ]) for arg in invalid: if vars()[arg] is not None: ansible_module.fail_json( msg="Argument '%s' can not be used with state '%s'" % (arg, state)) elif state in ["enabled", "disabled"]: if len(names) < 1: ansible_module.fail_json(msg="No name given.") if action == "member": ansible_module.fail_json( msg="Action member can not be used with states enabled and " "disabled") invalid = [ "description", "usercategory", "hostcategory", "cmdcategory", "runasusercategory", "runasgroupcategory", "nomembers", "nomembers", "host", "hostgroup", "user", "group", "allow_sudocmd", "allow_sudocmdgroup", "deny_sudocmd", "deny_sudocmdgroup", "runasuser", "runasgroup", "order", "sudooption" ] for arg in invalid: if vars()[arg] is not None: ansible_module.fail_json( msg="Argument '%s' can not be used with state '%s'" % (arg, state)) else: ansible_module.fail_json(msg="Invalid state '%s'" % state) # Init changed = False exit_args = {} ccache_dir = None ccache_name = None try: if not valid_creds(ansible_module, ipaadmin_principal): ccache_dir, ccache_name = temp_kinit(ipaadmin_principal, ipaadmin_password) api_connect() commands = [] for name in names: # Make sure sudorule exists res_find = find_sudorule(ansible_module, name) # Create command if state == "present": # Generate args args = gen_args(description, usercategory, hostcategory, cmdcategory, runasusercategory, runasgroupcategory, order, nomembers) if action == "sudorule": # Found the sudorule if res_find is not None: # Remove empty usercategory, hostcategory, # cmdcaterory, runasusercategory and hostcategory # from args if "" and if the category is not in the # sudorule. The empty string is used to reset the # category. if "usercategory" in args \ and args["usercategory"] == "" \ and "usercategory" not in res_find: del args["usercategory"] if "hostcategory" in args \ and args["hostcategory"] == "" \ and "hostcategory" not in res_find: del args["hostcategory"] if "cmdcategory" in args \ and args["cmdcategory"] == "" \ and "cmdcategory" not in res_find: del args["cmdcategory"] if "ipasudorunasusercategory" in args \ and args["ipasudorunasusercategory"] == "" \ and "ipasudorunasusercategory" not in res_find: del args["ipasudorunasusercategory"] if "ipasudorunasgroupcategory" in args \ and args["ipasudorunasgroupcategory"] == "" \ and "ipasudorunasgroupcategory" not in res_find: del args["ipasudorunasgroupcategory"] # For all settings is args, check if there are # different settings in the find result. # If yes: modify if not compare_args_ipa(ansible_module, args, res_find): commands.append([name, "sudorule_mod", args]) else: commands.append([name, "sudorule_add", args]) # Set res_find to empty dict for next step res_find = {} # Generate addition and removal lists host_add, host_del = gen_add_del_lists( host, res_find.get('memberhost_host', [])) hostgroup_add, hostgroup_del = gen_add_del_lists( hostgroup, res_find.get('memberhost_hostgroup', [])) user_add, user_del = gen_add_del_lists( user, res_find.get('memberuser_user', [])) group_add, group_del = gen_add_del_lists( group, res_find.get('memberuser_group', [])) allow_cmd_add, allow_cmd_del = gen_add_del_lists( allow_sudocmd, res_find.get('memberallowcmd_sudocmd', [])) allow_cmdgroup_add, allow_cmdgroup_del = gen_add_del_lists( allow_sudocmdgroup, res_find.get('memberallowcmd_sudocmdgroup', [])) deny_cmd_add, deny_cmd_del = gen_add_del_lists( deny_sudocmd, res_find.get('memberdenycmd_sudocmd', [])) deny_cmdgroup_add, deny_cmdgroup_del = gen_add_del_lists( deny_sudocmdgroup, res_find.get('memberdenycmd_sudocmdgroup', [])) sudooption_add, sudooption_del = gen_add_del_lists( sudooption, res_find.get('ipasudoopt', [])) runasuser_add, runasuser_del = gen_add_del_lists( runasuser, res_find.get('ipasudorunas_user', [])) runasgroup_add, runasgroup_del = gen_add_del_lists( runasgroup, res_find.get('ipasudorunas_group', [])) # Add hosts and hostgroups if len(host_add) > 0 or len(hostgroup_add) > 0: commands.append([ name, "sudorule_add_host", { "host": host_add, "hostgroup": hostgroup_add, } ]) # Remove hosts and hostgroups if len(host_del) > 0 or len(hostgroup_del) > 0: commands.append([ name, "sudorule_remove_host", { "host": host_del, "hostgroup": hostgroup_del, } ]) # Add users and groups if len(user_add) > 0 or len(group_add) > 0: commands.append([ name, "sudorule_add_user", { "user": user_add, "group": group_add, } ]) # Remove users and groups if len(user_del) > 0 or len(group_del) > 0: commands.append([ name, "sudorule_remove_user", { "user": user_del, "group": group_del, } ]) # Add commands allowed if len(allow_cmd_add) > 0 or len(allow_cmdgroup_add) > 0: commands.append([ name, "sudorule_add_allow_command", { "sudocmd": allow_cmd_add, "sudocmdgroup": allow_cmdgroup_add, } ]) if len(allow_cmd_del) > 0 or len(allow_cmdgroup_del) > 0: commands.append([ name, "sudorule_remove_allow_command", { "sudocmd": allow_cmd_del, "sudocmdgroup": allow_cmdgroup_del } ]) # Add commands denied if len(deny_cmd_add) > 0 or len(deny_cmdgroup_add) > 0: commands.append([ name, "sudorule_add_deny_command", { "sudocmd": deny_cmd_add, "sudocmdgroup": deny_cmdgroup_add, } ]) if len(deny_cmd_del) > 0 or len(deny_cmdgroup_del) > 0: commands.append([ name, "sudorule_remove_deny_command", { "sudocmd": deny_cmd_del, "sudocmdgroup": deny_cmdgroup_del } ]) # Add RunAS Users if len(runasuser_add) > 0: commands.append([ name, "sudorule_add_runasuser", { "user": runasuser_add } ]) # Remove RunAS Users if len(runasuser_del) > 0: commands.append([ name, "sudorule_remove_runasuser", { "user": runasuser_del } ]) # Add RunAS Groups if len(runasgroup_add) > 0: commands.append([ name, "sudorule_add_runasgroup", { "group": runasgroup_add } ]) # Remove RunAS Groups if len(runasgroup_del) > 0: commands.append([ name, "sudorule_remove_runasgroup", { "group": runasgroup_del } ]) # Add sudo options for sudoopt in sudooption_add: commands.append([ name, "sudorule_add_option", { "ipasudoopt": sudoopt } ]) # Remove sudo options for sudoopt in sudooption_del: commands.append([ name, "sudorule_remove_option", { "ipasudoopt": sudoopt } ]) elif action == "member": if res_find is None: ansible_module.fail_json(msg="No sudorule '%s'" % name) # Add hosts and hostgroups if host is not None or hostgroup is not None: commands.append([ name, "sudorule_add_host", { "host": host, "hostgroup": hostgroup, } ]) # Add users and groups if user is not None or group is not None: commands.append([ name, "sudorule_add_user", { "user": user, "group": group, } ]) # Add commands if allow_sudocmd is not None \ or allow_sudocmdgroup is not None: commands.append([ name, "sudorule_add_allow_command", { "sudocmd": allow_sudocmd, "sudocmdgroup": allow_sudocmdgroup, } ]) # Add commands if deny_sudocmd is not None \ or deny_sudocmdgroup is not None: commands.append([ name, "sudorule_add_deny_command", { "sudocmd": deny_sudocmd, "sudocmdgroup": deny_sudocmdgroup, } ]) # Add RunAS Users if runasuser is not None: commands.append([ name, "sudorule_add_runasuser", { "user": runasuser } ]) # Add RunAS Groups if runasgroup is not None: commands.append([ name, "sudorule_add_runasgroup", { "group": runasgroup } ]) # Add options if sudooption is not None: existing_opts = res_find.get('ipasudoopt', []) for sudoopt in sudooption: if sudoopt not in existing_opts: commands.append([ name, "sudorule_add_option", { "ipasudoopt": sudoopt } ]) elif state == "absent": if action == "sudorule": if res_find is not None: commands.append([name, "sudorule_del", {}]) elif action == "member": if res_find is None: ansible_module.fail_json(msg="No sudorule '%s'" % name) # Remove hosts and hostgroups if host is not None or hostgroup is not None: commands.append([ name, "sudorule_remove_host", { "host": host, "hostgroup": hostgroup, } ]) # Remove users and groups if user is not None or group is not None: commands.append([ name, "sudorule_remove_user", { "user": user, "group": group, } ]) # Remove allow commands if allow_sudocmd is not None \ or allow_sudocmdgroup is not None: commands.append([ name, "sudorule_remove_allow_command", { "sudocmd": allow_sudocmd, "sudocmdgroup": allow_sudocmdgroup } ]) # Remove deny commands if deny_sudocmd is not None \ or deny_sudocmdgroup is not None: commands.append([ name, "sudorule_remove_deny_command", { "sudocmd": deny_sudocmd, "sudocmdgroup": deny_sudocmdgroup } ]) # Remove RunAS Users if runasuser is not None: commands.append([ name, "sudorule_remove_runasuser", { "user": runasuser } ]) # Remove RunAS Groups if runasgroup is not None: commands.append([ name, "sudorule_remove_runasgroup", { "group": runasgroup } ]) # Remove options if sudooption is not None: existing_opts = res_find.get('ipasudoopt', []) for sudoopt in sudooption: if sudoopt in existing_opts: commands.append([ name, "sudorule_remove_option", { "ipasudoopt": sudoopt } ]) elif state == "enabled": if res_find is None: ansible_module.fail_json(msg="No sudorule '%s'" % name) # sudorule_enable is not failing on an enabled sudorule # Therefore it is needed to have a look at the ipaenabledflag # in res_find. if "ipaenabledflag" not in res_find or \ res_find["ipaenabledflag"][0] != "TRUE": commands.append([name, "sudorule_enable", {}]) elif state == "disabled": if res_find is None: ansible_module.fail_json(msg="No sudorule '%s'" % name) # sudorule_disable is not failing on an disabled sudorule # Therefore it is needed to have a look at the ipaenabledflag # in res_find. if "ipaenabledflag" not in res_find or \ res_find["ipaenabledflag"][0] != "FALSE": commands.append([name, "sudorule_disable", {}]) else: ansible_module.fail_json(msg="Unkown state '%s'" % state) # Check mode exit if ansible_module.check_mode: ansible_module.exit_json(changed=len(commands) > 0, **exit_args) # Execute commands errors = [] for name, command, args in commands: try: result = api_command(ansible_module, command, name, args) if "completed" in result: if result["completed"] > 0: changed = True else: changed = True except Exception as ex: ansible_module.fail_json(msg="%s: %s: %s" % (command, name, str(ex))) # Get all errors # All "already a member" and "not a member" failures in the # result are ignored. All others are reported. if "failed" in result and len(result["failed"]) > 0: for item in result["failed"]: failed_item = result["failed"][item] for member_type in failed_item: for member, failure in failed_item[member_type]: if "already a member" in failure \ or "not a member" in failure: continue errors.append( "%s: %s %s: %s" % (command, member_type, member, failure)) if len(errors) > 0: ansible_module.fail_json(msg=", ".join(errors)) except Exception as ex: ansible_module.fail_json(msg=str(ex)) finally: temp_kdestroy(ccache_dir, ccache_name) # Done ansible_module.exit_json(changed=changed, **exit_args)
def main(): ansible_module = AnsibleModule( argument_spec=dict( ### server ### setup_kra=dict(required=False, type='bool'), setup_dns=dict(required=False, type='bool'), ### certificate system ### subject_base=dict(required=True), ### dns ### zonemgr=dict(required=False), forwarders=dict(required=False, type='list', default=[]), forward_policy=dict(default=None, choices=['first', 'only']), no_dnssec_validation=dict(required=False, type='bool', default=False), ### additional ### ccache=dict(required=True), _top_dir=dict(required=True), setup_ca=dict(required=True, type='bool'), config_master_host_name=dict(required=True), ), supports_check_mode=True, ) ansible_module._ansible_debug = True ansible_log = AnsibleModuleLog(ansible_module) # get parameters # options = installer ### server ### options.setup_kra = ansible_module.params.get('setup_kra') options.setup_dns = ansible_module.params.get('setup_dns') ### certificate system ### options.subject_base = ansible_module.params.get('subject_base') if options.subject_base is not None: options.subject_base = DN(options.subject_base) ### dns ### options.zonemgr = ansible_module.params.get('zonemgr') options.forwarders = ansible_module.params.get('forwarders') options.forward_policy = ansible_module.params.get('forward_policy') options.no_dnssec_validation = ansible_module.params.get( 'no_dnssec_validationdnssec_validation') ### additional ### ccache = ansible_module.params.get('ccache') os.environ['KRB5CCNAME'] = ccache options._top_dir = ansible_module.params.get('_top_dir') options.setup_ca = ansible_module.params.get('setup_ca') config_master_host_name = ansible_module.params.get( 'config_master_host_name') # init # fstore = sysrestore.FileStore(paths.SYSRESTORE) sstore = sysrestore.StateFile(paths.SYSRESTORE) ansible_log.debug("== INSTALL ==") promote = installer.promote env = gen_env_boostrap_finalize_core(paths.ETC_IPA, constants.DEFAULT_CONFIG) api_bootstrap_finalize(env) config = gen_ReplicaConfig() config.subject_base = options.subject_base config.master_host_name = config_master_host_name remote_api = gen_remote_api(config.master_host_name, paths.ETC_IPA) installer._remote_api = remote_api conn = remote_api.Backend.ldap2 ccache = os.environ['KRB5CCNAME'] # There is a api.Backend.ldap2.connect call somewhere in ca, ds, dns or # ntpinstance api.Backend.ldap2.connect() with redirect_stdout(ansible_log): if options.setup_dns: ansible_log.debug("-- INSTALL DNS --") dns.install(False, True, options, api) else: ansible_log.debug("-- DNS UPDATE_SYSTEM_RECORDS --") api.Command.dns_update_system_records() # done # ansible_module.exit_json(changed=True)
def main(): ansible_module = AnsibleModule( argument_spec=dict( # general ipaadmin_principal=dict(type="str", default="admin"), ipaadmin_password=dict(type="str", required=False, no_log=True), maxusername=dict(type="int", required=False, aliases=['ipamaxusernamelength']), maxhostname=dict(type="int", required=False, aliases=['ipamaxhostnamelength']), homedirectory=dict(type="str", required=False, aliases=['ipahomesrootdir']), defaultshell=dict(type="str", required=False, aliases=['ipadefaultloginshell', 'loginshell']), defaultgroup=dict(type="str", required=False, aliases=['ipadefaultprimarygroup']), emaildomain=dict(type="str", required=False, aliases=['ipadefaultemaildomain']), searchtimelimit=dict(type="int", required=False, aliases=['ipasearchtimelimit']), searchrecordslimit=dict(type="int", required=False, aliases=['ipasearchrecordslimit']), usersearch=dict(type="list", required=False, aliases=['ipausersearchfields']), groupsearch=dict(type="list", required=False, aliases=['ipagroupsearchfields']), enable_migration=dict(type="bool", required=False, aliases=['ipamigrationenabled']), groupobjectclasses=dict(type="list", required=False, aliases=['ipagroupobjectclasses']), userobjectclasses=dict(type="list", required=False, aliases=['ipauserobjectclasses']), pwdexpnotify=dict(type="int", required=False, aliases=['ipapwdexpadvnotify']), configstring=dict(type="list", required=False, aliases=['ipaconfigstring'], choices=[ "AllowNThash", "KDC:Disable Last Success", "KDC:Disable Lockout", "KDC:Disable Default Preauth for SPNs", "" ]), # noqa E128 selinuxusermaporder=dict(type="list", required=False, aliases=['ipaselinuxusermaporder']), selinuxusermapdefault=dict(type="str", required=False, aliases=['ipaselinuxusermapdefault']), pac_type=dict(type="list", required=False, aliases=["ipakrbauthzdata"], choices=["MS-PAC", "PAD", "nfs:NONE", ""]), user_auth_type=dict( type="list", required=False, choices=["password", "radius", "otp", "disabled", ""], aliases=["ipauserauthtype"]), ca_renewal_master_server=dict(type="str", required=False), domain_resolution_order=dict(type="list", required=False, aliases=["ipadomainresolutionorder" ])), supports_check_mode=True, ) ansible_module._ansible_debug = True # Get parameters # general ipaadmin_principal = module_params_get(ansible_module, "ipaadmin_principal") ipaadmin_password = module_params_get(ansible_module, "ipaadmin_password") field_map = { "maxusername": "******", "maxhostname": "ipamaxhostnamelength", "homedirectory": "ipahomesrootdir", "defaultshell": "ipadefaultloginshell", "defaultgroup": "ipadefaultprimarygroup", "emaildomain": "ipadefaultemaildomain", "searchtimelimit": "ipasearchtimelimit", "searchrecordslimit": "ipasearchrecordslimit", "usersearch": "ipausersearchfields", "groupsearch": "ipagroupsearchfields", "enable_migration": "ipamigrationenabled", "groupobjectclasses": "ipagroupobjectclasses", "userobjectclasses": "ipauserobjectclasses", "pwdexpnotify": "ipapwdexpadvnotify", "configstring": "ipaconfigstring", "selinuxusermaporder": "ipaselinuxusermaporder", "selinuxusermapdefault": "ipaselinuxusermapdefault", "pac_type": "ipakrbauthzdata", "user_auth_type": "ipauserauthtype", "ca_renewal_master_server": "ca_renewal_master_server", "domain_resolution_order": "ipadomainresolutionorder" } reverse_field_map = {v: k for k, v in field_map.items()} params = {} for x in field_map: val = module_params_get(ansible_module, x) if val is not None: params[field_map.get(x, x)] = val if params.get("ipamigrationenabled") is not None: params["ipamigrationenabled"] = \ str(params["ipamigrationenabled"]).upper() if params.get("ipaselinuxusermaporder", None): params["ipaselinuxusermaporder"] = \ "$".join(params["ipaselinuxusermaporder"]) if params.get("ipadomainresolutionorder", None): params["ipadomainresolutionorder"] = \ ":".join(params["ipadomainresolutionorder"]) if params.get("ipausersearchfields", None): params["ipausersearchfields"] = \ ",".join(params["ipausersearchfields"]) if params.get("ipagroupsearchfields", None): params["ipagroupsearchfields"] = \ ",".join(params["ipagroupsearchfields"]) # verify limits on INT values. args_with_limits = [ ("ipamaxusernamelength", 1, 255), ("ipamaxhostnamelength", 64, 255), ("ipasearchtimelimit", -1, 2147483647), ("ipasearchrecordslimit", -1, 2147483647), ("ipapwdexpadvnotify", 0, 2147483647), ] for arg, minimum, maximum in args_with_limits: if arg in params and (params[arg] > maximum or params[arg] < minimum): ansible_module.fail_json( msg="Argument '%s' must be between %d and %d." % (arg, minimum, maximum)) changed = False exit_args = {} ccache_dir = None ccache_name = None res_show = None try: if not valid_creds(ansible_module, ipaadmin_principal): ccache_dir, ccache_name = temp_kinit(ipaadmin_principal, ipaadmin_password) api_connect() if params: res_show = config_show(ansible_module) params = { k: v for k, v in params.items() if k not in res_show or res_show[k] != v } if params \ and not compare_args_ipa(ansible_module, params, res_show): changed = True if not ansible_module.check_mode: api_command_no_name(ansible_module, "config_mod", params) else: rawresult = api_command_no_name(ansible_module, "config_show", {}) result = rawresult['result'] del result['dn'] for key, value in result.items(): k = reverse_field_map.get(key, key) if ansible_module.argument_spec.get(k): if k == 'ipaselinuxusermaporder': exit_args['ipaselinuxusermaporder'] = \ result.get(key)[0].split('$') elif k == 'domain_resolution_order': exit_args['domain_resolution_order'] = \ result.get(key)[0].split('$') elif k == 'usersearch': exit_args['usersearch'] = \ result.get(key)[0].split(',') elif k == 'groupsearch': exit_args['groupsearch'] = \ result.get(key)[0].split(',') elif isinstance(value, str) and \ ansible_module.argument_spec[k]['type'] == "list": exit_args[k] = [value] elif isinstance(value, list) and \ ansible_module.argument_spec[k]['type'] == "str": exit_args[k] = ",".join(value) elif isinstance(value, list) and \ ansible_module.argument_spec[k]['type'] == "int": exit_args[k] = ",".join(value) elif isinstance(value, list) and \ ansible_module.argument_spec[k]['type'] == "bool": exit_args[k] = (value[0] == "TRUE") else: exit_args[k] = value except ipalib_errors.EmptyModlist: changed = False except Exception as e: ansible_module.fail_json(msg="%s %s" % (params, str(e))) finally: temp_kdestroy(ccache_dir, ccache_name) # Done ansible_module.exit_json(changed=changed, config=exit_args)
def main(): ansible_module = AnsibleModule( argument_spec=dict( ### basic ### dm_password=dict(required=False, no_log=True), password=dict(required=False, no_log=True), ip_addresses=dict(required=False, type='list', default=[]), domain=dict(required=False), realm=dict(required=False), hostname=dict(required=False), ca_cert_files=dict(required=False, type='list', default=[]), no_host_dns=dict(required=False, type='bool', default=False), pki_config_override=dict(required=False), ### server ### setup_adtrust=dict(required=False, type='bool'), setup_ca=dict(required=False, type='bool'), setup_kra=dict(required=False, type='bool'), setup_dns=dict(required=False, type='bool'), ### ssl certificate ### dirsrv_cert_files=dict(required=False, type='list', default=[]), ### client ### force_join=dict(required=False, type='bool'), ### certificate system ### subject_base=dict(required=True), ### additional ### server=dict(required=True), config_master_host_name=dict(required=True), ccache=dict(required=True), installer_ccache=dict(required=True), _ca_enabled=dict(required=False, type='bool'), _kra_enabled=dict(required=False, type='bool'), _kra_host_name=dict(required=False), _top_dir=dict(required=True), _add_to_ipaservers=dict(required=True, type='bool'), _ca_subject=dict(required=True), _subject_base=dict(required=True), ), supports_check_mode=True, ) ansible_module._ansible_debug = True ansible_log = AnsibleModuleLog(ansible_module) # get parameters # options = installer options.dm_password = ansible_module.params.get('dm_password') options.password = options.dm_password options.admin_password = ansible_module.params.get('password') options.ip_addresses = ansible_module_get_parsed_ip_addresses( ansible_module) options.domain_name = ansible_module.params.get('domain') options.realm_name = ansible_module.params.get('realm') options.host_name = ansible_module.params.get('hostname') options.ca_cert_files = ansible_module.params.get('ca_cert_files') options.no_host_dns = ansible_module.params.get('no_host_dns') options.pki_config_override = ansible_module.params.get( 'pki_config_override') ### server ### options.setup_adtrust = ansible_module.params.get('setup_adtrust') options.setup_ca = ansible_module.params.get('setup_ca') options.setup_kra = ansible_module.params.get('setup_kra') options.setup_dns = ansible_module.params.get('setup_dns') ### ssl certificate ### options.dirsrv_cert_files = ansible_module.params.get('dirsrv_cert_files') ### client ### options.force_join = ansible_module.params.get('force_join') ### certificate system ### options.external_ca = ansible_module.params.get('external_ca') options.external_cert_files = ansible_module.params.get( 'external_cert_files') options.subject_base = ansible_module.params.get('subject_base') if options.subject_base is not None: options.subject_base = DN(options.subject_base) options.ca_subject = ansible_module.params.get('ca_subject') ### dns ### options.reverse_zones = ansible_module.params.get('reverse_zones') options.no_reverse = ansible_module.params.get('no_reverse') options.auto_reverse = ansible_module.params.get('auto_reverse') options.forwarders = ansible_module.params.get('forwarders') options.no_forwarders = ansible_module.params.get('no_forwarders') options.auto_forwarders = ansible_module.params.get('auto_forwarders') options.forward_policy = ansible_module.params.get('forward_policy') ### additional ### options.server = ansible_module.params.get('server') master_host_name = ansible_module.params.get('config_master_host_name') ccache = ansible_module.params.get('ccache') #os.environ['KRB5CCNAME'] = ccache os.environ['KRB5CCNAME'] = ansible_module.params.get('installer_ccache') installer._ccache = ansible_module.params.get('installer_ccache') ca_enabled = ansible_module.params.get('_ca_enabled') kra_enabled = ansible_module.params.get('_kra_enabled') kra_host_name = ansible_module.params.get('_kra_host_name') options.subject_base = ansible_module.params.get('subject_base') if options.subject_base is not None: options.subject_base = DN(options.subject_base) options._top_dir = ansible_module.params.get('_top_dir') options._add_to_ipaservers = ansible_module.params.get( '_add_to_ipaservers') options._ca_subject = ansible_module.params.get('_ca_subject') options._subject_base = ansible_module.params.get('_subject_base') # init # ansible_log.debug("== INSTALL ==") options = installer env = gen_env_boostrap_finalize_core(paths.ETC_IPA, constants.DEFAULT_CONFIG) api_bootstrap_finalize(env) config = gen_ReplicaConfig() config.subject_base = options.subject_base config.promote = installer.promote config.kra_enabled = kra_enabled config.kra_host_name = kra_host_name remote_api = gen_remote_api(master_host_name, paths.ETC_IPA) installer._remote_api = remote_api ccache = os.environ['KRB5CCNAME'] with redirect_stdout(ansible_log): ansible_log.debug("-- INSTALL KRA --") if not hasattr(custodiainstance, "get_custodia_instance"): kra.install(api, config, options) else: if ca_enabled: mode = custodiainstance.CustodiaModes.CA_PEER else: mode = custodiainstance.CustodiaModes.MASTER_PEER custodia = custodiainstance.get_custodia_instance(config, mode) kra.install(api, config, options, custodia=custodia) # done # ansible_module.exit_json(changed=True)
def main(): ansible_module = AnsibleModule( argument_spec=dict( #### server ### setup_ca=dict(required=False, type='bool'), setup_kra=dict(required=False, type='bool'), no_pkinit=dict(required=False, type='bool'), no_ui_redirect=dict(required=False, type='bool'), #### certificate system ### subject_base=dict(required=True), #### additional ### ccache=dict(required=True), _ca_enabled=dict(required=False, type='bool'), _ca_file=dict(required=False), _dirsrv_pkcs12_info=dict(required=False), _pkinit_pkcs12_info=dict(required=False), _top_dir=dict(required=True), _ca_subject=dict(required=True), _subject_base=dict(required=True), dirman_password=dict(required=True, no_log=True), config_setup_ca=dict(required=True, type='bool'), config_master_host_name=dict(required=True), config_ca_host_name=dict(required=True), config_ips=dict(required=False, type='list', default=[]), ), supports_check_mode=True, ) ansible_module._ansible_debug = True ansible_log = AnsibleModuleLog(ansible_module) # get parameters # options = installer ### server ### options.setup_ca = ansible_module.params.get('setup_ca') options.setup_kra = ansible_module.params.get('setup_kra') options.no_pkinit = ansible_module.params.get('no_pkinit') ### certificate system ### options.subject_base = ansible_module.params.get('subject_base') if options.subject_base is not None: options.subject_base = DN(options.subject_base) ### additional ### ccache = ansible_module.params.get('ccache') os.environ['KRB5CCNAME'] = ccache #os.environ['KRB5CCNAME'] = ansible_module.params.get('installer_ccache') #installer._ccache = ansible_module.params.get('installer_ccache') ca_enabled = ansible_module.params.get('_ca_enabled') installer._dirsrv_pkcs12_info = ansible_module.params.get( '_dirsrv_pkcs12_info') installer._pkinit_pkcs12_info = ansible_module.params.get( '_pkinit_pkcs12_info') options._top_dir = ansible_module.params.get('_top_dir') options._ca_subject = ansible_module.params.get('_ca_subject') if options._ca_subject is not None: options._ca_subject = DN(options._ca_subject) options._subject_base = ansible_module.params.get('_subject_base') if options._subject_base is not None: options._subject_base = DN(options._subject_base) dirman_password = ansible_module.params.get('dirman_password') config_setup_ca = ansible_module.params.get('config_setup_ca') config_master_host_name = ansible_module.params.get( 'config_master_host_name') config_ca_host_name = ansible_module.params.get('config_ca_host_name') config_ips = ansible_module_get_parsed_ip_addresses( ansible_module, "config_ips") # init # fstore = sysrestore.FileStore(paths.SYSRESTORE) sstore = sysrestore.StateFile(paths.SYSRESTORE) ansible_log.debug("== INSTALL ==") options = installer promote = installer.promote pkinit_pkcs12_info = installer._pkinit_pkcs12_info env = gen_env_boostrap_finalize_core(paths.ETC_IPA, constants.DEFAULT_CONFIG) api_bootstrap_finalize(env) config = gen_ReplicaConfig() config.dirman_password = dirman_password config.setup_ca = config_setup_ca config.master_host_name = config_master_host_name config.ca_host_name = config_ca_host_name config.ips = config_ips config.promote = options.promote remote_api = gen_remote_api(config.master_host_name, paths.ETC_IPA) options._remote_api = remote_api conn = remote_api.Backend.ldap2 ccache = os.environ['KRB5CCNAME'] # There is a api.Backend.ldap2.connect call somewhere in ca, ds, dns or # ntpinstance api.Backend.ldap2.connect() #conn.connect(ccache=ccache) ansible_log.debug("-- INSTALL CA --") with redirect_stdout(ansible_log): options.realm_name = config.realm_name options.domain_name = config.domain_name options.host_name = config.host_name options.dm_password = config.dirman_password if not hasattr(custodiainstance, "get_custodia_instance"): ca.install(False, config, options) else: if ca_enabled: mode = custodiainstance.CustodiaModes.CA_PEER else: mode = custodiainstance.CustodiaModes.MASTER_PEER custodia = custodiainstance.get_custodia_instance(config, mode) ca.install(False, config, options, custodia=custodia) # done # ansible_module.exit_json(changed=True)
def main(): module = AnsibleModule( argument_spec=dict( servers=dict(required=False, type='list', default=[]), domain=dict(required=False), realm=dict(required=False), hostname=dict(required=False), ca_cert_file=dict(required=False), on_master=dict(required=False, type='bool', default=False), ntp_servers=dict(required=False, type='list', default=[]), no_ntp=dict(required=False, type='bool', default=False), ), supports_check_mode=True, ) module._ansible_debug = True opt_domain = module.params.get('domain') opt_servers = module.params.get('servers') opt_realm = module.params.get('realm') opt_hostname = module.params.get('hostname') opt_ca_cert_file = module.params.get('ca_cert_file') opt_on_master = module.params.get('on_master') opt_ntp_servers = module.params.get('ntp_servers') opt_no_ntp = module.params.get('no_ntp') hostname = None hostname_source = None dnsok = False cli_domain = None cli_server = None cli_realm = None cli_kdc = None client_domain = None cli_basedn = None if opt_hostname: hostname = opt_hostname hostname_source = 'Provided as option' else: hostname = socket.getfqdn() hostname_source = "Machine's FQDN" if hostname != hostname.lower(): module.fail_json(msg="Invalid hostname '%s', must be lower-case." % hostname) if (hostname == 'localhost') or (hostname == 'localhost.localdomain'): module.fail_json(msg="Invalid hostname, '%s' must not be used." % hostname) # Get domain from first server if domain is not set, but there are servers if opt_domain is None and len(opt_servers) > 0: opt_domain = opt_servers[0][opt_servers[0].find(".") + 1:] # Create the discovery instance ds = ipadiscovery.IPADiscovery() ret = ds.search(domain=opt_domain, servers=opt_servers, realm=opt_realm, hostname=hostname, ca_cert_path=get_cert_path(opt_ca_cert_file)) if opt_servers and ret != 0: # 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 # better result module.fail_json(msg="Failed to verify that %s is an IPA Server." % \ ', '.join(opt_servers)) if ret == ipadiscovery.BAD_HOST_CONFIG: module.fail_json(msg="Can't get the fully qualified name of this host") if ret == ipadiscovery.NOT_FQDN: module.fail_json(msg="%s is not a fully-qualified hostname" % hostname) if ret in (ipadiscovery.NO_LDAP_SERVER, ipadiscovery.NOT_IPA_SERVER) \ or not ds.domain: if ret == ipadiscovery.NO_LDAP_SERVER: if ds.server: module.log("%s is not an LDAP server" % ds.server) else: module.log("No LDAP server found") elif ret == ipadiscovery.NOT_IPA_SERVER: if ds.server: module.log("%s is not an IPA server" % ds.server) else: module.log("No IPA server found") else: module.log("Domain not found") if opt_domain: cli_domain = opt_domain cli_domain_source = 'Provided as option' else: module.fail_json(msg="Unable to discover domain, not provided") ret = ds.search(domain=cli_domain, servers=opt_servers, hostname=hostname, ca_cert_path=get_cert_path(opt_ca_cert_file)) if not cli_domain: if ds.domain: cli_domain = ds.domain cli_domain_source = ds.domain_source module.debug("will use discovered domain: %s" % cli_domain) client_domain = hostname[hostname.find(".") + 1:] if ret in (ipadiscovery.NO_LDAP_SERVER, ipadiscovery.NOT_IPA_SERVER) \ or not ds.server: module.debug("IPA Server not found") if opt_servers: cli_server = opt_servers cli_server_source = 'Provided as option' else: module.fail_json(msg="Unable to find IPA Server to join") ret = ds.search(domain=cli_domain, servers=cli_server, hostname=hostname, ca_cert_path=get_cert_path(opt_ca_cert_file)) else: # Only set dnsok to True if we were not passed in one or more servers # and if DNS discovery actually worked. if not opt_servers: (server, domain) = ds.check_domain(ds.domain, set(), "Validating DNS Discovery") if server and domain: module.debug("DNS validated, enabling discovery") dnsok = True else: module.debug("DNS discovery failed, disabling discovery") else: module.debug( "Using servers from command line, disabling DNS discovery") if not cli_server: if opt_servers: cli_server = ds.servers cli_server_source = 'Provided as option' module.debug("will use provided server: %s" % ', '.join(opt_servers)) elif ds.server: cli_server = ds.servers cli_server_source = ds.server_source module.debug("will use discovered server: %s" % cli_server[0]) if ret == ipadiscovery.NOT_IPA_SERVER: module.fail_json(msg="%s is not an IPA v2 Server." % cli_server[0]) if ret == ipadiscovery.NO_ACCESS_TO_LDAP: module.warn("Anonymous access to the LDAP server is disabled.") ret = 0 if ret == ipadiscovery.NO_TLS_LDAP: module.warn( "The LDAP server requires TLS is but we do not have the CA.") ret = 0 if ret != 0: module.fail_json(msg="Failed to verify that %s is an IPA Server." % cli_server[0]) cli_kdc = ds.kdc if dnsok and not cli_kdc: module.fail_json(msg="DNS domain '%s' is not configured for automatic " "KDC address lookup." % ds.realm.lower()) if dnsok: module.log("Discovery was successful!") cli_realm = ds.realm cli_realm_source = ds.realm_source module.debug("will use discovered realm: %s" % cli_realm) if opt_realm and opt_realm != cli_realm: module.fail_json( msg= "The provided realm name [%s] does not match discovered one [%s]" % (opt_realm, cli_realm)) cli_basedn = str(ds.basedn) cli_basedn_source = ds.basedn_source module.debug("will use discovered basedn: %s" % cli_basedn) module.log("Client hostname: %s" % hostname) module.debug("Hostname source: %s" % hostname_source) module.log("Realm: %s" % cli_realm) module.debug("Realm source: %s" % cli_realm_source) module.log("DNS Domain: %s" % cli_domain) module.debug("DNS Domain source: %s" % cli_domain_source) module.log("IPA Server: %s" % ', '.join(cli_server)) module.debug("IPA Server source: %s" % cli_server_source) module.log("BaseDN: %s" % cli_basedn) module.debug("BaseDN source: %s" % cli_basedn_source) # ipa-join would fail with IP address instead of a FQDN for srv in cli_server: try: socket.inet_pton(socket.AF_INET, srv) is_ipaddr = True except socket.error: try: socket.inet_pton(socket.AF_INET6, srv) is_ipaddr = True except socket.error: is_ipaddr = False if is_ipaddr: module.warn("It seems that you are using an IP address " "instead of FQDN as an argument to --server. The " "installation may fail.") break if not opt_on_master and not opt_no_ntp: if len(opt_ntp_servers) < 1: # Detect NTP servers ds = ipadiscovery.IPADiscovery() ntp_servers = ds.ipadns_search_srv(cli_domain, '_ntp._udp', None, break_on_first=False) else: ntp_servers = opt_ntp_servers # Attempt to sync time: # At first with given or dicovered time servers. If no ntp # servers have been given or discovered, then with the ipa # server. module.log('Synchronizing time ...') synced_ntp = False # use user specified NTP servers if there are any for s in ntp_servers: synced_ntp = ntpconf.synconce_ntp(s, False) if synced_ntp: break if not synced_ntp and not ntp_servers: synced_ntp = ntpconf.synconce_ntp(cli_server[0], False) if not synced_ntp: module.warn("Unable to sync time with NTP server") else: ntp_servers = [] # Check if ipa client is already configured if is_client_configured(): # Check that realm and domain match current_config = get_ipa_conf() if cli_domain != current_config.get('domain'): return module.fail_json(msg="IPA client already installed " "with a conflicting domain") if cli_realm != current_config.get('realm'): return module.fail_json(msg="IPA client already installed " "with a conflicting realm") # Done module.exit_json(changed=True, servers=cli_server, domain=cli_domain, realm=cli_realm, kdc=cli_kdc, basedn=cli_basedn, hostname=hostname, client_domain=client_domain, dnsok=dnsok, ntp_servers=ntp_servers, ipa_python_version=IPA_PYTHON_VERSION)
def main(): ansible_module = AnsibleModule( argument_spec=dict( # basic dm_password=dict(required=False, no_log=True), password=dict(required=False, no_log=True), ip_addresses=dict(required=False, type='list', default=[]), domain=dict(required=False), realm=dict(required=False), hostname=dict(required=False), principal=dict(required=True), ca_cert_files=dict(required=False, type='list', default=[]), no_host_dns=dict(required=False, type='bool', default=False), # server setup_adtrust=dict(required=False, type='bool'), setup_ca=dict(required=False, type='bool'), setup_kra=dict(required=False, type='bool'), setup_dns=dict(required=False, type='bool'), # ssl certificate dirsrv_cert_files=dict(required=False, type='list', default=[]), dirsrv_cert_name=dict(required=False), dirsrv_pin=dict(required=False), http_cert_files=dict(required=False, type='list', default=[]), http_cert_name=dict(required=False), http_pin=dict(required=False), pkinit_cert_files=dict(required=False, type='list', default=[]), pkinit_cert_name=dict(required=False), pkinit_pin=dict(required=False), # client keytab=dict(required=False), mkhomedir=dict(required=False, type='bool'), force_join=dict(required=False, type='bool'), no_ntp=dict(required=False, type='bool'), ssh_trust_dns=dict(required=False, type='bool'), no_ssh=dict(required=False, type='bool'), no_sshd=dict(required=False, type='bool'), no_dns_sshfp=dict(required=False, type='bool'), # certificate system # subject_base=dict(required=False), # dns allow_zone_overlap=dict(required=False, type='bool', default=False), reverse_zones=dict(required=False, type='list', default=[]), no_reverse=dict(required=False, type='bool', default=False), auto_reverse=dict(required=False, type='bool', default=False), forwarders=dict(required=False, type='list', default=[]), no_forwarders=dict(required=False, type='bool', default=False), auto_forwarders=dict(required=False, type='bool', default=False), forward_policy=dict(default=None, choices=['first', 'only']), no_dnssec_validation=dict(required=False, type='bool', default=False), # ad trust enable_compat=dict(required=False, type='bool', default=False), netbios_name=dict(required=False), rid_base=dict(required=False, type='int', default=1000), secondary_rid_base=dict(required=False, type='int', default=100000000), # additional server=dict(required=True), skip_conncheck=dict(required=False, type='bool'), ), supports_check_mode=True, ) ansible_module._ansible_debug = True setup_logging() ansible_log = AnsibleModuleLog(ansible_module) # get parameters # options.dm_password = ansible_module.params.get('dm_password') options.password = options.dm_password options.admin_password = ansible_module.params.get('password') options.ip_addresses = ansible_module_get_parsed_ip_addresses( ansible_module) options.domain_name = ansible_module.params.get('domain') options.realm_name = ansible_module.params.get('realm') options.host_name = ansible_module.params.get('hostname') options.principal = ansible_module.params.get('principal') options.ca_cert_files = ansible_module.params.get('ca_cert_files') options.no_host_dns = ansible_module.params.get('no_host_dns') # server options.setup_adtrust = ansible_module.params.get('setup_adtrust') options.setup_ca = ansible_module.params.get('setup_ca') options.setup_kra = ansible_module.params.get('setup_kra') options.setup_dns = ansible_module.params.get('setup_dns') # ssl certificate options.dirsrv_cert_files = ansible_module.params.get('dirsrv_cert_files') options.dirsrv_cert_name = ansible_module.params.get('dirsrv_cert_name') options.dirsrv_pin = ansible_module.params.get('dirsrv_pin') options.http_cert_files = ansible_module.params.get('http_cert_files') options.http_cert_name = ansible_module.params.get('http_cert_name') options.http_pin = ansible_module.params.get('http_pin') options.pkinit_cert_files = ansible_module.params.get('pkinit_cert_files') options.pkinit_cert_name = ansible_module.params.get('pkinit_cert_name') options.pkinit_pin = ansible_module.params.get('pkinit_pin') # client options.keytab = ansible_module.params.get('keytab') options.mkhomedir = ansible_module.params.get('mkhomedir') options.force_join = ansible_module.params.get('force_join') options.no_ntp = ansible_module.params.get('no_ntp') options.ssh_trust_dns = ansible_module.params.get('ssh_trust_dns') options.no_ssh = ansible_module.params.get('no_ssh') options.no_sshd = ansible_module.params.get('no_sshd') options.no_dns_sshfp = ansible_module.params.get('no_dns_sshfp') # certificate system options.external_ca = ansible_module.params.get('external_ca') options.external_cert_files = ansible_module.params.get( 'external_cert_files') # options.subject_base = ansible_module.params.get('subject_base') # options.ca_subject = ansible_module.params.get('ca_subject') options.no_dnssec_validation = ansible_module.params.get( 'no_dnssec_validation') # dns options.allow_zone_overlap = ansible_module.params.get( 'allow_zone_overlap') options.reverse_zones = ansible_module.params.get('reverse_zones') options.no_reverse = ansible_module.params.get('no_reverse') options.auto_reverse = ansible_module.params.get('auto_reverse') options.forwarders = ansible_module.params.get('forwarders') options.no_forwarders = ansible_module.params.get('no_forwarders') options.auto_forwarders = ansible_module.params.get('auto_forwarders') options.forward_policy = ansible_module.params.get('forward_policy') options.no_dnssec_validation = ansible_module.params.get( 'no_dnssec_validationdnssec_validation') # ad trust options.enable_compat = ansible_module.params.get('enable_compat') options.netbios_name = ansible_module.params.get('netbios_name') options.rid_base = ansible_module.params.get('rid_base') options.secondary_rid_base = ansible_module.params.get( 'secondary_rid_base') # additional # options._host_name_overridden = ansible_module.params.get( # '_hostname_overridden') options.server = ansible_module.params.get('server') options.skip_conncheck = ansible_module.params.get('skip_conncheck') # init # fstore = sysrestore.FileStore(paths.SYSRESTORE) sstore = sysrestore.StateFile(paths.SYSRESTORE) # prepare (install prepare, install checks) # ########################################################################## # replica promote_check ################################################## ########################################################################## ansible_log.debug("== PROMOTE CHECK ==") # ansible_log.debug("-- NO_NTP --") # already done in test # check selinux status, http and DS ports, NTP conflicting services # common_check(options.no_ntp) installer._enrollment_performed = False installer._top_dir = tempfile.mkdtemp("ipa") # with ipautil.private_ccache(): dir_path = tempfile.mkdtemp(prefix='krbcc') os.environ['KRB5CCNAME'] = os.path.join(dir_path, 'ccache') ansible_log.debug("-- API --") env = Env() env._bootstrap(context='installer', confdir=paths.ETC_IPA, log=None) env._finalize_core(**dict(constants.DEFAULT_CONFIG)) # pylint: disable=no-member xmlrpc_uri = 'https://{}/ipa/xml'.format(ipautil.format_netloc(env.host)) if hasattr(ipaldap, "realm_to_ldapi_uri"): realm_to_ldapi_uri = ipaldap.realm_to_ldapi_uri else: realm_to_ldapi_uri = installutils.realm_to_ldapi_uri api.bootstrap(in_server=True, context='installer', confdir=paths.ETC_IPA, ldap_uri=realm_to_ldapi_uri(env.realm), xmlrpc_uri=xmlrpc_uri) # pylint: enable=no-member api.finalize() ansible_log.debug("-- REPLICA_CONFIG --") config = ReplicaConfig() config.realm_name = api.env.realm config.host_name = api.env.host config.domain_name = api.env.domain config.master_host_name = api.env.server if not api.env.ca_host or api.env.ca_host == api.env.host: # ca_host has not been configured explicitly, prefer source master config.ca_host_name = api.env.server else: # default to ca_host from IPA config config.ca_host_name = api.env.ca_host config.kra_host_name = config.ca_host_name config.ca_ds_port = 389 config.setup_ca = options.setup_ca config.setup_kra = options.setup_kra config.dir = installer._top_dir config.basedn = api.env.basedn # config.hidden_replica = options.hidden_replica # load and check certificates # ansible_log.debug("-- CERT_FILES --") http_pkcs12_file = None http_pkcs12_info = None http_ca_cert = None dirsrv_pkcs12_file = None dirsrv_pkcs12_info = None dirsrv_ca_cert = None pkinit_pkcs12_file = None pkinit_pkcs12_info = None pkinit_ca_cert = None if options.http_cert_files: ansible_log.debug("-- HTTP_CERT_FILES --") if options.http_pin is None: ansible_module.fail_json( msg="Apache Server private key unlock password required") http_pkcs12_file, http_pin, http_ca_cert = load_pkcs12( cert_files=options.http_cert_files, key_password=options.http_pin, key_nickname=options.http_cert_name, ca_cert_files=options.ca_cert_files, host_name=config.host_name) http_pkcs12_info = (http_pkcs12_file.name, http_pin) if options.dirsrv_cert_files: ansible_log.debug("-- DIRSRV_CERT_FILES --") if options.dirsrv_pin is None: ansible_module.fail_json( msg="Directory Server private key unlock password required") dirsrv_pkcs12_file, dirsrv_pin, dirsrv_ca_cert = load_pkcs12( cert_files=options.dirsrv_cert_files, key_password=options.dirsrv_pin, key_nickname=options.dirsrv_cert_name, ca_cert_files=options.ca_cert_files, host_name=config.host_name) dirsrv_pkcs12_info = (dirsrv_pkcs12_file.name, dirsrv_pin) if options.pkinit_cert_files: ansible_log.debug("-- PKINIT_CERT_FILES --") if options.pkinit_pin is None: ansible_module.fail_json( msg="Kerberos KDC private key unlock password required") pkinit_pkcs12_file, pkinit_pin, pkinit_ca_cert = load_pkcs12( cert_files=options.pkinit_cert_files, key_password=options.pkinit_pin, key_nickname=options.pkinit_cert_name, ca_cert_files=options.ca_cert_files, realm_name=config.realm_name) pkinit_pkcs12_info = (pkinit_pkcs12_file.name, pkinit_pin) if (options.http_cert_files and options.dirsrv_cert_files and http_ca_cert != dirsrv_ca_cert): ansible_module.fail_json( msg="Apache Server SSL certificate and Directory " "Server SSL certificate are not signed by the same" " CA certificate") if (options.http_cert_files and options.pkinit_cert_files and http_ca_cert != pkinit_ca_cert): ansible_module.fail_json( msg="Apache Server SSL certificate and PKINIT KDC " "certificate are not signed by the same CA " "certificate") ansible_log.debug("-- FQDN --") installutils.verify_fqdn(config.host_name, options.no_host_dns) installutils.verify_fqdn(config.master_host_name, options.no_host_dns) ansible_log.debug("-- KINIT_KEYTAB --") ccache = os.environ['KRB5CCNAME'] kinit_keytab('host/{env.host}@{env.realm}'.format(env=api.env), paths.KRB5_KEYTAB, ccache) ansible_log.debug("-- CA_CRT --") cafile = paths.IPA_CA_CRT if not os.path.isfile(cafile): ansible_module.fail_json( msg="CA cert file is not available! Please reinstall" "the client and try again.") ansible_log.debug("-- REMOTE_API --") ldapuri = 'ldaps://%s' % ipautil.format_netloc(config.master_host_name) xmlrpc_uri = 'https://{}/ipa/xml'.format( ipautil.format_netloc(config.master_host_name)) remote_api = create_api(mode=None) remote_api.bootstrap(in_server=True, context='installer', confdir=paths.ETC_IPA, ldap_uri=ldapuri, xmlrpc_uri=xmlrpc_uri) remote_api.finalize() installer._remote_api = remote_api ansible_log.debug("-- RPC_CLIENT --") with rpc_client(remote_api) as client: check_remote_version(client, parse_version(api.env.version)) check_remote_fips_mode(client, api.env.fips_mode) conn = remote_api.Backend.ldap2 replman = None try: ansible_log.debug("-- CONNECT --") # Try out authentication conn.connect(ccache=ccache) replman = ReplicationManager(config.realm_name, config.master_host_name, None) ansible_log.debug("-- CHECK IPA_DOMAIN --") promotion_check_ipa_domain(conn, remote_api.env.basedn) ansible_log.debug("-- CHECK DOMAIN_LEVEL --") # Make sure that domain fulfills minimal domain level # requirement domain_level = current_domain_level(remote_api) check_domain_level_is_supported(domain_level) if domain_level < constants.MIN_DOMAIN_LEVEL: ansible_module.fail_json( msg="Cannot promote this client to a replica. The domain " "level " "must be raised to {mindomainlevel} before the replica can be " "installed".format( mindomainlevel=constants.MIN_DOMAIN_LEVEL)) ansible_log.debug("-- CHECK AUTHORIZATION --") # Check authorization result = remote_api.Command['hostgroup_find']( cn=u'ipaservers', host=[unicode(api.env.host)] )['result'] add_to_ipaservers = not result ansible_log.debug("-- ADD_TO_IPASERVERS --") if add_to_ipaservers: if options.password and not options.admin_password: raise errors.ACIError(info="Not authorized") if installer._ccache is None: del os.environ['KRB5CCNAME'] else: os.environ['KRB5CCNAME'] = installer._ccache try: installutils.check_creds(options, config.realm_name) installer._ccache = os.environ.get('KRB5CCNAME') finally: os.environ['KRB5CCNAME'] = ccache conn.disconnect() conn.connect(ccache=installer._ccache) try: result = remote_api.Command['hostgroup_show']( u'ipaservers', all=True, rights=True )['result'] if 'w' not in result['attributelevelrights']['member']: raise errors.ACIError(info="Not authorized") finally: ansible_log.debug("-- RECONNECT --") conn.disconnect() conn.connect(ccache=ccache) ansible_log.debug("-- CHECK FOR REPLICATION AGREEMENT --") # Check that we don't already have a replication agreement if replman.get_replication_agreement(config.host_name): msg = ("A replication agreement for this host already exists. " "It needs to be removed.\n" "Run this command:\n" " %% ipa-replica-manage del {host} --force" .format(host=config.host_name)) raise ScriptError(msg, rval=3) ansible_log.debug("-- DETECT REPLICATION MANAGER GROUP --") # Detect if the other master can handle replication managers # cn=replication managers,cn=sysaccounts,cn=etc,$SUFFIX dn = DN(('cn', 'replication managers'), ('cn', 'sysaccounts'), ('cn', 'etc'), ipautil.realm_to_suffix(config.realm_name)) try: conn.get_entry(dn) except errors.NotFound: msg = ("The Replication Managers group is not available in " "the domain. Replica promotion requires the use of " "Replication Managers to be able to replicate data. " "Upgrade the peer master or use the ipa-replica-prepare " "command on the master and use a prep file to install " "this replica.") logger.error("%s", msg) raise ScriptError(msg, rval=3) ansible_log.debug("-- CHECK DNS_MASTERS --") dns_masters = remote_api.Object['dnsrecord'].get_dns_masters() if dns_masters: if not options.no_host_dns: logger.debug('Check forward/reverse DNS resolution') resolution_ok = ( check_dns_resolution(config.master_host_name, dns_masters) and check_dns_resolution(config.host_name, dns_masters)) if not resolution_ok and installer.interactive: if not ipautil.user_input("Continue?", False): raise ScriptError(rval=0) else: logger.debug('No IPA DNS servers, ' 'skipping forward/reverse resolution check') ansible_log.debug("-- GET_IPA_CONFIG --") entry_attrs = conn.get_ipa_config() subject_base = entry_attrs.get('ipacertificatesubjectbase', [None])[0] if subject_base is not None: config.subject_base = DN(subject_base) ansible_log.debug("-- SEARCH FOR CA --") # Find if any server has a CA if not hasattr(service, "find_providing_server"): _host = [config.ca_host_name] else: _host = config.ca_host_name ca_host = find_providing_server('CA', conn, _host) if ca_host is not None: config.ca_host_name = ca_host ca_enabled = True if options.dirsrv_cert_files: msg = ("Certificates could not be provided when " "CA is present on some master.") logger.error(msg) raise ScriptError(msg, rval=3) else: if options.setup_ca: msg = ("The remote master does not have a CA " "installed, can't set up CA") logger.error(msg) raise ScriptError(msg, rval=3) ca_enabled = False if not options.dirsrv_cert_files: msg = ("Cannot issue certificates: a CA is not " "installed. Use the --http-cert-file, " "--dirsrv-cert-file options to provide " "custom certificates.") logger.error(msg) raise ScriptError(msg, rval=3) ansible_log.debug("-- SEARCH FOR KRA --") if not hasattr(service, "find_providing_server"): _host = [config.kra_host_name] else: _host = config.kra_host_name kra_host = find_providing_server('KRA', conn, _host) if kra_host is not None: config.kra_host_name = kra_host kra_enabled = True else: if options.setup_kra: msg = ("There is no active KRA server in the domain, " "can't setup a KRA clone") logger.error(msg) raise ScriptError(msg, rval=3) kra_enabled = False ansible_log.debug("-- CHECK CA --") if ca_enabled: options.realm_name = config.realm_name options.host_name = config.host_name ca.install_check(False, config, options) ansible_log.debug(" ca.external_cert_file=%s" % repr(ca.external_cert_file)) ansible_log.debug(" ca.external_ca_file=%s" % repr(ca.external_ca_file)) # TODO # TODO # Save global vars external_cert_file, external_ca_file for # later use # TODO # TODO ansible_log.debug("-- CHECK KRA --") if kra_enabled: try: kra.install_check(remote_api, config, options) except RuntimeError as e: raise ScriptError(e) ansible_log.debug("-- CHECK DNS --") if options.setup_dns: dns.install_check(False, remote_api, True, options, config.host_name) config.ips = dns.ip_addresses else: config.ips = installutils.get_server_ip_address( config.host_name, not installer.interactive, False, options.ip_addresses) # check addresses here, dns module is doing own check no_matching_interface_for_ip_address_warning(config.ips) ansible_log.debug("-- CHECK ADTRUST --") if options.setup_adtrust: adtrust.install_check(False, options, remote_api) except errors.ACIError: logger.debug("%s", traceback.format_exc()) ansible_module.fail_json( msg=("\nInsufficient privileges to promote the server." "\nPossible issues:" "\n- A user has insufficient privileges" "\n- This client has insufficient privileges " "to become an IPA replica")) except errors.LDAPError: logger.debug("%s", traceback.format_exc()) ansible_module.fail_json(msg="\nUnable to connect to LDAP server %s" % config.master_host_name) except ScriptError as e: ansible_module.fail_json(msg=str(e)) finally: if replman and replman.conn: ansible_log.debug("-- UNBIND REPLMAN--") replman.conn.unbind() if conn.isconnected(): ansible_log.debug("-- DISCONNECT --") conn.disconnect() ansible_log.debug("-- CHECK CONNECTION --") # check connection if not options.skip_conncheck: if add_to_ipaservers: # use user's credentials when the server host is not ipaservers if installer._ccache is None: del os.environ['KRB5CCNAME'] else: os.environ['KRB5CCNAME'] = installer._ccache try: with redirect_stdout(ansible_log): replica_conn_check( config.master_host_name, config.host_name, config.realm_name, options.setup_ca, 389, options.admin_password, principal=options.principal, ca_cert_file=cafile) except ScriptError as e: ansible_module.fail_json(msg=str(e)) finally: if add_to_ipaservers: os.environ['KRB5CCNAME'] = ccache if hasattr(tasks, "configure_pkcs11_modules"): if tasks.configure_pkcs11_modules(fstore): ansible_log.info("Disabled p11-kit-proxy") installer._ca_enabled = ca_enabled installer._kra_enabled = kra_enabled installer._ca_file = cafile installer._fstore = fstore installer._sstore = sstore installer._config = config installer._add_to_ipaservers = add_to_ipaservers # done # ansible_module.exit_json( changed=True, ccache=ccache, installer_ccache=installer._ccache, subject_base=str(config.subject_base), forward_policy=options.forward_policy, _ca_enabled=ca_enabled, _ca_subject=str(options._ca_subject), _subject_base=str(options._subject_base) if options._subject_base is not None else None, _kra_enabled=kra_enabled, _ca_file=cafile, _top_dir=installer._top_dir, _add_to_ipaservers=add_to_ipaservers, _dirsrv_pkcs12_info=dirsrv_pkcs12_info, _dirsrv_ca_cert=dirsrv_ca_cert, _http_pkcs12_info=http_pkcs12_info, _http_ca_cert=http_ca_cert, _pkinit_pkcs12_info=pkinit_pkcs12_info, _pkinit_ca_cert=pkinit_ca_cert, no_dnssec_validation=options.no_dnssec_validation, config_setup_ca=config.setup_ca, config_master_host_name=config.master_host_name, config_ca_host_name=config.ca_host_name, config_kra_host_name=config.kra_host_name, config_ips=[str(ip) for ip in config.ips], # ad trust dns_ip_addresses=[str(ip) for ip in dns.ip_addresses], dns_reverse_zones=dns.reverse_zones, rid_base=options.rid_base, secondary_rid_base=options.secondary_rid_base, adtrust_netbios_name=adtrust.netbios_name, adtrust_reset_netbios_name=adtrust.reset_netbios_name)
def main(): ansible_module = AnsibleModule( argument_spec=dict( # basic dm_password=dict(required=True, no_log=True), password=dict(required=True, no_log=True), domain=dict(required=True), realm=dict(required=True), hostname=dict(required=True), # server setup_ca=dict(required=True, type='bool'), idstart=dict(required=True, type='int'), idmax=dict(required=True, type='int'), no_hbac_allow=dict(required=False, type='bool', default=False), no_pkinit=dict(required=False, type='bool', default=False), dirsrv_config_file=dict(required=False), _dirsrv_pkcs12_info=dict(required=False), # ssl certificate dirsrv_cert_files=dict(required=False, type='list', default=[]), subject_base=dict(required=False), ca_subject=dict(required=False), # certificate system external_cert_files=dict(required=False, type='list', default=[]), # additional domainlevel=dict(required=False, type='int', default=MAX_DOMAIN_LEVEL), ), ) ansible_module._ansible_debug = True setup_logging() ansible_log = AnsibleModuleLog(ansible_module) # set values #################################################### # basic options.dm_password = ansible_module.params.get('dm_password') options.admin_password = ansible_module.params.get('password') options.domain_name = ansible_module.params.get('domain') options.realm_name = ansible_module.params.get('realm') options.host_name = ansible_module.params.get('hostname') # server options.setup_ca = ansible_module.params.get('setup_ca') options.idstart = ansible_module.params.get('idstart') options.idmax = ansible_module.params.get('idmax') options.no_hbac_allow = ansible_module.params.get('no_hbac_allow') options.no_pkinit = ansible_module.params.get('no_pkinit') options.dirsrv_config_file = ansible_module.params.get( 'dirsrv_config_file') options._dirsrv_pkcs12_info = ansible_module.params.get( '_dirsrv_pkcs12_info') # ssl certificate options.dirsrv_cert_files = ansible_module.params.get('dirsrv_cert_files') options.subject_base = ansible_module.params.get('subject_base') options.ca_subject = ansible_module.params.get('ca_subject') # certificate system options.external_cert_files = ansible_module.params.get( 'external_cert_files') # additional options.domainlevel = ansible_module.params.get('domainlevel') options.domain_level = options.domainlevel # init ########################################################## fstore = sysrestore.FileStore(paths.SYSRESTORE) api_Backend_ldap2(options.host_name, options.setup_ca, connect=True) ds = ds_init_info(ansible_log, fstore, options.domainlevel, options.dirsrv_config_file, options.realm_name, options.host_name, options.domain_name, options.dm_password, options.idstart, options.idmax, options.subject_base, options.ca_subject, options.no_hbac_allow, options._dirsrv_pkcs12_info, options.no_pkinit) # set ds password ############################################### with redirect_stdout(ansible_log): ds.change_admin_password(options.admin_password) # done ########################################################## ansible_module.exit_json(changed=True)
def configure_module(): """Configure ipadnsrecord ansible module variables.""" record_spec = dict( zone_name=dict(type='str', required=False, aliases=['dnszone']), record_type=dict(type='str', default="A", choices=["A", "AAAA", "A6", "AFSDB", "CERT", "CNAME", "DLV", "DNAME", "DS", "KX", "LOC", "MX", "NAPTR", "NS", "PTR", "SRV", "SSHFP", "TLSA", "TXT", "URI"]), record_value=dict(type='list', required=False), record_ttl=dict(type='int', required=False), del_all=dict(type='bool', required=False), a_rec=dict(type='list', required=False, aliases=['a_record']), aaaa_rec=dict(type='list', required=False, aliases=['aaaa_record']), a6_rec=dict(type='list', required=False, aliases=['a6_record']), afsdb_rec=dict(type='list', required=False, aliases=['afsdb_record']), cert_rec=dict(type='list', required=False, aliases=['cert_record']), cname_rec=dict(type='list', required=False, aliases=['cname_record']), dlv_rec=dict(type='list', required=False, aliases=['dlv_record']), dname_rec=dict(type='list', required=False, aliases=['dname_record']), ds_rec=dict(type='list', required=False, aliases=['ds_record']), kx_rec=dict(type='list', required=False, aliases=['kx_record']), loc_rec=dict(type='list', required=False, aliases=['loc_record']), mx_rec=dict(type='list', required=False, aliases=['mx_record']), naptr_rec=dict(type='list', required=False, aliases=['naptr_record']), ns_rec=dict(type='list', required=False, aliases=['ns_record']), ptr_rec=dict(type='list', required=False, aliases=['ptr_record']), srv_rec=dict(type='list', required=False, aliases=['srv_record']), sshfp_rec=dict(type='list', required=False, aliases=['sshfp_record']), tlsa_rec=dict(type='list', required=False, aliases=['tlsa_record']), txt_rec=dict(type='list', required=False, aliases=['txt_record']), uri_rec=dict(type='list', required=False, aliases=['uri_record']), ip_address=dict(type='str', required=False), create_reverse=dict(type='bool', required=False, aliases=['reverse']), a_ip_address=dict(type='str', required=False), a_create_reverse=dict(type='bool', required=False), aaaa_ip_address=dict(type='str', required=False), aaaa_create_reverse=dict(type='bool', required=False), a6_data=dict(type='str', required=False), afsdb_subtype=dict(type='int', required=False), afsdb_hostname=dict(type='str', required=False), cert_type=dict(type='int', required=False), cert_key_tag=dict(type='int', required=False), cert_algorithm=dict(type='int', required=False), cert_certificate_or_crl=dict(type='str', required=False), cname_hostname=dict(type='str', required=False), dlv_key_tag=dict(type='int', required=False), dlv_algorithm=dict(type='int', required=False), dlv_digest_type=dict(type='int', required=False), dlv_digest=dict(type='str', required=False), dname_target=dict(type='str', required=False), ds_key_tag=dict(type='int', required=False), ds_algorithm=dict(type='int', required=False), ds_digest_type=dict(type='int', required=False), ds_digest=dict(type='str', required=False), kx_preference=dict(type='int', required=False), kx_exchanger=dict(type='str', required=False), loc_lat_deg=dict(type='int', required=False), loc_lat_min=dict(type='int', required=False), loc_lat_sec=dict(type='float', required=False), loc_lat_dir=dict(type='str', required=False), loc_lon_deg=dict(type='int', required=False), loc_lon_min=dict(type='int', required=False), loc_lon_sec=dict(type='float', required=False), loc_lon_dir=dict(type='str', required=False), loc_altitude=dict(type='float', required=False), loc_size=dict(type='float', required=False), loc_h_precision=dict(type='float', required=False), loc_v_precision=dict(type='float', required=False), mx_preference=dict(type='int', required=False), mx_exchanger=dict(type='str', required=False), naptr_order=dict(type='int', required=False), naptr_preference=dict(type='int', required=False), naptr_flags=dict(type='str', required=False), naptr_service=dict(type='str', required=False), naptr_regexp=dict(type='str', required=False), naptr_replacement=dict(type='str', required=False), ns_hostname=dict(type='str', required=False), ptr_hostname=dict(type='str', required=False), srv_priority=dict(type='int', required=False), srv_weight=dict(type='int', required=False), srv_port=dict(type='int', required=False), srv_target=dict(type='str', required=False), sshfp_algorithm=dict(type='int', required=False), sshfp_fingerprint=dict(type='str', required=False), sshfp_fp_type=dict(type='int', required=False), tlsa_cert_usage=dict(type='int', required=False), tlsa_cert_association_data=dict(type='str', required=False), tlsa_matching_type=dict(type='int', required=False), tlsa_selector=dict(type='int', required=False), txt_data=dict(type='str', required=False), uri_priority=dict(type='int', required=False), uri_target=dict(type='str', required=False), uri_weight=dict(type='int', required=False), ) ansible_module = AnsibleModule( argument_spec=dict( # general ipaadmin_principal=dict(type="str", default="admin"), ipaadmin_password=dict(type="str", no_log=True), name=dict(type="list", aliases=["record_name"], default=None, required=False), records=dict(type="list", default=None, options=dict( # Here name is a simple string name=dict(type='str', required=True, aliases=['record_name']), **record_spec), ), # general state=dict(type="str", default="present", choices=["present", "absent", "disabled"]), # Add record specific parameters for simple use case **record_spec ), mutually_exclusive=[["name", "records"], ['record_value', 'del_all']], required_one_of=[["name", "records"]], supports_check_mode=True, ) ansible_module._ansible_debug = True return ansible_module
def main(): ansible_module = AnsibleModule( argument_spec=dict( # server setup_ca=dict(required=False, type='bool'), setup_kra=dict(required=False, type='bool'), no_pkinit=dict(required=False, type='bool'), # certificate system subject_base=dict(required=True), # additional config_master_host_name=dict(required=True), ccache=dict(required=True), _ca_enabled=dict(required=False, type='bool'), _ca_file=dict(required=False), _pkinit_pkcs12_info=dict(required=False), _top_dir=dict(required=True), dirman_password=dict(required=True, no_log=True), ), supports_check_mode=True, ) ansible_module._ansible_debug = True ansible_log = AnsibleModuleLog(ansible_module) # get parameters # options = installer # server options.setup_ca = ansible_module.params.get('setup_ca') options.setup_kra = ansible_module.params.get('setup_kra') options.no_pkinit = ansible_module.params.get('no_pkinit') # certificate system options.subject_base = ansible_module.params.get('subject_base') if options.subject_base is not None: options.subject_base = DN(options.subject_base) # additional master_host_name = ansible_module.params.get('config_master_host_name') ccache = ansible_module.params.get('ccache') os.environ['KRB5CCNAME'] = ccache # os.environ['KRB5CCNAME'] = ansible_module.params.get('installer_ccache') # installer._ccache = ansible_module.params.get('installer_ccache') options._pkinit_pkcs12_info = ansible_module.params.get( '_pkinit_pkcs12_info') options._top_dir = ansible_module.params.get('_top_dir') dirman_password = ansible_module.params.get('dirman_password') # init # fstore = sysrestore.FileStore(paths.SYSRESTORE) ansible_log.debug("== INSTALL ==") options = installer env = gen_env_boostrap_finalize_core(paths.ETC_IPA, constants.DEFAULT_CONFIG) api_bootstrap_finalize(env) config = gen_ReplicaConfig() config.dirman_password = dirman_password remote_api = gen_remote_api(master_host_name, paths.ETC_IPA) # installer._remote_api = remote_api conn = remote_api.Backend.ldap2 ccache = os.environ['KRB5CCNAME'] # There is a api.Backend.ldap2.connect call somewhere in ca, ds, dns or # ntpinstance api.Backend.ldap2.connect() conn.connect(ccache=ccache) # krb krb = krbinstance.KrbInstance(fstore) krb.set_output(ansible_log) with redirect_stdout(ansible_log): krb.init_info(api.env.realm, api.env.host, setup_pkinit=not options.no_pkinit, subject_base=options.subject_base) krb.pkcs12_info = options._pkinit_pkcs12_info krb.master_fqdn = master_host_name ansible_log.debug("-- KRB ENABLE_SSL --") # configure PKINIT now that all required services are in place krb.enable_ssl() # done # ansible_module.exit_json(changed=True)
def main(): module = AnsibleModule( argument_spec=dict( servers=dict(required=True, type='list'), domain=dict(required=True), realm=dict(required=True), hostname=dict(required=True), basedn=dict(required=True), principal=dict(required=False), subject_base=dict(required=True), ca_enabled=dict(required=True, type='bool'), mkhomedir=dict(required=False, type='bool'), on_master=dict(required=False, type='bool'), dnsok=dict(required=False, type='bool', default=False), enable_dns_updates=dict(required=False, type='bool'), all_ip_addresses=dict(required=False, type='bool', default=False), ip_addresses=dict(required=False, type='list', default=None), request_cert=dict(required=False, type='bool', default=False), preserve_sssd=dict(required=False, type='bool'), no_ssh=dict(required=False, type='bool'), no_sshd=dict(required=False, type='bool'), no_sudo=dict(required=False, type='bool'), fixed_primary=dict(required=False, type='bool'), permit=dict(required=False, type='bool'), no_krb5_offline_passwords=dict(required=False, type='bool'), no_dns_sshfp=dict(required=False, type='bool', default=False), nosssd_files=dict(required=True, type='dict'), ), supports_check_mode=True, ) module._ansible_debug = True setup_logging() cli_server = module.params.get('servers') cli_realm = module.params.get('realm') hostname = module.params.get('hostname') cli_basedn = module.params.get('basedn') cli_domain = module.params.get('domain') options.principal = module.params.get('principal') subject_base = module.params.get('subject_base') ca_enabled = module.params.get('ca_enabled') options.mkhomedir = module.params.get('mkhomedir') options.on_master = module.params.get('on_master') dnsok = module.params.get('dnsok') fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE) statestore = sysrestore.StateFile(paths.IPA_CLIENT_SYSRESTORE) os.environ['KRB5CCNAME'] = paths.IPA_DNS_CCACHE options.dns_updates = module.params.get('enable_dns_updates') options.all_ip_addresses = module.params.get('all_ip_addresses') options.ip_addresses = ansible_module_get_parsed_ip_addresses(module) options.request_cert = module.params.get('request_cert') options.hostname = hostname options.host_name = hostname options.preserve_sssd = module.params.get('preserve_sssd') options.no_ssh = module.params.get('no_ssh') options.conf_ssh = not options.no_ssh options.no_sshd = module.params.get('no_sshd') options.conf_sshd = not options.no_sshd options.no_sudo = module.params.get('no_sudo') options.conf_sudo = not options.no_sudo options.primary = module.params.get('fixed_primary') options.permit = module.params.get('permit') options.no_krb5_offline_passwords = module.params.get( 'no_krb5_offline_passwords') options.krb5_offline_passwords = not options.no_krb5_offline_passwords options.no_dns_sshfp = module.params.get('no_dns_sshfp') options.create_sshfp = not options.no_dns_sshfp options.no_sssd = False options.sssd = not options.no_sssd options.no_ac = False nosssd_files = module.params.get('nosssd_files') # pylint: disable=invalid-name CCACHE_FILE = paths.IPA_DNS_CCACHE api.bootstrap(context='cli_installer', confdir=paths.ETC_IPA, debug=False, delegate=False) api.finalize() api.Backend.rpcclient.connect() try: api.Backend.rpcclient.forward('ping') except errors.KerberosError: # Cannot connect to the server due to Kerberos error, trying with # delegate=True api.Backend.rpcclient.disconnect() api.Backend.rpcclient.connect(delegate=True) api.Backend.rpcclient.forward('ping') ########################################################################## try: # Create IPA NSS database try: create_ipa_nssdb() except ipautil.CalledProcessError as e: raise ScriptError( "Failed to create IPA NSS database: %s" % e, rval=CLIENT_INSTALL_ERROR) # Get CA certificates from the certificate store try: ca_certs = get_certs_from_ldap(cli_server[0], cli_basedn, cli_realm, ca_enabled) except errors.NoCertificateError: if ca_enabled: ca_subject = DN(('CN', 'Certificate Authority'), subject_base) else: ca_subject = None ca_certs = certstore.make_compat_ca_certs(ca_certs, cli_realm, ca_subject) ca_certs_trust = [(c, n, certstore.key_policy_to_trust_flags(t, True, u)) for (c, n, t, u) in ca_certs] if hasattr(paths, "KDC_CA_BUNDLE_PEM"): x509.write_certificate_list( [c for c, n, t, u in ca_certs if t is not False], paths.KDC_CA_BUNDLE_PEM, # mode=0o644 ) if hasattr(paths, "CA_BUNDLE_PEM"): x509.write_certificate_list( [c for c, n, t, u in ca_certs if t is not False], paths.CA_BUNDLE_PEM, # mode=0o644 ) # Add the CA certificates to the IPA NSS database logger.debug("Adding CA certificates to the IPA NSS database.") ipa_db = certdb.NSSDatabase(paths.IPA_NSSDB_DIR) for cert, nickname, trust_flags in ca_certs_trust: try: ipa_db.add_cert(cert, nickname, trust_flags) except CalledProcessError: raise ScriptError( "Failed to add %s to the IPA NSS database." % nickname, rval=CLIENT_INSTALL_ERROR) # Add the CA certificates to the platform-dependant systemwide CA # store tasks.insert_ca_certs_into_systemwide_ca_store(ca_certs) if not options.on_master: client_dns(cli_server[0], hostname, options) configure_certmonger(fstore, subject_base, cli_realm, hostname, options, ca_enabled) if hasattr(paths, "SSH_CONFIG_DIR"): ssh_config_dir = paths.SSH_CONFIG_DIR else: ssh_config_dir = services.knownservices.sshd.get_config_dir() update_ssh_keys(hostname, ssh_config_dir, options.create_sshfp) try: os.remove(CCACHE_FILE) except Exception: pass # pylint: disable=deprecated-method argspec_save_state = inspect.getargspec(save_state) # Name Server Caching Daemon. Disable for SSSD, use otherwise # (if installed) nscd = services.knownservices.nscd if nscd.is_installed(): if "statestore" in argspec_save_state.args: save_state(nscd, statestore) else: save_state(nscd) nscd_service_action = None try: if options.sssd: nscd_service_action = 'stop' nscd.stop() else: nscd_service_action = 'restart' nscd.restart() except Exception: logger.warning( "Failed to %s the %s daemon", nscd_service_action, nscd.service_name) if not options.sssd: logger.warning( "Caching of users/groups will not be available") try: if options.sssd: nscd.disable() else: nscd.enable() except Exception: if not options.sssd: logger.warning( "Failed to configure automatic startup of the %s " "daemon", nscd.service_name) logger.info( "Caching of users/groups will not be " "available after reboot") else: logger.warning( "Failed to disable %s daemon. Disable it manually.", nscd.service_name) else: # this is optional service, just log if not options.sssd: logger.info( "%s daemon is not installed, skip configuration", nscd.service_name) nslcd = services.knownservices.nslcd if nslcd.is_installed(): if "statestore" in argspec_save_state.args: save_state(nslcd, statestore) else: save_state(nslcd) retcode, conf = (0, None) if not options.no_ac: # Modify nsswitch/pam stack # pylint: disable=deprecated-method argspec = inspect.getargspec(tasks.modify_nsswitch_pam_stack) if "sudo" in argspec.args: tasks.modify_nsswitch_pam_stack( sssd=options.sssd, mkhomedir=options.mkhomedir, statestore=statestore, sudo=options.conf_sudo ) else: tasks.modify_nsswitch_pam_stack( sssd=options.sssd, mkhomedir=options.mkhomedir, statestore=statestore ) if hasattr(paths, "AUTHSELECT") and paths.AUTHSELECT is not None: # authselect is used # if mkhomedir, make sure oddjobd is enabled and started if options.mkhomedir: oddjobd = services.service('oddjobd', api) running = oddjobd.is_running() enabled = oddjobd.is_enabled() statestore.backup_state('oddjobd', 'running', running) statestore.backup_state('oddjobd', 'enabled', enabled) try: if not enabled: oddjobd.enable() if not running: oddjobd.start() except Exception as e: logger.critical("Unable to start oddjobd: %s", str(e)) logger.info("%s enabled", "SSSD" if options.sssd else "LDAP") if options.sssd: sssd = services.service('sssd', api) try: sssd.restart() except CalledProcessError: logger.warning("SSSD service restart was unsuccessful.") try: sssd.enable() except CalledProcessError as e: logger.warning( "Failed to enable automatic startup of the SSSD " "daemon: %s", e) if not options.sssd: tasks.modify_pam_to_use_krb5(statestore) logger.info("Kerberos 5 enabled") # Update non-SSSD LDAP configuration after authconfig calls as it # would change its configuration otherways if not options.sssd: for configurer in [configure_ldap_conf, configure_nslcd_conf]: (retcode, conf, filenames) = configurer( fstore, cli_basedn, cli_realm, cli_domain, cli_server, dnsok, options, nosssd_files[configurer.__name__]) if retcode: raise ScriptError(rval=CLIENT_INSTALL_ERROR) if conf: logger.info( "%s configured using configuration file(s) %s", conf, filenames) if configure_openldap_conf(fstore, cli_basedn, cli_server): logger.info("Configured /etc/openldap/ldap.conf") else: logger.info("Failed to configure /etc/openldap/ldap.conf") # Check that nss is working properly if not options.on_master: user = options.principal if user is None: user = "******" % cli_domain logger.info("Principal is not set when enrolling with OTP" "; using principal '%s' for 'getent passwd'", user) elif '@' not in user: user = "******" % (user, cli_domain) n = 0 found = False # Loop for up to 10 seconds to see if nss is working properly. # It can sometimes take a few seconds to connect to the remote # provider. # Particulary, SSSD might take longer than 6-8 seconds. if hasattr(paths, "GETENT"): getent_cmd = paths.GETENT else: getent_cmd = '/usr/bin/getent' while n < 10 and not found: try: ipautil.run([getent_cmd, "passwd", user]) found = True except Exception: time.sleep(1) n = n + 1 if not found: logger.error("Unable to find '%s' user with 'getent " "passwd %s'!", user.split("@")[0], user) if conf: logger.info("Recognized configuration: %s", conf) else: logger.error( "Unable to reliably detect " "configuration. Check NSS setup manually.") try: hardcode_ldap_server(cli_server) except Exception as e: logger.error( "Adding hardcoded server name to " "/etc/ldap.conf failed: %s", str(e)) except ScriptError as e: module.fail_json(msg=str(e)) ########################################################################## module.exit_json(changed=True, ca_enabled_ra=ca_enabled)
def main(): ansible_module = AnsibleModule( argument_spec=dict( # basic dm_password=dict(required=True, no_log=True), password=dict(required=True, no_log=True), domain=dict(required=True), realm=dict(required=True), hostname=dict(required=False), # server idstart=dict(required=True, type='int'), idmax=dict(required=True, type='int'), no_hbac_allow=dict(required=False, type='bool', default=False), no_pkinit=dict(required=False, type='bool', default=False), dirsrv_config_file=dict(required=False), # ssl certificate dirsrv_cert_files=dict(required=False, type='list', default=[]), _dirsrv_pkcs12_info=dict(required=False), # certificate system external_cert_files=dict(required=False, type='list', default=[]), subject_base=dict(required=False), ca_subject=dict(required=False), # additional setup_ca=dict(required=False, type='bool', default=False), ), ) ansible_module._ansible_debug = True setup_logging() ansible_log = AnsibleModuleLog(ansible_module) # set values ############################################################ # basic options.dm_password = ansible_module.params.get('dm_password') options.domain_name = ansible_module.params.get('domain') options.realm_name = ansible_module.params.get('realm') options.host_name = ansible_module.params.get('hostname') # server options.idstart = ansible_module.params.get('idstart') options.idmax = ansible_module.params.get('idmax') options.no_pkinit = ansible_module.params.get('no_pkinit') options.no_hbac_allow = ansible_module.params.get('no_hbac_allow') options.dirsrv_config_file = ansible_module.params.get( 'dirsrv_config_file') options._dirsrv_pkcs12_info = ansible_module.params.get( '_dirsrv_pkcs12_info') # ssl certificate options.dirsrv_cert_files = ansible_module.params.get('dirsrv_cert_files') # certificate system options.external_cert_files = ansible_module.params.get( 'external_cert_files') options.subject_base = ansible_module.params.get('subject_base') options.ca_subject = ansible_module.params.get('ca_subject') # additional options.setup_ca = ansible_module.params.get('setup_ca') # init ################################################################## fstore = sysrestore.FileStore(paths.SYSRESTORE) # api Backend connect only if external_cert_files is not set api_Backend_ldap2(options.host_name, options.setup_ca, connect=False) # setup DS ############################################################## # Make sure tmpfiles dir exist before installing components if NUM_VERSION == 40504: tasks.create_tmpfiles_dirs(IPAAPI_USER) elif 40500 <= NUM_VERSION <= 40503: tasks.create_tmpfiles_dirs() # Create a directory server instance if not options.external_cert_files: ds = dsinstance.DsInstance(fstore=fstore, domainlevel=options.domainlevel, config_ldif=options.dirsrv_config_file) ds.set_output(ansible_log) if options.dirsrv_cert_files: _dirsrv_pkcs12_info = options._dirsrv_pkcs12_info else: _dirsrv_pkcs12_info = None with redirect_stdout(ansible_log): ds.create_instance(options.realm_name, options.host_name, options.domain_name, options.dm_password, _dirsrv_pkcs12_info, idstart=options.idstart, idmax=options.idmax, subject_base=options.subject_base, ca_subject=options.ca_subject, hbac_allow=not options.no_hbac_allow, setup_pkinit=not options.no_pkinit) if not options.dirsrv_cert_files and NUM_VERSION < 40690: ntpinstance.ntp_ldap_enable(options.host_name, ds.suffix, options.realm_name) else: api.Backend.ldap2.connect() ds = dsinstance.DsInstance(fstore=fstore, domainlevel=options.domainlevel) ds.set_output(ansible_log) with redirect_stdout(ansible_log): ds.init_info(options.realm_name, options.host_name, options.domain_name, options.dm_password, options.subject_base, options.ca_subject, 1101, 1100, None, setup_pkinit=not options.no_pkinit) # done ################################################################## ansible_module.exit_json(changed=True)
def main(): ansible_module = AnsibleModule( argument_spec=dict( # generalgroups ipaadmin_principal=dict(type="str", default="admin"), ipaadmin_password=dict(type="str", required=False, no_log=True), name=dict(type="list", aliases=["cn"], default=None, required=True), description=dict(required=False, type="str", default=None), vault_type=dict(type="str", aliases=["ipavaulttype"], default=None, required=False, choices=["standard", "symmetric", "asymmetric"]), vault_public_key=dict(type="str", required=False, default=None, aliases=['ipavaultpublickey', 'public_key']), vault_public_key_file=dict(type="str", required=False, default=None, aliases=['public_key_file']), vault_private_key=dict( type="str", required=False, default=None, no_log=True, aliases=['ipavaultprivatekey', 'private_key']), vault_private_key_file=dict(type="str", required=False, default=None, aliases=['private_key_file']), vault_salt=dict(type="str", required=False, default=None, aliases=['ipavaultsalt', 'salt']), username=dict(type="str", required=False, default=None, aliases=['user']), service=dict(type="str", required=False, default=None), shared=dict(type="bool", required=False, default=None), users=dict(required=False, type='list', default=None), groups=dict(required=False, type='list', default=None), services=dict(required=False, type='list', default=None), owners=dict(required=False, type='list', default=None, aliases=['ownerusers']), ownergroups=dict(required=False, type='list', default=None), ownerservices=dict(required=False, type='list', default=None), vault_data=dict(type="str", required=False, default=None, no_log=True, aliases=['ipavaultdata', 'data']), datafile_in=dict(type="str", required=False, default=None, aliases=['in']), datafile_out=dict(type="str", required=False, default=None, aliases=['out']), vault_password=dict(type="str", required=False, default=None, no_log=True, aliases=['ipavaultpassword', 'password', "old_password"]), vault_password_file=dict(type="str", required=False, default=None, no_log=False, aliases=[ 'password_file', "old_password_file" ]), new_password=dict(type="str", required=False, default=None, no_log=True), new_password_file=dict(type="str", required=False, default=None, no_log=False), # state action=dict(type="str", default="vault", choices=["vault", "data", "member"]), state=dict(type="str", default="present", choices=["present", "absent", "retrieved"]), ), supports_check_mode=True, mutually_exclusive=[['username', 'service', 'shared'], ['datafile_in', 'vault_data'], ['new_password', 'new_password_file'], ['vault_password', 'vault_password_file'], ['vault_public_key', 'vault_public_key_file']], ) ansible_module._ansible_debug = True # general ipaadmin_principal = module_params_get(ansible_module, "ipaadmin_principal") ipaadmin_password = module_params_get(ansible_module, "ipaadmin_password") names = module_params_get(ansible_module, "name") # present description = module_params_get(ansible_module, "description") username = module_params_get(ansible_module, "username") service = module_params_get(ansible_module, "service") shared = module_params_get(ansible_module, "shared") users = module_params_get(ansible_module, "users") groups = module_params_get(ansible_module, "groups") services = module_params_get(ansible_module, "services") owners = module_params_get(ansible_module, "owners") ownergroups = module_params_get(ansible_module, "ownergroups") ownerservices = module_params_get(ansible_module, "ownerservices") vault_type = module_params_get(ansible_module, "vault_type") salt = module_params_get(ansible_module, "vault_salt") password = module_params_get(ansible_module, "vault_password") password_file = module_params_get(ansible_module, "vault_password_file") new_password = module_params_get(ansible_module, "new_password") new_password_file = module_params_get(ansible_module, "new_password_file") public_key = module_params_get(ansible_module, "vault_public_key") public_key_file = module_params_get(ansible_module, "vault_public_key_file") private_key = module_params_get(ansible_module, "vault_private_key") private_key_file = module_params_get(ansible_module, "vault_private_key_file") vault_data = module_params_get(ansible_module, "vault_data") datafile_in = module_params_get(ansible_module, "datafile_in") datafile_out = module_params_get(ansible_module, "datafile_out") action = module_params_get(ansible_module, "action") state = module_params_get(ansible_module, "state") # Check parameters if state == "present": if len(names) != 1: ansible_module.fail_json( msg="Only one vault can be added at a time.") elif state == "absent": if len(names) < 1: ansible_module.fail_json(msg="No name given.") elif state == "retrieved": if len(names) != 1: ansible_module.fail_json( msg="Only one vault can be retrieved at a time.") else: ansible_module.fail_json(msg="Invalid state '%s'" % state) check_parameters(ansible_module, state, action, description, username, service, shared, users, groups, services, owners, ownergroups, ownerservices, vault_type, salt, password, password_file, public_key, public_key_file, private_key, private_key_file, vault_data, datafile_in, datafile_out, new_password, new_password_file) # Init changed = False exit_args = {} ccache_dir = None ccache_name = None try: if not valid_creds(ansible_module, ipaadmin_principal): ccache_dir, ccache_name = temp_kinit(ipaadmin_principal, ipaadmin_password) # Need to set krb5 ccache name, due to context='ansible-freeipa' if ccache_name is not None: os.environ["KRB5CCNAME"] = ccache_name api_connect(context='ansible-freeipa') commands = [] for name in names: # Make sure vault exists res_find = find_vault( ansible_module, name, username, service, shared) # Generate args args = gen_args(description, username, service, shared, vault_type, salt, password, password_file, public_key, public_key_file, vault_data, datafile_in, datafile_out) pwdargs = None # Set default vault_type if needed. if vault_type is None and vault_data is not None: if res_find is not None: res_vault_type = res_find.get('ipavaulttype')[0] args['ipavaulttype'] = vault_type = res_vault_type else: args['ipavaulttype'] = vault_type = u"symmetric" # Create command if state == "present": # verify data encription args check_encryption_params( ansible_module, state, action, vault_type, salt, password, password_file, public_key, public_key_file, private_key, private_key_file, vault_data, datafile_in, datafile_out, new_password, new_password_file, res_find) # Found the vault if action == "vault": if res_find is not None: # For all settings is args, check if there are # different settings in the find result. # If yes: modify if not compare_args_ipa(ansible_module, args, res_find): commands.append([name, "vault_mod_internal", args]) else: if vault_type == 'symmetric' \ and 'ipavaultsalt' not in args: args['ipavaultsalt'] = os.urandom(32) commands.append([name, "vault_add_internal", args]) if vault_type != 'standard' and vault_data is None: vault_data = '' # Set res_find to empty dict for next steps res_find = {} # Generate adittion and removal lists user_add, user_del = \ gen_add_del_lists(users, res_find.get('member_user', [])) group_add, group_del = \ gen_add_del_lists(groups, res_find.get('member_group', [])) service_add, service_del = \ gen_add_del_lists(services, res_find.get('member_service', [])) owner_add, owner_del = \ gen_add_del_lists(owners, res_find.get('owner_user', [])) ownergroups_add, ownergroups_del = \ gen_add_del_lists(ownergroups, res_find.get('owner_group', [])) ownerservice_add, ownerservice_del = \ gen_add_del_lists(ownerservices, res_find.get('owner_service', [])) # Add users and groups user_add_args = gen_member_args(args, user_add, group_add, service_add) if user_add_args is not None: commands.append( [name, 'vault_add_member', user_add_args]) # Remove users and groups user_del_args = gen_member_args(args, user_del, group_del, service_del) if user_del_args is not None: commands.append( [name, 'vault_remove_member', user_del_args]) # Add owner users and groups owner_add_args = gen_member_args( args, owner_add, ownergroups_add, ownerservice_add) if owner_add_args is not None: commands.append( [name, 'vault_add_owner', owner_add_args]) # Remove owner users and groups owner_del_args = gen_member_args( args, owner_del, ownergroups_del, ownerservice_del) if owner_del_args is not None: commands.append( [name, 'vault_remove_owner', owner_del_args]) elif action in "member": # Add users and groups if any([users, groups, services]): user_args = gen_member_args(args, users, groups, services) commands.append([name, 'vault_add_member', user_args]) if any([owners, ownergroups, ownerservices]): owner_args = gen_member_args(args, owners, ownergroups, ownerservices) commands.append([name, 'vault_add_owner', owner_args]) pwdargs = data_storage_args( args, vault_data, password, password_file, private_key, private_key_file, datafile_in, datafile_out) if any([vault_data, datafile_in]): commands.append([name, "vault_archive", pwdargs]) cmds = change_password( ansible_module, res_find, password, password_file, new_password, new_password_file) commands.extend(cmds) elif state == "retrieved": if res_find is None: ansible_module.fail_json( msg="Vault `%s` not found to retrieve data." % name) # verify data encription args check_encryption_params( ansible_module, state, action, vault_type, salt, password, password_file, public_key, public_key_file, private_key, private_key_file, vault_data, datafile_in, datafile_out, new_password, new_password_file, res_find) pwdargs = data_storage_args( args, vault_data, password, password_file, private_key, private_key_file, datafile_in, datafile_out) if 'data' in pwdargs: del pwdargs['data'] commands.append([name, "vault_retrieve", pwdargs]) elif state == "absent": if 'ipavaulttype' in args: del args['ipavaulttype'] if action == "vault": if res_find is not None: commands.append([name, "vault_del", args]) elif action == "member": # remove users and groups if any([users, groups, services]): user_args = gen_member_args( args, users, groups, services) commands.append( [name, 'vault_remove_member', user_args]) if any([owners, ownergroups, ownerservices]): owner_args = gen_member_args( args, owners, ownergroups, ownerservices) commands.append( [name, 'vault_remove_owner', owner_args]) else: ansible_module.fail_json( msg="Invalid action '%s' for state '%s'" % (action, state)) else: ansible_module.fail_json(msg="Unknown state '%s'" % state) # Execute commands errors = [] for name, command, args in commands: try: result = api_command(ansible_module, command, name, args) if command == 'vault_archive': changed = 'Archived data into' in result['summary'] elif command == 'vault_retrieve': if 'result' not in result: raise Exception("No result obtained.") if 'data' in result['result']: data_return = exit_args.setdefault('vault', {}) data_return['data'] = result['result']['data'] elif 'vault_data' in result['result']: data_return = exit_args.setdefault('vault', {}) data_return['data'] = result['result']['vault_data'] else: raise Exception("No data retrieved.") changed = False else: if "completed" in result: if result["completed"] > 0: changed = True else: changed = True except EmptyModlist: result = {} except Exception as exception: ansible_module.fail_json( msg="%s: %s: %s" % (command, name, str(exception))) # Get all errors # All "already a member" and "not a member" failures in the # result are ignored. All others are reported. if "failed" in result and len(result["failed"]) > 0: for item in result["failed"]: failed_item = result["failed"][item] for member_type in failed_item: for member, failure in failed_item[member_type]: if "already a member" in failure \ or "not a member" in failure: continue errors.append("%s: %s %s: %s" % ( command, member_type, member, failure)) if len(errors) > 0: ansible_module.fail_json(msg=", ".join(errors)) except Exception as exception: ansible_module.fail_json(msg=str(exception)) finally: temp_kdestroy(ccache_dir, ccache_name) # Done ansible_module.exit_json(changed=changed, **exit_args)
def main(): module = AnsibleModule( argument_spec=dict( domain=dict(required=False, default=None), servers=dict(required=False, type='list', default=None), realm=dict(required=False, default=None), hostname=dict(required=False, default=None), kdc=dict(required=False, default=None), dnsok=dict(required=False, type='bool', default=False), client_domain=dict(required=False, default=None), sssd=dict(required=False, type='bool', default=False), force=dict(required=False, type='bool', default=False), # on_master=dict(required=False, type='bool', default=False), ), supports_check_mode=True, ) module._ansible_debug = True setup_logging() servers = module.params.get('servers') domain = module.params.get('domain') realm = module.params.get('realm') hostname = module.params.get('hostname') kdc = module.params.get('kdc') dnsok = module.params.get('dnsok') client_domain = module.params.get('client_domain') sssd = module.params.get('sssd') force = module.params.get('force') # on_master = module.params.get('on_master') fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE) # if options.on_master: # # If on master assume kerberos is already configured properly. # # Get the host TGT. # try: # kinit_keytab(host_principal, paths.KRB5_KEYTAB, CCACHE_FILE, # attempts=options.kinit_attempts) # os.environ['KRB5CCNAME'] = CCACHE_FILE # except gssapi.exceptions.GSSError as e: # logger.error("Failed to obtain host TGT: %s", e) # raise ScriptError(rval=CLIENT_INSTALL_ERROR) # else: # Configure krb5.conf fstore.backup_file(paths.KRB5_CONF) configure_krb5_conf(cli_realm=realm, cli_domain=domain, cli_server=servers, cli_kdc=kdc, dnsok=dnsok, filename=paths.KRB5_CONF, client_domain=client_domain, client_hostname=hostname, configure_sssd=sssd, force=force) logger.info("Configured /etc/krb5.conf for IPA realm %s", realm) module.exit_json(changed=True)
def main(): ansible_module = AnsibleModule( argument_spec=dict( # general ipaadmin_principal=dict(type="str", default="admin"), ipaadmin_password=dict(type="str", required=False, no_log=True), name=dict(type="list", aliases=["cn"], default=None, required=True), # present description=dict(type="str", default=None), nomembers=dict(required=False, type='bool', default=None), sudocmd=dict(required=False, type='list', default=None), action=dict(type="str", default="sudocmdgroup", choices=["member", "sudocmdgroup"]), # state state=dict(type="str", default="present", choices=["present", "absent"]), ), supports_check_mode=True, ) ansible_module._ansible_debug = True # Get parameters # general ipaadmin_principal = ansible_module.params.get("ipaadmin_principal") ipaadmin_password = ansible_module.params.get("ipaadmin_password") names = ansible_module.params.get("name") # present description = ansible_module.params.get("description") nomembers = ansible_module.params.get("nomembers") sudocmd = ansible_module.params.get("sudocmd") action = ansible_module.params.get("action") # state state = ansible_module.params.get("state") # Check parameters if state == "present": if len(names) != 1: ansible_module.fail_json( msg="Only one sudocmdgroup can be added at a time.") if action == "member": invalid = ["description", "nomembers"] for x in invalid: if vars()[x] is not None: ansible_module.fail_json( msg="Argument '%s' can not be used with action " "'%s'" % (x, action)) if state == "absent": if len(names) < 1: ansible_module.fail_json(msg="No name given.") invalid = ["description", "nomembers"] if action == "sudocmdgroup": invalid.extend(["sudocmd"]) for x in invalid: if vars()[x] is not None: ansible_module.fail_json( msg="Argument '%s' can not be used with state '%s'" % (x, state)) # Init changed = False exit_args = {} ccache_dir = None ccache_name = None try: if not valid_creds(ansible_module, ipaadmin_principal): ccache_dir, ccache_name = temp_kinit(ipaadmin_principal, ipaadmin_password) api_connect() commands = [] for name in names: # Make sure hostgroup exists res_find = find_sudocmdgroup(ansible_module, name) # Create command if state == "present": # Generate args args = gen_args(description, nomembers) if action == "sudocmdgroup": # Found the hostgroup if res_find is not None: # For all settings is args, check if there are # different settings in the find result. # If yes: modify if not compare_args_ipa(ansible_module, args, res_find): commands.append([name, "sudocmdgroup_mod", args]) else: commands.append([name, "sudocmdgroup_add", args]) # Set res_find to empty dict for next step res_find = {} member_args = gen_member_args(sudocmd) if not compare_args_ipa(ansible_module, member_args, res_find): # Generate addition and removal lists sudocmd_add, sudocmd_del = \ gen_add_del_lists( sudocmd, res_find.get("member_sudocmd")) # Add members if len(sudocmd_add) > 0: commands.append([ name, "sudocmdgroup_add_member", { "sudocmd": [to_text(c) for c in sudocmd_add] } ]) # Remove members if len(sudocmd_del) > 0: commands.append([ name, "sudocmdgroup_remove_member", { "sudocmd": [to_text(c) for c in sudocmd_del] } ]) elif action == "member": if res_find is None: ansible_module.fail_json(msg="No sudocmdgroup '%s'" % name) # Ensure members are present commands.append([ name, "sudocmdgroup_add_member", { "sudocmd": [to_text(c) for c in sudocmd] } ]) elif state == "absent": if action == "sudocmdgroup": if res_find is not None: commands.append([name, "sudocmdgroup_del", {}]) elif action == "member": if res_find is None: ansible_module.fail_json(msg="No sudocmdgroup '%s'" % name) # Ensure members are absent commands.append([ name, "sudocmdgroup_remove_member", { "sudocmd": [to_text(c) for c in sudocmd] } ]) else: ansible_module.fail_json(msg="Unkown state '%s'" % state) # Check mode exit if ansible_module.check_mode: ansible_module.exit_json(changed=len(commands) > 0, **exit_args) # Execute commands for name, command, args in commands: try: result = api_command(ansible_module, command, to_text(name), args) if action == "member": if "completed" in result and result["completed"] > 0: changed = True else: if command == "sudocmdgroup_del": changed |= "Deleted" in result['summary'] elif command == "sudocmdgroup_add": changed |= "Added" in result['summary'] except Exception as e: ansible_module.fail_json(msg="%s: %s: %s" % (command, name, str(e))) # Get all errors # All "already a member" and "not a member" failures in the # result are ignored. All others are reported. errors = [] if "failed" in result and "member" in result["failed"]: failed = result["failed"]["member"] for member_type in failed: for member, failure in failed[member_type]: if "already a member" not in failure \ and "not a member" not in failure: errors.append( "%s: %s %s: %s" % (command, member_type, member, failure)) if len(errors) > 0: ansible_module.fail_json(msg=", ".join(errors)) except Exception as e: ansible_module.fail_json(msg=str(e)) finally: temp_kdestroy(ccache_dir, ccache_name) # Done ansible_module.exit_json(changed=changed, **exit_args)
def main(): module = AnsibleModule( argument_spec = dict( servers=dict(required=True, type='list'), domain=dict(required=True), realm=dict(required=True), hostname=dict(required=True), basedn=dict(required=True), principal=dict(required=False), subject_base=dict(required=True), ca_enabled=dict(required=True, type='bool'), mkhomedir=dict(required=False, type='bool'), on_master=dict(required=False, type='bool'), ), supports_check_mode = True, ) module._ansible_debug = True servers = module.params.get('servers') realm = module.params.get('realm') hostname = module.params.get('hostname') basedn = module.params.get('basedn') domain = module.params.get('domain') principal = module.params.get('principal') subject_base = module.params.get('subject_base') ca_enabled = module.params.get('ca_enabled') mkhomedir = module.params.get('mkhomedir') on_master = module.params.get('on_master') fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE) statestore = sysrestore.StateFile(paths.IPA_CLIENT_SYSRESTORE) standard_logging_setup( paths.IPACLIENT_INSTALL_LOG, verbose=True, debug=False, filemode='a', console_format='%(message)s') os.environ['KRB5CCNAME'] = paths.IPA_DNS_CCACHE options.dns_updates = False options.all_ip_addresses = False options.ip_addresses = None options.request_cert = False options.hostname = hostname options.preserve_sssd = False options.on_master = False options.conf_ssh = True options.conf_sshd = True options.conf_sudo = True options.primary = False options.permit = False options.krb5_offline_passwords = False options.create_sshfp = True ########################################################################## # Create IPA NSS database try: create_ipa_nssdb() except ipautil.CalledProcessError as e: module.fail_json(msg="Failed to create IPA NSS database: %s" % e) # Get CA certificates from the certificate store try: ca_certs = get_certs_from_ldap(servers[0], basedn, realm, ca_enabled) except errors.NoCertificateError: if ca_enabled: ca_subject = DN(('CN', 'Certificate Authority'), subject_base) else: ca_subject = None ca_certs = certstore.make_compat_ca_certs(ca_certs, realm, ca_subject) ca_certs_trust = [(c, n, certstore.key_policy_to_trust_flags(t, True, u)) for (c, n, t, u) in ca_certs] if hasattr(paths, "KDC_CA_BUNDLE_PEM"): x509.write_certificate_list( [c for c, n, t, u in ca_certs if t is not False], paths.KDC_CA_BUNDLE_PEM) if hasattr(paths, "CA_BUNDLE_PEM"): x509.write_certificate_list( [c for c, n, t, u in ca_certs if t is not False], paths.CA_BUNDLE_PEM) # Add the CA certificates to the IPA NSS database module.debug("Adding CA certificates to the IPA NSS database.") ipa_db = certdb.NSSDatabase(paths.IPA_NSSDB_DIR) for cert, nickname, trust_flags in ca_certs_trust: try: ipa_db.add_cert(cert, nickname, trust_flags) except CalledProcessError as e: module.fail_json(msg="Failed to add %s to the IPA NSS database." % nickname) # Add the CA certificates to the platform-dependant systemwide CA store tasks.insert_ca_certs_into_systemwide_ca_store(ca_certs) if not on_master: client_dns(servers[0], hostname, options) configure_certmonger(fstore, subject_base, realm, hostname, options, ca_enabled) if hasattr(paths, "SSH_CONFIG_DIR"): ssh_config_dir = paths.SSH_CONFIG_DIR else: ssh_config_dir = services.knownservices.sshd.get_config_dir() update_ssh_keys(hostname, ssh_config_dir, options.create_sshfp) try: os.remove(paths.IPA_DNS_CCACHE) except Exception: pass ########################################################################## # Name Server Caching Daemon. Disable for SSSD, use otherwise # (if installed) nscd = services.knownservices.nscd if nscd.is_installed(): if NUM_VERSION < 40500: save_state(nscd) else: save_state(nscd, statestore) try: nscd_service_action = 'stop' nscd.stop() except Exception: module.warn("Failed to %s the %s daemon" % (nscd_service_action, nscd.service_name)) try: nscd.disable() except Exception: module.warn("Failed to disable %s daemon. Disable it manually." % nscd.service_name) nslcd = services.knownservices.nslcd if nslcd.is_installed(): if NUM_VERSION < 40500: save_state(nslcd) else: save_state(nslcd, statestore) ########################################################################## # Modify nsswitch/pam stack tasks.modify_nsswitch_pam_stack(sssd=True, mkhomedir=mkhomedir, statestore=statestore) module.log("SSSD enabled") argspec = inspect.getargspec(services.service) if len(argspec.args) > 1: sssd = services.service('sssd', api) else: sssd = services.service('sssd') try: sssd.restart() except CalledProcessError: module.warn("SSSD service restart was unsuccessful.") try: sssd.enable() except CalledProcessError as e: module.warn( "Failed to enable automatic startup of the SSSD daemon: " "%s", e) if configure_openldap_conf(fstore, basedn, servers): module.log("Configured /etc/openldap/ldap.conf") else: module.log("Failed to configure /etc/openldap/ldap.conf") # Check that nss is working properly if not on_master: user = principal if user is None or user == "": user = "******" % domain module.log("Principal is not set when enrolling with OTP" "; using principal '%s' for 'getent passwd'" % user) elif '@' not in user: user = "******" % (user, domain) n = 0 found = False # Loop for up to 10 seconds to see if nss is working properly. # It can sometimes take a few seconds to connect to the remote # provider. # Particulary, SSSD might take longer than 6-8 seconds. while n < 10 and not found: try: ipautil.run([paths.GETENT if hasattr(paths, "GETENT") else "getent", "passwd", user]) found = True except Exception as e: time.sleep(1) n = n + 1 if not found: module.fail_json(msg="Unable to find '%s' user with 'getent " "passwd %s'!" % (user.split("@")[0], user)) if conf: module.log("Recognized configuration: %s" % conf) else: module.fail_json(msg= "Unable to reliably detect " "configuration. Check NSS setup manually.") try: hardcode_ldap_server(servers) except Exception as e: module.fail_json(msg="Adding hardcoded server name to " "/etc/ldap.conf failed: %s" % str(e)) ########################################################################## module.exit_json(changed=True, ca_enabled_ra=ca_enabled)