1#!/usr/bin/python
2# -*- coding: utf-8 -*-
3# Copyright: (c) 2016, Werner Dijkerman (ikben@werner-dijkerman.nl)
4# Copyright: (c) 2017, Ansible Project
5# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
6
7from __future__ import absolute_import, division, print_function
8__metaclass__ = type
9
10ANSIBLE_METADATA = {'metadata_version': '1.1',
11                    'status': ['preview'],
12                    'supported_by': 'community'}
13
14
15DOCUMENTATION = '''
16---
17module: opendj_backendprop
18short_description: Will update the backend configuration of OpenDJ via the dsconfig set-backend-prop command.
19description:
20   - This module will update settings for OpenDJ with the command set-backend-prop.
21   - It will check first via de get-backend-prop if configuration needs to be applied.
22version_added: "2.2"
23author:
24    - Werner Dijkerman (@dj-wasabi)
25options:
26    opendj_bindir:
27        description:
28            - The path to the bin directory of OpenDJ.
29        required: false
30        default: /opt/opendj/bin
31    hostname:
32        description:
33            - The hostname of the OpenDJ server.
34        required: true
35    port:
36        description:
37            - The Admin port on which the OpenDJ instance is available.
38        required: true
39    username:
40        description:
41            - The username to connect to.
42        required: false
43        default: cn=Directory Manager
44    password:
45        description:
46            - The password for the cn=Directory Manager user.
47            - Either password or passwordfile is needed.
48        required: false
49    passwordfile:
50        description:
51            - Location to the password file which holds the password for the cn=Directory Manager user.
52            - Either password or passwordfile is needed.
53        required: false
54    backend:
55        description:
56            - The name of the backend on which the property needs to be updated.
57        required: true
58    name:
59        description:
60            - The configuration setting to update.
61        required: true
62    value:
63        description:
64            - The value for the configuration item.
65        required: true
66    state:
67        description:
68            - If configuration needs to be added/updated
69        required: false
70        default: "present"
71'''
72
73EXAMPLES = '''
74  - name: "Add or update OpenDJ backend properties"
75    action: opendj_backendprop
76            hostname=localhost
77            port=4444
78            username="cn=Directory Manager"
79            password=password
80            backend=userRoot
81            name=index-entry-limit
82            value=5000
83'''
84
85RETURN = '''
86'''
87
88from ansible.module_utils.basic import AnsibleModule
89
90
91class BackendProp(object):
92
93    def __init__(self, module):
94        self._module = module
95
96    def get_property(self, opendj_bindir, hostname, port, username, password_method, backend_name):
97        my_command = [
98            opendj_bindir + '/dsconfig',
99            'get-backend-prop',
100            '-h', hostname,
101            '--port', str(port),
102            '--bindDN', username,
103            '--backend-name', backend_name,
104            '-n', '-X', '-s'
105        ] + password_method
106        rc, stdout, stderr = self._module.run_command(my_command)
107        if rc == 0:
108            return stdout
109        else:
110            self._module.fail_json(msg="Error message: " + str(stderr))
111
112    def set_property(self, opendj_bindir, hostname, port, username, password_method, backend_name, name, value):
113        my_command = [
114            opendj_bindir + '/dsconfig',
115            'set-backend-prop',
116            '-h', hostname,
117            '--port', str(port),
118            '--bindDN', username,
119            '--backend-name', backend_name,
120            '--set', name + ":" + value,
121            '-n', '-X'
122        ] + password_method
123        rc, stdout, stderr = self._module.run_command(my_command)
124        if rc == 0:
125            return True
126        else:
127            self._module.fail_json(msg="Error message: " + stderr)
128
129    def validate_data(self, data=None, name=None, value=None):
130        for config_line in data.split('\n'):
131            if config_line:
132                split_line = config_line.split()
133                if split_line[0] == name:
134                    if split_line[1] == value:
135                        return True
136        return False
137
138
139def main():
140    module = AnsibleModule(
141        argument_spec=dict(
142            opendj_bindir=dict(default="/opt/opendj/bin", type="path"),
143            hostname=dict(required=True),
144            port=dict(required=True),
145            username=dict(default="cn=Directory Manager", required=False),
146            password=dict(required=False, no_log=True),
147            passwordfile=dict(required=False, type="path"),
148            backend=dict(required=True),
149            name=dict(required=True),
150            value=dict(required=True),
151            state=dict(default="present"),
152        ),
153        supports_check_mode=True,
154        mutually_exclusive=[['password', 'passwordfile']],
155        required_one_of=[['password', 'passwordfile']]
156    )
157
158    opendj_bindir = module.params['opendj_bindir']
159    hostname = module.params['hostname']
160    port = module.params['port']
161    username = module.params['username']
162    password = module.params['password']
163    passwordfile = module.params['passwordfile']
164    backend_name = module.params['backend']
165    name = module.params['name']
166    value = module.params['value']
167    state = module.params['state']
168
169    if module.params["password"] is not None:
170        password_method = ['-w', password]
171    elif module.params["passwordfile"] is not None:
172        password_method = ['-j', passwordfile]
173
174    opendj = BackendProp(module)
175    validate = opendj.get_property(opendj_bindir=opendj_bindir,
176                                   hostname=hostname,
177                                   port=port,
178                                   username=username,
179                                   password_method=password_method,
180                                   backend_name=backend_name)
181
182    if validate:
183        if not opendj.validate_data(data=validate, name=name, value=value):
184            if module.check_mode:
185                module.exit_json(changed=True)
186            if opendj.set_property(opendj_bindir=opendj_bindir,
187                                   hostname=hostname,
188                                   port=port,
189                                   username=username,
190                                   password_method=password_method,
191                                   backend_name=backend_name,
192                                   name=name,
193                                   value=value):
194                module.exit_json(changed=True)
195            else:
196                module.exit_json(changed=False)
197        else:
198            module.exit_json(changed=False)
199    else:
200        module.exit_json(changed=False)
201
202
203if __name__ == '__main__':
204    main()
205