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_system_virtual_wan_link
27short_description: Configure redundant internet connections using SD-WAN (formerly virtual WAN link) 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 virtual_wan_link 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    system_virtual_wan_link:
77        description:
78            - Configure redundant internet connections using SD-WAN (formerly virtual WAN link).
79        default: null
80        type: dict
81        suboptions:
82            fail_alert_interfaces:
83                description:
84                    - Physical interfaces that will be alerted.
85                type: list
86                suboptions:
87                    name:
88                        description:
89                            - Physical interface name. Source system.interface.name.
90                        required: true
91                        type: str
92            fail_detect:
93                description:
94                    - Enable/disable SD-WAN Internet connection status checking (failure detection).
95                type: str
96                choices:
97                    - enable
98                    - disable
99            health_check:
100                description:
101                    - SD-WAN status checking or health checking. Identify a server on the Internet and determine how SD-WAN verifies that the FortiGate can
102                       communicate with it.
103                type: list
104                suboptions:
105                    addr_mode:
106                        description:
107                            - Address mode (IPv4 or IPv6).
108                        type: str
109                        choices:
110                            - ipv4
111                            - ipv6
112                    failtime:
113                        description:
114                            - Number of failures before server is considered lost (1 - 3600).
115                        type: int
116                    http_agent:
117                        description:
118                            - String in the http-agent field in the HTTP header.
119                        type: str
120                    http_get:
121                        description:
122                            - URL used to communicate with the server if the protocol if the protocol is HTTP.
123                        type: str
124                    http_match:
125                        description:
126                            - Response string expected from the server if the protocol is HTTP.
127                        type: str
128                    interval:
129                        description:
130                            - Status check interval, or the time between attempting to connect to the server (1 - 3600 sec).
131                        type: int
132                    members:
133                        description:
134                            - Member sequence number list.
135                        type: list
136                        suboptions:
137                            seq_num:
138                                description:
139                                    - Member sequence number. Source system.virtual-wan-link.members.seq-num.
140                                type: int
141                    name:
142                        description:
143                            - Status check or health check name.
144                        required: true
145                        type: str
146                    packet_size:
147                        description:
148                            - Packet size of a twamp test session,
149                        type: int
150                    password:
151                        description:
152                            - Twamp controller password in authentication mode
153                        type: str
154                    port:
155                        description:
156                            - Port number used to communicate with the server over the selected protocol.
157                        type: int
158                    protocol:
159                        description:
160                            - Protocol used to determine if the FortiGate can communicate with the server.
161                        type: str
162                        choices:
163                            - ping
164                            - tcp-echo
165                            - udp-echo
166                            - http
167                            - twamp
168                            - ping6
169                    recoverytime:
170                        description:
171                            - Number of successful responses received before server is considered recovered (1 - 3600).
172                        type: int
173                    security_mode:
174                        description:
175                            - Twamp controller security mode.
176                        type: str
177                        choices:
178                            - none
179                            - authentication
180                    server:
181                        description:
182                            - IP address or FQDN name of the server.
183                        type: str
184                    sla:
185                        description:
186                            - Service level agreement (SLA).
187                        type: list
188                        suboptions:
189                            id:
190                                description:
191                                    - SLA ID.
192                                required: true
193                                type: int
194                            jitter_threshold:
195                                description:
196                                    - Jitter for SLA to make decision in milliseconds. (0 - 10000000).
197                                type: int
198                            latency_threshold:
199                                description:
200                                    - Latency for SLA to make decision in milliseconds. (0 - 10000000).
201                                type: int
202                            link_cost_factor:
203                                description:
204                                    - Criteria on which to base link selection.
205                                type: str
206                                choices:
207                                    - latency
208                                    - jitter
209                                    - packet-loss
210                            packetloss_threshold:
211                                description:
212                                    - Packet loss for SLA to make decision in percentage. (0 - 100).
213                                type: int
214                    threshold_alert_jitter:
215                        description:
216                            - Alert threshold for jitter (ms).
217                        type: int
218                    threshold_alert_latency:
219                        description:
220                            - Alert threshold for latency (ms).
221                        type: int
222                    threshold_alert_packetloss:
223                        description:
224                            - Alert threshold for packet loss (percentage).
225                        type: int
226                    threshold_warning_jitter:
227                        description:
228                            - Warning threshold for jitter (ms).
229                        type: int
230                    threshold_warning_latency:
231                        description:
232                            - Warning threshold for latency (ms).
233                        type: int
234                    threshold_warning_packetloss:
235                        description:
236                            - Warning threshold for packet loss (percentage).
237                        type: int
238                    update_cascade_interface:
239                        description:
240                            - Enable/disable update cascade interface.
241                        type: str
242                        choices:
243                            - enable
244                            - disable
245                    update_static_route:
246                        description:
247                            - Enable/disable updating the static route.
248                        type: str
249                        choices:
250                            - enable
251                            - disable
252            load_balance_mode:
253                description:
254                    - Algorithm or mode to use for load balancing Internet traffic to SD-WAN members.
255                type: str
256                choices:
257                    - source-ip-based
258                    - weight-based
259                    - usage-based
260                    - source-dest-ip-based
261                    - measured-volume-based
262            members:
263                description:
264                    - Physical FortiGate interfaces added to the virtual-wan-link.
265                type: list
266                suboptions:
267                    comment:
268                        description:
269                            - Comments.
270                        type: str
271                    gateway:
272                        description:
273                            - The default gateway for this interface. Usually the default gateway of the Internet service provider that this interface is
274                               connected to.
275                        type: str
276                    gateway6:
277                        description:
278                            - IPv6 gateway.
279                        type: str
280                    ingress_spillover_threshold:
281                        description:
282                            - Ingress spillover threshold for this interface (0 - 16776000 kbit/s). When this traffic volume threshold is reached, new
283                               sessions spill over to other interfaces in the SD-WAN.
284                        type: int
285                    interface:
286                        description:
287                            - Interface name. Source system.interface.name.
288                        type: str
289                    priority:
290                        description:
291                            - Priority of the interface (0 - 4294967295). Used for SD-WAN rules or priority rules.
292                        type: int
293                    seq_num:
294                        description:
295                            - Sequence number(1-255).
296                        type: int
297                    source:
298                        description:
299                            - Source IP address used in the health-check packet to the server.
300                        type: str
301                    source6:
302                        description:
303                            - Source IPv6 address used in the health-check packet to the server.
304                        type: str
305                    spillover_threshold:
306                        description:
307                            - Egress spillover threshold for this interface (0 - 16776000 kbit/s). When this traffic volume threshold is reached, new sessions
308                               spill over to other interfaces in the SD-WAN.
309                        type: int
310                    status:
311                        description:
312                            - Enable/disable this interface in the SD-WAN.
313                        type: str
314                        choices:
315                            - disable
316                            - enable
317                    volume_ratio:
318                        description:
319                            - Measured volume ratio (this value / sum of all values = percentage of link volume, 0 - 255).
320                        type: int
321                    weight:
322                        description:
323                            - Weight of this interface for weighted load balancing. (0 - 255) More traffic is directed to interfaces with higher weights.
324                        type: int
325            service:
326                description:
327                    - Create SD-WAN rules or priority rules (also called services) to control how sessions are distributed to physical interfaces in the
328                       SD-WAN.
329                type: list
330                suboptions:
331                    addr_mode:
332                        description:
333                            - Address mode (IPv4 or IPv6).
334                        type: str
335                        choices:
336                            - ipv4
337                            - ipv6
338                    bandwidth_weight:
339                        description:
340                            - Coefficient of reciprocal of available bidirectional bandwidth in the formula of custom-profile-1.
341                        type: int
342                    default:
343                        description:
344                            - Enable/disable use of SD-WAN as default service.
345                        type: str
346                        choices:
347                            - enable
348                            - disable
349                    dscp_forward:
350                        description:
351                            - Enable/disable forward traffic DSCP tag.
352                        type: str
353                        choices:
354                            - enable
355                            - disable
356                    dscp_forward_tag:
357                        description:
358                            - Forward traffic DSCP tag.
359                        type: str
360                    dscp_reverse:
361                        description:
362                            - Enable/disable reverse traffic DSCP tag.
363                        type: str
364                        choices:
365                            - enable
366                            - disable
367                    dscp_reverse_tag:
368                        description:
369                            - Reverse traffic DSCP tag.
370                        type: str
371                    dst:
372                        description:
373                            - Destination address name.
374                        type: list
375                        suboptions:
376                            name:
377                                description:
378                                    - Address or address group name. Source firewall.address.name firewall.addrgrp.name.
379                                required: true
380                                type: str
381                    dst_negate:
382                        description:
383                            - Enable/disable negation of destination address match.
384                        type: str
385                        choices:
386                            - enable
387                            - disable
388                    dst6:
389                        description:
390                            - Destination address6 name.
391                        type: list
392                        suboptions:
393                            name:
394                                description:
395                                    - Address6 or address6 group name. Source firewall.address6.name firewall.addrgrp6.name.
396                                required: true
397                                type: str
398                    end_port:
399                        description:
400                            - End destination port number.
401                        type: int
402                    gateway:
403                        description:
404                            - Enable/disable SD-WAN service gateway.
405                        type: str
406                        choices:
407                            - enable
408                            - disable
409                    groups:
410                        description:
411                            - User groups.
412                        type: list
413                        suboptions:
414                            name:
415                                description:
416                                    - Group name. Source user.group.name.
417                                required: true
418                                type: str
419                    health_check:
420                        description:
421                            - Health check. Source system.virtual-wan-link.health-check.name.
422                        type: str
423                    hold_down_time:
424                        description:
425                            - Waiting period in seconds when switching from the back-up member to the primary member (0 - 10000000).
426                        type: int
427                    id:
428                        description:
429                            - Priority rule ID (1 - 4000).
430                        required: true
431                        type: int
432                    input_device:
433                        description:
434                            - Source interface name.
435                        type: list
436                        suboptions:
437                            name:
438                                description:
439                                    - Interface name. Source system.interface.name.
440                                required: true
441                                type: str
442                    internet_service:
443                        description:
444                            - Enable/disable use of Internet service for application-based load balancing.
445                        type: str
446                        choices:
447                            - enable
448                            - disable
449                    internet_service_ctrl:
450                        description:
451                            - Control-based Internet Service ID list.
452                        type: list
453                        suboptions:
454                            id:
455                                description:
456                                    - Control-based Internet Service ID.
457                                required: true
458                                type: int
459                    internet_service_ctrl_group:
460                        description:
461                            - Control-based Internet Service group list.
462                        type: list
463                        suboptions:
464                            name:
465                                description:
466                                    - Control-based Internet Service group name. Source application.group.name.
467                                required: true
468                                type: str
469                    internet_service_custom:
470                        description:
471                            - Custom Internet service name list.
472                        type: list
473                        suboptions:
474                            name:
475                                description:
476                                    - Custom Internet service name. Source firewall.internet-service-custom.name.
477                                required: true
478                                type: str
479                    internet_service_custom_group:
480                        description:
481                            - Custom Internet Service group list.
482                        type: list
483                        suboptions:
484                            name:
485                                description:
486                                    - Custom Internet Service group name. Source firewall.internet-service-custom-group.name.
487                                required: true
488                                type: str
489                    internet_service_group:
490                        description:
491                            - Internet Service group list.
492                        type: list
493                        suboptions:
494                            name:
495                                description:
496                                    - Internet Service group name. Source firewall.internet-service-group.name.
497                                required: true
498                                type: str
499                    internet_service_id:
500                        description:
501                            - Internet service ID list.
502                        type: list
503                        suboptions:
504                            id:
505                                description:
506                                    - Internet service ID. Source firewall.internet-service.id.
507                                required: true
508                                type: int
509                    jitter_weight:
510                        description:
511                            - Coefficient of jitter in the formula of custom-profile-1.
512                        type: int
513                    latency_weight:
514                        description:
515                            - Coefficient of latency in the formula of custom-profile-1.
516                        type: int
517                    link_cost_factor:
518                        description:
519                            - Link cost factor.
520                        type: str
521                        choices:
522                            - latency
523                            - jitter
524                            - packet-loss
525                            - inbandwidth
526                            - outbandwidth
527                            - bibandwidth
528                            - custom-profile-1
529                    link_cost_threshold:
530                        description:
531                            - Percentage threshold change of link cost values that will result in policy route regeneration (0 - 10000000).
532                        type: int
533                    member:
534                        description:
535                            - Member sequence number.
536                        type: int
537                    mode:
538                        description:
539                            - Control how the priority rule sets the priority of interfaces in the SD-WAN.
540                        type: str
541                        choices:
542                            - auto
543                            - manual
544                            - priority
545                            - sla
546                    name:
547                        description:
548                            - Priority rule name.
549                        type: str
550                    packet_loss_weight:
551                        description:
552                            - Coefficient of packet-loss in the formula of custom-profile-1.
553                        type: int
554                    priority_members:
555                        description:
556                            - Member sequence number list.
557                        type: list
558                        suboptions:
559                            seq_num:
560                                description:
561                                    - Member sequence number. Source system.virtual-wan-link.members.seq-num.
562                                type: int
563                    protocol:
564                        description:
565                            - Protocol number.
566                        type: int
567                    quality_link:
568                        description:
569                            - Quality grade.
570                        type: int
571                    route_tag:
572                        description:
573                            - IPv4 route map route-tag.
574                        type: int
575                    sla:
576                        description:
577                            - Service level agreement (SLA).
578                        type: list
579                        suboptions:
580                            health_check:
581                                description:
582                                    - Virtual WAN Link health-check. Source system.virtual-wan-link.health-check.name.
583                                type: str
584                            id:
585                                description:
586                                    - SLA ID.
587                                type: int
588                    src:
589                        description:
590                            - Source address name.
591                        type: list
592                        suboptions:
593                            name:
594                                description:
595                                    - Address or address group name. Source firewall.address.name firewall.addrgrp.name.
596                                required: true
597                                type: str
598                    src_negate:
599                        description:
600                            - Enable/disable negation of source address match.
601                        type: str
602                        choices:
603                            - enable
604                            - disable
605                    src6:
606                        description:
607                            - Source address6 name.
608                        type: list
609                        suboptions:
610                            name:
611                                description:
612                                    - Address6 or address6 group name. Source firewall.address6.name firewall.addrgrp6.name.
613                                required: true
614                                type: str
615                    start_port:
616                        description:
617                            - Start destination port number.
618                        type: int
619                    status:
620                        description:
621                            - Enable/disable SD-WAN service.
622                        type: str
623                        choices:
624                            - enable
625                            - disable
626                    tos:
627                        description:
628                            - Type of service bit pattern.
629                        type: str
630                    tos_mask:
631                        description:
632                            - Type of service evaluated bits.
633                        type: str
634                    users:
635                        description:
636                            - User name.
637                        type: list
638                        suboptions:
639                            name:
640                                description:
641                                    - User name. Source user.local.name.
642                                required: true
643                                type: str
644            status:
645                description:
646                    - Enable/disable SD-WAN.
647                type: str
648                choices:
649                    - disable
650                    - enable
651'''
652
653EXAMPLES = '''
654- hosts: localhost
655  vars:
656   host: "192.168.122.40"
657   username: "admin"
658   password: ""
659   vdom: "root"
660   ssl_verify: "False"
661  tasks:
662  - name: Configure redundant internet connections using SD-WAN (formerly virtual WAN link).
663    fortios_system_virtual_wan_link:
664      host:  "{{ host }}"
665      username: "{{ username }}"
666      password: "{{ password }}"
667      vdom:  "{{ vdom }}"
668      https: "False"
669      system_virtual_wan_link:
670        fail_alert_interfaces:
671         -
672            name: "default_name_4 (source system.interface.name)"
673        fail_detect: "enable"
674        health_check:
675         -
676            addr_mode: "ipv4"
677            failtime: "8"
678            http_agent: "<your_own_value>"
679            http_get: "<your_own_value>"
680            http_match: "<your_own_value>"
681            interval: "12"
682            members:
683             -
684                seq_num: "14 (source system.virtual-wan-link.members.seq-num)"
685            name: "default_name_15"
686            packet_size: "16"
687            password: "<your_own_value>"
688            port: "18"
689            protocol: "ping"
690            recoverytime: "20"
691            security_mode: "none"
692            server: "192.168.100.40"
693            sla:
694             -
695                id:  "24"
696                jitter_threshold: "25"
697                latency_threshold: "26"
698                link_cost_factor: "latency"
699                packetloss_threshold: "28"
700            threshold_alert_jitter: "29"
701            threshold_alert_latency: "30"
702            threshold_alert_packetloss: "31"
703            threshold_warning_jitter: "32"
704            threshold_warning_latency: "33"
705            threshold_warning_packetloss: "34"
706            update_cascade_interface: "enable"
707            update_static_route: "enable"
708        load_balance_mode: "source-ip-based"
709        members:
710         -
711            comment: "Comments."
712            gateway: "<your_own_value>"
713            gateway6: "<your_own_value>"
714            ingress_spillover_threshold: "42"
715            interface: "<your_own_value> (source system.interface.name)"
716            priority: "44"
717            seq_num: "45"
718            source: "<your_own_value>"
719            source6: "<your_own_value>"
720            spillover_threshold: "48"
721            status: "disable"
722            volume_ratio: "50"
723            weight: "51"
724        service:
725         -
726            addr_mode: "ipv4"
727            bandwidth_weight: "54"
728            default: "enable"
729            dscp_forward: "enable"
730            dscp_forward_tag: "<your_own_value>"
731            dscp_reverse: "enable"
732            dscp_reverse_tag: "<your_own_value>"
733            dst:
734             -
735                name: "default_name_61 (source firewall.address.name firewall.addrgrp.name)"
736            dst_negate: "enable"
737            dst6:
738             -
739                name: "default_name_64 (source firewall.address6.name firewall.addrgrp6.name)"
740            end_port: "65"
741            gateway: "enable"
742            groups:
743             -
744                name: "default_name_68 (source user.group.name)"
745            health_check: "<your_own_value> (source system.virtual-wan-link.health-check.name)"
746            hold_down_time: "70"
747            id:  "71"
748            input_device:
749             -
750                name: "default_name_73 (source system.interface.name)"
751            internet_service: "enable"
752            internet_service_ctrl:
753             -
754                id:  "76"
755            internet_service_ctrl_group:
756             -
757                name: "default_name_78 (source application.group.name)"
758            internet_service_custom:
759             -
760                name: "default_name_80 (source firewall.internet-service-custom.name)"
761            internet_service_custom_group:
762             -
763                name: "default_name_82 (source firewall.internet-service-custom-group.name)"
764            internet_service_group:
765             -
766                name: "default_name_84 (source firewall.internet-service-group.name)"
767            internet_service_id:
768             -
769                id:  "86 (source firewall.internet-service.id)"
770            jitter_weight: "87"
771            latency_weight: "88"
772            link_cost_factor: "latency"
773            link_cost_threshold: "90"
774            member: "91"
775            mode: "auto"
776            name: "default_name_93"
777            packet_loss_weight: "94"
778            priority_members:
779             -
780                seq_num: "96 (source system.virtual-wan-link.members.seq-num)"
781            protocol: "97"
782            quality_link: "98"
783            route_tag: "99"
784            sla:
785             -
786                health_check: "<your_own_value> (source system.virtual-wan-link.health-check.name)"
787                id:  "102"
788            src:
789             -
790                name: "default_name_104 (source firewall.address.name firewall.addrgrp.name)"
791            src_negate: "enable"
792            src6:
793             -
794                name: "default_name_107 (source firewall.address6.name firewall.addrgrp6.name)"
795            start_port: "108"
796            status: "enable"
797            tos: "<your_own_value>"
798            tos_mask: "<your_own_value>"
799            users:
800             -
801                name: "default_name_113 (source user.local.name)"
802        status: "disable"
803'''
804
805RETURN = '''
806build:
807  description: Build number of the fortigate image
808  returned: always
809  type: str
810  sample: '1547'
811http_method:
812  description: Last method used to provision the content into FortiGate
813  returned: always
814  type: str
815  sample: 'PUT'
816http_status:
817  description: Last result given by FortiGate on last operation applied
818  returned: always
819  type: str
820  sample: "200"
821mkey:
822  description: Master key (id) used in the last call to FortiGate
823  returned: success
824  type: str
825  sample: "id"
826name:
827  description: Name of the table used to fulfill the request
828  returned: always
829  type: str
830  sample: "urlfilter"
831path:
832  description: Path of the table used to fulfill the request
833  returned: always
834  type: str
835  sample: "webfilter"
836revision:
837  description: Internal revision number
838  returned: always
839  type: str
840  sample: "17.0.2.10658"
841serial:
842  description: Serial number of the unit
843  returned: always
844  type: str
845  sample: "FGVMEVYYQT3AB5352"
846status:
847  description: Indication of the operation's result
848  returned: always
849  type: str
850  sample: "success"
851vdom:
852  description: Virtual domain used
853  returned: always
854  type: str
855  sample: "root"
856version:
857  description: Version of the FortiGate
858  returned: always
859  type: str
860  sample: "v5.6.3"
861
862'''
863
864from ansible.module_utils.basic import AnsibleModule
865from ansible.module_utils.connection import Connection
866from ansible.module_utils.network.fortios.fortios import FortiOSHandler
867from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
868
869
870def login(data, fos):
871    host = data['host']
872    username = data['username']
873    password = data['password']
874    ssl_verify = data['ssl_verify']
875
876    fos.debug('on')
877    if 'https' in data and not data['https']:
878        fos.https('off')
879    else:
880        fos.https('on')
881
882    fos.login(host, username, password, verify=ssl_verify)
883
884
885def filter_system_virtual_wan_link_data(json):
886    option_list = ['fail_alert_interfaces', 'fail_detect', 'health_check',
887                   'load_balance_mode', 'members', 'service',
888                   'status']
889    dictionary = {}
890
891    for attribute in option_list:
892        if attribute in json and json[attribute] is not None:
893            dictionary[attribute] = json[attribute]
894
895    return dictionary
896
897
898def underscore_to_hyphen(data):
899    if isinstance(data, list):
900        for elem in data:
901            elem = underscore_to_hyphen(elem)
902    elif isinstance(data, dict):
903        new_data = {}
904        for k, v in data.items():
905            new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
906        data = new_data
907
908    return data
909
910
911def system_virtual_wan_link(data, fos):
912    vdom = data['vdom']
913    system_virtual_wan_link_data = data['system_virtual_wan_link']
914    filtered_data = underscore_to_hyphen(filter_system_virtual_wan_link_data(system_virtual_wan_link_data))
915
916    return fos.set('system',
917                   'virtual-wan-link',
918                   data=filtered_data,
919                   vdom=vdom)
920
921
922def is_successful_status(status):
923    return status['status'] == "success" or \
924        status['http_method'] == "DELETE" and status['http_status'] == 404
925
926
927def fortios_system(data, fos):
928
929    if data['system_virtual_wan_link']:
930        resp = system_virtual_wan_link(data, fos)
931
932    return not is_successful_status(resp), \
933        resp['status'] == "success", \
934        resp
935
936
937def main():
938    fields = {
939        "host": {"required": False, "type": "str"},
940        "username": {"required": False, "type": "str"},
941        "password": {"required": False, "type": "str", "default": "", "no_log": True},
942        "vdom": {"required": False, "type": "str", "default": "root"},
943        "https": {"required": False, "type": "bool", "default": True},
944        "ssl_verify": {"required": False, "type": "bool", "default": True},
945        "system_virtual_wan_link": {
946            "required": False, "type": "dict", "default": None,
947            "options": {
948                "fail_alert_interfaces": {"required": False, "type": "list",
949                                          "options": {
950                                              "name": {"required": True, "type": "str"}
951                                          }},
952                "fail_detect": {"required": False, "type": "str",
953                                "choices": ["enable", "disable"]},
954                "health_check": {"required": False, "type": "list",
955                                 "options": {
956                                     "addr_mode": {"required": False, "type": "str",
957                                                   "choices": ["ipv4", "ipv6"]},
958                                     "failtime": {"required": False, "type": "int"},
959                                     "http_agent": {"required": False, "type": "str"},
960                                     "http_get": {"required": False, "type": "str"},
961                                     "http_match": {"required": False, "type": "str"},
962                                     "interval": {"required": False, "type": "int"},
963                                     "members": {"required": False, "type": "list",
964                                                 "options": {
965                                                     "seq_num": {"required": False, "type": "int"}
966                                                 }},
967                                     "name": {"required": True, "type": "str"},
968                                     "packet_size": {"required": False, "type": "int"},
969                                     "password": {"required": False, "type": "str", "no_log": True},
970                                     "port": {"required": False, "type": "int"},
971                                     "protocol": {"required": False, "type": "str",
972                                                  "choices": ["ping", "tcp-echo", "udp-echo",
973                                                              "http", "twamp", "ping6"]},
974                                     "recoverytime": {"required": False, "type": "int"},
975                                     "security_mode": {"required": False, "type": "str",
976                                                       "choices": ["none", "authentication"]},
977                                     "server": {"required": False, "type": "str"},
978                                     "sla": {"required": False, "type": "list",
979                                             "options": {
980                                                 "id": {"required": True, "type": "int"},
981                                                 "jitter_threshold": {"required": False, "type": "int"},
982                                                 "latency_threshold": {"required": False, "type": "int"},
983                                                 "link_cost_factor": {"required": False, "type": "str",
984                                                                      "choices": ["latency", "jitter", "packet-loss"]},
985                                                 "packetloss_threshold": {"required": False, "type": "int"}
986                                             }},
987                                     "threshold_alert_jitter": {"required": False, "type": "int"},
988                                     "threshold_alert_latency": {"required": False, "type": "int"},
989                                     "threshold_alert_packetloss": {"required": False, "type": "int"},
990                                     "threshold_warning_jitter": {"required": False, "type": "int"},
991                                     "threshold_warning_latency": {"required": False, "type": "int"},
992                                     "threshold_warning_packetloss": {"required": False, "type": "int"},
993                                     "update_cascade_interface": {"required": False, "type": "str",
994                                                                  "choices": ["enable", "disable"]},
995                                     "update_static_route": {"required": False, "type": "str",
996                                                             "choices": ["enable", "disable"]}
997                                 }},
998                "load_balance_mode": {"required": False, "type": "str",
999                                      "choices": ["source-ip-based", "weight-based", "usage-based",
1000                                                  "source-dest-ip-based", "measured-volume-based"]},
1001                "members": {"required": False, "type": "list",
1002                            "options": {
1003                                "comment": {"required": False, "type": "str"},
1004                                "gateway": {"required": False, "type": "str"},
1005                                "gateway6": {"required": False, "type": "str"},
1006                                "ingress_spillover_threshold": {"required": False, "type": "int"},
1007                                "interface": {"required": False, "type": "str"},
1008                                "priority": {"required": False, "type": "int"},
1009                                "seq_num": {"required": False, "type": "int"},
1010                                "source": {"required": False, "type": "str"},
1011                                "source6": {"required": False, "type": "str"},
1012                                "spillover_threshold": {"required": False, "type": "int"},
1013                                "status": {"required": False, "type": "str",
1014                                           "choices": ["disable", "enable"]},
1015                                "volume_ratio": {"required": False, "type": "int"},
1016                                "weight": {"required": False, "type": "int"}
1017                            }},
1018                "service": {"required": False, "type": "list",
1019                            "options": {
1020                                "addr_mode": {"required": False, "type": "str",
1021                                              "choices": ["ipv4", "ipv6"]},
1022                                "bandwidth_weight": {"required": False, "type": "int"},
1023                                "default": {"required": False, "type": "str",
1024                                            "choices": ["enable", "disable"]},
1025                                "dscp_forward": {"required": False, "type": "str",
1026                                                 "choices": ["enable", "disable"]},
1027                                "dscp_forward_tag": {"required": False, "type": "str"},
1028                                "dscp_reverse": {"required": False, "type": "str",
1029                                                 "choices": ["enable", "disable"]},
1030                                "dscp_reverse_tag": {"required": False, "type": "str"},
1031                                "dst": {"required": False, "type": "list",
1032                                        "options": {
1033                                            "name": {"required": True, "type": "str"}
1034                                        }},
1035                                "dst_negate": {"required": False, "type": "str",
1036                                               "choices": ["enable", "disable"]},
1037                                "dst6": {"required": False, "type": "list",
1038                                         "options": {
1039                                             "name": {"required": True, "type": "str"}
1040                                         }},
1041                                "end_port": {"required": False, "type": "int"},
1042                                "gateway": {"required": False, "type": "str",
1043                                            "choices": ["enable", "disable"]},
1044                                "groups": {"required": False, "type": "list",
1045                                           "options": {
1046                                               "name": {"required": True, "type": "str"}
1047                                           }},
1048                                "health_check": {"required": False, "type": "str"},
1049                                "hold_down_time": {"required": False, "type": "int"},
1050                                "id": {"required": True, "type": "int"},
1051                                "input_device": {"required": False, "type": "list",
1052                                                 "options": {
1053                                                     "name": {"required": True, "type": "str"}
1054                                                 }},
1055                                "internet_service": {"required": False, "type": "str",
1056                                                     "choices": ["enable", "disable"]},
1057                                "internet_service_ctrl": {"required": False, "type": "list",
1058                                                          "options": {
1059                                                              "id": {"required": True, "type": "int"}
1060                                                          }},
1061                                "internet_service_ctrl_group": {"required": False, "type": "list",
1062                                                                "options": {
1063                                                                    "name": {"required": True, "type": "str"}
1064                                                                }},
1065                                "internet_service_custom": {"required": False, "type": "list",
1066                                                            "options": {
1067                                                                "name": {"required": True, "type": "str"}
1068                                                            }},
1069                                "internet_service_custom_group": {"required": False, "type": "list",
1070                                                                  "options": {
1071                                                                      "name": {"required": True, "type": "str"}
1072                                                                  }},
1073                                "internet_service_group": {"required": False, "type": "list",
1074                                                           "options": {
1075                                                               "name": {"required": True, "type": "str"}
1076                                                           }},
1077                                "internet_service_id": {"required": False, "type": "list",
1078                                                        "options": {
1079                                                            "id": {"required": True, "type": "int"}
1080                                                        }},
1081                                "jitter_weight": {"required": False, "type": "int"},
1082                                "latency_weight": {"required": False, "type": "int"},
1083                                "link_cost_factor": {"required": False, "type": "str",
1084                                                     "choices": ["latency", "jitter", "packet-loss",
1085                                                                 "inbandwidth", "outbandwidth", "bibandwidth",
1086                                                                 "custom-profile-1"]},
1087                                "link_cost_threshold": {"required": False, "type": "int"},
1088                                "member": {"required": False, "type": "int"},
1089                                "mode": {"required": False, "type": "str",
1090                                         "choices": ["auto", "manual", "priority",
1091                                                     "sla"]},
1092                                "name": {"required": False, "type": "str"},
1093                                "packet_loss_weight": {"required": False, "type": "int"},
1094                                "priority_members": {"required": False, "type": "list",
1095                                                     "options": {
1096                                                         "seq_num": {"required": False, "type": "int"}
1097                                                     }},
1098                                "protocol": {"required": False, "type": "int"},
1099                                "quality_link": {"required": False, "type": "int"},
1100                                "route_tag": {"required": False, "type": "int"},
1101                                "sla": {"required": False, "type": "list",
1102                                        "options": {
1103                                            "health_check": {"required": False, "type": "str"},
1104                                            "id": {"required": False, "type": "int"}
1105                                        }},
1106                                "src": {"required": False, "type": "list",
1107                                        "options": {
1108                                            "name": {"required": True, "type": "str"}
1109                                        }},
1110                                "src_negate": {"required": False, "type": "str",
1111                                               "choices": ["enable", "disable"]},
1112                                "src6": {"required": False, "type": "list",
1113                                         "options": {
1114                                             "name": {"required": True, "type": "str"}
1115                                         }},
1116                                "start_port": {"required": False, "type": "int"},
1117                                "status": {"required": False, "type": "str",
1118                                           "choices": ["enable", "disable"]},
1119                                "tos": {"required": False, "type": "str"},
1120                                "tos_mask": {"required": False, "type": "str"},
1121                                "users": {"required": False, "type": "list",
1122                                          "options": {
1123                                              "name": {"required": True, "type": "str"}
1124                                          }}
1125                            }},
1126                "status": {"required": False, "type": "str",
1127                           "choices": ["disable", "enable"]}
1128
1129            }
1130        }
1131    }
1132
1133    module = AnsibleModule(argument_spec=fields,
1134                           supports_check_mode=False)
1135
1136    # legacy_mode refers to using fortiosapi instead of HTTPAPI
1137    legacy_mode = 'host' in module.params and module.params['host'] is not None and \
1138                  'username' in module.params and module.params['username'] is not None and \
1139                  'password' in module.params and module.params['password'] is not None
1140
1141    if not legacy_mode:
1142        if module._socket_path:
1143            connection = Connection(module._socket_path)
1144            fos = FortiOSHandler(connection)
1145
1146            is_error, has_changed, result = fortios_system(module.params, fos)
1147        else:
1148            module.fail_json(**FAIL_SOCKET_MSG)
1149    else:
1150        try:
1151            from fortiosapi import FortiOSAPI
1152        except ImportError:
1153            module.fail_json(msg="fortiosapi module is required")
1154
1155        fos = FortiOSAPI()
1156
1157        login(module.params, fos)
1158        is_error, has_changed, result = fortios_system(module.params, fos)
1159        fos.logout()
1160
1161    if not is_error:
1162        module.exit_json(changed=has_changed, meta=result)
1163    else:
1164        module.fail_json(msg="Error in repo", meta=result)
1165
1166
1167if __name__ == '__main__':
1168    main()
1169