import ansible-freeipa-0.1.8-3.el8
This commit is contained in:
parent
961430aca3
commit
0695dc66b6
@ -1 +1 @@
|
||||
4dcce87f3b09e7c53760980e6687de575a44ee4e SOURCES/ansible-freeipa-0.1.6.tar.gz
|
||||
583ac570c030eb68a2026a506054f2f93587beb4 SOURCES/ansible-freeipa-0.1.8.tar.gz
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1 @@
|
||||
SOURCES/ansible-freeipa-0.1.6.tar.gz
|
||||
SOURCES/ansible-freeipa-0.1.8.tar.gz
|
||||
|
@ -1,51 +0,0 @@
|
||||
From 5bb44245c6c43d752c1e066ebdc6cb3eb0253d98 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Woerner <twoerner@redhat.com>
|
||||
Date: Wed, 4 Sep 2019 14:40:46 +0200
|
||||
Subject: [PATCH] ansible_ipa_client: Drop import of
|
||||
configure_nsswitch_database
|
||||
|
||||
configure_nsswitch_database has been removed with the freeipa commit
|
||||
|
||||
https://github.com/freeipa/freeipa/commit/41ef8fba31ddbb32e2e5b7cccdc9b582a0809111
|
||||
|
||||
The 4.4 compatibility hack leads to a ALREADY installed error in
|
||||
ipaclient_test because of the removal. This affects ipaclient and
|
||||
ipareplica roles and also the ipaclient deployment part in ipaserver.
|
||||
|
||||
configure_nsswitch_database is not used any more in ipaclient role modules
|
||||
and therefore simply can be removed from ansible_ipa_client.
|
||||
---
|
||||
roles/ipaclient/module_utils/ansible_ipa_client.py | 6 ++----
|
||||
1 file changed, 2 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/roles/ipaclient/module_utils/ansible_ipa_client.py b/roles/ipaclient/module_utils/ansible_ipa_client.py
|
||||
index 30b8d42..d45171b 100644
|
||||
--- a/roles/ipaclient/module_utils/ansible_ipa_client.py
|
||||
+++ b/roles/ipaclient/module_utils/ansible_ipa_client.py
|
||||
@@ -35,7 +35,7 @@
|
||||
"configure_sssd_conf", "realm_to_suffix", "run", "timeconf",
|
||||
"serialization", "configure_krb5_conf", "get_ca_certs",
|
||||
"SECURE_PATH", "get_server_connection_interface",
|
||||
- "configure_nsswitch_database", "disable_ra", "client_dns",
|
||||
+ "disable_ra", "client_dns",
|
||||
"configure_certmonger", "update_ssh_keys",
|
||||
"configure_openldap_conf", "hardcode_ldap_server",
|
||||
"get_certs_from_ldap", "save_state", "create_ipa_nssdb",
|
||||
@@ -143,7 +143,7 @@ def knobs(self):
|
||||
try:
|
||||
from ipaclient.install.client import configure_krb5_conf, \
|
||||
get_ca_certs, SECURE_PATH, get_server_connection_interface, \
|
||||
- configure_nsswitch_database, disable_ra, client_dns, \
|
||||
+ disable_ra, client_dns, \
|
||||
configure_certmonger, update_ssh_keys, configure_openldap_conf, \
|
||||
hardcode_ldap_server, get_certs_from_ldap, save_state, \
|
||||
create_ipa_nssdb, configure_ssh_config, configure_sshd_config, \
|
||||
@@ -204,8 +204,6 @@ def configure_krb5_conf(
|
||||
|
||||
get_server_connection_interface = \
|
||||
ipa_client_install.get_server_connection_interface
|
||||
- configure_nsswitch_database = \
|
||||
- ipa_client_install.configure_nsswitch_database
|
||||
disable_ra = ipa_client_install.disable_ra
|
||||
client_dns = ipa_client_install.client_dns
|
||||
configure_certmonger = ipa_client_install.configure_certmonger
|
@ -1,13 +0,0 @@
|
||||
diff -up ansible-freeipa-0.1.6/utils/gen_module_docs.py.remove-key-dirserv_cert_files ansible-freeipa-0.1.6/utils/gen_module_docs.py
|
||||
--- ansible-freeipa-0.1.6/utils/gen_module_docs.py.gen_module_docs-drop-key-dirserv_cert_files 2019-07-23 10:01:59.000000000 +0200
|
||||
+++ ansible-freeipa-0.1.6/utils/gen_module_docs.py 2019-07-23 11:27:12.921162481 +0200
|
||||
@@ -47,9 +47,6 @@ param_docs = {
|
||||
"setup_ca": "Configure a dogtag CA",
|
||||
"setup_kra": "Configure a dogtag KRA",
|
||||
"setup_dns": "Configure bind with our zone",
|
||||
- "dirserv_cert_files": [
|
||||
- "File containing the Directory Server SSL certificate and private key"
|
||||
- ],
|
||||
"force_join": "Force client enrollment even if already enrolled",
|
||||
"subject_base": [
|
||||
"The certificate subject base (default O=<realm-name>).",
|
@ -1,62 +0,0 @@
|
||||
From e4497c18e9fb39b4e8c022eb0898060005cf6af6 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Woerner <twoerner@redhat.com>
|
||||
Date: Fri, 26 Jul 2019 18:33:41 +0200
|
||||
Subject: [PATCH] ipatopologysegment: Store suffix for commands in command list
|
||||
|
||||
With adding the domain and ca suffixes with `suffix: domain+ca` only ca
|
||||
has been added as the suffix was only used from the last command. The
|
||||
suffix is now stored together with the command and the argument. This
|
||||
will fix this error.
|
||||
|
||||
Fixes: #106 (Last suffix adding twice in the list of topology segments)
|
||||
---
|
||||
plugins/modules/ipatopologysegment.py | 13 +++++++------
|
||||
1 file changed, 7 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/plugins/modules/ipatopologysegment.py b/plugins/modules/ipatopologysegment.py
|
||||
index d64c7be..e768f72 100644
|
||||
--- a/plugins/modules/ipatopologysegment.py
|
||||
+++ b/plugins/modules/ipatopologysegment.py
|
||||
@@ -256,12 +256,12 @@ def main():
|
||||
del args[key]
|
||||
if len(args) > 1:
|
||||
# cn needs to be in args always
|
||||
- commands.append(["topologysegment_mod", args])
|
||||
+ commands.append(["topologysegment_mod", args, suffix])
|
||||
# else: Nothing to change
|
||||
else:
|
||||
if name is None:
|
||||
args["cn"] = to_text("%s-to-%s" % (left, right))
|
||||
- commands.append(["topologysegment_add", args])
|
||||
+ commands.append(["topologysegment_add", args, suffix])
|
||||
|
||||
elif state in ["absent", "disabled"]:
|
||||
# Make sure topology segment does not exist
|
||||
@@ -274,7 +274,7 @@ def main():
|
||||
args = {
|
||||
"cn": res_find["cn"][0]
|
||||
}
|
||||
- commands.append(["topologysegment_del", args])
|
||||
+ commands.append(["topologysegment_del", args, suffix])
|
||||
|
||||
elif state == "checked":
|
||||
# Check if topology segment does exists
|
||||
@@ -309,14 +309,15 @@ def main():
|
||||
elif direction == "right-to-left":
|
||||
args["right"] = True
|
||||
|
||||
- commands.append(["topologysegment_reinitialize", args])
|
||||
+ commands.append(["topologysegment_reinitialize", args,
|
||||
+ suffix])
|
||||
else:
|
||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
||||
|
||||
# Execute command
|
||||
|
||||
- for command, args in commands:
|
||||
- api_command(ansible_module, command, to_text(suffix), args)
|
||||
+ for command, args, _suffix in commands:
|
||||
+ api_command(ansible_module, command, to_text(_suffix), args)
|
||||
changed = True
|
||||
|
||||
except Exception as e:
|
@ -1,38 +0,0 @@
|
||||
From c212b43516cb870bbaa86c607dde33f373768043 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Woerner <twoerner@redhat.com>
|
||||
Date: Fri, 26 Jul 2019 19:30:11 +0200
|
||||
Subject: [PATCH] ipatopologysegment: Fail for missing entry with reinitialized
|
||||
|
||||
Currently it is ignored if the entry for reinitialized can not be found if
|
||||
the name or left and right are not correct. Now there is a failure in this
|
||||
case.
|
||||
|
||||
Fixes: #107 (Reinitialize are failed to find the node in ipatopology ..)
|
||||
Signed-off-by: Thomas Woerner <twoerner@redhat.com>
|
||||
---
|
||||
plugins/modules/ipatopologysegment.py | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
diff --git a/plugins/modules/ipatopologysegment.py b/plugins/modules/ipatopologysegment.py
|
||||
index e768f72..e506b53 100644
|
||||
--- a/plugins/modules/ipatopologysegment.py
|
||||
+++ b/plugins/modules/ipatopologysegment.py
|
||||
@@ -311,6 +311,18 @@ def main():
|
||||
|
||||
commands.append(["topologysegment_reinitialize", args,
|
||||
suffix])
|
||||
+ else:
|
||||
+ params = []
|
||||
+ if name is not None:
|
||||
+ params.append("name=%s" % name)
|
||||
+ if left is not None:
|
||||
+ params.append("left=%s" % left)
|
||||
+ if right is not None:
|
||||
+ params.append("right=%s" % right)
|
||||
+ ansible_module.fail_json(
|
||||
+ msg="No entry '%s' for suffix '%s'" %
|
||||
+ (",".join(params), suffix))
|
||||
+
|
||||
else:
|
||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,177 @@
|
||||
From 3780a9a00e77ae0fd2944b36adad446d094fc90f Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Woerner <twoerner@redhat.com>
|
||||
Date: Tue, 11 Feb 2020 10:34:39 +0100
|
||||
Subject: [PATCH] ansible_freeipa_module: Fix comparison of bool parameters in
|
||||
compare_args_ipa
|
||||
|
||||
Bool types are not iterable. Therefore the comparison using sets was failing
|
||||
with a TypeError. This prevented to change the bool parameters for hosts.
|
||||
|
||||
A test for the host module has been added to verify that the bool parameters
|
||||
can be modified.
|
||||
|
||||
New test:
|
||||
|
||||
tests/host/test_host_bool_params.yml
|
||||
|
||||
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1784514
|
||||
---
|
||||
.../module_utils/ansible_freeipa_module.py | 18 ++-
|
||||
tests/host/test_host_bool_params.yml | 119 ++++++++++++++++++
|
||||
2 files changed, 133 insertions(+), 4 deletions(-)
|
||||
create mode 100644 tests/host/test_host_bool_params.yml
|
||||
|
||||
diff --git a/plugins/module_utils/ansible_freeipa_module.py b/plugins/module_utils/ansible_freeipa_module.py
|
||||
index 8154a12..9e97b88 100644
|
||||
--- a/plugins/module_utils/ansible_freeipa_module.py
|
||||
+++ b/plugins/module_utils/ansible_freeipa_module.py
|
||||
@@ -222,10 +222,20 @@ def compare_args_ipa(module, args, ipa):
|
||||
arg = [to_text(_arg) for _arg in arg]
|
||||
if isinstance(ipa_arg[0], unicode) and isinstance(arg[0], int):
|
||||
arg = [to_text(_arg) for _arg in arg]
|
||||
- # module.warn("%s <=> %s" % (arg, ipa_arg))
|
||||
- if set(arg) != set(ipa_arg):
|
||||
- # module.warn("DIFFERENT")
|
||||
- return False
|
||||
+ # module.warn("%s <=> %s" % (repr(arg), repr(ipa_arg)))
|
||||
+ try:
|
||||
+ arg_set = set(arg)
|
||||
+ ipa_arg_set = set(ipa_arg)
|
||||
+ except TypeError:
|
||||
+ if arg != ipa_arg:
|
||||
+ # module.warn("%s != %s" % (repr(arg), repr(ipa_arg)))
|
||||
+ return False
|
||||
+ else:
|
||||
+ if arg_set != ipa_arg_set:
|
||||
+ # module.warn("%s != %s" % (repr(arg), repr(ipa_arg)))
|
||||
+ return False
|
||||
+
|
||||
+ # module.warn("%s == %s" % (repr(arg), repr(ipa_arg)))
|
||||
|
||||
return True
|
||||
|
||||
diff --git a/tests/host/test_host_bool_params.yml b/tests/host/test_host_bool_params.yml
|
||||
new file mode 100644
|
||||
index 0000000..824ea99
|
||||
--- /dev/null
|
||||
+++ b/tests/host/test_host_bool_params.yml
|
||||
@@ -0,0 +1,119 @@
|
||||
+---
|
||||
+- name: Test host bool parameters
|
||||
+ hosts: ipaserver
|
||||
+ become: true
|
||||
+
|
||||
+ tasks:
|
||||
+ - name: Get Domain from server name
|
||||
+ set_fact:
|
||||
+ ipaserver_domain: "{{ groups.ipaserver[0].split('.')[1:] | join ('.') }}"
|
||||
+ when: ipaserver_domain is not defined
|
||||
+
|
||||
+ - name: Set host1_fqdn .. host6_fqdn
|
||||
+ set_fact:
|
||||
+ host1_fqdn: "{{ 'host1.' + ipaserver_domain }}"
|
||||
+
|
||||
+ - name: Host absent
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name:
|
||||
+ - "{{ host1_fqdn }}"
|
||||
+ update_dns: yes
|
||||
+ state: absent
|
||||
+
|
||||
+ - name: Host "{{ host1_fqdn }}" present with requires_pre_auth, ok_as_delegate and ok_to_auth_as_delegate
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: "{{ host1_fqdn }}"
|
||||
+ force: yes
|
||||
+ requires_pre_auth: yes
|
||||
+ ok_as_delegate: yes
|
||||
+ ok_to_auth_as_delegate: yes
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
+ - name: Host "{{ host1_fqdn }}" present with requires_pre_auth, ok_as_delegate and ok_to_auth_as_delegate again
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: "{{ host1_fqdn }}"
|
||||
+ requires_pre_auth: yes
|
||||
+ ok_as_delegate: yes
|
||||
+ ok_to_auth_as_delegate: yes
|
||||
+ register: result
|
||||
+ failed_when: result.changed
|
||||
+
|
||||
+ - name: Host "{{ host1_fqdn }}" present with requires_pre_auth, ok_as_delegate and ok_to_auth_as_delegate set to no
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: "{{ host1_fqdn }}"
|
||||
+ requires_pre_auth: no
|
||||
+ ok_as_delegate: no
|
||||
+ ok_to_auth_as_delegate: no
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
+ - name: Host "{{ host1_fqdn }}" present with requires_pre_auth, ok_as_delegate and ok_to_auth_as_delegate set to no again
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: "{{ host1_fqdn }}"
|
||||
+ requires_pre_auth: no
|
||||
+ ok_as_delegate: no
|
||||
+ ok_to_auth_as_delegate: no
|
||||
+ register: result
|
||||
+ failed_when: result.changed
|
||||
+
|
||||
+ - name: Host "{{ host1_fqdn }}" present with requires_pre_auth
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: "{{ host1_fqdn }}"
|
||||
+ requires_pre_auth: yes
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
+ - name: Host "{{ host1_fqdn }}" present with requires_pre_auth again
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: "{{ host1_fqdn }}"
|
||||
+ requires_pre_auth: yes
|
||||
+ register: result
|
||||
+ failed_when: result.changed
|
||||
+
|
||||
+ - name: Host "{{ host1_fqdn }}" present with ok_as_delegate
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: "{{ host1_fqdn }}"
|
||||
+ ok_as_delegate: yes
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
+ - name: Host "{{ host1_fqdn }}" present with ok_as_delegate again
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: "{{ host1_fqdn }}"
|
||||
+ ok_as_delegate: yes
|
||||
+ register: result
|
||||
+ failed_when: result.changed
|
||||
+
|
||||
+ - name: Host "{{ host1_fqdn }}" present with ok_to_auth_as_delegate
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: "{{ host1_fqdn }}"
|
||||
+ ok_to_auth_as_delegate: yes
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
+ - name: Host "{{ host1_fqdn }}" present with ok_to_auth_as_delegate again
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: "{{ host1_fqdn }}"
|
||||
+ ok_to_auth_as_delegate: yes
|
||||
+ register: result
|
||||
+ failed_when: result.changed
|
||||
+
|
||||
+ - name: Host absent
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name:
|
||||
+ - "{{ host1_fqdn }}"
|
||||
+ update_dns: yes
|
||||
+ state: absent
|
@ -0,0 +1,838 @@
|
||||
From 3865ce657e3ea1b621aa054c792201aedfde2d11 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Woerner <twoerner@redhat.com>
|
||||
Date: Fri, 7 Feb 2020 10:11:38 +0100
|
||||
Subject: [PATCH] ipahbacrule: Fix handing of members with action hbacrule
|
||||
|
||||
Changing members (host, hostgroup, hbacsvc, hbacsvcgroup, user, group) with
|
||||
action hbacrule was not working due to the use of the wrong parameter
|
||||
prefix. This has been fixed and the old members are removed correctly now.
|
||||
|
||||
The test script has been reworked completely to verify the fix.
|
||||
|
||||
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1787996
|
||||
---
|
||||
plugins/modules/ipahbacrule.py | 24 +-
|
||||
tests/hbacrule/test_hbacrule.yml | 549 +++++++++++++++++++++++--------
|
||||
2 files changed, 432 insertions(+), 141 deletions(-)
|
||||
|
||||
diff --git a/plugins/modules/ipahbacrule.py b/plugins/modules/ipahbacrule.py
|
||||
index 385876b..82340c2 100644
|
||||
--- a/plugins/modules/ipahbacrule.py
|
||||
+++ b/plugins/modules/ipahbacrule.py
|
||||
@@ -344,41 +344,41 @@ def main():
|
||||
# Generate addition and removal lists
|
||||
host_add = list(
|
||||
set(host or []) -
|
||||
- set(res_find.get("member_host", [])))
|
||||
+ set(res_find.get("memberhost_host", [])))
|
||||
host_del = list(
|
||||
- set(res_find.get("member_host", [])) -
|
||||
+ set(res_find.get("memberhost_host", [])) -
|
||||
set(host or []))
|
||||
hostgroup_add = list(
|
||||
set(hostgroup or []) -
|
||||
- set(res_find.get("member_hostgroup", [])))
|
||||
+ set(res_find.get("memberhost_hostgroup", [])))
|
||||
hostgroup_del = list(
|
||||
- set(res_find.get("member_hostgroup", [])) -
|
||||
+ set(res_find.get("memberhost_hostgroup", [])) -
|
||||
set(hostgroup or []))
|
||||
|
||||
hbacsvc_add = list(
|
||||
set(hbacsvc or []) -
|
||||
- set(res_find.get("member_hbacsvc", [])))
|
||||
+ set(res_find.get("memberservice_hbacsvc", [])))
|
||||
hbacsvc_del = list(
|
||||
- set(res_find.get("member_hbacsvc", [])) -
|
||||
+ set(res_find.get("memberservice_hbacsvc", [])) -
|
||||
set(hbacsvc or []))
|
||||
hbacsvcgroup_add = list(
|
||||
set(hbacsvcgroup or []) -
|
||||
- set(res_find.get("member_hbacsvcgroup", [])))
|
||||
+ set(res_find.get("memberservice_hbacsvcgroup", [])))
|
||||
hbacsvcgroup_del = list(
|
||||
- set(res_find.get("member_hbacsvcgroup", [])) -
|
||||
+ set(res_find.get("memberservice_hbacsvcgroup", [])) -
|
||||
set(hbacsvcgroup or []))
|
||||
|
||||
user_add = list(
|
||||
set(user or []) -
|
||||
- set(res_find.get("member_user", [])))
|
||||
+ set(res_find.get("memberuser_user", [])))
|
||||
user_del = list(
|
||||
- set(res_find.get("member_user", [])) -
|
||||
+ set(res_find.get("memberuser_user", [])) -
|
||||
set(user or []))
|
||||
group_add = list(
|
||||
set(group or []) -
|
||||
- set(res_find.get("member_group", [])))
|
||||
+ set(res_find.get("memberuser_group", [])))
|
||||
group_del = list(
|
||||
- set(res_find.get("member_group", [])) -
|
||||
+ set(res_find.get("memberuser_group", [])) -
|
||||
set(group or []))
|
||||
|
||||
# Add hosts and hostgroups
|
||||
diff --git a/tests/hbacrule/test_hbacrule.yml b/tests/hbacrule/test_hbacrule.yml
|
||||
index a5615cc..38858d3 100644
|
||||
--- a/tests/hbacrule/test_hbacrule.yml
|
||||
+++ b/tests/hbacrule/test_hbacrule.yml
|
||||
@@ -1,338 +1,629 @@
|
||||
---
|
||||
-- name: Tests
|
||||
+- name: Playbook to handle hbacrules
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
- gather_facts: false
|
||||
|
||||
tasks:
|
||||
- - name: Ensure HBAC Rule allhosts is absent
|
||||
- ipahbacrule:
|
||||
+ - name: Get Domain from server name
|
||||
+ set_fact:
|
||||
+ ipaserver_domain: "{{ groups.ipaserver[0].split('.')[1:] | join ('.') }}"
|
||||
+ when: ipaserver_domain is not defined
|
||||
+
|
||||
+ # CLEANUP TEST ITEMS
|
||||
+
|
||||
+ - name: Ensure test hosts are absent
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name:
|
||||
+ - "{{ 'testhost01.' + ipaserver_domain }}"
|
||||
+ - "{{ 'testhost02.' + ipaserver_domain }}"
|
||||
+ - "{{ 'testhost03.' + ipaserver_domain }}"
|
||||
+ - "{{ 'testhost04.' + ipaserver_domain }}"
|
||||
+ state: absent
|
||||
+
|
||||
+ - name: Ensure test hostgroups are absent
|
||||
+ ipahostgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: allhosts,sshd-pinky,loginRule
|
||||
+ name: testhostgroup01,testhostgroup02,testhostgroup03,testhostgroup04
|
||||
state: absent
|
||||
|
||||
- - name: User pinky absent
|
||||
+ - name: Ensure test users are absent
|
||||
ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: pinky
|
||||
+ name: testuser01,testuser02,testuser03,testuser04
|
||||
state: absent
|
||||
|
||||
- - name: User group login absent
|
||||
+ - name: Ensure test user groups are absent
|
||||
ipagroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: login
|
||||
+ name: testgroup01,testgroup02,testgroup03,testgroup04
|
||||
+ state: absent
|
||||
+
|
||||
+ - name: Ensure test HBAC Services are absent
|
||||
+ ipahbacsvc:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: testhbacsvc01,testhbacsvc02,testhbacsvc03,testhbacsvc04
|
||||
+ state: absent
|
||||
+
|
||||
+ - name: Ensure test HBAC Service Groups are absent
|
||||
+ ipahbacsvcgroup:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: testhbacsvcgroup01,testhbacsvcgroup02,testhbacsvcgroup03,testhbacsvcgroup04
|
||||
state: absent
|
||||
|
||||
- - name: User pinky present
|
||||
+ # CREATE TEST ITEMS
|
||||
+
|
||||
+ - name: Ensure hosts "{{ 'host[1..4].' + ipaserver_domain }}" are present
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ hosts:
|
||||
+ - name: "{{ 'testhost01.' + ipaserver_domain }}"
|
||||
+ force: yes
|
||||
+ - name: "{{ 'testhost02.' + ipaserver_domain }}"
|
||||
+ force: yes
|
||||
+ - name: "{{ 'testhost03.' + ipaserver_domain }}"
|
||||
+ force: yes
|
||||
+ - name: "{{ 'testhost04.' + ipaserver_domain }}"
|
||||
+ force: yes
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
+ - name: Ensure host-group testhostgroup01 is present
|
||||
+ ipahostgroup:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: testhostgroup01
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
+ - name: Ensure host-group testhostgroup02 is present
|
||||
+ ipahostgroup:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: testhostgroup02
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
+ - name: Ensure host-group testhostgroup03 is present
|
||||
+ ipahostgroup:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: testhostgroup03
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
+ - name: Ensure host-group testhostgroup04 is present
|
||||
+ ipahostgroup:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: testhostgroup04
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
+ - name: Ensure testusers are present
|
||||
ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: pinky
|
||||
- uid: 10001
|
||||
- gid: 100
|
||||
- phone: "+555123457"
|
||||
- email: pinky@acme.com
|
||||
- principalexpiration: "20220119235959"
|
||||
- #passwordexpiration: "2022-01-19 23:59:59"
|
||||
- first: pinky
|
||||
- last: Acme
|
||||
+ users:
|
||||
+ - name: testuser01
|
||||
+ first: test
|
||||
+ last: user01
|
||||
+ - name: testuser02
|
||||
+ first: test
|
||||
+ last: user02
|
||||
+ - name: testuser03
|
||||
+ first: test
|
||||
+ last: user03
|
||||
+ - name: testuser04
|
||||
+ first: test
|
||||
+ last: user04
|
||||
register: result
|
||||
failed_when: not result.changed
|
||||
|
||||
- - name: User group login present
|
||||
+ - name: Ensure user group testgroup01 is present
|
||||
ipagroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: login
|
||||
+ name: testgroup01
|
||||
register: result
|
||||
failed_when: not result.changed
|
||||
|
||||
- - name: Ensure HBAC Rule allhosts is present
|
||||
- ipahbacrule:
|
||||
+ - name: Ensure user group testgroup02 is present
|
||||
+ ipagroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: allhosts
|
||||
- usercategory: all
|
||||
+ name: testgroup02
|
||||
register: result
|
||||
failed_when: not result.changed
|
||||
|
||||
- - name: Ensure HBAC Rule allhosts is present again
|
||||
- ipahbacrule:
|
||||
+ - name: Ensure user group testgroup03 is present
|
||||
+ ipagroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: allhosts
|
||||
- usercategory: all
|
||||
+ name: testgroup03
|
||||
register: result
|
||||
- failed_when: result.changed
|
||||
+ failed_when: not result.changed
|
||||
|
||||
- - name: Ensure host "{{ groups.ipaserver[0] }}" is present in HBAC Rule allhosts
|
||||
+ - name: Ensure user group testgroup04 is present
|
||||
+ ipagroup:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: testgroup04
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
+ - name: Ensure HBAC Service testhbacsvc01 is present
|
||||
+ ipahbacsvc:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: testhbacsvc01
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
+ - name: Ensure HBAC Service testhbacsvc02 is present
|
||||
+ ipahbacsvc:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: testhbacsvc02
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
+ - name: Ensure HBAC Service testhbacsvc03 is present
|
||||
+ ipahbacsvc:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: testhbacsvc03
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
+ - name: Ensure HBAC Service testhbacsvc04 is present
|
||||
+ ipahbacsvc:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: testhbacsvc04
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
+ - name: Ensure HBAC Service Group testhbacsvcgroup01 is present
|
||||
+ ipahbacsvcgroup:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: testhbacsvcgroup01
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
+ - name: Ensure HBAC Service Group testhbacsvcgroup02 is present
|
||||
+ ipahbacsvcgroup:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: testhbacsvcgroup02
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
+ - name: Ensure HBAC Service Group testhbacsvcgroup03 is present
|
||||
+ ipahbacsvcgroup:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: testhbacsvcgroup03
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
+ - name: Ensure HBAC Service Group testhbacsvcgroup04 is present
|
||||
+ ipahbacsvcgroup:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: testhbacsvcgroup04
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
+ - name: Ensure test HBAC rule hbacrule01 is absent
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: allhosts
|
||||
- host: "{{ groups.ipaserver[0] }}"
|
||||
- action: member
|
||||
+ name: hbacrule01
|
||||
+ state: absent
|
||||
+
|
||||
+ # ENSURE HBACRULE
|
||||
+
|
||||
+ - name: Ensure HBAC rule hbacrule01 is present
|
||||
+ ipahbacrule:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: hbacrule01
|
||||
register: result
|
||||
failed_when: not result.changed
|
||||
|
||||
- - name: Ensure host "{{ groups.ipaserver[0] }}" is present in HBAC Rule allhosts again
|
||||
+ - name: Ensure HBAC rule hbacrule01 is present again
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: allhosts
|
||||
- host: "{{ groups.ipaserver[0] }}"
|
||||
- action: member
|
||||
+ name: hbacrule01
|
||||
register: result
|
||||
failed_when: result.changed
|
||||
|
||||
- - name: Ensure HBAC Rule sshd-pinky is present
|
||||
+ # CHANGE HBACRULE WITH ALL MEMBERS
|
||||
+
|
||||
+ - name: Ensure HBAC rule hbacrule01 is present with hosts, hostgroups, users, groups, hbassvcs and hbacsvcgroups
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: sshd-pinky
|
||||
- hostcategory: all
|
||||
+ name: hbacrule01
|
||||
+ host:
|
||||
+ - "{{ 'testhost01.' + ipaserver_domain }}"
|
||||
+ - "{{ 'testhost02.' + ipaserver_domain }}"
|
||||
+ hostgroup: testhostgroup01,testhostgroup02
|
||||
+ user: testuser01,testuser02
|
||||
+ group: testgroup01,testgroup02
|
||||
+ hbacsvc: testhbacsvc01,testhbacsvc02
|
||||
+ hbacsvcgroup: testhbacsvcgroup01,testhbacsvcgroup02
|
||||
register: result
|
||||
failed_when: not result.changed
|
||||
|
||||
- - name: Ensure HBAC Rule sshd-pinky is present again
|
||||
+ - name: Ensure HBAC rule hbacrule01 is present with hosts, hostgroups, users, groups, hbassvcs and hbacsvcgroups again
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: sshd-pinky
|
||||
- hostcategory: all
|
||||
+ name: hbacrule01
|
||||
+ host:
|
||||
+ - "{{ 'testhost01.' + ipaserver_domain }}"
|
||||
+ - "{{ 'testhost02.' + ipaserver_domain }}"
|
||||
+ hostgroup: testhostgroup01,testhostgroup02
|
||||
+ user: testuser01,testuser02
|
||||
+ group: testgroup01,testgroup02
|
||||
+ hbacsvc: testhbacsvc01,testhbacsvc02
|
||||
+ hbacsvcgroup: testhbacsvcgroup01,testhbacsvcgroup02
|
||||
register: result
|
||||
failed_when: result.changed
|
||||
|
||||
- - name: Ensure user pinky is present in HBAC Rule sshd-pinky
|
||||
+ # REMOVE MEMBERS ONE BY ONE
|
||||
+
|
||||
+ - name: Ensure test HBAC rule hbacrule01 host members are absent
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: sshd-pinky
|
||||
- user: pinky
|
||||
+ name: hbacrule01
|
||||
+ host:
|
||||
+ - "{{ 'testhost01.' + ipaserver_domain }}"
|
||||
+ - "{{ 'testhost02.' + ipaserver_domain }}"
|
||||
+ state: absent
|
||||
action: member
|
||||
register: result
|
||||
failed_when: not result.changed
|
||||
|
||||
- - name: Ensure user pinky is present in HBAC Rule sshd-pinky again
|
||||
+ - name: Ensure test HBAC rule hbacrule01 host members are absent again
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: sshd-pinky
|
||||
- user: pinky
|
||||
+ name: hbacrule01
|
||||
+ host:
|
||||
+ - "{{ 'testhost01.' + ipaserver_domain }}"
|
||||
+ - "{{ 'testhost02.' + ipaserver_domain }}"
|
||||
+ state: absent
|
||||
action: member
|
||||
register: result
|
||||
failed_when: result.changed
|
||||
|
||||
- - name: Ensure HBAC service sshd is present in HBAC Rule sshd-pinky
|
||||
+ - name: Ensure test HBAC rule hbacrule01 hostgroup members are absent
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: sshd-pinky
|
||||
- hbacsvc: sshd
|
||||
+ name: hbacrule01
|
||||
+ hostgroup: testhostgroup01,testhostgroup02
|
||||
+ state: absent
|
||||
action: member
|
||||
register: result
|
||||
failed_when: not result.changed
|
||||
|
||||
- - name: Ensure HBAC service sshd is present in HBAC Rule sshd-pinky again
|
||||
+ - name: Ensure test HBAC rule hbacrule01 hostgroup members are absent again
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: sshd-pinky
|
||||
- hbacsvc: sshd
|
||||
+ name: hbacrule01
|
||||
+ hostgroup: testhostgroup01,testhostgroup02
|
||||
+ state: absent
|
||||
action: member
|
||||
register: result
|
||||
failed_when: result.changed
|
||||
|
||||
- - name: Ensure HBAC Rule loginRule is present with HBAC service sshd
|
||||
+ - name: Ensure test HBAC rule hbacrule01 user members are absent
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: loginRule
|
||||
- group: login
|
||||
+ name: hbacrule01
|
||||
+ user: testuser01,testuser02
|
||||
+ state: absent
|
||||
+ action: member
|
||||
register: result
|
||||
failed_when: not result.changed
|
||||
|
||||
- - name: Ensure HBAC Rule loginRule is present with HBAC service sshd again
|
||||
+ - name: Ensure test HBAC rule hbacrule01 user members are absent again
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: loginRule
|
||||
- group: login
|
||||
+ name: hbacrule01
|
||||
+ user: testuser01,testuser02
|
||||
+ state: absent
|
||||
+ action: member
|
||||
register: result
|
||||
failed_when: result.changed
|
||||
|
||||
- - name: Ensure user pinky is present in HBAC Rule loginRule
|
||||
+ - name: Ensure test HBAC rule hbacrule01 user group members are absent
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: loginRule
|
||||
- user: pinky
|
||||
+ name: hbacrule01
|
||||
+ group: testgroup01,testgroup02
|
||||
+ state: absent
|
||||
action: member
|
||||
register: result
|
||||
failed_when: not result.changed
|
||||
|
||||
- - name: Ensure user pinky is present in HBAC Rule loginRule again
|
||||
+ - name: Ensure test HBAC rule hbacrule01 user group members are absent again
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: loginRule
|
||||
- user: pinky
|
||||
+ name: hbacrule01
|
||||
+ group: testgroup01,testgroup02
|
||||
+ state: absent
|
||||
action: member
|
||||
register: result
|
||||
failed_when: result.changed
|
||||
|
||||
- - name: Ensure user pinky is absent in HBAC Rule loginRule
|
||||
+ - name: Ensure test HBAC rule hbacrule01 hbacsvc members are absent
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: loginRule
|
||||
- user: pinky
|
||||
- action: member
|
||||
+ name: hbacrule01
|
||||
+ hbacsvc: testhbacsvc01,testhbacsvc02
|
||||
state: absent
|
||||
+ action: member
|
||||
register: result
|
||||
failed_when: not result.changed
|
||||
|
||||
- - name: Ensure user pinky is absent in HBAC Rule loginRule again
|
||||
+ - name: Ensure test HBAC rule hbacrule01 hbacsvc members are absent again
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: loginRule
|
||||
- user: pinky
|
||||
- action: member
|
||||
+ name: hbacrule01
|
||||
+ hbacsvc: testhbacsvc01,testhbacsvc02
|
||||
state: absent
|
||||
+ action: member
|
||||
register: result
|
||||
failed_when: result.changed
|
||||
|
||||
- - name: Ensure HBAC Rule loginRule is absent
|
||||
+ - name: Ensure test HBAC rule hbacrule01 hbacsvcgroup members are absent
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: loginRule
|
||||
+ name: hbacrule01
|
||||
+ hbacsvcgroup: testhbacsvcgroup01,testhbacsvcgroup02
|
||||
state: absent
|
||||
+ action: member
|
||||
register: result
|
||||
failed_when: not result.changed
|
||||
|
||||
- - name: Ensure HBAC Rule loginRule is absent again
|
||||
+ - name: Ensure test HBAC rule hbacrule01 hbacsvcgroup members are absent again
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: loginRule
|
||||
+ name: hbacrule01
|
||||
+ hbacsvcgroup: testhbacsvcgroup01,testhbacsvcgroup02
|
||||
state: absent
|
||||
+ action: member
|
||||
register: result
|
||||
failed_when: result.changed
|
||||
|
||||
- - name: Ensure HBAC service sshd is absent in HBAC Rule sshd-pinky
|
||||
+ # ADD MEMBERS BACK
|
||||
+
|
||||
+ - name: Ensure test HBAC rule hbacrule01 host members are present
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: sshd-pinky
|
||||
- hbacsvc: sshd
|
||||
+ name: hbacrule01
|
||||
+ host:
|
||||
+ - "{{ 'testhost01.' + ipaserver_domain }}"
|
||||
+ - "{{ 'testhost02.' + ipaserver_domain }}"
|
||||
action: member
|
||||
- state: absent
|
||||
register: result
|
||||
failed_when: not result.changed
|
||||
|
||||
- - name: Ensure HBAC service sshd is absent in HBAC Rule sshd-pinky again
|
||||
+ - name: Ensure test HBAC rule hbacrule01 host members are present again
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: sshd-pinky
|
||||
- hbacsvc: sshd
|
||||
+ name: hbacrule01
|
||||
+ host:
|
||||
+ - "{{ 'testhost01.' + ipaserver_domain }}"
|
||||
+ - "{{ 'testhost02.' + ipaserver_domain }}"
|
||||
action: member
|
||||
- state: absent
|
||||
register: result
|
||||
failed_when: result.changed
|
||||
|
||||
- - name: Ensure user pinky is absent in HBAC Rule sshd-pinky
|
||||
+ - name: Ensure test HBAC rule hbacrule01 hostgroup members are present
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: sshd-pinky
|
||||
- user: pinky
|
||||
+ name: hbacrule01
|
||||
+ hostgroup: testhostgroup01,testhostgroup02
|
||||
action: member
|
||||
- state: absent
|
||||
register: result
|
||||
failed_when: not result.changed
|
||||
|
||||
- - name: Ensure user pinky is absent in HBAC Rule sshd-pinky again
|
||||
+ - name: Ensure test HBAC rule hbacrule01 hostgroup members are present again
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: sshd-pinky
|
||||
- user: pinky
|
||||
+ name: hbacrule01
|
||||
+ hostgroup: testhostgroup01,testhostgroup02
|
||||
action: member
|
||||
- state: absent
|
||||
register: result
|
||||
failed_when: result.changed
|
||||
|
||||
- - name: Ensure HBAC Rule sshd-pinky is disabled
|
||||
+ - name: Ensure test HBAC rule hbacrule01 user members are present
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: sshd-pinky
|
||||
- state: disabled
|
||||
+ name: hbacrule01
|
||||
+ user: testuser01,testuser02
|
||||
+ action: member
|
||||
register: result
|
||||
failed_when: not result.changed
|
||||
|
||||
- - name: Ensure HBAC Rule sshd-pinky is disabled again
|
||||
+ - name: Ensure test HBAC rule hbacrule01 user members are present again
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: sshd-pinky
|
||||
- state: disabled
|
||||
+ name: hbacrule01
|
||||
+ user: testuser01,testuser02
|
||||
+ action: member
|
||||
register: result
|
||||
failed_when: result.changed
|
||||
|
||||
- - name: Ensure HBAC Rule sshd-pinky is enabled
|
||||
+ - name: Ensure test HBAC rule hbacrule01 user group members are present
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: sshd-pinky
|
||||
- state: enabled
|
||||
+ name: hbacrule01
|
||||
+ group: testgroup01,testgroup02
|
||||
+ action: member
|
||||
register: result
|
||||
failed_when: not result.changed
|
||||
|
||||
- - name: Ensure HBAC Rule sshd-pinky is enabled again
|
||||
+ - name: Ensure test HBAC rule hbacrule01 user group members are present again
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: sshd-pinky
|
||||
- state: enabled
|
||||
+ name: hbacrule01
|
||||
+ group: testgroup01,testgroup02
|
||||
+ action: member
|
||||
register: result
|
||||
failed_when: result.changed
|
||||
|
||||
- - name: Ensure HBAC Rule sshd-pinky is absent
|
||||
+ - name: Ensure test HBAC rule hbacrule01 hbacsvc members are present
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: sshd-pinky
|
||||
- state: absent
|
||||
+ name: hbacrule01
|
||||
+ hbacsvc: testhbacsvc01,testhbacsvc02
|
||||
+ action: member
|
||||
register: result
|
||||
failed_when: not result.changed
|
||||
|
||||
- - name: Ensure HBAC Rule sshd-pinky is absent again
|
||||
+ - name: Ensure test HBAC rule hbacrule01 hbacsvc members are present again
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: sshd-pinky
|
||||
- state: absent
|
||||
+ name: hbacrule01
|
||||
+ hbacsvc: testhbacsvc01,testhbacsvc02
|
||||
+ action: member
|
||||
register: result
|
||||
failed_when: result.changed
|
||||
|
||||
- - name: Ensure host "{{ groups.ipaserver[0] }}" is absent in HBAC Rule allhosts
|
||||
+ - name: Ensure test HBAC rule hbacrule01 hbacsvcgroup members are present
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: allhosts
|
||||
- host: "{{ groups.ipaserver[0] }}"
|
||||
+ name: hbacrule01
|
||||
+ hbacsvcgroup: testhbacsvcgroup01,testhbacsvcgroup02
|
||||
action: member
|
||||
- state: absent
|
||||
register: result
|
||||
failed_when: not result.changed
|
||||
|
||||
- - name: Ensure host "{{ groups.ipaserver[0] }}" is absent in HBAC Rule allhosts again
|
||||
+ - name: Ensure test HBAC rule hbacrule01 hbacsvcgroup members are present again
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: allhosts
|
||||
- host: "{{ groups.ipaserver[0] }}"
|
||||
+ name: hbacrule01
|
||||
+ hbacsvcgroup: testhbacsvcgroup01,testhbacsvcgroup02
|
||||
action: member
|
||||
+ register: result
|
||||
+ failed_when: result.changed
|
||||
+
|
||||
+ # CHANGE TO DIFFERENT MEMBERS
|
||||
+
|
||||
+ - name: Ensure HBAC rule hbacrule01 is present with different hosts, hostgroups, users, groups, hbassvcs and hbacsvcgroups
|
||||
+ ipahbacrule:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: hbacrule01
|
||||
+ host:
|
||||
+ - "{{ 'testhost03.' + ipaserver_domain }}"
|
||||
+ - "{{ 'testhost04.' + ipaserver_domain }}"
|
||||
+ hostgroup: testhostgroup03,testhostgroup04
|
||||
+ user: testuser03,testuser04
|
||||
+ group: testgroup03,testgroup04
|
||||
+ hbacsvc: testhbacsvc03,testhbacsvc04
|
||||
+ hbacsvcgroup: testhbacsvcgroup03,testhbacsvcgroup04
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
+ - name: Ensure HBAC rule hbacrule01 is present with different hosts, hostgroups, users, groups, hbassvcs and hbacsvcgroups again
|
||||
+ ipahbacrule:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: hbacrule01
|
||||
+ host:
|
||||
+ - "{{ 'testhost03.' + ipaserver_domain }}"
|
||||
+ - "{{ 'testhost04.' + ipaserver_domain }}"
|
||||
+ hostgroup: testhostgroup03,testhostgroup04
|
||||
+ user: testuser03,testuser04
|
||||
+ group: testgroup03,testgroup04
|
||||
+ hbacsvc: testhbacsvc03,testhbacsvc04
|
||||
+ hbacsvcgroup: testhbacsvcgroup03,testhbacsvcgroup04
|
||||
+ register: result
|
||||
+ failed_when: result.changed
|
||||
+
|
||||
+ # ENSURE OLD TEST MEMBERS ARE ABSENT
|
||||
+
|
||||
+ - name: Ensure HBAC rule hbacrule01 members (same) are present
|
||||
+ ipahbacrule:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: hbacrule01
|
||||
+ host:
|
||||
+ - "{{ 'testhost01.' + ipaserver_domain }}"
|
||||
+ - "{{ 'testhost02.' + ipaserver_domain }}"
|
||||
+ hostgroup: testhostgroup01,testhostgroup02
|
||||
+ user: testuser01,testuser02
|
||||
+ group: testgroup01,testgroup02
|
||||
+ hbacsvc: testhbacsvc01,testhbacsvc02
|
||||
+ hbacsvcgroup: testhbacsvcgroup01,testhbacsvcgroup02
|
||||
state: absent
|
||||
+ action: member
|
||||
register: result
|
||||
failed_when: result.changed
|
||||
|
||||
- - name: Ensure HBAC Rule allhosts is absent
|
||||
+ # ENSURE NEW TEST MEMBERS ARE ABSENT
|
||||
+
|
||||
+ - name: Ensure HBAC rule hbacrule01 members are absent
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: allhosts
|
||||
+ name: hbacrule01
|
||||
+ host:
|
||||
+ - "{{ 'testhost03.' + ipaserver_domain }}"
|
||||
+ - "{{ 'testhost04.' + ipaserver_domain }}"
|
||||
+ hostgroup: testhostgroup03,testhostgroup04
|
||||
+ user: testuser03,testuser04
|
||||
+ group: testgroup03,testgroup04
|
||||
+ hbacsvc: testhbacsvc03,testhbacsvc04
|
||||
+ hbacsvcgroup: testhbacsvcgroup03,testhbacsvcgroup04
|
||||
state: absent
|
||||
+ action: member
|
||||
register: result
|
||||
failed_when: not result.changed
|
||||
|
||||
- - name: Ensure HBAC Rule allhosts is absent again
|
||||
+ - name: Ensure HBAC rule hbacrule01 members are absent again
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: allhosts
|
||||
+ name: hbacrule01
|
||||
+ host:
|
||||
+ - "{{ 'testhost03.' + ipaserver_domain }}"
|
||||
+ - "{{ 'testhost04.' + ipaserver_domain }}"
|
||||
+ hostgroup: testhostgroup03,testhostgroup04
|
||||
+ user: testuser03,testuser04
|
||||
+ group: testgroup03,testgroup04
|
||||
+ hbacsvc: testhbacsvc03,testhbacsvc04
|
||||
+ hbacsvcgroup: testhbacsvcgroup03,testhbacsvcgroup04
|
||||
state: absent
|
||||
+ action: member
|
||||
register: result
|
||||
failed_when: result.changed
|
||||
|
||||
- - name: User pinky absent
|
||||
+ # CLEANUP TEST ITEMS
|
||||
+
|
||||
+ - name: Ensure test HBAC rule hbacrule01 is absent
|
||||
+ ipahbacrule:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: hbacrule01
|
||||
+ state: absent
|
||||
+
|
||||
+ - name: Ensure test hosts are absent
|
||||
+ ipahostgroup:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name:
|
||||
+ - "{{ 'testhost01.' + ipaserver_domain }}"
|
||||
+ - "{{ 'testhost02.' + ipaserver_domain }}"
|
||||
+ - "{{ 'testhost03.' + ipaserver_domain }}"
|
||||
+ - "{{ 'testhost04.' + ipaserver_domain }}"
|
||||
+ state: absent
|
||||
+
|
||||
+ - name: Ensure test hostgroups are absent
|
||||
+ ipahostgroup:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: testhostgroup01,testhostgroup02,testhostgroup03,testhostgroup04
|
||||
+ state: absent
|
||||
+
|
||||
+ - name: Ensure test users are absent
|
||||
ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: pinky
|
||||
+ name: testuser01,testuser02,testuser03,testuser04
|
||||
state: absent
|
||||
|
||||
- - name: User group login absent
|
||||
+ - name: Ensure test user groups are absent
|
||||
ipagroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: login
|
||||
+ name: testgroup01,testgroup02,testgroup03,testgroup04
|
||||
+ state: absent
|
||||
+
|
||||
+ - name: Ensure test HBAC Services are absent
|
||||
+ ipahbacsvc:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: testhbacsvc01,testhbacsvc02,testhbacsvc03,testhbacsvc04
|
||||
+ state: absent
|
||||
+
|
||||
+ - name: Ensure test HBAC Service Groups are absent
|
||||
+ ipahbacsvcgroup:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: testhbacsvcgroup01,testhbacsvcgroup02,testhbacsvcgroup03,testhbacsvcgroup04
|
||||
state: absent
|
@ -0,0 +1,106 @@
|
||||
From 22d8784da29dcfede0744ef6b691b4506eae5deb Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Woerner <twoerner@redhat.com>
|
||||
Date: Thu, 20 Feb 2020 12:58:11 +0100
|
||||
Subject: [PATCH] ipahost: Do not fail on missing DNS or zone when no IP
|
||||
address given
|
||||
|
||||
If no IP address is given and either DNS is not configured or if the zone is
|
||||
not found then ipahost may not fail in dnsrecord_find.
|
||||
|
||||
The error happened for example by ensuring the absence of a host that is not
|
||||
part of the domain or for a host that has been added with force and is using
|
||||
a domain that is not served by the DNS server in the domain. It also
|
||||
happened if there was no DNS server in the domain at all.
|
||||
|
||||
A new test case has been added to test_host_ipaddresses.yml
|
||||
|
||||
The fix requires ipalib_errors provided by ansible_freeipa_module.
|
||||
|
||||
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1804838
|
||||
---
|
||||
plugins/modules/ipahost.py | 17 +++++++++++++++--
|
||||
tests/host/test_host_ipaddresses.yml | 9 +++++++++
|
||||
2 files changed, 24 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/plugins/modules/ipahost.py b/plugins/modules/ipahost.py
|
||||
index 558560e..062f768 100644
|
||||
--- a/plugins/modules/ipahost.py
|
||||
+++ b/plugins/modules/ipahost.py
|
||||
@@ -409,7 +409,7 @@
|
||||
from ansible.module_utils.ansible_freeipa_module import temp_kinit, \
|
||||
temp_kdestroy, valid_creds, api_connect, api_command, compare_args_ipa, \
|
||||
module_params_get, gen_add_del_lists, encode_certificate, api_get_realm, \
|
||||
- is_ipv4_addr, is_ipv6_addr
|
||||
+ is_ipv4_addr, is_ipv6_addr, ipalib_errors
|
||||
import six
|
||||
|
||||
|
||||
@@ -871,7 +871,20 @@ def main():
|
||||
|
||||
# Make sure host exists
|
||||
res_find = find_host(ansible_module, name)
|
||||
- res_find_dnsrecord = find_dnsrecord(ansible_module, name)
|
||||
+ try:
|
||||
+ res_find_dnsrecord = find_dnsrecord(ansible_module, name)
|
||||
+ except ipalib_errors.NotFound as e:
|
||||
+ msg = str(e)
|
||||
+ if ip_address is None and \
|
||||
+ ("DNS is not configured" in msg or \
|
||||
+ "DNS zone not found" in msg):
|
||||
+ # IP address(es) not given and no DNS support in IPA
|
||||
+ # -> Ignore failure
|
||||
+ # IP address(es) not given and DNS zone is not found
|
||||
+ # -> Ignore failure
|
||||
+ res_find_dnsrecord = None
|
||||
+ else:
|
||||
+ ansible_module.fail_json(msg="%s: %s" % (host, msg))
|
||||
|
||||
# Create command
|
||||
if state == "present":
|
||||
diff --git a/tests/host/test_host_ipaddresses.yml b/tests/host/test_host_ipaddresses.yml
|
||||
index 0a97dd5..136a610 100644
|
||||
--- a/tests/host/test_host_ipaddresses.yml
|
||||
+++ b/tests/host/test_host_ipaddresses.yml
|
||||
@@ -301,6 +301,15 @@
|
||||
register: result
|
||||
failed_when: result.changed
|
||||
|
||||
+ - name: Absent host01.ihavenodns.info test
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ hosts:
|
||||
+ - name: host01.ihavenodns.info
|
||||
+ state: absent
|
||||
+ register: result
|
||||
+ failed_when: result.changed
|
||||
+
|
||||
- name: Host absent
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
From 4d94cb09a9fb09dd2576223b9be7f77d515202fb Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Woerner <twoerner@redhat.com>
|
||||
Date: Thu, 20 Feb 2020 12:54:32 +0100
|
||||
Subject: [PATCH] ansible_freeipa_module: Import ipalib.errors as ipalib_errors
|
||||
|
||||
For beeing able to catch ipalib.errors.NotFound errors in ipahost it is
|
||||
needed to import ipalib.errors. ipalib.errors is now imported as
|
||||
ipalib_errors to not have name conflicts with the errors list used in some
|
||||
of the modules.
|
||||
|
||||
Related: https://bugzilla.redhat.com/show_bug.cgi?id=1804838
|
||||
---
|
||||
plugins/module_utils/ansible_freeipa_module.py | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/plugins/module_utils/ansible_freeipa_module.py b/plugins/module_utils/ansible_freeipa_module.py
|
||||
index 6acdbef..5066de3 100644
|
||||
--- a/plugins/module_utils/ansible_freeipa_module.py
|
||||
+++ b/plugins/module_utils/ansible_freeipa_module.py
|
||||
@@ -28,6 +28,7 @@
|
||||
import gssapi
|
||||
from datetime import datetime
|
||||
from ipalib import api
|
||||
+from ipalib import errors as ipalib_errors
|
||||
from ipalib.config import Env
|
||||
from ipalib.constants import DEFAULT_CONFIG, LDAP_GENERALIZED_TIME_FORMAT
|
||||
try:
|
@ -0,0 +1,51 @@
|
||||
From 24515e40ad289552d45bddd33c7a0dda93117a7f Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Woerner <twoerner@redhat.com>
|
||||
Date: Wed, 18 Dec 2019 12:28:03 +0100
|
||||
Subject: [PATCH] ipahost: Enhanced failure msg for member params used without
|
||||
member action
|
||||
|
||||
The failure message if member parameters like certificate, managedby_host,
|
||||
principal, allow_create_keytab_* and allow_retrieve_keytab_* are used
|
||||
without member action for state absent has been enhanced to propose the
|
||||
member action.
|
||||
---
|
||||
plugins/modules/ipahost.py | 20 +++++++++++++-------
|
||||
1 file changed, 13 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/plugins/modules/ipahost.py b/plugins/modules/ipahost.py
|
||||
index ec5e196..8ee9532 100644
|
||||
--- a/plugins/modules/ipahost.py
|
||||
+++ b/plugins/modules/ipahost.py
|
||||
@@ -511,19 +511,25 @@ def check_parameters(
|
||||
"userclass", "auth_ind", "requires_pre_auth",
|
||||
"ok_as_delegate", "ok_to_auth_as_delegate", "force",
|
||||
"reverse", "ip_address", "update_password"]
|
||||
+ for x in invalid:
|
||||
+ if vars()[x] is not None:
|
||||
+ module.fail_json(
|
||||
+ msg="Argument '%s' can not be used with state '%s'" %
|
||||
+ (x, state))
|
||||
if action == "host":
|
||||
- invalid.extend([
|
||||
+ invalid = [
|
||||
"certificate", "managedby_host", "principal",
|
||||
"allow_create_keytab_user", "allow_create_keytab_group",
|
||||
"allow_create_keytab_host", "allow_create_keytab_hostgroup",
|
||||
"allow_retrieve_keytab_user", "allow_retrieve_keytab_group",
|
||||
"allow_retrieve_keytab_host",
|
||||
- "allow_retrieve_keytab_hostgroup"])
|
||||
- for x in invalid:
|
||||
- if vars()[x] is not None:
|
||||
- module.fail_json(
|
||||
- msg="Argument '%s' can not be used with state '%s'" %
|
||||
- (x, state))
|
||||
+ "allow_retrieve_keytab_hostgroup"
|
||||
+ ]
|
||||
+ for x in invalid:
|
||||
+ if vars()[x] is not None:
|
||||
+ module.fail_json(
|
||||
+ msg="Argument '%s' can only be used with action "
|
||||
+ "'member' for state '%s'" % (x, state))
|
||||
|
||||
|
||||
def main():
|
@ -0,0 +1,57 @@
|
||||
From 0816b0773b1535780c7c3e5f05bda39434ab6bac Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Woerner <twoerner@redhat.com>
|
||||
Date: Fri, 14 Feb 2020 13:21:54 +0100
|
||||
Subject: [PATCH] ipahost: Fail on action member for new hosts, fix
|
||||
dnsrecord_add reverse flag
|
||||
|
||||
The check to make sure that member can not be used on non existing hosts
|
||||
has bee missing. Also the reverse flag for the dnsrecord_add call was None
|
||||
if the varaible was not set.
|
||||
|
||||
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1803026
|
||||
---
|
||||
plugins/modules/ipahost.py | 23 +++++++++++++++--------
|
||||
1 file changed, 15 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/plugins/modules/ipahost.py b/plugins/modules/ipahost.py
|
||||
index a5fd482..558560e 100644
|
||||
--- a/plugins/modules/ipahost.py
|
||||
+++ b/plugins/modules/ipahost.py
|
||||
@@ -1005,6 +1005,11 @@ def main():
|
||||
dnsrecord_args.get("aaaarecord"),
|
||||
_dnsrec.get("aaaarecord"))
|
||||
|
||||
+ else:
|
||||
+ if res_find is None:
|
||||
+ ansible_module.fail_json(
|
||||
+ msg="No host '%s'" % name)
|
||||
+
|
||||
if action != "host" or (action == "host" and res_find is None):
|
||||
certificate_add = certificate or []
|
||||
certificate_del = []
|
||||
@@ -1178,15 +1183,17 @@ def main():
|
||||
domain_name = name[name.find(".")+1:]
|
||||
host_name = name[:name.find(".")]
|
||||
|
||||
+ _args = {"idnsname": host_name}
|
||||
+ if reverse is not None:
|
||||
+ _args["a_extra_create_reverse"] = reverse
|
||||
+ _args["aaaa_extra_create_reverse"] = reverse
|
||||
+ if len(dnsrecord_a_add) > 0:
|
||||
+ _args["arecord"] = dnsrecord_a_add
|
||||
+ if len(dnsrecord_aaaa_add) > 0:
|
||||
+ _args["aaaarecord"] = dnsrecord_aaaa_add
|
||||
+
|
||||
commands.append([domain_name,
|
||||
- "dnsrecord_add",
|
||||
- {
|
||||
- "idnsname": host_name,
|
||||
- "arecord": dnsrecord_a_add,
|
||||
- "a_extra_create_reverse": reverse,
|
||||
- "aaaarecord": dnsrecord_aaaa_add,
|
||||
- "aaaa_extra_create_reverse": reverse
|
||||
- }])
|
||||
+ "dnsrecord_add", _args])
|
||||
|
||||
if len(dnsrecord_a_del) > 0 or len(dnsrecord_aaaa_del) > 0:
|
||||
domain_name = name[name.find(".")+1:]
|
@ -0,0 +1,78 @@
|
||||
From b6100f0c19e2caf73ab70bbc572d3e47e6066b48 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Woerner <twoerner@redhat.com>
|
||||
Date: Tue, 17 Dec 2019 14:04:43 +0100
|
||||
Subject: [PATCH] ipahost: Fix choices of auth_ind parameter, allow to reset
|
||||
parameter
|
||||
|
||||
The choices for the auth_ind parameter have been wrong. The choices are now
|
||||
['radius', 'otp', 'pkinit', 'hardened', '']. The empty string has been added
|
||||
to be able to rest auth_ind for the host entry.
|
||||
---
|
||||
README-host.md | 2 +-
|
||||
plugins/modules/ipahost.py | 15 ++++++++++++---
|
||||
2 files changed, 13 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/README-host.md b/README-host.md
|
||||
index edec8d9..be5ad79 100644
|
||||
--- a/README-host.md
|
||||
+++ b/README-host.md
|
||||
@@ -280,7 +280,7 @@ Variable | Description | Required
|
||||
`mac_address` \| `macaddress` | List of hardware MAC addresses. | no
|
||||
`sshpubkey` \| `ipasshpubkey` | List of SSH public keys | no
|
||||
`userclass` \| `class` | Host category (semantics placed on this attribute are for local interpretation) | no
|
||||
-`auth_ind` \| `krbprincipalauthind` | Defines a whitelist for Authentication Indicators. Use 'otp' to allow OTP-based 2FA authentications. Use 'radius' to allow RADIUS-based 2FA authentications. Other values may be used for custom configurations. choices: ["radius", "otp", "pkinit", "hardened"] | no
|
||||
+`auth_ind` \| `krbprincipalauthind` | Defines a whitelist for Authentication Indicators. Use 'otp' to allow OTP-based 2FA authentications. Use 'radius' to allow RADIUS-based 2FA authentications. Use empty string to reset auth_ind to the initial value. Other values may be used for custom configurations. choices: ["radius", "otp", "pkinit", "hardened", ""] | no
|
||||
`requires_pre_auth` \| `ipakrbrequirespreauth` | Pre-authentication is required for the service (bool) | no
|
||||
`ok_as_delegate` \| `ipakrbokasdelegate` | Client credentials may be delegated to the service (bool) | no
|
||||
`ok_to_auth_as_delegate` \| `ipakrboktoauthasdelegate` | The service is allowed to authenticate on behalf of a client (bool) | no
|
||||
diff --git a/plugins/modules/ipahost.py b/plugins/modules/ipahost.py
|
||||
index ec5e196..b130395 100644
|
||||
--- a/plugins/modules/ipahost.py
|
||||
+++ b/plugins/modules/ipahost.py
|
||||
@@ -147,9 +147,10 @@
|
||||
Defines a whitelist for Authentication Indicators. Use 'otp' to allow
|
||||
OTP-based 2FA authentications. Use 'radius' to allow RADIUS-based 2FA
|
||||
authentications. Other values may be used for custom configurations.
|
||||
+ Use empty string to reset auth_ind to the initial value.
|
||||
type: list
|
||||
aliases: ["krbprincipalauthind"]
|
||||
- choices: ["radius", "otp", "pkinit", "hardened"]
|
||||
+ choices: ["radius", "otp", "pkinit", "hardened", ""]
|
||||
required: false
|
||||
requires_pre_auth:
|
||||
description: Pre-authentication is required for the service
|
||||
@@ -277,9 +278,10 @@
|
||||
Defines a whitelist for Authentication Indicators. Use 'otp' to allow
|
||||
OTP-based 2FA authentications. Use 'radius' to allow RADIUS-based 2FA
|
||||
authentications. Other values may be used for custom configurations.
|
||||
+ Use empty string to reset auth_ind to the initial value.
|
||||
type: list
|
||||
aliases: ["krbprincipalauthind"]
|
||||
- choices: ["radius", "otp", "pkinit", "hardened"]
|
||||
+ choices: ["radius", "otp", "pkinit", "hardened", ""]
|
||||
required: false
|
||||
requires_pre_auth:
|
||||
description: Pre-authentication is required for the service
|
||||
@@ -590,7 +592,7 @@ def main():
|
||||
default=None),
|
||||
auth_ind=dict(type='list', aliases=["krbprincipalauthind"],
|
||||
default=None,
|
||||
- choices=['password', 'radius', 'otp']),
|
||||
+ choices=['radius', 'otp', 'pkinit', 'hardened', '']),
|
||||
requires_pre_auth=dict(type="bool", aliases=["ipakrbrequirespreauth"],
|
||||
default=None),
|
||||
ok_as_delegate=dict(type="bool", aliases=["ipakrbokasdelegate"],
|
||||
@@ -835,6 +837,13 @@ def main():
|
||||
if x in args:
|
||||
del args[x]
|
||||
|
||||
+ # Ignore auth_ind if it is empty (for resetting)
|
||||
+ # and not set in for the host
|
||||
+ if "krbprincipalauthind" not in res_find and \
|
||||
+ "krbprincipalauthind" in args and \
|
||||
+ args["krbprincipalauthind"] == ['']:
|
||||
+ del args["krbprincipalauthind"]
|
||||
+
|
||||
# For all settings is args, check if there are
|
||||
# different settings in the find result.
|
||||
# If yes: modify
|
@ -0,0 +1,179 @@
|
||||
From 4dd1d25eacd1481be0a881a017144ff4d3396ccd Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Woerner <twoerner@redhat.com>
|
||||
Date: Thu, 6 Feb 2020 15:38:00 +0100
|
||||
Subject: [PATCH] ipapwpolicy: Use global_policy if name is not set
|
||||
|
||||
If the name is not set, the policy global_policy is now used. It was needed
|
||||
before to explicitly name the global_policy. Also a check has been added
|
||||
to fail early if global_policy is used with state absent.
|
||||
|
||||
The README for pwpolicy has been extended with an example for global_policy
|
||||
and also the description of the name variable.
|
||||
|
||||
The test has also been extended to check a change of maxlife for
|
||||
global_policy and that global_policy can not be used with state: absent
|
||||
|
||||
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1797532
|
||||
---
|
||||
README-pwpolicy.md | 19 +++++++++++--
|
||||
plugins/modules/ipapwpolicy.py | 9 ++++--
|
||||
tests/pwpolicy/test_pwpolicy.yml | 49 ++++++++++++++++++++++++++++++++
|
||||
3 files changed, 73 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/README-pwpolicy.md b/README-pwpolicy.md
|
||||
index 16306b7..847b32d 100644
|
||||
--- a/README-pwpolicy.md
|
||||
+++ b/README-pwpolicy.md
|
||||
@@ -56,7 +56,7 @@ Example playbook to ensure presence of pwpolicies for exisiting group ops:
|
||||
maxfail: 3
|
||||
```
|
||||
|
||||
-Example playbook to ensure absence of pwpolicies for group ops
|
||||
+Example playbook to ensure absence of pwpolicies for group ops:
|
||||
|
||||
```yaml
|
||||
---
|
||||
@@ -72,6 +72,21 @@ Example playbook to ensure absence of pwpolicies for group ops
|
||||
state: absent
|
||||
```
|
||||
|
||||
+Example playbook to ensure maxlife is set to 49 in global policy:
|
||||
+
|
||||
+```yaml
|
||||
+---
|
||||
+- name: Playbook to handle pwpolicies
|
||||
+ hosts: ipaserver
|
||||
+ become: true
|
||||
+
|
||||
+ tasks:
|
||||
+ # Ensure absence of pwpolicies for group ops
|
||||
+ - ipapwpolicy:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ maxlife: 49
|
||||
+```
|
||||
+
|
||||
|
||||
Variables
|
||||
=========
|
||||
@@ -83,7 +98,7 @@ Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`ipaadmin_principal` | The admin principal is a string and defaults to `admin` | no
|
||||
`ipaadmin_password` | The admin password is a string and is required if there is no admin ticket available on the node | no
|
||||
-`name` \| `cn` | The list of pwpolicy name strings. | no
|
||||
+`name` \| `cn` | The list of pwpolicy name strings. If name is not given, `global_policy` will be used automatically. | no
|
||||
`maxlife` \| `krbmaxpwdlife` | Maximum password lifetime in days. (int) | no
|
||||
`minlife` \| `krbminpwdlife` | Minimum password lifetime in hours. (int) | no
|
||||
`history` \| `krbpwdhistorylength` | Password history size. (int) | no
|
||||
diff --git a/plugins/modules/ipapwpolicy.py b/plugins/modules/ipapwpolicy.py
|
||||
index 9437b59..f168703 100644
|
||||
--- a/plugins/modules/ipapwpolicy.py
|
||||
+++ b/plugins/modules/ipapwpolicy.py
|
||||
@@ -167,7 +167,7 @@ def main():
|
||||
ipaadmin_password=dict(type="str", required=False, no_log=True),
|
||||
|
||||
name=dict(type="list", aliases=["cn"], default=None,
|
||||
- required=True),
|
||||
+ required=False),
|
||||
# present
|
||||
|
||||
maxlife=dict(type="int", aliases=["krbmaxpwdlife"], default=None),
|
||||
@@ -218,6 +218,9 @@ def main():
|
||||
|
||||
# Check parameters
|
||||
|
||||
+ if names is None:
|
||||
+ names = ["global_policy"]
|
||||
+
|
||||
if state == "present":
|
||||
if len(names) != 1:
|
||||
ansible_module.fail_json(
|
||||
@@ -225,8 +228,10 @@ def main():
|
||||
|
||||
if state == "absent":
|
||||
if len(names) < 1:
|
||||
+ ansible_module.fail_json(msg="No name given.")
|
||||
+ if "global_policy" in names:
|
||||
ansible_module.fail_json(
|
||||
- msg="No name given.")
|
||||
+ msg="'global_policy' can not be made absent.")
|
||||
invalid = ["maxlife", "minlife", "history", "minclasses",
|
||||
"minlength", "priority", "maxfail", "failinterval",
|
||||
"lockouttime"]
|
||||
diff --git a/tests/pwpolicy/test_pwpolicy.yml b/tests/pwpolicy/test_pwpolicy.yml
|
||||
index 5c69345..f93f275 100644
|
||||
--- a/tests/pwpolicy/test_pwpolicy.yml
|
||||
+++ b/tests/pwpolicy/test_pwpolicy.yml
|
||||
@@ -5,10 +5,30 @@
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
+ - name: Ensure maxlife of 90 for global_policy
|
||||
+ ipapwpolicy:
|
||||
+ ipaadmin_password: SomeADMINpassword
|
||||
+ maxlife: 90
|
||||
+
|
||||
+ - name: Ensure absence of group ops
|
||||
+ ipagroup:
|
||||
+ ipaadmin_password: SomeADMINpassword
|
||||
+ name: ops
|
||||
+ state: absent
|
||||
+
|
||||
+ - name: Ensure absence of pwpolicies for group ops
|
||||
+ ipapwpolicy:
|
||||
+ ipaadmin_password: SomeADMINpassword
|
||||
+ name: ops
|
||||
+ state: absent
|
||||
+
|
||||
- name: Ensure presence of group ops
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: ops
|
||||
+ state: present
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
|
||||
- name: Ensure presence of pwpolicies for group ops
|
||||
ipapwpolicy:
|
||||
@@ -42,6 +62,28 @@
|
||||
register: result
|
||||
failed_when: result.changed
|
||||
|
||||
+ - name: Ensure maxlife of 49 for global_policy
|
||||
+ ipapwpolicy:
|
||||
+ ipaadmin_password: SomeADMINpassword
|
||||
+ maxlife: 49
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
+ - name: Ensure maxlife of 49 for global_policy again
|
||||
+ ipapwpolicy:
|
||||
+ ipaadmin_password: SomeADMINpassword
|
||||
+ maxlife: 49
|
||||
+ register: result
|
||||
+ failed_when: result.changed
|
||||
+
|
||||
+ - name: Ensure absence of pwpoliciy global_policy will fail
|
||||
+ ipapwpolicy:
|
||||
+ ipaadmin_password: SomeADMINpassword
|
||||
+ state: absent
|
||||
+ register: result
|
||||
+ ignore_errors: True
|
||||
+ failed_when: result is defined and result
|
||||
+
|
||||
- name: Ensure absence of pwpolicies for group ops
|
||||
ipapwpolicy:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
@@ -50,6 +92,13 @@
|
||||
register: result
|
||||
failed_when: not result.changed
|
||||
|
||||
+ - name: Ensure maxlife of 90 for global_policy
|
||||
+ ipapwpolicy:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ maxlife: 90
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
- name: Ensure absence of pwpolicies for group ops
|
||||
ipapwpolicy:
|
||||
ipaadmin_password: SomeADMINpassword
|
@ -0,0 +1,116 @@
|
||||
From 36c1c837086c42049f09cf689a1ebd61627abae0 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Woerner <twoerner@redhat.com>
|
||||
Date: Tue, 17 Dec 2019 15:30:45 +0100
|
||||
Subject: [PATCH] ipauser: Allow reset of userauthtype, do not depend on
|
||||
first,last for mod
|
||||
|
||||
It was not possible to reset the userauthtype. The empty string has been
|
||||
added to userauthtype for this.
|
||||
|
||||
Also ipauser will only depend on given first and last name if the user
|
||||
does not exist yet. For the update operation these parameters are not
|
||||
needed anymore.
|
||||
---
|
||||
README-user.md | 2 +-
|
||||
plugins/modules/ipauser.py | 38 ++++++++++++++++++++++++++------------
|
||||
2 files changed, 27 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/README-user.md b/README-user.md
|
||||
index 56772a7..991121c 100644
|
||||
--- a/README-user.md
|
||||
+++ b/README-user.md
|
||||
@@ -408,7 +408,7 @@ Variable | Description | Required
|
||||
`manager` | List of manager user names. | no
|
||||
`carlicense` | List of car licenses. | no
|
||||
`sshpubkey` \| `ipasshpubkey` | List of SSH public keys. | no
|
||||
-`userauthtype` | List of supported user authentication types. Choices: `password`, `radius` and `otp` | no
|
||||
+`userauthtype` | List of supported user authentication types. Choices: `password`, `radius`, `otp` and ``. Use empty string to reset userauthtype to the initial value. | no
|
||||
`userclass` | User category. (semantics placed on this attribute are for local interpretation). | no
|
||||
`radius` | RADIUS proxy configuration | no
|
||||
`radiususer` | RADIUS proxy username | no
|
||||
diff --git a/plugins/modules/ipauser.py b/plugins/modules/ipauser.py
|
||||
index ac45295..36e8bae 100644
|
||||
--- a/plugins/modules/ipauser.py
|
||||
+++ b/plugins/modules/ipauser.py
|
||||
@@ -153,9 +153,12 @@
|
||||
required: false
|
||||
aliases: ["ipasshpubkey"]
|
||||
userauthtype:
|
||||
- description: List of supported user authentication types
|
||||
- choices=['password', 'radius', 'otp']
|
||||
+ description:
|
||||
+ List of supported user authentication types
|
||||
+ Use empty string to reset userauthtype to the initial value.
|
||||
+ choices=['password', 'radius', 'otp', '']
|
||||
required: false
|
||||
+ aliases: ["ipauserauthtype"]
|
||||
userclass:
|
||||
description:
|
||||
- User category
|
||||
@@ -310,9 +313,12 @@
|
||||
required: false
|
||||
aliases: ["ipasshpubkey"]
|
||||
userauthtype:
|
||||
- description: List of supported user authentication types
|
||||
- choices=['password', 'radius', 'otp']
|
||||
+ description:
|
||||
+ List of supported user authentication types
|
||||
+ Use empty string to reset userauthtype to the initial value.
|
||||
+ choices=['password', 'radius', 'otp', '']
|
||||
required: false
|
||||
+ aliases: ["ipauserauthtype"]
|
||||
userclass:
|
||||
description:
|
||||
- User category
|
||||
@@ -701,7 +707,7 @@ def main():
|
||||
default=None),
|
||||
userauthtype=dict(type='list', aliases=["ipauserauthtype"],
|
||||
default=None,
|
||||
- choices=['password', 'radius', 'otp']),
|
||||
+ choices=['password', 'radius', 'otp', '']),
|
||||
userclass=dict(type="list", aliases=["class"],
|
||||
default=None),
|
||||
radius=dict(type="str", aliases=["ipatokenradiusconfiglink"],
|
||||
@@ -845,13 +851,6 @@ def main():
|
||||
if names is not None and len(names) != 1:
|
||||
ansible_module.fail_json(
|
||||
msg="Only one user can be added at a time using name.")
|
||||
- if action != "member":
|
||||
- # Only check first and last here if names is set
|
||||
- if names is not None:
|
||||
- if first is None:
|
||||
- ansible_module.fail_json(msg="First name is needed")
|
||||
- if last is None:
|
||||
- ansible_module.fail_json(msg="Last name is needed")
|
||||
|
||||
check_parameters(
|
||||
ansible_module, state, action,
|
||||
@@ -1011,6 +1010,13 @@ def main():
|
||||
if "noprivate" in args:
|
||||
del args["noprivate"]
|
||||
|
||||
+ # Ignore userauthtype if it is empty (for resetting)
|
||||
+ # and not set in for the user
|
||||
+ if "ipauserauthtype" not in res_find and \
|
||||
+ "ipauserauthtype" in args and \
|
||||
+ args["ipauserauthtype"] == ['']:
|
||||
+ del args["ipauserauthtype"]
|
||||
+
|
||||
# For all settings is args, check if there are
|
||||
# different settings in the find result.
|
||||
# If yes: modify
|
||||
@@ -1019,6 +1025,14 @@ def main():
|
||||
commands.append([name, "user_mod", args])
|
||||
|
||||
else:
|
||||
+ # Make sure we have a first and last name
|
||||
+ if first is None:
|
||||
+ ansible_module.fail_json(
|
||||
+ msg="First name is needed")
|
||||
+ if last is None:
|
||||
+ ansible_module.fail_json(
|
||||
+ msg="Last name is needed")
|
||||
+
|
||||
commands.append([name, "user_add", args])
|
||||
|
||||
# Handle members: principal, manager, certificate and
|
@ -0,0 +1,915 @@
|
||||
From 167c76311da72c2bfabf4b2bce9e128c11d519d0 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Woerner <twoerner@redhat.com>
|
||||
Date: Wed, 12 Feb 2020 16:54:13 +0100
|
||||
Subject: [PATCH] ipahost: Add support for several IP addresses and also to
|
||||
change them
|
||||
|
||||
ipahost was so far ignoring IP addresses when the host already existed.
|
||||
This happened because host_mod is not providing functionality to do this.
|
||||
Now ipaddress is a list and it is possible to ensure a host with several
|
||||
IP addresses (these can be IPv4 and IPv6). Also it is possible to ensure
|
||||
presence and absence of IP addresses for an exising host using action
|
||||
member.
|
||||
|
||||
There are no IP address conclict checks as this would lead into issues with
|
||||
updating an existing host that already is using a duplicate IP address for
|
||||
example for round-robin (RR). Also this might lead into issues with ensuring
|
||||
a new host with several IP addresses in this case. Also to ensure a list of
|
||||
hosts with changing the IP address of one host to another in the list would
|
||||
result in issues here.
|
||||
|
||||
New example playbooks have been added:
|
||||
|
||||
playbooks/host/host-present-with-several-ip-addresses.yml
|
||||
playbooks/host/host-member-ipaddresses-absent.yml
|
||||
playbooks/host/host-member-ipaddresses-present.yml
|
||||
|
||||
A new test has been added for verification:
|
||||
|
||||
tests/host/test_host_ipaddresses.yml
|
||||
|
||||
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1783976
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1783979
|
||||
---
|
||||
README-host.md | 79 ++++-
|
||||
.../host/host-member-ipaddresses-absent.yml | 17 +
|
||||
.../host/host-member-ipaddresses-present.yml | 16 +
|
||||
...host-present-with-several-ip-addresses.yml | 24 ++
|
||||
.../module_utils/ansible_freeipa_module.py | 23 ++
|
||||
plugins/modules/ipahost.py | 179 +++++++---
|
||||
tests/host/test_host_ipaddresses.yml | 312 ++++++++++++++++++
|
||||
7 files changed, 600 insertions(+), 50 deletions(-)
|
||||
create mode 100644 playbooks/host/host-member-ipaddresses-absent.yml
|
||||
create mode 100644 playbooks/host/host-member-ipaddresses-present.yml
|
||||
create mode 100644 playbooks/host/host-present-with-several-ip-addresses.yml
|
||||
create mode 100644 tests/host/test_host_ipaddresses.yml
|
||||
|
||||
diff --git a/README-host.md b/README-host.md
|
||||
index be5ad79..ecc59a9 100644
|
||||
--- a/README-host.md
|
||||
+++ b/README-host.md
|
||||
@@ -65,6 +65,79 @@ Example playbook to ensure host presence:
|
||||
- "52:54:00:BD:97:1E"
|
||||
state: present
|
||||
```
|
||||
+Compared to `ipa host-add` command no IP address conflict check is done as the ipahost module supports to have several IPv4 and IPv6 addresses for a host.
|
||||
+
|
||||
+
|
||||
+Example playbook to ensure host presence with several IP addresses:
|
||||
+
|
||||
+```yaml
|
||||
+---
|
||||
+- name: Playbook to handle hosts
|
||||
+ hosts: ipaserver
|
||||
+ become: true
|
||||
+
|
||||
+ tasks:
|
||||
+ # Ensure host is present
|
||||
+ - ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: host01.example.com
|
||||
+ description: Example host
|
||||
+ ip_address:
|
||||
+ - 192.168.0.123
|
||||
+ - 192.168.0.124
|
||||
+ - fe80::20c:29ff:fe02:a1b3
|
||||
+ - fe80::20c:29ff:fe02:a1b4
|
||||
+ locality: Lab
|
||||
+ ns_host_location: Lab
|
||||
+ ns_os_version: CentOS 7
|
||||
+ ns_hardware_platform: Lenovo T61
|
||||
+ mac_address:
|
||||
+ - "08:00:27:E3:B1:2D"
|
||||
+ - "52:54:00:BD:97:1E"
|
||||
+ state: present
|
||||
+```
|
||||
+
|
||||
+
|
||||
+Example playbook to ensure IP addresses are present for a host:
|
||||
+
|
||||
+```yaml
|
||||
+---
|
||||
+- name: Playbook to handle hosts
|
||||
+ hosts: ipaserver
|
||||
+ become: true
|
||||
+
|
||||
+ tasks:
|
||||
+ # Ensure host is present
|
||||
+ - ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: host01.example.com
|
||||
+ ip_address:
|
||||
+ - 192.168.0.124
|
||||
+ - fe80::20c:29ff:fe02:a1b4
|
||||
+ action: member
|
||||
+ state: present
|
||||
+```
|
||||
+
|
||||
+
|
||||
+Example playbook to ensure IP addresses are absent for a host:
|
||||
+
|
||||
+```yaml
|
||||
+---
|
||||
+- name: Playbook to handle hosts
|
||||
+ hosts: ipaserver
|
||||
+ become: true
|
||||
+
|
||||
+ tasks:
|
||||
+ # Ensure host is present
|
||||
+ - ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: host01.example.com
|
||||
+ ip_address:
|
||||
+ - 192.168.0.124
|
||||
+ - fe80::20c:29ff:fe02:a1b4
|
||||
+ action: member
|
||||
+ state: absent
|
||||
+```
|
||||
|
||||
|
||||
Example playbook to ensure host presence without DNS:
|
||||
@@ -215,7 +288,7 @@ Example playbook to disable a host:
|
||||
update_dns: yes
|
||||
state: disabled
|
||||
```
|
||||
-`update_dns` controls if the DNS entries will be updated.
|
||||
+`update_dns` controls if the DNS entries will be updated in this case. For `state` present it is controlling the update of the DNS SSHFP records, but not the the other DNS records.
|
||||
|
||||
|
||||
Example playbook to ensure a host is absent:
|
||||
@@ -286,8 +359,8 @@ Variable | Description | Required
|
||||
`ok_to_auth_as_delegate` \| `ipakrboktoauthasdelegate` | The service is allowed to authenticate on behalf of a client (bool) | no
|
||||
`force` | Force host name even if not in DNS. | no
|
||||
`reverse` | Reverse DNS detection. | no
|
||||
-`ip_address` \| `ipaddress` | The host IP address. | no
|
||||
-`update_dns` | Update DNS entries. | no
|
||||
+`ip_address` \| `ipaddress` | The host IP address list. It can contain IPv4 and IPv6 addresses. No conflict check for IP addresses is done. | no
|
||||
+`update_dns` | For existing hosts: DNS SSHFP records are updated with `state` present and all DNS entries for a host removed with `state` absent. | no
|
||||
|
||||
|
||||
Return Values
|
||||
diff --git a/playbooks/host/host-member-ipaddresses-absent.yml b/playbooks/host/host-member-ipaddresses-absent.yml
|
||||
new file mode 100644
|
||||
index 0000000..2466dbd
|
||||
--- /dev/null
|
||||
+++ b/playbooks/host/host-member-ipaddresses-absent.yml
|
||||
@@ -0,0 +1,17 @@
|
||||
+---
|
||||
+- name: Host member IP addresses absent
|
||||
+ hosts: ipaserver
|
||||
+ become: true
|
||||
+
|
||||
+ tasks:
|
||||
+ - name: Ensure host01.example.com IP addresses absent
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: host01.example.com
|
||||
+ ip_address:
|
||||
+ - 192.168.0.123
|
||||
+ - fe80::20c:29ff:fe02:a1b3
|
||||
+ - 192.168.0.124
|
||||
+ - fe80::20c:29ff:fe02:a1b4
|
||||
+ action: member
|
||||
+ state: absent
|
||||
diff --git a/playbooks/host/host-member-ipaddresses-present.yml b/playbooks/host/host-member-ipaddresses-present.yml
|
||||
new file mode 100644
|
||||
index 0000000..f473993
|
||||
--- /dev/null
|
||||
+++ b/playbooks/host/host-member-ipaddresses-present.yml
|
||||
@@ -0,0 +1,16 @@
|
||||
+---
|
||||
+- name: Host member IP addresses present
|
||||
+ hosts: ipaserver
|
||||
+ become: true
|
||||
+
|
||||
+ tasks:
|
||||
+ - name: Ensure host01.example.com IP addresses present
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: host01.example.com
|
||||
+ ip_address:
|
||||
+ - 192.168.0.123
|
||||
+ - fe80::20c:29ff:fe02:a1b3
|
||||
+ - 192.168.0.124
|
||||
+ - fe80::20c:29ff:fe02:a1b4
|
||||
+ action: member
|
||||
diff --git a/playbooks/host/host-present-with-several-ip-addresses.yml b/playbooks/host/host-present-with-several-ip-addresses.yml
|
||||
new file mode 100644
|
||||
index 0000000..4956562
|
||||
--- /dev/null
|
||||
+++ b/playbooks/host/host-present-with-several-ip-addresses.yml
|
||||
@@ -0,0 +1,24 @@
|
||||
+---
|
||||
+- name: Host present with several IP addresses
|
||||
+ hosts: ipaserver
|
||||
+ become: true
|
||||
+
|
||||
+ tasks:
|
||||
+ - name: Ensure host is present
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: host01.example.com
|
||||
+ description: Example host
|
||||
+ ip_address:
|
||||
+ - 192.168.0.123
|
||||
+ - fe80::20c:29ff:fe02:a1b3
|
||||
+ - 192.168.0.124
|
||||
+ - fe80::20c:29ff:fe02:a1b4
|
||||
+ locality: Lab
|
||||
+ ns_host_location: Lab
|
||||
+ ns_os_version: CentOS 7
|
||||
+ ns_hardware_platform: Lenovo T61
|
||||
+ mac_address:
|
||||
+ - "08:00:27:E3:B1:2D"
|
||||
+ - "52:54:00:BD:97:1E"
|
||||
+ state: present
|
||||
diff --git a/plugins/module_utils/ansible_freeipa_module.py b/plugins/module_utils/ansible_freeipa_module.py
|
||||
index 9e97b88..6acdbef 100644
|
||||
--- a/plugins/module_utils/ansible_freeipa_module.py
|
||||
+++ b/plugins/module_utils/ansible_freeipa_module.py
|
||||
@@ -42,6 +42,7 @@
|
||||
from ipalib.x509 import Encoding
|
||||
except ImportError:
|
||||
from cryptography.hazmat.primitives.serialization import Encoding
|
||||
+import socket
|
||||
import base64
|
||||
import six
|
||||
|
||||
@@ -285,3 +286,25 @@ def encode_certificate(cert):
|
||||
if not six.PY2:
|
||||
encoded = encoded.decode('ascii')
|
||||
return encoded
|
||||
+
|
||||
+
|
||||
+def is_ipv4_addr(ipaddr):
|
||||
+ """
|
||||
+ Test if figen IP address is a valid IPv4 address
|
||||
+ """
|
||||
+ try:
|
||||
+ socket.inet_pton(socket.AF_INET, ipaddr)
|
||||
+ except socket.error:
|
||||
+ return False
|
||||
+ return True
|
||||
+
|
||||
+
|
||||
+def is_ipv6_addr(ipaddr):
|
||||
+ """
|
||||
+ Test if figen IP address is a valid IPv6 address
|
||||
+ """
|
||||
+ try:
|
||||
+ socket.inet_pton(socket.AF_INET6, ipaddr)
|
||||
+ except socket.error:
|
||||
+ return False
|
||||
+ return True
|
||||
diff --git a/plugins/modules/ipahost.py b/plugins/modules/ipahost.py
|
||||
index dba4181..a5fd482 100644
|
||||
--- a/plugins/modules/ipahost.py
|
||||
+++ b/plugins/modules/ipahost.py
|
||||
@@ -176,11 +176,16 @@
|
||||
default: true
|
||||
required: false
|
||||
ip_address:
|
||||
- description: The host IP address
|
||||
+ description:
|
||||
+ The host IP address list (IPv4 and IPv6). No IP address conflict
|
||||
+ check will be done.
|
||||
aliases: ["ipaddress"]
|
||||
required: false
|
||||
update_dns:
|
||||
- description: Update DNS entries
|
||||
+ description:
|
||||
+ Controls the update of the DNS SSHFP records for existing hosts and
|
||||
+ the removal of all DNS entries if a host gets removed with state
|
||||
+ absent.
|
||||
required: false
|
||||
description:
|
||||
description: The host description
|
||||
@@ -306,11 +311,16 @@
|
||||
default: true
|
||||
required: false
|
||||
ip_address:
|
||||
- description: The host IP address
|
||||
+ description:
|
||||
+ The host IP address list (IPv4 and IPv6). No IP address conflict
|
||||
+ check will be done.
|
||||
aliases: ["ipaddress"]
|
||||
required: false
|
||||
update_dns:
|
||||
- description: Update DNS entries
|
||||
+ description:
|
||||
+ Controls the update of the DNS SSHFP records for existing hosts and
|
||||
+ the removal of all DNS entries if a host gets removed with state
|
||||
+ absent.
|
||||
required: false
|
||||
update_password:
|
||||
description:
|
||||
@@ -398,7 +408,8 @@
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.ansible_freeipa_module import temp_kinit, \
|
||||
temp_kdestroy, valid_creds, api_connect, api_command, compare_args_ipa, \
|
||||
- module_params_get, gen_add_del_lists, encode_certificate, api_get_realm
|
||||
+ module_params_get, gen_add_del_lists, encode_certificate, api_get_realm, \
|
||||
+ is_ipv4_addr, is_ipv6_addr
|
||||
import six
|
||||
|
||||
|
||||
@@ -428,6 +439,32 @@ def find_host(module, name):
|
||||
return None
|
||||
|
||||
|
||||
+def find_dnsrecord(module, name):
|
||||
+ domain_name = name[name.find(".")+1:]
|
||||
+ host_name = name[:name.find(".")]
|
||||
+
|
||||
+ _args = {
|
||||
+ "all": True,
|
||||
+ "idnsname": to_text(host_name),
|
||||
+ }
|
||||
+
|
||||
+ _result = api_command(module, "dnsrecord_find", to_text(domain_name),
|
||||
+ _args)
|
||||
+
|
||||
+ if len(_result["result"]) > 1:
|
||||
+ module.fail_json(
|
||||
+ msg="There is more than one host '%s'" % (name))
|
||||
+ elif len(_result["result"]) == 1:
|
||||
+ _res = _result["result"][0]
|
||||
+ certs = _res.get("usercertificate")
|
||||
+ if certs is not None:
|
||||
+ _res["usercertificate"] = [encode_certificate(cert) for
|
||||
+ cert in certs]
|
||||
+ return _res
|
||||
+ else:
|
||||
+ return None
|
||||
+
|
||||
+
|
||||
def show_host(module, name):
|
||||
_result = api_command(module, "host_show", to_text(name), {})
|
||||
return _result["result"]
|
||||
@@ -470,16 +507,34 @@ def gen_args(description, locality, location, platform, os, password, random,
|
||||
_args["ipakrboktoauthasdelegate"] = ok_to_auth_as_delegate
|
||||
if force is not None:
|
||||
_args["force"] = force
|
||||
- if reverse is not None:
|
||||
- _args["no_reverse"] = not reverse
|
||||
if ip_address is not None:
|
||||
- _args["ip_address"] = ip_address
|
||||
+ # IP addresses are handed extra, therefore it is needed to set
|
||||
+ # the force option here to make sure that host-add is able to
|
||||
+ # add a host without IP address.
|
||||
+ _args["force"] = True
|
||||
if update_dns is not None:
|
||||
_args["updatedns"] = update_dns
|
||||
|
||||
return _args
|
||||
|
||||
|
||||
+def gen_dnsrecord_args(module, ip_address, reverse):
|
||||
+ _args = {}
|
||||
+ if reverse is not None:
|
||||
+ _args["a_extra_create_reverse"] = reverse
|
||||
+ _args["aaaa_extra_create_reverse"] = reverse
|
||||
+ if ip_address is not None:
|
||||
+ for ip in ip_address:
|
||||
+ if is_ipv4_addr(ip):
|
||||
+ _args.setdefault("arecord", []).append(ip)
|
||||
+ elif is_ipv6_addr(ip):
|
||||
+ _args.setdefault("aaaarecord", []).append(ip)
|
||||
+ else:
|
||||
+ module.fail_json(msg="'%s' is not a valid IP address." % ip)
|
||||
+
|
||||
+ return _args
|
||||
+
|
||||
+
|
||||
def check_parameters(
|
||||
module, state, action,
|
||||
description, locality, location, platform, os, password, random,
|
||||
@@ -499,8 +554,7 @@ def check_parameters(
|
||||
"os", "password", "random", "mac_address", "sshpubkey",
|
||||
"userclass", "auth_ind", "requires_pre_auth",
|
||||
"ok_as_delegate", "ok_to_auth_as_delegate", "force",
|
||||
- "reverse", "ip_address", "update_dns",
|
||||
- "update_password"]
|
||||
+ "reverse", "update_dns", "update_password"]
|
||||
for x in invalid:
|
||||
if vars()[x] is not None:
|
||||
module.fail_json(
|
||||
@@ -512,7 +566,7 @@ def check_parameters(
|
||||
"password", "random", "mac_address", "sshpubkey",
|
||||
"userclass", "auth_ind", "requires_pre_auth",
|
||||
"ok_as_delegate", "ok_to_auth_as_delegate", "force",
|
||||
- "reverse", "ip_address", "update_password"]
|
||||
+ "reverse", "update_password"]
|
||||
for x in invalid:
|
||||
if vars()[x] is not None:
|
||||
module.fail_json(
|
||||
@@ -549,9 +603,6 @@ def main():
|
||||
default=None, no_log=True),
|
||||
random=dict(type="bool", aliases=["random_password"],
|
||||
default=None),
|
||||
-
|
||||
-
|
||||
-
|
||||
certificate=dict(type="list", aliases=["usercertificate"],
|
||||
default=None),
|
||||
managedby_host=dict(type="list",
|
||||
@@ -608,7 +659,7 @@ def main():
|
||||
default=None),
|
||||
force=dict(type='bool', default=None),
|
||||
reverse=dict(type='bool', default=None),
|
||||
- ip_address=dict(type="str", aliases=["ipaddress"],
|
||||
+ ip_address=dict(type="list", aliases=["ipaddress"],
|
||||
default=None),
|
||||
update_dns=dict(type="bool", aliases=["updatedns"],
|
||||
default=None),
|
||||
@@ -820,6 +871,7 @@ def main():
|
||||
|
||||
# Make sure host exists
|
||||
res_find = find_host(ansible_module, name)
|
||||
+ res_find_dnsrecord = find_dnsrecord(ansible_module, name)
|
||||
|
||||
# Create command
|
||||
if state == "present":
|
||||
@@ -829,6 +881,8 @@ def main():
|
||||
random, mac_address, sshpubkey, userclass, auth_ind,
|
||||
requires_pre_auth, ok_as_delegate, ok_to_auth_as_delegate,
|
||||
force, reverse, ip_address, update_dns)
|
||||
+ dnsrecord_args = gen_dnsrecord_args(
|
||||
+ ansible_module, ip_address, reverse)
|
||||
|
||||
if action == "host":
|
||||
# Found the host
|
||||
@@ -938,39 +992,20 @@ def main():
|
||||
res_find.get(
|
||||
"ipaallowedtoperform_read_keys_hostgroup"))
|
||||
|
||||
- else:
|
||||
- certificate_add = certificate or []
|
||||
- certificate_del = []
|
||||
- managedby_host_add = managedby_host or []
|
||||
- managedby_host_del = []
|
||||
- principal_add = principal or []
|
||||
- principal_del = []
|
||||
- allow_create_keytab_user_add = \
|
||||
- allow_create_keytab_user or []
|
||||
- allow_create_keytab_user_del = []
|
||||
- allow_create_keytab_group_add = \
|
||||
- allow_create_keytab_group or []
|
||||
- allow_create_keytab_group_del = []
|
||||
- allow_create_keytab_host_add = \
|
||||
- allow_create_keytab_host or []
|
||||
- allow_create_keytab_host_del = []
|
||||
- allow_create_keytab_hostgroup_add = \
|
||||
- allow_create_keytab_hostgroup or []
|
||||
- allow_create_keytab_hostgroup_del = []
|
||||
- allow_retrieve_keytab_user_add = \
|
||||
- allow_retrieve_keytab_user or []
|
||||
- allow_retrieve_keytab_user_del = []
|
||||
- allow_retrieve_keytab_group_add = \
|
||||
- allow_retrieve_keytab_group or []
|
||||
- allow_retrieve_keytab_group_del = []
|
||||
- allow_retrieve_keytab_host_add = \
|
||||
- allow_retrieve_keytab_host or []
|
||||
- allow_retrieve_keytab_host_del = []
|
||||
- allow_retrieve_keytab_hostgroup_add = \
|
||||
- allow_retrieve_keytab_hostgroup or []
|
||||
- allow_retrieve_keytab_hostgroup_del = []
|
||||
+ # IP addresses are not really a member of hosts, but
|
||||
+ # we will simply treat it as this to enable the
|
||||
+ # addition and removal of IPv4 and IPv6 addresses in
|
||||
+ # a simple way.
|
||||
+ _dnsrec = res_find_dnsrecord or {}
|
||||
+ dnsrecord_a_add, dnsrecord_a_del = gen_add_del_lists(
|
||||
+ dnsrecord_args.get("arecord"),
|
||||
+ _dnsrec.get("arecord"))
|
||||
+ dnsrecord_aaaa_add, dnsrecord_aaaa_del = \
|
||||
+ gen_add_del_lists(
|
||||
+ dnsrecord_args.get("aaaarecord"),
|
||||
+ _dnsrec.get("aaaarecord"))
|
||||
|
||||
- else:
|
||||
+ if action != "host" or (action == "host" and res_find is None):
|
||||
certificate_add = certificate or []
|
||||
certificate_del = []
|
||||
managedby_host_add = managedby_host or []
|
||||
@@ -1001,6 +1036,10 @@ def main():
|
||||
allow_retrieve_keytab_hostgroup_add = \
|
||||
allow_retrieve_keytab_hostgroup or []
|
||||
allow_retrieve_keytab_hostgroup_del = []
|
||||
+ dnsrecord_a_add = dnsrecord_args.get("arecord") or []
|
||||
+ dnsrecord_a_del = []
|
||||
+ dnsrecord_aaaa_add = dnsrecord_args.get("aaaarecord") or []
|
||||
+ dnsrecord_aaaa_del = []
|
||||
|
||||
# Remove canonical principal from principal_del
|
||||
canonical_principal = "host/" + name + "@" + server_realm
|
||||
@@ -1135,6 +1174,36 @@ def main():
|
||||
"hostgroup": allow_retrieve_keytab_hostgroup_del,
|
||||
}])
|
||||
|
||||
+ if len(dnsrecord_a_add) > 0 or len(dnsrecord_aaaa_add) > 0:
|
||||
+ domain_name = name[name.find(".")+1:]
|
||||
+ host_name = name[:name.find(".")]
|
||||
+
|
||||
+ commands.append([domain_name,
|
||||
+ "dnsrecord_add",
|
||||
+ {
|
||||
+ "idnsname": host_name,
|
||||
+ "arecord": dnsrecord_a_add,
|
||||
+ "a_extra_create_reverse": reverse,
|
||||
+ "aaaarecord": dnsrecord_aaaa_add,
|
||||
+ "aaaa_extra_create_reverse": reverse
|
||||
+ }])
|
||||
+
|
||||
+ if len(dnsrecord_a_del) > 0 or len(dnsrecord_aaaa_del) > 0:
|
||||
+ domain_name = name[name.find(".")+1:]
|
||||
+ host_name = name[:name.find(".")]
|
||||
+
|
||||
+ # There seems to be an issue with dnsrecord_del (not
|
||||
+ # for dnsrecord_add) if aaaarecord is an empty list.
|
||||
+ # Therefore this is done differently here:
|
||||
+ _args = {"idnsname": host_name}
|
||||
+ if len(dnsrecord_a_del) > 0:
|
||||
+ _args["arecord"] = dnsrecord_a_del
|
||||
+ if len(dnsrecord_aaaa_del) > 0:
|
||||
+ _args["aaaarecord"] = dnsrecord_aaaa_del
|
||||
+
|
||||
+ commands.append([domain_name,
|
||||
+ "dnsrecord_del", _args])
|
||||
+
|
||||
elif state == "absent":
|
||||
if action == "host":
|
||||
|
||||
@@ -1215,6 +1284,17 @@ def main():
|
||||
"hostgroup": allow_retrieve_keytab_hostgroup,
|
||||
}])
|
||||
|
||||
+ dnsrecord_args = gen_dnsrecord_args(ansible_module,
|
||||
+ ip_address, reverse)
|
||||
+ if "arecord" in dnsrecord_args or \
|
||||
+ "aaaarecord" in dnsrecord_args:
|
||||
+ domain_name = name[name.find(".")+1:]
|
||||
+ host_name = name[:name.find(".")]
|
||||
+ dnsrecord_args["idnsname"] = host_name
|
||||
+
|
||||
+ commands.append([domain_name, "dnsrecord_del",
|
||||
+ dnsrecord_args])
|
||||
+
|
||||
elif state == "disabled":
|
||||
if res_find is not None:
|
||||
commands.append([name, "host_disable", {}])
|
||||
@@ -1259,6 +1339,11 @@ def main():
|
||||
# Host is already disabled, ignore error
|
||||
if "This entry is already disabled" in msg:
|
||||
continue
|
||||
+
|
||||
+ # Ignore no modification error.
|
||||
+ if "no modifications to be performed" in msg:
|
||||
+ continue
|
||||
+
|
||||
ansible_module.fail_json(msg="%s: %s: %s" % (command, name,
|
||||
msg))
|
||||
|
||||
diff --git a/tests/host/test_host_ipaddresses.yml b/tests/host/test_host_ipaddresses.yml
|
||||
new file mode 100644
|
||||
index 0000000..0a97dd5
|
||||
--- /dev/null
|
||||
+++ b/tests/host/test_host_ipaddresses.yml
|
||||
@@ -0,0 +1,312 @@
|
||||
+---
|
||||
+- name: Test host IP addresses
|
||||
+ hosts: ipaserver
|
||||
+ become: true
|
||||
+
|
||||
+ tasks:
|
||||
+ - name: Get Domain from server name
|
||||
+ set_fact:
|
||||
+ ipaserver_domain: "{{ groups.ipaserver[0].split('.')[1:] | join ('.') }}"
|
||||
+ when: ipaserver_domain is not defined
|
||||
+
|
||||
+ - name: Set host1_fqdn .. host6_fqdn
|
||||
+ set_fact:
|
||||
+ host1_fqdn: "{{ 'host1.' + ipaserver_domain }}"
|
||||
+ host2_fqdn: "{{ 'host2.' + ipaserver_domain }}"
|
||||
+ host3_fqdn: "{{ 'host3.' + ipaserver_domain }}"
|
||||
+
|
||||
+ - name: Get IPv4 address prefix from server node
|
||||
+ set_fact:
|
||||
+ ipv4_prefix: "{{ ansible_default_ipv4.address.split('.')[:-1] |
|
||||
+ join('.') }}"
|
||||
+
|
||||
+ - name: Host absent
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name:
|
||||
+ - "{{ host1_fqdn }}"
|
||||
+ - "{{ host2_fqdn }}"
|
||||
+ - "{{ host3_fqdn }}"
|
||||
+ update_dns: yes
|
||||
+ state: absent
|
||||
+
|
||||
+ - name: Host "{{ host1_fqdn }}" present
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: "{{ host1_fqdn }}"
|
||||
+ ip_address:
|
||||
+ - "{{ ipv4_prefix + '.201' }}"
|
||||
+ - fe80::20c:29ff:fe02:a1b2
|
||||
+ update_dns: yes
|
||||
+ reverse: no
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
+ - name: Host "{{ host1_fqdn }}" present again
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: "{{ host1_fqdn }}"
|
||||
+ ip_address:
|
||||
+ - "{{ ipv4_prefix + '.201' }}"
|
||||
+ - fe80::20c:29ff:fe02:a1b2
|
||||
+ update_dns: yes
|
||||
+ reverse: no
|
||||
+ register: result
|
||||
+ failed_when: result.changed
|
||||
+
|
||||
+ - name: Host "{{ host1_fqdn }}" present again with new IP address
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: "{{ host1_fqdn }}"
|
||||
+ ip_address:
|
||||
+ - "{{ ipv4_prefix + '.211' }}"
|
||||
+ - fe80::20c:29ff:fe02:a1b3
|
||||
+ - "{{ ipv4_prefix + '.221' }}"
|
||||
+ - fe80::20c:29ff:fe02:a1b4
|
||||
+ update_dns: yes
|
||||
+ reverse: no
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
+ - name: Host "{{ host1_fqdn }}" present again with new IP address again
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: "{{ host1_fqdn }}"
|
||||
+ ip_address:
|
||||
+ - "{{ ipv4_prefix + '.211' }}"
|
||||
+ - fe80::20c:29ff:fe02:a1b3
|
||||
+ - "{{ ipv4_prefix + '.221' }}"
|
||||
+ - fe80::20c:29ff:fe02:a1b4
|
||||
+ update_dns: yes
|
||||
+ reverse: no
|
||||
+ register: result
|
||||
+ failed_when: result.changed
|
||||
+
|
||||
+ - name: Host "{{ host1_fqdn }}" member IPv4 address present
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: "{{ host1_fqdn }}"
|
||||
+ ip_address: "{{ ipv4_prefix + '.201' }}"
|
||||
+ action: member
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
+ - name: Host "{{ host1_fqdn }}" member IPv4 address present again
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: "{{ host1_fqdn }}"
|
||||
+ ip_address: "{{ ipv4_prefix + '.201' }}"
|
||||
+ action: member
|
||||
+ register: result
|
||||
+ failed_when: result.changed
|
||||
+
|
||||
+ - name: Host "{{ host1_fqdn }}" member IPv4 address absent
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: "{{ host1_fqdn }}"
|
||||
+ ip_address: "{{ ipv4_prefix + '.201' }}"
|
||||
+ action: member
|
||||
+ state: absent
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
+ - name: Host "{{ host1_fqdn }}" member IPv4 address absent again
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: "{{ host1_fqdn }}"
|
||||
+ ip_address: "{{ ipv4_prefix + '.201' }}"
|
||||
+ action: member
|
||||
+ state: absent
|
||||
+ register: result
|
||||
+ failed_when: result.changed
|
||||
+
|
||||
+ - name: Host "{{ host1_fqdn }}" member IPv6 address present
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: "{{ host1_fqdn }}"
|
||||
+ ip_address: fe80::20c:29ff:fe02:a1b2
|
||||
+ action: member
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
+ - name: Host "{{ host1_fqdn }}" member IPv6 address present again
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: "{{ host1_fqdn }}"
|
||||
+ ip_address: fe80::20c:29ff:fe02:a1b2
|
||||
+ action: member
|
||||
+ register: result
|
||||
+ failed_when: result.changed
|
||||
+
|
||||
+ - name: Host "{{ host1_fqdn }}" member IPv6 address absent
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: "{{ host1_fqdn }}"
|
||||
+ ip_address: fe80::20c:29ff:fe02:a1b2
|
||||
+ action: member
|
||||
+ state: absent
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
+ - name: Host "{{ host1_fqdn }}" member IPv6 address absent again
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: "{{ host1_fqdn }}"
|
||||
+ ip_address: fe80::20c:29ff:fe02:a1b2
|
||||
+ action: member
|
||||
+ state: absent
|
||||
+ register: result
|
||||
+
|
||||
+ - name: Host "{{ host1_fqdn }}" member all ip-addresses absent
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: "{{ host1_fqdn }}"
|
||||
+ ip_address:
|
||||
+ - "{{ ipv4_prefix + '.211' }}"
|
||||
+ - fe80::20c:29ff:fe02:a1b3
|
||||
+ - "{{ ipv4_prefix + '.221' }}"
|
||||
+ - fe80::20c:29ff:fe02:a1b4
|
||||
+ action: member
|
||||
+ state: absent
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
+ - name: Host "{{ host1_fqdn }}" all member ip-addresses absent again
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name: "{{ host1_fqdn }}"
|
||||
+ ip_address:
|
||||
+ - "{{ ipv4_prefix + '.211' }}"
|
||||
+ - fe80::20c:29ff:fe02:a1b3
|
||||
+ - "{{ ipv4_prefix + '.221' }}"
|
||||
+ - fe80::20c:29ff:fe02:a1b4
|
||||
+ action: member
|
||||
+ state: absent
|
||||
+ register: result
|
||||
+ failed_when: result.changed
|
||||
+
|
||||
+ - name: Hosts "{{ host1_fqdn }}" and "{{ host2_fqdn }}" present with same IP addresses
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ hosts:
|
||||
+ - name: "{{ host1_fqdn }}"
|
||||
+ ip_address:
|
||||
+ - "{{ ipv4_prefix + '.211' }}"
|
||||
+ - fe80::20c:29ff:fe02:a1b3
|
||||
+ - "{{ ipv4_prefix + '.221' }}"
|
||||
+ - fe80::20c:29ff:fe02:a1b4
|
||||
+ - name: "{{ host2_fqdn }}"
|
||||
+ ip_address:
|
||||
+ - "{{ ipv4_prefix + '.211' }}"
|
||||
+ - fe80::20c:29ff:fe02:a1b3
|
||||
+ - "{{ ipv4_prefix + '.221' }}"
|
||||
+ - fe80::20c:29ff:fe02:a1b4
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
+ - name: Hosts "{{ host1_fqdn }}" and "{{ host2_fqdn }}" present with same IP addresses again
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ hosts:
|
||||
+ - name: "{{ host1_fqdn }}"
|
||||
+ ip_address:
|
||||
+ - "{{ ipv4_prefix + '.211' }}"
|
||||
+ - fe80::20c:29ff:fe02:a1b3
|
||||
+ - "{{ ipv4_prefix + '.221' }}"
|
||||
+ - fe80::20c:29ff:fe02:a1b4
|
||||
+ - name: "{{ host2_fqdn }}"
|
||||
+ ip_address:
|
||||
+ - "{{ ipv4_prefix + '.211' }}"
|
||||
+ - fe80::20c:29ff:fe02:a1b3
|
||||
+ - "{{ ipv4_prefix + '.221' }}"
|
||||
+ - fe80::20c:29ff:fe02:a1b4
|
||||
+ register: result
|
||||
+ failed_when: result.changed
|
||||
+
|
||||
+ - name: Hosts "{{ host3_fqdn }}" present with same IP addresses
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ hosts:
|
||||
+ - name: "{{ host3_fqdn }}"
|
||||
+ ip_address:
|
||||
+ - "{{ ipv4_prefix + '.211' }}"
|
||||
+ - fe80::20c:29ff:fe02:a1b3
|
||||
+ - "{{ ipv4_prefix + '.221' }}"
|
||||
+ - fe80::20c:29ff:fe02:a1b4
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
+ - name: Hosts "{{ host3_fqdn }}" present with same IP addresses again
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ hosts:
|
||||
+ - name: "{{ host3_fqdn }}"
|
||||
+ ip_address:
|
||||
+ - "{{ ipv4_prefix + '.211' }}"
|
||||
+ - fe80::20c:29ff:fe02:a1b3
|
||||
+ - "{{ ipv4_prefix + '.221' }}"
|
||||
+ - fe80::20c:29ff:fe02:a1b4
|
||||
+ register: result
|
||||
+ failed_when: result.changed
|
||||
+
|
||||
+ - name: Host "{{ host3_fqdn }}" present with differnt IP addresses
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ hosts:
|
||||
+ - name: "{{ host3_fqdn }}"
|
||||
+ ip_address:
|
||||
+ - "{{ ipv4_prefix + '.111' }}"
|
||||
+ - fe80::20c:29ff:fe02:a1b1
|
||||
+ - "{{ ipv4_prefix + '.121' }}"
|
||||
+ - fe80::20c:29ff:fe02:a1b2
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
+ - name: Host "{{ host3_fqdn }}" present with different IP addresses again
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ hosts:
|
||||
+ - name: "{{ host3_fqdn }}"
|
||||
+ ip_address:
|
||||
+ - "{{ ipv4_prefix + '.111' }}"
|
||||
+ - fe80::20c:29ff:fe02:a1b1
|
||||
+ - "{{ ipv4_prefix + '.121' }}"
|
||||
+ - fe80::20c:29ff:fe02:a1b2
|
||||
+ register: result
|
||||
+ failed_when: result.changed
|
||||
+
|
||||
+ - name: Host "{{ host3_fqdn }}" present with old IP addresses
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ hosts:
|
||||
+ - name: "{{ host3_fqdn }}"
|
||||
+ ip_address:
|
||||
+ - "{{ ipv4_prefix + '.211' }}"
|
||||
+ - fe80::20c:29ff:fe02:a1b3
|
||||
+ - "{{ ipv4_prefix + '.221' }}"
|
||||
+ - fe80::20c:29ff:fe02:a1b4
|
||||
+ register: result
|
||||
+ failed_when: not result.changed
|
||||
+
|
||||
+ - name: Host "{{ host3_fqdn }}" present with old IP addresses again
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ hosts:
|
||||
+ - name: "{{ host3_fqdn }}"
|
||||
+ ip_address:
|
||||
+ - "{{ ipv4_prefix + '.211' }}"
|
||||
+ - fe80::20c:29ff:fe02:a1b3
|
||||
+ - "{{ ipv4_prefix + '.221' }}"
|
||||
+ - fe80::20c:29ff:fe02:a1b4
|
||||
+ register: result
|
||||
+ failed_when: result.changed
|
||||
+
|
||||
+ - name: Host absent
|
||||
+ ipahost:
|
||||
+ ipaadmin_password: MyPassword123
|
||||
+ name:
|
||||
+ - "{{ host1_fqdn }}"
|
||||
+ - "{{ host2_fqdn }}"
|
||||
+ - "{{ host3_fqdn }}"
|
||||
+ update_dns: yes
|
||||
+ state: absent
|
||||
From 8f32cb04c1e161e1e3217f10413685a2cc9bf492 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Woerner <twoerner@redhat.com>
|
||||
Date: Thu, 13 Feb 2020 14:10:38 +0100
|
||||
Subject: [PATCH] tests/host/test_host: Fix use of wrong host in the host5 test
|
||||
|
||||
host1 was used instead of host5 in the repeated host5 test. This lead to an
|
||||
error with the new IP address handling in ipahost. It was correctly
|
||||
reporting a change for host1 which resulted in a failed test.
|
||||
---
|
||||
tests/host/test_host.yml | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tests/host/test_host.yml b/tests/host/test_host.yml
|
||||
index 1a555a1..f3ec11d 100644
|
||||
--- a/tests/host/test_host.yml
|
||||
+++ b/tests/host/test_host.yml
|
||||
@@ -129,7 +129,7 @@
|
||||
- name: Host "{{ host5_fqdn }}" present again
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
- name: "{{ host1_fqdn }}"
|
||||
+ name: "{{ host5_fqdn }}"
|
||||
ip_address: "{{ ipv4_prefix + '.205' }}"
|
||||
update_dns: yes
|
||||
reverse: no
|
@ -5,22 +5,28 @@
|
||||
|
||||
Summary: Roles and playbooks to deploy FreeIPA servers, replicas and clients
|
||||
Name: ansible-freeipa
|
||||
Version: 0.1.6
|
||||
Release: 4%{?dist}
|
||||
Version: 0.1.8
|
||||
Release: 3%{?dist}
|
||||
URL: https://github.com/freeipa/ansible-freeipa
|
||||
License: GPLv3+
|
||||
Source: https://github.com/freeipa/ansible-freeipa/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz
|
||||
Patch1: ansible-freeipa-0.1.6-gen_module_docs-drop-key-dirserv_cert_files.patch
|
||||
Patch2: ansible-freeipa-0.1.6-ipatopologysegment-command-suffix-e4497c18_rhbz#1733547.patch
|
||||
Patch3: ansible-freeipa-0.1.6-ipatopologysegment-reinitialized-c212b435_rhbz#1733559.patch
|
||||
Patch4: ansible-freeipa-0.1.6-ansible_ipa_client_Drop_import_of_configure_nsswitch_database_rhbz#1748905.patch
|
||||
Patch1: ansible-freeipa-0.1.8-ipahost-Fix-choices-of-auth_ind-parameter-allow-to-reset-parameter_rhbz#1783992.patch
|
||||
Patch2: ansible-freeipa-0.1.8-ipauser-Allow-reset-of-userauthtype-do-not-depend-on-first-last-for-mod_rhbz#1784474.patch
|
||||
Patch3: ansible-freeipa-0.1.8-ipahost-Enhanced-failure-msg-for-member-params-used-without-member-action_rhbz#1783948.patch
|
||||
Patch4: ansible-freeipa-0.1.8-Add-missing-attributes-to-ipasudorule_rhbz#1788168,1788035,1788024.patch
|
||||
Patch5: ansible-freeipa-0.1.8-ipapwpolicy-Use-global_policy-if-name-is-not-set_rhbz#1797532.patch
|
||||
Patch6: ansible-freeipa-0.1.8-ipahbacrule-Fix-handing-of-members-with-action-hbacrule_rhbz#1787996.patch
|
||||
Patch7: ansible-freeipa-0.1.8-ansible_freeipa_module-Fix-comparison-of-bool-parameters-in-compare_args_ipa_rhbz#1784514.patch
|
||||
Patch8: ansible-freeipa-ipahost-Add-support-for-several-IP-addresses-and-also-to-change-them_rhbz#1783979,1783976.patch
|
||||
Patch9: ansible-freeipa-0.1.8-ipahost-Fail-on-action-member-for-new-hosts-fix-dnsrecord_add-reverse-flag_rhbz#1803026.patch
|
||||
Patch10: ansible-freeipa-0.1.8-ipahost-Do-not-fail-on-missing-DNS-or-zone-when-no-IP-address-given_rhbz#1804838.patch
|
||||
BuildArch: noarch
|
||||
|
||||
#Requires: ansible
|
||||
|
||||
%description
|
||||
ansible-freeipa provides Ansible roles and playbooks to install and uninstall
|
||||
FreeIPA servers, replicas and clients.
|
||||
FreeIPA servers, replicas and clients also modules for management.
|
||||
|
||||
Note: The ansible playbooks and roles require a configured ansible environment
|
||||
where the ansible nodes are reachable and are properly set up to have an IP
|
||||
@ -32,6 +38,18 @@ Features
|
||||
- Cluster deployments: Server, replicas and clients in one playbook
|
||||
- One-time-password (OTP) support for client installation
|
||||
- Repair mode for clients
|
||||
- Modules for group management
|
||||
- Modules for hbacrule management
|
||||
- Modules for hbacsvc management
|
||||
- Modules for hbacsvcgroup management
|
||||
- Modules for host management
|
||||
- Modules for hostgroup management
|
||||
- Modules for pwpolicy management
|
||||
- Modules for sudocmd management
|
||||
- Modules for sudocmdgroup management
|
||||
- Modules for sudorule management
|
||||
- Modules for topology management
|
||||
- Modules for user management
|
||||
|
||||
Supported FreeIPA Versions
|
||||
|
||||
@ -46,13 +64,16 @@ Supported Distributions
|
||||
- RHEL/CentOS 7.4+
|
||||
- Fedora 26+
|
||||
- Ubuntu
|
||||
- Debian 10+ (ipaclient only, no server or replica!)
|
||||
|
||||
Requirements
|
||||
|
||||
Controller
|
||||
- Ansible version: 2.5+
|
||||
- Ansible version: 2.8+ (ansible-freeipa is an Ansible Collection)
|
||||
- /usr/bin/kinit is required on the controller if a one time password (OTP)
|
||||
is used
|
||||
- python3-gssapi is required on the controller if a one time password (OTP)
|
||||
is used to install the client.
|
||||
is used with keytab to install the client.
|
||||
|
||||
Node
|
||||
- Supported FreeIPA version (see above)
|
||||
@ -73,6 +94,12 @@ or clients in one playbook.
|
||||
%patch2 -p1
|
||||
%patch3 -p1
|
||||
%patch4 -p1
|
||||
%patch5 -p1
|
||||
%patch6 -p1
|
||||
%patch7 -p1
|
||||
%patch8 -p1
|
||||
%patch9 -p1
|
||||
%patch10 -p1
|
||||
# Fix python modules and module utils:
|
||||
# - Remove shebang
|
||||
# - Remove execute flag
|
||||
@ -104,13 +131,103 @@ cp -rp plugins/* %{buildroot}%{_datadir}/ansible/plugins/
|
||||
%{_datadir}/ansible/plugins/module_utils
|
||||
%{_datadir}/ansible/plugins/modules
|
||||
%doc README.md
|
||||
%doc README-topology.md
|
||||
%doc README-server.md
|
||||
%doc README-replica.md
|
||||
%doc README-client.md
|
||||
%doc README-*.md
|
||||
%doc playbooks
|
||||
|
||||
%changelog
|
||||
* Thu Feb 20 2020 Thomas Woerner <twoerner@redhat.com> - 0.1.8-3
|
||||
- ipahost: Do not fail on missing DNS or zone when no IP address given
|
||||
Resolves: RHBZ#1804838
|
||||
|
||||
* Fri Feb 14 2020 Thomas Woerner <twoerner@redhat.com> - 0.1.8-2
|
||||
- Updated RPM description for ansible-freeipa 0.1.8
|
||||
Related: RHBZ#1748986
|
||||
- ipahost: Fix choices of auth_ind parameter, allow to reset parameter
|
||||
Resolves: RHBZ#1783992
|
||||
- ipauser: Allow reset of userauthtype, do not depend on first,last for mod
|
||||
Resolves: RHBZ#1784474
|
||||
- ipahost: Enhanced failure msg for member params used without member action
|
||||
Resolves: RHBZ#1783948
|
||||
- Add missing attributes to ipasudorule
|
||||
Resolves: RHBZ#1788168
|
||||
Resolves: RHBZ#1788035
|
||||
Resolves: RHBZ#1788024
|
||||
- ipapwpolicy: Use global_policy if name is not set
|
||||
Resolves: RHBZ#1797532
|
||||
- ipahbacrule: Fix handing of members with action hbacrule
|
||||
Resolves: RHBZ#1787996
|
||||
- ansible_freeipa_module: Fix comparison of bool parameters in compare_args_isa
|
||||
Resolves: RHBZ#1784514
|
||||
- ipahost: Add support for several IP addresses and also to change them
|
||||
Resolves: RHBZ#1783979
|
||||
Resolves: RHBZ#1783976
|
||||
- ipahost: Fail on action member for new hosts, fix dnsrecord_add reverse flag
|
||||
Resolves: RHBZ#1803026
|
||||
|
||||
* Sat Dec 14 2019 Thomas Woerner <twoerner@redhat.com> - 0.1.8-1
|
||||
- Update to version 0.1.8 (bug fix release)
|
||||
- roles/ipaclient/README.md: Add information about ipaclient_otp
|
||||
- Install and enable firewalld if it is configured for ipaserver and
|
||||
ipareplica roles
|
||||
- ipaserver_test: Do not use zone_overlap_check for domain name validation
|
||||
- Allow execution of API commands that do not require a name
|
||||
- Update README-host: Drop options from allow_*keytab parameters docs
|
||||
- ipauser: Extend email addresses with default email domain if no domain is
|
||||
given
|
||||
Resolves: RHBZ#1747413
|
||||
Related: RHBZ#1748986
|
||||
|
||||
* Mon Dec 2 2019 Thomas Woerner <twoerner@redhat.com> - 0.1.7-1
|
||||
- Update to version 0.1.7
|
||||
- Add debian support for ipaclient
|
||||
- Added support for predefining client OTP using ipaclient_otp
|
||||
- ipatopologysegment: Store suffix for commands in command list
|
||||
- ipatopologysegment: Fail for missing entry with reinitialized
|
||||
- Utils scripts: ansible-ipa-[server,replica,client]-install
|
||||
- ipaserver_test,ipareplica_prepare: Do not return _pkcs12_file settings
|
||||
- ansible_freeipa_module: Add support for GSSAPI
|
||||
- ansible_ipa_client: Drop import of configure_nsswitch_database
|
||||
- New host management module
|
||||
- New hostgroup management module
|
||||
- ipagroup: Remove unused member_[present,absent] states
|
||||
- external-ca tests: Fix typo in inventory files
|
||||
- tests/external-signed-ca tests: Fix external-ca.sh to use proper serials
|
||||
- ipagroup: Rework to use same mechanisms as ipahostgroup module
|
||||
- ansible_freeipa_module: api_command should not have extra try clause
|
||||
- ansible_freeipa_module: compare_args_ipa needs to compare lists orderless
|
||||
- ansible_freeipa_module: New function api_check_param
|
||||
- ansible_freeipa_module: New functions module_params_get and _afm_convert
|
||||
- ansible_freeipa_module: Add missing to_text import for _afm_convert
|
||||
- ansible_freeipa_module: Convert tuple to list in compare_args_ipa
|
||||
- ansible_freeipa_module: New function api_get_realm
|
||||
- ipauser: User module extension
|
||||
- New sudocmd management module
|
||||
- New sudocmdgroup management module
|
||||
- ansible_freeipa_module: Convert int to string in compare_args_ipa
|
||||
- New pwpolicy management module
|
||||
- New hbacsvc (HBAC Service) management module
|
||||
- New hbacsvcgroup (HBAC Service Group) management module
|
||||
- ipagroup: Properly support IPA versions 4.6 and RHEL-7
|
||||
- ipagroup: Fix changed flag, new test cases
|
||||
- ipauser: Add info about version limitation of passwordexpiration
|
||||
- New hbacrule (HBAC Rule) management module
|
||||
- ipahostgroup: Fix changed flag, support IPA 4.6 on RHEL-7, new test cases
|
||||
- New sudorule (Sudo Rule) management module
|
||||
- ipauser: Support 'sn' alias of 'last' for surname
|
||||
- Update galaxy.yml: Update description, drop empty dependencies
|
||||
- Update ipauser.py: Fix typo in users.name description
|
||||
- ipaclient: Fix misspelled sssd options
|
||||
- ipauser: Return generated random password
|
||||
- ipahost: Return generated random password
|
||||
- Added context configuration to api_connect
|
||||
- ansible_freeipa_module: Better support for KRB5CCNAME environment variable
|
||||
- ipa[server,replica,client]: Add support for CentOS-8
|
||||
- ipahost: Extension to be able handle several hosts and all settings
|
||||
- Flake8 fixes
|
||||
- Documentation updates
|
||||
- Cleanup
|
||||
Resolves: RHBZ#1748986
|
||||
|
||||
* Fri Sep 6 2019 Thomas Woerner <twoerner@redhat.com> - 0.1.6-4
|
||||
- ansible_ipa_client: Drop import of configure_nsswitch_database
|
||||
(RHBZ#1748905)
|
||||
|
Loading…
Reference in New Issue
Block a user