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