1#!/usr/local/bin/python3.8
2from __future__ import (absolute_import, division, print_function)
3# Copyright 2019-2020 Fortinet, Inc.
4#
5# This program is free software: you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation, either version 3 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program.  If not, see <https://www.gnu.org/licenses/>.
17
18__metaclass__ = type
19
20ANSIBLE_METADATA = {'status': ['preview'],
21                    'supported_by': 'community',
22                    'metadata_version': '1.1'}
23
24DOCUMENTATION = '''
25---
26module: fortios_switch_controller_snmp_community
27short_description: Configure FortiSwitch SNMP v1/v2c communities globally in Fortinet's FortiOS and FortiGate.
28description:
29    - This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
30      user to set and modify switch_controller feature and snmp_community category.
31      Examples include all parameters and values need to be adjusted to datasources before usage.
32      Tested with FOS v6.0.0
33version_added: "2.10"
34author:
35    - Link Zheng (@chillancezen)
36    - Jie Xue (@JieX19)
37    - Hongbin Lu (@fgtdev-hblu)
38    - Frank Shen (@frankshen01)
39    - Miguel Angel Munoz (@mamunozgonzalez)
40    - Nicolas Thomas (@thomnico)
41notes:
42    - Legacy fortiosapi has been deprecated, httpapi is the preferred way to run playbooks
43
44requirements:
45    - ansible>=2.9.0
46options:
47    access_token:
48        description:
49            - Token-based authentication.
50              Generated from GUI of Fortigate.
51        type: str
52        required: false
53    enable_log:
54        description:
55            - Enable/Disable logging for task.
56        type: bool
57        required: false
58        default: false
59    vdom:
60        description:
61            - Virtual domain, among those defined previously. A vdom is a
62              virtual instance of the FortiGate that can be configured and
63              used as a different unit.
64        type: str
65        default: root
66
67    state:
68        description:
69            - Indicates whether to create or remove the object.
70        type: str
71        required: true
72        choices:
73            - present
74            - absent
75    switch_controller_snmp_community:
76        description:
77            - Configure FortiSwitch SNMP v1/v2c communities globally.
78        default: null
79        type: dict
80        suboptions:
81            events:
82                description:
83                    - SNMP notifications (traps) to send.
84                type: list
85                choices:
86                    - cpu-high
87                    - mem-low
88                    - log-full
89                    - intf-ip
90                    - ent-conf-change
91            hosts:
92                description:
93                    - Configure IPv4 SNMP managers (hosts).
94                type: list
95                suboptions:
96                    id:
97                        description:
98                            - Host entry ID.
99                        required: true
100                        type: int
101                    ip:
102                        description:
103                            - IPv4 address of the SNMP manager (host).
104                        type: str
105            id:
106                description:
107                    - SNMP community ID.
108                required: true
109                type: int
110            name:
111                description:
112                    - SNMP community name.
113                type: str
114            query_v1_port:
115                description:
116                    - SNMP v1 query port .
117                type: int
118            query_v1_status:
119                description:
120                    - Enable/disable SNMP v1 queries.
121                type: str
122                choices:
123                    - disable
124                    - enable
125            query_v2c_port:
126                description:
127                    - SNMP v2c query port .
128                type: int
129            query_v2c_status:
130                description:
131                    - Enable/disable SNMP v2c queries.
132                type: str
133                choices:
134                    - disable
135                    - enable
136            status:
137                description:
138                    - Enable/disable this SNMP community.
139                type: str
140                choices:
141                    - disable
142                    - enable
143            trap_v1_lport:
144                description:
145                    - SNMP v2c trap local port .
146                type: int
147            trap_v1_rport:
148                description:
149                    - SNMP v2c trap remote port .
150                type: int
151            trap_v1_status:
152                description:
153                    - Enable/disable SNMP v1 traps.
154                type: str
155                choices:
156                    - disable
157                    - enable
158            trap_v2c_lport:
159                description:
160                    - SNMP v2c trap local port .
161                type: int
162            trap_v2c_rport:
163                description:
164                    - SNMP v2c trap remote port .
165                type: int
166            trap_v2c_status:
167                description:
168                    - Enable/disable SNMP v2c traps.
169                type: str
170                choices:
171                    - disable
172                    - enable
173'''
174
175EXAMPLES = '''
176- hosts: fortigates
177  collections:
178    - fortinet.fortios
179  connection: httpapi
180  vars:
181   vdom: "root"
182   ansible_httpapi_use_ssl: yes
183   ansible_httpapi_validate_certs: no
184   ansible_httpapi_port: 443
185  tasks:
186  - name: Configure FortiSwitch SNMP v1/v2c communities globally.
187    fortios_switch_controller_snmp_community:
188      vdom:  "{{ vdom }}"
189      state: "present"
190      access_token: "<your_own_value>"
191      switch_controller_snmp_community:
192        events: "cpu-high"
193        hosts:
194         -
195            id:  "5"
196            ip: "<your_own_value>"
197        id:  "7"
198        name: "default_name_8"
199        query_v1_port: "9"
200        query_v1_status: "disable"
201        query_v2c_port: "11"
202        query_v2c_status: "disable"
203        status: "disable"
204        trap_v1_lport: "14"
205        trap_v1_rport: "15"
206        trap_v1_status: "disable"
207        trap_v2c_lport: "17"
208        trap_v2c_rport: "18"
209        trap_v2c_status: "disable"
210
211'''
212
213RETURN = '''
214build:
215  description: Build number of the fortigate image
216  returned: always
217  type: str
218  sample: '1547'
219http_method:
220  description: Last method used to provision the content into FortiGate
221  returned: always
222  type: str
223  sample: 'PUT'
224http_status:
225  description: Last result given by FortiGate on last operation applied
226  returned: always
227  type: str
228  sample: "200"
229mkey:
230  description: Master key (id) used in the last call to FortiGate
231  returned: success
232  type: str
233  sample: "id"
234name:
235  description: Name of the table used to fulfill the request
236  returned: always
237  type: str
238  sample: "urlfilter"
239path:
240  description: Path of the table used to fulfill the request
241  returned: always
242  type: str
243  sample: "webfilter"
244revision:
245  description: Internal revision number
246  returned: always
247  type: str
248  sample: "17.0.2.10658"
249serial:
250  description: Serial number of the unit
251  returned: always
252  type: str
253  sample: "FGVMEVYYQT3AB5352"
254status:
255  description: Indication of the operation's result
256  returned: always
257  type: str
258  sample: "success"
259vdom:
260  description: Virtual domain used
261  returned: always
262  type: str
263  sample: "root"
264version:
265  description: Version of the FortiGate
266  returned: always
267  type: str
268  sample: "v5.6.3"
269
270'''
271from ansible.module_utils.basic import AnsibleModule
272from ansible.module_utils.connection import Connection
273from ansible_collections.fortinet.fortios.plugins.module_utils.fortios.fortios import FortiOSHandler
274from ansible_collections.fortinet.fortios.plugins.module_utils.fortios.fortios import check_legacy_fortiosapi
275from ansible_collections.fortinet.fortios.plugins.module_utils.fortios.fortios import schema_to_module_spec
276from ansible_collections.fortinet.fortios.plugins.module_utils.fortios.fortios import check_schema_versioning
277from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FAIL_SOCKET_MSG
278from ansible_collections.fortinet.fortios.plugins.module_utils.fortios.comparison import is_same_comparison
279from ansible_collections.fortinet.fortios.plugins.module_utils.fortios.comparison import serialize
280
281
282def filter_switch_controller_snmp_community_data(json):
283    option_list = ['events', 'hosts', 'id',
284                   'name', 'query_v1_port', 'query_v1_status',
285                   'query_v2c_port', 'query_v2c_status', 'status',
286                   'trap_v1_lport', 'trap_v1_rport', 'trap_v1_status',
287                   'trap_v2c_lport', 'trap_v2c_rport', 'trap_v2c_status']
288    dictionary = {}
289
290    for attribute in option_list:
291        if attribute in json and json[attribute] is not None:
292            dictionary[attribute] = json[attribute]
293
294    return dictionary
295
296
297def flatten_single_path(data, path, index):
298    if not data or index == len(path) or path[index] not in data or not data[path[index]]:
299        return
300
301    if index == len(path) - 1:
302        data[path[index]] = ' '.join(str(elem) for elem in data[path[index]])
303    elif isinstance(data[path[index]], list):
304        for value in data[path[index]]:
305            flatten_single_path(value, path, index + 1)
306    else:
307        flatten_single_path(data[path[index]], path, index + 1)
308
309
310def flatten_multilists_attributes(data):
311    multilist_attrs = [[u'events']]
312
313    for attr in multilist_attrs:
314        flatten_single_path(data, attr, 0)
315
316    return data
317
318
319def underscore_to_hyphen(data):
320    if isinstance(data, list):
321        for i, elem in enumerate(data):
322            data[i] = underscore_to_hyphen(elem)
323    elif isinstance(data, dict):
324        new_data = {}
325        for k, v in data.items():
326            new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
327        data = new_data
328
329    return data
330
331
332def switch_controller_snmp_community(data, fos, check_mode=False):
333
334    vdom = data['vdom']
335
336    state = data['state']
337
338    switch_controller_snmp_community_data = data['switch_controller_snmp_community']
339    switch_controller_snmp_community_data = flatten_multilists_attributes(switch_controller_snmp_community_data)
340    filtered_data = underscore_to_hyphen(filter_switch_controller_snmp_community_data(switch_controller_snmp_community_data))
341
342    # check_mode starts from here
343    if check_mode:
344        mkey = fos.get_mkey('system', 'interface', filtered_data, vdom=vdom)
345        current_data = fos.get('system', 'interface', vdom=vdom, mkey=mkey)
346        is_existed = current_data and current_data.get('http_status') == 200 \
347            and isinstance(current_data.get('results'), list) \
348            and len(current_data['results']) > 0
349
350        # 2. if it exists and the state is 'present' then compare current settings with desired
351        if state == 'present' or state is True:
352            if mkey is None:
353                return False, True, filtered_data
354
355            # if mkey exists then compare each other
356            # record exits and they're matched or not
357            if is_existed:
358                is_same = is_same_comparison(
359                    serialize(current_data['results'][0]), serialize(filtered_data))
360                return False, not is_same, filtered_data
361
362            # record does not exist
363            return False, True, filtered_data
364
365        if state == 'absent':
366            if mkey is None:
367                return False, False, filtered_data
368
369            if is_existed:
370                return False, True, filtered_data
371            return False, False, filtered_data
372
373        return True, False, {'reason: ': 'Must provide state parameter'}
374
375    if state == "present" or state is True:
376        return fos.set('switch-controller',
377                       'snmp-community',
378                       data=filtered_data,
379                       vdom=vdom)
380
381    elif state == "absent":
382        return fos.delete('switch-controller',
383                          'snmp-community',
384                          mkey=filtered_data['id'],
385                          vdom=vdom)
386    else:
387        fos._module.fail_json(msg='state must be present or absent!')
388
389
390def is_successful_status(status):
391    return status['status'] == "success" or \
392        status['http_method'] == "DELETE" and status['http_status'] == 404
393
394
395def fortios_switch_controller(data, fos, check_mode):
396
397    if data['switch_controller_snmp_community']:
398        resp = switch_controller_snmp_community(data, fos, check_mode)
399    else:
400        fos._module.fail_json(msg='missing task body: %s' % ('switch_controller_snmp_community'))
401    if check_mode:
402        return resp
403    return not is_successful_status(resp), \
404        resp['status'] == "success" and \
405        (resp['revision_changed'] if 'revision_changed' in resp else True), \
406        resp
407
408
409versioned_schema = {
410    "type": "list",
411    "children": {
412        "status": {
413            "type": "string",
414            "options": [
415                {
416                    "value": "disable",
417                    "revisions": {
418                        "v7.0.0": True,
419                        "v6.4.4": True,
420                        "v6.4.0": True,
421                        "v6.4.1": True,
422                        "v6.2.0": True,
423                        "v6.2.3": True,
424                        "v6.2.5": True,
425                        "v6.2.7": True
426                    }
427                },
428                {
429                    "value": "enable",
430                    "revisions": {
431                        "v7.0.0": True,
432                        "v6.4.4": True,
433                        "v6.4.0": True,
434                        "v6.4.1": True,
435                        "v6.2.0": True,
436                        "v6.2.3": True,
437                        "v6.2.5": True,
438                        "v6.2.7": True
439                    }
440                }
441            ],
442            "revisions": {
443                "v7.0.0": True,
444                "v6.4.4": True,
445                "v6.4.0": True,
446                "v6.4.1": True,
447                "v6.2.0": True,
448                "v6.2.3": True,
449                "v6.2.5": True,
450                "v6.2.7": True
451            }
452        },
453        "query_v1_port": {
454            "type": "integer",
455            "revisions": {
456                "v7.0.0": True,
457                "v6.4.4": True,
458                "v6.4.0": True,
459                "v6.4.1": True,
460                "v6.2.0": True,
461                "v6.2.3": True,
462                "v6.2.5": True,
463                "v6.2.7": True
464            }
465        },
466        "name": {
467            "type": "string",
468            "revisions": {
469                "v7.0.0": True,
470                "v6.4.4": True,
471                "v6.4.0": True,
472                "v6.4.1": True,
473                "v6.2.0": True,
474                "v6.2.3": True,
475                "v6.2.5": True,
476                "v6.2.7": True
477            }
478        },
479        "query_v1_status": {
480            "type": "string",
481            "options": [
482                {
483                    "value": "disable",
484                    "revisions": {
485                        "v7.0.0": True,
486                        "v6.4.4": True,
487                        "v6.4.0": True,
488                        "v6.4.1": True,
489                        "v6.2.0": True,
490                        "v6.2.3": True,
491                        "v6.2.5": True,
492                        "v6.2.7": True
493                    }
494                },
495                {
496                    "value": "enable",
497                    "revisions": {
498                        "v7.0.0": True,
499                        "v6.4.4": True,
500                        "v6.4.0": True,
501                        "v6.4.1": True,
502                        "v6.2.0": True,
503                        "v6.2.3": True,
504                        "v6.2.5": True,
505                        "v6.2.7": True
506                    }
507                }
508            ],
509            "revisions": {
510                "v7.0.0": True,
511                "v6.4.4": True,
512                "v6.4.0": True,
513                "v6.4.1": True,
514                "v6.2.0": True,
515                "v6.2.3": True,
516                "v6.2.5": True,
517                "v6.2.7": True
518            }
519        },
520        "id": {
521            "type": "integer",
522            "revisions": {
523                "v7.0.0": True,
524                "v6.4.4": True,
525                "v6.4.0": True,
526                "v6.4.1": True,
527                "v6.2.0": True,
528                "v6.2.3": True,
529                "v6.2.5": True,
530                "v6.2.7": True
531            }
532        },
533        "trap_v2c_rport": {
534            "type": "integer",
535            "revisions": {
536                "v7.0.0": True,
537                "v6.4.4": True,
538                "v6.4.0": True,
539                "v6.4.1": True,
540                "v6.2.0": True,
541                "v6.2.3": True,
542                "v6.2.5": True,
543                "v6.2.7": True
544            }
545        },
546        "hosts": {
547            "type": "list",
548            "children": {
549                "ip": {
550                    "type": "string",
551                    "revisions": {
552                        "v7.0.0": True,
553                        "v6.4.4": True,
554                        "v6.4.0": True,
555                        "v6.4.1": True,
556                        "v6.2.0": True,
557                        "v6.2.3": True,
558                        "v6.2.5": True,
559                        "v6.2.7": True
560                    }
561                },
562                "id": {
563                    "type": "integer",
564                    "revisions": {
565                        "v7.0.0": True,
566                        "v6.4.4": True,
567                        "v6.4.0": True,
568                        "v6.4.1": True,
569                        "v6.2.0": True,
570                        "v6.2.3": True,
571                        "v6.2.5": True,
572                        "v6.2.7": True
573                    }
574                }
575            },
576            "revisions": {
577                "v7.0.0": True,
578                "v6.4.4": True,
579                "v6.4.0": True,
580                "v6.4.1": True,
581                "v6.2.0": True,
582                "v6.2.3": True,
583                "v6.2.5": True,
584                "v6.2.7": True
585            }
586        },
587        "trap_v1_status": {
588            "type": "string",
589            "options": [
590                {
591                    "value": "disable",
592                    "revisions": {
593                        "v7.0.0": True,
594                        "v6.4.4": True,
595                        "v6.4.0": True,
596                        "v6.4.1": True,
597                        "v6.2.0": True,
598                        "v6.2.3": True,
599                        "v6.2.5": True,
600                        "v6.2.7": True
601                    }
602                },
603                {
604                    "value": "enable",
605                    "revisions": {
606                        "v7.0.0": True,
607                        "v6.4.4": True,
608                        "v6.4.0": True,
609                        "v6.4.1": True,
610                        "v6.2.0": True,
611                        "v6.2.3": True,
612                        "v6.2.5": True,
613                        "v6.2.7": True
614                    }
615                }
616            ],
617            "revisions": {
618                "v7.0.0": True,
619                "v6.4.4": True,
620                "v6.4.0": True,
621                "v6.4.1": True,
622                "v6.2.0": True,
623                "v6.2.3": True,
624                "v6.2.5": True,
625                "v6.2.7": True
626            }
627        },
628        "trap_v1_lport": {
629            "type": "integer",
630            "revisions": {
631                "v7.0.0": True,
632                "v6.4.4": True,
633                "v6.4.0": True,
634                "v6.4.1": True,
635                "v6.2.0": True,
636                "v6.2.3": True,
637                "v6.2.5": True,
638                "v6.2.7": True
639            }
640        },
641        "trap_v2c_status": {
642            "type": "string",
643            "options": [
644                {
645                    "value": "disable",
646                    "revisions": {
647                        "v7.0.0": True,
648                        "v6.4.4": True,
649                        "v6.4.0": True,
650                        "v6.4.1": True,
651                        "v6.2.0": True,
652                        "v6.2.3": True,
653                        "v6.2.5": True,
654                        "v6.2.7": True
655                    }
656                },
657                {
658                    "value": "enable",
659                    "revisions": {
660                        "v7.0.0": True,
661                        "v6.4.4": True,
662                        "v6.4.0": True,
663                        "v6.4.1": True,
664                        "v6.2.0": True,
665                        "v6.2.3": True,
666                        "v6.2.5": True,
667                        "v6.2.7": True
668                    }
669                }
670            ],
671            "revisions": {
672                "v7.0.0": True,
673                "v6.4.4": True,
674                "v6.4.0": True,
675                "v6.4.1": True,
676                "v6.2.0": True,
677                "v6.2.3": True,
678                "v6.2.5": True,
679                "v6.2.7": True
680            }
681        },
682        "trap_v1_rport": {
683            "type": "integer",
684            "revisions": {
685                "v7.0.0": True,
686                "v6.4.4": True,
687                "v6.4.0": True,
688                "v6.4.1": True,
689                "v6.2.0": True,
690                "v6.2.3": True,
691                "v6.2.5": True,
692                "v6.2.7": True
693            }
694        },
695        "events": {
696            "multiple_values": True,
697            "type": "list",
698            "options": [
699                {
700                    "value": "cpu-high",
701                    "revisions": {
702                        "v7.0.0": True,
703                        "v6.4.4": True,
704                        "v6.4.0": True,
705                        "v6.4.1": True,
706                        "v6.2.0": True,
707                        "v6.2.3": True,
708                        "v6.2.5": True,
709                        "v6.2.7": True
710                    }
711                },
712                {
713                    "value": "mem-low",
714                    "revisions": {
715                        "v7.0.0": True,
716                        "v6.4.4": True,
717                        "v6.4.0": True,
718                        "v6.4.1": True,
719                        "v6.2.0": True,
720                        "v6.2.3": True,
721                        "v6.2.5": True,
722                        "v6.2.7": True
723                    }
724                },
725                {
726                    "value": "log-full",
727                    "revisions": {
728                        "v7.0.0": True,
729                        "v6.4.4": True,
730                        "v6.4.0": True,
731                        "v6.4.1": True,
732                        "v6.2.0": True,
733                        "v6.2.3": True,
734                        "v6.2.5": True,
735                        "v6.2.7": True
736                    }
737                },
738                {
739                    "value": "intf-ip",
740                    "revisions": {
741                        "v7.0.0": True,
742                        "v6.4.4": True,
743                        "v6.4.0": True,
744                        "v6.4.1": True,
745                        "v6.2.0": True,
746                        "v6.2.3": True,
747                        "v6.2.5": True,
748                        "v6.2.7": True
749                    }
750                },
751                {
752                    "value": "ent-conf-change",
753                    "revisions": {
754                        "v7.0.0": True,
755                        "v6.4.4": True,
756                        "v6.4.0": True,
757                        "v6.4.1": True,
758                        "v6.2.0": True,
759                        "v6.2.3": True,
760                        "v6.2.5": True,
761                        "v6.2.7": True
762                    }
763                }
764            ],
765            "revisions": {
766                "v7.0.0": True,
767                "v6.4.4": True,
768                "v6.4.0": True,
769                "v6.4.1": True,
770                "v6.2.0": True,
771                "v6.2.3": True,
772                "v6.2.5": True,
773                "v6.2.7": True
774            }
775        },
776        "query_v2c_status": {
777            "type": "string",
778            "options": [
779                {
780                    "value": "disable",
781                    "revisions": {
782                        "v7.0.0": True,
783                        "v6.4.4": True,
784                        "v6.4.0": True,
785                        "v6.4.1": True,
786                        "v6.2.0": True,
787                        "v6.2.3": True,
788                        "v6.2.5": True,
789                        "v6.2.7": True
790                    }
791                },
792                {
793                    "value": "enable",
794                    "revisions": {
795                        "v7.0.0": True,
796                        "v6.4.4": True,
797                        "v6.4.0": True,
798                        "v6.4.1": True,
799                        "v6.2.0": True,
800                        "v6.2.3": True,
801                        "v6.2.5": True,
802                        "v6.2.7": True
803                    }
804                }
805            ],
806            "revisions": {
807                "v7.0.0": True,
808                "v6.4.4": True,
809                "v6.4.0": True,
810                "v6.4.1": True,
811                "v6.2.0": True,
812                "v6.2.3": True,
813                "v6.2.5": True,
814                "v6.2.7": True
815            }
816        },
817        "trap_v2c_lport": {
818            "type": "integer",
819            "revisions": {
820                "v7.0.0": True,
821                "v6.4.4": True,
822                "v6.4.0": True,
823                "v6.4.1": True,
824                "v6.2.0": True,
825                "v6.2.3": True,
826                "v6.2.5": True,
827                "v6.2.7": True
828            }
829        },
830        "query_v2c_port": {
831            "type": "integer",
832            "revisions": {
833                "v7.0.0": True,
834                "v6.4.4": True,
835                "v6.4.0": True,
836                "v6.4.1": True,
837                "v6.2.0": True,
838                "v6.2.3": True,
839                "v6.2.5": True,
840                "v6.2.7": True
841            }
842        }
843    },
844    "revisions": {
845        "v7.0.0": True,
846        "v6.4.4": True,
847        "v6.4.0": True,
848        "v6.4.1": True,
849        "v6.2.0": True,
850        "v6.2.3": True,
851        "v6.2.5": True,
852        "v6.2.7": True
853    }
854}
855
856
857def main():
858    module_spec = schema_to_module_spec(versioned_schema)
859    mkeyname = 'id'
860    fields = {
861        "access_token": {"required": False, "type": "str", "no_log": True},
862        "enable_log": {"required": False, "type": bool},
863        "vdom": {"required": False, "type": "str", "default": "root"},
864        "state": {"required": True, "type": "str",
865                  "choices": ["present", "absent"]},
866        "switch_controller_snmp_community": {
867            "required": False, "type": "dict", "default": None,
868            "options": {
869            }
870        }
871    }
872    for attribute_name in module_spec['options']:
873        fields["switch_controller_snmp_community"]['options'][attribute_name] = module_spec['options'][attribute_name]
874        if mkeyname and mkeyname == attribute_name:
875            fields["switch_controller_snmp_community"]['options'][attribute_name]['required'] = True
876
877    check_legacy_fortiosapi()
878    module = AnsibleModule(argument_spec=fields,
879                           supports_check_mode=True)
880
881    versions_check_result = None
882    if module._socket_path:
883        connection = Connection(module._socket_path)
884        if 'access_token' in module.params:
885            connection.set_option('access_token', module.params['access_token'])
886
887        if 'enable_log' in module.params:
888            connection.set_option('enable_log', module.params['enable_log'])
889        else:
890            connection.set_option('enable_log', False)
891        fos = FortiOSHandler(connection, module, mkeyname)
892        versions_check_result = check_schema_versioning(fos, versioned_schema, "switch_controller_snmp_community")
893
894        is_error, has_changed, result = fortios_switch_controller(module.params, fos, module.check_mode)
895
896    else:
897        module.fail_json(**FAIL_SOCKET_MSG)
898
899    if versions_check_result and versions_check_result['matched'] is False:
900        module.warn("Ansible has detected version mismatch between FortOS system and your playbook, see more details by specifying option -vvv")
901
902    if not is_error:
903        if versions_check_result and versions_check_result['matched'] is False:
904            module.exit_json(changed=has_changed, version_check_warning=versions_check_result, meta=result)
905        else:
906            module.exit_json(changed=has_changed, meta=result)
907    else:
908        if versions_check_result and versions_check_result['matched'] is False:
909            module.fail_json(msg="Error in repo", version_check_warning=versions_check_result, meta=result)
910        else:
911            module.fail_json(msg="Error in repo", meta=result)
912
913
914if __name__ == '__main__':
915    main()
916