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