Compare commits

...

22 Commits

Author SHA1 Message Date
Rafael Guterres Jeffman
9195494f37 Merge pull request #1243 from t-woerner/ipareplica_ip_addresses_use_for_client
ipareplica: Pass ipareplica_ip_addresses to client deployment part
2024-12-12 10:00:09 -03:00
Thomas Woerner
81abf6889b ipareplica: Pass ipareplica_ip_addresses to client deployment part
The IP addresses set with ipareplica_ip_addresses have not been passed
to ipaclient role for client deployment part. This resulted in not
setting the IP addresses.

The description for ipareplica_ip_addresses in the ipareplica README and
also the role modules was wrong and have been fixed to "List of IPA
replica IP addresses".

Related: https://pagure.io/freeipa/issue/7405

Resolves: https://github.com/freeipa/ansible-freeipa/issues/1244
2024-12-12 12:10:56 +01:00
Thomas Woerner
81906edec6 Merge pull request #1322 from rjeffman/rhel70023
ipagroup: Correctly handle externalmember in member actions
2024-12-12 12:02:37 +01:00
Thomas Woerner
5071653db3 Merge pull request #1321 from rjeffman/rhel-68439
ipasudorule: Evaluate all members related to hosts and users
2024-12-12 11:27:01 +01:00
Rafael Guterres Jeffman
df4ec30a51 ipasudorule: Evaluate all members related to hosts and users
When handling users and hosts is ipasudorule we were missing nome entry
attributes returned from FreeIPA, which would cause the add/del lists to
be incorrectly generated.

By adding the proper lists, both attributes are handled correctly.

A new test to verify the fix is added:

    tests/sudorule/test_sudorule_user_host_external.yml

Fixes https://issues.redhat.com/browse/RHEL-68439
2024-12-11 10:56:11 -03:00
Thomas Woerner
73160a037b Merge pull request #1323 from rjeffman/rhel70021
ipacert: Revoking with  removeFromCRL should be handled as cert release
2024-12-11 14:54:59 +01:00
Rafael Guterres Jeffman
b7ed9ecfd5 Merge pull request #1324 from t-woerner/no_role_plugin_duplicates
utils/build-galaxy-release.sh: Do not create duplicates for role plugins
2024-12-11 10:29:07 -03:00
Thomas Woerner
a4f608854d ansible_ipa_server.py: Calm down ansible-test "metaclass-boilerplate"
ansible-test sanity test "metaclass-boilerplate" fails now to recognize
the line "__metaclass__ = type" if there is a pylint disable comment
appended to the same line to not fail on using bad class naming.

The pylint disable comment has been moved to an extra preceding line and
an additional enable commend has been added after the metaclass line.
2024-12-11 14:19:09 +01:00
Thomas Woerner
8e6c5e566d utils/build-galaxy-release.sh: Do not create duplicates for role plugins
This change reduces the size of the Ansible collection and removes unused
files.

While creating the collection, the role plugins have been linked into the
global plugin folders, but a subsequent sed call replaced the links with
changed files. The original files have also been changed with another sed
call in the same way. This resulted in the duplication of the changed
files.

The plugins of the roles are now moved into the global plugin folders and
only changed there. The now empty plugin folders in the roles are
removed.
2024-12-10 17:12:09 +01:00
Rafael Guterres Jeffman
431dc8667a ipagroup: Correctly handle externalmember in member actions
When creating the lists of external members, the attribute
'ipaexternalmember' also needs to be added to the list of external
members that are part of the group object for external groups.

A test to verify the correct behavior was added and the test suite for
group external members have been cleaned up with 'yes' values changed to
'true' and the use of module_defaults.
2024-12-10 08:25:49 -03:00
Rafael Guterres Jeffman
bc16ccaef7 ipacert: Revoking with removeFromCRL should be handled as cert release
When a revoked certificate with reason 6 (certificateHold) is revoked
with reason 8 (removeFromCRL), the effect is that the certificate is
valid again, as it is the same procedure as 'state: release'.

This is, at least, the behavior with IPA CLI comands, which is
implemented by this patch.

A new test is added to verify this behavior:

    tests/cert/test_cert_remove_hold_with_removeFromCRL.yml
2024-12-05 15:42:58 -03:00
Thomas Woerner
227c95e62e Merge pull request #1319 from rjeffman/fix_show_broad_exception
modules: Do not hide errors using IPA *_show command with Exception
2024-12-03 15:09:14 +01:00
Rafael Guterres Jeffman
5abb515c92 utils/templates: Use ipalib_errors.NotFound instead of Exception
Modify the plugin templates so that the code generated does not hide
errors when querying IPA wih *_show command by handlig only the exeption
where an object is not found.
2024-12-02 23:27:56 -03:00
Rafael Guterres Jeffman
1c4b50fa51 modules: Do not hide errors using IPA *_show command with Exception
When searching for objects with *_show IPA API command, most plugins
were hiding errors other than "ipalib_errors.NotFound" by handling the
broad exception Exception instead.

This patch uses "ipalib_errors.NotFound" whenever "*_show" is used so
that the only exception handled is when an object is not found. Other
errors will not be handled making the module break as expected.
2024-12-02 22:58:51 -03:00
Rafael Guterres Jeffman
8fc2de1673 Merge pull request #1318 from t-woerner/testing_container_create_enable_cap_sys_admin
infra/image: Use SYS_ADMIN capability for server deployment
2024-12-02 14:41:35 -03:00
Thomas Woerner
8d74fe34ef Enable c10s testing for PRs and nightly and after merge testing 2024-12-02 15:38:39 +01:00
Thomas Woerner
87ad46f7a4 Enable to build c10s test container image 2024-12-02 15:11:48 +01:00
Thomas Woerner
4c3f4e6f7d infra/image: Use SYS_ADMIN capability for server deployment
This adds the capabilities SYS_ADMIN and SYSLOG to the container_create
call in build.sh as long as server deployment has been enabled.

The privileged option has been removed as it is no longer needed.

The hostnamectl-wrapper for the container has been removed as it is no
longer needed.
2024-12-02 15:06:44 +01:00
Rafael Guterres Jeffman
489f4d5784 Merge pull request #1316 from t-woerner/c10s_niddomainname
infra/image/dockerfile/c10s: Fix client part deployment for the server
2024-11-29 08:39:21 -03:00
Rafael Guterres Jeffman
29fc03c625 Merge pull request #1315 from t-woerner/container_copy_fetch
infra/image/shcontainer: New container_copy and container_fetch
2024-11-28 11:02:44 -03:00
Thomas Woerner
2dc1deeb87 infra/image/dockerfile/c10s: Fix client part deployment for the server
The client part deployment fails in the configuration of NIS. The command
/usr/bin/nisdomainname is failing in a container in this task as the
container is not privileged.

The hostnamectl-wrapper is copied from the freeipa-container container
project to replace /usr/bin/nisdomainname in the container.
2024-11-19 15:54:03 +01:00
Thomas Woerner
82a53b9ae4 infra/image/shcontainer: New container_copy and container_fetch
container_copy can be used to copy a file to the container,
container_fetch can be used to copy a file from the container.

For more information, please have a look at the podman-cp man page.
2024-11-19 15:08:46 +01:00
43 changed files with 391 additions and 112 deletions

View File

@@ -9,7 +9,7 @@ variables:
ansible_version: "-core >=2.16,<2.17"
ansible_latest: "-core"
ansible_minimum: "-core <2.16"
distros: "fedora-latest,c9s,fedora-rawhide"
distros: "fedora-latest,c9s,c10s,fedora-rawhide"
stages:

View File

@@ -12,7 +12,7 @@ trigger: none
pool:
vmImage: 'ubuntu-24.04'
variables: { distros: "fedora-latest,fedora-rawhide,c9s" }
variables: { distros: "fedora-latest,fedora-rawhide,c9s,c10s" }
stages:

View File

@@ -14,8 +14,8 @@ pool:
variables:
# We need to have two sets, as c8s is not supported by all ansible versions
recent_distros: "fedora-latest,fedora-rawhide,c9s"
distros: "fedora-latest,fedora-rawhide,c9s,c8s"
recent_distros: "fedora-latest,fedora-rawhide,c10s,c9s"
distros: "fedora-latest,fedora-rawhide,c10s,c9s,c8s"
ansible_latest: "-core"
ansible_minimum: "-core <2.16"
ansible_version: "-core >=2.16,<2.17"

View File

@@ -6,7 +6,7 @@ pool:
vmImage: 'ubuntu-20.04'
variables:
distros: "fedora-latest,c9s,c8s,fedora-rawhide"
distros: "fedora-latest,c10s,c9s,c8s,fedora-rawhide"
ansible_version: "-core >=2.15,<2.16"
stages:

View File

@@ -23,7 +23,7 @@ jobs:
- script: ansible-galaxy collection install containers.podman
displayName: Install Ansible Galaxy collections
- script: infra/image/build.sh -p -s ${{ parameters.distro }}
- script: infra/image/build.sh -s ${{ parameters.distro }}
displayName: Build ${{ parameters.distro }} base image
env:
ANSIBLE_ROLES_PATH: "${PWD}/roles"

View File

@@ -0,0 +1,21 @@
#
# Variables must be defined as comma separated lists.
# For easier management of items to enable/disable,
# use one test/module on each line, followed by a comma.
#
# Example:
#
# ipa_disabled_modules: >-
# dnsconfig,
# group,
# hostgroup
#
# If no variables are set, set "empty: true" as at least
# one item is needed in the set.
---
variables:
empty: true
# ipa_enabled_modules: >-
# ipa_enabled_tests: >-
# ipa_disabled_modules: >-
# ipa_disabled_tests: >-

View File

@@ -15,7 +15,7 @@ valid_distro() {
usage() {
local prog="${0##*/}"
cat << EOF
usage: ${prog} [-h] [-p] [-n HOSTNAME] [-s] distro
usage: ${prog} [-h] [-n HOSTNAME] [-s] distro
${prog} build a container image to test ansible-freeipa.
EOF
}
@@ -41,14 +41,14 @@ cpus="2"
memory="3g"
quayname="quay.io/ansible-freeipa/upstream-tests"
deploy_server="N"
privileged=""
deploy_capabilities="SYS_ADMIN,SYSLOG"
capabilities=""
while getopts ":hn:ps" option
while getopts ":hn:s" option
do
case "${option}" in
h) help && exit 0 ;;
n) hostname="${OPTARG}" ;;
p) privileged="privileged" ;;
s) deploy_server="Y" ;;
*) die -u "Invalid option: ${option}" ;;
esac
@@ -66,6 +66,8 @@ container_check
if [ "${deploy_server}" == "Y" ]
then
capabilities="${deploy_capabilities}"
[ -n "$(command -v "ansible-playbook")" ] || die "ansible-playbook is required to install FreeIPA."
deploy_playbook="${TOPDIR}/playbooks/install-server.yml"
@@ -89,7 +91,7 @@ container_create "${name}" "${tag}" \
"hostname=${hostname}" \
"memory=${memory}" \
"cpus=${cpus}" \
"${privileged}"
"${capabilities:+capabilities=$capabilities}"
container_commit "${name}" "${quayname}:${tag}"
if [ "${deploy_server}" == "Y" ]

View File

@@ -9,7 +9,8 @@ dnf --assumeyes install \
bash \
systemd \
procps-ng \
iproute; \
iproute \
hostname; \
rm -rf /var/cache/dnf/;
RUN (cd /lib/systemd/system/; \

View File

@@ -18,7 +18,7 @@ container_create() {
hostname=*) extra_opts+=("--${opt}") ;;
cpus=*) extra_opts+=("--${opt}") ;;
memory=*) extra_opts+=("--${opt}") ;;
privileged) extra_opts+=("--${opt}") ;;
capabilities=*) extra_opts+=("--cap-add=${opt##*=}") ;;
*) log error "container_create: Invalid option: ${opt}" ;;
esac
done
@@ -175,3 +175,23 @@ container_image_list() {
container_check() {
[ -n "$(command -v "podman")" ] || die "podman is required."
}
container_copy() {
local name="${1}"
local source="${2}"
local destination="${3}"
log info "= Copying ${source} to ${name}:${destination} ="
podman cp "${source}" "${name}:${destination}"
echo
}
container_fetch() {
local name="${1}"
local source="${2}"
local destination="${3}"
log info "= Copying ${name}:${source} to ${destination} ="
podman cp "${name}:${source}" "${destination}"
echo
}

View File

@@ -106,7 +106,7 @@ RETURN = '''
'''
from ansible.module_utils.ansible_freeipa_module import (
IPAAnsibleModule, compare_args_ipa
IPAAnsibleModule, compare_args_ipa, ipalib_errors
)
@@ -124,7 +124,7 @@ class AutomountMap(IPAAnsibleModule):
location,
{"automountmapname": name, "all": True}
)
except Exception: # pylint: disable=broad-except
except ipalib_errors.NotFound:
return None
return response["result"]
@@ -132,7 +132,7 @@ class AutomountMap(IPAAnsibleModule):
"""Check if 'name' is an indirect map for 'parentmap'."""
try:
maps = self.ipa_command("automountmap_find", location, {})
except Exception: # pylint: disable=broad-except
except ipalib_errors.NotFound:
return []
result = []

View File

@@ -487,6 +487,8 @@ def main():
# revoked
reason = ansible_module.params_get("revocation_reason")
if reason is not None:
reason = get_revocation_reason(ansible_module, reason)
# general
serial_number = ansible_module.params.get("serial_number")
@@ -521,6 +523,9 @@ def main():
invalid.append("revocation_reason")
if state == "revoked":
invalid.extend(["certificate_out", "chain"])
# Reason 8 (revomeFromCRL) is the same as release hold
if reason == 8:
state = "released"
elif state == "held":
reason = 6 # certificateHold

View File

@@ -356,7 +356,7 @@ def config_show(module):
def get_netbios_name(module):
try:
_result = module.ipa_command_no_name("trustconfig_show", {"all": True})
except Exception: # pylint: disable=broad-except
except ipalib_errors.NotFound:
return None
return _result["result"]["ipantflatname"][0]

View File

@@ -124,14 +124,14 @@ RETURN = """
from ansible.module_utils.ansible_freeipa_module import \
IPAAnsibleModule, compare_args_ipa
IPAAnsibleModule, compare_args_ipa, ipalib_errors
def find_delegation(module, name):
"""Find if a delegation with the given name already exist."""
try:
_result = module.ipa_command("delegation_show", name, {"all": True})
except Exception: # pylint: disable=broad-except
except ipalib_errors.NotFound:
# An exception is raised if delegation name is not found.
return None
return _result["result"]

View File

@@ -746,7 +746,11 @@ def main():
(externalmember_add,
externalmember_del) = gen_add_del_lists(
externalmember, res_find.get("member_external"))
externalmember, (
list(res_find.get("member_external", []))
+ list(res_find.get("ipaexternalmember", []))
)
)
(idoverrides_add,
idoverrides_del) = gen_add_del_lists(
@@ -780,7 +784,11 @@ def main():
service_add = gen_add_list(
service, res_find.get("member_service"))
externalmember_add = gen_add_list(
externalmember, res_find.get("member_external"))
externalmember, (
list(res_find.get("member_external", []))
+ list(res_find.get("ipaexternalmember", []))
)
)
idoverrides_add = gen_add_list(
idoverrideuser, res_find.get("member_idoverrideuser"))
@@ -815,7 +823,11 @@ def main():
service_del = gen_intersection_list(
service, res_find.get("member_service"))
externalmember_del = gen_intersection_list(
externalmember, res_find.get("member_external"))
externalmember, (
list(res_find.get("member_external", []))
+ list(res_find.get("ipaexternalmember", []))
)
)
idoverrides_del = gen_intersection_list(
idoverrideuser, res_find.get("member_idoverrideuser"))

View File

@@ -155,7 +155,7 @@ RETURN = """
from ansible.module_utils.ansible_freeipa_module import \
IPAAnsibleModule, compare_args_ipa
IPAAnsibleModule, compare_args_ipa, ipalib_errors
from ansible.module_utils import six
if six.PY3:
@@ -168,7 +168,7 @@ def find_idoverridegroup(module, idview, anchor):
_result = module.ipa_command("idoverridegroup_show", idview,
{"ipaanchoruuid": anchor,
"all": True})
except Exception: # pylint: disable=broad-except
except ipalib_errors.NotFound:
# An exception is raised if idoverridegroup anchor is not found.
return None
return _result["result"]

View File

@@ -315,7 +315,8 @@ RETURN = """
from ansible.module_utils.ansible_freeipa_module import \
IPAAnsibleModule, compare_args_ipa, gen_add_del_lists, gen_add_list, \
gen_intersection_list, encode_certificate, convert_input_certificates
gen_intersection_list, encode_certificate, convert_input_certificates, \
ipalib_errors
from ansible.module_utils import six
if six.PY3:
@@ -328,7 +329,7 @@ def find_idoverrideuser(module, idview, anchor):
_result = module.ipa_command("idoverrideuser_show", idview,
{"ipaanchoruuid": anchor,
"all": True})
except Exception: # pylint: disable=broad-except
except ipalib_errors.NotFound:
# An exception is raised if idoverrideuser anchor is not found.
return None

View File

@@ -184,7 +184,8 @@ RETURN = """
from ansible.module_utils.ansible_freeipa_module import \
IPAAnsibleModule, compare_args_ipa, template_str, urlparse
IPAAnsibleModule, compare_args_ipa, template_str, urlparse, \
ipalib_errors
from ansible.module_utils import six
from copy import deepcopy
import string
@@ -269,7 +270,7 @@ def find_idp(module, name):
"""Find if a idp with the given name already exist."""
try:
_result = module.ipa_command("idp_show", name, {"all": True})
except Exception: # pylint: disable=broad-except
except ipalib_errors.NotFound:
# An exception is raised if idp name is not found.
return None

View File

@@ -143,7 +143,8 @@ RETURN = """
from ansible.module_utils.ansible_freeipa_module import \
IPAAnsibleModule, compare_args_ipa, get_trusted_domain_sid_from_name
IPAAnsibleModule, compare_args_ipa, get_trusted_domain_sid_from_name, \
ipalib_errors
from ansible.module_utils import six
if six.PY3:
@@ -154,7 +155,7 @@ def find_idrange(module, name):
"""Find if a idrange with the given name already exist."""
try:
_result = module.ipa_command("idrange_show", name, {"all": True})
except Exception: # pylint: disable=broad-except
except ipalib_errors.NotFound:
# An exception is raised if idrange name is not found.
return None
return _result["result"]

View File

@@ -138,7 +138,7 @@ def find_idview(module, name):
"""Find if a idview with the given name already exist."""
try:
_result = module.ipa_command("idview_show", name, {"all": True})
except Exception: # pylint: disable=broad-except
except ipalib_errors.NotFound:
# An exception is raised if idview name is not found.
return None
return _result["result"]

View File

@@ -76,14 +76,14 @@ RETURN = """
from ansible.module_utils.ansible_freeipa_module import \
IPAAnsibleModule, compare_args_ipa
IPAAnsibleModule, compare_args_ipa, ipalib_errors
def find_location(module, name):
"""Find if a location with the given name already exist."""
try:
_result = module.ipa_command("location_show", name, {"all": True})
except Exception: # pylint: disable=broad-except
except ipalib_errors.NotFound:
# An exception is raised if location name is not found.
return None
return _result["result"]

View File

@@ -154,14 +154,14 @@ RETURN = """
from ansible.module_utils.ansible_freeipa_module import \
IPAAnsibleModule, compare_args_ipa, to_text
IPAAnsibleModule, compare_args_ipa, to_text, ipalib_errors
def find_permission(module, name):
"""Find if a permission with the given name already exist."""
try:
_result = module.ipa_command("permission_show", name, {"all": True})
except Exception: # pylint: disable=broad-except
except ipalib_errors.NotFound:
# An exception is raised if permission name is not found.
return None
_res = _result["result"]

View File

@@ -124,7 +124,7 @@ RETURN = """
from ansible.module_utils.ansible_freeipa_module import \
IPAAnsibleModule, compare_args_ipa, gen_add_del_lists, gen_add_list, \
gen_intersection_list
gen_intersection_list, ipalib_errors
from ansible.module_utils import six
if six.PY3:
@@ -135,7 +135,7 @@ def find_privilege(module, name):
"""Find if a privilege with the given name already exist."""
try:
_result = module.ipa_command("privilege_show", name, {"all": True})
except Exception: # pylint: disable=broad-except
except ipalib_errors.NotFound:
# An exception is raised if privilege name is not found.
return None
return _result["result"]

View File

@@ -129,7 +129,7 @@ EXAMPLES = """
from ansible.module_utils._text import to_text
from ansible.module_utils.ansible_freeipa_module import \
IPAAnsibleModule, gen_add_del_lists, compare_args_ipa, \
gen_intersection_list, ensure_fqdn
gen_intersection_list, ensure_fqdn, ipalib_errors
from ansible.module_utils import six
if six.PY3:
@@ -140,7 +140,7 @@ def find_role(module, name):
"""Find if a role with the given name already exist."""
try:
_result = module.ipa_command("role_show", name, {"all": True})
except Exception: # pylint: disable=broad-except
except ipalib_errors.NotFound:
# An exception is raised if role name is not found.
return None
return _result["result"]

View File

@@ -113,14 +113,14 @@ RETURN = """
from ansible.module_utils.ansible_freeipa_module import \
IPAAnsibleModule, compare_args_ipa
IPAAnsibleModule, compare_args_ipa, ipalib_errors
def find_selfservice(module, name):
"""Find if a selfservice with the given name already exist."""
try:
_result = module.ipa_command("selfservice_show", name, {"all": True})
except Exception: # pylint: disable=broad-except
except ipalib_errors.NotFound:
# An exception is raised if selfservice name is not found.
return None
return _result["result"]

View File

@@ -192,14 +192,14 @@ RETURN = """
from ansible.module_utils.ansible_freeipa_module import \
IPAAnsibleModule, compare_args_ipa, DNSName
IPAAnsibleModule, compare_args_ipa, DNSName, ipalib_errors
def find_server(module, name):
"""Find if a server with the given name already exist."""
try:
_result = module.ipa_command("server_show", name, {"all": True})
except Exception: # pylint: disable=broad-except
except ipalib_errors.NotFound:
# An exception is raised if server name is not found.
return None
return _result["result"]
@@ -214,7 +214,7 @@ def server_role_status(module, name):
"include_master": True,
"raw": True,
"all": True})
except Exception: # pylint: disable=broad-except
except ipalib_errors.NotFound:
# An exception is raised if server name is not found.
return None
return _result["result"][0]

View File

@@ -142,7 +142,7 @@ def find_servicedelegationrule(module, name):
try:
_result = module.ipa_command("servicedelegationrule_show", name,
{"all": True})
except Exception: # pylint: disable=broad-except
except ipalib_errors.NotFound:
# An exception is raised if servicedelegationrule name is not found.
return None
return _result["result"]

View File

@@ -106,7 +106,7 @@ RETURN = """
from ansible.module_utils.ansible_freeipa_module import \
IPAAnsibleModule, gen_add_del_lists, gen_add_list, gen_intersection_list, \
servicedelegation_normalize_principals
servicedelegation_normalize_principals, ipalib_errors
from ansible.module_utils import six
if six.PY3:
@@ -118,7 +118,7 @@ def find_servicedelegationtarget(module, name):
try:
_result = module.ipa_command("servicedelegationtarget_show", name,
{"all": True})
except Exception: # pylint: disable=broad-except
except ipalib_errors.NotFound:
# An exception is raised if servicedelegationtarget name is not found.
return None
return _result["result"]

View File

@@ -710,7 +710,11 @@ def main():
# Generate addition and removal lists
host_add, host_del = gen_add_del_lists(
entry.host, res_find.get('memberhost_host', []))
entry.host, (
list(res_find.get('memberhost_host', []))
+ list(res_find.get('externalhost', []))
)
)
hostgroup_add, hostgroup_del = gen_add_del_lists(
entry.hostgroup,
@@ -721,7 +725,11 @@ def main():
entry.hostmask, res_find.get('hostmask', []))
user_add, user_del = gen_add_del_lists(
entry.user, res_find.get('memberuser_user', []))
entry.user, (
list(res_find.get('memberuser_user', []))
+ list(res_find.get('externaluser', []))
)
)
group_add, group_del = gen_add_del_lists(
entry.group, res_find.get('memberuser_group', []))
@@ -751,8 +759,7 @@ def main():
# the provided list against both users and external
# users list.
runasuser_add, runasuser_del = gen_add_del_lists(
entry.runasuser,
(
entry.runasuser, (
list(res_find.get('ipasudorunas_user', []))
+ list(res_find.get('ipasudorunasextuser', []))
)
@@ -785,7 +792,11 @@ def main():
# the sudorule already
if entry.host is not None:
host_add = gen_add_list(
entry.host, res_find.get("memberhost_host"))
entry.host, (
list(res_find.get("memberhost_host", []))
+ list(res_find.get("externalhost", []))
)
)
if entry.hostgroup is not None:
hostgroup_add = gen_add_list(
entry.hostgroup,
@@ -796,7 +807,11 @@ def main():
entry.hostmask, res_find.get("hostmask"))
if entry.user is not None:
user_add = gen_add_list(
entry.user, res_find.get("memberuser_user"))
entry.user, (
list(res_find.get('memberuser_user', []))
+ list(res_find.get('externaluser', []))
)
)
if entry.group is not None:
group_add = gen_add_list(
entry.group, res_find.get("memberuser_group"))
@@ -862,7 +877,11 @@ def main():
# in sudorule
if entry.host is not None:
host_del = gen_intersection_list(
entry.host, res_find.get("memberhost_host"))
entry.host, (
list(res_find.get("memberhost_host", []))
+ list(res_find.get("externalhost", []))
)
)
if entry.hostgroup is not None:
hostgroup_del = gen_intersection_list(
@@ -876,7 +895,11 @@ def main():
if entry.user is not None:
user_del = gen_intersection_list(
entry.user, res_find.get("memberuser_user"))
entry.user, (
list(res_find.get('memberuser_user', []))
+ list(res_find.get('externaluser', []))
)
)
if entry.group is not None:
group_del = gen_intersection_list(
@@ -911,8 +934,7 @@ def main():
# users list.
if entry.runasuser is not None:
runasuser_del = gen_intersection_list(
entry.runasuser,
(
entry.runasuser, (
list(res_find.get('ipasudorunas_user', []))
+ list(res_find.get('ipasudorunasextuser', []))
)

View File

@@ -190,7 +190,7 @@ Variable | Description | Required
`ipaservers` | This group with the IPA master full qualified hostnames. (list of strings) | mostly
`ipareplicas` | Group of IPA replica hostnames. (list of strings) | yes
`ipaadmin_password` | The password for the IPA admin user (string) | mostly
`ipareplica_ip_addresses` | The list of master server IP addresses. (list of strings) | no
`ipareplica_ip_addresses` | The list of IPA replica IP addresses. (list of strings) | no
`ipareplica_domain` | The primary DNS domain of an existing IPA deployment. (string) | no
`ipaserver_realm` | The Kerberos realm of an existing IPA deployment. (string) | no
`ipaserver_hostname` | Fully qualified name of the server. (string) | no

View File

@@ -47,7 +47,7 @@ options:
type: str
required: no
ip_addresses:
description: List of Master Server IP Addresses
description: List of IPA replica IP addresses
type: list
elements: str
required: no

View File

@@ -47,7 +47,7 @@ options:
type: str
required: no
ip_addresses:
description: List of Master Server IP Addresses
description: List of IPA replica IP addresses
type: list
elements: str
required: no

View File

@@ -49,7 +49,7 @@ options:
type: str
required: no
ip_addresses:
description: List of Master Server IP Addresses
description: List of IPA replica IP addresses
type: list
elements: str
required: no

View File

@@ -47,7 +47,7 @@ options:
type: str
required: no
ip_addresses:
description: List of Master Server IP Addresses
description: List of IPA replica IP addresses
type: list
elements: str
required: no

View File

@@ -47,7 +47,7 @@ options:
type: str
required: no
ip_addresses:
description: List of Master Server IP Addresses
description: List of IPA replica IP addresses
type: list
elements: str
required: no

View File

@@ -38,7 +38,7 @@ short_description: IPA replica deployment tests
description: IPA replica deployment tests
options:
ip_addresses:
description: List of Master Server IP Addresses
description: List of IPA replica IP addresses
type: list
elements: str
required: no

View File

@@ -125,6 +125,7 @@
ipaclient_realm: "{{ result_ipareplica_test.realm | default(omit) }}"
ipaclient_servers: "{{ ipareplica_servers | default(omit) }}"
ipaclient_hostname: "{{ result_ipareplica_test.hostname }}"
ipaclient_ip_addresses: "{{ ipareplica_ip_addresses | default(omit) }}"
ipaclient_install_packages: "{{ ipareplica_install_packages }}"
when: not result_ipareplica_test.client_enrolled

View File

@@ -23,7 +23,9 @@
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type # pylint: disable=invalid-name
# pylint: disable=invalid-name
__metaclass__ = type
# pylint: enable=invalid-name
__all__ = ["IPAChangeConf", "certmonger", "sysrestore", "root_logger",
"ipa_generate_password", "run", "ScriptError", "services",

View File

@@ -0,0 +1,65 @@
---
- name: Test remove certificate hold by removing it from CRL.
hosts: ipaserver
become: false
gather_facts: false
module_defaults:
ipauser:
ipaadmin_password: SomeADMINpassword
ipacert:
ipaadmin_password: SomeADMINpassword
tasks:
- name: Ensure test users are present
ipauser:
name: testuser
first: test
last: user
- name: Create user certificae CSR
ansible.builtin.shell:
cmd: |-
openssl req -newkey rsa:2048 -keyout /dev/null -nodes \
-subj /CN=testuser -reqexts IECUserRoles -config \
<(cat /etc/pki/tls/openssl.cnf; \
printf "[IECUserRoles]\n1.2.3.10.9.8=ASN1:UTF8String:Testing Cert")
args:
executable: /bin/bash
register: user_csr
- name: Request certificate with ipacert
ipacert:
csr: '{{ user_csr.stdout }}'
principal: testuser
state: requested
register: user_csr
failed_when: not user_csr.changed or user_csr.failed
- name: Revoke certifice with reason 6 (certificateHold)
ipacert:
serial_number: "{{ user_csr.certificate.serial_number }}"
revocation_reason: certificateHold
state: revoked
register: result
failed_when: not result.changed or result.failed
- name: Revoke certificate with reason 8 (removeFromCRL)
ipacert:
serial_number: "{{ user_csr.certificate.serial_number }}"
revocation_reason: removeFromCRL
state: revoked
register: result
failed_when: not result.changed or result.failed
- name: Revoke certificate with reason 8 (removeFromCRL), again
ipacert:
serial_number: "{{ user_csr.certificate.serial_number }}"
revocation_reason: removeFromCRL
state: revoked
register: result
failed_when: result.changed or result.failed
- name: Ensure test users are absent
ipauser:
name: testuser
state: absent

View File

@@ -1,37 +1,45 @@
---
- name: Find trust
hosts: ipaserver
become: true
become: false
gather_facts: false
module_defaults:
ipagroup:
ipaadmin_password: SomeADMINpassword
ipaapi_context: "{{ ipa_context | default(omit) }}"
tasks:
- name: Include tasks ../env_freeipa_facts.yml
ansible.builtin.include_tasks: ../env_freeipa_facts.yml
- name: Ensure tests groups are absent
ipagroup:
name:
- extgroup
- extgroup_members
state: absent
- name: Execute group tests if trust test environment is supported
when: trust_test_is_supported | default(false)
block:
- name: Add nonposix group.
ipagroup:
ipaadmin_password: SomeADMINpassword
name: extgroup
nonposix: yes
nonposix: true
register: result
failed_when: result.failed or not result.changed
- name: Set group to be external
ipagroup:
ipaadmin_password: SomeADMINpassword
name: extgroup
external: yes
external: true
register: result
failed_when: result.failed or not result.changed
- name: Add AD users to group
ipagroup:
ipaadmin_password: SomeADMINpassword
name: extgroup
external_member: "AD\\Domain Users"
register: result
@@ -39,7 +47,6 @@
- name: Add AD users to group, again
ipagroup:
ipaadmin_password: SomeADMINpassword
name: extgroup
external_member: "AD\\Domain Users"
register: result
@@ -47,7 +54,6 @@
- name: Remove external group
ipagroup:
ipaadmin_password: SomeADMINpassword
name: extgroup
state: absent
register: result
@@ -55,27 +61,24 @@
- name: Add nonposix, external group, with AD users.
ipagroup:
ipaadmin_password: SomeADMINpassword
name: extgroup
nonposix: yes
external: yes
nonposix: true
external: true
external_member: "AD\\Domain Users"
register: result
failed_when: result.failed or not result.changed
- name: Add nonposix, external group, with AD users, again.
ipagroup:
ipaadmin_password: SomeADMINpassword
name: extgroup
nonposix: yes
external: yes
nonposix: true
external: true
external_member: "AD\\Domain Users"
register: result
failed_when: result.failed or result.changed
- name: Remove group
ipagroup:
ipaadmin_password: SomeADMINpassword
name: extgroup
state: absent
register: result
@@ -83,32 +86,71 @@
- name: Add nonposix group.
ipagroup:
ipaadmin_password: SomeADMINpassword
name: extgroup
nonposix: yes
nonposix: true
register: result
failed_when: result.failed or not result.changed
- name: Set group to be external, and add users.
ipagroup:
ipaadmin_password: SomeADMINpassword
name: extgroup
external: yes
external: true
external_member: "AD\\Domain Users"
register: result
failed_when: result.failed or not result.changed
- name: Set group to be external, and add users, again.
ipagroup:
ipaadmin_password: SomeADMINpassword
name: extgroup
external: yes
external: true
external_member: "AD\\Domain Users"
register: result
failed_when: result.failed or result.changed
- name: Cleanup environment.
- name: Ensure external group for external member exist
ipagroup:
ipaadmin_password: SomeADMINpassword
name: extgroup
name: extgroup_members
external: true
register: result
failed_when: result.failed or not result.changed
- name: Ensure external group members are present
ipagroup:
name: extgroup_members
external_member: "AD\\Domain Users"
action: member
register: result
failed_when: result.failed or not result.changed
- name: Ensure external group members are present, again
ipagroup:
name: extgroup_members
external_member: "AD\\Domain Users"
action: member
register: result
failed_when: result.failed or result.changed
- name: Ensure external group members are absent
ipagroup:
name: extgroup_members
external_member: "AD\\Domain Users"
action: member
state: absent
register: result
failed_when: result.failed or not result.changed
- name: Ensure external group members are absent, again
ipagroup:
name: extgroup_members
external_member: "AD\\Domain Users"
action: member
state: absent
register: result
failed_when: result.failed or result.changed
- name: Ensure tests groups are absent
ipagroup:
name:
- extgroup
- extgroup_members
state: absent

View File

@@ -0,0 +1,94 @@
---
- name: Test correct handling of users and hosts lists on ipasudorule
hosts: ipaserver
become: false
gather_facts: false
module_defaults:
ipauser:
ipaadmin_password: SomeADMINpassword
ipahost:
ipaadmin_password: SomeADMINpassword
ipasudorule:
ipaadmin_password: SomeADMINpassword
tasks:
- name: Ensure test state is valid
block:
- name: Ensure users are present
ipauser:
users:
- name: user_s1
first: user
last: s1
- name: user_s2
first: user
last: s2
- name: Ensure hosts are present
ipahost:
hosts:
- name: mytesthost1.ipadomain.test
force: true
- name: mytesthost1a.ipadomain.test
force: true
- name: Ensure sudorule_5a is absent
ipasudorule:
name: sudorule_5a
state: absent
- name: Ensule sudorule_5a is present with host masks and external hosts
ipasudorule:
name: sudorule_5a
hostmask: [192.168.221.0/24, 192.168.110.0/24]
host: [mytesthost1.ipa.test, mytesthost2.ipa.test]
user: [user_s1, user_s2]
- name: Ensure that sudorule remain present after remove their members(using action member).
block:
- name: Ensure sudorules members are absent
ipasudorule:
name: sudorule_5a
hostmask: 192.168.221.0/24
user: "user_s1"
host: "mytesthost1.ipa.test"
action: member
state: absent
register: result
failed_when: not result.changed or result.failed
- name: Ensure sudorules members are absent, again
ipasudorule:
name: sudorule_5a
hostmask: 192.168.221.0/24
user: "user_s1"
host: "mytesthost1.ipa.test"
action: member
state: absent
register: result
failed_when: result.changed or result.failed
- name: Check if other sudorule members are still present.
ipasudorule:
name: sudorule_5a
hostmask: 192.168.110.0/24
user: "user_s2"
host: "mytesthost2.ipa.test"
action: member
check_mode: true
register: result
failed_when: result.changed or result.failed
# cleanup
- name: Ensure test sudorule is absent
ipasudorule:
name: sudorule_5a
state: absent
- name: Ensure test hosts are absent
ipahost:
name: [mytesthost1.ipa.test, mytesthost1a.ipa.test]
state: absent
- name: Ensure test users are absent
ipauser:
name: [user_s1, user_s2]
state: absent
...

View File

@@ -140,21 +140,18 @@ sed -i -e "s/ansible.module_utils.ansible_freeipa_module/ansible_collections.${c
python utils/create_action_group.py "meta/runtime.yml" "$collection_prefix"
(cd plugins/module_utils && {
ln -sf ../../roles/*/module_utils/*.py .
})
mv roles/*/module_utils/*.py plugins/module_utils/
rmdir roles/*/module_utils
(cd plugins/modules && {
sed -i -e "s/ansible.module_utils.ansible_ipa_/ansible_collections.${collection_prefix}.plugins.module_utils.ansible_ipa_/" ../../roles/*/library/*.py
ln -sf ../../roles/*/library/*.py .
})
sed -i -e "s/ansible.module_utils.ansible_ipa_/ansible_collections.${collection_prefix}.plugins.module_utils.ansible_ipa_/" roles/*/library/*.py
mv roles/*/library/*.py plugins/modules/
rmdir roles/*/library
# There are no action plugins anymore in the roles, therefore this section
# is commneted out.
#[ ! -x plugins/action ] && mkdir plugins/action
#(cd plugins/action && {
# ln -sf ../../roles/*/action_plugins/*.py .
#})
#mv roles/*/action_plugins/*.py plugins/action/
#rmdir roles/*/action_plugins
# Adapt inventory plugin and inventory plugin README
echo "Fixing inventory plugin and doc..."
@@ -181,19 +178,11 @@ find plugins/modules -name "*.py" -print0 |
done
echo -e "\033[AFixing examples in plugins/modules... \033[32;1mDONE\033[0m"
echo "Fixing examples in roles/*/library..."
find roles/*/library -name "*.py" -print0 |
while IFS= read -d '' -r line; do
python utils/galaxyfy-module-EXAMPLES.py "$line" \
"ipa" "$collection_prefix"
done
echo -e "\033[AFixing examples in roles/*/library... \033[32;1mDONE\033[0m"
echo "Fixing playbooks in roles/*/tasks..."
for line in roles/*/tasks/*.yml; do
python utils/galaxyfy-playbook.py "$line" "ipa" "$collection_prefix"
done
echo -e "\033[AFixing playbooks in roles/*tasks... \033[32;1mDONE\033[0m"
echo -e "\033[AFixing playbooks in roles/*/tasks... \033[32;1mDONE\033[0m"
echo "Fixing playbooks in playbooks..."
find playbooks -name "*.yml" -print0 |

View File

@@ -113,7 +113,7 @@ RETURN = """
from ansible.module_utils.ansible_freeipa_module import \
IPAAnsibleModule, compare_args_ipa, gen_add_del_lists, gen_add_list, \
gen_intersection_list
gen_intersection_list, ipalib_errors
from ansible.module_utils import six
if six.PY3:
@@ -124,7 +124,7 @@ def find_$name(module, name):
"""Find if a $name with the given name already exist."""
try:
_result = module.ipa_command("$name_show", name, {"all": True})
except Exception: # pylint: disable=broad-except
except ipalib_errors.NotFound:
# An exception is raised if $name name is not found.
return None
return _result["result"]

View File

@@ -89,7 +89,7 @@ RETURN = """
from ansible.module_utils.ansible_freeipa_module import \
IPAAnsibleModule, compare_args_ipa
IPAAnsibleModule, compare_args_ipa, ipalib_errors
from ansible.module_utils import six
if six.PY3:
@@ -100,7 +100,7 @@ def find_$name(module, name):
"""Find if a $name with the given name already exist."""
try:
_result = module.ipa_command("$name_show", name, {"all": True})
except Exception: # pylint: disable=broad-except
except ipalib_errors.NotFound:
# An exception is raised if $name name is not found.
return None
return _result["result"]