1#!/usr/bin/python
2# -*- coding: utf-8 -*-
3
4# (c) 2019, Simon Dodsley (simon@purestorage.com)
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
14DOCUMENTATION = r'''
15---
16module: purefa_snmp
17version_added: '2.9'
18short_description: Configure FlashArray SNMP Managers
19description:
20- Manage SNMP managers on a Pure Storage FlashArray.
21- Changing of a named SNMP managers version is not supported.
22- This module is not idempotent and will always modify an
23  existing SNMP manager due to hidden parameters that cannot
24  be compared to the play parameters.
25author:
26- Pure Storage Ansible Team (@sdodsley) <pure-ansible-team@purestorage.com>
27options:
28  name:
29    description:
30    - Name of SNMP Manager
31    required: True
32    type: str
33  state:
34    description:
35    - Create or delete SNMP manager
36    type: str
37    default: present
38    choices: [ absent, present ]
39  auth_passphrase:
40    type: str
41    description:
42    - SNMPv3 only. Passphrase of 8 - 32 characters.
43  auth_protocol:
44    type: str
45    description:
46    - SNMP v3 only. Hash algorithm to use
47    choices: [ MD5, SHA ]
48  community:
49    type: str
50    description:
51    - SNMP v2c only. Manager community ID. Between 1 and 32 characters long.
52  host:
53    type: str
54    description:
55    - IPv4 or IPv6 address or FQDN to send trap messages to.
56  user:
57    type: str
58    description:
59    - SNMP v3 only. User ID recognized by the specified SNMP manager.
60      Must be between 1 and 32 characters.
61  version:
62    type: str
63    description:
64    - Version of SNMP protocol to use for the manager.
65    choices: [ v2c, v3 ]
66    default: v2c
67  notification:
68    type: str
69    description:
70    - Action to perform on event.
71    default: trap
72    choices: [ inform, trap ]
73  privacy_passphrase:
74    type: str
75    description:
76    - SNMPv3 only. Passphrase to encrypt SNMP messages.
77      Must be between 8 and 63 non-space ASCII characters.
78  privacy_protocol:
79    type: str
80    description:
81    - SNMP v3 only. Encryption protocol to use
82    choices: [ AES, DES ]
83extends_documentation_fragment:
84- purestorage.fa
85'''
86
87EXAMPLES = r'''
88- name: Delete existing SNMP manager
89  purefa_snmp:
90    name: manager1
91    state: absent
92    fa_url: 10.10.10.2
93    api_token: e31060a7-21fc-e277-6240-25983c6c4592
94
95- name: Create v2c SNMP manager
96  purefa_snmp:
97    name: manager1
98    community: public
99    host: 10.21.22.23
100    fa_url: 10.10.10.2
101    api_token: e31060a7-21fc-e277-6240-25983c6c4592
102
103- name: Create v3 SNMP manager
104  purefa_snmp:
105    name: manager2
106    version: v3
107    auth_protocol: MD5
108    auth_passphrase: password
109    host: 10.21.22.23
110    fa_url: 10.10.10.2
111    api_token: e31060a7-21fc-e277-6240-25983c6c4592
112
113- name: Update existing SNMP manager
114  purefa_snmp:
115    name: manager1
116    community: private
117    fa_url: 10.10.10.2
118    api_token: e31060a7-21fc-e277-6240-25983c6c4592
119'''
120
121RETURN = r'''
122'''
123
124
125from ansible.module_utils.basic import AnsibleModule
126from ansible.module_utils.pure import get_system, purefa_argument_spec
127
128
129def update_manager(module, array):
130    """Update SNMP Manager"""
131    changed = True
132    if not module.check_mode:
133        try:
134            mgr = array.get_snmp_manager(module.params['name'])
135        except Exception:
136            module.fail_json(msg="Failed to get current configuration for SNMP manager {0}.".format(module.params['name']))
137        if mgr['version'] != module.params['version']:
138            module.fail_json(msg="Changing an SNMP managers version is not supported.")
139        elif module.params['version'] == "v2c":
140            try:
141                array.set_snmp_manager(module.params['name'],
142                                       community=module.params['community'],
143                                       notification=module.params['notification'],
144                                       host=module.params['host']
145                                       )
146            except Exception:
147                module.fail_json(msg="Failed to update SNMP manager {0}.".format(module.params['name']))
148        else:
149            if module.params['auth_protocol'] and module.params['privacy_protocol']:
150                try:
151                    array.set_snmp_manager(module.params['name'],
152                                           auth_passphrase=module.params['auth_passphrase'],
153                                           auth_protocol=module.params['auth_protocol'],
154                                           privacy_passphrase=module.params['privacy_passphrase'],
155                                           privacy_protocol=module.params['privacy_protocol'],
156                                           notification=module.params['notification'],
157                                           user=module.params['user'],
158                                           host=module.params['host']
159                                           )
160                except Exception:
161                    module.fail_json(msg="Failed to update SNMP manager {0}.".format(module.params['name']))
162            elif module.params['auth_protocol'] and not module.params['privacy_protocol']:
163                try:
164                    array.set_snmp_manager(module.params['name'],
165                                           version=module.params['version'],
166                                           auth_passphrase=module.params['auth_passphrase'],
167                                           auth_protocol=module.params['auth_protocol'],
168                                           notification=module.params['notification'],
169                                           user=module.params['user'],
170                                           host=module.params['host']
171                                           )
172                except Exception:
173                    module.fail_json(msg="Failed to update SNMP manager {0}.".format(module.params['name']))
174            elif not module.params['auth_protocol'] and module.params['privacy_protocol']:
175                try:
176                    array.set_snmp_manager(module.params['name'],
177                                           version=module.params['version'],
178                                           privacy_passphrase=module.params['privacy_passphrase'],
179                                           privacy_protocol=module.params['privacy_protocol'],
180                                           notification=module.params['notification'],
181                                           user=module.params['user'],
182                                           host=module.params['host']
183                                           )
184                except Exception:
185                    module.fail_json(msg="Failed to update SNMP manager {0}.".format(module.params['name']))
186            elif not module.params['auth_protocol'] and not module.params['privacy_protocol']:
187                try:
188                    array.set_snmp_manager(module.params['name'],
189                                           version=module.params['version'],
190                                           notification=module.params['notification'],
191                                           user=module.params['user'],
192                                           host=module.params['host']
193                                           )
194                except Exception:
195                    module.fail_json(msg="Failed to update SNMP manager {0}.".format(module.params['name']))
196            else:
197                module.fail_json(msg="Invalid parameters selected in update. Please raise issue in Ansible GitHub")
198
199    module.exit_json(changed=changed)
200
201
202def delete_manager(module, array):
203    """Delete SNMP Manager"""
204    changed = True
205    if not module.check_mode:
206        try:
207            array.delete_snmp_manager(module.params['name'])
208        except Exception:
209            module.fail_json(msg='Delete SNMP manager {0} failed'.format(module.params['name']))
210    module.exit_json(changed=changed)
211
212
213def create_manager(module, array):
214    """Create SNMP Manager"""
215    changed = True
216    if not module.check_mode:
217        if module.params['version'] == "v2c":
218            try:
219                array.create_snmp_manager(module.params['name'],
220                                          version=module.params['version'],
221                                          community=module.params['community'],
222                                          notification=module.params['notification'],
223                                          host=module.params['host']
224                                          )
225            except Exception:
226                module.fail_json(msg="Failed to create SNMP manager {0}.".format(module.params['name']))
227        else:
228            if module.params['auth_protocol'] and module.params['privacy_protocol']:
229                try:
230                    array.create_snmp_manager(module.params['name'],
231                                              version=module.params['version'],
232                                              auth_passphrase=module.params['auth_passphrase'],
233                                              auth_protocol=module.params['auth_protocol'],
234                                              privacy_passphrase=module.params['privacy_passphrase'],
235                                              privacy_protocol=module.params['privacy_protocol'],
236                                              notification=module.params['notification'],
237                                              user=module.params['user'],
238                                              host=module.params['host']
239                                              )
240                except Exception:
241                    module.fail_json(msg="Failed to create SNMP manager {0}.".format(module.params['name']))
242            elif module.params['auth_protocol'] and not module.params['privacy_protocol']:
243                try:
244                    array.create_snmp_manager(module.params['name'],
245                                              version=module.params['version'],
246                                              auth_passphrase=module.params['auth_passphrase'],
247                                              auth_protocol=module.params['auth_protocol'],
248                                              notification=module.params['notification'],
249                                              user=module.params['user'],
250                                              host=module.params['host']
251                                              )
252                except Exception:
253                    module.fail_json(msg="Failed to create SNMP manager {0}.".format(module.params['name']))
254            elif not module.params['auth_protocol'] and module.params['privacy_protocol']:
255                try:
256                    array.create_snmp_manager(module.params['name'],
257                                              version=module.params['version'],
258                                              privacy_passphrase=module.params['privacy_passphrase'],
259                                              privacy_protocol=module.params['privacy_protocol'],
260                                              notification=module.params['notification'],
261                                              user=module.params['user'],
262                                              host=module.params['host']
263                                              )
264                except Exception:
265                    module.fail_json(msg="Failed to create SNMP manager {0}.".format(module.params['name']))
266            elif not module.params['auth_protocol'] and not module.params['privacy_protocol']:
267                try:
268                    array.create_snmp_manager(module.params['name'],
269                                              version=module.params['version'],
270                                              notification=module.params['notification'],
271                                              user=module.params['user'],
272                                              host=module.params['host']
273                                              )
274                except Exception:
275                    module.fail_json(msg="Failed to create SNMP manager {0}.".format(module.params['name']))
276            else:
277                module.fail_json(msg="Invalid parameters selected in create. Please raise issue in Ansible GitHub")
278    module.exit_json(changed=changed)
279
280
281def main():
282    argument_spec = purefa_argument_spec()
283    argument_spec.update(dict(
284        name=dict(type='str', required=True),
285        host=dict(type='str'),
286        state=dict(type='str', default='present', choices=['absent', 'present']),
287        user=dict(type='str'),
288        notification=dict(type='str', choices=['inform', 'trap'], default='trap'),
289        auth_passphrase=dict(type='str', no_log=True),
290        auth_protocol=dict(type='str', choices=['MD5', 'SHA']),
291        privacy_passphrase=dict(type='str', no_log=True),
292        privacy_protocol=dict(type='str', choices=['AES', 'DES']),
293        version=dict(type='str', default='v2c', choices=['v2c', 'v3']),
294        community=dict(type='str'),
295    ))
296
297    required_together = [['auth_passphrase', 'auth_protocol'],
298                         ['privacy_passphrase', 'privacy_protocol']]
299    required_if = [['version', 'v2c', ['community', 'host']],
300                   ['version', 'v3', ['host', 'user']]]
301
302    module = AnsibleModule(argument_spec,
303                           required_together=required_together,
304                           required_if=required_if,
305                           supports_check_mode=True)
306
307    state = module.params['state']
308    array = get_system(module)
309    mgr_configured = False
310    mgrs = array.list_snmp_managers()
311    for mgr in range(0, len(mgrs)):
312        if mgrs[mgr]['name'] == module.params['name']:
313            mgr_configured = True
314            break
315    if module.params['version'] == "v3":
316        if module.params['auth_passphrase'] and (8 > len(module.params['auth_passphrase']) > 32):
317            module.fail_json(msg="auth_password must be between 8 and 32 characters")
318        if module.params['privacy_passphrase'] and 8 > len(module.params['privacy_passphrase']) > 63:
319            module.fail_json(msg="privacy_password must be between 8 and 63 characters")
320    if state == 'absent' and mgr_configured:
321        delete_manager(module, array)
322    elif mgr_configured and state == 'present':
323        update_manager(module, array)
324    elif not mgr_configured and state == 'present':
325        create_manager(module, array)
326    else:
327        module.exit_json(changed=False)
328
329
330if __name__ == '__main__':
331    main()
332