FreeIPA module polymorphic restructuring and small fixes. (#3485)
* Moved JSON-RPC client IPAClient class to ansible.module_utils.ipa, which is extended by all ipa modules * ipa_user: incorporate displayname and userpassword attributes in module_user * ipa_user: capitalized "I" in comment * ipa_user: updated get_ssh_key_fingerprint to include possibility of the uploaded SSH key including user@hostname comment, which also appears in the queried fingerprint. This fixes a mismatch in the calculated and queried SSH key fingerprint in the user_diff calculation when the user already exists. * ipa_hbacrule: ipaenabledflag must be 'TRUE' or 'FALSE', not 'NO' * ipa_sudorule: ipaenabledflag must be 'TRUE' or 'FALSE', not 'NO' * Add author to files missing it
This commit is contained in:
parent
92a53a7182
commit
a6f0a279a9
9 changed files with 88 additions and 738 deletions
|
@ -87,8 +87,6 @@ options:
|
||||||
required: false
|
required: false
|
||||||
default: true
|
default: true
|
||||||
version_added: "2.3"
|
version_added: "2.3"
|
||||||
requirements:
|
|
||||||
- json
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
EXAMPLES = '''
|
EXAMPLES = '''
|
||||||
|
@ -137,83 +135,12 @@ group:
|
||||||
type: dict
|
type: dict
|
||||||
'''
|
'''
|
||||||
|
|
||||||
try:
|
from ansible.module_utils.ipa import IPAClient
|
||||||
import json
|
|
||||||
except ImportError:
|
|
||||||
import simplejson as json
|
|
||||||
|
|
||||||
|
class GroupIPAClient(IPAClient):
|
||||||
|
|
||||||
class IPAClient:
|
|
||||||
def __init__(self, module, host, port, protocol):
|
def __init__(self, module, host, port, protocol):
|
||||||
self.host = host
|
super(GroupIPAClient, self).__init__(module, host, port, protocol)
|
||||||
self.port = port
|
|
||||||
self.protocol = protocol
|
|
||||||
self.module = module
|
|
||||||
self.headers = None
|
|
||||||
|
|
||||||
def get_base_url(self):
|
|
||||||
return '%s://%s/ipa' % (self.protocol, self.host)
|
|
||||||
|
|
||||||
def get_json_url(self):
|
|
||||||
return '%s/session/json' % self.get_base_url()
|
|
||||||
|
|
||||||
def login(self, username, password):
|
|
||||||
url = '%s/session/login_password' % self.get_base_url()
|
|
||||||
data = 'user=%s&password=%s' % (username, password)
|
|
||||||
headers = {'referer': self.get_base_url(),
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
|
||||||
'Accept': 'text/plain'}
|
|
||||||
try:
|
|
||||||
resp, info = fetch_url(module=self.module, url=url, data=data, headers=headers)
|
|
||||||
status_code = info['status']
|
|
||||||
if status_code not in [200, 201, 204]:
|
|
||||||
self._fail('login', info['body'])
|
|
||||||
|
|
||||||
self.headers = {'referer': self.get_base_url(),
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Accept': 'application/json',
|
|
||||||
'Cookie': resp.info().getheader('Set-Cookie')}
|
|
||||||
except Exception:
|
|
||||||
e = get_exception()
|
|
||||||
self._fail('login', str(e))
|
|
||||||
|
|
||||||
def _fail(self, msg, e):
|
|
||||||
if 'message' in e:
|
|
||||||
err_string = e.get('message')
|
|
||||||
else:
|
|
||||||
err_string = e
|
|
||||||
self.module.fail_json(msg='%s: %s' % (msg, err_string))
|
|
||||||
|
|
||||||
def _post_json(self, method, name, item=None):
|
|
||||||
if item is None:
|
|
||||||
item = {}
|
|
||||||
url = '%s/session/json' % self.get_base_url()
|
|
||||||
data = {'method': method, 'params': [[name], item]}
|
|
||||||
try:
|
|
||||||
resp, info = fetch_url(module=self.module, url=url, data=json.dumps(data), headers=self.headers)
|
|
||||||
status_code = info['status']
|
|
||||||
if status_code not in [200, 201, 204]:
|
|
||||||
self._fail(method, info['body'])
|
|
||||||
except Exception:
|
|
||||||
e = get_exception()
|
|
||||||
self._fail('post %s' % method, str(e))
|
|
||||||
|
|
||||||
resp = json.loads(resp.read())
|
|
||||||
err = resp.get('error')
|
|
||||||
if err is not None:
|
|
||||||
self._fail('repsonse %s' % method, err)
|
|
||||||
|
|
||||||
if 'result' in resp:
|
|
||||||
result = resp.get('result')
|
|
||||||
if 'result' in result:
|
|
||||||
result = result.get('result')
|
|
||||||
if isinstance(result, list):
|
|
||||||
if len(result) > 0:
|
|
||||||
return result[0]
|
|
||||||
else:
|
|
||||||
return {}
|
|
||||||
return result
|
|
||||||
return None
|
|
||||||
|
|
||||||
def group_find(self, name):
|
def group_find(self, name):
|
||||||
return self._post_json(method='group_find', name=None, item={'all': True, 'cn': name})
|
return self._post_json(method='group_find', name=None, item={'all': True, 'cn': name})
|
||||||
|
@ -364,10 +291,10 @@ def main():
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
client = IPAClient(module=module,
|
client = GroupIPAClient(module=module,
|
||||||
host=module.params['ipa_host'],
|
host=module.params['ipa_host'],
|
||||||
port=module.params['ipa_port'],
|
port=module.params['ipa_port'],
|
||||||
protocol=module.params['ipa_prot'])
|
protocol=module.params['ipa_prot'])
|
||||||
try:
|
try:
|
||||||
client.login(username=module.params['ipa_user'],
|
client.login(username=module.params['ipa_user'],
|
||||||
password=module.params['ipa_pass'])
|
password=module.params['ipa_pass'])
|
||||||
|
@ -380,7 +307,6 @@ def main():
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.pycompat24 import get_exception
|
from ansible.module_utils.pycompat24 import get_exception
|
||||||
from ansible.module_utils.urls import fetch_url
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -122,8 +122,6 @@ options:
|
||||||
required: false
|
required: false
|
||||||
default: true
|
default: true
|
||||||
version_added: "2.3"
|
version_added: "2.3"
|
||||||
requirements:
|
|
||||||
- json
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
EXAMPLES = '''
|
EXAMPLES = '''
|
||||||
|
@ -168,83 +166,12 @@ hbacrule:
|
||||||
type: dict
|
type: dict
|
||||||
'''
|
'''
|
||||||
|
|
||||||
try:
|
from ansible.module_utils.ipa import IPAClient
|
||||||
import json
|
|
||||||
except ImportError:
|
|
||||||
import simplejson as json
|
|
||||||
|
|
||||||
|
class HBACRuleIPAClient(IPAClient):
|
||||||
|
|
||||||
class IPAClient:
|
|
||||||
def __init__(self, module, host, port, protocol):
|
def __init__(self, module, host, port, protocol):
|
||||||
self.host = host
|
super(HBACRuleIPAClient, self).__init__(module, host, port, protocol)
|
||||||
self.port = port
|
|
||||||
self.protocol = protocol
|
|
||||||
self.module = module
|
|
||||||
self.headers = None
|
|
||||||
|
|
||||||
def get_base_url(self):
|
|
||||||
return '%s://%s/ipa' % (self.protocol, self.host)
|
|
||||||
|
|
||||||
def get_json_url(self):
|
|
||||||
return '%s/session/json' % self.get_base_url()
|
|
||||||
|
|
||||||
def login(self, username, password):
|
|
||||||
url = '%s/session/login_password' % self.get_base_url()
|
|
||||||
data = 'user=%s&password=%s' % (username, password)
|
|
||||||
headers = {'referer': self.get_base_url(),
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
|
||||||
'Accept': 'text/plain'}
|
|
||||||
try:
|
|
||||||
resp, info = fetch_url(module=self.module, url=url, data=data, headers=headers)
|
|
||||||
status_code = info['status']
|
|
||||||
if status_code not in [200, 201, 204]:
|
|
||||||
self._fail('login', info['body'])
|
|
||||||
|
|
||||||
self.headers = {'referer': self.get_base_url(),
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Accept': 'application/json',
|
|
||||||
'Cookie': resp.info().getheader('Set-Cookie')}
|
|
||||||
except Exception:
|
|
||||||
e = get_exception()
|
|
||||||
self._fail('login', str(e))
|
|
||||||
|
|
||||||
def _fail(self, msg, e):
|
|
||||||
if 'message' in e:
|
|
||||||
err_string = e.get('message')
|
|
||||||
else:
|
|
||||||
err_string = e
|
|
||||||
self.module.fail_json(msg='%s: %s' % (msg, err_string))
|
|
||||||
|
|
||||||
def _post_json(self, method, name, item=None):
|
|
||||||
if item is None:
|
|
||||||
item = {}
|
|
||||||
url = '%s/session/json' % self.get_base_url()
|
|
||||||
data = {'method': method, 'params': [[name], item]}
|
|
||||||
try:
|
|
||||||
resp, info = fetch_url(module=self.module, url=url, data=json.dumps(data), headers=self.headers)
|
|
||||||
status_code = info['status']
|
|
||||||
if status_code not in [200, 201, 204]:
|
|
||||||
self._fail(method, info['body'])
|
|
||||||
except Exception:
|
|
||||||
e = get_exception()
|
|
||||||
self._fail('post %s' % method, str(e))
|
|
||||||
|
|
||||||
resp = json.loads(resp.read())
|
|
||||||
err = resp.get('error')
|
|
||||||
if err is not None:
|
|
||||||
self._fail('repsonse %s' % method, err)
|
|
||||||
|
|
||||||
if 'result' in resp:
|
|
||||||
result = resp.get('result')
|
|
||||||
if 'result' in result:
|
|
||||||
result = result.get('result')
|
|
||||||
if isinstance(result, list):
|
|
||||||
if len(result) > 0:
|
|
||||||
return result[0]
|
|
||||||
else:
|
|
||||||
return {}
|
|
||||||
return result
|
|
||||||
return None
|
|
||||||
|
|
||||||
def hbacrule_find(self, name):
|
def hbacrule_find(self, name):
|
||||||
return self._post_json(method='hbacrule_find', name=None, item={'all': True, 'cn': name})
|
return self._post_json(method='hbacrule_find', name=None, item={'all': True, 'cn': name})
|
||||||
|
@ -341,7 +268,7 @@ def ensure(module, client):
|
||||||
if state in ['present', 'enabled']:
|
if state in ['present', 'enabled']:
|
||||||
ipaenabledflag = 'TRUE'
|
ipaenabledflag = 'TRUE'
|
||||||
else:
|
else:
|
||||||
ipaenabledflag = 'NO'
|
ipaenabledflag = 'FALSE'
|
||||||
|
|
||||||
host = module.params['host']
|
host = module.params['host']
|
||||||
hostcategory = module.params['hostcategory']
|
hostcategory = module.params['hostcategory']
|
||||||
|
@ -458,10 +385,10 @@ def main():
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
client = IPAClient(module=module,
|
client = HBACRuleIPAClient(module=module,
|
||||||
host=module.params['ipa_host'],
|
host=module.params['ipa_host'],
|
||||||
port=module.params['ipa_port'],
|
port=module.params['ipa_port'],
|
||||||
protocol=module.params['ipa_prot'])
|
protocol=module.params['ipa_prot'])
|
||||||
|
|
||||||
try:
|
try:
|
||||||
client.login(username=module.params['ipa_user'],
|
client.login(username=module.params['ipa_user'],
|
||||||
|
@ -475,7 +402,6 @@ def main():
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.pycompat24 import get_exception
|
from ansible.module_utils.pycompat24 import get_exception
|
||||||
from ansible.module_utils.urls import fetch_url
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
---
|
---
|
||||||
module: ipa_host
|
module: ipa_host
|
||||||
|
author: Thomas Krahn (@Nosmoht)
|
||||||
short_description: Manage FreeIPA host
|
short_description: Manage FreeIPA host
|
||||||
description:
|
description:
|
||||||
- Add, modify and delete an IPA host using IPA API
|
- Add, modify and delete an IPA host using IPA API
|
||||||
|
@ -104,8 +105,6 @@ options:
|
||||||
required: false
|
required: false
|
||||||
default: true
|
default: true
|
||||||
version_added: "2.3"
|
version_added: "2.3"
|
||||||
requirements:
|
|
||||||
- json
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
EXAMPLES = '''
|
EXAMPLES = '''
|
||||||
|
@ -161,83 +160,12 @@ host_diff:
|
||||||
type: list
|
type: list
|
||||||
'''
|
'''
|
||||||
|
|
||||||
try:
|
from ansible.module_utils.ipa import IPAClient
|
||||||
import json
|
|
||||||
except ImportError:
|
|
||||||
import simplejson as json
|
|
||||||
|
|
||||||
|
class HostIPAClient(IPAClient):
|
||||||
|
|
||||||
class IPAClient:
|
|
||||||
def __init__(self, module, host, port, protocol):
|
def __init__(self, module, host, port, protocol):
|
||||||
self.host = host
|
super(HostIPAClient, self).__init__(module, host, port, protocol)
|
||||||
self.port = port
|
|
||||||
self.protocol = protocol
|
|
||||||
self.module = module
|
|
||||||
self.headers = None
|
|
||||||
|
|
||||||
def get_base_url(self):
|
|
||||||
return '%s://%s/ipa' % (self.protocol, self.host)
|
|
||||||
|
|
||||||
def get_json_url(self):
|
|
||||||
return '%s/session/json' % self.get_base_url()
|
|
||||||
|
|
||||||
def login(self, username, password):
|
|
||||||
url = '%s/session/login_password' % self.get_base_url()
|
|
||||||
data = 'user=%s&password=%s' % (username, password)
|
|
||||||
headers = {'referer': self.get_base_url(),
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
|
||||||
'Accept': 'text/plain'}
|
|
||||||
try:
|
|
||||||
resp, info = fetch_url(module=self.module, url=url, data=data, headers=headers)
|
|
||||||
status_code = info['status']
|
|
||||||
if status_code not in [200, 201, 204]:
|
|
||||||
self._fail('login', info['body'])
|
|
||||||
|
|
||||||
self.headers = {'referer': self.get_base_url(),
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Accept': 'application/json',
|
|
||||||
'Cookie': resp.info().getheader('Set-Cookie')}
|
|
||||||
except Exception:
|
|
||||||
e = get_exception()
|
|
||||||
self._fail('login', str(e))
|
|
||||||
|
|
||||||
def _fail(self, msg, e):
|
|
||||||
if 'message' in e:
|
|
||||||
err_string = e.get('message')
|
|
||||||
else:
|
|
||||||
err_string = e
|
|
||||||
self.module.fail_json(msg='%s: %s' % (msg, err_string))
|
|
||||||
|
|
||||||
def _post_json(self, method, name, item=None):
|
|
||||||
if item is None:
|
|
||||||
item = {}
|
|
||||||
url = '%s/session/json' % self.get_base_url()
|
|
||||||
data = {'method': method, 'params': [[name], item]}
|
|
||||||
try:
|
|
||||||
resp, info = fetch_url(module=self.module, url=url, data=json.dumps(data), headers=self.headers)
|
|
||||||
status_code = info['status']
|
|
||||||
if status_code not in [200, 201, 204]:
|
|
||||||
self._fail(method, info['body'])
|
|
||||||
except Exception:
|
|
||||||
e = get_exception()
|
|
||||||
self._fail('post %s' % method, str(e))
|
|
||||||
|
|
||||||
resp = json.loads(resp.read())
|
|
||||||
err = resp.get('error')
|
|
||||||
if err is not None:
|
|
||||||
self._fail('repsonse %s' % method, err)
|
|
||||||
|
|
||||||
if 'result' in resp:
|
|
||||||
result = resp.get('result')
|
|
||||||
if 'result' in result:
|
|
||||||
result = result.get('result')
|
|
||||||
if isinstance(result, list):
|
|
||||||
if len(result) > 0:
|
|
||||||
return result[0]
|
|
||||||
else:
|
|
||||||
return {}
|
|
||||||
return result
|
|
||||||
return None
|
|
||||||
|
|
||||||
def host_find(self, name):
|
def host_find(self, name):
|
||||||
return self._post_json(method='host_find', name=None, item={'all': True, 'fqdn': name})
|
return self._post_json(method='host_find', name=None, item={'all': True, 'fqdn': name})
|
||||||
|
@ -357,10 +285,10 @@ def main():
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
client = IPAClient(module=module,
|
client = HostIPAClient(module=module,
|
||||||
host=module.params['ipa_host'],
|
host=module.params['ipa_host'],
|
||||||
port=module.params['ipa_port'],
|
port=module.params['ipa_port'],
|
||||||
protocol=module.params['ipa_prot'])
|
protocol=module.params['ipa_prot'])
|
||||||
|
|
||||||
try:
|
try:
|
||||||
client.login(username=module.params['ipa_user'],
|
client.login(username=module.params['ipa_user'],
|
||||||
|
@ -374,7 +302,6 @@ def main():
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.pycompat24 import get_exception
|
from ansible.module_utils.pycompat24 import get_exception
|
||||||
from ansible.module_utils.urls import fetch_url
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
---
|
---
|
||||||
module: ipa_hostgroup
|
module: ipa_hostgroup
|
||||||
|
author: Thomas Krahn (@Nosmoht)
|
||||||
short_description: Manage FreeIPA host-group
|
short_description: Manage FreeIPA host-group
|
||||||
description:
|
description:
|
||||||
- Add, modify and delete an IPA host-group using IPA API
|
- Add, modify and delete an IPA host-group using IPA API
|
||||||
|
@ -80,8 +81,6 @@ options:
|
||||||
required: false
|
required: false
|
||||||
default: true
|
default: true
|
||||||
version_added: "2.3"
|
version_added: "2.3"
|
||||||
requirements:
|
|
||||||
- json
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
EXAMPLES = '''
|
EXAMPLES = '''
|
||||||
|
@ -114,83 +113,12 @@ hostgroup:
|
||||||
type: dict
|
type: dict
|
||||||
'''
|
'''
|
||||||
|
|
||||||
try:
|
from ansible.module_utils.ipa import IPAClient
|
||||||
import json
|
|
||||||
except ImportError:
|
|
||||||
import simplejson as json
|
|
||||||
|
|
||||||
|
class HostGroupIPAClient(IPAClient):
|
||||||
|
|
||||||
class IPAClient:
|
|
||||||
def __init__(self, module, host, port, protocol):
|
def __init__(self, module, host, port, protocol):
|
||||||
self.host = host
|
super(HostGroupIPAClient, self).__init__(module, host, port, protocol)
|
||||||
self.port = port
|
|
||||||
self.protocol = protocol
|
|
||||||
self.module = module
|
|
||||||
self.headers = None
|
|
||||||
|
|
||||||
def get_base_url(self):
|
|
||||||
return '%s://%s/ipa' % (self.protocol, self.host)
|
|
||||||
|
|
||||||
def get_json_url(self):
|
|
||||||
return '%s/session/json' % self.get_base_url()
|
|
||||||
|
|
||||||
def login(self, username, password):
|
|
||||||
url = '%s/session/login_password' % self.get_base_url()
|
|
||||||
data = 'user=%s&password=%s' % (username, password)
|
|
||||||
headers = {'referer': self.get_base_url(),
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
|
||||||
'Accept': 'text/plain'}
|
|
||||||
try:
|
|
||||||
resp, info = fetch_url(module=self.module, url=url, data=data, headers=headers)
|
|
||||||
status_code = info['status']
|
|
||||||
if status_code not in [200, 201, 204]:
|
|
||||||
self._fail('login', info['body'])
|
|
||||||
|
|
||||||
self.headers = {'referer': self.get_base_url(),
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Accept': 'application/json',
|
|
||||||
'Cookie': resp.info().getheader('Set-Cookie')}
|
|
||||||
except Exception:
|
|
||||||
e = get_exception()
|
|
||||||
self._fail('login', str(e))
|
|
||||||
|
|
||||||
def _fail(self, msg, e):
|
|
||||||
if 'message' in e:
|
|
||||||
err_string = e.get('message')
|
|
||||||
else:
|
|
||||||
err_string = e
|
|
||||||
self.module.fail_json(msg='%s: %s' % (msg, err_string))
|
|
||||||
|
|
||||||
def _post_json(self, method, name, item=None):
|
|
||||||
if item is None:
|
|
||||||
item = {}
|
|
||||||
url = '%s/session/json' % self.get_base_url()
|
|
||||||
data = {'method': method, 'params': [[name], item]}
|
|
||||||
try:
|
|
||||||
resp, info = fetch_url(module=self.module, url=url, data=json.dumps(data), headers=self.headers)
|
|
||||||
status_code = info['status']
|
|
||||||
if status_code not in [200, 201, 204]:
|
|
||||||
self._fail(method, info['body'])
|
|
||||||
except Exception:
|
|
||||||
e = get_exception()
|
|
||||||
self._fail('post %s' % method, str(e))
|
|
||||||
|
|
||||||
resp = json.loads(resp.read())
|
|
||||||
err = resp.get('error')
|
|
||||||
if err is not None:
|
|
||||||
self._fail('repsonse %s' % method, err)
|
|
||||||
|
|
||||||
if 'result' in resp:
|
|
||||||
result = resp.get('result')
|
|
||||||
if 'result' in result:
|
|
||||||
result = result.get('result')
|
|
||||||
if isinstance(result, list):
|
|
||||||
if len(result) > 0:
|
|
||||||
return result[0]
|
|
||||||
else:
|
|
||||||
return {}
|
|
||||||
return result
|
|
||||||
return None
|
|
||||||
|
|
||||||
def hostgroup_find(self, name):
|
def hostgroup_find(self, name):
|
||||||
return self._post_json(method='hostgroup_find', name=None, item={'all': True, 'cn': name})
|
return self._post_json(method='hostgroup_find', name=None, item={'all': True, 'cn': name})
|
||||||
|
@ -324,10 +252,10 @@ def main():
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
client = IPAClient(module=module,
|
client = HostGroupIPAClient(module=module,
|
||||||
host=module.params['ipa_host'],
|
host=module.params['ipa_host'],
|
||||||
port=module.params['ipa_port'],
|
port=module.params['ipa_port'],
|
||||||
protocol=module.params['ipa_prot'])
|
protocol=module.params['ipa_prot'])
|
||||||
|
|
||||||
try:
|
try:
|
||||||
client.login(username=module.params['ipa_user'],
|
client.login(username=module.params['ipa_user'],
|
||||||
|
@ -341,7 +269,6 @@ def main():
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.pycompat24 import get_exception
|
from ansible.module_utils.pycompat24 import get_exception
|
||||||
from ansible.module_utils.urls import fetch_url
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
---
|
---
|
||||||
module: ipa_role
|
module: ipa_role
|
||||||
|
author: Thomas Krahn (@Nosmoht)
|
||||||
short_description: Manage FreeIPA role
|
short_description: Manage FreeIPA role
|
||||||
description:
|
description:
|
||||||
- Add, modify and delete a role within FreeIPA server using FreeIPA API
|
- Add, modify and delete a role within FreeIPA server using FreeIPA API
|
||||||
|
@ -98,8 +99,6 @@ options:
|
||||||
required: false
|
required: false
|
||||||
default: true
|
default: true
|
||||||
version_added: "2.3"
|
version_added: "2.3"
|
||||||
requirements:
|
|
||||||
- json
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
EXAMPLES = '''
|
EXAMPLES = '''
|
||||||
|
@ -144,83 +143,12 @@ role:
|
||||||
type: dict
|
type: dict
|
||||||
'''
|
'''
|
||||||
|
|
||||||
try:
|
from ansible.module_utils.ipa import IPAClient
|
||||||
import json
|
|
||||||
except ImportError:
|
|
||||||
import simplejson as json
|
|
||||||
|
|
||||||
|
class RoleIPAClient(IPAClient):
|
||||||
|
|
||||||
class IPAClient:
|
|
||||||
def __init__(self, module, host, port, protocol):
|
def __init__(self, module, host, port, protocol):
|
||||||
self.host = host
|
super(RoleIPAClient, self).__init__(module, host, port, protocol)
|
||||||
self.port = port
|
|
||||||
self.protocol = protocol
|
|
||||||
self.module = module
|
|
||||||
self.headers = None
|
|
||||||
|
|
||||||
def get_base_url(self):
|
|
||||||
return '%s://%s/ipa' % (self.protocol, self.host)
|
|
||||||
|
|
||||||
def get_json_url(self):
|
|
||||||
return '%s/session/json' % self.get_base_url()
|
|
||||||
|
|
||||||
def login(self, username, password):
|
|
||||||
url = '%s/session/login_password' % self.get_base_url()
|
|
||||||
data = 'user=%s&password=%s' % (username, password)
|
|
||||||
headers = {'referer': self.get_base_url(),
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
|
||||||
'Accept': 'text/plain'}
|
|
||||||
try:
|
|
||||||
resp, info = fetch_url(module=self.module, url=url, data=data, headers=headers)
|
|
||||||
status_code = info['status']
|
|
||||||
if status_code not in [200, 201, 204]:
|
|
||||||
self._fail('login', info['body'])
|
|
||||||
|
|
||||||
self.headers = {'referer': self.get_base_url(),
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Accept': 'application/json',
|
|
||||||
'Cookie': resp.info().getheader('Set-Cookie')}
|
|
||||||
except Exception:
|
|
||||||
e = get_exception()
|
|
||||||
self._fail('login', str(e))
|
|
||||||
|
|
||||||
def _fail(self, msg, e):
|
|
||||||
if 'message' in e:
|
|
||||||
err_string = e.get('message')
|
|
||||||
else:
|
|
||||||
err_string = e
|
|
||||||
self.module.fail_json(msg='%s: %s' % (msg, err_string))
|
|
||||||
|
|
||||||
def _post_json(self, method, name, item=None):
|
|
||||||
if item is None:
|
|
||||||
item = {}
|
|
||||||
url = '%s/session/json' % self.get_base_url()
|
|
||||||
data = {'method': method, 'params': [[name], item]}
|
|
||||||
try:
|
|
||||||
resp, info = fetch_url(module=self.module, url=url, data=json.dumps(data), headers=self.headers)
|
|
||||||
status_code = info['status']
|
|
||||||
if status_code not in [200, 201, 204]:
|
|
||||||
self._fail(method, info['body'])
|
|
||||||
except Exception:
|
|
||||||
e = get_exception()
|
|
||||||
self._fail('post %s' % method, str(e))
|
|
||||||
|
|
||||||
resp = json.loads(resp.read())
|
|
||||||
err = resp.get('error')
|
|
||||||
if err is not None:
|
|
||||||
self._fail('repsonse %s' % method, err)
|
|
||||||
|
|
||||||
if 'result' in resp:
|
|
||||||
result = resp.get('result')
|
|
||||||
if 'result' in result:
|
|
||||||
result = result.get('result')
|
|
||||||
if isinstance(result, list):
|
|
||||||
if len(result) > 0:
|
|
||||||
return result[0]
|
|
||||||
else:
|
|
||||||
return {}
|
|
||||||
return result
|
|
||||||
return None
|
|
||||||
|
|
||||||
def role_find(self, name):
|
def role_find(self, name):
|
||||||
return self._post_json(method='role_find', name=None, item={'all': True, 'cn': name})
|
return self._post_json(method='role_find', name=None, item={'all': True, 'cn': name})
|
||||||
|
@ -390,10 +318,10 @@ def main():
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
client = IPAClient(module=module,
|
client = RoleIPAClient(module=module,
|
||||||
host=module.params['ipa_host'],
|
host=module.params['ipa_host'],
|
||||||
port=module.params['ipa_port'],
|
port=module.params['ipa_port'],
|
||||||
protocol=module.params['ipa_prot'])
|
protocol=module.params['ipa_prot'])
|
||||||
|
|
||||||
try:
|
try:
|
||||||
client.login(username=module.params['ipa_user'],
|
client.login(username=module.params['ipa_user'],
|
||||||
|
@ -407,7 +335,6 @@ def main():
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.pycompat24 import get_exception
|
from ansible.module_utils.pycompat24 import get_exception
|
||||||
from ansible.module_utils.urls import fetch_url
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -65,8 +65,6 @@ options:
|
||||||
required: false
|
required: false
|
||||||
default: true
|
default: true
|
||||||
version_added: "2.3"
|
version_added: "2.3"
|
||||||
requirements:
|
|
||||||
- json
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
EXAMPLES = '''
|
EXAMPLES = '''
|
||||||
|
@ -94,83 +92,12 @@ sudocmd:
|
||||||
type: dict
|
type: dict
|
||||||
'''
|
'''
|
||||||
|
|
||||||
try:
|
from ansible.module_utils.ipa import IPAClient
|
||||||
import json
|
|
||||||
except ImportError:
|
|
||||||
import simplejson as json
|
|
||||||
|
|
||||||
|
class SudoCmdIPAClient(IPAClient):
|
||||||
|
|
||||||
class IPAClient:
|
|
||||||
def __init__(self, module, host, port, protocol):
|
def __init__(self, module, host, port, protocol):
|
||||||
self.host = host
|
super(SudoCmdIPAClient, self).__init__(module, host, port, protocol)
|
||||||
self.port = port
|
|
||||||
self.protocol = protocol
|
|
||||||
self.module = module
|
|
||||||
self.headers = None
|
|
||||||
|
|
||||||
def get_base_url(self):
|
|
||||||
return '%s://%s/ipa' % (self.protocol, self.host)
|
|
||||||
|
|
||||||
def get_json_url(self):
|
|
||||||
return '%s/session/json' % self.get_base_url()
|
|
||||||
|
|
||||||
def login(self, username, password):
|
|
||||||
url = '%s/session/login_password' % self.get_base_url()
|
|
||||||
data = 'user=%s&password=%s' % (username, password)
|
|
||||||
headers = {'referer': self.get_base_url(),
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
|
||||||
'Accept': 'text/plain'}
|
|
||||||
try:
|
|
||||||
resp, info = fetch_url(module=self.module, url=url, data=data, headers=headers)
|
|
||||||
status_code = info['status']
|
|
||||||
if status_code not in [200, 201, 204]:
|
|
||||||
self._fail('login', info['body'])
|
|
||||||
|
|
||||||
self.headers = {'referer': self.get_base_url(),
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Accept': 'application/json',
|
|
||||||
'Cookie': resp.info().getheader('Set-Cookie')}
|
|
||||||
except Exception:
|
|
||||||
e = get_exception()
|
|
||||||
self._fail('login', str(e))
|
|
||||||
|
|
||||||
def _fail(self, msg, e):
|
|
||||||
if 'message' in e:
|
|
||||||
err_string = e.get('message')
|
|
||||||
else:
|
|
||||||
err_string = e
|
|
||||||
self.module.fail_json(msg='%s: %s' % (msg, err_string))
|
|
||||||
|
|
||||||
def _post_json(self, method, name, item=None):
|
|
||||||
if item is None:
|
|
||||||
item = {}
|
|
||||||
url = '%s/session/json' % self.get_base_url()
|
|
||||||
data = {'method': method, 'params': [[name], item]}
|
|
||||||
try:
|
|
||||||
resp, info = fetch_url(module=self.module, url=url, data=json.dumps(data), headers=self.headers)
|
|
||||||
status_code = info['status']
|
|
||||||
if status_code not in [200, 201, 204]:
|
|
||||||
self._fail(method, info['body'])
|
|
||||||
except Exception:
|
|
||||||
e = get_exception()
|
|
||||||
self._fail('post %s' % method, str(e))
|
|
||||||
|
|
||||||
resp = json.loads(resp.read())
|
|
||||||
err = resp.get('error')
|
|
||||||
if err is not None:
|
|
||||||
self._fail('repsonse %s' % method, err)
|
|
||||||
|
|
||||||
if 'result' in resp:
|
|
||||||
result = resp.get('result')
|
|
||||||
if 'result' in result:
|
|
||||||
result = result.get('result')
|
|
||||||
if isinstance(result, list):
|
|
||||||
if len(result) > 0:
|
|
||||||
return result[0]
|
|
||||||
else:
|
|
||||||
return {}
|
|
||||||
return result
|
|
||||||
return None
|
|
||||||
|
|
||||||
def sudocmd_find(self, name):
|
def sudocmd_find(self, name):
|
||||||
return self._post_json(method='sudocmd_find', name=None, item={'all': True, 'sudocmd': name})
|
return self._post_json(method='sudocmd_find', name=None, item={'all': True, 'sudocmd': name})
|
||||||
|
@ -255,10 +182,10 @@ def main():
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
client = IPAClient(module=module,
|
client = SudoCmdIPAClient(module=module,
|
||||||
host=module.params['ipa_host'],
|
host=module.params['ipa_host'],
|
||||||
port=module.params['ipa_port'],
|
port=module.params['ipa_port'],
|
||||||
protocol=module.params['ipa_prot'])
|
protocol=module.params['ipa_prot'])
|
||||||
try:
|
try:
|
||||||
client.login(username=module.params['ipa_user'],
|
client.login(username=module.params['ipa_user'],
|
||||||
password=module.params['ipa_pass'])
|
password=module.params['ipa_pass'])
|
||||||
|
@ -271,7 +198,6 @@ def main():
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.pycompat24 import get_exception
|
from ansible.module_utils.pycompat24 import get_exception
|
||||||
from ansible.module_utils.urls import fetch_url
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -70,8 +70,6 @@ options:
|
||||||
required: false
|
required: false
|
||||||
default: true
|
default: true
|
||||||
version_added: "2.3"
|
version_added: "2.3"
|
||||||
requirements:
|
|
||||||
- json
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
EXAMPLES = '''
|
EXAMPLES = '''
|
||||||
|
@ -101,83 +99,12 @@ sudocmdgroup:
|
||||||
type: dict
|
type: dict
|
||||||
'''
|
'''
|
||||||
|
|
||||||
try:
|
from ansible.module_utils.ipa import IPAClient
|
||||||
import json
|
|
||||||
except ImportError:
|
|
||||||
import simplejson as json
|
|
||||||
|
|
||||||
|
class SudoCmdGroupIPAClient(IPAClient):
|
||||||
|
|
||||||
class IPAClient:
|
|
||||||
def __init__(self, module, host, port, protocol):
|
def __init__(self, module, host, port, protocol):
|
||||||
self.host = host
|
super(SudoCmdGroupIPAClient, self).__init__(module, host, port, protocol)
|
||||||
self.port = port
|
|
||||||
self.protocol = protocol
|
|
||||||
self.module = module
|
|
||||||
self.headers = None
|
|
||||||
|
|
||||||
def get_base_url(self):
|
|
||||||
return '%s://%s/ipa' % (self.protocol, self.host)
|
|
||||||
|
|
||||||
def get_json_url(self):
|
|
||||||
return '%s/session/json' % self.get_base_url()
|
|
||||||
|
|
||||||
def login(self, username, password):
|
|
||||||
url = '%s/session/login_password' % self.get_base_url()
|
|
||||||
data = 'user=%s&password=%s' % (username, password)
|
|
||||||
headers = {'referer': self.get_base_url(),
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
|
||||||
'Accept': 'text/plain'}
|
|
||||||
try:
|
|
||||||
resp, info = fetch_url(module=self.module, url=url, data=data, headers=headers)
|
|
||||||
status_code = info['status']
|
|
||||||
if status_code not in [200, 201, 204]:
|
|
||||||
self._fail('login', info['body'])
|
|
||||||
|
|
||||||
self.headers = {'referer': self.get_base_url(),
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Accept': 'application/json',
|
|
||||||
'Cookie': resp.info().getheader('Set-Cookie')}
|
|
||||||
except Exception:
|
|
||||||
e = get_exception()
|
|
||||||
self._fail('login', str(e))
|
|
||||||
|
|
||||||
def _fail(self, msg, e):
|
|
||||||
if 'message' in e:
|
|
||||||
err_string = e.get('message')
|
|
||||||
else:
|
|
||||||
err_string = e
|
|
||||||
self.module.fail_json(msg='%s: %s' % (msg, err_string))
|
|
||||||
|
|
||||||
def _post_json(self, method, name, item=None):
|
|
||||||
if item is None:
|
|
||||||
item = {}
|
|
||||||
url = '%s/session/json' % self.get_base_url()
|
|
||||||
data = {'method': method, 'params': [[name], item]}
|
|
||||||
try:
|
|
||||||
resp, info = fetch_url(module=self.module, url=url, data=json.dumps(data), headers=self.headers)
|
|
||||||
status_code = info['status']
|
|
||||||
if status_code not in [200, 201, 204]:
|
|
||||||
self._fail(method, info['body'])
|
|
||||||
except Exception:
|
|
||||||
e = get_exception()
|
|
||||||
self._fail('post %s' % method, str(e))
|
|
||||||
|
|
||||||
resp = json.loads(resp.read())
|
|
||||||
err = resp.get('error')
|
|
||||||
if err is not None:
|
|
||||||
self._fail('repsonse %s' % method, err)
|
|
||||||
|
|
||||||
if 'result' in resp:
|
|
||||||
result = resp.get('result')
|
|
||||||
if 'result' in result:
|
|
||||||
result = result.get('result')
|
|
||||||
if isinstance(result, list):
|
|
||||||
if len(result) > 0:
|
|
||||||
return result[0]
|
|
||||||
else:
|
|
||||||
return {}
|
|
||||||
return result
|
|
||||||
return None
|
|
||||||
|
|
||||||
def sudocmdgroup_find(self, name):
|
def sudocmdgroup_find(self, name):
|
||||||
return self._post_json(method='sudocmdgroup_find', name=None, item={'all': True, 'cn': name})
|
return self._post_json(method='sudocmdgroup_find', name=None, item={'all': True, 'cn': name})
|
||||||
|
@ -297,10 +224,10 @@ def main():
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
client = IPAClient(module=module,
|
client = SudoCmdGroupIPAClient(module=module,
|
||||||
host=module.params['ipa_host'],
|
host=module.params['ipa_host'],
|
||||||
port=module.params['ipa_port'],
|
port=module.params['ipa_port'],
|
||||||
protocol=module.params['ipa_prot'])
|
protocol=module.params['ipa_prot'])
|
||||||
try:
|
try:
|
||||||
client.login(username=module.params['ipa_user'],
|
client.login(username=module.params['ipa_user'],
|
||||||
password=module.params['ipa_pass'])
|
password=module.params['ipa_pass'])
|
||||||
|
@ -313,7 +240,6 @@ def main():
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.pycompat24 import get_exception
|
from ansible.module_utils.pycompat24 import get_exception
|
||||||
from ansible.module_utils.urls import fetch_url
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -111,8 +111,6 @@ options:
|
||||||
required: false
|
required: false
|
||||||
default: true
|
default: true
|
||||||
version_added: "2.3"
|
version_added: "2.3"
|
||||||
requirements:
|
|
||||||
- json
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
EXAMPLES = '''
|
EXAMPLES = '''
|
||||||
|
@ -153,83 +151,12 @@ sudorule:
|
||||||
type: dict
|
type: dict
|
||||||
'''
|
'''
|
||||||
|
|
||||||
try:
|
from ansible.module_utils.ipa import IPAClient
|
||||||
import json
|
|
||||||
except ImportError:
|
|
||||||
import simplejson as json
|
|
||||||
|
|
||||||
|
class SudoRuleIPAClient(IPAClient):
|
||||||
|
|
||||||
class IPAClient:
|
|
||||||
def __init__(self, module, host, port, protocol):
|
def __init__(self, module, host, port, protocol):
|
||||||
self.host = host
|
super(SudoRuleIPAClient, self).__init__(module, host, port, protocol)
|
||||||
self.port = port
|
|
||||||
self.protocol = protocol
|
|
||||||
self.module = module
|
|
||||||
self.headers = None
|
|
||||||
|
|
||||||
def get_base_url(self):
|
|
||||||
return '%s://%s/ipa' % (self.protocol, self.host)
|
|
||||||
|
|
||||||
def get_json_url(self):
|
|
||||||
return '%s/session/json' % self.get_base_url()
|
|
||||||
|
|
||||||
def login(self, username, password):
|
|
||||||
url = '%s/session/login_password' % self.get_base_url()
|
|
||||||
data = 'user=%s&password=%s' % (username, password)
|
|
||||||
headers = {'referer': self.get_base_url(),
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
|
||||||
'Accept': 'text/plain'}
|
|
||||||
try:
|
|
||||||
resp, info = fetch_url(module=self.module, url=url, data=data, headers=headers)
|
|
||||||
status_code = info['status']
|
|
||||||
if status_code not in [200, 201, 204]:
|
|
||||||
self._fail('login', info['body'])
|
|
||||||
|
|
||||||
self.headers = {'referer': self.get_base_url(),
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Accept': 'application/json',
|
|
||||||
'Cookie': resp.info().getheader('Set-Cookie')}
|
|
||||||
except Exception:
|
|
||||||
e = get_exception()
|
|
||||||
self._fail('login', str(e))
|
|
||||||
|
|
||||||
def _fail(self, msg, e):
|
|
||||||
if 'message' in e:
|
|
||||||
err_string = e.get('message')
|
|
||||||
else:
|
|
||||||
err_string = e
|
|
||||||
self.module.fail_json(msg='%s: %s' % (msg, err_string))
|
|
||||||
|
|
||||||
def _post_json(self, method, name, item=None):
|
|
||||||
if item is None:
|
|
||||||
item = {}
|
|
||||||
url = '%s/session/json' % self.get_base_url()
|
|
||||||
data = {'method': method, 'params': [[name], item]}
|
|
||||||
try:
|
|
||||||
resp, info = fetch_url(module=self.module, url=url, data=json.dumps(data), headers=self.headers)
|
|
||||||
status_code = info['status']
|
|
||||||
if status_code not in [200, 201, 204]:
|
|
||||||
self._fail(method, info['body'])
|
|
||||||
except Exception:
|
|
||||||
e = get_exception()
|
|
||||||
self._fail('post %s' % method, str(e))
|
|
||||||
|
|
||||||
resp = json.loads(resp.read())
|
|
||||||
err = resp.get('error')
|
|
||||||
if err is not None:
|
|
||||||
self._fail('repsonse %s' % method, err)
|
|
||||||
|
|
||||||
if 'result' in resp:
|
|
||||||
result = resp.get('result')
|
|
||||||
if 'result' in result:
|
|
||||||
result = result.get('result')
|
|
||||||
if isinstance(result, list):
|
|
||||||
if len(result) > 0:
|
|
||||||
return result[0]
|
|
||||||
else:
|
|
||||||
return {}
|
|
||||||
return result
|
|
||||||
return None
|
|
||||||
|
|
||||||
def sudorule_find(self, name):
|
def sudorule_find(self, name):
|
||||||
return self._post_json(method='sudorule_find', name=None, item={'all': True, 'cn': name})
|
return self._post_json(method='sudorule_find', name=None, item={'all': True, 'cn': name})
|
||||||
|
@ -368,7 +295,7 @@ def ensure(module, client):
|
||||||
if state in ['present', 'enabled']:
|
if state in ['present', 'enabled']:
|
||||||
ipaenabledflag = 'TRUE'
|
ipaenabledflag = 'TRUE'
|
||||||
else:
|
else:
|
||||||
ipaenabledflag = 'NO'
|
ipaenabledflag = 'FALSE'
|
||||||
|
|
||||||
sudoopt = module.params['sudoopt']
|
sudoopt = module.params['sudoopt']
|
||||||
user = module.params['user']
|
user = module.params['user']
|
||||||
|
@ -472,10 +399,10 @@ def main():
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
client = IPAClient(module=module,
|
client = SudoRuleIPAClient(module=module,
|
||||||
host=module.params['ipa_host'],
|
host=module.params['ipa_host'],
|
||||||
port=module.params['ipa_port'],
|
port=module.params['ipa_port'],
|
||||||
protocol=module.params['ipa_prot'])
|
protocol=module.params['ipa_prot'])
|
||||||
try:
|
try:
|
||||||
client.login(username=module.params['ipa_user'],
|
client.login(username=module.params['ipa_user'],
|
||||||
password=module.params['ipa_pass'])
|
password=module.params['ipa_pass'])
|
||||||
|
@ -488,7 +415,6 @@ def main():
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.pycompat24 import get_exception
|
from ansible.module_utils.pycompat24 import get_exception
|
||||||
from ansible.module_utils.urls import fetch_url
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
---
|
---
|
||||||
module: ipa_user
|
module: ipa_user
|
||||||
|
author: Thomas Krahn (@Nosmoht)
|
||||||
short_description: Manage FreeIPA users
|
short_description: Manage FreeIPA users
|
||||||
description:
|
description:
|
||||||
- Add, modify and delete user within IPA server
|
- Add, modify and delete user within IPA server
|
||||||
|
@ -99,7 +100,6 @@ version_added: "2.3"
|
||||||
requirements:
|
requirements:
|
||||||
- base64
|
- base64
|
||||||
- hashlib
|
- hashlib
|
||||||
- json
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
EXAMPLES = '''
|
EXAMPLES = '''
|
||||||
|
@ -139,83 +139,12 @@ user:
|
||||||
import base64
|
import base64
|
||||||
import hashlib
|
import hashlib
|
||||||
|
|
||||||
try:
|
from ansible.module_utils.ipa import IPAClient
|
||||||
import json
|
|
||||||
except ImportError:
|
|
||||||
import simplejson as json
|
|
||||||
|
|
||||||
|
class UserIPAClient(IPAClient):
|
||||||
|
|
||||||
class IPAClient:
|
|
||||||
def __init__(self, module, host, port, protocol):
|
def __init__(self, module, host, port, protocol):
|
||||||
self.host = host
|
super(UserIPAClient, self).__init__(module, host, port, protocol)
|
||||||
self.port = port
|
|
||||||
self.protocol = protocol
|
|
||||||
self.module = module
|
|
||||||
self.headers = None
|
|
||||||
|
|
||||||
def get_base_url(self):
|
|
||||||
return '%s://%s/ipa' % (self.protocol, self.host)
|
|
||||||
|
|
||||||
def get_json_url(self):
|
|
||||||
return '%s/session/json' % self.get_base_url()
|
|
||||||
|
|
||||||
def login(self, username, password):
|
|
||||||
url = '%s/session/login_password' % self.get_base_url()
|
|
||||||
data = 'user=%s&password=%s' % (username, password)
|
|
||||||
headers = {'referer': self.get_base_url(),
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
|
||||||
'Accept': 'text/plain'}
|
|
||||||
try:
|
|
||||||
resp, info = fetch_url(module=self.module, url=url, data=data, headers=headers)
|
|
||||||
status_code = info['status']
|
|
||||||
if status_code not in [200, 201, 204]:
|
|
||||||
self._fail('login', info['body'])
|
|
||||||
|
|
||||||
self.headers = {'referer': self.get_base_url(),
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Accept': 'application/json',
|
|
||||||
'Cookie': resp.info().getheader('Set-Cookie')}
|
|
||||||
except Exception:
|
|
||||||
e = get_exception()
|
|
||||||
self._fail('login', str(e))
|
|
||||||
|
|
||||||
def _fail(self, msg, e):
|
|
||||||
if 'message' in e:
|
|
||||||
err_string = e.get('message')
|
|
||||||
else:
|
|
||||||
err_string = e
|
|
||||||
self.module.fail_json(msg='%s: %s' % (msg, err_string))
|
|
||||||
|
|
||||||
def _post_json(self, method, name, item=None):
|
|
||||||
if item is None:
|
|
||||||
item = {}
|
|
||||||
url = '%s/session/json' % self.get_base_url()
|
|
||||||
data = {'method': method, 'params': [[name], item]}
|
|
||||||
try:
|
|
||||||
resp, info = fetch_url(module=self.module, url=url, data=json.dumps(data), headers=self.headers)
|
|
||||||
status_code = info['status']
|
|
||||||
if status_code not in [200, 201, 204]:
|
|
||||||
self._fail(method, info['body'])
|
|
||||||
except Exception:
|
|
||||||
e = get_exception()
|
|
||||||
self._fail('post %s' % method, str(e))
|
|
||||||
|
|
||||||
resp = json.loads(resp.read())
|
|
||||||
err = resp.get('error')
|
|
||||||
if err is not None:
|
|
||||||
self._fail('repsonse %s' % method, err)
|
|
||||||
|
|
||||||
if 'result' in resp:
|
|
||||||
result = resp.get('result')
|
|
||||||
if 'result' in result:
|
|
||||||
result = result.get('result')
|
|
||||||
if isinstance(result, list):
|
|
||||||
if len(result) > 0:
|
|
||||||
return result[0]
|
|
||||||
else:
|
|
||||||
return {}
|
|
||||||
return result
|
|
||||||
return None
|
|
||||||
|
|
||||||
def user_find(self, name):
|
def user_find(self, name):
|
||||||
return self._post_json(method='user_find', name=None, item={'all': True, 'uid': name})
|
return self._post_json(method='user_find', name=None, item={'all': True, 'uid': name})
|
||||||
|
@ -236,10 +165,11 @@ class IPAClient:
|
||||||
return self._post_json(method='user_enable', name=name)
|
return self._post_json(method='user_enable', name=name)
|
||||||
|
|
||||||
|
|
||||||
def get_user_dict(givenname=None, loginshell=None, mail=None, nsaccountlock=False, sn=None, sshpubkey=None,
|
def get_user_dict(displayname=None, givenname=None, loginshell=None, mail=None, nsaccountlock=False, sn=None,
|
||||||
telephonenumber=None,
|
sshpubkey=None, telephonenumber=None, title=None, userpassword=None):
|
||||||
title=None):
|
|
||||||
user = {}
|
user = {}
|
||||||
|
if displayname is not None:
|
||||||
|
user['displayname'] = displayname
|
||||||
if givenname is not None:
|
if givenname is not None:
|
||||||
user['givenname'] = givenname
|
user['givenname'] = givenname
|
||||||
if loginshell is not None:
|
if loginshell is not None:
|
||||||
|
@ -255,6 +185,8 @@ def get_user_dict(givenname=None, loginshell=None, mail=None, nsaccountlock=Fals
|
||||||
user['telephonenumber'] = telephonenumber
|
user['telephonenumber'] = telephonenumber
|
||||||
if title is not None:
|
if title is not None:
|
||||||
user['title'] = title
|
user['title'] = title
|
||||||
|
if userpassword is not None:
|
||||||
|
user['userpassword'] = userpassword
|
||||||
|
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
@ -265,7 +197,7 @@ def get_user_diff(ipa_user, module_user):
|
||||||
API returns everything as a list even if only a single value is possible.
|
API returns everything as a list even if only a single value is possible.
|
||||||
Therefore some more complexity is needed.
|
Therefore some more complexity is needed.
|
||||||
The method will check if the value type of module_user.attr is not a list and
|
The method will check if the value type of module_user.attr is not a list and
|
||||||
create a list with that element if the same attribute in ipa_user is list. In this way i hope that the method
|
create a list with that element if the same attribute in ipa_user is list. In this way I hope that the method
|
||||||
must not be changed if the returned API dict is changed.
|
must not be changed if the returned API dict is changed.
|
||||||
:param ipa_user:
|
:param ipa_user:
|
||||||
:param module_user:
|
:param module_user:
|
||||||
|
@ -301,7 +233,7 @@ def get_user_diff(ipa_user, module_user):
|
||||||
def get_ssh_key_fingerprint(ssh_key):
|
def get_ssh_key_fingerprint(ssh_key):
|
||||||
"""
|
"""
|
||||||
Return the public key fingerprint of a given public SSH key
|
Return the public key fingerprint of a given public SSH key
|
||||||
in format "FB:0C:AC:0A:07:94:5B:CE:75:6E:63:32:13:AD:AD:D7 (ssh-rsa)"
|
in format "FB:0C:AC:0A:07:94:5B:CE:75:6E:63:32:13:AD:AD:D7 [user@host] (ssh-rsa)"
|
||||||
:param ssh_key:
|
:param ssh_key:
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
|
@ -312,7 +244,12 @@ def get_ssh_key_fingerprint(ssh_key):
|
||||||
key = base64.b64decode(parts[1].encode('ascii'))
|
key = base64.b64decode(parts[1].encode('ascii'))
|
||||||
|
|
||||||
fp_plain = hashlib.md5(key).hexdigest()
|
fp_plain = hashlib.md5(key).hexdigest()
|
||||||
return ':'.join(a + b for a, b in zip(fp_plain[::2], fp_plain[1::2])).upper() + ' (%s)' % key_type
|
key_fp = ':'.join(a + b for a, b in zip(fp_plain[::2], fp_plain[1::2])).upper()
|
||||||
|
if len(parts) < 3:
|
||||||
|
return "%s (%s)" % (key_fp, key_type)
|
||||||
|
else:
|
||||||
|
user_host = parts[2]
|
||||||
|
return "%s %s (%s)" % (key_fp, user_host, key_type)
|
||||||
|
|
||||||
|
|
||||||
def ensure(module, client):
|
def ensure(module, client):
|
||||||
|
@ -320,10 +257,13 @@ def ensure(module, client):
|
||||||
name = module.params['name']
|
name = module.params['name']
|
||||||
nsaccountlock = state == 'disabled'
|
nsaccountlock = state == 'disabled'
|
||||||
|
|
||||||
module_user = get_user_dict(givenname=module.params.get('givenname'), loginshell=module.params['loginshell'],
|
module_user = get_user_dict(displayname=module.params.get('displayname'),
|
||||||
|
givenname=module.params.get('givenname'),
|
||||||
|
loginshell=module.params['loginshell'],
|
||||||
mail=module.params['mail'], sn=module.params['sn'],
|
mail=module.params['mail'], sn=module.params['sn'],
|
||||||
sshpubkey=module.params['sshpubkey'], nsaccountlock=nsaccountlock,
|
sshpubkey=module.params['sshpubkey'], nsaccountlock=nsaccountlock,
|
||||||
telephonenumber=module.params['telephonenumber'], title=module.params['title'])
|
telephonenumber=module.params['telephonenumber'], title=module.params['title'],
|
||||||
|
userpassword=module.params['password'])
|
||||||
|
|
||||||
ipa_user = client.user_find(name=name)
|
ipa_user = client.user_find(name=name)
|
||||||
|
|
||||||
|
@ -373,10 +313,10 @@ def main():
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
client = IPAClient(module=module,
|
client = UserIPAClient(module=module,
|
||||||
host=module.params['ipa_host'],
|
host=module.params['ipa_host'],
|
||||||
port=module.params['ipa_port'],
|
port=module.params['ipa_port'],
|
||||||
protocol=module.params['ipa_prot'])
|
protocol=module.params['ipa_prot'])
|
||||||
|
|
||||||
# If sshpubkey is defined as None than module.params['sshpubkey'] is [None]. IPA itself returns None (not a list).
|
# If sshpubkey is defined as None than module.params['sshpubkey'] is [None]. IPA itself returns None (not a list).
|
||||||
# Therefore a small check here to replace list(None) by None. Otherwise get_user_diff() would return sshpubkey
|
# Therefore a small check here to replace list(None) by None. Otherwise get_user_diff() would return sshpubkey
|
||||||
|
@ -397,7 +337,6 @@ def main():
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.pycompat24 import get_exception
|
from ansible.module_utils.pycompat24 import get_exception
|
||||||
from ansible.module_utils.urls import fetch_url
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
Loading…
Reference in a new issue