mirror of
https://github.com/freeipa/ansible-freeipa.git
synced 2026-06-10 10:45:55 +00:00
ansible-test with ansible-2.14 is adding a lot of new tests to ensure that the documentation section and the agument spec is complete. Needed changes: A copyright header needs to be present. DOCUMENTATION section - `author` needs to be given with the github user also: `Name (@user)` Example section needs to be present, even if empty. RETURN section needs to be present if parameters are returned.
283 lines
7.7 KiB
Python
283 lines
7.7 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
# Authors:
|
|
# Thomas Woerner <twoerner@redhat.com>
|
|
#
|
|
# Based on ipa-client-install code
|
|
#
|
|
# Copyright (C) 2018-2022 Red Hat
|
|
# see file 'COPYING' for use and warranty information
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
from __future__ import (absolute_import, division, print_function)
|
|
|
|
__metaclass__ = type
|
|
|
|
DOCUMENTATION = """
|
|
---
|
|
module: ipaclient_get_facts
|
|
short_description: Get facts about IPA client and server configuration.
|
|
description: Get facts about IPA client and server configuration.
|
|
author:
|
|
- Thomas Woerner (@t-woerner)
|
|
"""
|
|
|
|
EXAMPLES = """
|
|
"""
|
|
|
|
RETURN = """
|
|
ipa:
|
|
description: IPA configuration
|
|
returned: always
|
|
type: complex
|
|
contains:
|
|
packages:
|
|
description: IPA lib and server bindings
|
|
type: dict
|
|
returned: always
|
|
contains:
|
|
ipalib:
|
|
description: Whether ipalib.api binding could be imported.
|
|
type: bool
|
|
returned: always
|
|
ipaserver:
|
|
description: Whether ipaserver binding could be imported.
|
|
type: bool
|
|
returned: always
|
|
configured:
|
|
description: IPA components
|
|
type: dict
|
|
returned: always
|
|
contains:
|
|
client:
|
|
description: Whether client is configured
|
|
type: bool
|
|
returned: always
|
|
server:
|
|
description: Whether server is configured
|
|
type: bool
|
|
returned: always
|
|
dns:
|
|
description: Whether dns is configured
|
|
type: bool
|
|
returned: always
|
|
ca:
|
|
description: Whether ca is configured
|
|
type: bool
|
|
returned: always
|
|
kra:
|
|
description: Whether kra is configured
|
|
type: bool
|
|
returned: always
|
|
ntpd:
|
|
description: Whether ntpd is configured
|
|
type: bool
|
|
returned: always
|
|
"""
|
|
|
|
import os
|
|
import re
|
|
from ansible.module_utils import six
|
|
try:
|
|
from ansible.module_utils.six.moves.configparser import RawConfigParser
|
|
except ImportError:
|
|
from ConfigParser import RawConfigParser
|
|
|
|
from ansible.module_utils.basic import AnsibleModule
|
|
|
|
# pylint: disable=unused-import
|
|
try:
|
|
from ipalib import api # noqa: F401
|
|
except ImportError:
|
|
HAS_IPALIB = False
|
|
else:
|
|
HAS_IPALIB = True
|
|
from ipaplatform.paths import paths
|
|
try:
|
|
# FreeIPA >= 4.5
|
|
from ipalib.install import sysrestore
|
|
except ImportError:
|
|
# FreeIPA 4.4 and older
|
|
from ipapython import sysrestore
|
|
|
|
try:
|
|
import ipaserver # noqa: F401
|
|
except ImportError:
|
|
HAS_IPASERVER = False
|
|
else:
|
|
HAS_IPASERVER = True
|
|
|
|
SERVER_SYSRESTORE_STATE = "/var/lib/ipa/sysrestore/sysrestore.state"
|
|
NAMED_CONF = "/etc/named.conf"
|
|
VAR_LIB_PKI_TOMCAT = "/var/lib/pki/pki-tomcat"
|
|
|
|
|
|
def is_ntpd_configured():
|
|
# ntpd is configured when sysrestore.state contains the line
|
|
# [ntpd]
|
|
ntpd_conf_section = re.compile(r'^\s*\[ntpd\]\s*$')
|
|
|
|
try:
|
|
# pylint: disable=invalid-name
|
|
with open(SERVER_SYSRESTORE_STATE) as f:
|
|
for line in f.readlines():
|
|
if ntpd_conf_section.match(line):
|
|
return True
|
|
# pylint: enable=invalid-name
|
|
return False
|
|
except IOError:
|
|
return False
|
|
|
|
|
|
def is_dns_configured():
|
|
# dns is configured when /etc/named.conf contains the line
|
|
# dyndb "ipa" "/usr/lib64/bind/ldap.so" {
|
|
bind_conf_section = re.compile(r'^\s*dyndb\s+"ipa"\s+"[^"]+"\s+{$')
|
|
|
|
try:
|
|
with open(NAMED_CONF) as f: # pylint: disable=invalid-name
|
|
for line in f.readlines():
|
|
if bind_conf_section.match(line):
|
|
return True
|
|
return False
|
|
except IOError:
|
|
return False
|
|
|
|
|
|
def is_dogtag_configured(subsystem):
|
|
# ca / kra is configured when the directory
|
|
# /var/lib/pki/pki-tomcat/[ca|kra] # exists
|
|
available_subsystems = {'ca', 'kra'}
|
|
if subsystem not in available_subsystems:
|
|
raise AssertionError("Subsystem '%s' not available" % subsystem)
|
|
|
|
return os.path.isdir(os.path.join(VAR_LIB_PKI_TOMCAT, subsystem))
|
|
|
|
|
|
def is_ca_configured():
|
|
return is_dogtag_configured('ca')
|
|
|
|
|
|
def is_kra_configured():
|
|
return is_dogtag_configured('kra')
|
|
|
|
|
|
def is_client_configured():
|
|
# IPA Client is configured when /etc/ipa/default.conf exists
|
|
# and /var/lib/ipa-client/sysrestore/sysrestore.state exists
|
|
|
|
fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
|
|
return os.path.isfile(paths.IPA_DEFAULT_CONF) and fstore.has_files()
|
|
|
|
|
|
def is_server_configured():
|
|
# IPA server is configured when /etc/ipa/default.conf exists
|
|
# and /var/lib/ipa/sysrestore/sysrestore.state exists
|
|
return (os.path.isfile(paths.IPA_DEFAULT_CONF) and
|
|
os.path.isfile(SERVER_SYSRESTORE_STATE))
|
|
|
|
|
|
def get_ipa_conf():
|
|
# Extract basedn, realm and domain from /etc/ipa/default.conf
|
|
parser = RawConfigParser()
|
|
parser.read(paths.IPA_DEFAULT_CONF)
|
|
basedn = parser.get('global', 'basedn')
|
|
realm = parser.get('global', 'realm')
|
|
domain = parser.get('global', 'domain')
|
|
return dict(
|
|
basedn=basedn,
|
|
realm=realm,
|
|
domain=domain
|
|
)
|
|
|
|
|
|
def get_ipa_version():
|
|
try:
|
|
# pylint: disable=import-outside-toplevel
|
|
from ipapython import version
|
|
# pylint: enable=import-outside-toplevel
|
|
except ImportError:
|
|
return None
|
|
else:
|
|
version_info = []
|
|
for part in version.VERSION.split('.'):
|
|
# DEV versions look like:
|
|
# 4.4.90.201610191151GITd852c00
|
|
# 4.4.90.dev201701071308+git2e43db1
|
|
# 4.6.90.pre2
|
|
if part.startswith('dev') or part.startswith('pre') or \
|
|
'GIT' in part:
|
|
version_info.append(part)
|
|
else:
|
|
version_info.append(int(part))
|
|
|
|
return dict(
|
|
api_version=version.API_VERSION,
|
|
num_version=version.NUM_VERSION,
|
|
vendor_version=version.VENDOR_VERSION,
|
|
version=version.VERSION,
|
|
version_info=version_info
|
|
)
|
|
|
|
|
|
def main():
|
|
module = AnsibleModule(
|
|
argument_spec={},
|
|
supports_check_mode=True
|
|
)
|
|
|
|
# The module does not change anything, meaning that
|
|
# check mode is supported
|
|
|
|
facts = dict(
|
|
packages=dict(
|
|
ipalib=HAS_IPALIB,
|
|
ipaserver=HAS_IPASERVER,
|
|
),
|
|
configured=dict(
|
|
client=False,
|
|
server=False,
|
|
dns=False,
|
|
ca=False,
|
|
kra=False,
|
|
ntpd=False
|
|
)
|
|
)
|
|
|
|
if HAS_IPALIB:
|
|
if is_client_configured():
|
|
facts['configured']['client'] = True
|
|
|
|
facts['version'] = get_ipa_version()
|
|
for key, value in six.iteritems(get_ipa_conf()):
|
|
facts[key] = value
|
|
|
|
if HAS_IPASERVER:
|
|
if is_server_configured():
|
|
facts['configured']['server'] = True
|
|
facts['configured']['dns'] = is_dns_configured()
|
|
facts['configured']['ca'] = is_ca_configured()
|
|
facts['configured']['kra'] = is_kra_configured()
|
|
facts['configured']['ntpd'] = is_ntpd_configured()
|
|
|
|
module.exit_json(
|
|
changed=False,
|
|
ansible_facts=dict(ipa=facts)
|
|
)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|