1#!/usr/bin/python 2from __future__ import (absolute_import, division, print_function) 3# Copyright 2019 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_wireless_controller_wtp 27short_description: Configure Wireless Termination Points (WTPs), that is, FortiAPs or APs to be managed by FortiGate 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 wireless_controller feature and wtp category. 31 Examples include all parameters and values need to be adjusted to datasources before usage. 32 Tested with FOS v6.0.5 33version_added: "2.8" 34author: 35 - Miguel Angel Munoz (@mamunozgonzalez) 36 - Nicolas Thomas (@thomnico) 37notes: 38 - Requires fortiosapi library developed by Fortinet 39 - Run as a local_action in your playbook 40requirements: 41 - fortiosapi>=0.9.8 42options: 43 host: 44 description: 45 - FortiOS or FortiGate IP address. 46 type: str 47 required: false 48 username: 49 description: 50 - FortiOS or FortiGate username. 51 type: str 52 required: false 53 password: 54 description: 55 - FortiOS or FortiGate password. 56 type: str 57 default: "" 58 vdom: 59 description: 60 - Virtual domain, among those defined previously. A vdom is a 61 virtual instance of the FortiGate that can be configured and 62 used as a different unit. 63 type: str 64 default: root 65 https: 66 description: 67 - Indicates if the requests towards FortiGate must use HTTPS protocol. 68 type: bool 69 default: true 70 ssl_verify: 71 description: 72 - Ensures FortiGate certificate must be verified by a proper CA. 73 type: bool 74 default: true 75 version_added: 2.9 76 state: 77 description: 78 - Indicates whether to create or remove the object. 79 This attribute was present already in previous version in a deeper level. 80 It has been moved out to this outer level. 81 type: str 82 required: false 83 choices: 84 - present 85 - absent 86 version_added: 2.9 87 wireless_controller_wtp: 88 description: 89 - Configure Wireless Termination Points (WTPs), that is, FortiAPs or APs to be managed by FortiGate. 90 default: null 91 type: dict 92 suboptions: 93 state: 94 description: 95 - B(Deprecated) 96 - Starting with Ansible 2.9 we recommend using the top-level 'state' parameter. 97 - HORIZONTALLINE 98 - Indicates whether to create or remove the object. 99 type: str 100 required: false 101 choices: 102 - present 103 - absent 104 admin: 105 description: 106 - Configure how the FortiGate operating as a wireless controller discovers and manages this WTP, AP or FortiAP. 107 type: str 108 choices: 109 - discovered 110 - disable 111 - enable 112 allowaccess: 113 description: 114 - Control management access to the managed WTP, FortiAP, or AP. Separate entries with a space. 115 type: str 116 choices: 117 - telnet 118 - http 119 - https 120 - ssh 121 bonjour_profile: 122 description: 123 - Bonjour profile name. Source wireless-controller.bonjour-profile.name. 124 type: str 125 coordinate_enable: 126 description: 127 - Enable/disable WTP coordinates (X,Y axis). 128 type: str 129 choices: 130 - enable 131 - disable 132 coordinate_latitude: 133 description: 134 - WTP latitude coordinate. 135 type: str 136 coordinate_longitude: 137 description: 138 - WTP longitude coordinate. 139 type: str 140 coordinate_x: 141 description: 142 - X axis coordinate. 143 type: str 144 coordinate_y: 145 description: 146 - Y axis coordinate. 147 type: str 148 image_download: 149 description: 150 - Enable/disable WTP image download. 151 type: str 152 choices: 153 - enable 154 - disable 155 index: 156 description: 157 - Index (0 - 4294967295). 158 type: int 159 ip_fragment_preventing: 160 description: 161 - Method by which IP fragmentation is prevented for CAPWAP tunneled control and data packets . 162 type: str 163 choices: 164 - tcp-mss-adjust 165 - icmp-unreachable 166 lan: 167 description: 168 - WTP LAN port mapping. 169 type: dict 170 suboptions: 171 port_mode: 172 description: 173 - LAN port mode. 174 type: str 175 choices: 176 - offline 177 - nat-to-wan 178 - bridge-to-wan 179 - bridge-to-ssid 180 port_ssid: 181 description: 182 - Bridge LAN port to SSID. Source wireless-controller.vap.name. 183 type: str 184 port1_mode: 185 description: 186 - LAN port 1 mode. 187 type: str 188 choices: 189 - offline 190 - nat-to-wan 191 - bridge-to-wan 192 - bridge-to-ssid 193 port1_ssid: 194 description: 195 - Bridge LAN port 1 to SSID. Source wireless-controller.vap.name. 196 type: str 197 port2_mode: 198 description: 199 - LAN port 2 mode. 200 type: str 201 choices: 202 - offline 203 - nat-to-wan 204 - bridge-to-wan 205 - bridge-to-ssid 206 port2_ssid: 207 description: 208 - Bridge LAN port 2 to SSID. Source wireless-controller.vap.name. 209 type: str 210 port3_mode: 211 description: 212 - LAN port 3 mode. 213 type: str 214 choices: 215 - offline 216 - nat-to-wan 217 - bridge-to-wan 218 - bridge-to-ssid 219 port3_ssid: 220 description: 221 - Bridge LAN port 3 to SSID. Source wireless-controller.vap.name. 222 type: str 223 port4_mode: 224 description: 225 - LAN port 4 mode. 226 type: str 227 choices: 228 - offline 229 - nat-to-wan 230 - bridge-to-wan 231 - bridge-to-ssid 232 port4_ssid: 233 description: 234 - Bridge LAN port 4 to SSID. Source wireless-controller.vap.name. 235 type: str 236 port5_mode: 237 description: 238 - LAN port 5 mode. 239 type: str 240 choices: 241 - offline 242 - nat-to-wan 243 - bridge-to-wan 244 - bridge-to-ssid 245 port5_ssid: 246 description: 247 - Bridge LAN port 5 to SSID. Source wireless-controller.vap.name. 248 type: str 249 port6_mode: 250 description: 251 - LAN port 6 mode. 252 type: str 253 choices: 254 - offline 255 - nat-to-wan 256 - bridge-to-wan 257 - bridge-to-ssid 258 port6_ssid: 259 description: 260 - Bridge LAN port 6 to SSID. Source wireless-controller.vap.name. 261 type: str 262 port7_mode: 263 description: 264 - LAN port 7 mode. 265 type: str 266 choices: 267 - offline 268 - nat-to-wan 269 - bridge-to-wan 270 - bridge-to-ssid 271 port7_ssid: 272 description: 273 - Bridge LAN port 7 to SSID. Source wireless-controller.vap.name. 274 type: str 275 port8_mode: 276 description: 277 - LAN port 8 mode. 278 type: str 279 choices: 280 - offline 281 - nat-to-wan 282 - bridge-to-wan 283 - bridge-to-ssid 284 port8_ssid: 285 description: 286 - Bridge LAN port 8 to SSID. Source wireless-controller.vap.name. 287 type: str 288 led_state: 289 description: 290 - Enable to allow the FortiAPs LEDs to light. Disable to keep the LEDs off. You may want to keep the LEDs off so they are not distracting 291 in low light areas etc. 292 type: str 293 choices: 294 - enable 295 - disable 296 location: 297 description: 298 - Field for describing the physical location of the WTP, AP or FortiAP. 299 type: str 300 login_passwd: 301 description: 302 - Set the managed WTP, FortiAP, or AP's administrator password. 303 type: str 304 login_passwd_change: 305 description: 306 - Change or reset the administrator password of a managed WTP, FortiAP or AP (yes, default, or no). 307 type: str 308 choices: 309 - yes 310 - default 311 - no 312 mesh_bridge_enable: 313 description: 314 - Enable/disable mesh Ethernet bridge when WTP is configured as a mesh branch/leaf AP. 315 type: str 316 choices: 317 - default 318 - enable 319 - disable 320 name: 321 description: 322 - WTP, AP or FortiAP configuration name. 323 type: str 324 override_allowaccess: 325 description: 326 - Enable to override the WTP profile management access configuration. 327 type: str 328 choices: 329 - enable 330 - disable 331 override_ip_fragment: 332 description: 333 - Enable/disable overriding the WTP profile IP fragment prevention setting. 334 type: str 335 choices: 336 - enable 337 - disable 338 override_lan: 339 description: 340 - Enable to override the WTP profile LAN port setting. 341 type: str 342 choices: 343 - enable 344 - disable 345 override_led_state: 346 description: 347 - Enable to override the profile LED state setting for this FortiAP. You must enable this option to use the led-state command to turn off 348 the FortiAP's LEDs. 349 type: str 350 choices: 351 - enable 352 - disable 353 override_login_passwd_change: 354 description: 355 - Enable to override the WTP profile login-password (administrator password) setting. 356 type: str 357 choices: 358 - enable 359 - disable 360 override_split_tunnel: 361 description: 362 - Enable/disable overriding the WTP profile split tunneling setting. 363 type: str 364 choices: 365 - enable 366 - disable 367 override_wan_port_mode: 368 description: 369 - Enable/disable overriding the wan-port-mode in the WTP profile. 370 type: str 371 choices: 372 - enable 373 - disable 374 radio_1: 375 description: 376 - Configuration options for radio 1. 377 type: dict 378 suboptions: 379 auto_power_high: 380 description: 381 - Automatic transmission power high limit in decibels (dB) of the measured power referenced to one milliwatt (mW), or dBm (10 - 17 382 dBm). 383 type: int 384 auto_power_level: 385 description: 386 - Enable/disable automatic power-level adjustment to prevent co-channel interference . 387 type: str 388 choices: 389 - enable 390 - disable 391 auto_power_low: 392 description: 393 - Automatic transmission power low limit in dBm (the actual range of transmit power depends on the AP platform type). 394 type: int 395 band: 396 description: 397 - WiFi band that Radio 1 operates on. 398 type: str 399 choices: 400 - 802.11a 401 - 802.11b 402 - 802.11g 403 - 802.11n 404 - 802.11n-5G 405 - 802.11n,g-only 406 - 802.11g-only 407 - 802.11n-only 408 - 802.11n-5G-only 409 - 802.11ac 410 - 802.11ac,n-only 411 - 802.11ac-only 412 channel: 413 description: 414 - Selected list of wireless radio channels. 415 type: list 416 suboptions: 417 chan: 418 description: 419 - Channel number. 420 required: true 421 type: str 422 override_analysis: 423 description: 424 - Enable to override the WTP profile spectrum analysis configuration. 425 type: str 426 choices: 427 - enable 428 - disable 429 override_band: 430 description: 431 - Enable to override the WTP profile band setting. 432 type: str 433 choices: 434 - enable 435 - disable 436 override_channel: 437 description: 438 - Enable to override WTP profile channel settings. 439 type: str 440 choices: 441 - enable 442 - disable 443 override_txpower: 444 description: 445 - Enable to override the WTP profile power level configuration. 446 type: str 447 choices: 448 - enable 449 - disable 450 override_vaps: 451 description: 452 - Enable to override WTP profile Virtual Access Point (VAP) settings. 453 type: str 454 choices: 455 - enable 456 - disable 457 power_level: 458 description: 459 - Radio power level as a percentage of the maximum transmit power (0 - 100). 460 type: int 461 radio_id: 462 description: 463 - radio-id 464 type: int 465 spectrum_analysis: 466 description: 467 - Enable/disable spectrum analysis to find interference that would negatively impact wireless performance. 468 type: str 469 choices: 470 - enable 471 - disable 472 vap_all: 473 description: 474 - Enable/disable the automatic inheritance of all Virtual Access Points (VAPs) . 475 type: str 476 choices: 477 - enable 478 - disable 479 vaps: 480 description: 481 - Manually selected list of Virtual Access Points (VAPs). 482 type: list 483 suboptions: 484 name: 485 description: 486 - Virtual Access Point (VAP) name. Source wireless-controller.vap-group.name wireless-controller.vap.name. 487 required: true 488 type: str 489 radio_2: 490 description: 491 - Configuration options for radio 2. 492 type: dict 493 suboptions: 494 auto_power_high: 495 description: 496 - Automatic transmission power high limit in decibels (dB) of the measured power referenced to one milliwatt (mW), or dBm (10 - 17 497 dBm). 498 type: int 499 auto_power_level: 500 description: 501 - Enable/disable automatic power-level adjustment to prevent co-channel interference . 502 type: str 503 choices: 504 - enable 505 - disable 506 auto_power_low: 507 description: 508 - Automatic transmission power low limit in dBm (the actual range of transmit power depends on the AP platform type). 509 type: int 510 band: 511 description: 512 - WiFi band that Radio 1 operates on. 513 type: str 514 choices: 515 - 802.11a 516 - 802.11b 517 - 802.11g 518 - 802.11n 519 - 802.11n-5G 520 - 802.11n,g-only 521 - 802.11g-only 522 - 802.11n-only 523 - 802.11n-5G-only 524 - 802.11ac 525 - 802.11ac,n-only 526 - 802.11ac-only 527 channel: 528 description: 529 - Selected list of wireless radio channels. 530 type: list 531 suboptions: 532 chan: 533 description: 534 - Channel number. 535 required: true 536 type: str 537 override_analysis: 538 description: 539 - Enable to override the WTP profile spectrum analysis configuration. 540 type: str 541 choices: 542 - enable 543 - disable 544 override_band: 545 description: 546 - Enable to override the WTP profile band setting. 547 type: str 548 choices: 549 - enable 550 - disable 551 override_channel: 552 description: 553 - Enable to override WTP profile channel settings. 554 type: str 555 choices: 556 - enable 557 - disable 558 override_txpower: 559 description: 560 - Enable to override the WTP profile power level configuration. 561 type: str 562 choices: 563 - enable 564 - disable 565 override_vaps: 566 description: 567 - Enable to override WTP profile Virtual Access Point (VAP) settings. 568 type: str 569 choices: 570 - enable 571 - disable 572 power_level: 573 description: 574 - Radio power level as a percentage of the maximum transmit power (0 - 100). 575 type: int 576 radio_id: 577 description: 578 - radio-id 579 type: int 580 spectrum_analysis: 581 description: 582 - Enable/disable spectrum analysis to find interference that would negatively impact wireless performance. 583 type: str 584 choices: 585 - enable 586 - disable 587 vap_all: 588 description: 589 - Enable/disable the automatic inheritance of all Virtual Access Points (VAPs) . 590 type: str 591 choices: 592 - enable 593 - disable 594 vaps: 595 description: 596 - Manually selected list of Virtual Access Points (VAPs). 597 type: list 598 suboptions: 599 name: 600 description: 601 - Virtual Access Point (VAP) name. Source wireless-controller.vap-group.name wireless-controller.vap.name. 602 required: true 603 type: str 604 split_tunneling_acl: 605 description: 606 - Split tunneling ACL filter list. 607 type: list 608 suboptions: 609 dest_ip: 610 description: 611 - Destination IP and mask for the split-tunneling subnet. 612 type: str 613 id: 614 description: 615 - ID. 616 required: true 617 type: int 618 split_tunneling_acl_local_ap_subnet: 619 description: 620 - Enable/disable automatically adding local subnetwork of FortiAP to split-tunneling ACL . 621 type: str 622 choices: 623 - enable 624 - disable 625 split_tunneling_acl_path: 626 description: 627 - Split tunneling ACL path is local/tunnel. 628 type: str 629 choices: 630 - tunnel 631 - local 632 tun_mtu_downlink: 633 description: 634 - Downlink tunnel MTU in octets. Set the value to either 0 (by default), 576, or 1500. 635 type: int 636 tun_mtu_uplink: 637 description: 638 - Uplink tunnel maximum transmission unit (MTU) in octets (eight-bit bytes). Set the value to either 0 (by default), 576, or 1500. 639 type: int 640 wan_port_mode: 641 description: 642 - Enable/disable using the FortiAP WAN port as a LAN port. 643 type: str 644 choices: 645 - wan-lan 646 - wan-only 647 wtp_id: 648 description: 649 - WTP ID. 650 type: str 651 wtp_mode: 652 description: 653 - WTP, AP, or FortiAP operating mode; normal (by default) or remote. A tunnel mode SSID can be assigned to an AP in normal mode but not 654 remote mode, while a local-bridge mode SSID can be assigned to an AP in either normal mode or remote mode. 655 type: str 656 choices: 657 - normal 658 - remote 659 wtp_profile: 660 description: 661 - WTP profile name to apply to this WTP, AP or FortiAP. Source wireless-controller.wtp-profile.name. 662 type: str 663''' 664 665EXAMPLES = ''' 666- hosts: localhost 667 vars: 668 host: "192.168.122.40" 669 username: "admin" 670 password: "" 671 vdom: "root" 672 ssl_verify: "False" 673 tasks: 674 - name: Configure Wireless Termination Points (WTPs), that is, FortiAPs or APs to be managed by FortiGate. 675 fortios_wireless_controller_wtp: 676 host: "{{ host }}" 677 username: "{{ username }}" 678 password: "{{ password }}" 679 vdom: "{{ vdom }}" 680 https: "False" 681 state: "present" 682 wireless_controller_wtp: 683 admin: "discovered" 684 allowaccess: "telnet" 685 bonjour_profile: "<your_own_value> (source wireless-controller.bonjour-profile.name)" 686 coordinate_enable: "enable" 687 coordinate_latitude: "<your_own_value>" 688 coordinate_longitude: "<your_own_value>" 689 coordinate_x: "<your_own_value>" 690 coordinate_y: "<your_own_value>" 691 image_download: "enable" 692 index: "12" 693 ip_fragment_preventing: "tcp-mss-adjust" 694 lan: 695 port_mode: "offline" 696 port_ssid: "<your_own_value> (source wireless-controller.vap.name)" 697 port1_mode: "offline" 698 port1_ssid: "<your_own_value> (source wireless-controller.vap.name)" 699 port2_mode: "offline" 700 port2_ssid: "<your_own_value> (source wireless-controller.vap.name)" 701 port3_mode: "offline" 702 port3_ssid: "<your_own_value> (source wireless-controller.vap.name)" 703 port4_mode: "offline" 704 port4_ssid: "<your_own_value> (source wireless-controller.vap.name)" 705 port5_mode: "offline" 706 port5_ssid: "<your_own_value> (source wireless-controller.vap.name)" 707 port6_mode: "offline" 708 port6_ssid: "<your_own_value> (source wireless-controller.vap.name)" 709 port7_mode: "offline" 710 port7_ssid: "<your_own_value> (source wireless-controller.vap.name)" 711 port8_mode: "offline" 712 port8_ssid: "<your_own_value> (source wireless-controller.vap.name)" 713 led_state: "enable" 714 location: "<your_own_value>" 715 login_passwd: "<your_own_value>" 716 login_passwd_change: "yes" 717 mesh_bridge_enable: "default" 718 name: "default_name_38" 719 override_allowaccess: "enable" 720 override_ip_fragment: "enable" 721 override_lan: "enable" 722 override_led_state: "enable" 723 override_login_passwd_change: "enable" 724 override_split_tunnel: "enable" 725 override_wan_port_mode: "enable" 726 radio_1: 727 auto_power_high: "47" 728 auto_power_level: "enable" 729 auto_power_low: "49" 730 band: "802.11a" 731 channel: 732 - 733 chan: "<your_own_value>" 734 override_analysis: "enable" 735 override_band: "enable" 736 override_channel: "enable" 737 override_txpower: "enable" 738 override_vaps: "enable" 739 power_level: "58" 740 radio_id: "59" 741 spectrum_analysis: "enable" 742 vap_all: "enable" 743 vaps: 744 - 745 name: "default_name_63 (source wireless-controller.vap-group.name wireless-controller.vap.name)" 746 radio_2: 747 auto_power_high: "65" 748 auto_power_level: "enable" 749 auto_power_low: "67" 750 band: "802.11a" 751 channel: 752 - 753 chan: "<your_own_value>" 754 override_analysis: "enable" 755 override_band: "enable" 756 override_channel: "enable" 757 override_txpower: "enable" 758 override_vaps: "enable" 759 power_level: "76" 760 radio_id: "77" 761 spectrum_analysis: "enable" 762 vap_all: "enable" 763 vaps: 764 - 765 name: "default_name_81 (source wireless-controller.vap-group.name wireless-controller.vap.name)" 766 split_tunneling_acl: 767 - 768 dest_ip: "<your_own_value>" 769 id: "84" 770 split_tunneling_acl_local_ap_subnet: "enable" 771 split_tunneling_acl_path: "tunnel" 772 tun_mtu_downlink: "87" 773 tun_mtu_uplink: "88" 774 wan_port_mode: "wan-lan" 775 wtp_id: "<your_own_value>" 776 wtp_mode: "normal" 777 wtp_profile: "<your_own_value> (source wireless-controller.wtp-profile.name)" 778''' 779 780RETURN = ''' 781build: 782 description: Build number of the fortigate image 783 returned: always 784 type: str 785 sample: '1547' 786http_method: 787 description: Last method used to provision the content into FortiGate 788 returned: always 789 type: str 790 sample: 'PUT' 791http_status: 792 description: Last result given by FortiGate on last operation applied 793 returned: always 794 type: str 795 sample: "200" 796mkey: 797 description: Master key (id) used in the last call to FortiGate 798 returned: success 799 type: str 800 sample: "id" 801name: 802 description: Name of the table used to fulfill the request 803 returned: always 804 type: str 805 sample: "urlfilter" 806path: 807 description: Path of the table used to fulfill the request 808 returned: always 809 type: str 810 sample: "webfilter" 811revision: 812 description: Internal revision number 813 returned: always 814 type: str 815 sample: "17.0.2.10658" 816serial: 817 description: Serial number of the unit 818 returned: always 819 type: str 820 sample: "FGVMEVYYQT3AB5352" 821status: 822 description: Indication of the operation's result 823 returned: always 824 type: str 825 sample: "success" 826vdom: 827 description: Virtual domain used 828 returned: always 829 type: str 830 sample: "root" 831version: 832 description: Version of the FortiGate 833 returned: always 834 type: str 835 sample: "v5.6.3" 836 837''' 838 839from ansible.module_utils.basic import AnsibleModule 840from ansible.module_utils.connection import Connection 841from ansible.module_utils.network.fortios.fortios import FortiOSHandler 842from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG 843 844 845def login(data, fos): 846 host = data['host'] 847 username = data['username'] 848 password = data['password'] 849 ssl_verify = data['ssl_verify'] 850 851 fos.debug('on') 852 if 'https' in data and not data['https']: 853 fos.https('off') 854 else: 855 fos.https('on') 856 857 fos.login(host, username, password, verify=ssl_verify) 858 859 860def filter_wireless_controller_wtp_data(json): 861 option_list = ['admin', 'allowaccess', 'bonjour_profile', 862 'coordinate_enable', 'coordinate_latitude', 'coordinate_longitude', 863 'coordinate_x', 'coordinate_y', 'image_download', 864 'index', 'ip_fragment_preventing', 'lan', 865 'led_state', 'location', 'login_passwd', 866 'login_passwd_change', 'mesh_bridge_enable', 'name', 867 'override_allowaccess', 'override_ip_fragment', 'override_lan', 868 'override_led_state', 'override_login_passwd_change', 'override_split_tunnel', 869 'override_wan_port_mode', 'radio_1', 'radio_2', 870 'split_tunneling_acl', 'split_tunneling_acl_local_ap_subnet', 'split_tunneling_acl_path', 871 'tun_mtu_downlink', 'tun_mtu_uplink', 'wan_port_mode', 872 'wtp_id', 'wtp_mode', 'wtp_profile'] 873 dictionary = {} 874 875 for attribute in option_list: 876 if attribute in json and json[attribute] is not None: 877 dictionary[attribute] = json[attribute] 878 879 return dictionary 880 881 882def underscore_to_hyphen(data): 883 if isinstance(data, list): 884 for elem in data: 885 elem = underscore_to_hyphen(elem) 886 elif isinstance(data, dict): 887 new_data = {} 888 for k, v in data.items(): 889 new_data[k.replace('_', '-')] = underscore_to_hyphen(v) 890 data = new_data 891 892 return data 893 894 895def wireless_controller_wtp(data, fos): 896 vdom = data['vdom'] 897 if 'state' in data and data['state']: 898 state = data['state'] 899 elif 'state' in data['wireless_controller_wtp'] and data['wireless_controller_wtp']: 900 state = data['wireless_controller_wtp']['state'] 901 else: 902 state = True 903 wireless_controller_wtp_data = data['wireless_controller_wtp'] 904 filtered_data = underscore_to_hyphen(filter_wireless_controller_wtp_data(wireless_controller_wtp_data)) 905 906 if state == "present": 907 return fos.set('wireless-controller', 908 'wtp', 909 data=filtered_data, 910 vdom=vdom) 911 912 elif state == "absent": 913 return fos.delete('wireless-controller', 914 'wtp', 915 mkey=filtered_data['wtp-id'], 916 vdom=vdom) 917 918 919def is_successful_status(status): 920 return status['status'] == "success" or \ 921 status['http_method'] == "DELETE" and status['http_status'] == 404 922 923 924def fortios_wireless_controller(data, fos): 925 926 if data['wireless_controller_wtp']: 927 resp = wireless_controller_wtp(data, fos) 928 929 return not is_successful_status(resp), \ 930 resp['status'] == "success", \ 931 resp 932 933 934def main(): 935 fields = { 936 "host": {"required": False, "type": "str"}, 937 "username": {"required": False, "type": "str"}, 938 "password": {"required": False, "type": "str", "default": "", "no_log": True}, 939 "vdom": {"required": False, "type": "str", "default": "root"}, 940 "https": {"required": False, "type": "bool", "default": True}, 941 "ssl_verify": {"required": False, "type": "bool", "default": True}, 942 "state": {"required": False, "type": "str", 943 "choices": ["present", "absent"]}, 944 "wireless_controller_wtp": { 945 "required": False, "type": "dict", "default": None, 946 "options": { 947 "state": {"required": False, "type": "str", 948 "choices": ["present", "absent"]}, 949 "admin": {"required": False, "type": "str", 950 "choices": ["discovered", "disable", "enable"]}, 951 "allowaccess": {"required": False, "type": "str", 952 "choices": ["telnet", "http", "https", 953 "ssh"]}, 954 "bonjour_profile": {"required": False, "type": "str"}, 955 "coordinate_enable": {"required": False, "type": "str", 956 "choices": ["enable", "disable"]}, 957 "coordinate_latitude": {"required": False, "type": "str"}, 958 "coordinate_longitude": {"required": False, "type": "str"}, 959 "coordinate_x": {"required": False, "type": "str"}, 960 "coordinate_y": {"required": False, "type": "str"}, 961 "image_download": {"required": False, "type": "str", 962 "choices": ["enable", "disable"]}, 963 "index": {"required": False, "type": "int"}, 964 "ip_fragment_preventing": {"required": False, "type": "str", 965 "choices": ["tcp-mss-adjust", "icmp-unreachable"]}, 966 "lan": {"required": False, "type": "dict", 967 "options": { 968 "port_mode": {"required": False, "type": "str", 969 "choices": ["offline", "nat-to-wan", "bridge-to-wan", 970 "bridge-to-ssid"]}, 971 "port_ssid": {"required": False, "type": "str"}, 972 "port1_mode": {"required": False, "type": "str", 973 "choices": ["offline", "nat-to-wan", "bridge-to-wan", 974 "bridge-to-ssid"]}, 975 "port1_ssid": {"required": False, "type": "str"}, 976 "port2_mode": {"required": False, "type": "str", 977 "choices": ["offline", "nat-to-wan", "bridge-to-wan", 978 "bridge-to-ssid"]}, 979 "port2_ssid": {"required": False, "type": "str"}, 980 "port3_mode": {"required": False, "type": "str", 981 "choices": ["offline", "nat-to-wan", "bridge-to-wan", 982 "bridge-to-ssid"]}, 983 "port3_ssid": {"required": False, "type": "str"}, 984 "port4_mode": {"required": False, "type": "str", 985 "choices": ["offline", "nat-to-wan", "bridge-to-wan", 986 "bridge-to-ssid"]}, 987 "port4_ssid": {"required": False, "type": "str"}, 988 "port5_mode": {"required": False, "type": "str", 989 "choices": ["offline", "nat-to-wan", "bridge-to-wan", 990 "bridge-to-ssid"]}, 991 "port5_ssid": {"required": False, "type": "str"}, 992 "port6_mode": {"required": False, "type": "str", 993 "choices": ["offline", "nat-to-wan", "bridge-to-wan", 994 "bridge-to-ssid"]}, 995 "port6_ssid": {"required": False, "type": "str"}, 996 "port7_mode": {"required": False, "type": "str", 997 "choices": ["offline", "nat-to-wan", "bridge-to-wan", 998 "bridge-to-ssid"]}, 999 "port7_ssid": {"required": False, "type": "str"}, 1000 "port8_mode": {"required": False, "type": "str", 1001 "choices": ["offline", "nat-to-wan", "bridge-to-wan", 1002 "bridge-to-ssid"]}, 1003 "port8_ssid": {"required": False, "type": "str"} 1004 }}, 1005 "led_state": {"required": False, "type": "str", 1006 "choices": ["enable", "disable"]}, 1007 "location": {"required": False, "type": "str"}, 1008 "login_passwd": {"required": False, "type": "str", "no_log": True}, 1009 "login_passwd_change": {"required": False, "type": "str", 1010 "choices": ["yes", "default", "no"]}, 1011 "mesh_bridge_enable": {"required": False, "type": "str", 1012 "choices": ["default", "enable", "disable"]}, 1013 "name": {"required": False, "type": "str"}, 1014 "override_allowaccess": {"required": False, "type": "str", 1015 "choices": ["enable", "disable"]}, 1016 "override_ip_fragment": {"required": False, "type": "str", 1017 "choices": ["enable", "disable"]}, 1018 "override_lan": {"required": False, "type": "str", 1019 "choices": ["enable", "disable"]}, 1020 "override_led_state": {"required": False, "type": "str", 1021 "choices": ["enable", "disable"]}, 1022 "override_login_passwd_change": {"required": False, "type": "str", 1023 "choices": ["enable", "disable"]}, 1024 "override_split_tunnel": {"required": False, "type": "str", 1025 "choices": ["enable", "disable"]}, 1026 "override_wan_port_mode": {"required": False, "type": "str", 1027 "choices": ["enable", "disable"]}, 1028 "radio_1": {"required": False, "type": "dict", 1029 "options": { 1030 "auto_power_high": {"required": False, "type": "int"}, 1031 "auto_power_level": {"required": False, "type": "str", 1032 "choices": ["enable", "disable"]}, 1033 "auto_power_low": {"required": False, "type": "int"}, 1034 "band": {"required": False, "type": "str", 1035 "choices": ["802.11a", "802.11b", "802.11g", 1036 "802.11n", "802.11n-5G", "802.11n,g-only", 1037 "802.11g-only", "802.11n-only", "802.11n-5G-only", 1038 "802.11ac", "802.11ac,n-only", "802.11ac-only"]}, 1039 "channel": {"required": False, "type": "list", 1040 "options": { 1041 "chan": {"required": True, "type": "str"} 1042 }}, 1043 "override_analysis": {"required": False, "type": "str", 1044 "choices": ["enable", "disable"]}, 1045 "override_band": {"required": False, "type": "str", 1046 "choices": ["enable", "disable"]}, 1047 "override_channel": {"required": False, "type": "str", 1048 "choices": ["enable", "disable"]}, 1049 "override_txpower": {"required": False, "type": "str", 1050 "choices": ["enable", "disable"]}, 1051 "override_vaps": {"required": False, "type": "str", 1052 "choices": ["enable", "disable"]}, 1053 "power_level": {"required": False, "type": "int"}, 1054 "radio_id": {"required": False, "type": "int"}, 1055 "spectrum_analysis": {"required": False, "type": "str", 1056 "choices": ["enable", "disable"]}, 1057 "vap_all": {"required": False, "type": "str", 1058 "choices": ["enable", "disable"]}, 1059 "vaps": {"required": False, "type": "list", 1060 "options": { 1061 "name": {"required": True, "type": "str"} 1062 }} 1063 }}, 1064 "radio_2": {"required": False, "type": "dict", 1065 "options": { 1066 "auto_power_high": {"required": False, "type": "int"}, 1067 "auto_power_level": {"required": False, "type": "str", 1068 "choices": ["enable", "disable"]}, 1069 "auto_power_low": {"required": False, "type": "int"}, 1070 "band": {"required": False, "type": "str", 1071 "choices": ["802.11a", "802.11b", "802.11g", 1072 "802.11n", "802.11n-5G", "802.11n,g-only", 1073 "802.11g-only", "802.11n-only", "802.11n-5G-only", 1074 "802.11ac", "802.11ac,n-only", "802.11ac-only"]}, 1075 "channel": {"required": False, "type": "list", 1076 "options": { 1077 "chan": {"required": True, "type": "str"} 1078 }}, 1079 "override_analysis": {"required": False, "type": "str", 1080 "choices": ["enable", "disable"]}, 1081 "override_band": {"required": False, "type": "str", 1082 "choices": ["enable", "disable"]}, 1083 "override_channel": {"required": False, "type": "str", 1084 "choices": ["enable", "disable"]}, 1085 "override_txpower": {"required": False, "type": "str", 1086 "choices": ["enable", "disable"]}, 1087 "override_vaps": {"required": False, "type": "str", 1088 "choices": ["enable", "disable"]}, 1089 "power_level": {"required": False, "type": "int"}, 1090 "radio_id": {"required": False, "type": "int"}, 1091 "spectrum_analysis": {"required": False, "type": "str", 1092 "choices": ["enable", "disable"]}, 1093 "vap_all": {"required": False, "type": "str", 1094 "choices": ["enable", "disable"]}, 1095 "vaps": {"required": False, "type": "list", 1096 "options": { 1097 "name": {"required": True, "type": "str"} 1098 }} 1099 }}, 1100 "split_tunneling_acl": {"required": False, "type": "list", 1101 "options": { 1102 "dest_ip": {"required": False, "type": "str"}, 1103 "id": {"required": True, "type": "int"} 1104 }}, 1105 "split_tunneling_acl_local_ap_subnet": {"required": False, "type": "str", 1106 "choices": ["enable", "disable"]}, 1107 "split_tunneling_acl_path": {"required": False, "type": "str", 1108 "choices": ["tunnel", "local"]}, 1109 "tun_mtu_downlink": {"required": False, "type": "int"}, 1110 "tun_mtu_uplink": {"required": False, "type": "int"}, 1111 "wan_port_mode": {"required": False, "type": "str", 1112 "choices": ["wan-lan", "wan-only"]}, 1113 "wtp_id": {"required": False, "type": "str"}, 1114 "wtp_mode": {"required": False, "type": "str", 1115 "choices": ["normal", "remote"]}, 1116 "wtp_profile": {"required": False, "type": "str"} 1117 1118 } 1119 } 1120 } 1121 1122 module = AnsibleModule(argument_spec=fields, 1123 supports_check_mode=False) 1124 1125 # legacy_mode refers to using fortiosapi instead of HTTPAPI 1126 legacy_mode = 'host' in module.params and module.params['host'] is not None and \ 1127 'username' in module.params and module.params['username'] is not None and \ 1128 'password' in module.params and module.params['password'] is not None 1129 1130 if not legacy_mode: 1131 if module._socket_path: 1132 connection = Connection(module._socket_path) 1133 fos = FortiOSHandler(connection) 1134 1135 is_error, has_changed, result = fortios_wireless_controller(module.params, fos) 1136 else: 1137 module.fail_json(**FAIL_SOCKET_MSG) 1138 else: 1139 try: 1140 from fortiosapi import FortiOSAPI 1141 except ImportError: 1142 module.fail_json(msg="fortiosapi module is required") 1143 1144 fos = FortiOSAPI() 1145 1146 login(module.params, fos) 1147 is_error, has_changed, result = fortios_wireless_controller(module.params, fos) 1148 fos.logout() 1149 1150 if not is_error: 1151 module.exit_json(changed=has_changed, meta=result) 1152 else: 1153 module.fail_json(msg="Error in repo", meta=result) 1154 1155 1156if __name__ == '__main__': 1157 main() 1158