mirror of
https://github.com/freeipa/ansible-freeipa.git
synced 2026-07-31 03:44:41 +00:00
Merge pull request #290 from rjeffman/fix_service_module
Fix service module
This commit is contained in:
@@ -310,6 +310,7 @@ Variable | Description | Required
|
|||||||
`allow_retrieve_keytab_group` \| `ipaallowedtoperform_read_keys_group` | Groups allowed to retrieve a keytab of this host. | no
|
`allow_retrieve_keytab_group` \| `ipaallowedtoperform_read_keys_group` | Groups allowed to retrieve a keytab of this host. | no
|
||||||
`allow_retrieve_keytab_host` \| `ipaallowedtoperform_read_keys_host` | Hosts allowed to retrieve a keytab from of host. | no
|
`allow_retrieve_keytab_host` \| `ipaallowedtoperform_read_keys_host` | Hosts allowed to retrieve a keytab from of host. | no
|
||||||
`allow_retrieve_keytab_hostgroup` \| `ipaallowedtoperform_read_keys_hostgroup` | Host groups allowed to retrieve a keytab of this host. | no
|
`allow_retrieve_keytab_hostgroup` \| `ipaallowedtoperform_read_keys_hostgroup` | Host groups allowed to retrieve a keytab of this host. | no
|
||||||
|
`continue` | Continuous mode: don't stop on errors. Valid only if `state` is `absent`. Default: `no` (bool) | no
|
||||||
`action` | Work on service or member level. It can be on of `member` or `service` and defaults to `service`. | no
|
`action` | Work on service or member level. It can be on of `member` or `service` and defaults to `service`. | no
|
||||||
`state` | The state to ensure. It can be one of `present`, `absent`, or `disabled`, default: `present`. | no
|
`state` | The state to ensure. It can be one of `present`, `absent`, or `disabled`, default: `present`. | no
|
||||||
|
|
||||||
|
|||||||
@@ -90,6 +90,14 @@ options:
|
|||||||
required: false
|
required: false
|
||||||
type: list
|
type: list
|
||||||
aliases: ["krbprincipalname"]
|
aliases: ["krbprincipalname"]
|
||||||
|
smb:
|
||||||
|
description: Add a SMB service. Can only be used with new services.
|
||||||
|
required: false
|
||||||
|
type: bool
|
||||||
|
netbiosname:
|
||||||
|
description: NETBIOS name for the SMB service.
|
||||||
|
required: false
|
||||||
|
type: str
|
||||||
host:
|
host:
|
||||||
description: Host that can manage the service.
|
description: Host that can manage the service.
|
||||||
required: false
|
required: false
|
||||||
@@ -135,6 +143,12 @@ options:
|
|||||||
required: false
|
required: false
|
||||||
type: list
|
type: list
|
||||||
aliases: ["ipaallowedtoperform_read_keys_hostgroup"]
|
aliases: ["ipaallowedtoperform_read_keys_hostgroup"]
|
||||||
|
continue:
|
||||||
|
description:
|
||||||
|
Continuous mode. Don't stop on errors. Valid only if `state` is `absent`.
|
||||||
|
required: false
|
||||||
|
default: True
|
||||||
|
type: bool
|
||||||
action:
|
action:
|
||||||
description: Work on service or member level
|
description: Work on service or member level
|
||||||
default: service
|
default: service
|
||||||
@@ -142,7 +156,7 @@ options:
|
|||||||
state:
|
state:
|
||||||
description: State to ensure
|
description: State to ensure
|
||||||
default: present
|
default: present
|
||||||
choices: ["present", "absent", "enabled", "disabled"]
|
choices: ["present", "absent", "disabled"]
|
||||||
author:
|
author:
|
||||||
- Rafael Jeffman
|
- Rafael Jeffman
|
||||||
"""
|
"""
|
||||||
@@ -217,20 +231,31 @@ from ansible.module_utils.ansible_freeipa_module import temp_kinit, \
|
|||||||
temp_kdestroy, valid_creds, api_connect, api_command, compare_args_ipa, \
|
temp_kdestroy, valid_creds, api_connect, api_command, compare_args_ipa, \
|
||||||
encode_certificate, gen_add_del_lists, module_params_get, to_text, \
|
encode_certificate, gen_add_del_lists, module_params_get, to_text, \
|
||||||
api_check_param
|
api_check_param
|
||||||
|
import ipalib.errors
|
||||||
|
|
||||||
|
|
||||||
def find_service(module, name):
|
def find_service(module, name, netbiosname):
|
||||||
_args = {
|
_args = {
|
||||||
"all": True,
|
"all": True,
|
||||||
}
|
}
|
||||||
|
|
||||||
_result = api_command(module, "service_find", to_text(name), _args)
|
# Search for a SMB/cifs service.
|
||||||
|
if netbiosname is not None:
|
||||||
|
_result = api_command(
|
||||||
|
module, "service_find", to_text(netbiosname), _args)
|
||||||
|
|
||||||
if len(_result["result"]) > 1:
|
for _res_find in _result.get('result', []):
|
||||||
module.fail_json(
|
for uid in _res_find.get('uid', []):
|
||||||
msg="There is more than one service '%s'" % (name))
|
if uid.startswith("%s$@" % netbiosname):
|
||||||
elif len(_result["result"]) == 1:
|
return _res_find
|
||||||
_res = _result["result"][0]
|
|
||||||
|
try:
|
||||||
|
_result = api_command(module, "service_show", to_text(name), _args)
|
||||||
|
except ipalib.errors.NotFound:
|
||||||
|
return None
|
||||||
|
|
||||||
|
if "result" in _result:
|
||||||
|
_res = _result["result"]
|
||||||
certs = _res.get("usercertificate")
|
certs = _res.get("usercertificate")
|
||||||
if certs is not None:
|
if certs is not None:
|
||||||
_res["usercertificate"] = [encode_certificate(cert) for
|
_res["usercertificate"] = [encode_certificate(cert) for
|
||||||
@@ -268,7 +293,7 @@ def check_parameters(module, state, action, names, parameters):
|
|||||||
# invalid parameters for everything but state 'present', action 'service'.
|
# invalid parameters for everything but state 'present', action 'service'.
|
||||||
invalid = ['pac_type', 'auth_ind', 'skip_host_check',
|
invalid = ['pac_type', 'auth_ind', 'skip_host_check',
|
||||||
'force', 'requires_pre_auth', 'ok_as_delegate',
|
'force', 'requires_pre_auth', 'ok_as_delegate',
|
||||||
'ok_to_auth_as_delegate']
|
'ok_to_auth_as_delegate', 'smb', 'netbiosname']
|
||||||
|
|
||||||
# invalid parameters when not handling service members.
|
# invalid parameters when not handling service members.
|
||||||
invalid_not_member = \
|
invalid_not_member = \
|
||||||
@@ -283,7 +308,19 @@ def check_parameters(module, state, action, names, parameters):
|
|||||||
module.fail_json(msg="Only one service can be added at a time.")
|
module.fail_json(msg="Only one service can be added at a time.")
|
||||||
|
|
||||||
if action == 'service':
|
if action == 'service':
|
||||||
invalid = []
|
invalid = ['delete_continue']
|
||||||
|
|
||||||
|
if parameters.get('smb', False):
|
||||||
|
invalid.extend(['force', 'auth_ind', 'skip_host_check',
|
||||||
|
'requires_pre_auth', 'auth_ind', 'pac_type'])
|
||||||
|
|
||||||
|
for _invalid in invalid:
|
||||||
|
if parameters.get(_invalid, False):
|
||||||
|
module.fail_json(
|
||||||
|
msg="Argument '%s' can not be used with SMB "
|
||||||
|
"service." % _invalid)
|
||||||
|
else:
|
||||||
|
invalid.append('delete_continue')
|
||||||
|
|
||||||
elif state == 'absent':
|
elif state == 'absent':
|
||||||
if len(names) < 1:
|
if len(names) < 1:
|
||||||
@@ -291,9 +328,12 @@ def check_parameters(module, state, action, names, parameters):
|
|||||||
|
|
||||||
if action == "service":
|
if action == "service":
|
||||||
invalid.extend(invalid_not_member)
|
invalid.extend(invalid_not_member)
|
||||||
|
else:
|
||||||
|
invalid.extend('delete_continue')
|
||||||
|
|
||||||
elif state == 'disabled':
|
elif state == 'disabled':
|
||||||
invalid.extend(invalid_not_member)
|
invalid.extend(invalid_not_member)
|
||||||
|
invalid.append('delete_continue')
|
||||||
if action != "service":
|
if action != "service":
|
||||||
module.fail_json(
|
module.fail_json(
|
||||||
msg="Invalid action '%s' for state '%s'" % (action, state))
|
msg="Invalid action '%s' for state '%s'" % (action, state))
|
||||||
@@ -302,10 +342,10 @@ def check_parameters(module, state, action, names, parameters):
|
|||||||
module.fail_json(msg="Invalid state '%s'" % (state))
|
module.fail_json(msg="Invalid state '%s'" % (state))
|
||||||
|
|
||||||
for _invalid in invalid:
|
for _invalid in invalid:
|
||||||
if parameters[_invalid] is not None:
|
if _invalid in parameters and parameters[_invalid] is not None:
|
||||||
module.fail_json(
|
module.fail_json(
|
||||||
msg="Argument '%s' can not be used with state '%s'" %
|
msg="Argument '%s' can not be used with state '%s', "
|
||||||
(_invalid, state))
|
"action '%s'" % (_invalid, state, action))
|
||||||
|
|
||||||
|
|
||||||
def init_ansible_module():
|
def init_ansible_module():
|
||||||
@@ -322,11 +362,13 @@ def init_ansible_module():
|
|||||||
default=None, required=False),
|
default=None, required=False),
|
||||||
principal=dict(type="list", aliases=["krbprincipalname"],
|
principal=dict(type="list", aliases=["krbprincipalname"],
|
||||||
default=None),
|
default=None),
|
||||||
|
smb=dict(type="bool", required=False),
|
||||||
|
netbiosname=dict(type="str", required=False),
|
||||||
pac_type=dict(type="list", aliases=["ipakrbauthzdata"],
|
pac_type=dict(type="list", aliases=["ipakrbauthzdata"],
|
||||||
choices=["MS-PAC", "PAD", "NONE"]),
|
choices=["MS-PAC", "PAD", "NONE"]),
|
||||||
auth_ind=dict(type="str",
|
auth_ind=dict(type="list",
|
||||||
aliases=["krbprincipalauthind"],
|
aliases=["krbprincipalauthind"],
|
||||||
choices=["otp", "radius", "pkinit", "hardened"]),
|
choices=["otp", "radius", "pkinit", "hardened", ""]),
|
||||||
skip_host_check=dict(type="bool"),
|
skip_host_check=dict(type="bool"),
|
||||||
force=dict(type="bool"),
|
force=dict(type="bool"),
|
||||||
requires_pre_auth=dict(
|
requires_pre_auth=dict(
|
||||||
@@ -359,13 +401,14 @@ def init_ansible_module():
|
|||||||
allow_retrieve_keytab_hostgroup=dict(
|
allow_retrieve_keytab_hostgroup=dict(
|
||||||
type="list", required=False,
|
type="list", required=False,
|
||||||
aliases=['ipaallowedtoperform_read_keys_hostgroup']),
|
aliases=['ipaallowedtoperform_read_keys_hostgroup']),
|
||||||
|
delete_continue=dict(type="bool", required=False,
|
||||||
|
aliases=['continue']),
|
||||||
# action
|
# action
|
||||||
action=dict(type="str", default="service",
|
action=dict(type="str", default="service",
|
||||||
choices=["member", "service"]),
|
choices=["member", "service"]),
|
||||||
# state
|
# state
|
||||||
state=dict(type="str", default="present",
|
state=dict(type="str", default="present",
|
||||||
choices=["present", "absent",
|
choices=["present", "absent", "disabled"]),
|
||||||
"enabled", "disabled"]),
|
|
||||||
),
|
),
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
)
|
)
|
||||||
@@ -398,6 +441,9 @@ def main():
|
|||||||
ok_to_auth_as_delegate = module_params_get(ansible_module,
|
ok_to_auth_as_delegate = module_params_get(ansible_module,
|
||||||
"ok_to_auth_as_delegate")
|
"ok_to_auth_as_delegate")
|
||||||
|
|
||||||
|
smb = module_params_get(ansible_module, "smb")
|
||||||
|
netbiosname = module_params_get(ansible_module, "netbiosname")
|
||||||
|
|
||||||
host = module_params_get(ansible_module, "host")
|
host = module_params_get(ansible_module, "host")
|
||||||
|
|
||||||
allow_create_keytab_user = module_params_get(
|
allow_create_keytab_user = module_params_get(
|
||||||
@@ -417,6 +463,7 @@ def main():
|
|||||||
ansible_module, "allow_create_keytab_host")
|
ansible_module, "allow_create_keytab_host")
|
||||||
allow_retrieve_keytab_hostgroup = module_params_get(
|
allow_retrieve_keytab_hostgroup = module_params_get(
|
||||||
ansible_module, "allow_retrieve_keytab_hostgroup")
|
ansible_module, "allow_retrieve_keytab_hostgroup")
|
||||||
|
delete_continue = module_params_get(ansible_module, "delete_continue")
|
||||||
|
|
||||||
# action
|
# action
|
||||||
action = module_params_get(ansible_module, "action")
|
action = module_params_get(ansible_module, "action")
|
||||||
@@ -447,9 +494,11 @@ def main():
|
|||||||
commands = []
|
commands = []
|
||||||
|
|
||||||
for name in names:
|
for name in names:
|
||||||
res_find = find_service(ansible_module, name)
|
res_find = find_service(ansible_module, name, netbiosname)
|
||||||
|
|
||||||
if state == "present":
|
if state == "present":
|
||||||
|
# if service exists, 'smb' cannot be used.
|
||||||
|
|
||||||
if action == "service":
|
if action == "service":
|
||||||
args = gen_args(
|
args = gen_args(
|
||||||
pac_type, auth_ind, skip_host_check, force,
|
pac_type, auth_ind, skip_host_check, force,
|
||||||
@@ -459,7 +508,12 @@ def main():
|
|||||||
del args['skip_host_check']
|
del args['skip_host_check']
|
||||||
|
|
||||||
if res_find is None:
|
if res_find is None:
|
||||||
commands.append([name, 'service_add', args])
|
if smb:
|
||||||
|
if netbiosname is not None:
|
||||||
|
args['ipantflatname'] = netbiosname
|
||||||
|
commands.append([name, 'service_add_smb', args])
|
||||||
|
else:
|
||||||
|
commands.append([name, 'service_add', args])
|
||||||
|
|
||||||
certificate_add = certificate or []
|
certificate_add = certificate or []
|
||||||
certificate_del = []
|
certificate_del = []
|
||||||
@@ -699,7 +753,8 @@ def main():
|
|||||||
elif state == "absent":
|
elif state == "absent":
|
||||||
if action == "service":
|
if action == "service":
|
||||||
if res_find is not None:
|
if res_find is not None:
|
||||||
commands.append([name, 'service_del', {}])
|
args = {'continue': True if delete_continue else False}
|
||||||
|
commands.append([name, 'service_del', args])
|
||||||
|
|
||||||
elif action == "member":
|
elif action == "member":
|
||||||
if res_find is None:
|
if res_find is None:
|
||||||
|
|||||||
@@ -113,7 +113,7 @@
|
|||||||
- PAD
|
- PAD
|
||||||
auth_ind: otp
|
auth_ind: otp
|
||||||
skip_host_check: no
|
skip_host_check: no
|
||||||
force: no
|
force: yes
|
||||||
requires_pre_auth: yes
|
requires_pre_auth: yes
|
||||||
ok_as_delegate: no
|
ok_as_delegate: no
|
||||||
ok_to_auth_as_delegate: no
|
ok_to_auth_as_delegate: no
|
||||||
@@ -475,6 +475,106 @@
|
|||||||
register: result
|
register: result
|
||||||
failed_when: result.changed
|
failed_when: result.changed
|
||||||
|
|
||||||
|
- name: Ensure service is present, with multiple auth_ind values.
|
||||||
|
ipaservice:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: "HTTP/{{ svc_fqdn }}"
|
||||||
|
auth_ind: otp,radius
|
||||||
|
skip_host_check: no
|
||||||
|
force: yes
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Ensure service is present, with multiple auth_ind values, again.
|
||||||
|
ipaservice:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: "HTTP/{{ svc_fqdn }}"
|
||||||
|
auth_ind: otp,radius
|
||||||
|
skip_host_check: no
|
||||||
|
force: yes
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed
|
||||||
|
|
||||||
|
- name: Clear auth_ind.
|
||||||
|
ipaservice:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: "HTTP/{{ svc_fqdn }}"
|
||||||
|
auth_ind: ""
|
||||||
|
skip_host_check: no
|
||||||
|
force: yes
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Clear auth_ind, again.
|
||||||
|
ipaservice:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: "HTTP/{{ svc_fqdn }}"
|
||||||
|
auth_ind: ""
|
||||||
|
skip_host_check: no
|
||||||
|
force: yes
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed
|
||||||
|
|
||||||
|
- name: Ensure services are absent.
|
||||||
|
ipaservice:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name:
|
||||||
|
- "HTTP/{{ svc_fqdn }}"
|
||||||
|
- HTTP/www.ansible.com
|
||||||
|
- HTTP/svc.ihavenodns.info
|
||||||
|
- HTTP/no.idontexist.local
|
||||||
|
continue: yes
|
||||||
|
state: absent
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Ensure services are absent.
|
||||||
|
ipaservice:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name:
|
||||||
|
- "HTTP/{{ svc_fqdn }}"
|
||||||
|
- HTTP/www.ansible.com
|
||||||
|
- HTTP/svc.ihavenodns.info
|
||||||
|
- HTTP/no.idontexist.local
|
||||||
|
continue: yes
|
||||||
|
state: absent
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed
|
||||||
|
|
||||||
|
- name: Ensure SMB service is present.
|
||||||
|
ipaservice:
|
||||||
|
ipaadmin_password: MyPassword123
|
||||||
|
name: "{{ host1_fqdn }}"
|
||||||
|
smb: yes
|
||||||
|
netbiosname: SAMBASVC
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Ensure SMB service is again.
|
||||||
|
ipaservice:
|
||||||
|
ipaadmin_password: MyPassword123
|
||||||
|
name: "{{ host1_fqdn }}"
|
||||||
|
smb: yes
|
||||||
|
netbiosname: SAMBASVC
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed
|
||||||
|
|
||||||
|
- name: Ensure SMB service is absent.
|
||||||
|
ipaservice:
|
||||||
|
ipaadmin_password: MyPassword123
|
||||||
|
name: "cifs/{{ host1_fqdn }}"
|
||||||
|
state: absent
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Ensure SMB service is absent, again.
|
||||||
|
ipaservice:
|
||||||
|
ipaadmin_password: MyPassword123
|
||||||
|
name: "cifs/{{ host1_fqdn }}"
|
||||||
|
state: absent
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed
|
||||||
|
|
||||||
# cleanup
|
# cleanup
|
||||||
|
|
||||||
- name: Ensure services are absent.
|
- name: Ensure services are absent.
|
||||||
@@ -485,6 +585,7 @@
|
|||||||
- HTTP/www.ansible.com
|
- HTTP/www.ansible.com
|
||||||
- HTTP/svc.ihavenodns.info
|
- HTTP/svc.ihavenodns.info
|
||||||
- HTTP/no.idontexist.local
|
- HTTP/no.idontexist.local
|
||||||
|
- "cifs/{{ host1_fqdn }}"
|
||||||
state: absent
|
state: absent
|
||||||
|
|
||||||
- name: Ensure host "{{ svc_fqdn }}" is absent
|
- name: Ensure host "{{ svc_fqdn }}" is absent
|
||||||
|
|||||||
Reference in New Issue
Block a user