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_firewall_policy64
27short_description: Configure IPv6 to IPv4 policies 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 firewall feature and policy64 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    firewall_policy64:
76        description:
77            - Configure IPv6 to IPv4 policies.
78        default: null
79        type: dict
80        suboptions:
81            action:
82                description:
83                    - Policy action.
84                type: str
85                choices:
86                    - accept
87                    - deny
88            comments:
89                description:
90                    - Comment.
91                type: str
92            dstaddr:
93                description:
94                    - Destination address name.
95                type: list
96                suboptions:
97                    name:
98                        description:
99                            - Address name. Source firewall.address.name firewall.addrgrp.name firewall.vip64.name firewall.vipgrp64.name.
100                        required: true
101                        type: str
102            dstintf:
103                description:
104                    - Destination interface name. Source system.interface.name system.zone.name.
105                type: str
106            fixedport:
107                description:
108                    - Enable/disable policy fixed port.
109                type: str
110                choices:
111                    - enable
112                    - disable
113            ippool:
114                description:
115                    - Enable/disable policy64 IP pool.
116                type: str
117                choices:
118                    - enable
119                    - disable
120            logtraffic:
121                description:
122                    - Enable/disable policy log traffic.
123                type: str
124                choices:
125                    - enable
126                    - disable
127            logtraffic_start:
128                description:
129                    - Record logs when a session starts and ends.
130                type: str
131                choices:
132                    - enable
133                    - disable
134            name:
135                description:
136                    - Policy name.
137                type: str
138            per_ip_shaper:
139                description:
140                    - Per-IP traffic shaper. Source firewall.shaper.per-ip-shaper.name.
141                type: str
142            permit_any_host:
143                description:
144                    - Enable/disable permit any host in.
145                type: str
146                choices:
147                    - enable
148                    - disable
149            policyid:
150                description:
151                    - Policy ID.
152                required: true
153                type: int
154            poolname:
155                description:
156                    - Policy IP pool names.
157                type: list
158                suboptions:
159                    name:
160                        description:
161                            - IP pool name. Source firewall.ippool.name.
162                        required: true
163                        type: str
164            schedule:
165                description:
166                    - Schedule name. Source firewall.schedule.onetime.name firewall.schedule.recurring.name firewall.schedule.group.name.
167                type: str
168            service:
169                description:
170                    - Service name.
171                type: list
172                suboptions:
173                    name:
174                        description:
175                            - Address name. Source firewall.service.custom.name firewall.service.group.name.
176                        required: true
177                        type: str
178            srcaddr:
179                description:
180                    - Source address name.
181                type: list
182                suboptions:
183                    name:
184                        description:
185                            - Address name. Source firewall.address6.name firewall.addrgrp6.name.
186                        required: true
187                        type: str
188            srcintf:
189                description:
190                    - Source interface name. Source system.zone.name system.interface.name.
191                type: str
192            status:
193                description:
194                    - Enable/disable policy status.
195                type: str
196                choices:
197                    - enable
198                    - disable
199            tcp_mss_receiver:
200                description:
201                    - TCP MSS value of receiver.
202                type: int
203            tcp_mss_sender:
204                description:
205                    - TCP MSS value of sender.
206                type: int
207            traffic_shaper:
208                description:
209                    - Traffic shaper. Source firewall.shaper.traffic-shaper.name.
210                type: str
211            traffic_shaper_reverse:
212                description:
213                    - Reverse traffic shaper. Source firewall.shaper.traffic-shaper.name.
214                type: str
215            uuid:
216                description:
217                    - Universally Unique Identifier (UUID; automatically assigned but can be manually reset).
218                type: str
219'''
220
221EXAMPLES = '''
222- hosts: fortigates
223  collections:
224    - fortinet.fortios
225  connection: httpapi
226  vars:
227   vdom: "root"
228   ansible_httpapi_use_ssl: yes
229   ansible_httpapi_validate_certs: no
230   ansible_httpapi_port: 443
231  tasks:
232  - name: Configure IPv6 to IPv4 policies.
233    fortios_firewall_policy64:
234      vdom:  "{{ vdom }}"
235      state: "present"
236      access_token: "<your_own_value>"
237      firewall_policy64:
238        action: "accept"
239        comments: "<your_own_value>"
240        dstaddr:
241         -
242            name: "default_name_6 (source firewall.address.name firewall.addrgrp.name firewall.vip64.name firewall.vipgrp64.name)"
243        dstintf: "<your_own_value> (source system.interface.name system.zone.name)"
244        fixedport: "enable"
245        ippool: "enable"
246        logtraffic: "enable"
247        logtraffic_start: "enable"
248        name: "default_name_12"
249        per_ip_shaper: "<your_own_value> (source firewall.shaper.per-ip-shaper.name)"
250        permit_any_host: "enable"
251        policyid: "15"
252        poolname:
253         -
254            name: "default_name_17 (source firewall.ippool.name)"
255        schedule: "<your_own_value> (source firewall.schedule.onetime.name firewall.schedule.recurring.name firewall.schedule.group.name)"
256        service:
257         -
258            name: "default_name_20 (source firewall.service.custom.name firewall.service.group.name)"
259        srcaddr:
260         -
261            name: "default_name_22 (source firewall.address6.name firewall.addrgrp6.name)"
262        srcintf: "<your_own_value> (source system.zone.name system.interface.name)"
263        status: "enable"
264        tcp_mss_receiver: "25"
265        tcp_mss_sender: "26"
266        traffic_shaper: "<your_own_value> (source firewall.shaper.traffic-shaper.name)"
267        traffic_shaper_reverse: "<your_own_value> (source firewall.shaper.traffic-shaper.name)"
268        uuid: "<your_own_value>"
269
270'''
271
272RETURN = '''
273build:
274  description: Build number of the fortigate image
275  returned: always
276  type: str
277  sample: '1547'
278http_method:
279  description: Last method used to provision the content into FortiGate
280  returned: always
281  type: str
282  sample: 'PUT'
283http_status:
284  description: Last result given by FortiGate on last operation applied
285  returned: always
286  type: str
287  sample: "200"
288mkey:
289  description: Master key (id) used in the last call to FortiGate
290  returned: success
291  type: str
292  sample: "id"
293name:
294  description: Name of the table used to fulfill the request
295  returned: always
296  type: str
297  sample: "urlfilter"
298path:
299  description: Path of the table used to fulfill the request
300  returned: always
301  type: str
302  sample: "webfilter"
303revision:
304  description: Internal revision number
305  returned: always
306  type: str
307  sample: "17.0.2.10658"
308serial:
309  description: Serial number of the unit
310  returned: always
311  type: str
312  sample: "FGVMEVYYQT3AB5352"
313status:
314  description: Indication of the operation's result
315  returned: always
316  type: str
317  sample: "success"
318vdom:
319  description: Virtual domain used
320  returned: always
321  type: str
322  sample: "root"
323version:
324  description: Version of the FortiGate
325  returned: always
326  type: str
327  sample: "v5.6.3"
328
329'''
330from ansible.module_utils.basic import AnsibleModule
331from ansible.module_utils.connection import Connection
332from ansible_collections.fortinet.fortios.plugins.module_utils.fortios.fortios import FortiOSHandler
333from ansible_collections.fortinet.fortios.plugins.module_utils.fortios.fortios import check_legacy_fortiosapi
334from ansible_collections.fortinet.fortios.plugins.module_utils.fortios.fortios import schema_to_module_spec
335from ansible_collections.fortinet.fortios.plugins.module_utils.fortios.fortios import check_schema_versioning
336from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FAIL_SOCKET_MSG
337from ansible_collections.fortinet.fortios.plugins.module_utils.fortios.comparison import is_same_comparison
338from ansible_collections.fortinet.fortios.plugins.module_utils.fortios.comparison import serialize
339
340
341def filter_firewall_policy64_data(json):
342    option_list = ['action', 'comments', 'dstaddr',
343                   'dstintf', 'fixedport', 'ippool',
344                   'logtraffic', 'logtraffic_start', 'name',
345                   'per_ip_shaper', 'permit_any_host', 'policyid',
346                   'poolname', 'schedule', 'service',
347                   'srcaddr', 'srcintf', 'status',
348                   'tcp_mss_receiver', 'tcp_mss_sender', 'traffic_shaper',
349                   'traffic_shaper_reverse', 'uuid']
350    dictionary = {}
351
352    for attribute in option_list:
353        if attribute in json and json[attribute] is not None:
354            dictionary[attribute] = json[attribute]
355
356    return dictionary
357
358
359def underscore_to_hyphen(data):
360    if isinstance(data, list):
361        for i, elem in enumerate(data):
362            data[i] = underscore_to_hyphen(elem)
363    elif isinstance(data, dict):
364        new_data = {}
365        for k, v in data.items():
366            new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
367        data = new_data
368
369    return data
370
371
372def firewall_policy64(data, fos, check_mode=False):
373
374    vdom = data['vdom']
375
376    state = data['state']
377
378    firewall_policy64_data = data['firewall_policy64']
379    filtered_data = underscore_to_hyphen(filter_firewall_policy64_data(firewall_policy64_data))
380
381    # check_mode starts from here
382    if check_mode:
383        mkey = fos.get_mkey('system', 'interface', filtered_data, vdom=vdom)
384        current_data = fos.get('system', 'interface', vdom=vdom, mkey=mkey)
385        is_existed = current_data and current_data.get('http_status') == 200 \
386            and isinstance(current_data.get('results'), list) \
387            and len(current_data['results']) > 0
388
389        # 2. if it exists and the state is 'present' then compare current settings with desired
390        if state == 'present' or state is True:
391            if mkey is None:
392                return False, True, filtered_data
393
394            # if mkey exists then compare each other
395            # record exits and they're matched or not
396            if is_existed:
397                is_same = is_same_comparison(
398                    serialize(current_data['results'][0]), serialize(filtered_data))
399                return False, not is_same, filtered_data
400
401            # record does not exist
402            return False, True, filtered_data
403
404        if state == 'absent':
405            if mkey is None:
406                return False, False, filtered_data
407
408            if is_existed:
409                return False, True, filtered_data
410            return False, False, filtered_data
411
412        return True, False, {'reason: ': 'Must provide state parameter'}
413
414    if state == "present" or state is True:
415        return fos.set('firewall',
416                       'policy64',
417                       data=filtered_data,
418                       vdom=vdom)
419
420    elif state == "absent":
421        return fos.delete('firewall',
422                          'policy64',
423                          mkey=filtered_data['policyid'],
424                          vdom=vdom)
425    else:
426        fos._module.fail_json(msg='state must be present or absent!')
427
428
429def is_successful_status(status):
430    return status['status'] == "success" or \
431        status['http_method'] == "DELETE" and status['http_status'] == 404
432
433
434def fortios_firewall(data, fos, check_mode):
435
436    if data['firewall_policy64']:
437        resp = firewall_policy64(data, fos, check_mode)
438    else:
439        fos._module.fail_json(msg='missing task body: %s' % ('firewall_policy64'))
440    if check_mode:
441        return resp
442    return not is_successful_status(resp), \
443        resp['status'] == "success" and \
444        (resp['revision_changed'] if 'revision_changed' in resp else True), \
445        resp
446
447
448versioned_schema = {
449    "type": "list",
450    "children": {
451        "per_ip_shaper": {
452            "type": "string",
453            "revisions": {
454                "v6.0.0": True,
455                "v7.0.0": True,
456                "v6.0.5": 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                "v6.0.11": True
465            }
466        },
467        "traffic_shaper": {
468            "type": "string",
469            "revisions": {
470                "v6.0.0": True,
471                "v7.0.0": True,
472                "v6.0.5": True,
473                "v6.4.4": True,
474                "v6.4.0": True,
475                "v6.4.1": True,
476                "v6.2.0": True,
477                "v6.2.3": True,
478                "v6.2.5": True,
479                "v6.2.7": True,
480                "v6.0.11": True
481            }
482        },
483        "ippool": {
484            "type": "string",
485            "options": [
486                {
487                    "value": "enable",
488                    "revisions": {
489                        "v6.0.0": True,
490                        "v7.0.0": True,
491                        "v6.0.5": True,
492                        "v6.4.4": True,
493                        "v6.4.0": True,
494                        "v6.4.1": True,
495                        "v6.2.0": True,
496                        "v6.2.3": True,
497                        "v6.2.5": True,
498                        "v6.2.7": True,
499                        "v6.0.11": True
500                    }
501                },
502                {
503                    "value": "disable",
504                    "revisions": {
505                        "v6.0.0": True,
506                        "v7.0.0": True,
507                        "v6.0.5": True,
508                        "v6.4.4": True,
509                        "v6.4.0": True,
510                        "v6.4.1": True,
511                        "v6.2.0": True,
512                        "v6.2.3": True,
513                        "v6.2.5": True,
514                        "v6.2.7": True,
515                        "v6.0.11": True
516                    }
517                }
518            ],
519            "revisions": {
520                "v6.0.0": True,
521                "v7.0.0": True,
522                "v6.0.5": True,
523                "v6.4.4": True,
524                "v6.4.0": True,
525                "v6.4.1": True,
526                "v6.2.0": True,
527                "v6.2.3": True,
528                "v6.2.5": True,
529                "v6.2.7": True,
530                "v6.0.11": True
531            }
532        },
533        "traffic_shaper_reverse": {
534            "type": "string",
535            "revisions": {
536                "v6.0.0": True,
537                "v7.0.0": True,
538                "v6.0.5": True,
539                "v6.4.4": True,
540                "v6.4.0": True,
541                "v6.4.1": True,
542                "v6.2.0": True,
543                "v6.2.3": True,
544                "v6.2.5": True,
545                "v6.2.7": True,
546                "v6.0.11": True
547            }
548        },
549        "fixedport": {
550            "type": "string",
551            "options": [
552                {
553                    "value": "enable",
554                    "revisions": {
555                        "v6.0.0": True,
556                        "v7.0.0": True,
557                        "v6.0.5": True,
558                        "v6.4.4": True,
559                        "v6.4.0": True,
560                        "v6.4.1": True,
561                        "v6.2.0": True,
562                        "v6.2.3": True,
563                        "v6.2.5": True,
564                        "v6.2.7": True,
565                        "v6.0.11": True
566                    }
567                },
568                {
569                    "value": "disable",
570                    "revisions": {
571                        "v6.0.0": True,
572                        "v7.0.0": True,
573                        "v6.0.5": True,
574                        "v6.4.4": True,
575                        "v6.4.0": True,
576                        "v6.4.1": True,
577                        "v6.2.0": True,
578                        "v6.2.3": True,
579                        "v6.2.5": True,
580                        "v6.2.7": True,
581                        "v6.0.11": True
582                    }
583                }
584            ],
585            "revisions": {
586                "v6.0.0": True,
587                "v7.0.0": True,
588                "v6.0.5": True,
589                "v6.4.4": True,
590                "v6.4.0": True,
591                "v6.4.1": True,
592                "v6.2.0": True,
593                "v6.2.3": True,
594                "v6.2.5": True,
595                "v6.2.7": True,
596                "v6.0.11": True
597            }
598        },
599        "uuid": {
600            "type": "string",
601            "revisions": {
602                "v6.0.0": True,
603                "v7.0.0": True,
604                "v6.0.5": True,
605                "v6.4.4": True,
606                "v6.4.0": True,
607                "v6.4.1": True,
608                "v6.2.0": True,
609                "v6.2.3": True,
610                "v6.2.5": True,
611                "v6.2.7": True,
612                "v6.0.11": True
613            }
614        },
615        "service": {
616            "type": "list",
617            "children": {
618                "name": {
619                    "type": "string",
620                    "revisions": {
621                        "v6.0.0": True,
622                        "v7.0.0": True,
623                        "v6.0.5": True,
624                        "v6.4.4": True,
625                        "v6.4.0": True,
626                        "v6.4.1": True,
627                        "v6.2.0": True,
628                        "v6.2.3": True,
629                        "v6.2.5": True,
630                        "v6.2.7": True,
631                        "v6.0.11": True
632                    }
633                }
634            },
635            "revisions": {
636                "v6.0.0": True,
637                "v7.0.0": True,
638                "v6.0.5": True,
639                "v6.4.4": True,
640                "v6.4.0": True,
641                "v6.4.1": True,
642                "v6.2.0": True,
643                "v6.2.3": True,
644                "v6.2.5": True,
645                "v6.2.7": True,
646                "v6.0.11": True
647            }
648        },
649        "poolname": {
650            "type": "list",
651            "children": {
652                "name": {
653                    "type": "string",
654                    "revisions": {
655                        "v6.0.0": True,
656                        "v7.0.0": True,
657                        "v6.0.5": True,
658                        "v6.4.4": True,
659                        "v6.4.0": True,
660                        "v6.4.1": True,
661                        "v6.2.0": True,
662                        "v6.2.3": True,
663                        "v6.2.5": True,
664                        "v6.2.7": True,
665                        "v6.0.11": True
666                    }
667                }
668            },
669            "revisions": {
670                "v6.0.0": True,
671                "v7.0.0": True,
672                "v6.0.5": 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                "v6.0.11": True
681            }
682        },
683        "comments": {
684            "type": "string",
685            "revisions": {
686                "v6.0.0": True,
687                "v7.0.0": True,
688                "v6.0.5": True,
689                "v6.4.4": True,
690                "v6.4.0": True,
691                "v6.4.1": True,
692                "v6.2.0": True,
693                "v6.2.3": True,
694                "v6.2.5": True,
695                "v6.2.7": True,
696                "v6.0.11": True
697            }
698        },
699        "dstintf": {
700            "type": "string",
701            "revisions": {
702                "v6.0.0": True,
703                "v7.0.0": True,
704                "v6.0.5": True,
705                "v6.4.4": True,
706                "v6.4.0": True,
707                "v6.4.1": True,
708                "v6.2.0": True,
709                "v6.2.3": True,
710                "v6.2.5": True,
711                "v6.2.7": True,
712                "v6.0.11": True
713            }
714        },
715        "tcp_mss_receiver": {
716            "type": "integer",
717            "revisions": {
718                "v6.0.0": True,
719                "v7.0.0": True,
720                "v6.0.5": True,
721                "v6.4.4": True,
722                "v6.4.0": True,
723                "v6.4.1": True,
724                "v6.2.0": True,
725                "v6.2.3": True,
726                "v6.2.5": True,
727                "v6.2.7": True,
728                "v6.0.11": True
729            }
730        },
731        "status": {
732            "type": "string",
733            "options": [
734                {
735                    "value": "enable",
736                    "revisions": {
737                        "v6.0.0": True,
738                        "v7.0.0": True,
739                        "v6.0.5": True,
740                        "v6.4.4": True,
741                        "v6.4.0": True,
742                        "v6.4.1": True,
743                        "v6.2.0": True,
744                        "v6.2.3": True,
745                        "v6.2.5": True,
746                        "v6.2.7": True,
747                        "v6.0.11": True
748                    }
749                },
750                {
751                    "value": "disable",
752                    "revisions": {
753                        "v6.0.0": True,
754                        "v7.0.0": True,
755                        "v6.0.5": True,
756                        "v6.4.4": True,
757                        "v6.4.0": True,
758                        "v6.4.1": True,
759                        "v6.2.0": True,
760                        "v6.2.3": True,
761                        "v6.2.5": True,
762                        "v6.2.7": True,
763                        "v6.0.11": True
764                    }
765                }
766            ],
767            "revisions": {
768                "v6.0.0": True,
769                "v7.0.0": True,
770                "v6.0.5": True,
771                "v6.4.4": True,
772                "v6.4.0": True,
773                "v6.4.1": True,
774                "v6.2.0": True,
775                "v6.2.3": True,
776                "v6.2.5": True,
777                "v6.2.7": True,
778                "v6.0.11": True
779            }
780        },
781        "schedule": {
782            "type": "string",
783            "revisions": {
784                "v6.0.0": True,
785                "v7.0.0": True,
786                "v6.0.5": True,
787                "v6.4.4": True,
788                "v6.4.0": True,
789                "v6.4.1": True,
790                "v6.2.0": True,
791                "v6.2.3": True,
792                "v6.2.5": True,
793                "v6.2.7": True,
794                "v6.0.11": True
795            }
796        },
797        "tcp_mss_sender": {
798            "type": "integer",
799            "revisions": {
800                "v6.0.0": True,
801                "v7.0.0": True,
802                "v6.0.5": True,
803                "v6.4.4": True,
804                "v6.4.0": True,
805                "v6.4.1": True,
806                "v6.2.0": True,
807                "v6.2.3": True,
808                "v6.2.5": True,
809                "v6.2.7": True,
810                "v6.0.11": True
811            }
812        },
813        "srcaddr": {
814            "type": "list",
815            "children": {
816                "name": {
817                    "type": "string",
818                    "revisions": {
819                        "v6.0.0": True,
820                        "v7.0.0": True,
821                        "v6.0.5": True,
822                        "v6.4.4": True,
823                        "v6.4.0": True,
824                        "v6.4.1": True,
825                        "v6.2.0": True,
826                        "v6.2.3": True,
827                        "v6.2.5": True,
828                        "v6.2.7": True,
829                        "v6.0.11": True
830                    }
831                }
832            },
833            "revisions": {
834                "v6.0.0": True,
835                "v7.0.0": True,
836                "v6.0.5": True,
837                "v6.4.4": True,
838                "v6.4.0": True,
839                "v6.4.1": True,
840                "v6.2.0": True,
841                "v6.2.3": True,
842                "v6.2.5": True,
843                "v6.2.7": True,
844                "v6.0.11": True
845            }
846        },
847        "policyid": {
848            "type": "integer",
849            "revisions": {
850                "v6.0.0": True,
851                "v7.0.0": True,
852                "v6.0.5": True,
853                "v6.4.4": True,
854                "v6.4.0": True,
855                "v6.4.1": True,
856                "v6.2.0": True,
857                "v6.2.3": True,
858                "v6.2.5": True,
859                "v6.2.7": True,
860                "v6.0.11": True
861            }
862        },
863        "srcintf": {
864            "type": "string",
865            "revisions": {
866                "v6.0.0": True,
867                "v7.0.0": True,
868                "v6.0.5": True,
869                "v6.4.4": True,
870                "v6.4.0": True,
871                "v6.4.1": True,
872                "v6.2.0": True,
873                "v6.2.3": True,
874                "v6.2.5": True,
875                "v6.2.7": True,
876                "v6.0.11": True
877            }
878        },
879        "permit_any_host": {
880            "type": "string",
881            "options": [
882                {
883                    "value": "enable",
884                    "revisions": {
885                        "v6.0.0": True,
886                        "v7.0.0": True,
887                        "v6.0.5": True,
888                        "v6.4.4": True,
889                        "v6.4.0": True,
890                        "v6.4.1": True,
891                        "v6.2.0": True,
892                        "v6.2.3": True,
893                        "v6.2.5": True,
894                        "v6.2.7": True,
895                        "v6.0.11": True
896                    }
897                },
898                {
899                    "value": "disable",
900                    "revisions": {
901                        "v6.0.0": True,
902                        "v7.0.0": True,
903                        "v6.0.5": True,
904                        "v6.4.4": True,
905                        "v6.4.0": True,
906                        "v6.4.1": True,
907                        "v6.2.0": True,
908                        "v6.2.3": True,
909                        "v6.2.5": True,
910                        "v6.2.7": True,
911                        "v6.0.11": True
912                    }
913                }
914            ],
915            "revisions": {
916                "v6.0.0": True,
917                "v7.0.0": True,
918                "v6.0.5": True,
919                "v6.4.4": True,
920                "v6.4.0": True,
921                "v6.4.1": True,
922                "v6.2.0": True,
923                "v6.2.3": True,
924                "v6.2.5": True,
925                "v6.2.7": True,
926                "v6.0.11": True
927            }
928        },
929        "logtraffic_start": {
930            "type": "string",
931            "options": [
932                {
933                    "value": "enable",
934                    "revisions": {
935                        "v7.0.0": True,
936                        "v6.4.4": True,
937                        "v6.4.0": True,
938                        "v6.4.1": True,
939                        "v6.2.0": True,
940                        "v6.2.3": True,
941                        "v6.2.5": True,
942                        "v6.2.7": True
943                    }
944                },
945                {
946                    "value": "disable",
947                    "revisions": {
948                        "v7.0.0": True,
949                        "v6.4.4": True,
950                        "v6.4.0": True,
951                        "v6.4.1": True,
952                        "v6.2.0": True,
953                        "v6.2.3": True,
954                        "v6.2.5": True,
955                        "v6.2.7": True
956                    }
957                }
958            ],
959            "revisions": {
960                "v7.0.0": True,
961                "v6.4.4": True,
962                "v6.4.0": True,
963                "v6.4.1": True,
964                "v6.2.0": True,
965                "v6.2.3": True,
966                "v6.2.5": True,
967                "v6.2.7": True
968            }
969        },
970        "name": {
971            "type": "string",
972            "revisions": {
973                "v6.4.4": True,
974                "v7.0.0": True,
975                "v6.4.0": True,
976                "v6.4.1": False
977            }
978        },
979        "action": {
980            "type": "string",
981            "options": [
982                {
983                    "value": "accept",
984                    "revisions": {
985                        "v6.0.0": True,
986                        "v7.0.0": True,
987                        "v6.0.5": True,
988                        "v6.4.4": True,
989                        "v6.4.0": True,
990                        "v6.4.1": True,
991                        "v6.2.0": True,
992                        "v6.2.3": True,
993                        "v6.2.5": True,
994                        "v6.2.7": True,
995                        "v6.0.11": True
996                    }
997                },
998                {
999                    "value": "deny",
1000                    "revisions": {
1001                        "v6.0.0": True,
1002                        "v7.0.0": True,
1003                        "v6.0.5": True,
1004                        "v6.4.4": True,
1005                        "v6.4.0": True,
1006                        "v6.4.1": True,
1007                        "v6.2.0": True,
1008                        "v6.2.3": True,
1009                        "v6.2.5": True,
1010                        "v6.2.7": True,
1011                        "v6.0.11": True
1012                    }
1013                }
1014            ],
1015            "revisions": {
1016                "v6.0.0": True,
1017                "v7.0.0": True,
1018                "v6.0.5": True,
1019                "v6.4.4": True,
1020                "v6.4.0": True,
1021                "v6.4.1": True,
1022                "v6.2.0": True,
1023                "v6.2.3": True,
1024                "v6.2.5": True,
1025                "v6.2.7": True,
1026                "v6.0.11": True
1027            }
1028        },
1029        "dstaddr": {
1030            "type": "list",
1031            "children": {
1032                "name": {
1033                    "type": "string",
1034                    "revisions": {
1035                        "v6.0.0": True,
1036                        "v7.0.0": True,
1037                        "v6.0.5": True,
1038                        "v6.4.4": True,
1039                        "v6.4.0": True,
1040                        "v6.4.1": True,
1041                        "v6.2.0": True,
1042                        "v6.2.3": True,
1043                        "v6.2.5": True,
1044                        "v6.2.7": True,
1045                        "v6.0.11": True
1046                    }
1047                }
1048            },
1049            "revisions": {
1050                "v6.0.0": True,
1051                "v7.0.0": True,
1052                "v6.0.5": True,
1053                "v6.4.4": True,
1054                "v6.4.0": True,
1055                "v6.4.1": True,
1056                "v6.2.0": True,
1057                "v6.2.3": True,
1058                "v6.2.5": True,
1059                "v6.2.7": True,
1060                "v6.0.11": True
1061            }
1062        },
1063        "logtraffic": {
1064            "type": "string",
1065            "options": [
1066                {
1067                    "value": "enable",
1068                    "revisions": {
1069                        "v6.0.0": True,
1070                        "v7.0.0": True,
1071                        "v6.0.5": True,
1072                        "v6.4.4": True,
1073                        "v6.4.0": True,
1074                        "v6.4.1": True,
1075                        "v6.2.0": True,
1076                        "v6.2.3": True,
1077                        "v6.2.5": True,
1078                        "v6.2.7": True,
1079                        "v6.0.11": True
1080                    }
1081                },
1082                {
1083                    "value": "disable",
1084                    "revisions": {
1085                        "v6.0.0": True,
1086                        "v7.0.0": True,
1087                        "v6.0.5": True,
1088                        "v6.4.4": True,
1089                        "v6.4.0": True,
1090                        "v6.4.1": True,
1091                        "v6.2.0": True,
1092                        "v6.2.3": True,
1093                        "v6.2.5": True,
1094                        "v6.2.7": True,
1095                        "v6.0.11": True
1096                    }
1097                }
1098            ],
1099            "revisions": {
1100                "v6.0.0": True,
1101                "v7.0.0": True,
1102                "v6.0.5": True,
1103                "v6.4.4": True,
1104                "v6.4.0": True,
1105                "v6.4.1": True,
1106                "v6.2.0": True,
1107                "v6.2.3": True,
1108                "v6.2.5": True,
1109                "v6.2.7": True,
1110                "v6.0.11": True
1111            }
1112        }
1113    },
1114    "revisions": {
1115        "v6.0.0": True,
1116        "v7.0.0": True,
1117        "v6.0.5": True,
1118        "v6.4.4": True,
1119        "v6.4.0": True,
1120        "v6.4.1": True,
1121        "v6.2.0": True,
1122        "v6.2.3": True,
1123        "v6.2.5": True,
1124        "v6.2.7": True,
1125        "v6.0.11": True
1126    }
1127}
1128
1129
1130def main():
1131    module_spec = schema_to_module_spec(versioned_schema)
1132    mkeyname = 'policyid'
1133    fields = {
1134        "access_token": {"required": False, "type": "str", "no_log": True},
1135        "enable_log": {"required": False, "type": bool},
1136        "vdom": {"required": False, "type": "str", "default": "root"},
1137        "state": {"required": True, "type": "str",
1138                  "choices": ["present", "absent"]},
1139        "firewall_policy64": {
1140            "required": False, "type": "dict", "default": None,
1141            "options": {
1142            }
1143        }
1144    }
1145    for attribute_name in module_spec['options']:
1146        fields["firewall_policy64"]['options'][attribute_name] = module_spec['options'][attribute_name]
1147        if mkeyname and mkeyname == attribute_name:
1148            fields["firewall_policy64"]['options'][attribute_name]['required'] = True
1149
1150    check_legacy_fortiosapi()
1151    module = AnsibleModule(argument_spec=fields,
1152                           supports_check_mode=True)
1153
1154    versions_check_result = None
1155    if module._socket_path:
1156        connection = Connection(module._socket_path)
1157        if 'access_token' in module.params:
1158            connection.set_option('access_token', module.params['access_token'])
1159
1160        if 'enable_log' in module.params:
1161            connection.set_option('enable_log', module.params['enable_log'])
1162        else:
1163            connection.set_option('enable_log', False)
1164        fos = FortiOSHandler(connection, module, mkeyname)
1165        versions_check_result = check_schema_versioning(fos, versioned_schema, "firewall_policy64")
1166
1167        is_error, has_changed, result = fortios_firewall(module.params, fos, module.check_mode)
1168
1169    else:
1170        module.fail_json(**FAIL_SOCKET_MSG)
1171
1172    if versions_check_result and versions_check_result['matched'] is False:
1173        module.warn("Ansible has detected version mismatch between FortOS system and your playbook, see more details by specifying option -vvv")
1174
1175    if not is_error:
1176        if versions_check_result and versions_check_result['matched'] is False:
1177            module.exit_json(changed=has_changed, version_check_warning=versions_check_result, meta=result)
1178        else:
1179            module.exit_json(changed=has_changed, meta=result)
1180    else:
1181        if versions_check_result and versions_check_result['matched'] is False:
1182            module.fail_json(msg="Error in repo", version_check_warning=versions_check_result, meta=result)
1183        else:
1184            module.fail_json(msg="Error in repo", meta=result)
1185
1186
1187if __name__ == '__main__':
1188    main()
1189