FortiOS modules for 2.9 - 11 (#61387)

pull/61454/head
Miguel Angel Muñoz González 5 years ago committed by Nilashish Chakraborty
parent f5d829392a
commit da762018e8

@ -26,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_web_proxy_explicit
short_description: Configure explicit Web proxy settings in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by allowing the
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify web_proxy feature and explicit category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -41,195 +41,242 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
web_proxy_explicit:
description:
- Configure explicit Web proxy settings.
default: null
type: dict
suboptions:
ftp-incoming-port:
ftp_incoming_port:
description:
- Accept incoming FTP-over-HTTP requests on one or more ports (0 - 65535, default = 0; use the same as HTTP).
ftp-over-http:
- Accept incoming FTP-over-HTTP requests on one or more ports (0 - 65535).
type: str
ftp_over_http:
description:
- Enable to proxy FTP-over-HTTP sessions sent from a web browser.
type: str
choices:
- enable
- disable
http-incoming-port:
http_incoming_port:
description:
- Accept incoming HTTP requests on one or more ports (0 - 65535, default = 8080).
https-incoming-port:
- Accept incoming HTTP requests on one or more ports (0 - 65535).
type: str
https_incoming_port:
description:
- Accept incoming HTTPS requests on one or more ports (0 - 65535, default = 0, use the same as HTTP).
https-replacement-message:
- Accept incoming HTTPS requests on one or more ports (0 - 65535).
type: str
https_replacement_message:
description:
- Enable/disable sending the client a replacement message for HTTPS requests.
type: str
choices:
- enable
- disable
incoming-ip:
incoming_ip:
description:
- Restrict the explicit HTTP proxy to only accept sessions from this IP address. An interface must have this IP address.
incoming-ip6:
type: str
incoming_ip6:
description:
- Restrict the explicit web proxy to only accept sessions from this IPv6 address. An interface must have this IPv6 address.
ipv6-status:
type: str
ipv6_status:
description:
- Enable/disable allowing an IPv6 web proxy destination in policies and all IPv6 related entries in this command.
type: str
choices:
- enable
- disable
message-upon-server-error:
message_upon_server_error:
description:
- Enable/disable displaying a replacement message when a server error is detected.
type: str
choices:
- enable
- disable
outgoing-ip:
outgoing_ip:
description:
- Outgoing HTTP requests will have this IP address as their source address. An interface must have this IP address.
outgoing-ip6:
type: str
outgoing_ip6:
description:
- Outgoing HTTP requests will leave this IPv6. Multiple interfaces can be specified. Interfaces must have these IPv6 addresses.
pac-file-data:
type: str
pac_file_data:
description:
- PAC file contents enclosed in quotes (maximum of 256K bytes).
pac-file-name:
type: str
pac_file_name:
description:
- Pac file name.
pac-file-server-port:
type: str
pac_file_server_port:
description:
- Port number that PAC traffic from client web browsers uses to connect to the explicit web proxy (0 - 65535, default = 0; use the same as
HTTP).
pac-file-server-status:
- Port number that PAC traffic from client web browsers uses to connect to the explicit web proxy (0 - 65535).
type: str
pac_file_server_status:
description:
- Enable/disable Proxy Auto-Configuration (PAC) for users of this explicit proxy profile.
type: str
choices:
- enable
- disable
pac-file-url:
pac_file_url:
description:
- PAC file access URL.
pac-policy:
type: str
pac_policy:
description:
- PAC policies.
type: list
suboptions:
comments:
description:
- Optional comments.
type: str
dstaddr:
description:
- Destination address objects.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address.name firewall.addrgrp.name.
required: true
pac-file-data:
type: str
pac_file_data:
description:
- PAC file contents enclosed in quotes (maximum of 256K bytes).
pac-file-name:
type: str
pac_file_name:
description:
- Pac file name.
type: str
policyid:
description:
- Policy ID.
required: true
type: int
srcaddr:
description:
- Source address objects.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address.name firewall.addrgrp.name firewall.proxy-address.name firewall.proxy-addrgrp.name.
required: true
type: str
srcaddr6:
description:
- Source address6 objects.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address6.name firewall.addrgrp6.name.
required: true
type: str
status:
description:
- Enable/disable policy.
type: str
choices:
- enable
- disable
pref-dns-result:
pref_dns_result:
description:
- Prefer resolving addresses using the configured IPv4 or IPv6 DNS server (default = ipv4).
- Prefer resolving addresses using the configured IPv4 or IPv6 DNS server .
type: str
choices:
- ipv4
- ipv6
realm:
description:
- Authentication realm used to identify the explicit web proxy (maximum of 63 characters).
sec-default-action:
type: str
sec_default_action:
description:
- Accept or deny explicit web proxy sessions when no web proxy firewall policy exists.
type: str
choices:
- accept
- deny
socks:
description:
- Enable/disable the SOCKS proxy.
type: str
choices:
- enable
- disable
socks-incoming-port:
socks_incoming_port:
description:
- Accept incoming SOCKS proxy requests on one or more ports (0 - 65535, default = 0; use the same as HTTP).
ssl-algorithm:
- Accept incoming SOCKS proxy requests on one or more ports (0 - 65535).
type: str
ssl_algorithm:
description:
- "Relative strength of encryption algorithms accepted in HTTPS deep scan: high, medium, or low."
type: str
choices:
- low
status:
description:
- Enable/disable the explicit Web proxy for HTTP and HTTPS session.
type: str
choices:
- enable
- disable
strict-guest:
strict_guest:
description:
- Enable/disable strict guest user checking by the explicit web proxy.
type: str
choices:
- enable
- disable
trace-auth-no-rsp:
trace_auth_no_rsp:
description:
- Enable/disable logging timed-out authentication requests.
type: str
choices:
- enable
- disable
unknown-http-version:
unknown_http_version:
description:
- Either reject unknown HTTP traffic as malformed or handle unknown HTTP traffic as best as the proxy server can.
type: str
choices:
- reject
- best-effort
@ -242,6 +289,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure explicit Web proxy settings.
fortios_web_proxy_explicit:
@ -251,30 +299,30 @@ EXAMPLES = '''
vdom: "{{ vdom }}"
https: "False"
web_proxy_explicit:
ftp-incoming-port: "<your_own_value>"
ftp-over-http: "enable"
http-incoming-port: "<your_own_value>"
https-incoming-port: "<your_own_value>"
https-replacement-message: "enable"
incoming-ip: "<your_own_value>"
incoming-ip6: "<your_own_value>"
ipv6-status: "enable"
message-upon-server-error: "enable"
outgoing-ip: "<your_own_value>"
outgoing-ip6: "<your_own_value>"
pac-file-data: "<your_own_value>"
pac-file-name: "<your_own_value>"
pac-file-server-port: "<your_own_value>"
pac-file-server-status: "enable"
pac-file-url: "<your_own_value>"
pac-policy:
ftp_incoming_port: "<your_own_value>"
ftp_over_http: "enable"
http_incoming_port: "<your_own_value>"
https_incoming_port: "<your_own_value>"
https_replacement_message: "enable"
incoming_ip: "<your_own_value>"
incoming_ip6: "<your_own_value>"
ipv6_status: "enable"
message_upon_server_error: "enable"
outgoing_ip: "<your_own_value>"
outgoing_ip6: "<your_own_value>"
pac_file_data: "<your_own_value>"
pac_file_name: "<your_own_value>"
pac_file_server_port: "<your_own_value>"
pac_file_server_status: "enable"
pac_file_url: "<your_own_value>"
pac_policy:
-
comments: "<your_own_value>"
dstaddr:
-
name: "default_name_22 (source firewall.address.name firewall.addrgrp.name)"
pac-file-data: "<your_own_value>"
pac-file-name: "<your_own_value>"
pac_file_data: "<your_own_value>"
pac_file_name: "<your_own_value>"
policyid: "25"
srcaddr:
-
@ -283,16 +331,16 @@ EXAMPLES = '''
-
name: "default_name_29 (source firewall.address6.name firewall.addrgrp6.name)"
status: "enable"
pref-dns-result: "ipv4"
pref_dns_result: "ipv4"
realm: "<your_own_value>"
sec-default-action: "accept"
sec_default_action: "accept"
socks: "enable"
socks-incoming-port: "<your_own_value>"
ssl-algorithm: "low"
socks_incoming_port: "<your_own_value>"
ssl_algorithm: "low"
status: "enable"
strict-guest: "enable"
trace-auth-no-rsp: "enable"
unknown-http-version: "reject"
strict_guest: "enable"
trace_auth_no_rsp: "enable"
unknown_http_version: "reject"
'''
RETURN = '''
@ -355,12 +403,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -368,19 +420,19 @@ def login(data, fos):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_web_proxy_explicit_data(json):
option_list = ['ftp-incoming-port', 'ftp-over-http', 'http-incoming-port',
'https-incoming-port', 'https-replacement-message', 'incoming-ip',
'incoming-ip6', 'ipv6-status', 'message-upon-server-error',
'outgoing-ip', 'outgoing-ip6', 'pac-file-data',
'pac-file-name', 'pac-file-server-port', 'pac-file-server-status',
'pac-file-url', 'pac-policy', 'pref-dns-result',
'realm', 'sec-default-action', 'socks',
'socks-incoming-port', 'ssl-algorithm', 'status',
'strict-guest', 'trace-auth-no-rsp', 'unknown-http-version']
option_list = ['ftp_incoming_port', 'ftp_over_http', 'http_incoming_port',
'https_incoming_port', 'https_replacement_message', 'incoming_ip',
'incoming_ip6', 'ipv6_status', 'message_upon_server_error',
'outgoing_ip', 'outgoing_ip6', 'pac_file_data',
'pac_file_name', 'pac_file_server_port', 'pac_file_server_status',
'pac_file_url', 'pac_policy', 'pref_dns_result',
'realm', 'sec_default_action', 'socks',
'socks_incoming_port', 'ssl_algorithm', 'status',
'strict_guest', 'trace_auth_no_rsp', 'unknown_http_version']
dictionary = {}
for attribute in option_list:
@ -390,10 +442,23 @@ def filter_web_proxy_explicit_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def web_proxy_explicit(data, fos):
vdom = data['vdom']
web_proxy_explicit_data = data['web_proxy_explicit']
filtered_data = filter_web_proxy_explicit_data(web_proxy_explicit_data)
filtered_data = underscore_to_hyphen(filter_web_proxy_explicit_data(web_proxy_explicit_data))
return fos.set('web-proxy',
'explicit',
@ -401,56 +466,62 @@ def web_proxy_explicit(data, fos):
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_web_proxy(data, fos):
login(data, fos)
if data['web_proxy_explicit']:
resp = web_proxy_explicit(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"web_proxy_explicit": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"ftp-incoming-port": {"required": False, "type": "str"},
"ftp-over-http": {"required": False, "type": "str",
"ftp_incoming_port": {"required": False, "type": "str"},
"ftp_over_http": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"http-incoming-port": {"required": False, "type": "str"},
"https-incoming-port": {"required": False, "type": "str"},
"https-replacement-message": {"required": False, "type": "str",
"http_incoming_port": {"required": False, "type": "str"},
"https_incoming_port": {"required": False, "type": "str"},
"https_replacement_message": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"incoming-ip": {"required": False, "type": "str"},
"incoming-ip6": {"required": False, "type": "str"},
"ipv6-status": {"required": False, "type": "str",
"incoming_ip": {"required": False, "type": "str"},
"incoming_ip6": {"required": False, "type": "str"},
"ipv6_status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"message-upon-server-error": {"required": False, "type": "str",
"message_upon_server_error": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"outgoing-ip": {"required": False, "type": "str"},
"outgoing-ip6": {"required": False, "type": "str"},
"pac-file-data": {"required": False, "type": "str"},
"pac-file-name": {"required": False, "type": "str"},
"pac-file-server-port": {"required": False, "type": "str"},
"pac-file-server-status": {"required": False, "type": "str",
"outgoing_ip": {"required": False, "type": "str"},
"outgoing_ip6": {"required": False, "type": "str"},
"pac_file_data": {"required": False, "type": "str"},
"pac_file_name": {"required": False, "type": "str"},
"pac_file_server_port": {"required": False, "type": "str"},
"pac_file_server_status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"pac-file-url": {"required": False, "type": "str"},
"pac-policy": {"required": False, "type": "list",
"pac_file_url": {"required": False, "type": "str"},
"pac_policy": {"required": False, "type": "list",
"options": {
"comments": {"required": False, "type": "str"},
"dstaddr": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"pac-file-data": {"required": False, "type": "str"},
"pac-file-name": {"required": False, "type": "str"},
"pac_file_data": {"required": False, "type": "str"},
"pac_file_name": {"required": False, "type": "str"},
"policyid": {"required": True, "type": "int"},
"srcaddr": {"required": False, "type": "list",
"options": {
@ -463,23 +534,23 @@ def main():
"status": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}},
"pref-dns-result": {"required": False, "type": "str",
"pref_dns_result": {"required": False, "type": "str",
"choices": ["ipv4", "ipv6"]},
"realm": {"required": False, "type": "str"},
"sec-default-action": {"required": False, "type": "str",
"sec_default_action": {"required": False, "type": "str",
"choices": ["accept", "deny"]},
"socks": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"socks-incoming-port": {"required": False, "type": "str"},
"ssl-algorithm": {"required": False, "type": "str",
"socks_incoming_port": {"required": False, "type": "str"},
"ssl_algorithm": {"required": False, "type": "str",
"choices": ["low"]},
"status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"strict-guest": {"required": False, "type": "str",
"strict_guest": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"trace-auth-no-rsp": {"required": False, "type": "str",
"trace_auth_no_rsp": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"unknown-http-version": {"required": False, "type": "str",
"unknown_http_version": {"required": False, "type": "str",
"choices": ["reject", "best-effort"]}
}
@ -488,14 +559,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_web_proxy(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_web_proxy(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_web_proxy(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -26,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_web_proxy_global
short_description: Configure Web proxy global settings in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by allowing the
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify web_proxy feature and global category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -41,113 +41,140 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
web_proxy_global:
description:
- Configure Web proxy global settings.
default: null
type: dict
suboptions:
fast-policy-match:
fast_policy_match:
description:
- Enable/disable fast matching algorithm for explicit and transparent proxy policy.
type: str
choices:
- enable
- disable
forward-proxy-auth:
forward_proxy_auth:
description:
- Enable/disable forwarding proxy authentication headers.
type: str
choices:
- enable
- disable
forward-server-affinity-timeout:
forward_server_affinity_timeout:
description:
- Period of time before the source IP's traffic is no longer assigned to the forwarding server (6 - 60 min, default = 30).
learn-client-ip:
- Period of time before the source IP's traffic is no longer assigned to the forwarding server (6 - 60 min).
type: int
learn_client_ip:
description:
- Enable/disable learning the client's IP address from headers.
type: str
choices:
- enable
- disable
learn-client-ip-from-header:
learn_client_ip_from_header:
description:
- Learn client IP address from the specified headers.
type: str
choices:
- true-client-ip
- x-real-ip
- x-forwarded-for
learn-client-ip-srcaddr:
learn_client_ip_srcaddr:
description:
- Source address name (srcaddr or srcaddr6 must be set).
type: list
suboptions:
name:
description:
- Address name. Source firewall.address.name firewall.addrgrp.name.
required: true
learn-client-ip-srcaddr6:
type: str
learn_client_ip_srcaddr6:
description:
- IPv6 Source address name (srcaddr or srcaddr6 must be set).
type: list
suboptions:
name:
description:
- Address name. Source firewall.address6.name firewall.addrgrp6.name.
required: true
max-message-length:
type: str
max_message_length:
description:
- Maximum length of HTTP message, not including body (16 - 256 Kbytes, default = 32).
max-request-length:
- Maximum length of HTTP message, not including body (16 - 256 Kbytes).
type: int
max_request_length:
description:
- Maximum length of HTTP request line (2 - 64 Kbytes, default = 4).
max-waf-body-cache-length:
- Maximum length of HTTP request line (2 - 64 Kbytes).
type: int
max_waf_body_cache_length:
description:
- Maximum length of HTTP messages processed by Web Application Firewall (WAF) (10 - 1024 Kbytes, default = 32).
proxy-fqdn:
- Maximum length of HTTP messages processed by Web Application Firewall (WAF) (10 - 1024 Kbytes).
type: int
proxy_fqdn:
description:
- Fully Qualified Domain Name (FQDN) that clients connect to (default = default.fqdn) to connect to the explicit web proxy.
strict-web-check:
- Fully Qualified Domain Name (FQDN) that clients connect to to connect to the explicit web proxy.
type: str
strict_web_check:
description:
- Enable/disable strict web checking to block web sites that send incorrect headers that don't conform to HTTP 1.1.
type: str
choices:
- enable
- disable
tunnel-non-http:
tunnel_non_http:
description:
- Enable/disable allowing non-HTTP traffic. Allowed non-HTTP traffic is tunneled.
type: str
choices:
- enable
- disable
unknown-http-version:
unknown_http_version:
description:
- "Action to take when an unknown version of HTTP is encountered: reject, allow (tunnel), or proceed with best-effort."
type: str
choices:
- reject
- tunnel
- best-effort
webproxy-profile:
webproxy_profile:
description:
- Name of the web proxy profile to apply when explicit proxy traffic is allowed by default and traffic is accepted that does not match an
explicit proxy policy. Source web-proxy.profile.name.
type: str
'''
EXAMPLES = '''
@ -157,6 +184,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure Web proxy global settings.
fortios_web_proxy_global:
@ -166,25 +194,25 @@ EXAMPLES = '''
vdom: "{{ vdom }}"
https: "False"
web_proxy_global:
fast-policy-match: "enable"
forward-proxy-auth: "enable"
forward-server-affinity-timeout: "5"
learn-client-ip: "enable"
learn-client-ip-from-header: "true-client-ip"
learn-client-ip-srcaddr:
fast_policy_match: "enable"
forward_proxy_auth: "enable"
forward_server_affinity_timeout: "5"
learn_client_ip: "enable"
learn_client_ip_from_header: "true-client-ip"
learn_client_ip_srcaddr:
-
name: "default_name_9 (source firewall.address.name firewall.addrgrp.name)"
learn-client-ip-srcaddr6:
learn_client_ip_srcaddr6:
-
name: "default_name_11 (source firewall.address6.name firewall.addrgrp6.name)"
max-message-length: "12"
max-request-length: "13"
max-waf-body-cache-length: "14"
proxy-fqdn: "<your_own_value>"
strict-web-check: "enable"
tunnel-non-http: "enable"
unknown-http-version: "reject"
webproxy-profile: "<your_own_value> (source web-proxy.profile.name)"
max_message_length: "12"
max_request_length: "13"
max_waf_body_cache_length: "14"
proxy_fqdn: "<your_own_value>"
strict_web_check: "enable"
tunnel_non_http: "enable"
unknown_http_version: "reject"
webproxy_profile: "<your_own_value> (source web-proxy.profile.name)"
'''
RETURN = '''
@ -247,12 +275,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -260,15 +292,15 @@ def login(data, fos):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_web_proxy_global_data(json):
option_list = ['fast-policy-match', 'forward-proxy-auth', 'forward-server-affinity-timeout',
'learn-client-ip', 'learn-client-ip-from-header', 'learn-client-ip-srcaddr',
'learn-client-ip-srcaddr6', 'max-message-length', 'max-request-length',
'max-waf-body-cache-length', 'proxy-fqdn', 'strict-web-check',
'tunnel-non-http', 'unknown-http-version', 'webproxy-profile']
option_list = ['fast_policy_match', 'forward_proxy_auth', 'forward_server_affinity_timeout',
'learn_client_ip', 'learn_client_ip_from_header', 'learn_client_ip_srcaddr',
'learn_client_ip_srcaddr6', 'max_message_length', 'max_request_length',
'max_waf_body_cache_length', 'proxy_fqdn', 'strict_web_check',
'tunnel_non_http', 'unknown_http_version', 'webproxy_profile']
dictionary = {}
for attribute in option_list:
@ -278,10 +310,23 @@ def filter_web_proxy_global_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def web_proxy_global(data, fos):
vdom = data['vdom']
web_proxy_global_data = data['web_proxy_global']
filtered_data = filter_web_proxy_global_data(web_proxy_global_data)
filtered_data = underscore_to_hyphen(filter_web_proxy_global_data(web_proxy_global_data))
return fos.set('web-proxy',
'global',
@ -289,54 +334,60 @@ def web_proxy_global(data, fos):
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_web_proxy(data, fos):
login(data, fos)
if data['web_proxy_global']:
resp = web_proxy_global(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"web_proxy_global": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"fast-policy-match": {"required": False, "type": "str",
"fast_policy_match": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"forward-proxy-auth": {"required": False, "type": "str",
"forward_proxy_auth": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"forward-server-affinity-timeout": {"required": False, "type": "int"},
"learn-client-ip": {"required": False, "type": "str",
"forward_server_affinity_timeout": {"required": False, "type": "int"},
"learn_client_ip": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"learn-client-ip-from-header": {"required": False, "type": "str",
"learn_client_ip_from_header": {"required": False, "type": "str",
"choices": ["true-client-ip", "x-real-ip", "x-forwarded-for"]},
"learn-client-ip-srcaddr": {"required": False, "type": "list",
"learn_client_ip_srcaddr": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"learn-client-ip-srcaddr6": {"required": False, "type": "list",
"learn_client_ip_srcaddr6": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"max-message-length": {"required": False, "type": "int"},
"max-request-length": {"required": False, "type": "int"},
"max-waf-body-cache-length": {"required": False, "type": "int"},
"proxy-fqdn": {"required": False, "type": "str"},
"strict-web-check": {"required": False, "type": "str",
"max_message_length": {"required": False, "type": "int"},
"max_request_length": {"required": False, "type": "int"},
"max_waf_body_cache_length": {"required": False, "type": "int"},
"proxy_fqdn": {"required": False, "type": "str"},
"strict_web_check": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"tunnel-non-http": {"required": False, "type": "str",
"tunnel_non_http": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"unknown-http-version": {"required": False, "type": "str",
"unknown_http_version": {"required": False, "type": "str",
"choices": ["reject", "tunnel", "best-effort"]},
"webproxy-profile": {"required": False, "type": "str"}
"webproxy_profile": {"required": False, "type": "str"}
}
}
@ -344,14 +395,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_web_proxy(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_web_proxy(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_web_proxy(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -26,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_web_proxy_profile
short_description: Configure web proxy profiles in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by allowing the
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify web_proxy feature and profile category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -41,85 +41,105 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
required: true
choices:
- present
- absent
version_added: 2.9
web_proxy_profile:
description:
- Configure web proxy profiles.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
header-client-ip:
header_client_ip:
description:
- "Action to take on the HTTP client-IP header in forwarded requests: forwards (pass), adds, or removes the HTTP header."
type: str
choices:
- pass
- add
- remove
header-front-end-https:
header_front_end_https:
description:
- "Action to take on the HTTP front-end-HTTPS header in forwarded requests: forwards (pass), adds, or removes the HTTP header."
type: str
choices:
- pass
- add
- remove
header-via-request:
header_via_request:
description:
- "Action to take on the HTTP via header in forwarded requests: forwards (pass), adds, or removes the HTTP header."
type: str
choices:
- pass
- add
- remove
header-via-response:
header_via_response:
description:
- "Action to take on the HTTP via header in forwarded responses: forwards (pass), adds, or removes the HTTP header."
type: str
choices:
- pass
- add
- remove
header-x-authenticated-groups:
header_x_authenticated_groups:
description:
- "Action to take on the HTTP x-authenticated-groups header in forwarded requests: forwards (pass), adds, or removes the HTTP header."
type: str
choices:
- pass
- add
- remove
header-x-authenticated-user:
header_x_authenticated_user:
description:
- "Action to take on the HTTP x-authenticated-user header in forwarded requests: forwards (pass), adds, or removes the HTTP header."
type: str
choices:
- pass
- add
- remove
header-x-forwarded-for:
header_x_forwarded_for:
description:
- "Action to take on the HTTP x-forwarded-for header in forwarded requests: forwards (pass), adds, or removes the HTTP header."
type: str
choices:
- pass
- add
@ -127,10 +147,12 @@ options:
headers:
description:
- Configure HTTP forwarded requests headers.
type: list
suboptions:
action:
description:
- Action when HTTP the header forwarded.
type: str
choices:
- add-to-request
- add-to-response
@ -139,16 +161,20 @@ options:
content:
description:
- HTTP header's content.
type: str
id:
description:
- HTTP forwarded header id.
required: true
type: int
name:
description:
- HTTP forwarded header name.
log-header-change:
type: str
log_header_change:
description:
- Enable/disable logging HTTP header changes.
type: str
choices:
- enable
- disable
@ -156,9 +182,11 @@ options:
description:
- Profile name.
required: true
strip-encoding:
type: str
strip_encoding:
description:
- Enable/disable stripping unsupported encoding from the request header.
type: str
choices:
- enable
- disable
@ -171,6 +199,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure web proxy profiles.
fortios_web_proxy_profile:
@ -179,24 +208,24 @@ EXAMPLES = '''
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
web_proxy_profile:
state: "present"
header-client-ip: "pass"
header-front-end-https: "pass"
header-via-request: "pass"
header-via-response: "pass"
header-x-authenticated-groups: "pass"
header-x-authenticated-user: "pass"
header-x-forwarded-for: "pass"
header_client_ip: "pass"
header_front_end_https: "pass"
header_via_request: "pass"
header_via_response: "pass"
header_x_authenticated_groups: "pass"
header_x_authenticated_user: "pass"
header_x_forwarded_for: "pass"
headers:
-
action: "add-to-request"
content: "<your_own_value>"
id: "13"
name: "default_name_14"
log-header-change: "enable"
log_header_change: "enable"
name: "default_name_16"
strip-encoding: "enable"
strip_encoding: "enable"
'''
RETURN = '''
@ -259,12 +288,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -272,14 +305,14 @@ def login(data, fos):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_web_proxy_profile_data(json):
option_list = ['header-client-ip', 'header-front-end-https', 'header-via-request',
'header-via-response', 'header-x-authenticated-groups', 'header-x-authenticated-user',
'header-x-forwarded-for', 'headers', 'log-header-change',
'name', 'strip-encoding']
option_list = ['header_client_ip', 'header_front_end_https', 'header_via_request',
'header_via_response', 'header_x_authenticated_groups', 'header_x_authenticated_user',
'header_x_forwarded_for', 'headers', 'log_header_change',
'name', 'strip_encoding']
dictionary = {}
for attribute in option_list:
@ -289,59 +322,79 @@ def filter_web_proxy_profile_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def web_proxy_profile(data, fos):
vdom = data['vdom']
state = data['state']
web_proxy_profile_data = data['web_proxy_profile']
filtered_data = filter_web_proxy_profile_data(web_proxy_profile_data)
filtered_data = underscore_to_hyphen(filter_web_proxy_profile_data(web_proxy_profile_data))
if web_proxy_profile_data['state'] == "present":
if state == "present":
return fos.set('web-proxy',
'profile',
data=filtered_data,
vdom=vdom)
elif web_proxy_profile_data['state'] == "absent":
elif state == "absent":
return fos.delete('web-proxy',
'profile',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_web_proxy(data, fos):
login(data, fos)
if data['web_proxy_profile']:
resp = web_proxy_profile(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"web_proxy_profile": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"header-client-ip": {"required": False, "type": "str",
"header_client_ip": {"required": False, "type": "str",
"choices": ["pass", "add", "remove"]},
"header-front-end-https": {"required": False, "type": "str",
"header_front_end_https": {"required": False, "type": "str",
"choices": ["pass", "add", "remove"]},
"header-via-request": {"required": False, "type": "str",
"header_via_request": {"required": False, "type": "str",
"choices": ["pass", "add", "remove"]},
"header-via-response": {"required": False, "type": "str",
"header_via_response": {"required": False, "type": "str",
"choices": ["pass", "add", "remove"]},
"header-x-authenticated-groups": {"required": False, "type": "str",
"header_x_authenticated_groups": {"required": False, "type": "str",
"choices": ["pass", "add", "remove"]},
"header-x-authenticated-user": {"required": False, "type": "str",
"header_x_authenticated_user": {"required": False, "type": "str",
"choices": ["pass", "add", "remove"]},
"header-x-forwarded-for": {"required": False, "type": "str",
"header_x_forwarded_for": {"required": False, "type": "str",
"choices": ["pass", "add", "remove"]},
"headers": {"required": False, "type": "list",
"options": {
@ -352,10 +405,10 @@ def main():
"id": {"required": True, "type": "int"},
"name": {"required": False, "type": "str"}
}},
"log-header-change": {"required": False, "type": "str",
"log_header_change": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"name": {"required": True, "type": "str"},
"strip-encoding": {"required": False, "type": "str",
"strip_encoding": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
@ -364,14 +417,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_web_proxy(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_web_proxy(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_web_proxy(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -1,6 +1,6 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2018 Fortinet, Inc.
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -27,12 +24,12 @@ ANSIBLE_METADATA = {'status': ['preview'],
DOCUMENTATION = '''
---
module: fortios_webfilter_fortiguard
short_description: Configure FortiGuard Web Filter service.
short_description: Configure FortiGuard Web Filter service in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure webfilter feature and fortiguard category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify webfilter feature and fortiguard category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -44,79 +41,100 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: false
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
webfilter_fortiguard:
description:
- Configure FortiGuard Web Filter service.
default: null
type: dict
suboptions:
cache-mem-percent:
cache_mem_percent:
description:
- Maximum percentage of available memory allocated to caching (1 - 15%).
cache-mode:
type: int
cache_mode:
description:
- Cache entry expiration mode.
type: str
choices:
- ttl
- db-ver
cache-prefix-match:
cache_prefix_match:
description:
- Enable/disable prefix matching in the cache.
type: str
choices:
- enable
- disable
close-ports:
close_ports:
description:
- Close ports used for HTTP/HTTPS override authentication and disable user overrides.
type: str
choices:
- enable
- disable
ovrd-auth-https:
ovrd_auth_https:
description:
- Enable/disable use of HTTPS for override authentication.
type: str
choices:
- enable
- disable
ovrd-auth-port:
ovrd_auth_port:
description:
- Port to use for FortiGuard Web Filter override authentication.
ovrd-auth-port-http:
type: int
ovrd_auth_port_http:
description:
- Port to use for FortiGuard Web Filter HTTP override authentication
ovrd-auth-port-https:
type: int
ovrd_auth_port_https:
description:
- Port to use for FortiGuard Web Filter HTTPS override authentication.
ovrd-auth-port-warning:
type: int
ovrd_auth_port_warning:
description:
- Port to use for FortiGuard Web Filter Warning override authentication.
request-packet-size-limit:
type: int
request_packet_size_limit:
description:
- Limit size of URL request packets sent to FortiGuard server (0 for default).
warn-auth-https:
type: int
warn_auth_https:
description:
- Enable/disable use of HTTPS for warning and authentication.
type: str
choices:
- enable
- disable
@ -129,25 +147,27 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure FortiGuard Web Filter service.
fortios_webfilter_fortiguard:
host: "{{ host }}"
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
vdom: "{{ vdom }}"
https: "False"
webfilter_fortiguard:
cache-mem-percent: "3"
cache-mode: "ttl"
cache-prefix-match: "enable"
close-ports: "enable"
ovrd-auth-https: "enable"
ovrd-auth-port: "8"
ovrd-auth-port-http: "9"
ovrd-auth-port-https: "10"
ovrd-auth-port-warning: "11"
request-packet-size-limit: "12"
warn-auth-https: "enable"
cache_mem_percent: "3"
cache_mode: "ttl"
cache_prefix_match: "enable"
close_ports: "enable"
ovrd_auth_https: "enable"
ovrd_auth_port: "8"
ovrd_auth_port_http: "9"
ovrd_auth_port_https: "10"
ovrd_auth_port_warning: "11"
request_packet_size_limit: "12"
warn_auth_https: "enable"
'''
RETURN = '''
@ -170,7 +190,7 @@ mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "key1"
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
@ -210,14 +230,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data):
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -225,75 +247,88 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_webfilter_fortiguard_data(json):
option_list = ['cache-mem-percent', 'cache-mode', 'cache-prefix-match',
'close-ports', 'ovrd-auth-https', 'ovrd-auth-port',
'ovrd-auth-port-http', 'ovrd-auth-port-https', 'ovrd-auth-port-warning',
'request-packet-size-limit', 'warn-auth-https']
option_list = ['cache_mem_percent', 'cache_mode', 'cache_prefix_match',
'close_ports', 'ovrd_auth_https', 'ovrd_auth_port',
'ovrd_auth_port_http', 'ovrd_auth_port_https', 'ovrd_auth_port_warning',
'request_packet_size_limit', 'warn_auth_https']
dictionary = {}
for attribute in option_list:
if attribute in json:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def webfilter_fortiguard(data, fos):
vdom = data['vdom']
webfilter_fortiguard_data = data['webfilter_fortiguard']
filtered_data = filter_webfilter_fortiguard_data(webfilter_fortiguard_data)
filtered_data = underscore_to_hyphen(filter_webfilter_fortiguard_data(webfilter_fortiguard_data))
return fos.set('webfilter',
'fortiguard',
data=filtered_data,
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_webfilter(data, fos):
host = data['host']
username = data['username']
password = data['password']
fos.https('off')
fos.login(host, username, password)
methodlist = ['webfilter_fortiguard']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['webfilter_fortiguard']:
resp = webfilter_fortiguard(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": "False"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"webfilter_fortiguard": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"cache-mem-percent": {"required": False, "type": "int"},
"cache-mode": {"required": False, "type": "str",
"cache_mem_percent": {"required": False, "type": "int"},
"cache_mode": {"required": False, "type": "str",
"choices": ["ttl", "db-ver"]},
"cache-prefix-match": {"required": False, "type": "str",
"cache_prefix_match": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"close-ports": {"required": False, "type": "str",
"close_ports": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"ovrd-auth-https": {"required": False, "type": "str",
"ovrd_auth_https": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"ovrd-auth-port": {"required": False, "type": "int"},
"ovrd-auth-port-http": {"required": False, "type": "int"},
"ovrd-auth-port-https": {"required": False, "type": "int"},
"ovrd-auth-port-warning": {"required": False, "type": "int"},
"request-packet-size-limit": {"required": False, "type": "int"},
"warn-auth-https": {"required": False, "type": "str",
"ovrd_auth_port": {"required": False, "type": "int"},
"ovrd_auth_port_http": {"required": False, "type": "int"},
"ovrd_auth_port_https": {"required": False, "type": "int"},
"ovrd_auth_port_warning": {"required": False, "type": "int"},
"request_packet_size_limit": {"required": False, "type": "int"},
"warn_auth_https": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
@ -302,14 +337,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_webfilter(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_webfilter(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_webfilter(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -1,6 +1,6 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2018 Fortinet, Inc.
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -27,12 +24,12 @@ ANSIBLE_METADATA = {'status': ['preview'],
DOCUMENTATION = '''
---
module: fortios_webfilter_ftgd_local_cat
short_description: Configure FortiGuard Web Filter local categories.
short_description: Configure FortiGuard Web Filter local categories in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure webfilter feature and ftgd_local_cat category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify webfilter feature and ftgd_local_cat category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -44,50 +41,66 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: false
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
required: true
choices:
- present
- absent
version_added: 2.9
webfilter_ftgd_local_cat:
description:
- Configure FortiGuard Web Filter local categories.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
desc:
description:
- Local category description.
required: true
type: str
id:
description:
- Local category ID.
type: int
status:
description:
- Enable/disable the local category.
type: str
choices:
- enable
- disable
@ -100,6 +113,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure FortiGuard Web Filter local categories.
fortios_webfilter_ftgd_local_cat:
@ -107,8 +121,9 @@ EXAMPLES = '''
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
webfilter_ftgd_local_cat:
state: "present"
desc: "<your_own_value>"
id: "4"
status: "enable"
@ -134,7 +149,7 @@ mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "key1"
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
@ -174,14 +189,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data):
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -189,7 +206,7 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_webfilter_ftgd_local_cat_data(json):
@ -197,55 +214,72 @@ def filter_webfilter_ftgd_local_cat_data(json):
dictionary = {}
for attribute in option_list:
if attribute in json:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def webfilter_ftgd_local_cat(data, fos):
vdom = data['vdom']
state = data['state']
webfilter_ftgd_local_cat_data = data['webfilter_ftgd_local_cat']
filtered_data = filter_webfilter_ftgd_local_cat_data(
webfilter_ftgd_local_cat_data)
if webfilter_ftgd_local_cat_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_webfilter_ftgd_local_cat_data(webfilter_ftgd_local_cat_data))
if state == "present":
return fos.set('webfilter',
'ftgd-local-cat',
data=filtered_data,
vdom=vdom)
elif webfilter_ftgd_local_cat_data['state'] == "absent":
elif state == "absent":
return fos.delete('webfilter',
'ftgd-local-cat',
mkey=filtered_data['desc'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_webfilter(data, fos):
login(data)
methodlist = ['webfilter_ftgd_local_cat']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['webfilter_ftgd_local_cat']:
resp = webfilter_ftgd_local_cat(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": "False"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"webfilter_ftgd_local_cat": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"desc": {"required": True, "type": "str"},
"id": {"required": False, "type": "int"},
"status": {"required": False, "type": "str",
@ -257,15 +291,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_webfilter(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_webfilter(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_webfilter(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -1,6 +1,6 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2018 Fortinet, Inc.
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -27,12 +24,12 @@ ANSIBLE_METADATA = {'status': ['preview'],
DOCUMENTATION = '''
---
module: fortios_webfilter_ftgd_local_rating
short_description: Configure local FortiGuard Web Filter local ratings.
short_description: Configure local FortiGuard Web Filter local ratings in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure webfilter feature and ftgd_local_rating category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify webfilter feature and ftgd_local_rating category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -44,46 +41,61 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: false
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
required: true
choices:
- present
- absent
version_added: 2.9
webfilter_ftgd_local_rating:
description:
- Configure local FortiGuard Web Filter local ratings.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
rating:
description:
- Local rating.
type: str
status:
description:
- Enable/disable local rating.
type: str
choices:
- enable
- disable
@ -91,6 +103,7 @@ options:
description:
- URL to rate locally.
required: true
type: str
'''
EXAMPLES = '''
@ -100,6 +113,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure local FortiGuard Web Filter local ratings.
fortios_webfilter_ftgd_local_rating:
@ -107,8 +121,9 @@ EXAMPLES = '''
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
webfilter_ftgd_local_rating:
state: "present"
rating: "<your_own_value>"
status: "enable"
url: "myurl.com"
@ -134,7 +149,7 @@ mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "key1"
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
@ -174,14 +189,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data):
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -189,7 +206,7 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_webfilter_ftgd_local_rating_data(json):
@ -197,55 +214,72 @@ def filter_webfilter_ftgd_local_rating_data(json):
dictionary = {}
for attribute in option_list:
if attribute in json:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def webfilter_ftgd_local_rating(data, fos):
vdom = data['vdom']
state = data['state']
webfilter_ftgd_local_rating_data = data['webfilter_ftgd_local_rating']
filtered_data = filter_webfilter_ftgd_local_rating_data(
webfilter_ftgd_local_rating_data)
if webfilter_ftgd_local_rating_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_webfilter_ftgd_local_rating_data(webfilter_ftgd_local_rating_data))
if state == "present":
return fos.set('webfilter',
'ftgd-local-rating',
data=filtered_data,
vdom=vdom)
elif webfilter_ftgd_local_rating_data['state'] == "absent":
elif state == "absent":
return fos.delete('webfilter',
'ftgd-local-rating',
mkey=filtered_data['url'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_webfilter(data, fos):
login(data)
methodlist = ['webfilter_ftgd_local_rating']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['webfilter_ftgd_local_rating']:
resp = webfilter_ftgd_local_rating(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": "False"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"webfilter_ftgd_local_rating": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"rating": {"required": False, "type": "str"},
"status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
@ -257,15 +291,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_webfilter(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_webfilter(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_webfilter(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -1,6 +1,6 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2018 Fortinet, Inc.
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -27,12 +24,12 @@ ANSIBLE_METADATA = {'status': ['preview'],
DOCUMENTATION = '''
---
module: fortios_webfilter_ips_urlfilter_cache_setting
short_description: Configure IPS URL filter cache settings.
short_description: Configure IPS URL filter cache settings in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure webfilter feature and ips_urlfilter_cache_setting category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify webfilter feature and ips_urlfilter_cache_setting category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -44,40 +41,52 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: false
default: true
version_added: 2.9
webfilter_ips_urlfilter_cache_setting:
description:
- Configure IPS URL filter cache settings.
default: null
type: dict
suboptions:
dns-retry-interval:
dns_retry_interval:
description:
- Retry interval. Refresh DNS faster than TTL to capture multiple IPs for hosts. 0 means use DNS server's TTL only.
extended-ttl:
type: int
extended_ttl:
description:
- Extend time to live beyond reported by DNS. 0 means use DNS server's TTL
type: int
'''
EXAMPLES = '''
@ -87,6 +96,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure IPS URL filter cache settings.
fortios_webfilter_ips_urlfilter_cache_setting:
@ -94,9 +104,10 @@ EXAMPLES = '''
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
webfilter_ips_urlfilter_cache_setting:
dns-retry-interval: "3"
extended-ttl: "4"
dns_retry_interval: "3"
extended_ttl: "4"
'''
RETURN = '''
@ -119,7 +130,7 @@ mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "key1"
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
@ -159,14 +170,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
fos = None
def login(data):
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -174,11 +187,11 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_webfilter_ips_urlfilter_cache_setting_data(json):
option_list = ['dns-retry-interval', 'extended-ttl']
option_list = ['dns_retry_interval', 'extended_ttl']
dictionary = {}
for attribute in option_list:
@ -188,42 +201,58 @@ def filter_webfilter_ips_urlfilter_cache_setting_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def webfilter_ips_urlfilter_cache_setting(data, fos):
vdom = data['vdom']
webfilter_ips_urlfilter_cache_setting_data = data['webfilter_ips_urlfilter_cache_setting']
filtered_data = filter_webfilter_ips_urlfilter_cache_setting_data(
webfilter_ips_urlfilter_cache_setting_data)
filtered_data = underscore_to_hyphen(filter_webfilter_ips_urlfilter_cache_setting_data(webfilter_ips_urlfilter_cache_setting_data))
return fos.set('webfilter',
'ips-urlfilter-cache-setting',
data=filtered_data,
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_webfilter(data, fos):
login(data)
methodlist = ['webfilter_ips_urlfilter_cache_setting']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['webfilter_ips_urlfilter_cache_setting']:
resp = webfilter_ips_urlfilter_cache_setting(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": "False"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"webfilter_ips_urlfilter_cache_setting": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"dns-retry-interval": {"required": False, "type": "int"},
"extended-ttl": {"required": False, "type": "int"}
"dns_retry_interval": {"required": False, "type": "int"},
"extended_ttl": {"required": False, "type": "int"}
}
}
@ -231,15 +260,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_webfilter(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_webfilter(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_webfilter(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -1,6 +1,6 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2018 Fortinet, Inc.
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -27,12 +24,12 @@ ANSIBLE_METADATA = {'status': ['preview'],
DOCUMENTATION = '''
---
module: fortios_webfilter_ips_urlfilter_setting
short_description: Configure IPS URL filter settings.
short_description: Configure IPS URL filter settings in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure webfilter feature and ips_urlfilter_setting category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify webfilter feature and ips_urlfilter_setting category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -44,46 +41,60 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: false
default: true
version_added: 2.9
webfilter_ips_urlfilter_setting:
description:
- Configure IPS URL filter settings.
default: null
type: dict
suboptions:
device:
description:
- Interface for this route. Source system.interface.name.
type: str
distance:
description:
- Administrative distance (1 - 255) for this route.
type: int
gateway:
description:
- Gateway IP address for this route.
geo-filter:
type: str
geo_filter:
description:
- Filter based on geographical location. Route will NOT be installed if the resolved IP address belongs to the country in the filter.
type: str
'''
EXAMPLES = '''
@ -93,6 +104,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure IPS URL filter settings.
fortios_webfilter_ips_urlfilter_setting:
@ -100,11 +112,12 @@ EXAMPLES = '''
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
webfilter_ips_urlfilter_setting:
device: "<your_own_value> (source system.interface.name)"
distance: "4"
gateway: "<your_own_value>"
geo-filter: "<your_own_value>"
geo_filter: "<your_own_value>"
'''
RETURN = '''
@ -127,7 +140,7 @@ mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "key1"
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
@ -167,14 +180,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
fos = None
def login(data):
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -182,12 +197,12 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_webfilter_ips_urlfilter_setting_data(json):
option_list = ['device', 'distance', 'gateway',
'geo-filter']
'geo_filter']
dictionary = {}
for attribute in option_list:
@ -197,44 +212,60 @@ def filter_webfilter_ips_urlfilter_setting_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def webfilter_ips_urlfilter_setting(data, fos):
vdom = data['vdom']
webfilter_ips_urlfilter_setting_data = data['webfilter_ips_urlfilter_setting']
filtered_data = filter_webfilter_ips_urlfilter_setting_data(
webfilter_ips_urlfilter_setting_data)
filtered_data = underscore_to_hyphen(filter_webfilter_ips_urlfilter_setting_data(webfilter_ips_urlfilter_setting_data))
return fos.set('webfilter',
'ips-urlfilter-setting',
data=filtered_data,
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_webfilter(data, fos):
login(data)
methodlist = ['webfilter_ips_urlfilter_setting']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['webfilter_ips_urlfilter_setting']:
resp = webfilter_ips_urlfilter_setting(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": "False"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"webfilter_ips_urlfilter_setting": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"device": {"required": False, "type": "str"},
"distance": {"required": False, "type": "int"},
"gateway": {"required": False, "type": "str"},
"geo-filter": {"required": False, "type": "str"}
"geo_filter": {"required": False, "type": "str"}
}
}
@ -242,15 +273,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_webfilter(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_webfilter(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_webfilter(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -1,6 +1,6 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2018 Fortinet, Inc.
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -27,12 +24,12 @@ ANSIBLE_METADATA = {'status': ['preview'],
DOCUMENTATION = '''
---
module: fortios_webfilter_ips_urlfilter_setting6
short_description: Configure IPS URL filter settings for IPv6.
short_description: Configure IPS URL filter settings for IPv6 in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure webfilter feature and ips_urlfilter_setting6 category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify webfilter feature and ips_urlfilter_setting6 category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -44,46 +41,60 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: false
default: true
version_added: 2.9
webfilter_ips_urlfilter_setting6:
description:
- Configure IPS URL filter settings for IPv6.
default: null
type: dict
suboptions:
device:
description:
- Interface for this route. Source system.interface.name.
type: str
distance:
description:
- Administrative distance (1 - 255) for this route.
type: int
gateway6:
description:
- Gateway IPv6 address for this route.
geo-filter:
type: str
geo_filter:
description:
- Filter based on geographical location. Route will NOT be installed if the resolved IPv6 address belongs to the country in the filter.
type: str
'''
EXAMPLES = '''
@ -93,6 +104,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure IPS URL filter settings for IPv6.
fortios_webfilter_ips_urlfilter_setting6:
@ -100,11 +112,12 @@ EXAMPLES = '''
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
webfilter_ips_urlfilter_setting6:
device: "<your_own_value> (source system.interface.name)"
distance: "4"
gateway6: "<your_own_value>"
geo-filter: "<your_own_value>"
geo_filter: "<your_own_value>"
'''
RETURN = '''
@ -127,7 +140,7 @@ mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "key1"
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
@ -167,14 +180,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
fos = None
def login(data):
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -182,12 +197,12 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_webfilter_ips_urlfilter_setting6_data(json):
option_list = ['device', 'distance', 'gateway6',
'geo-filter']
'geo_filter']
dictionary = {}
for attribute in option_list:
@ -197,44 +212,60 @@ def filter_webfilter_ips_urlfilter_setting6_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def webfilter_ips_urlfilter_setting6(data, fos):
vdom = data['vdom']
webfilter_ips_urlfilter_setting6_data = data['webfilter_ips_urlfilter_setting6']
filtered_data = filter_webfilter_ips_urlfilter_setting6_data(
webfilter_ips_urlfilter_setting6_data)
filtered_data = underscore_to_hyphen(filter_webfilter_ips_urlfilter_setting6_data(webfilter_ips_urlfilter_setting6_data))
return fos.set('webfilter',
'ips-urlfilter-setting6',
data=filtered_data,
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_webfilter(data, fos):
login(data)
methodlist = ['webfilter_ips_urlfilter_setting6']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['webfilter_ips_urlfilter_setting6']:
resp = webfilter_ips_urlfilter_setting6(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": "False"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"webfilter_ips_urlfilter_setting6": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"device": {"required": False, "type": "str"},
"distance": {"required": False, "type": "int"},
"gateway6": {"required": False, "type": "str"},
"geo-filter": {"required": False, "type": "str"}
"geo_filter": {"required": False, "type": "str"}
}
}
@ -242,15 +273,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_webfilter(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_webfilter(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_webfilter(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -1,6 +1,6 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2018 Fortinet, Inc.
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -27,12 +24,12 @@ ANSIBLE_METADATA = {'status': ['preview'],
DOCUMENTATION = '''
---
module: fortios_webfilter_override
short_description: Configure FortiGuard Web Filter administrative overrides.
short_description: Configure FortiGuard Web Filter administrative overrides in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure webfilter feature and override category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify webfilter feature and override category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -44,65 +41,86 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: false
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
required: true
choices:
- present
- absent
version_added: 2.9
webfilter_override:
description:
- Configure FortiGuard Web Filter administrative overrides.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
expires:
description:
- "Override expiration date and time, from 5 minutes to 365 from now (format: yyyy/mm/dd hh:mm:ss)."
type: str
id:
description:
- Override rule ID.
required: true
type: int
initiator:
description:
- Initiating user of override (read-only setting).
type: str
ip:
description:
- IPv4 address which the override applies.
type: str
ip6:
description:
- IPv6 address which the override applies.
new-profile:
type: str
new_profile:
description:
- Name of the new web filter profile used by the override. Source webfilter.profile.name.
old-profile:
type: str
old_profile:
description:
- Name of the web filter profile which the override applies. Source webfilter.profile.name.
type: str
scope:
description:
- Override either the specific user, user group, IPv4 address, or IPv6 address.
type: str
choices:
- user
- user-group
@ -111,15 +129,18 @@ options:
status:
description:
- Enable/disable override rule.
type: str
choices:
- enable
- disable
user:
description:
- Name of the user which the override applies.
user-group:
type: str
user_group:
description:
- Specify the user group for which the override applies. Source user.group.name.
type: str
'''
EXAMPLES = '''
@ -129,6 +150,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure FortiGuard Web Filter administrative overrides.
fortios_webfilter_override:
@ -136,19 +158,20 @@ EXAMPLES = '''
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
webfilter_override:
state: "present"
expires: "<your_own_value>"
id: "4"
initiator: "<your_own_value>"
ip: "<your_own_value>"
ip6: "<your_own_value>"
new-profile: "<your_own_value> (source webfilter.profile.name)"
old-profile: "<your_own_value> (source webfilter.profile.name)"
new_profile: "<your_own_value> (source webfilter.profile.name)"
old_profile: "<your_own_value> (source webfilter.profile.name)"
scope: "user"
status: "enable"
user: "<your_own_value>"
user-group: "<your_own_value> (source user.group.name)"
user_group: "<your_own_value> (source user.group.name)"
'''
RETURN = '''
@ -171,7 +194,7 @@ mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "key1"
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
@ -211,14 +234,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data):
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -226,14 +251,14 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_webfilter_override_data(json):
option_list = ['expires', 'id', 'initiator',
'ip', 'ip6', 'new-profile',
'old-profile', 'scope', 'status',
'user', 'user-group']
'ip', 'ip6', 'new_profile',
'old_profile', 'scope', 'status',
'user', 'user_group']
dictionary = {}
for attribute in option_list:
@ -243,62 +268,80 @@ def filter_webfilter_override_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def webfilter_override(data, fos):
vdom = data['vdom']
state = data['state']
webfilter_override_data = data['webfilter_override']
filtered_data = filter_webfilter_override_data(webfilter_override_data)
if webfilter_override_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_webfilter_override_data(webfilter_override_data))
if state == "present":
return fos.set('webfilter',
'override',
data=filtered_data,
vdom=vdom)
elif webfilter_override_data['state'] == "absent":
elif state == "absent":
return fos.delete('webfilter',
'override',
mkey=filtered_data['id'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_webfilter(data, fos):
login(data)
methodlist = ['webfilter_override']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['webfilter_override']:
resp = webfilter_override(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": "False"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"webfilter_override": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"expires": {"required": False, "type": "str"},
"id": {"required": True, "type": "int"},
"initiator": {"required": False, "type": "str"},
"ip": {"required": False, "type": "str"},
"ip6": {"required": False, "type": "str"},
"new-profile": {"required": False, "type": "str"},
"old-profile": {"required": False, "type": "str"},
"new_profile": {"required": False, "type": "str"},
"old_profile": {"required": False, "type": "str"},
"scope": {"required": False, "type": "str",
"choices": ["user", "user-group", "ip",
"ip6"]},
"status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"user": {"required": False, "type": "str"},
"user-group": {"required": False, "type": "str"}
"user_group": {"required": False, "type": "str"}
}
}
@ -306,15 +349,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_webfilter(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_webfilter(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_webfilter(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -1,6 +1,6 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2018 Fortinet, Inc.
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -27,12 +24,12 @@ ANSIBLE_METADATA = {'status': ['preview'],
DOCUMENTATION = '''
---
module: fortios_webfilter_search_engine
short_description: Configure web filter search engines.
short_description: Configure web filter search engines in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure webfilter feature and search_engine category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify webfilter feature and search_engine category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -44,69 +41,89 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: false
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
required: true
choices:
- present
- absent
version_added: 2.9
webfilter_search_engine:
description:
- Configure web filter search engines.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
charset:
description:
- Search engine charset.
type: str
choices:
- utf-8
- gb2312
hostname:
description:
- Hostname (regular expression).
type: str
name:
description:
- Search engine name.
required: true
type: str
query:
description:
- Code used to prefix a query (must end with an equals character).
type: str
safesearch:
description:
- Safe search method. You can disable safe search, add the safe search string to URLs, or insert a safe search header.
type: str
choices:
- disable
- url
- header
safesearch-str:
safesearch_str:
description:
- Safe search parameter used in the URL.
type: str
url:
description:
- URL (regular expression).
type: str
'''
EXAMPLES = '''
@ -116,22 +133,24 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure web filter search engines.
fortios_webfilter_search_engine:
host: "{{ host }}"
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
webfilter_search_engine:
state: "present"
charset: "utf-8"
hostname: "myhostname"
name: "default_name_5"
query: "<your_own_value>"
safesearch: "disable"
safesearch-str: "<your_own_value>"
url: "http://myurl.com"
safesearch_str: "<your_own_value>"
url: "myurl.com"
'''
RETURN = '''
@ -154,7 +173,7 @@ mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "key1"
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
@ -194,14 +213,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data):
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -209,65 +230,82 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_webfilter_search_engine_data(json):
option_list = ['charset', 'hostname', 'name',
'query', 'safesearch', 'safesearch-str',
'query', 'safesearch', 'safesearch_str',
'url']
dictionary = {}
for attribute in option_list:
if attribute in json:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def webfilter_search_engine(data, fos):
vdom = data['vdom']
state = data['state']
webfilter_search_engine_data = data['webfilter_search_engine']
filtered_data = filter_webfilter_search_engine_data(
webfilter_search_engine_data)
if webfilter_search_engine_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_webfilter_search_engine_data(webfilter_search_engine_data))
if state == "present":
return fos.set('webfilter',
'search-engine',
data=filtered_data,
vdom=vdom)
elif webfilter_search_engine_data['state'] == "absent":
elif state == "absent":
return fos.delete('webfilter',
'search-engine',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_webfilter(data, fos):
login(data)
methodlist = ['webfilter_search_engine']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['webfilter_search_engine']:
resp = webfilter_search_engine(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": "False"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"webfilter_search_engine": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"charset": {"required": False, "type": "str",
"choices": ["utf-8", "gb2312"]},
"hostname": {"required": False, "type": "str"},
@ -275,7 +313,7 @@ def main():
"query": {"required": False, "type": "str"},
"safesearch": {"required": False, "type": "str",
"choices": ["disable", "url", "header"]},
"safesearch-str": {"required": False, "type": "str"},
"safesearch_str": {"required": False, "type": "str"},
"url": {"required": False, "type": "str"}
}
@ -284,15 +322,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_webfilter(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_webfilter(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_webfilter(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -1,6 +1,6 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2018 Fortinet, Inc.
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_webfilter_urlfilter
short_description: Configure URL filter lists in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure webfilter feature and urlfilter category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify webfilter feature and urlfilter category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -44,58 +41,75 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: false
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
required: true
choices:
- present
- absent
version_added: 2.9
webfilter_urlfilter:
description:
- Configure URL filter lists.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
comment:
description:
- Optional comments.
type: str
entries:
description:
- URL filter entries.
type: list
suboptions:
action:
description:
- Action to take for URL filter matches.
type: str
choices:
- exempt
- block
- allow
- monitor
dns-address-family:
dns_address_family:
description:
- Resolve IPv4 address, IPv6 address, or both from DNS server.
type: str
choices:
- ipv4
- ipv6
@ -103,6 +117,7 @@ options:
exempt:
description:
- If action is set to exempt, select the security profile operations that exempt URLs skip. Separate multiple options with a space.
type: str
choices:
- av
- web-content
@ -116,18 +131,22 @@ options:
description:
- Id.
required: true
referrer-host:
type: int
referrer_host:
description:
- Referrer host name.
type: str
status:
description:
- Enable/disable this URL filter.
type: str
choices:
- enable
- disable
type:
description:
- Filter type (simple, regex, or wildcard).
type: str
choices:
- simple
- regex
@ -135,25 +154,31 @@ options:
url:
description:
- URL to be filtered.
web-proxy-profile:
type: str
web_proxy_profile:
description:
- Web proxy profile. Source web-proxy.profile.name.
type: str
id:
description:
- ID.
required: true
ip-addr-block:
type: int
ip_addr_block:
description:
- Enable/disable blocking URLs when the hostname appears as an IP address.
type: str
choices:
- enable
- disable
name:
description:
- Name of URL filter list.
one-arm-ips-urlfilter:
type: str
one_arm_ips_urlfilter:
description:
- Enable/disable DNS resolver for one-arm IPS URL filter operation.
type: str
choices:
- enable
- disable
@ -166,6 +191,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure URL filter lists.
fortios_webfilter_urlfilter:
@ -173,24 +199,25 @@ EXAMPLES = '''
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
webfilter_urlfilter:
state: "present"
comment: "Optional comments."
entries:
-
action: "exempt"
dns-address-family: "ipv4"
dns_address_family: "ipv4"
exempt: "av"
id: "8"
referrer-host: "myhostname"
referrer_host: "myhostname"
status: "enable"
type: "simple"
url: "myurl.com"
web-proxy-profile: "<your_own_value> (source web-proxy.profile.name)"
web_proxy_profile: "<your_own_value> (source web-proxy.profile.name)"
id: "14"
ip-addr-block: "enable"
ip_addr_block: "enable"
name: "default_name_16"
one-arm-ips-urlfilter: "enable"
one_arm_ips_urlfilter: "enable"
'''
RETURN = '''
@ -253,14 +280,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data):
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -268,12 +297,12 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_webfilter_urlfilter_data(json):
option_list = ['comment', 'entries', 'id',
'ip-addr-block', 'name', 'one-arm-ips-urlfilter']
'ip_addr_block', 'name', 'one_arm_ips_urlfilter']
dictionary = {}
for attribute in option_list:
@ -283,74 +312,92 @@ def filter_webfilter_urlfilter_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def webfilter_urlfilter(data, fos):
vdom = data['vdom']
state = data['state']
webfilter_urlfilter_data = data['webfilter_urlfilter']
filtered_data = filter_webfilter_urlfilter_data(webfilter_urlfilter_data)
if webfilter_urlfilter_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_webfilter_urlfilter_data(webfilter_urlfilter_data))
if state == "present":
return fos.set('webfilter',
'urlfilter',
data=filtered_data,
vdom=vdom)
elif webfilter_urlfilter_data['state'] == "absent":
elif state == "absent":
return fos.delete('webfilter',
'urlfilter',
mkey=filtered_data['id'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_webfilter(data, fos):
login(data)
methodlist = ['webfilter_urlfilter']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['webfilter_urlfilter']:
resp = webfilter_urlfilter(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": "False"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"webfilter_urlfilter": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"comment": {"required": False, "type": "str"},
"entries": {"required": False, "type": "list",
"options": {
"action": {"required": False, "type": "str",
"choices": ["exempt", "block", "allow",
"monitor"]},
"dns-address-family": {"required": False, "type": "str",
"dns_address_family": {"required": False, "type": "str",
"choices": ["ipv4", "ipv6", "both"]},
"exempt": {"required": False, "type": "str",
"choices": ["av", "web-content", "activex-java-cookie",
"dlp", "fortiguard", "range-block",
"pass", "all"]},
"id": {"required": True, "type": "int"},
"referrer-host": {"required": False, "type": "str"},
"referrer_host": {"required": False, "type": "str"},
"status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"type": {"required": False, "type": "str",
"choices": ["simple", "regex", "wildcard"]},
"url": {"required": False, "type": "str"},
"web-proxy-profile": {"required": False, "type": "str"}
"web_proxy_profile": {"required": False, "type": "str"}
}},
"id": {"required": True, "type": "int"},
"ip-addr-block": {"required": False, "type": "str",
"ip_addr_block": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"name": {"required": False, "type": "str"},
"one-arm-ips-urlfilter": {"required": False, "type": "str",
"one_arm_ips_urlfilter": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
@ -359,15 +406,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_webfilter(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_webfilter(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_webfilter(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -26,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_wireless_controller_global
short_description: Configure wireless controller global settings in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by allowing the
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify wireless_controller feature and global category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -41,49 +41,63 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
wireless_controller_global:
description:
- Configure wireless controller global settings.
default: null
type: dict
suboptions:
ap-log-server:
ap_log_server:
description:
- Enable/disable configuring APs or FortiAPs to send log messages to a syslog server (default = disable).
- Enable/disable configuring APs or FortiAPs to send log messages to a syslog server .
type: str
choices:
- enable
- disable
ap-log-server-ip:
ap_log_server_ip:
description:
- IP address that APs or FortiAPs send log messages to.
ap-log-server-port:
type: str
ap_log_server_port:
description:
- Port that APs or FortiAPs send log messages to.
control-message-offload:
type: int
control_message_offload:
description:
- Configure CAPWAP control message data channel offload.
type: str
choices:
- ebp-frame
- aeroscout-tag
@ -92,54 +106,67 @@ options:
- sta-cap-list
- stats
- aeroscout-mu
data-ethernet-II:
data_ethernet_II:
description:
- Configure the wireless controller to use Ethernet II or 802.3 frames with 802.3 data tunnel mode (default = disable).
- Configure the wireless controller to use Ethernet II or 802.3 frames with 802.3 data tunnel mode .
type: str
choices:
- enable
- disable
discovery-mc-addr:
discovery_mc_addr:
description:
- Multicast IP address for AP discovery (default = 244.0.1.140).
fiapp-eth-type:
- Multicast IP address for AP discovery .
type: str
fiapp_eth_type:
description:
- Ethernet type for Fortinet Inter-Access Point Protocol (IAPP), or IEEE 802.11f, packets (0 - 65535, default = 5252).
image-download:
- Ethernet type for Fortinet Inter-Access Point Protocol (IAPP), or IEEE 802.11f, packets (0 - 65535).
type: int
image_download:
description:
- Enable/disable WTP image download at join time.
type: str
choices:
- enable
- disable
ipsec-base-ip:
ipsec_base_ip:
description:
- Base IP address for IPsec VPN tunnels between the access points and the wireless controller (default = 169.254.0.1).
link-aggregation:
- Base IP address for IPsec VPN tunnels between the access points and the wireless controller .
type: str
link_aggregation:
description:
- Enable/disable calculating the CAPWAP transmit hash to load balance sessions to link aggregation nodes (default = disable).
- Enable/disable calculating the CAPWAP transmit hash to load balance sessions to link aggregation nodes .
type: str
choices:
- enable
- disable
location:
description:
- Description of the location of the wireless controller.
max-clients:
type: str
max_clients:
description:
- Maximum number of clients that can connect simultaneously (default = 0, meaning no limitation).
max-retransmit:
- Maximum number of clients that can connect simultaneously .
type: int
max_retransmit:
description:
- Maximum number of tunnel packet retransmissions (0 - 64, default = 3).
mesh-eth-type:
- Maximum number of tunnel packet retransmissions (0 - 64).
type: int
mesh_eth_type:
description:
- Mesh Ethernet identifier included in backhaul packets (0 - 65535, default = 8755).
- Mesh Ethernet identifier included in backhaul packets (0 - 65535).
type: int
name:
description:
- Name of the wireless controller.
rogue-scan-mac-adjacency:
type: str
rogue_scan_mac_adjacency:
description:
- Maximum numerical difference between an AP's Ethernet and wireless MAC values to match for rogue detection (0 - 31, default = 7).
wtp-share:
- Maximum numerical difference between an AP's Ethernet and wireless MAC values to match for rogue detection (0 - 31).
type: int
wtp_share:
description:
- Enable/disable sharing of WTPs between VDOMs.
type: str
choices:
- enable
- disable
@ -152,6 +179,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure wireless controller global settings.
fortios_wireless_controller_global:
@ -161,23 +189,23 @@ EXAMPLES = '''
vdom: "{{ vdom }}"
https: "False"
wireless_controller_global:
ap-log-server: "enable"
ap-log-server-ip: "<your_own_value>"
ap-log-server-port: "5"
control-message-offload: "ebp-frame"
data-ethernet-II: "enable"
discovery-mc-addr: "<your_own_value>"
fiapp-eth-type: "9"
image-download: "enable"
ipsec-base-ip: "<your_own_value>"
link-aggregation: "enable"
ap_log_server: "enable"
ap_log_server_ip: "<your_own_value>"
ap_log_server_port: "5"
control_message_offload: "ebp-frame"
data_ethernet_II: "enable"
discovery_mc_addr: "<your_own_value>"
fiapp_eth_type: "9"
image_download: "enable"
ipsec_base_ip: "<your_own_value>"
link_aggregation: "enable"
location: "<your_own_value>"
max-clients: "14"
max-retransmit: "15"
mesh-eth-type: "16"
max_clients: "14"
max_retransmit: "15"
mesh_eth_type: "16"
name: "default_name_17"
rogue-scan-mac-adjacency: "18"
wtp-share: "enable"
rogue_scan_mac_adjacency: "18"
wtp_share: "enable"
'''
RETURN = '''
@ -240,12 +268,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -253,16 +285,16 @@ def login(data, fos):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_wireless_controller_global_data(json):
option_list = ['ap-log-server', 'ap-log-server-ip', 'ap-log-server-port',
'control-message-offload', 'data-ethernet-II', 'discovery-mc-addr',
'fiapp-eth-type', 'image-download', 'ipsec-base-ip',
'link-aggregation', 'location', 'max-clients',
'max-retransmit', 'mesh-eth-type', 'name',
'rogue-scan-mac-adjacency', 'wtp-share']
option_list = ['ap_log_server', 'ap_log_server_ip', 'ap_log_server_port',
'control_message_offload', 'data_ethernet_II', 'discovery_mc_addr',
'fiapp_eth_type', 'image_download', 'ipsec_base_ip',
'link_aggregation', 'location', 'max_clients',
'max_retransmit', 'mesh_eth_type', 'name',
'rogue_scan_mac_adjacency', 'wtp_share']
dictionary = {}
for attribute in option_list:
@ -272,10 +304,23 @@ def filter_wireless_controller_global_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def wireless_controller_global(data, fos):
vdom = data['vdom']
wireless_controller_global_data = data['wireless_controller_global']
filtered_data = filter_wireless_controller_global_data(wireless_controller_global_data)
filtered_data = underscore_to_hyphen(filter_wireless_controller_global_data(wireless_controller_global_data))
return fos.set('wireless-controller',
'global',
@ -283,50 +328,56 @@ def wireless_controller_global(data, fos):
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_wireless_controller(data, fos):
login(data, fos)
if data['wireless_controller_global']:
resp = wireless_controller_global(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"wireless_controller_global": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"ap-log-server": {"required": False, "type": "str",
"ap_log_server": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"ap-log-server-ip": {"required": False, "type": "str"},
"ap-log-server-port": {"required": False, "type": "int"},
"control-message-offload": {"required": False, "type": "str",
"ap_log_server_ip": {"required": False, "type": "str"},
"ap_log_server_port": {"required": False, "type": "int"},
"control_message_offload": {"required": False, "type": "str",
"choices": ["ebp-frame", "aeroscout-tag", "ap-list",
"sta-list", "sta-cap-list", "stats",
"aeroscout-mu"]},
"data-ethernet-II": {"required": False, "type": "str",
"data_ethernet_II": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"discovery-mc-addr": {"required": False, "type": "ipv4-address-multicast"},
"fiapp-eth-type": {"required": False, "type": "int"},
"image-download": {"required": False, "type": "str",
"discovery_mc_addr": {"required": False, "type": "str"},
"fiapp_eth_type": {"required": False, "type": "int"},
"image_download": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"ipsec-base-ip": {"required": False, "type": "str"},
"link-aggregation": {"required": False, "type": "str",
"ipsec_base_ip": {"required": False, "type": "str"},
"link_aggregation": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"location": {"required": False, "type": "str"},
"max-clients": {"required": False, "type": "int"},
"max-retransmit": {"required": False, "type": "int"},
"mesh-eth-type": {"required": False, "type": "int"},
"max_clients": {"required": False, "type": "int"},
"max_retransmit": {"required": False, "type": "int"},
"mesh_eth_type": {"required": False, "type": "int"},
"name": {"required": False, "type": "str"},
"rogue-scan-mac-adjacency": {"required": False, "type": "int"},
"wtp-share": {"required": False, "type": "str",
"rogue_scan_mac_adjacency": {"required": False, "type": "int"},
"wtp_share": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
@ -335,14 +386,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_wireless_controller(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_wireless_controller(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_wireless_controller(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -26,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_wireless_controller_setting
short_description: VDOM wireless controller configuration in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by allowing the
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify wireless_controller feature and setting category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -41,40 +41,52 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
wireless_controller_setting:
description:
- VDOM wireless controller configuration.
default: null
type: dict
suboptions:
account-id:
account_id:
description:
- FortiCloud customer account ID.
type: str
country:
description:
- Country or region in which the FortiGate is located. The country determines the 802.11 bands and channels that are available.
type: str
choices:
- NA
- AL
@ -204,15 +216,17 @@ options:
- ZW
- JP
- CA
duplicate-ssid:
duplicate_ssid:
description:
- Enable/disable allowing Virtual Access Points (VAPs) to use the same SSID name in the same VDOM.
type: str
choices:
- enable
- disable
fapc-compatibility:
fapc_compatibility:
description:
- Enable/disable FAP-C series compatibility.
type: str
choices:
- enable
- disable
@ -225,6 +239,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: VDOM wireless controller configuration.
fortios_wireless_controller_setting:
@ -234,10 +249,10 @@ EXAMPLES = '''
vdom: "{{ vdom }}"
https: "False"
wireless_controller_setting:
account-id: "<your_own_value>"
account_id: "<your_own_value>"
country: "NA"
duplicate-ssid: "enable"
fapc-compatibility: "enable"
duplicate_ssid: "enable"
fapc_compatibility: "enable"
'''
RETURN = '''
@ -300,12 +315,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -313,12 +332,12 @@ def login(data, fos):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_wireless_controller_setting_data(json):
option_list = ['account-id', 'country', 'duplicate-ssid',
'fapc-compatibility']
option_list = ['account_id', 'country', 'duplicate_ssid',
'fapc_compatibility']
dictionary = {}
for attribute in option_list:
@ -328,17 +347,15 @@ def filter_wireless_controller_setting_data(json):
return dictionary
def flatten_multilists_attributes(data):
multilist_attrs = []
for attr in multilist_attrs:
try:
path = "data['" + "']['".join(elem for elem in attr) + "']"
current_val = eval(path)
flattened_val = ' '.join(elem for elem in current_val)
exec(path + '= flattened_val')
except BaseException:
pass
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
@ -346,35 +363,41 @@ def flatten_multilists_attributes(data):
def wireless_controller_setting(data, fos):
vdom = data['vdom']
wireless_controller_setting_data = data['wireless_controller_setting']
flattened_data = flatten_multilists_attributes(wireless_controller_setting_data)
filtered_data = filter_wireless_controller_setting_data(flattened_data)
filtered_data = underscore_to_hyphen(filter_wireless_controller_setting_data(wireless_controller_setting_data))
return fos.set('wireless-controller',
'setting',
data=filtered_data,
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_wireless_controller(data, fos):
login(data, fos)
if data['wireless_controller_setting']:
resp = wireless_controller_setting(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"wireless_controller_setting": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"account-id": {"required": False, "type": "str"},
"account_id": {"required": False, "type": "str"},
"country": {"required": False, "type": "str",
"choices": ["NA", "AL", "DZ",
"AO", "AR", "AM",
@ -419,9 +442,9 @@ def main():
"UZ", "VE", "VN",
"YE", "ZB", "ZW",
"JP", "CA"]},
"duplicate-ssid": {"required": False, "type": "str",
"duplicate_ssid": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"fapc-compatibility": {"required": False, "type": "str",
"fapc_compatibility": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
@ -430,14 +453,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_wireless_controller(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_wireless_controller(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_wireless_controller(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -26,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_wireless_controller_utm_profile
short_description: Configure UTM (Unified Threat Management) profile in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by allowing the
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify wireless_controller feature and utm_profile category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -41,72 +41,93 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
required: true
choices:
- present
- absent
version_added: 2.9
wireless_controller_utm_profile:
description:
- Configure UTM (Unified Threat Management) profile.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
antivirus-profile:
antivirus_profile:
description:
- AntiVirus profile name. Source antivirus.profile.name.
application-list:
type: str
application_list:
description:
- Application control list name. Source application.list.name.
type: str
comment:
description:
- Comment.
ips-sensor:
type: str
ips_sensor:
description:
- IPS sensor name. Source ips.sensor.name.
type: str
name:
description:
- UTM profile name.
required: true
scan-botnet-connections:
type: str
scan_botnet_connections:
description:
- Block or monitor connections to Botnet servers or disable Botnet scanning.
type: str
choices:
- disable
- block
- monitor
utm-log:
- block
utm_log:
description:
- Enable/disable UTM logging.
type: str
choices:
- enable
- disable
webfilter-profile:
webfilter_profile:
description:
- WebFilter profile name. Source webfilter.profile.name.
type: str
'''
EXAMPLES = '''
@ -116,6 +137,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure UTM (Unified Threat Management) profile.
fortios_wireless_controller_utm_profile:
@ -124,16 +146,16 @@ EXAMPLES = '''
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
wireless_controller_utm_profile:
state: "present"
antivirus-profile: "<your_own_value> (source antivirus.profile.name)"
application-list: "<your_own_value> (source application.list.name)"
antivirus_profile: "<your_own_value> (source antivirus.profile.name)"
application_list: "<your_own_value> (source application.list.name)"
comment: "Comment."
ips-sensor: "<your_own_value> (source ips.sensor.name)"
ips_sensor: "<your_own_value> (source ips.sensor.name)"
name: "default_name_7"
scan-botnet-connections: "disable"
utm-log: "enable"
webfilter-profile: "<your_own_value> (source webfilter.profile.name)"
scan_botnet_connections: "disable"
utm_log: "enable"
webfilter_profile: "<your_own_value> (source webfilter.profile.name)"
'''
RETURN = '''
@ -196,12 +218,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -209,13 +235,13 @@ def login(data, fos):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_wireless_controller_utm_profile_data(json):
option_list = ['antivirus-profile', 'application-list', 'comment',
'ips-sensor', 'name', 'scan-botnet-connections',
'utm-log', 'webfilter-profile']
option_list = ['antivirus_profile', 'application_list', 'comment',
'ips_sensor', 'name', 'scan_botnet_connections',
'utm_log', 'webfilter_profile']
dictionary = {}
for attribute in option_list:
@ -225,71 +251,76 @@ def filter_wireless_controller_utm_profile_data(json):
return dictionary
def flatten_multilists_attributes(data):
multilist_attrs = []
for attr in multilist_attrs:
try:
path = "data['" + "']['".join(elem for elem in attr) + "']"
current_val = eval(path)
flattened_val = ' '.join(elem for elem in current_val)
exec(path + '= flattened_val')
except BaseException:
pass
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def wireless_controller_utm_profile(data, fos):
vdom = data['vdom']
state = data['state']
wireless_controller_utm_profile_data = data['wireless_controller_utm_profile']
flattened_data = flatten_multilists_attributes(wireless_controller_utm_profile_data)
filtered_data = filter_wireless_controller_utm_profile_data(flattened_data)
if wireless_controller_utm_profile_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_wireless_controller_utm_profile_data(wireless_controller_utm_profile_data))
if state == "present":
return fos.set('wireless-controller',
'utm-profile',
data=filtered_data,
vdom=vdom)
elif wireless_controller_utm_profile_data['state'] == "absent":
elif state == "absent":
return fos.delete('wireless-controller',
'utm-profile',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_wireless_controller(data, fos):
login(data, fos)
if data['wireless_controller_utm_profile']:
resp = wireless_controller_utm_profile(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"wireless_controller_utm_profile": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"antivirus-profile": {"required": False, "type": "str"},
"application-list": {"required": False, "type": "str"},
"antivirus_profile": {"required": False, "type": "str"},
"application_list": {"required": False, "type": "str"},
"comment": {"required": False, "type": "str"},
"ips-sensor": {"required": False, "type": "str"},
"ips_sensor": {"required": False, "type": "str"},
"name": {"required": True, "type": "str"},
"scan-botnet-connections": {"required": False, "type": "str",
"choices": ["disable", "block", "monitor"]},
"utm-log": {"required": False, "type": "str",
"scan_botnet_connections": {"required": False, "type": "str",
"choices": ["disable", "monitor", "block"]},
"utm_log": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"webfilter-profile": {"required": False, "type": "str"}
"webfilter_profile": {"required": False, "type": "str"}
}
}
@ -297,14 +328,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_wireless_controller(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_wireless_controller(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_wireless_controller(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -26,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_wireless_controller_wids_profile
short_description: Configure wireless intrusion detection system (WIDS) profiles in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by allowing the
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify wireless_controller feature and wids_profile category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -41,49 +41,64 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
required: true
choices:
- present
- absent
version_added: 2.9
wireless_controller_wids_profile:
description:
- Configure wireless intrusion detection system (WIDS) profiles.
default: null
type: dict
suboptions:
state:
ap_auto_suppress:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
ap-auto-suppress:
description:
- Enable/disable on-wire rogue AP auto-suppression (default = disable).
- Enable/disable on-wire rogue AP auto-suppression .
type: str
choices:
- enable
- disable
ap-bgscan-disable-day:
ap_bgscan_disable_day:
description:
- Optionally turn off scanning for one or more days of the week. Separate the days with a space. By default, no days are set.
type: str
choices:
- sunday
- monday
@ -92,203 +107,250 @@ options:
- thursday
- friday
- saturday
ap-bgscan-disable-end:
ap_bgscan_disable_end:
description:
- "End time, using a 24-hour clock in the format of hh:mm, for disabling background scanning (default = 00:00)."
ap-bgscan-disable-start:
- "End time, using a 24-hour clock in the format of hh:mm, for disabling background scanning ."
type: str
ap_bgscan_disable_start:
description:
- "Start time, using a 24-hour clock in the format of hh:mm, for disabling background scanning (default = 00:00)."
ap-bgscan-duration:
- "Start time, using a 24-hour clock in the format of hh:mm, for disabling background scanning ."
type: str
ap_bgscan_duration:
description:
- Listening time on a scanning channel (10 - 1000 msec, default = 20).
ap-bgscan-idle:
- Listening time on a scanning channel (10 - 1000 msec).
type: int
ap_bgscan_idle:
description:
- Waiting time for channel inactivity before scanning this channel (0 - 1000 msec, default = 0).
ap-bgscan-intv:
- Waiting time for channel inactivity before scanning this channel (0 - 1000 msec).
type: int
ap_bgscan_intv:
description:
- Period of time between scanning two channels (1 - 600 sec, default = 1).
ap-bgscan-period:
- Period of time between scanning two channels (1 - 600 sec).
type: int
ap_bgscan_period:
description:
- Period of time between background scans (60 - 3600 sec, default = 600).
ap-bgscan-report-intv:
- Period of time between background scans (60 - 3600 sec).
type: int
ap_bgscan_report_intv:
description:
- Period of time between background scan reports (15 - 600 sec, default = 30).
ap-fgscan-report-intv:
- Period of time between background scan reports (15 - 600 sec).
type: int
ap_fgscan_report_intv:
description:
- Period of time between foreground scan reports (15 - 600 sec, default = 15).
ap-scan:
- Period of time between foreground scan reports (15 - 600 sec).
type: int
ap_scan:
description:
- Enable/disable rogue AP detection.
type: str
choices:
- disable
- enable
ap-scan-passive:
ap_scan_passive:
description:
- Enable/disable passive scanning. Enable means do not send probe request on any channels (default = disable).
- Enable/disable passive scanning. Enable means do not send probe request on any channels .
type: str
choices:
- enable
- disable
asleap-attack:
asleap_attack:
description:
- Enable/disable asleap attack detection (default = disable).
- Enable/disable asleap attack detection .
type: str
choices:
- enable
- disable
assoc-flood-thresh:
assoc_flood_thresh:
description:
- The threshold value for association frame flooding.
assoc-flood-time:
type: int
assoc_flood_time:
description:
- Number of seconds after which a station is considered not connected.
assoc-frame-flood:
type: int
assoc_frame_flood:
description:
- Enable/disable association frame flooding detection (default = disable).
- Enable/disable association frame flooding detection .
type: str
choices:
- enable
- disable
auth-flood-thresh:
auth_flood_thresh:
description:
- The threshold value for authentication frame flooding.
auth-flood-time:
type: int
auth_flood_time:
description:
- Number of seconds after which a station is considered not connected.
auth-frame-flood:
type: int
auth_frame_flood:
description:
- Enable/disable authentication frame flooding detection (default = disable).
- Enable/disable authentication frame flooding detection .
type: str
choices:
- enable
- disable
comment:
description:
- Comment.
deauth-broadcast:
type: str
deauth_broadcast:
description:
- Enable/disable broadcasting de-authentication detection (default = disable).
- Enable/disable broadcasting de-authentication detection .
type: str
choices:
- enable
- disable
deauth-unknown-src-thresh:
deauth_unknown_src_thresh:
description:
- "Threshold value per second to deauth unknown src for DoS attack (0: no limit)."
eapol-fail-flood:
type: int
eapol_fail_flood:
description:
- Enable/disable EAPOL-Failure flooding (to AP) detection (default = disable).
- Enable/disable EAPOL-Failure flooding (to AP) detection .
type: str
choices:
- enable
- disable
eapol-fail-intv:
eapol_fail_intv:
description:
- The detection interval for EAPOL-Failure flooding (1 - 3600 sec).
eapol-fail-thresh:
type: int
eapol_fail_thresh:
description:
- The threshold value for EAPOL-Failure flooding in specified interval.
eapol-logoff-flood:
type: int
eapol_logoff_flood:
description:
- Enable/disable EAPOL-Logoff flooding (to AP) detection (default = disable).
- Enable/disable EAPOL-Logoff flooding (to AP) detection .
type: str
choices:
- enable
- disable
eapol-logoff-intv:
eapol_logoff_intv:
description:
- The detection interval for EAPOL-Logoff flooding (1 - 3600 sec).
eapol-logoff-thresh:
type: int
eapol_logoff_thresh:
description:
- The threshold value for EAPOL-Logoff flooding in specified interval.
eapol-pre-fail-flood:
type: int
eapol_pre_fail_flood:
description:
- Enable/disable premature EAPOL-Failure flooding (to STA) detection (default = disable).
- Enable/disable premature EAPOL-Failure flooding (to STA) detection .
type: str
choices:
- enable
- disable
eapol-pre-fail-intv:
eapol_pre_fail_intv:
description:
- The detection interval for premature EAPOL-Failure flooding (1 - 3600 sec).
eapol-pre-fail-thresh:
type: int
eapol_pre_fail_thresh:
description:
- The threshold value for premature EAPOL-Failure flooding in specified interval.
eapol-pre-succ-flood:
type: int
eapol_pre_succ_flood:
description:
- Enable/disable premature EAPOL-Success flooding (to STA) detection (default = disable).
- Enable/disable premature EAPOL-Success flooding (to STA) detection .
type: str
choices:
- enable
- disable
eapol-pre-succ-intv:
eapol_pre_succ_intv:
description:
- The detection interval for premature EAPOL-Success flooding (1 - 3600 sec).
eapol-pre-succ-thresh:
type: int
eapol_pre_succ_thresh:
description:
- The threshold value for premature EAPOL-Success flooding in specified interval.
eapol-start-flood:
type: int
eapol_start_flood:
description:
- Enable/disable EAPOL-Start flooding (to AP) detection (default = disable).
- Enable/disable EAPOL-Start flooding (to AP) detection .
type: str
choices:
- enable
- disable
eapol-start-intv:
eapol_start_intv:
description:
- The detection interval for EAPOL-Start flooding (1 - 3600 sec).
eapol-start-thresh:
type: int
eapol_start_thresh:
description:
- The threshold value for EAPOL-Start flooding in specified interval.
eapol-succ-flood:
type: int
eapol_succ_flood:
description:
- Enable/disable EAPOL-Success flooding (to AP) detection (default = disable).
- Enable/disable EAPOL-Success flooding (to AP) detection .
type: str
choices:
- enable
- disable
eapol-succ-intv:
eapol_succ_intv:
description:
- The detection interval for EAPOL-Success flooding (1 - 3600 sec).
eapol-succ-thresh:
type: int
eapol_succ_thresh:
description:
- The threshold value for EAPOL-Success flooding in specified interval.
invalid-mac-oui:
type: int
invalid_mac_oui:
description:
- Enable/disable invalid MAC OUI detection.
type: str
choices:
- enable
- disable
long-duration-attack:
long_duration_attack:
description:
- Enable/disable long duration attack detection based on user configured threshold (default = disable).
- Enable/disable long duration attack detection based on user configured threshold .
type: str
choices:
- enable
- disable
long-duration-thresh:
long_duration_thresh:
description:
- Threshold value for long duration attack detection (1000 - 32767 usec, default = 8200).
- Threshold value for long duration attack detection (1000 - 32767 usec).
type: int
name:
description:
- WIDS profile name.
required: true
null-ssid-probe-resp:
type: str
null_ssid_probe_resp:
description:
- Enable/disable null SSID probe response detection (default = disable).
- Enable/disable null SSID probe response detection .
type: str
choices:
- enable
- disable
sensor-mode:
sensor_mode:
description:
- Scan WiFi nearby stations (default = disable).
- Scan WiFi nearby stations .
type: str
choices:
- disable
- foreign
- both
spoofed-deauth:
spoofed_deauth:
description:
- Enable/disable spoofed de-authentication attack detection (default = disable).
- Enable/disable spoofed de-authentication attack detection .
type: str
choices:
- enable
- disable
weak-wep-iv:
weak_wep_iv:
description:
- Enable/disable weak WEP IV (Initialization Vector) detection (default = disable).
- Enable/disable weak WEP IV (Initialization Vector) detection .
type: str
choices:
- enable
- disable
wireless-bridge:
wireless_bridge:
description:
- Enable/disable wireless bridge detection (default = disable).
- Enable/disable wireless bridge detection .
type: str
choices:
- enable
- disable
@ -301,6 +363,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure wireless intrusion detection system (WIDS) profiles.
fortios_wireless_controller_wids_profile:
@ -309,57 +372,57 @@ EXAMPLES = '''
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
wireless_controller_wids_profile:
state: "present"
ap-auto-suppress: "enable"
ap-bgscan-disable-day: "sunday"
ap-bgscan-disable-end: "<your_own_value>"
ap-bgscan-disable-start: "<your_own_value>"
ap-bgscan-duration: "7"
ap-bgscan-idle: "8"
ap-bgscan-intv: "9"
ap-bgscan-period: "10"
ap-bgscan-report-intv: "11"
ap-fgscan-report-intv: "12"
ap-scan: "disable"
ap-scan-passive: "enable"
asleap-attack: "enable"
assoc-flood-thresh: "16"
assoc-flood-time: "17"
assoc-frame-flood: "enable"
auth-flood-thresh: "19"
auth-flood-time: "20"
auth-frame-flood: "enable"
ap_auto_suppress: "enable"
ap_bgscan_disable_day: "sunday"
ap_bgscan_disable_end: "<your_own_value>"
ap_bgscan_disable_start: "<your_own_value>"
ap_bgscan_duration: "7"
ap_bgscan_idle: "8"
ap_bgscan_intv: "9"
ap_bgscan_period: "10"
ap_bgscan_report_intv: "11"
ap_fgscan_report_intv: "12"
ap_scan: "disable"
ap_scan_passive: "enable"
asleap_attack: "enable"
assoc_flood_thresh: "16"
assoc_flood_time: "17"
assoc_frame_flood: "enable"
auth_flood_thresh: "19"
auth_flood_time: "20"
auth_frame_flood: "enable"
comment: "Comment."
deauth-broadcast: "enable"
deauth-unknown-src-thresh: "24"
eapol-fail-flood: "enable"
eapol-fail-intv: "26"
eapol-fail-thresh: "27"
eapol-logoff-flood: "enable"
eapol-logoff-intv: "29"
eapol-logoff-thresh: "30"
eapol-pre-fail-flood: "enable"
eapol-pre-fail-intv: "32"
eapol-pre-fail-thresh: "33"
eapol-pre-succ-flood: "enable"
eapol-pre-succ-intv: "35"
eapol-pre-succ-thresh: "36"
eapol-start-flood: "enable"
eapol-start-intv: "38"
eapol-start-thresh: "39"
eapol-succ-flood: "enable"
eapol-succ-intv: "41"
eapol-succ-thresh: "42"
invalid-mac-oui: "enable"
long-duration-attack: "enable"
long-duration-thresh: "45"
deauth_broadcast: "enable"
deauth_unknown_src_thresh: "24"
eapol_fail_flood: "enable"
eapol_fail_intv: "26"
eapol_fail_thresh: "27"
eapol_logoff_flood: "enable"
eapol_logoff_intv: "29"
eapol_logoff_thresh: "30"
eapol_pre_fail_flood: "enable"
eapol_pre_fail_intv: "32"
eapol_pre_fail_thresh: "33"
eapol_pre_succ_flood: "enable"
eapol_pre_succ_intv: "35"
eapol_pre_succ_thresh: "36"
eapol_start_flood: "enable"
eapol_start_intv: "38"
eapol_start_thresh: "39"
eapol_succ_flood: "enable"
eapol_succ_intv: "41"
eapol_succ_thresh: "42"
invalid_mac_oui: "enable"
long_duration_attack: "enable"
long_duration_thresh: "45"
name: "default_name_46"
null-ssid-probe-resp: "enable"
sensor-mode: "disable"
spoofed-deauth: "enable"
weak-wep-iv: "enable"
wireless-bridge: "enable"
null_ssid_probe_resp: "enable"
sensor_mode: "disable"
spoofed_deauth: "enable"
weak_wep_iv: "enable"
wireless_bridge: "enable"
'''
RETURN = '''
@ -422,12 +485,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -435,27 +502,27 @@ def login(data, fos):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_wireless_controller_wids_profile_data(json):
option_list = ['ap-auto-suppress', 'ap-bgscan-disable-day', 'ap-bgscan-disable-end',
'ap-bgscan-disable-start', 'ap-bgscan-duration', 'ap-bgscan-idle',
'ap-bgscan-intv', 'ap-bgscan-period', 'ap-bgscan-report-intv',
'ap-fgscan-report-intv', 'ap-scan', 'ap-scan-passive',
'asleap-attack', 'assoc-flood-thresh', 'assoc-flood-time',
'assoc-frame-flood', 'auth-flood-thresh', 'auth-flood-time',
'auth-frame-flood', 'comment', 'deauth-broadcast',
'deauth-unknown-src-thresh', 'eapol-fail-flood', 'eapol-fail-intv',
'eapol-fail-thresh', 'eapol-logoff-flood', 'eapol-logoff-intv',
'eapol-logoff-thresh', 'eapol-pre-fail-flood', 'eapol-pre-fail-intv',
'eapol-pre-fail-thresh', 'eapol-pre-succ-flood', 'eapol-pre-succ-intv',
'eapol-pre-succ-thresh', 'eapol-start-flood', 'eapol-start-intv',
'eapol-start-thresh', 'eapol-succ-flood', 'eapol-succ-intv',
'eapol-succ-thresh', 'invalid-mac-oui', 'long-duration-attack',
'long-duration-thresh', 'name', 'null-ssid-probe-resp',
'sensor-mode', 'spoofed-deauth', 'weak-wep-iv',
'wireless-bridge']
option_list = ['ap_auto_suppress', 'ap_bgscan_disable_day', 'ap_bgscan_disable_end',
'ap_bgscan_disable_start', 'ap_bgscan_duration', 'ap_bgscan_idle',
'ap_bgscan_intv', 'ap_bgscan_period', 'ap_bgscan_report_intv',
'ap_fgscan_report_intv', 'ap_scan', 'ap_scan_passive',
'asleap_attack', 'assoc_flood_thresh', 'assoc_flood_time',
'assoc_frame_flood', 'auth_flood_thresh', 'auth_flood_time',
'auth_frame_flood', 'comment', 'deauth_broadcast',
'deauth_unknown_src_thresh', 'eapol_fail_flood', 'eapol_fail_intv',
'eapol_fail_thresh', 'eapol_logoff_flood', 'eapol_logoff_intv',
'eapol_logoff_thresh', 'eapol_pre_fail_flood', 'eapol_pre_fail_intv',
'eapol_pre_fail_thresh', 'eapol_pre_succ_flood', 'eapol_pre_succ_intv',
'eapol_pre_succ_thresh', 'eapol_start_flood', 'eapol_start_intv',
'eapol_start_thresh', 'eapol_succ_flood', 'eapol_succ_intv',
'eapol_succ_thresh', 'invalid_mac_oui', 'long_duration_attack',
'long_duration_thresh', 'name', 'null_ssid_probe_resp',
'sensor_mode', 'spoofed_deauth', 'weak_wep_iv',
'wireless_bridge']
dictionary = {}
for attribute in option_list:
@ -465,132 +532,137 @@ def filter_wireless_controller_wids_profile_data(json):
return dictionary
def flatten_multilists_attributes(data):
multilist_attrs = []
for attr in multilist_attrs:
try:
path = "data['" + "']['".join(elem for elem in attr) + "']"
current_val = eval(path)
flattened_val = ' '.join(elem for elem in current_val)
exec(path + '= flattened_val')
except BaseException:
pass
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def wireless_controller_wids_profile(data, fos):
vdom = data['vdom']
state = data['state']
wireless_controller_wids_profile_data = data['wireless_controller_wids_profile']
flattened_data = flatten_multilists_attributes(wireless_controller_wids_profile_data)
filtered_data = filter_wireless_controller_wids_profile_data(flattened_data)
if wireless_controller_wids_profile_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_wireless_controller_wids_profile_data(wireless_controller_wids_profile_data))
if state == "present":
return fos.set('wireless-controller',
'wids-profile',
data=filtered_data,
vdom=vdom)
elif wireless_controller_wids_profile_data['state'] == "absent":
elif state == "absent":
return fos.delete('wireless-controller',
'wids-profile',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_wireless_controller(data, fos):
login(data, fos)
if data['wireless_controller_wids_profile']:
resp = wireless_controller_wids_profile(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"wireless_controller_wids_profile": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"ap-auto-suppress": {"required": False, "type": "str",
"ap_auto_suppress": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"ap-bgscan-disable-day": {"required": False, "type": "str",
"ap_bgscan_disable_day": {"required": False, "type": "str",
"choices": ["sunday", "monday", "tuesday",
"wednesday", "thursday", "friday",
"saturday"]},
"ap-bgscan-disable-end": {"required": False, "type": "str"},
"ap-bgscan-disable-start": {"required": False, "type": "str"},
"ap-bgscan-duration": {"required": False, "type": "int"},
"ap-bgscan-idle": {"required": False, "type": "int"},
"ap-bgscan-intv": {"required": False, "type": "int"},
"ap-bgscan-period": {"required": False, "type": "int"},
"ap-bgscan-report-intv": {"required": False, "type": "int"},
"ap-fgscan-report-intv": {"required": False, "type": "int"},
"ap-scan": {"required": False, "type": "str",
"ap_bgscan_disable_end": {"required": False, "type": "str"},
"ap_bgscan_disable_start": {"required": False, "type": "str"},
"ap_bgscan_duration": {"required": False, "type": "int"},
"ap_bgscan_idle": {"required": False, "type": "int"},
"ap_bgscan_intv": {"required": False, "type": "int"},
"ap_bgscan_period": {"required": False, "type": "int"},
"ap_bgscan_report_intv": {"required": False, "type": "int"},
"ap_fgscan_report_intv": {"required": False, "type": "int"},
"ap_scan": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"ap-scan-passive": {"required": False, "type": "str",
"ap_scan_passive": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"asleap-attack": {"required": False, "type": "str",
"asleap_attack": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"assoc-flood-thresh": {"required": False, "type": "int"},
"assoc-flood-time": {"required": False, "type": "int"},
"assoc-frame-flood": {"required": False, "type": "str",
"assoc_flood_thresh": {"required": False, "type": "int"},
"assoc_flood_time": {"required": False, "type": "int"},
"assoc_frame_flood": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"auth-flood-thresh": {"required": False, "type": "int"},
"auth-flood-time": {"required": False, "type": "int"},
"auth-frame-flood": {"required": False, "type": "str",
"auth_flood_thresh": {"required": False, "type": "int"},
"auth_flood_time": {"required": False, "type": "int"},
"auth_frame_flood": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"comment": {"required": False, "type": "str"},
"deauth-broadcast": {"required": False, "type": "str",
"deauth_broadcast": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"deauth-unknown-src-thresh": {"required": False, "type": "int"},
"eapol-fail-flood": {"required": False, "type": "str",
"deauth_unknown_src_thresh": {"required": False, "type": "int"},
"eapol_fail_flood": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"eapol-fail-intv": {"required": False, "type": "int"},
"eapol-fail-thresh": {"required": False, "type": "int"},
"eapol-logoff-flood": {"required": False, "type": "str",
"eapol_fail_intv": {"required": False, "type": "int"},
"eapol_fail_thresh": {"required": False, "type": "int"},
"eapol_logoff_flood": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"eapol-logoff-intv": {"required": False, "type": "int"},
"eapol-logoff-thresh": {"required": False, "type": "int"},
"eapol-pre-fail-flood": {"required": False, "type": "str",
"eapol_logoff_intv": {"required": False, "type": "int"},
"eapol_logoff_thresh": {"required": False, "type": "int"},
"eapol_pre_fail_flood": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"eapol-pre-fail-intv": {"required": False, "type": "int"},
"eapol-pre-fail-thresh": {"required": False, "type": "int"},
"eapol-pre-succ-flood": {"required": False, "type": "str",
"eapol_pre_fail_intv": {"required": False, "type": "int"},
"eapol_pre_fail_thresh": {"required": False, "type": "int"},
"eapol_pre_succ_flood": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"eapol-pre-succ-intv": {"required": False, "type": "int"},
"eapol-pre-succ-thresh": {"required": False, "type": "int"},
"eapol-start-flood": {"required": False, "type": "str",
"eapol_pre_succ_intv": {"required": False, "type": "int"},
"eapol_pre_succ_thresh": {"required": False, "type": "int"},
"eapol_start_flood": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"eapol-start-intv": {"required": False, "type": "int"},
"eapol-start-thresh": {"required": False, "type": "int"},
"eapol-succ-flood": {"required": False, "type": "str",
"eapol_start_intv": {"required": False, "type": "int"},
"eapol_start_thresh": {"required": False, "type": "int"},
"eapol_succ_flood": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"eapol-succ-intv": {"required": False, "type": "int"},
"eapol-succ-thresh": {"required": False, "type": "int"},
"invalid-mac-oui": {"required": False, "type": "str",
"eapol_succ_intv": {"required": False, "type": "int"},
"eapol_succ_thresh": {"required": False, "type": "int"},
"invalid_mac_oui": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"long-duration-attack": {"required": False, "type": "str",
"long_duration_attack": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"long-duration-thresh": {"required": False, "type": "int"},
"long_duration_thresh": {"required": False, "type": "int"},
"name": {"required": True, "type": "str"},
"null-ssid-probe-resp": {"required": False, "type": "str",
"null_ssid_probe_resp": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"sensor-mode": {"required": False, "type": "str",
"sensor_mode": {"required": False, "type": "str",
"choices": ["disable", "foreign", "both"]},
"spoofed-deauth": {"required": False, "type": "str",
"spoofed_deauth": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"weak-wep-iv": {"required": False, "type": "str",
"weak_wep_iv": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"wireless-bridge": {"required": False, "type": "str",
"wireless_bridge": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
@ -599,14 +671,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_wireless_controller(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_wireless_controller(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_wireless_controller(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -3712,51 +3712,13 @@ lib/ansible/modules/network/fortios/fortios_system_global.py validate-modules:E3
lib/ansible/modules/network/fortios/fortios_voip_profile.py validate-modules:E326
lib/ansible/modules/network/fortios/fortios_vpn_ipsec_manualkey.py validate-modules:E326
lib/ansible/modules/network/fortios/fortios_vpn_ipsec_manualkey_interface.py validate-modules:E326
lib/ansible/modules/network/fortios/fortios_web_proxy_explicit.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_web_proxy_explicit.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_web_proxy_global.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_web_proxy_global.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_web_proxy_profile.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_web_proxy_profile.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_webfilter.py validate-modules:E326
lib/ansible/modules/network/fortios/fortios_webfilter.py validate-modules:E328
lib/ansible/modules/network/fortios/fortios_webfilter.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_webfilter.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_webfilter_fortiguard.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_webfilter_fortiguard.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_webfilter_ftgd_local_cat.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_webfilter_ftgd_local_rating.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_webfilter_ips_urlfilter_cache_setting.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_webfilter_ips_urlfilter_cache_setting.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_webfilter_ips_urlfilter_setting.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_webfilter_ips_urlfilter_setting.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_webfilter_ips_urlfilter_setting6.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_webfilter_ips_urlfilter_setting6.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_webfilter_override.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_webfilter_override.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_webfilter_profile.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_webfilter_profile.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_webfilter_search_engine.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_webfilter_search_engine.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_webfilter_urlfilter.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_webfilter_urlfilter.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_wireless_controller_global.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_wireless_controller_global.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_wireless_controller_setting.py validate-modules:E326
lib/ansible/modules/network/fortios/fortios_wireless_controller_setting.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_wireless_controller_setting.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_wireless_controller_utm_profile.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_wireless_controller_utm_profile.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_wireless_controller_vap.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_wireless_controller_vap.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_wireless_controller_wids_profile.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_wireless_controller_wids_profile.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_wireless_controller_wtp.py validate-modules:E326
lib/ansible/modules/network/fortios/fortios_wireless_controller_wtp.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_wireless_controller_wtp.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_wireless_controller_wtp_profile.py validate-modules:E326
lib/ansible/modules/network/fortios/fortios_wireless_controller_wtp_profile.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_wireless_controller_wtp_profile.py validate-modules:E337
lib/ansible/modules/network/frr/frr_bgp.py validate-modules:E322
lib/ansible/modules/network/frr/frr_bgp.py validate-modules:E323
lib/ansible/modules/network/frr/frr_bgp.py validate-modules:E337

@ -0,0 +1,351 @@
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_web_proxy_explicit
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_web_proxy_explicit.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_web_proxy_explicit_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'web_proxy_explicit': {
'ftp_incoming_port': 'test_value_3',
'ftp_over_http': 'enable',
'http_incoming_port': 'test_value_5',
'https_incoming_port': 'test_value_6',
'https_replacement_message': 'enable',
'incoming_ip': 'test_value_8',
'incoming_ip6': 'test_value_9',
'ipv6_status': 'enable',
'message_upon_server_error': 'enable',
'outgoing_ip': 'test_value_12',
'outgoing_ip6': 'test_value_13',
'pac_file_data': 'test_value_14',
'pac_file_name': 'test_value_15',
'pac_file_server_port': 'test_value_16',
'pac_file_server_status': 'enable',
'pac_file_url': 'test_value_18',
'pref_dns_result': 'ipv4',
'realm': 'test_value_20',
'sec_default_action': 'accept',
'socks': 'enable',
'socks_incoming_port': 'test_value_23',
'ssl_algorithm': 'low',
'status': 'enable',
'strict_guest': 'enable',
'trace_auth_no_rsp': 'enable',
'unknown_http_version': 'reject'
},
'vdom': 'root'}
is_error, changed, response = fortios_web_proxy_explicit.fortios_web_proxy(input_data, fos_instance)
expected_data = {
'ftp-incoming-port': 'test_value_3',
'ftp-over-http': 'enable',
'http-incoming-port': 'test_value_5',
'https-incoming-port': 'test_value_6',
'https-replacement-message': 'enable',
'incoming-ip': 'test_value_8',
'incoming-ip6': 'test_value_9',
'ipv6-status': 'enable',
'message-upon-server-error': 'enable',
'outgoing-ip': 'test_value_12',
'outgoing-ip6': 'test_value_13',
'pac-file-data': 'test_value_14',
'pac-file-name': 'test_value_15',
'pac-file-server-port': 'test_value_16',
'pac-file-server-status': 'enable',
'pac-file-url': 'test_value_18',
'pref-dns-result': 'ipv4',
'realm': 'test_value_20',
'sec-default-action': 'accept',
'socks': 'enable',
'socks-incoming-port': 'test_value_23',
'ssl-algorithm': 'low',
'status': 'enable',
'strict-guest': 'enable',
'trace-auth-no-rsp': 'enable',
'unknown-http-version': 'reject'
}
set_method_mock.assert_called_with('web-proxy', 'explicit', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_web_proxy_explicit_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'web_proxy_explicit': {
'ftp_incoming_port': 'test_value_3',
'ftp_over_http': 'enable',
'http_incoming_port': 'test_value_5',
'https_incoming_port': 'test_value_6',
'https_replacement_message': 'enable',
'incoming_ip': 'test_value_8',
'incoming_ip6': 'test_value_9',
'ipv6_status': 'enable',
'message_upon_server_error': 'enable',
'outgoing_ip': 'test_value_12',
'outgoing_ip6': 'test_value_13',
'pac_file_data': 'test_value_14',
'pac_file_name': 'test_value_15',
'pac_file_server_port': 'test_value_16',
'pac_file_server_status': 'enable',
'pac_file_url': 'test_value_18',
'pref_dns_result': 'ipv4',
'realm': 'test_value_20',
'sec_default_action': 'accept',
'socks': 'enable',
'socks_incoming_port': 'test_value_23',
'ssl_algorithm': 'low',
'status': 'enable',
'strict_guest': 'enable',
'trace_auth_no_rsp': 'enable',
'unknown_http_version': 'reject'
},
'vdom': 'root'}
is_error, changed, response = fortios_web_proxy_explicit.fortios_web_proxy(input_data, fos_instance)
expected_data = {
'ftp-incoming-port': 'test_value_3',
'ftp-over-http': 'enable',
'http-incoming-port': 'test_value_5',
'https-incoming-port': 'test_value_6',
'https-replacement-message': 'enable',
'incoming-ip': 'test_value_8',
'incoming-ip6': 'test_value_9',
'ipv6-status': 'enable',
'message-upon-server-error': 'enable',
'outgoing-ip': 'test_value_12',
'outgoing-ip6': 'test_value_13',
'pac-file-data': 'test_value_14',
'pac-file-name': 'test_value_15',
'pac-file-server-port': 'test_value_16',
'pac-file-server-status': 'enable',
'pac-file-url': 'test_value_18',
'pref-dns-result': 'ipv4',
'realm': 'test_value_20',
'sec-default-action': 'accept',
'socks': 'enable',
'socks-incoming-port': 'test_value_23',
'ssl-algorithm': 'low',
'status': 'enable',
'strict-guest': 'enable',
'trace-auth-no-rsp': 'enable',
'unknown-http-version': 'reject'
}
set_method_mock.assert_called_with('web-proxy', 'explicit', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_web_proxy_explicit_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'web_proxy_explicit': {
'ftp_incoming_port': 'test_value_3',
'ftp_over_http': 'enable',
'http_incoming_port': 'test_value_5',
'https_incoming_port': 'test_value_6',
'https_replacement_message': 'enable',
'incoming_ip': 'test_value_8',
'incoming_ip6': 'test_value_9',
'ipv6_status': 'enable',
'message_upon_server_error': 'enable',
'outgoing_ip': 'test_value_12',
'outgoing_ip6': 'test_value_13',
'pac_file_data': 'test_value_14',
'pac_file_name': 'test_value_15',
'pac_file_server_port': 'test_value_16',
'pac_file_server_status': 'enable',
'pac_file_url': 'test_value_18',
'pref_dns_result': 'ipv4',
'realm': 'test_value_20',
'sec_default_action': 'accept',
'socks': 'enable',
'socks_incoming_port': 'test_value_23',
'ssl_algorithm': 'low',
'status': 'enable',
'strict_guest': 'enable',
'trace_auth_no_rsp': 'enable',
'unknown_http_version': 'reject'
},
'vdom': 'root'}
is_error, changed, response = fortios_web_proxy_explicit.fortios_web_proxy(input_data, fos_instance)
expected_data = {
'ftp-incoming-port': 'test_value_3',
'ftp-over-http': 'enable',
'http-incoming-port': 'test_value_5',
'https-incoming-port': 'test_value_6',
'https-replacement-message': 'enable',
'incoming-ip': 'test_value_8',
'incoming-ip6': 'test_value_9',
'ipv6-status': 'enable',
'message-upon-server-error': 'enable',
'outgoing-ip': 'test_value_12',
'outgoing-ip6': 'test_value_13',
'pac-file-data': 'test_value_14',
'pac-file-name': 'test_value_15',
'pac-file-server-port': 'test_value_16',
'pac-file-server-status': 'enable',
'pac-file-url': 'test_value_18',
'pref-dns-result': 'ipv4',
'realm': 'test_value_20',
'sec-default-action': 'accept',
'socks': 'enable',
'socks-incoming-port': 'test_value_23',
'ssl-algorithm': 'low',
'status': 'enable',
'strict-guest': 'enable',
'trace-auth-no-rsp': 'enable',
'unknown-http-version': 'reject'
}
set_method_mock.assert_called_with('web-proxy', 'explicit', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_web_proxy_explicit_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'web_proxy_explicit': {
'random_attribute_not_valid': 'tag',
'ftp_incoming_port': 'test_value_3',
'ftp_over_http': 'enable',
'http_incoming_port': 'test_value_5',
'https_incoming_port': 'test_value_6',
'https_replacement_message': 'enable',
'incoming_ip': 'test_value_8',
'incoming_ip6': 'test_value_9',
'ipv6_status': 'enable',
'message_upon_server_error': 'enable',
'outgoing_ip': 'test_value_12',
'outgoing_ip6': 'test_value_13',
'pac_file_data': 'test_value_14',
'pac_file_name': 'test_value_15',
'pac_file_server_port': 'test_value_16',
'pac_file_server_status': 'enable',
'pac_file_url': 'test_value_18',
'pref_dns_result': 'ipv4',
'realm': 'test_value_20',
'sec_default_action': 'accept',
'socks': 'enable',
'socks_incoming_port': 'test_value_23',
'ssl_algorithm': 'low',
'status': 'enable',
'strict_guest': 'enable',
'trace_auth_no_rsp': 'enable',
'unknown_http_version': 'reject'
},
'vdom': 'root'}
is_error, changed, response = fortios_web_proxy_explicit.fortios_web_proxy(input_data, fos_instance)
expected_data = {
'ftp-incoming-port': 'test_value_3',
'ftp-over-http': 'enable',
'http-incoming-port': 'test_value_5',
'https-incoming-port': 'test_value_6',
'https-replacement-message': 'enable',
'incoming-ip': 'test_value_8',
'incoming-ip6': 'test_value_9',
'ipv6-status': 'enable',
'message-upon-server-error': 'enable',
'outgoing-ip': 'test_value_12',
'outgoing-ip6': 'test_value_13',
'pac-file-data': 'test_value_14',
'pac-file-name': 'test_value_15',
'pac-file-server-port': 'test_value_16',
'pac-file-server-status': 'enable',
'pac-file-url': 'test_value_18',
'pref-dns-result': 'ipv4',
'realm': 'test_value_20',
'sec-default-action': 'accept',
'socks': 'enable',
'socks-incoming-port': 'test_value_23',
'ssl-algorithm': 'low',
'status': 'enable',
'strict-guest': 'enable',
'trace-auth-no-rsp': 'enable',
'unknown-http-version': 'reject'
}
set_method_mock.assert_called_with('web-proxy', 'explicit', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,247 @@
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_web_proxy_global
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_web_proxy_global.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_web_proxy_global_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'web_proxy_global': {
'fast_policy_match': 'enable',
'forward_proxy_auth': 'enable',
'forward_server_affinity_timeout': '5',
'learn_client_ip': 'enable',
'learn_client_ip_from_header': 'true-client-ip',
'max_message_length': '8',
'max_request_length': '9',
'max_waf_body_cache_length': '10',
'proxy_fqdn': 'test_value_11',
'strict_web_check': 'enable',
'tunnel_non_http': 'enable',
'unknown_http_version': 'reject',
'webproxy_profile': 'test_value_15'
},
'vdom': 'root'}
is_error, changed, response = fortios_web_proxy_global.fortios_web_proxy(input_data, fos_instance)
expected_data = {
'fast-policy-match': 'enable',
'forward-proxy-auth': 'enable',
'forward-server-affinity-timeout': '5',
'learn-client-ip': 'enable',
'learn-client-ip-from-header': 'true-client-ip',
'max-message-length': '8',
'max-request-length': '9',
'max-waf-body-cache-length': '10',
'proxy-fqdn': 'test_value_11',
'strict-web-check': 'enable',
'tunnel-non-http': 'enable',
'unknown-http-version': 'reject',
'webproxy-profile': 'test_value_15'
}
set_method_mock.assert_called_with('web-proxy', 'global', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_web_proxy_global_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'web_proxy_global': {
'fast_policy_match': 'enable',
'forward_proxy_auth': 'enable',
'forward_server_affinity_timeout': '5',
'learn_client_ip': 'enable',
'learn_client_ip_from_header': 'true-client-ip',
'max_message_length': '8',
'max_request_length': '9',
'max_waf_body_cache_length': '10',
'proxy_fqdn': 'test_value_11',
'strict_web_check': 'enable',
'tunnel_non_http': 'enable',
'unknown_http_version': 'reject',
'webproxy_profile': 'test_value_15'
},
'vdom': 'root'}
is_error, changed, response = fortios_web_proxy_global.fortios_web_proxy(input_data, fos_instance)
expected_data = {
'fast-policy-match': 'enable',
'forward-proxy-auth': 'enable',
'forward-server-affinity-timeout': '5',
'learn-client-ip': 'enable',
'learn-client-ip-from-header': 'true-client-ip',
'max-message-length': '8',
'max-request-length': '9',
'max-waf-body-cache-length': '10',
'proxy-fqdn': 'test_value_11',
'strict-web-check': 'enable',
'tunnel-non-http': 'enable',
'unknown-http-version': 'reject',
'webproxy-profile': 'test_value_15'
}
set_method_mock.assert_called_with('web-proxy', 'global', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_web_proxy_global_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'web_proxy_global': {
'fast_policy_match': 'enable',
'forward_proxy_auth': 'enable',
'forward_server_affinity_timeout': '5',
'learn_client_ip': 'enable',
'learn_client_ip_from_header': 'true-client-ip',
'max_message_length': '8',
'max_request_length': '9',
'max_waf_body_cache_length': '10',
'proxy_fqdn': 'test_value_11',
'strict_web_check': 'enable',
'tunnel_non_http': 'enable',
'unknown_http_version': 'reject',
'webproxy_profile': 'test_value_15'
},
'vdom': 'root'}
is_error, changed, response = fortios_web_proxy_global.fortios_web_proxy(input_data, fos_instance)
expected_data = {
'fast-policy-match': 'enable',
'forward-proxy-auth': 'enable',
'forward-server-affinity-timeout': '5',
'learn-client-ip': 'enable',
'learn-client-ip-from-header': 'true-client-ip',
'max-message-length': '8',
'max-request-length': '9',
'max-waf-body-cache-length': '10',
'proxy-fqdn': 'test_value_11',
'strict-web-check': 'enable',
'tunnel-non-http': 'enable',
'unknown-http-version': 'reject',
'webproxy-profile': 'test_value_15'
}
set_method_mock.assert_called_with('web-proxy', 'global', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_web_proxy_global_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'web_proxy_global': {
'random_attribute_not_valid': 'tag',
'fast_policy_match': 'enable',
'forward_proxy_auth': 'enable',
'forward_server_affinity_timeout': '5',
'learn_client_ip': 'enable',
'learn_client_ip_from_header': 'true-client-ip',
'max_message_length': '8',
'max_request_length': '9',
'max_waf_body_cache_length': '10',
'proxy_fqdn': 'test_value_11',
'strict_web_check': 'enable',
'tunnel_non_http': 'enable',
'unknown_http_version': 'reject',
'webproxy_profile': 'test_value_15'
},
'vdom': 'root'}
is_error, changed, response = fortios_web_proxy_global.fortios_web_proxy(input_data, fos_instance)
expected_data = {
'fast-policy-match': 'enable',
'forward-proxy-auth': 'enable',
'forward-server-affinity-timeout': '5',
'learn-client-ip': 'enable',
'learn-client-ip-from-header': 'true-client-ip',
'max-message-length': '8',
'max-request-length': '9',
'max-waf-body-cache-length': '10',
'proxy-fqdn': 'test_value_11',
'strict-web-check': 'enable',
'tunnel-non-http': 'enable',
'unknown-http-version': 'reject',
'webproxy-profile': 'test_value_15'
}
set_method_mock.assert_called_with('web-proxy', 'global', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,289 @@
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_web_proxy_profile
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_web_proxy_profile.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_web_proxy_profile_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'web_proxy_profile': {
'header_client_ip': 'pass',
'header_front_end_https': 'pass',
'header_via_request': 'pass',
'header_via_response': 'pass',
'header_x_authenticated_groups': 'pass',
'header_x_authenticated_user': 'pass',
'header_x_forwarded_for': 'pass',
'log_header_change': 'enable',
'name': 'default_name_11',
'strip_encoding': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_web_proxy_profile.fortios_web_proxy(input_data, fos_instance)
expected_data = {
'header-client-ip': 'pass',
'header-front-end-https': 'pass',
'header-via-request': 'pass',
'header-via-response': 'pass',
'header-x-authenticated-groups': 'pass',
'header-x-authenticated-user': 'pass',
'header-x-forwarded-for': 'pass',
'log-header-change': 'enable',
'name': 'default_name_11',
'strip-encoding': 'enable'
}
set_method_mock.assert_called_with('web-proxy', 'profile', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_web_proxy_profile_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'web_proxy_profile': {
'header_client_ip': 'pass',
'header_front_end_https': 'pass',
'header_via_request': 'pass',
'header_via_response': 'pass',
'header_x_authenticated_groups': 'pass',
'header_x_authenticated_user': 'pass',
'header_x_forwarded_for': 'pass',
'log_header_change': 'enable',
'name': 'default_name_11',
'strip_encoding': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_web_proxy_profile.fortios_web_proxy(input_data, fos_instance)
expected_data = {
'header-client-ip': 'pass',
'header-front-end-https': 'pass',
'header-via-request': 'pass',
'header-via-response': 'pass',
'header-x-authenticated-groups': 'pass',
'header-x-authenticated-user': 'pass',
'header-x-forwarded-for': 'pass',
'log-header-change': 'enable',
'name': 'default_name_11',
'strip-encoding': 'enable'
}
set_method_mock.assert_called_with('web-proxy', 'profile', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_web_proxy_profile_removal(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'web_proxy_profile': {
'header_client_ip': 'pass',
'header_front_end_https': 'pass',
'header_via_request': 'pass',
'header_via_response': 'pass',
'header_x_authenticated_groups': 'pass',
'header_x_authenticated_user': 'pass',
'header_x_forwarded_for': 'pass',
'log_header_change': 'enable',
'name': 'default_name_11',
'strip_encoding': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_web_proxy_profile.fortios_web_proxy(input_data, fos_instance)
delete_method_mock.assert_called_with('web-proxy', 'profile', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_web_proxy_profile_deletion_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'web_proxy_profile': {
'header_client_ip': 'pass',
'header_front_end_https': 'pass',
'header_via_request': 'pass',
'header_via_response': 'pass',
'header_x_authenticated_groups': 'pass',
'header_x_authenticated_user': 'pass',
'header_x_forwarded_for': 'pass',
'log_header_change': 'enable',
'name': 'default_name_11',
'strip_encoding': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_web_proxy_profile.fortios_web_proxy(input_data, fos_instance)
delete_method_mock.assert_called_with('web-proxy', 'profile', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_web_proxy_profile_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'web_proxy_profile': {
'header_client_ip': 'pass',
'header_front_end_https': 'pass',
'header_via_request': 'pass',
'header_via_response': 'pass',
'header_x_authenticated_groups': 'pass',
'header_x_authenticated_user': 'pass',
'header_x_forwarded_for': 'pass',
'log_header_change': 'enable',
'name': 'default_name_11',
'strip_encoding': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_web_proxy_profile.fortios_web_proxy(input_data, fos_instance)
expected_data = {
'header-client-ip': 'pass',
'header-front-end-https': 'pass',
'header-via-request': 'pass',
'header-via-response': 'pass',
'header-x-authenticated-groups': 'pass',
'header-x-authenticated-user': 'pass',
'header-x-forwarded-for': 'pass',
'log-header-change': 'enable',
'name': 'default_name_11',
'strip-encoding': 'enable'
}
set_method_mock.assert_called_with('web-proxy', 'profile', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_web_proxy_profile_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'web_proxy_profile': {
'random_attribute_not_valid': 'tag',
'header_client_ip': 'pass',
'header_front_end_https': 'pass',
'header_via_request': 'pass',
'header_via_response': 'pass',
'header_x_authenticated_groups': 'pass',
'header_x_authenticated_user': 'pass',
'header_x_forwarded_for': 'pass',
'log_header_change': 'enable',
'name': 'default_name_11',
'strip_encoding': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_web_proxy_profile.fortios_web_proxy(input_data, fos_instance)
expected_data = {
'header-client-ip': 'pass',
'header-front-end-https': 'pass',
'header-via-request': 'pass',
'header-via-response': 'pass',
'header-x-authenticated-groups': 'pass',
'header-x-authenticated-user': 'pass',
'header-x-forwarded-for': 'pass',
'log-header-change': 'enable',
'name': 'default_name_11',
'strip-encoding': 'enable'
}
set_method_mock.assert_called_with('web-proxy', 'profile', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,231 @@
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_webfilter_fortiguard
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_webfilter_fortiguard.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_webfilter_fortiguard_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_fortiguard': {
'cache_mem_percent': '3',
'cache_mode': 'ttl',
'cache_prefix_match': 'enable',
'close_ports': 'enable',
'ovrd_auth_https': 'enable',
'ovrd_auth_port': '8',
'ovrd_auth_port_http': '9',
'ovrd_auth_port_https': '10',
'ovrd_auth_port_warning': '11',
'request_packet_size_limit': '12',
'warn_auth_https': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_fortiguard.fortios_webfilter(input_data, fos_instance)
expected_data = {
'cache-mem-percent': '3',
'cache-mode': 'ttl',
'cache-prefix-match': 'enable',
'close-ports': 'enable',
'ovrd-auth-https': 'enable',
'ovrd-auth-port': '8',
'ovrd-auth-port-http': '9',
'ovrd-auth-port-https': '10',
'ovrd-auth-port-warning': '11',
'request-packet-size-limit': '12',
'warn-auth-https': 'enable'
}
set_method_mock.assert_called_with('webfilter', 'fortiguard', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_webfilter_fortiguard_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_fortiguard': {
'cache_mem_percent': '3',
'cache_mode': 'ttl',
'cache_prefix_match': 'enable',
'close_ports': 'enable',
'ovrd_auth_https': 'enable',
'ovrd_auth_port': '8',
'ovrd_auth_port_http': '9',
'ovrd_auth_port_https': '10',
'ovrd_auth_port_warning': '11',
'request_packet_size_limit': '12',
'warn_auth_https': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_fortiguard.fortios_webfilter(input_data, fos_instance)
expected_data = {
'cache-mem-percent': '3',
'cache-mode': 'ttl',
'cache-prefix-match': 'enable',
'close-ports': 'enable',
'ovrd-auth-https': 'enable',
'ovrd-auth-port': '8',
'ovrd-auth-port-http': '9',
'ovrd-auth-port-https': '10',
'ovrd-auth-port-warning': '11',
'request-packet-size-limit': '12',
'warn-auth-https': 'enable'
}
set_method_mock.assert_called_with('webfilter', 'fortiguard', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_webfilter_fortiguard_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_fortiguard': {
'cache_mem_percent': '3',
'cache_mode': 'ttl',
'cache_prefix_match': 'enable',
'close_ports': 'enable',
'ovrd_auth_https': 'enable',
'ovrd_auth_port': '8',
'ovrd_auth_port_http': '9',
'ovrd_auth_port_https': '10',
'ovrd_auth_port_warning': '11',
'request_packet_size_limit': '12',
'warn_auth_https': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_fortiguard.fortios_webfilter(input_data, fos_instance)
expected_data = {
'cache-mem-percent': '3',
'cache-mode': 'ttl',
'cache-prefix-match': 'enable',
'close-ports': 'enable',
'ovrd-auth-https': 'enable',
'ovrd-auth-port': '8',
'ovrd-auth-port-http': '9',
'ovrd-auth-port-https': '10',
'ovrd-auth-port-warning': '11',
'request-packet-size-limit': '12',
'warn-auth-https': 'enable'
}
set_method_mock.assert_called_with('webfilter', 'fortiguard', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_webfilter_fortiguard_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_fortiguard': {
'random_attribute_not_valid': 'tag',
'cache_mem_percent': '3',
'cache_mode': 'ttl',
'cache_prefix_match': 'enable',
'close_ports': 'enable',
'ovrd_auth_https': 'enable',
'ovrd_auth_port': '8',
'ovrd_auth_port_http': '9',
'ovrd_auth_port_https': '10',
'ovrd_auth_port_warning': '11',
'request_packet_size_limit': '12',
'warn_auth_https': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_fortiguard.fortios_webfilter(input_data, fos_instance)
expected_data = {
'cache-mem-percent': '3',
'cache-mode': 'ttl',
'cache-prefix-match': 'enable',
'close-ports': 'enable',
'ovrd-auth-https': 'enable',
'ovrd-auth-port': '8',
'ovrd-auth-port-http': '9',
'ovrd-auth-port-https': '10',
'ovrd-auth-port-warning': '11',
'request-packet-size-limit': '12',
'warn-auth-https': 'enable'
}
set_method_mock.assert_called_with('webfilter', 'fortiguard', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,219 @@
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_webfilter_ftgd_local_cat
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_webfilter_ftgd_local_cat.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_webfilter_ftgd_local_cat_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_ftgd_local_cat': {
'desc': 'test_value_3',
'id': '4',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_ftgd_local_cat.fortios_webfilter(input_data, fos_instance)
expected_data = {
'desc': 'test_value_3',
'id': '4',
'status': 'enable'
}
set_method_mock.assert_called_with('webfilter', 'ftgd-local-cat', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_webfilter_ftgd_local_cat_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_ftgd_local_cat': {
'desc': 'test_value_3',
'id': '4',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_ftgd_local_cat.fortios_webfilter(input_data, fos_instance)
expected_data = {
'desc': 'test_value_3',
'id': '4',
'status': 'enable'
}
set_method_mock.assert_called_with('webfilter', 'ftgd-local-cat', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_webfilter_ftgd_local_cat_removal(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'webfilter_ftgd_local_cat': {
'desc': 'test_value_3',
'id': '4',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_ftgd_local_cat.fortios_webfilter(input_data, fos_instance)
delete_method_mock.assert_called_with('webfilter', 'ftgd-local-cat', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_webfilter_ftgd_local_cat_deletion_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'webfilter_ftgd_local_cat': {
'desc': 'test_value_3',
'id': '4',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_ftgd_local_cat.fortios_webfilter(input_data, fos_instance)
delete_method_mock.assert_called_with('webfilter', 'ftgd-local-cat', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_webfilter_ftgd_local_cat_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_ftgd_local_cat': {
'desc': 'test_value_3',
'id': '4',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_ftgd_local_cat.fortios_webfilter(input_data, fos_instance)
expected_data = {
'desc': 'test_value_3',
'id': '4',
'status': 'enable'
}
set_method_mock.assert_called_with('webfilter', 'ftgd-local-cat', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_webfilter_ftgd_local_cat_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_ftgd_local_cat': {
'random_attribute_not_valid': 'tag',
'desc': 'test_value_3',
'id': '4',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_ftgd_local_cat.fortios_webfilter(input_data, fos_instance)
expected_data = {
'desc': 'test_value_3',
'id': '4',
'status': 'enable'
}
set_method_mock.assert_called_with('webfilter', 'ftgd-local-cat', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,219 @@
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_webfilter_ftgd_local_rating
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_webfilter_ftgd_local_rating.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_webfilter_ftgd_local_rating_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_ftgd_local_rating': {
'rating': 'test_value_3',
'status': 'enable',
'url': 'myurl_5.com'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_ftgd_local_rating.fortios_webfilter(input_data, fos_instance)
expected_data = {
'rating': 'test_value_3',
'status': 'enable',
'url': 'myurl_5.com'
}
set_method_mock.assert_called_with('webfilter', 'ftgd-local-rating', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_webfilter_ftgd_local_rating_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_ftgd_local_rating': {
'rating': 'test_value_3',
'status': 'enable',
'url': 'myurl_5.com'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_ftgd_local_rating.fortios_webfilter(input_data, fos_instance)
expected_data = {
'rating': 'test_value_3',
'status': 'enable',
'url': 'myurl_5.com'
}
set_method_mock.assert_called_with('webfilter', 'ftgd-local-rating', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_webfilter_ftgd_local_rating_removal(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'webfilter_ftgd_local_rating': {
'rating': 'test_value_3',
'status': 'enable',
'url': 'myurl_5.com'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_ftgd_local_rating.fortios_webfilter(input_data, fos_instance)
delete_method_mock.assert_called_with('webfilter', 'ftgd-local-rating', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_webfilter_ftgd_local_rating_deletion_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'webfilter_ftgd_local_rating': {
'rating': 'test_value_3',
'status': 'enable',
'url': 'myurl_5.com'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_ftgd_local_rating.fortios_webfilter(input_data, fos_instance)
delete_method_mock.assert_called_with('webfilter', 'ftgd-local-rating', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_webfilter_ftgd_local_rating_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_ftgd_local_rating': {
'rating': 'test_value_3',
'status': 'enable',
'url': 'myurl_5.com'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_ftgd_local_rating.fortios_webfilter(input_data, fos_instance)
expected_data = {
'rating': 'test_value_3',
'status': 'enable',
'url': 'myurl_5.com'
}
set_method_mock.assert_called_with('webfilter', 'ftgd-local-rating', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_webfilter_ftgd_local_rating_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_ftgd_local_rating': {
'random_attribute_not_valid': 'tag',
'rating': 'test_value_3',
'status': 'enable',
'url': 'myurl_5.com'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_ftgd_local_rating.fortios_webfilter(input_data, fos_instance)
expected_data = {
'rating': 'test_value_3',
'status': 'enable',
'url': 'myurl_5.com'
}
set_method_mock.assert_called_with('webfilter', 'ftgd-local-rating', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,159 @@
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_webfilter_ips_urlfilter_cache_setting
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_webfilter_ips_urlfilter_cache_setting.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_webfilter_ips_urlfilter_cache_setting_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_ips_urlfilter_cache_setting': {
'dns_retry_interval': '3',
'extended_ttl': '4'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_ips_urlfilter_cache_setting.fortios_webfilter(input_data, fos_instance)
expected_data = {
'dns-retry-interval': '3',
'extended-ttl': '4'
}
set_method_mock.assert_called_with('webfilter', 'ips-urlfilter-cache-setting', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_webfilter_ips_urlfilter_cache_setting_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_ips_urlfilter_cache_setting': {
'dns_retry_interval': '3',
'extended_ttl': '4'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_ips_urlfilter_cache_setting.fortios_webfilter(input_data, fos_instance)
expected_data = {
'dns-retry-interval': '3',
'extended-ttl': '4'
}
set_method_mock.assert_called_with('webfilter', 'ips-urlfilter-cache-setting', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_webfilter_ips_urlfilter_cache_setting_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_ips_urlfilter_cache_setting': {
'dns_retry_interval': '3',
'extended_ttl': '4'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_ips_urlfilter_cache_setting.fortios_webfilter(input_data, fos_instance)
expected_data = {
'dns-retry-interval': '3',
'extended-ttl': '4'
}
set_method_mock.assert_called_with('webfilter', 'ips-urlfilter-cache-setting', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_webfilter_ips_urlfilter_cache_setting_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_ips_urlfilter_cache_setting': {
'random_attribute_not_valid': 'tag',
'dns_retry_interval': '3',
'extended_ttl': '4'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_ips_urlfilter_cache_setting.fortios_webfilter(input_data, fos_instance)
expected_data = {
'dns-retry-interval': '3',
'extended-ttl': '4'
}
set_method_mock.assert_called_with('webfilter', 'ips-urlfilter-cache-setting', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,175 @@
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_webfilter_ips_urlfilter_setting
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_webfilter_ips_urlfilter_setting.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_webfilter_ips_urlfilter_setting_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_ips_urlfilter_setting': {
'device': 'test_value_3',
'distance': '4',
'gateway': 'test_value_5',
'geo_filter': 'test_value_6'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_ips_urlfilter_setting.fortios_webfilter(input_data, fos_instance)
expected_data = {
'device': 'test_value_3',
'distance': '4',
'gateway': 'test_value_5',
'geo-filter': 'test_value_6'
}
set_method_mock.assert_called_with('webfilter', 'ips-urlfilter-setting', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_webfilter_ips_urlfilter_setting_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_ips_urlfilter_setting': {
'device': 'test_value_3',
'distance': '4',
'gateway': 'test_value_5',
'geo_filter': 'test_value_6'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_ips_urlfilter_setting.fortios_webfilter(input_data, fos_instance)
expected_data = {
'device': 'test_value_3',
'distance': '4',
'gateway': 'test_value_5',
'geo-filter': 'test_value_6'
}
set_method_mock.assert_called_with('webfilter', 'ips-urlfilter-setting', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_webfilter_ips_urlfilter_setting_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_ips_urlfilter_setting': {
'device': 'test_value_3',
'distance': '4',
'gateway': 'test_value_5',
'geo_filter': 'test_value_6'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_ips_urlfilter_setting.fortios_webfilter(input_data, fos_instance)
expected_data = {
'device': 'test_value_3',
'distance': '4',
'gateway': 'test_value_5',
'geo-filter': 'test_value_6'
}
set_method_mock.assert_called_with('webfilter', 'ips-urlfilter-setting', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_webfilter_ips_urlfilter_setting_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_ips_urlfilter_setting': {
'random_attribute_not_valid': 'tag',
'device': 'test_value_3',
'distance': '4',
'gateway': 'test_value_5',
'geo_filter': 'test_value_6'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_ips_urlfilter_setting.fortios_webfilter(input_data, fos_instance)
expected_data = {
'device': 'test_value_3',
'distance': '4',
'gateway': 'test_value_5',
'geo-filter': 'test_value_6'
}
set_method_mock.assert_called_with('webfilter', 'ips-urlfilter-setting', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,175 @@
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_webfilter_ips_urlfilter_setting6
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_webfilter_ips_urlfilter_setting6.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_webfilter_ips_urlfilter_setting6_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_ips_urlfilter_setting6': {
'device': 'test_value_3',
'distance': '4',
'gateway6': 'test_value_5',
'geo_filter': 'test_value_6'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_ips_urlfilter_setting6.fortios_webfilter(input_data, fos_instance)
expected_data = {
'device': 'test_value_3',
'distance': '4',
'gateway6': 'test_value_5',
'geo-filter': 'test_value_6'
}
set_method_mock.assert_called_with('webfilter', 'ips-urlfilter-setting6', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_webfilter_ips_urlfilter_setting6_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_ips_urlfilter_setting6': {
'device': 'test_value_3',
'distance': '4',
'gateway6': 'test_value_5',
'geo_filter': 'test_value_6'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_ips_urlfilter_setting6.fortios_webfilter(input_data, fos_instance)
expected_data = {
'device': 'test_value_3',
'distance': '4',
'gateway6': 'test_value_5',
'geo-filter': 'test_value_6'
}
set_method_mock.assert_called_with('webfilter', 'ips-urlfilter-setting6', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_webfilter_ips_urlfilter_setting6_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_ips_urlfilter_setting6': {
'device': 'test_value_3',
'distance': '4',
'gateway6': 'test_value_5',
'geo_filter': 'test_value_6'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_ips_urlfilter_setting6.fortios_webfilter(input_data, fos_instance)
expected_data = {
'device': 'test_value_3',
'distance': '4',
'gateway6': 'test_value_5',
'geo-filter': 'test_value_6'
}
set_method_mock.assert_called_with('webfilter', 'ips-urlfilter-setting6', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_webfilter_ips_urlfilter_setting6_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_ips_urlfilter_setting6': {
'random_attribute_not_valid': 'tag',
'device': 'test_value_3',
'distance': '4',
'gateway6': 'test_value_5',
'geo_filter': 'test_value_6'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_ips_urlfilter_setting6.fortios_webfilter(input_data, fos_instance)
expected_data = {
'device': 'test_value_3',
'distance': '4',
'gateway6': 'test_value_5',
'geo-filter': 'test_value_6'
}
set_method_mock.assert_called_with('webfilter', 'ips-urlfilter-setting6', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,299 @@
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_webfilter_override
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_webfilter_override.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_webfilter_override_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_override': {
'expires': 'test_value_3',
'id': '4',
'initiator': 'test_value_5',
'ip': 'test_value_6',
'ip6': 'test_value_7',
'new_profile': 'test_value_8',
'old_profile': 'test_value_9',
'scope': 'user',
'status': 'enable',
'user': 'test_value_12',
'user_group': 'test_value_13'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_override.fortios_webfilter(input_data, fos_instance)
expected_data = {
'expires': 'test_value_3',
'id': '4',
'initiator': 'test_value_5',
'ip': 'test_value_6',
'ip6': 'test_value_7',
'new-profile': 'test_value_8',
'old-profile': 'test_value_9',
'scope': 'user',
'status': 'enable',
'user': 'test_value_12',
'user-group': 'test_value_13'
}
set_method_mock.assert_called_with('webfilter', 'override', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_webfilter_override_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_override': {
'expires': 'test_value_3',
'id': '4',
'initiator': 'test_value_5',
'ip': 'test_value_6',
'ip6': 'test_value_7',
'new_profile': 'test_value_8',
'old_profile': 'test_value_9',
'scope': 'user',
'status': 'enable',
'user': 'test_value_12',
'user_group': 'test_value_13'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_override.fortios_webfilter(input_data, fos_instance)
expected_data = {
'expires': 'test_value_3',
'id': '4',
'initiator': 'test_value_5',
'ip': 'test_value_6',
'ip6': 'test_value_7',
'new-profile': 'test_value_8',
'old-profile': 'test_value_9',
'scope': 'user',
'status': 'enable',
'user': 'test_value_12',
'user-group': 'test_value_13'
}
set_method_mock.assert_called_with('webfilter', 'override', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_webfilter_override_removal(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'webfilter_override': {
'expires': 'test_value_3',
'id': '4',
'initiator': 'test_value_5',
'ip': 'test_value_6',
'ip6': 'test_value_7',
'new_profile': 'test_value_8',
'old_profile': 'test_value_9',
'scope': 'user',
'status': 'enable',
'user': 'test_value_12',
'user_group': 'test_value_13'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_override.fortios_webfilter(input_data, fos_instance)
delete_method_mock.assert_called_with('webfilter', 'override', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_webfilter_override_deletion_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'webfilter_override': {
'expires': 'test_value_3',
'id': '4',
'initiator': 'test_value_5',
'ip': 'test_value_6',
'ip6': 'test_value_7',
'new_profile': 'test_value_8',
'old_profile': 'test_value_9',
'scope': 'user',
'status': 'enable',
'user': 'test_value_12',
'user_group': 'test_value_13'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_override.fortios_webfilter(input_data, fos_instance)
delete_method_mock.assert_called_with('webfilter', 'override', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_webfilter_override_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_override': {
'expires': 'test_value_3',
'id': '4',
'initiator': 'test_value_5',
'ip': 'test_value_6',
'ip6': 'test_value_7',
'new_profile': 'test_value_8',
'old_profile': 'test_value_9',
'scope': 'user',
'status': 'enable',
'user': 'test_value_12',
'user_group': 'test_value_13'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_override.fortios_webfilter(input_data, fos_instance)
expected_data = {
'expires': 'test_value_3',
'id': '4',
'initiator': 'test_value_5',
'ip': 'test_value_6',
'ip6': 'test_value_7',
'new-profile': 'test_value_8',
'old-profile': 'test_value_9',
'scope': 'user',
'status': 'enable',
'user': 'test_value_12',
'user-group': 'test_value_13'
}
set_method_mock.assert_called_with('webfilter', 'override', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_webfilter_override_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_override': {
'random_attribute_not_valid': 'tag',
'expires': 'test_value_3',
'id': '4',
'initiator': 'test_value_5',
'ip': 'test_value_6',
'ip6': 'test_value_7',
'new_profile': 'test_value_8',
'old_profile': 'test_value_9',
'scope': 'user',
'status': 'enable',
'user': 'test_value_12',
'user_group': 'test_value_13'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_override.fortios_webfilter(input_data, fos_instance)
expected_data = {
'expires': 'test_value_3',
'id': '4',
'initiator': 'test_value_5',
'ip': 'test_value_6',
'ip6': 'test_value_7',
'new-profile': 'test_value_8',
'old-profile': 'test_value_9',
'scope': 'user',
'status': 'enable',
'user': 'test_value_12',
'user-group': 'test_value_13'
}
set_method_mock.assert_called_with('webfilter', 'override', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,479 @@
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_webfilter_profile
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_webfilter_profile.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_webfilter_profile_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_profile': {
'comment': 'Optional comments.',
'extended_log': 'enable',
'https_replacemsg': 'enable',
'inspection_mode': 'proxy',
'log_all_url': 'enable',
'name': 'default_name_8',
'options': 'activexfilter',
'ovrd_perm': 'bannedword-override',
'post_action': 'normal',
'replacemsg_group': 'test_value_12',
'web_content_log': 'enable',
'web_extended_all_action_log': 'enable',
'web_filter_activex_log': 'enable',
'web_filter_applet_log': 'enable',
'web_filter_command_block_log': 'enable',
'web_filter_cookie_log': 'enable',
'web_filter_cookie_removal_log': 'enable',
'web_filter_js_log': 'enable',
'web_filter_jscript_log': 'enable',
'web_filter_referer_log': 'enable',
'web_filter_unknown_log': 'enable',
'web_filter_vbs_log': 'enable',
'web_ftgd_err_log': 'enable',
'web_ftgd_quota_usage': 'enable',
'web_invalid_domain_log': 'enable',
'web_url_log': 'enable',
'wisp': 'enable',
'wisp_algorithm': 'primary-secondary',
'youtube_channel_status': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_profile.fortios_webfilter(input_data, fos_instance)
expected_data = {
'comment': 'Optional comments.',
'extended-log': 'enable',
'https-replacemsg': 'enable',
'inspection-mode': 'proxy',
'log-all-url': 'enable',
'name': 'default_name_8',
'options': 'activexfilter',
'ovrd-perm': 'bannedword-override',
'post-action': 'normal',
'replacemsg-group': 'test_value_12',
'web-content-log': 'enable',
'web-extended-all-action-log': 'enable',
'web-filter-activex-log': 'enable',
'web-filter-applet-log': 'enable',
'web-filter-command-block-log': 'enable',
'web-filter-cookie-log': 'enable',
'web-filter-cookie-removal-log': 'enable',
'web-filter-js-log': 'enable',
'web-filter-jscript-log': 'enable',
'web-filter-referer-log': 'enable',
'web-filter-unknown-log': 'enable',
'web-filter-vbs-log': 'enable',
'web-ftgd-err-log': 'enable',
'web-ftgd-quota-usage': 'enable',
'web-invalid-domain-log': 'enable',
'web-url-log': 'enable',
'wisp': 'enable',
'wisp-algorithm': 'primary-secondary',
'youtube-channel-status': 'disable'
}
set_method_mock.assert_called_with('webfilter', 'profile', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_webfilter_profile_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_profile': {
'comment': 'Optional comments.',
'extended_log': 'enable',
'https_replacemsg': 'enable',
'inspection_mode': 'proxy',
'log_all_url': 'enable',
'name': 'default_name_8',
'options': 'activexfilter',
'ovrd_perm': 'bannedword-override',
'post_action': 'normal',
'replacemsg_group': 'test_value_12',
'web_content_log': 'enable',
'web_extended_all_action_log': 'enable',
'web_filter_activex_log': 'enable',
'web_filter_applet_log': 'enable',
'web_filter_command_block_log': 'enable',
'web_filter_cookie_log': 'enable',
'web_filter_cookie_removal_log': 'enable',
'web_filter_js_log': 'enable',
'web_filter_jscript_log': 'enable',
'web_filter_referer_log': 'enable',
'web_filter_unknown_log': 'enable',
'web_filter_vbs_log': 'enable',
'web_ftgd_err_log': 'enable',
'web_ftgd_quota_usage': 'enable',
'web_invalid_domain_log': 'enable',
'web_url_log': 'enable',
'wisp': 'enable',
'wisp_algorithm': 'primary-secondary',
'youtube_channel_status': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_profile.fortios_webfilter(input_data, fos_instance)
expected_data = {
'comment': 'Optional comments.',
'extended-log': 'enable',
'https-replacemsg': 'enable',
'inspection-mode': 'proxy',
'log-all-url': 'enable',
'name': 'default_name_8',
'options': 'activexfilter',
'ovrd-perm': 'bannedword-override',
'post-action': 'normal',
'replacemsg-group': 'test_value_12',
'web-content-log': 'enable',
'web-extended-all-action-log': 'enable',
'web-filter-activex-log': 'enable',
'web-filter-applet-log': 'enable',
'web-filter-command-block-log': 'enable',
'web-filter-cookie-log': 'enable',
'web-filter-cookie-removal-log': 'enable',
'web-filter-js-log': 'enable',
'web-filter-jscript-log': 'enable',
'web-filter-referer-log': 'enable',
'web-filter-unknown-log': 'enable',
'web-filter-vbs-log': 'enable',
'web-ftgd-err-log': 'enable',
'web-ftgd-quota-usage': 'enable',
'web-invalid-domain-log': 'enable',
'web-url-log': 'enable',
'wisp': 'enable',
'wisp-algorithm': 'primary-secondary',
'youtube-channel-status': 'disable'
}
set_method_mock.assert_called_with('webfilter', 'profile', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_webfilter_profile_removal(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'webfilter_profile': {
'comment': 'Optional comments.',
'extended_log': 'enable',
'https_replacemsg': 'enable',
'inspection_mode': 'proxy',
'log_all_url': 'enable',
'name': 'default_name_8',
'options': 'activexfilter',
'ovrd_perm': 'bannedword-override',
'post_action': 'normal',
'replacemsg_group': 'test_value_12',
'web_content_log': 'enable',
'web_extended_all_action_log': 'enable',
'web_filter_activex_log': 'enable',
'web_filter_applet_log': 'enable',
'web_filter_command_block_log': 'enable',
'web_filter_cookie_log': 'enable',
'web_filter_cookie_removal_log': 'enable',
'web_filter_js_log': 'enable',
'web_filter_jscript_log': 'enable',
'web_filter_referer_log': 'enable',
'web_filter_unknown_log': 'enable',
'web_filter_vbs_log': 'enable',
'web_ftgd_err_log': 'enable',
'web_ftgd_quota_usage': 'enable',
'web_invalid_domain_log': 'enable',
'web_url_log': 'enable',
'wisp': 'enable',
'wisp_algorithm': 'primary-secondary',
'youtube_channel_status': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_profile.fortios_webfilter(input_data, fos_instance)
delete_method_mock.assert_called_with('webfilter', 'profile', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_webfilter_profile_deletion_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'webfilter_profile': {
'comment': 'Optional comments.',
'extended_log': 'enable',
'https_replacemsg': 'enable',
'inspection_mode': 'proxy',
'log_all_url': 'enable',
'name': 'default_name_8',
'options': 'activexfilter',
'ovrd_perm': 'bannedword-override',
'post_action': 'normal',
'replacemsg_group': 'test_value_12',
'web_content_log': 'enable',
'web_extended_all_action_log': 'enable',
'web_filter_activex_log': 'enable',
'web_filter_applet_log': 'enable',
'web_filter_command_block_log': 'enable',
'web_filter_cookie_log': 'enable',
'web_filter_cookie_removal_log': 'enable',
'web_filter_js_log': 'enable',
'web_filter_jscript_log': 'enable',
'web_filter_referer_log': 'enable',
'web_filter_unknown_log': 'enable',
'web_filter_vbs_log': 'enable',
'web_ftgd_err_log': 'enable',
'web_ftgd_quota_usage': 'enable',
'web_invalid_domain_log': 'enable',
'web_url_log': 'enable',
'wisp': 'enable',
'wisp_algorithm': 'primary-secondary',
'youtube_channel_status': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_profile.fortios_webfilter(input_data, fos_instance)
delete_method_mock.assert_called_with('webfilter', 'profile', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_webfilter_profile_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_profile': {
'comment': 'Optional comments.',
'extended_log': 'enable',
'https_replacemsg': 'enable',
'inspection_mode': 'proxy',
'log_all_url': 'enable',
'name': 'default_name_8',
'options': 'activexfilter',
'ovrd_perm': 'bannedword-override',
'post_action': 'normal',
'replacemsg_group': 'test_value_12',
'web_content_log': 'enable',
'web_extended_all_action_log': 'enable',
'web_filter_activex_log': 'enable',
'web_filter_applet_log': 'enable',
'web_filter_command_block_log': 'enable',
'web_filter_cookie_log': 'enable',
'web_filter_cookie_removal_log': 'enable',
'web_filter_js_log': 'enable',
'web_filter_jscript_log': 'enable',
'web_filter_referer_log': 'enable',
'web_filter_unknown_log': 'enable',
'web_filter_vbs_log': 'enable',
'web_ftgd_err_log': 'enable',
'web_ftgd_quota_usage': 'enable',
'web_invalid_domain_log': 'enable',
'web_url_log': 'enable',
'wisp': 'enable',
'wisp_algorithm': 'primary-secondary',
'youtube_channel_status': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_profile.fortios_webfilter(input_data, fos_instance)
expected_data = {
'comment': 'Optional comments.',
'extended-log': 'enable',
'https-replacemsg': 'enable',
'inspection-mode': 'proxy',
'log-all-url': 'enable',
'name': 'default_name_8',
'options': 'activexfilter',
'ovrd-perm': 'bannedword-override',
'post-action': 'normal',
'replacemsg-group': 'test_value_12',
'web-content-log': 'enable',
'web-extended-all-action-log': 'enable',
'web-filter-activex-log': 'enable',
'web-filter-applet-log': 'enable',
'web-filter-command-block-log': 'enable',
'web-filter-cookie-log': 'enable',
'web-filter-cookie-removal-log': 'enable',
'web-filter-js-log': 'enable',
'web-filter-jscript-log': 'enable',
'web-filter-referer-log': 'enable',
'web-filter-unknown-log': 'enable',
'web-filter-vbs-log': 'enable',
'web-ftgd-err-log': 'enable',
'web-ftgd-quota-usage': 'enable',
'web-invalid-domain-log': 'enable',
'web-url-log': 'enable',
'wisp': 'enable',
'wisp-algorithm': 'primary-secondary',
'youtube-channel-status': 'disable'
}
set_method_mock.assert_called_with('webfilter', 'profile', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_webfilter_profile_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_profile': {
'random_attribute_not_valid': 'tag',
'comment': 'Optional comments.',
'extended_log': 'enable',
'https_replacemsg': 'enable',
'inspection_mode': 'proxy',
'log_all_url': 'enable',
'name': 'default_name_8',
'options': 'activexfilter',
'ovrd_perm': 'bannedword-override',
'post_action': 'normal',
'replacemsg_group': 'test_value_12',
'web_content_log': 'enable',
'web_extended_all_action_log': 'enable',
'web_filter_activex_log': 'enable',
'web_filter_applet_log': 'enable',
'web_filter_command_block_log': 'enable',
'web_filter_cookie_log': 'enable',
'web_filter_cookie_removal_log': 'enable',
'web_filter_js_log': 'enable',
'web_filter_jscript_log': 'enable',
'web_filter_referer_log': 'enable',
'web_filter_unknown_log': 'enable',
'web_filter_vbs_log': 'enable',
'web_ftgd_err_log': 'enable',
'web_ftgd_quota_usage': 'enable',
'web_invalid_domain_log': 'enable',
'web_url_log': 'enable',
'wisp': 'enable',
'wisp_algorithm': 'primary-secondary',
'youtube_channel_status': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_profile.fortios_webfilter(input_data, fos_instance)
expected_data = {
'comment': 'Optional comments.',
'extended-log': 'enable',
'https-replacemsg': 'enable',
'inspection-mode': 'proxy',
'log-all-url': 'enable',
'name': 'default_name_8',
'options': 'activexfilter',
'ovrd-perm': 'bannedword-override',
'post-action': 'normal',
'replacemsg-group': 'test_value_12',
'web-content-log': 'enable',
'web-extended-all-action-log': 'enable',
'web-filter-activex-log': 'enable',
'web-filter-applet-log': 'enable',
'web-filter-command-block-log': 'enable',
'web-filter-cookie-log': 'enable',
'web-filter-cookie-removal-log': 'enable',
'web-filter-js-log': 'enable',
'web-filter-jscript-log': 'enable',
'web-filter-referer-log': 'enable',
'web-filter-unknown-log': 'enable',
'web-filter-vbs-log': 'enable',
'web-ftgd-err-log': 'enable',
'web-ftgd-quota-usage': 'enable',
'web-invalid-domain-log': 'enable',
'web-url-log': 'enable',
'wisp': 'enable',
'wisp-algorithm': 'primary-secondary',
'youtube-channel-status': 'disable'
}
set_method_mock.assert_called_with('webfilter', 'profile', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,259 @@
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_webfilter_search_engine
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_webfilter_search_engine.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_webfilter_search_engine_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_search_engine': {
'charset': 'utf-8',
'hostname': 'myhostname4',
'name': 'default_name_5',
'query': 'test_value_6',
'safesearch': 'disable',
'safesearch_str': 'test_value_8',
'url': 'myurl_9.com'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_search_engine.fortios_webfilter(input_data, fos_instance)
expected_data = {
'charset': 'utf-8',
'hostname': 'myhostname4',
'name': 'default_name_5',
'query': 'test_value_6',
'safesearch': 'disable',
'safesearch-str': 'test_value_8',
'url': 'myurl_9.com'
}
set_method_mock.assert_called_with('webfilter', 'search-engine', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_webfilter_search_engine_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_search_engine': {
'charset': 'utf-8',
'hostname': 'myhostname4',
'name': 'default_name_5',
'query': 'test_value_6',
'safesearch': 'disable',
'safesearch_str': 'test_value_8',
'url': 'myurl_9.com'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_search_engine.fortios_webfilter(input_data, fos_instance)
expected_data = {
'charset': 'utf-8',
'hostname': 'myhostname4',
'name': 'default_name_5',
'query': 'test_value_6',
'safesearch': 'disable',
'safesearch-str': 'test_value_8',
'url': 'myurl_9.com'
}
set_method_mock.assert_called_with('webfilter', 'search-engine', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_webfilter_search_engine_removal(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'webfilter_search_engine': {
'charset': 'utf-8',
'hostname': 'myhostname4',
'name': 'default_name_5',
'query': 'test_value_6',
'safesearch': 'disable',
'safesearch_str': 'test_value_8',
'url': 'myurl_9.com'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_search_engine.fortios_webfilter(input_data, fos_instance)
delete_method_mock.assert_called_with('webfilter', 'search-engine', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_webfilter_search_engine_deletion_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'webfilter_search_engine': {
'charset': 'utf-8',
'hostname': 'myhostname4',
'name': 'default_name_5',
'query': 'test_value_6',
'safesearch': 'disable',
'safesearch_str': 'test_value_8',
'url': 'myurl_9.com'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_search_engine.fortios_webfilter(input_data, fos_instance)
delete_method_mock.assert_called_with('webfilter', 'search-engine', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_webfilter_search_engine_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_search_engine': {
'charset': 'utf-8',
'hostname': 'myhostname4',
'name': 'default_name_5',
'query': 'test_value_6',
'safesearch': 'disable',
'safesearch_str': 'test_value_8',
'url': 'myurl_9.com'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_search_engine.fortios_webfilter(input_data, fos_instance)
expected_data = {
'charset': 'utf-8',
'hostname': 'myhostname4',
'name': 'default_name_5',
'query': 'test_value_6',
'safesearch': 'disable',
'safesearch-str': 'test_value_8',
'url': 'myurl_9.com'
}
set_method_mock.assert_called_with('webfilter', 'search-engine', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_webfilter_search_engine_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_search_engine': {
'random_attribute_not_valid': 'tag',
'charset': 'utf-8',
'hostname': 'myhostname4',
'name': 'default_name_5',
'query': 'test_value_6',
'safesearch': 'disable',
'safesearch_str': 'test_value_8',
'url': 'myurl_9.com'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_search_engine.fortios_webfilter(input_data, fos_instance)
expected_data = {
'charset': 'utf-8',
'hostname': 'myhostname4',
'name': 'default_name_5',
'query': 'test_value_6',
'safesearch': 'disable',
'safesearch-str': 'test_value_8',
'url': 'myurl_9.com'
}
set_method_mock.assert_called_with('webfilter', 'search-engine', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,239 @@
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_webfilter_urlfilter
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_webfilter_urlfilter.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_webfilter_urlfilter_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_urlfilter': {
'comment': 'Optional comments.',
'id': '4',
'ip_addr_block': 'enable',
'name': 'default_name_6',
'one_arm_ips_urlfilter': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_urlfilter.fortios_webfilter(input_data, fos_instance)
expected_data = {
'comment': 'Optional comments.',
'id': '4',
'ip-addr-block': 'enable',
'name': 'default_name_6',
'one-arm-ips-urlfilter': 'enable'
}
set_method_mock.assert_called_with('webfilter', 'urlfilter', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_webfilter_urlfilter_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_urlfilter': {
'comment': 'Optional comments.',
'id': '4',
'ip_addr_block': 'enable',
'name': 'default_name_6',
'one_arm_ips_urlfilter': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_urlfilter.fortios_webfilter(input_data, fos_instance)
expected_data = {
'comment': 'Optional comments.',
'id': '4',
'ip-addr-block': 'enable',
'name': 'default_name_6',
'one-arm-ips-urlfilter': 'enable'
}
set_method_mock.assert_called_with('webfilter', 'urlfilter', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_webfilter_urlfilter_removal(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'webfilter_urlfilter': {
'comment': 'Optional comments.',
'id': '4',
'ip_addr_block': 'enable',
'name': 'default_name_6',
'one_arm_ips_urlfilter': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_urlfilter.fortios_webfilter(input_data, fos_instance)
delete_method_mock.assert_called_with('webfilter', 'urlfilter', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_webfilter_urlfilter_deletion_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'webfilter_urlfilter': {
'comment': 'Optional comments.',
'id': '4',
'ip_addr_block': 'enable',
'name': 'default_name_6',
'one_arm_ips_urlfilter': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_urlfilter.fortios_webfilter(input_data, fos_instance)
delete_method_mock.assert_called_with('webfilter', 'urlfilter', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_webfilter_urlfilter_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_urlfilter': {
'comment': 'Optional comments.',
'id': '4',
'ip_addr_block': 'enable',
'name': 'default_name_6',
'one_arm_ips_urlfilter': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_urlfilter.fortios_webfilter(input_data, fos_instance)
expected_data = {
'comment': 'Optional comments.',
'id': '4',
'ip-addr-block': 'enable',
'name': 'default_name_6',
'one-arm-ips-urlfilter': 'enable'
}
set_method_mock.assert_called_with('webfilter', 'urlfilter', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_webfilter_urlfilter_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'webfilter_urlfilter': {
'random_attribute_not_valid': 'tag',
'comment': 'Optional comments.',
'id': '4',
'ip_addr_block': 'enable',
'name': 'default_name_6',
'one_arm_ips_urlfilter': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_webfilter_urlfilter.fortios_webfilter(input_data, fos_instance)
expected_data = {
'comment': 'Optional comments.',
'id': '4',
'ip-addr-block': 'enable',
'name': 'default_name_6',
'one-arm-ips-urlfilter': 'enable'
}
set_method_mock.assert_called_with('webfilter', 'urlfilter', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,279 @@
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_wireless_controller_global
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_wireless_controller_global.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_wireless_controller_global_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'wireless_controller_global': {
'ap_log_server': 'enable',
'ap_log_server_ip': 'test_value_4',
'ap_log_server_port': '5',
'control_message_offload': 'ebp-frame',
'data_ethernet_II': 'enable',
'discovery_mc_addr': 'test_value_8',
'fiapp_eth_type': '9',
'image_download': 'enable',
'ipsec_base_ip': 'test_value_11',
'link_aggregation': 'enable',
'location': 'test_value_13',
'max_clients': '14',
'max_retransmit': '15',
'mesh_eth_type': '16',
'name': 'default_name_17',
'rogue_scan_mac_adjacency': '18',
'wtp_share': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_wireless_controller_global.fortios_wireless_controller(input_data, fos_instance)
expected_data = {
'ap-log-server': 'enable',
'ap-log-server-ip': 'test_value_4',
'ap-log-server-port': '5',
'control-message-offload': 'ebp-frame',
'data-ethernet-II': 'enable',
'discovery-mc-addr': 'test_value_8',
'fiapp-eth-type': '9',
'image-download': 'enable',
'ipsec-base-ip': 'test_value_11',
'link-aggregation': 'enable',
'location': 'test_value_13',
'max-clients': '14',
'max-retransmit': '15',
'mesh-eth-type': '16',
'name': 'default_name_17',
'rogue-scan-mac-adjacency': '18',
'wtp-share': 'enable'
}
set_method_mock.assert_called_with('wireless-controller', 'global', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_wireless_controller_global_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'wireless_controller_global': {
'ap_log_server': 'enable',
'ap_log_server_ip': 'test_value_4',
'ap_log_server_port': '5',
'control_message_offload': 'ebp-frame',
'data_ethernet_II': 'enable',
'discovery_mc_addr': 'test_value_8',
'fiapp_eth_type': '9',
'image_download': 'enable',
'ipsec_base_ip': 'test_value_11',
'link_aggregation': 'enable',
'location': 'test_value_13',
'max_clients': '14',
'max_retransmit': '15',
'mesh_eth_type': '16',
'name': 'default_name_17',
'rogue_scan_mac_adjacency': '18',
'wtp_share': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_wireless_controller_global.fortios_wireless_controller(input_data, fos_instance)
expected_data = {
'ap-log-server': 'enable',
'ap-log-server-ip': 'test_value_4',
'ap-log-server-port': '5',
'control-message-offload': 'ebp-frame',
'data-ethernet-II': 'enable',
'discovery-mc-addr': 'test_value_8',
'fiapp-eth-type': '9',
'image-download': 'enable',
'ipsec-base-ip': 'test_value_11',
'link-aggregation': 'enable',
'location': 'test_value_13',
'max-clients': '14',
'max-retransmit': '15',
'mesh-eth-type': '16',
'name': 'default_name_17',
'rogue-scan-mac-adjacency': '18',
'wtp-share': 'enable'
}
set_method_mock.assert_called_with('wireless-controller', 'global', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_wireless_controller_global_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'wireless_controller_global': {
'ap_log_server': 'enable',
'ap_log_server_ip': 'test_value_4',
'ap_log_server_port': '5',
'control_message_offload': 'ebp-frame',
'data_ethernet_II': 'enable',
'discovery_mc_addr': 'test_value_8',
'fiapp_eth_type': '9',
'image_download': 'enable',
'ipsec_base_ip': 'test_value_11',
'link_aggregation': 'enable',
'location': 'test_value_13',
'max_clients': '14',
'max_retransmit': '15',
'mesh_eth_type': '16',
'name': 'default_name_17',
'rogue_scan_mac_adjacency': '18',
'wtp_share': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_wireless_controller_global.fortios_wireless_controller(input_data, fos_instance)
expected_data = {
'ap-log-server': 'enable',
'ap-log-server-ip': 'test_value_4',
'ap-log-server-port': '5',
'control-message-offload': 'ebp-frame',
'data-ethernet-II': 'enable',
'discovery-mc-addr': 'test_value_8',
'fiapp-eth-type': '9',
'image-download': 'enable',
'ipsec-base-ip': 'test_value_11',
'link-aggregation': 'enable',
'location': 'test_value_13',
'max-clients': '14',
'max-retransmit': '15',
'mesh-eth-type': '16',
'name': 'default_name_17',
'rogue-scan-mac-adjacency': '18',
'wtp-share': 'enable'
}
set_method_mock.assert_called_with('wireless-controller', 'global', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_wireless_controller_global_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'wireless_controller_global': {
'random_attribute_not_valid': 'tag',
'ap_log_server': 'enable',
'ap_log_server_ip': 'test_value_4',
'ap_log_server_port': '5',
'control_message_offload': 'ebp-frame',
'data_ethernet_II': 'enable',
'discovery_mc_addr': 'test_value_8',
'fiapp_eth_type': '9',
'image_download': 'enable',
'ipsec_base_ip': 'test_value_11',
'link_aggregation': 'enable',
'location': 'test_value_13',
'max_clients': '14',
'max_retransmit': '15',
'mesh_eth_type': '16',
'name': 'default_name_17',
'rogue_scan_mac_adjacency': '18',
'wtp_share': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_wireless_controller_global.fortios_wireless_controller(input_data, fos_instance)
expected_data = {
'ap-log-server': 'enable',
'ap-log-server-ip': 'test_value_4',
'ap-log-server-port': '5',
'control-message-offload': 'ebp-frame',
'data-ethernet-II': 'enable',
'discovery-mc-addr': 'test_value_8',
'fiapp-eth-type': '9',
'image-download': 'enable',
'ipsec-base-ip': 'test_value_11',
'link-aggregation': 'enable',
'location': 'test_value_13',
'max-clients': '14',
'max-retransmit': '15',
'mesh-eth-type': '16',
'name': 'default_name_17',
'rogue-scan-mac-adjacency': '18',
'wtp-share': 'enable'
}
set_method_mock.assert_called_with('wireless-controller', 'global', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,175 @@
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_wireless_controller_setting
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_wireless_controller_setting.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_wireless_controller_setting_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'wireless_controller_setting': {
'account_id': 'test_value_3',
'country': 'NA',
'duplicate_ssid': 'enable',
'fapc_compatibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_wireless_controller_setting.fortios_wireless_controller(input_data, fos_instance)
expected_data = {
'account-id': 'test_value_3',
'country': 'NA',
'duplicate-ssid': 'enable',
'fapc-compatibility': 'enable'
}
set_method_mock.assert_called_with('wireless-controller', 'setting', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_wireless_controller_setting_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'wireless_controller_setting': {
'account_id': 'test_value_3',
'country': 'NA',
'duplicate_ssid': 'enable',
'fapc_compatibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_wireless_controller_setting.fortios_wireless_controller(input_data, fos_instance)
expected_data = {
'account-id': 'test_value_3',
'country': 'NA',
'duplicate-ssid': 'enable',
'fapc-compatibility': 'enable'
}
set_method_mock.assert_called_with('wireless-controller', 'setting', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_wireless_controller_setting_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'wireless_controller_setting': {
'account_id': 'test_value_3',
'country': 'NA',
'duplicate_ssid': 'enable',
'fapc_compatibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_wireless_controller_setting.fortios_wireless_controller(input_data, fos_instance)
expected_data = {
'account-id': 'test_value_3',
'country': 'NA',
'duplicate-ssid': 'enable',
'fapc-compatibility': 'enable'
}
set_method_mock.assert_called_with('wireless-controller', 'setting', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_wireless_controller_setting_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'wireless_controller_setting': {
'random_attribute_not_valid': 'tag',
'account_id': 'test_value_3',
'country': 'NA',
'duplicate_ssid': 'enable',
'fapc_compatibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_wireless_controller_setting.fortios_wireless_controller(input_data, fos_instance)
expected_data = {
'account-id': 'test_value_3',
'country': 'NA',
'duplicate-ssid': 'enable',
'fapc-compatibility': 'enable'
}
set_method_mock.assert_called_with('wireless-controller', 'setting', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,269 @@
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_wireless_controller_utm_profile
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_wireless_controller_utm_profile.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_wireless_controller_utm_profile_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'wireless_controller_utm_profile': {
'antivirus_profile': 'test_value_3',
'application_list': 'test_value_4',
'comment': 'Comment.',
'ips_sensor': 'test_value_6',
'name': 'default_name_7',
'scan_botnet_connections': 'disable',
'utm_log': 'enable',
'webfilter_profile': 'test_value_10'
},
'vdom': 'root'}
is_error, changed, response = fortios_wireless_controller_utm_profile.fortios_wireless_controller(input_data, fos_instance)
expected_data = {
'antivirus-profile': 'test_value_3',
'application-list': 'test_value_4',
'comment': 'Comment.',
'ips-sensor': 'test_value_6',
'name': 'default_name_7',
'scan-botnet-connections': 'disable',
'utm-log': 'enable',
'webfilter-profile': 'test_value_10'
}
set_method_mock.assert_called_with('wireless-controller', 'utm-profile', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_wireless_controller_utm_profile_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'wireless_controller_utm_profile': {
'antivirus_profile': 'test_value_3',
'application_list': 'test_value_4',
'comment': 'Comment.',
'ips_sensor': 'test_value_6',
'name': 'default_name_7',
'scan_botnet_connections': 'disable',
'utm_log': 'enable',
'webfilter_profile': 'test_value_10'
},
'vdom': 'root'}
is_error, changed, response = fortios_wireless_controller_utm_profile.fortios_wireless_controller(input_data, fos_instance)
expected_data = {
'antivirus-profile': 'test_value_3',
'application-list': 'test_value_4',
'comment': 'Comment.',
'ips-sensor': 'test_value_6',
'name': 'default_name_7',
'scan-botnet-connections': 'disable',
'utm-log': 'enable',
'webfilter-profile': 'test_value_10'
}
set_method_mock.assert_called_with('wireless-controller', 'utm-profile', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_wireless_controller_utm_profile_removal(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'wireless_controller_utm_profile': {
'antivirus_profile': 'test_value_3',
'application_list': 'test_value_4',
'comment': 'Comment.',
'ips_sensor': 'test_value_6',
'name': 'default_name_7',
'scan_botnet_connections': 'disable',
'utm_log': 'enable',
'webfilter_profile': 'test_value_10'
},
'vdom': 'root'}
is_error, changed, response = fortios_wireless_controller_utm_profile.fortios_wireless_controller(input_data, fos_instance)
delete_method_mock.assert_called_with('wireless-controller', 'utm-profile', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_wireless_controller_utm_profile_deletion_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'wireless_controller_utm_profile': {
'antivirus_profile': 'test_value_3',
'application_list': 'test_value_4',
'comment': 'Comment.',
'ips_sensor': 'test_value_6',
'name': 'default_name_7',
'scan_botnet_connections': 'disable',
'utm_log': 'enable',
'webfilter_profile': 'test_value_10'
},
'vdom': 'root'}
is_error, changed, response = fortios_wireless_controller_utm_profile.fortios_wireless_controller(input_data, fos_instance)
delete_method_mock.assert_called_with('wireless-controller', 'utm-profile', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_wireless_controller_utm_profile_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'wireless_controller_utm_profile': {
'antivirus_profile': 'test_value_3',
'application_list': 'test_value_4',
'comment': 'Comment.',
'ips_sensor': 'test_value_6',
'name': 'default_name_7',
'scan_botnet_connections': 'disable',
'utm_log': 'enable',
'webfilter_profile': 'test_value_10'
},
'vdom': 'root'}
is_error, changed, response = fortios_wireless_controller_utm_profile.fortios_wireless_controller(input_data, fos_instance)
expected_data = {
'antivirus-profile': 'test_value_3',
'application-list': 'test_value_4',
'comment': 'Comment.',
'ips-sensor': 'test_value_6',
'name': 'default_name_7',
'scan-botnet-connections': 'disable',
'utm-log': 'enable',
'webfilter-profile': 'test_value_10'
}
set_method_mock.assert_called_with('wireless-controller', 'utm-profile', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_wireless_controller_utm_profile_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'wireless_controller_utm_profile': {
'random_attribute_not_valid': 'tag',
'antivirus_profile': 'test_value_3',
'application_list': 'test_value_4',
'comment': 'Comment.',
'ips_sensor': 'test_value_6',
'name': 'default_name_7',
'scan_botnet_connections': 'disable',
'utm_log': 'enable',
'webfilter_profile': 'test_value_10'
},
'vdom': 'root'}
is_error, changed, response = fortios_wireless_controller_utm_profile.fortios_wireless_controller(input_data, fos_instance)
expected_data = {
'antivirus-profile': 'test_value_3',
'application-list': 'test_value_4',
'comment': 'Comment.',
'ips-sensor': 'test_value_6',
'name': 'default_name_7',
'scan-botnet-connections': 'disable',
'utm-log': 'enable',
'webfilter-profile': 'test_value_10'
}
set_method_mock.assert_called_with('wireless-controller', 'utm-profile', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,679 @@
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_wireless_controller_wids_profile
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_wireless_controller_wids_profile.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_wireless_controller_wids_profile_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'wireless_controller_wids_profile': {
'ap_auto_suppress': 'enable',
'ap_bgscan_disable_day': 'sunday',
'ap_bgscan_disable_end': 'test_value_5',
'ap_bgscan_disable_start': 'test_value_6',
'ap_bgscan_duration': '7',
'ap_bgscan_idle': '8',
'ap_bgscan_intv': '9',
'ap_bgscan_period': '10',
'ap_bgscan_report_intv': '11',
'ap_fgscan_report_intv': '12',
'ap_scan': 'disable',
'ap_scan_passive': 'enable',
'asleap_attack': 'enable',
'assoc_flood_thresh': '16',
'assoc_flood_time': '17',
'assoc_frame_flood': 'enable',
'auth_flood_thresh': '19',
'auth_flood_time': '20',
'auth_frame_flood': 'enable',
'comment': 'Comment.',
'deauth_broadcast': 'enable',
'deauth_unknown_src_thresh': '24',
'eapol_fail_flood': 'enable',
'eapol_fail_intv': '26',
'eapol_fail_thresh': '27',
'eapol_logoff_flood': 'enable',
'eapol_logoff_intv': '29',
'eapol_logoff_thresh': '30',
'eapol_pre_fail_flood': 'enable',
'eapol_pre_fail_intv': '32',
'eapol_pre_fail_thresh': '33',
'eapol_pre_succ_flood': 'enable',
'eapol_pre_succ_intv': '35',
'eapol_pre_succ_thresh': '36',
'eapol_start_flood': 'enable',
'eapol_start_intv': '38',
'eapol_start_thresh': '39',
'eapol_succ_flood': 'enable',
'eapol_succ_intv': '41',
'eapol_succ_thresh': '42',
'invalid_mac_oui': 'enable',
'long_duration_attack': 'enable',
'long_duration_thresh': '45',
'name': 'default_name_46',
'null_ssid_probe_resp': 'enable',
'sensor_mode': 'disable',
'spoofed_deauth': 'enable',
'weak_wep_iv': 'enable',
'wireless_bridge': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_wireless_controller_wids_profile.fortios_wireless_controller(input_data, fos_instance)
expected_data = {
'ap-auto-suppress': 'enable',
'ap-bgscan-disable-day': 'sunday',
'ap-bgscan-disable-end': 'test_value_5',
'ap-bgscan-disable-start': 'test_value_6',
'ap-bgscan-duration': '7',
'ap-bgscan-idle': '8',
'ap-bgscan-intv': '9',
'ap-bgscan-period': '10',
'ap-bgscan-report-intv': '11',
'ap-fgscan-report-intv': '12',
'ap-scan': 'disable',
'ap-scan-passive': 'enable',
'asleap-attack': 'enable',
'assoc-flood-thresh': '16',
'assoc-flood-time': '17',
'assoc-frame-flood': 'enable',
'auth-flood-thresh': '19',
'auth-flood-time': '20',
'auth-frame-flood': 'enable',
'comment': 'Comment.',
'deauth-broadcast': 'enable',
'deauth-unknown-src-thresh': '24',
'eapol-fail-flood': 'enable',
'eapol-fail-intv': '26',
'eapol-fail-thresh': '27',
'eapol-logoff-flood': 'enable',
'eapol-logoff-intv': '29',
'eapol-logoff-thresh': '30',
'eapol-pre-fail-flood': 'enable',
'eapol-pre-fail-intv': '32',
'eapol-pre-fail-thresh': '33',
'eapol-pre-succ-flood': 'enable',
'eapol-pre-succ-intv': '35',
'eapol-pre-succ-thresh': '36',
'eapol-start-flood': 'enable',
'eapol-start-intv': '38',
'eapol-start-thresh': '39',
'eapol-succ-flood': 'enable',
'eapol-succ-intv': '41',
'eapol-succ-thresh': '42',
'invalid-mac-oui': 'enable',
'long-duration-attack': 'enable',
'long-duration-thresh': '45',
'name': 'default_name_46',
'null-ssid-probe-resp': 'enable',
'sensor-mode': 'disable',
'spoofed-deauth': 'enable',
'weak-wep-iv': 'enable',
'wireless-bridge': 'enable'
}
set_method_mock.assert_called_with('wireless-controller', 'wids-profile', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_wireless_controller_wids_profile_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'wireless_controller_wids_profile': {
'ap_auto_suppress': 'enable',
'ap_bgscan_disable_day': 'sunday',
'ap_bgscan_disable_end': 'test_value_5',
'ap_bgscan_disable_start': 'test_value_6',
'ap_bgscan_duration': '7',
'ap_bgscan_idle': '8',
'ap_bgscan_intv': '9',
'ap_bgscan_period': '10',
'ap_bgscan_report_intv': '11',
'ap_fgscan_report_intv': '12',
'ap_scan': 'disable',
'ap_scan_passive': 'enable',
'asleap_attack': 'enable',
'assoc_flood_thresh': '16',
'assoc_flood_time': '17',
'assoc_frame_flood': 'enable',
'auth_flood_thresh': '19',
'auth_flood_time': '20',
'auth_frame_flood': 'enable',
'comment': 'Comment.',
'deauth_broadcast': 'enable',
'deauth_unknown_src_thresh': '24',
'eapol_fail_flood': 'enable',
'eapol_fail_intv': '26',
'eapol_fail_thresh': '27',
'eapol_logoff_flood': 'enable',
'eapol_logoff_intv': '29',
'eapol_logoff_thresh': '30',
'eapol_pre_fail_flood': 'enable',
'eapol_pre_fail_intv': '32',
'eapol_pre_fail_thresh': '33',
'eapol_pre_succ_flood': 'enable',
'eapol_pre_succ_intv': '35',
'eapol_pre_succ_thresh': '36',
'eapol_start_flood': 'enable',
'eapol_start_intv': '38',
'eapol_start_thresh': '39',
'eapol_succ_flood': 'enable',
'eapol_succ_intv': '41',
'eapol_succ_thresh': '42',
'invalid_mac_oui': 'enable',
'long_duration_attack': 'enable',
'long_duration_thresh': '45',
'name': 'default_name_46',
'null_ssid_probe_resp': 'enable',
'sensor_mode': 'disable',
'spoofed_deauth': 'enable',
'weak_wep_iv': 'enable',
'wireless_bridge': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_wireless_controller_wids_profile.fortios_wireless_controller(input_data, fos_instance)
expected_data = {
'ap-auto-suppress': 'enable',
'ap-bgscan-disable-day': 'sunday',
'ap-bgscan-disable-end': 'test_value_5',
'ap-bgscan-disable-start': 'test_value_6',
'ap-bgscan-duration': '7',
'ap-bgscan-idle': '8',
'ap-bgscan-intv': '9',
'ap-bgscan-period': '10',
'ap-bgscan-report-intv': '11',
'ap-fgscan-report-intv': '12',
'ap-scan': 'disable',
'ap-scan-passive': 'enable',
'asleap-attack': 'enable',
'assoc-flood-thresh': '16',
'assoc-flood-time': '17',
'assoc-frame-flood': 'enable',
'auth-flood-thresh': '19',
'auth-flood-time': '20',
'auth-frame-flood': 'enable',
'comment': 'Comment.',
'deauth-broadcast': 'enable',
'deauth-unknown-src-thresh': '24',
'eapol-fail-flood': 'enable',
'eapol-fail-intv': '26',
'eapol-fail-thresh': '27',
'eapol-logoff-flood': 'enable',
'eapol-logoff-intv': '29',
'eapol-logoff-thresh': '30',
'eapol-pre-fail-flood': 'enable',
'eapol-pre-fail-intv': '32',
'eapol-pre-fail-thresh': '33',
'eapol-pre-succ-flood': 'enable',
'eapol-pre-succ-intv': '35',
'eapol-pre-succ-thresh': '36',
'eapol-start-flood': 'enable',
'eapol-start-intv': '38',
'eapol-start-thresh': '39',
'eapol-succ-flood': 'enable',
'eapol-succ-intv': '41',
'eapol-succ-thresh': '42',
'invalid-mac-oui': 'enable',
'long-duration-attack': 'enable',
'long-duration-thresh': '45',
'name': 'default_name_46',
'null-ssid-probe-resp': 'enable',
'sensor-mode': 'disable',
'spoofed-deauth': 'enable',
'weak-wep-iv': 'enable',
'wireless-bridge': 'enable'
}
set_method_mock.assert_called_with('wireless-controller', 'wids-profile', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_wireless_controller_wids_profile_removal(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'wireless_controller_wids_profile': {
'ap_auto_suppress': 'enable',
'ap_bgscan_disable_day': 'sunday',
'ap_bgscan_disable_end': 'test_value_5',
'ap_bgscan_disable_start': 'test_value_6',
'ap_bgscan_duration': '7',
'ap_bgscan_idle': '8',
'ap_bgscan_intv': '9',
'ap_bgscan_period': '10',
'ap_bgscan_report_intv': '11',
'ap_fgscan_report_intv': '12',
'ap_scan': 'disable',
'ap_scan_passive': 'enable',
'asleap_attack': 'enable',
'assoc_flood_thresh': '16',
'assoc_flood_time': '17',
'assoc_frame_flood': 'enable',
'auth_flood_thresh': '19',
'auth_flood_time': '20',
'auth_frame_flood': 'enable',
'comment': 'Comment.',
'deauth_broadcast': 'enable',
'deauth_unknown_src_thresh': '24',
'eapol_fail_flood': 'enable',
'eapol_fail_intv': '26',
'eapol_fail_thresh': '27',
'eapol_logoff_flood': 'enable',
'eapol_logoff_intv': '29',
'eapol_logoff_thresh': '30',
'eapol_pre_fail_flood': 'enable',
'eapol_pre_fail_intv': '32',
'eapol_pre_fail_thresh': '33',
'eapol_pre_succ_flood': 'enable',
'eapol_pre_succ_intv': '35',
'eapol_pre_succ_thresh': '36',
'eapol_start_flood': 'enable',
'eapol_start_intv': '38',
'eapol_start_thresh': '39',
'eapol_succ_flood': 'enable',
'eapol_succ_intv': '41',
'eapol_succ_thresh': '42',
'invalid_mac_oui': 'enable',
'long_duration_attack': 'enable',
'long_duration_thresh': '45',
'name': 'default_name_46',
'null_ssid_probe_resp': 'enable',
'sensor_mode': 'disable',
'spoofed_deauth': 'enable',
'weak_wep_iv': 'enable',
'wireless_bridge': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_wireless_controller_wids_profile.fortios_wireless_controller(input_data, fos_instance)
delete_method_mock.assert_called_with('wireless-controller', 'wids-profile', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_wireless_controller_wids_profile_deletion_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'wireless_controller_wids_profile': {
'ap_auto_suppress': 'enable',
'ap_bgscan_disable_day': 'sunday',
'ap_bgscan_disable_end': 'test_value_5',
'ap_bgscan_disable_start': 'test_value_6',
'ap_bgscan_duration': '7',
'ap_bgscan_idle': '8',
'ap_bgscan_intv': '9',
'ap_bgscan_period': '10',
'ap_bgscan_report_intv': '11',
'ap_fgscan_report_intv': '12',
'ap_scan': 'disable',
'ap_scan_passive': 'enable',
'asleap_attack': 'enable',
'assoc_flood_thresh': '16',
'assoc_flood_time': '17',
'assoc_frame_flood': 'enable',
'auth_flood_thresh': '19',
'auth_flood_time': '20',
'auth_frame_flood': 'enable',
'comment': 'Comment.',
'deauth_broadcast': 'enable',
'deauth_unknown_src_thresh': '24',
'eapol_fail_flood': 'enable',
'eapol_fail_intv': '26',
'eapol_fail_thresh': '27',
'eapol_logoff_flood': 'enable',
'eapol_logoff_intv': '29',
'eapol_logoff_thresh': '30',
'eapol_pre_fail_flood': 'enable',
'eapol_pre_fail_intv': '32',
'eapol_pre_fail_thresh': '33',
'eapol_pre_succ_flood': 'enable',
'eapol_pre_succ_intv': '35',
'eapol_pre_succ_thresh': '36',
'eapol_start_flood': 'enable',
'eapol_start_intv': '38',
'eapol_start_thresh': '39',
'eapol_succ_flood': 'enable',
'eapol_succ_intv': '41',
'eapol_succ_thresh': '42',
'invalid_mac_oui': 'enable',
'long_duration_attack': 'enable',
'long_duration_thresh': '45',
'name': 'default_name_46',
'null_ssid_probe_resp': 'enable',
'sensor_mode': 'disable',
'spoofed_deauth': 'enable',
'weak_wep_iv': 'enable',
'wireless_bridge': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_wireless_controller_wids_profile.fortios_wireless_controller(input_data, fos_instance)
delete_method_mock.assert_called_with('wireless-controller', 'wids-profile', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_wireless_controller_wids_profile_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'wireless_controller_wids_profile': {
'ap_auto_suppress': 'enable',
'ap_bgscan_disable_day': 'sunday',
'ap_bgscan_disable_end': 'test_value_5',
'ap_bgscan_disable_start': 'test_value_6',
'ap_bgscan_duration': '7',
'ap_bgscan_idle': '8',
'ap_bgscan_intv': '9',
'ap_bgscan_period': '10',
'ap_bgscan_report_intv': '11',
'ap_fgscan_report_intv': '12',
'ap_scan': 'disable',
'ap_scan_passive': 'enable',
'asleap_attack': 'enable',
'assoc_flood_thresh': '16',
'assoc_flood_time': '17',
'assoc_frame_flood': 'enable',
'auth_flood_thresh': '19',
'auth_flood_time': '20',
'auth_frame_flood': 'enable',
'comment': 'Comment.',
'deauth_broadcast': 'enable',
'deauth_unknown_src_thresh': '24',
'eapol_fail_flood': 'enable',
'eapol_fail_intv': '26',
'eapol_fail_thresh': '27',
'eapol_logoff_flood': 'enable',
'eapol_logoff_intv': '29',
'eapol_logoff_thresh': '30',
'eapol_pre_fail_flood': 'enable',
'eapol_pre_fail_intv': '32',
'eapol_pre_fail_thresh': '33',
'eapol_pre_succ_flood': 'enable',
'eapol_pre_succ_intv': '35',
'eapol_pre_succ_thresh': '36',
'eapol_start_flood': 'enable',
'eapol_start_intv': '38',
'eapol_start_thresh': '39',
'eapol_succ_flood': 'enable',
'eapol_succ_intv': '41',
'eapol_succ_thresh': '42',
'invalid_mac_oui': 'enable',
'long_duration_attack': 'enable',
'long_duration_thresh': '45',
'name': 'default_name_46',
'null_ssid_probe_resp': 'enable',
'sensor_mode': 'disable',
'spoofed_deauth': 'enable',
'weak_wep_iv': 'enable',
'wireless_bridge': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_wireless_controller_wids_profile.fortios_wireless_controller(input_data, fos_instance)
expected_data = {
'ap-auto-suppress': 'enable',
'ap-bgscan-disable-day': 'sunday',
'ap-bgscan-disable-end': 'test_value_5',
'ap-bgscan-disable-start': 'test_value_6',
'ap-bgscan-duration': '7',
'ap-bgscan-idle': '8',
'ap-bgscan-intv': '9',
'ap-bgscan-period': '10',
'ap-bgscan-report-intv': '11',
'ap-fgscan-report-intv': '12',
'ap-scan': 'disable',
'ap-scan-passive': 'enable',
'asleap-attack': 'enable',
'assoc-flood-thresh': '16',
'assoc-flood-time': '17',
'assoc-frame-flood': 'enable',
'auth-flood-thresh': '19',
'auth-flood-time': '20',
'auth-frame-flood': 'enable',
'comment': 'Comment.',
'deauth-broadcast': 'enable',
'deauth-unknown-src-thresh': '24',
'eapol-fail-flood': 'enable',
'eapol-fail-intv': '26',
'eapol-fail-thresh': '27',
'eapol-logoff-flood': 'enable',
'eapol-logoff-intv': '29',
'eapol-logoff-thresh': '30',
'eapol-pre-fail-flood': 'enable',
'eapol-pre-fail-intv': '32',
'eapol-pre-fail-thresh': '33',
'eapol-pre-succ-flood': 'enable',
'eapol-pre-succ-intv': '35',
'eapol-pre-succ-thresh': '36',
'eapol-start-flood': 'enable',
'eapol-start-intv': '38',
'eapol-start-thresh': '39',
'eapol-succ-flood': 'enable',
'eapol-succ-intv': '41',
'eapol-succ-thresh': '42',
'invalid-mac-oui': 'enable',
'long-duration-attack': 'enable',
'long-duration-thresh': '45',
'name': 'default_name_46',
'null-ssid-probe-resp': 'enable',
'sensor-mode': 'disable',
'spoofed-deauth': 'enable',
'weak-wep-iv': 'enable',
'wireless-bridge': 'enable'
}
set_method_mock.assert_called_with('wireless-controller', 'wids-profile', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_wireless_controller_wids_profile_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'wireless_controller_wids_profile': {
'random_attribute_not_valid': 'tag',
'ap_auto_suppress': 'enable',
'ap_bgscan_disable_day': 'sunday',
'ap_bgscan_disable_end': 'test_value_5',
'ap_bgscan_disable_start': 'test_value_6',
'ap_bgscan_duration': '7',
'ap_bgscan_idle': '8',
'ap_bgscan_intv': '9',
'ap_bgscan_period': '10',
'ap_bgscan_report_intv': '11',
'ap_fgscan_report_intv': '12',
'ap_scan': 'disable',
'ap_scan_passive': 'enable',
'asleap_attack': 'enable',
'assoc_flood_thresh': '16',
'assoc_flood_time': '17',
'assoc_frame_flood': 'enable',
'auth_flood_thresh': '19',
'auth_flood_time': '20',
'auth_frame_flood': 'enable',
'comment': 'Comment.',
'deauth_broadcast': 'enable',
'deauth_unknown_src_thresh': '24',
'eapol_fail_flood': 'enable',
'eapol_fail_intv': '26',
'eapol_fail_thresh': '27',
'eapol_logoff_flood': 'enable',
'eapol_logoff_intv': '29',
'eapol_logoff_thresh': '30',
'eapol_pre_fail_flood': 'enable',
'eapol_pre_fail_intv': '32',
'eapol_pre_fail_thresh': '33',
'eapol_pre_succ_flood': 'enable',
'eapol_pre_succ_intv': '35',
'eapol_pre_succ_thresh': '36',
'eapol_start_flood': 'enable',
'eapol_start_intv': '38',
'eapol_start_thresh': '39',
'eapol_succ_flood': 'enable',
'eapol_succ_intv': '41',
'eapol_succ_thresh': '42',
'invalid_mac_oui': 'enable',
'long_duration_attack': 'enable',
'long_duration_thresh': '45',
'name': 'default_name_46',
'null_ssid_probe_resp': 'enable',
'sensor_mode': 'disable',
'spoofed_deauth': 'enable',
'weak_wep_iv': 'enable',
'wireless_bridge': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_wireless_controller_wids_profile.fortios_wireless_controller(input_data, fos_instance)
expected_data = {
'ap-auto-suppress': 'enable',
'ap-bgscan-disable-day': 'sunday',
'ap-bgscan-disable-end': 'test_value_5',
'ap-bgscan-disable-start': 'test_value_6',
'ap-bgscan-duration': '7',
'ap-bgscan-idle': '8',
'ap-bgscan-intv': '9',
'ap-bgscan-period': '10',
'ap-bgscan-report-intv': '11',
'ap-fgscan-report-intv': '12',
'ap-scan': 'disable',
'ap-scan-passive': 'enable',
'asleap-attack': 'enable',
'assoc-flood-thresh': '16',
'assoc-flood-time': '17',
'assoc-frame-flood': 'enable',
'auth-flood-thresh': '19',
'auth-flood-time': '20',
'auth-frame-flood': 'enable',
'comment': 'Comment.',
'deauth-broadcast': 'enable',
'deauth-unknown-src-thresh': '24',
'eapol-fail-flood': 'enable',
'eapol-fail-intv': '26',
'eapol-fail-thresh': '27',
'eapol-logoff-flood': 'enable',
'eapol-logoff-intv': '29',
'eapol-logoff-thresh': '30',
'eapol-pre-fail-flood': 'enable',
'eapol-pre-fail-intv': '32',
'eapol-pre-fail-thresh': '33',
'eapol-pre-succ-flood': 'enable',
'eapol-pre-succ-intv': '35',
'eapol-pre-succ-thresh': '36',
'eapol-start-flood': 'enable',
'eapol-start-intv': '38',
'eapol-start-thresh': '39',
'eapol-succ-flood': 'enable',
'eapol-succ-intv': '41',
'eapol-succ-thresh': '42',
'invalid-mac-oui': 'enable',
'long-duration-attack': 'enable',
'long-duration-thresh': '45',
'name': 'default_name_46',
'null-ssid-probe-resp': 'enable',
'sensor-mode': 'disable',
'spoofed-deauth': 'enable',
'weak-wep-iv': 'enable',
'wireless-bridge': 'enable'
}
set_method_mock.assert_called_with('wireless-controller', 'wids-profile', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,509 @@
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_wireless_controller_wtp
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_wireless_controller_wtp.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_wireless_controller_wtp_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'wireless_controller_wtp': {
'admin': 'discovered',
'allowaccess': 'telnet',
'bonjour_profile': 'test_value_5',
'coordinate_enable': 'enable',
'coordinate_latitude': 'test_value_7',
'coordinate_longitude': 'test_value_8',
'coordinate_x': 'test_value_9',
'coordinate_y': 'test_value_10',
'image_download': 'enable',
'index': '12',
'ip_fragment_preventing': 'tcp-mss-adjust',
'led_state': 'enable',
'location': 'test_value_15',
'login_passwd': 'test_value_16',
'login_passwd_change': 'yes',
'mesh_bridge_enable': 'default',
'name': 'default_name_19',
'override_allowaccess': 'enable',
'override_ip_fragment': 'enable',
'override_lan': 'enable',
'override_led_state': 'enable',
'override_login_passwd_change': 'enable',
'override_split_tunnel': 'enable',
'override_wan_port_mode': 'enable',
'split_tunneling_acl_local_ap_subnet': 'enable',
'split_tunneling_acl_path': 'tunnel',
'tun_mtu_downlink': '29',
'tun_mtu_uplink': '30',
'wan_port_mode': 'wan-lan',
'wtp_id': 'test_value_32',
'wtp_mode': 'normal',
'wtp_profile': 'test_value_34'
},
'vdom': 'root'}
is_error, changed, response = fortios_wireless_controller_wtp.fortios_wireless_controller(input_data, fos_instance)
expected_data = {
'admin': 'discovered',
'allowaccess': 'telnet',
'bonjour-profile': 'test_value_5',
'coordinate-enable': 'enable',
'coordinate-latitude': 'test_value_7',
'coordinate-longitude': 'test_value_8',
'coordinate-x': 'test_value_9',
'coordinate-y': 'test_value_10',
'image-download': 'enable',
'index': '12',
'ip-fragment-preventing': 'tcp-mss-adjust',
'led-state': 'enable',
'location': 'test_value_15',
'login-passwd': 'test_value_16',
'login-passwd-change': 'yes',
'mesh-bridge-enable': 'default',
'name': 'default_name_19',
'override-allowaccess': 'enable',
'override-ip-fragment': 'enable',
'override-lan': 'enable',
'override-led-state': 'enable',
'override-login-passwd-change': 'enable',
'override-split-tunnel': 'enable',
'override-wan-port-mode': 'enable',
'split-tunneling-acl-local-ap-subnet': 'enable',
'split-tunneling-acl-path': 'tunnel',
'tun-mtu-downlink': '29',
'tun-mtu-uplink': '30',
'wan-port-mode': 'wan-lan',
'wtp-id': 'test_value_32',
'wtp-mode': 'normal',
'wtp-profile': 'test_value_34'
}
set_method_mock.assert_called_with('wireless-controller', 'wtp', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_wireless_controller_wtp_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'wireless_controller_wtp': {
'admin': 'discovered',
'allowaccess': 'telnet',
'bonjour_profile': 'test_value_5',
'coordinate_enable': 'enable',
'coordinate_latitude': 'test_value_7',
'coordinate_longitude': 'test_value_8',
'coordinate_x': 'test_value_9',
'coordinate_y': 'test_value_10',
'image_download': 'enable',
'index': '12',
'ip_fragment_preventing': 'tcp-mss-adjust',
'led_state': 'enable',
'location': 'test_value_15',
'login_passwd': 'test_value_16',
'login_passwd_change': 'yes',
'mesh_bridge_enable': 'default',
'name': 'default_name_19',
'override_allowaccess': 'enable',
'override_ip_fragment': 'enable',
'override_lan': 'enable',
'override_led_state': 'enable',
'override_login_passwd_change': 'enable',
'override_split_tunnel': 'enable',
'override_wan_port_mode': 'enable',
'split_tunneling_acl_local_ap_subnet': 'enable',
'split_tunneling_acl_path': 'tunnel',
'tun_mtu_downlink': '29',
'tun_mtu_uplink': '30',
'wan_port_mode': 'wan-lan',
'wtp_id': 'test_value_32',
'wtp_mode': 'normal',
'wtp_profile': 'test_value_34'
},
'vdom': 'root'}
is_error, changed, response = fortios_wireless_controller_wtp.fortios_wireless_controller(input_data, fos_instance)
expected_data = {
'admin': 'discovered',
'allowaccess': 'telnet',
'bonjour-profile': 'test_value_5',
'coordinate-enable': 'enable',
'coordinate-latitude': 'test_value_7',
'coordinate-longitude': 'test_value_8',
'coordinate-x': 'test_value_9',
'coordinate-y': 'test_value_10',
'image-download': 'enable',
'index': '12',
'ip-fragment-preventing': 'tcp-mss-adjust',
'led-state': 'enable',
'location': 'test_value_15',
'login-passwd': 'test_value_16',
'login-passwd-change': 'yes',
'mesh-bridge-enable': 'default',
'name': 'default_name_19',
'override-allowaccess': 'enable',
'override-ip-fragment': 'enable',
'override-lan': 'enable',
'override-led-state': 'enable',
'override-login-passwd-change': 'enable',
'override-split-tunnel': 'enable',
'override-wan-port-mode': 'enable',
'split-tunneling-acl-local-ap-subnet': 'enable',
'split-tunneling-acl-path': 'tunnel',
'tun-mtu-downlink': '29',
'tun-mtu-uplink': '30',
'wan-port-mode': 'wan-lan',
'wtp-id': 'test_value_32',
'wtp-mode': 'normal',
'wtp-profile': 'test_value_34'
}
set_method_mock.assert_called_with('wireless-controller', 'wtp', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_wireless_controller_wtp_removal(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'wireless_controller_wtp': {
'admin': 'discovered',
'allowaccess': 'telnet',
'bonjour_profile': 'test_value_5',
'coordinate_enable': 'enable',
'coordinate_latitude': 'test_value_7',
'coordinate_longitude': 'test_value_8',
'coordinate_x': 'test_value_9',
'coordinate_y': 'test_value_10',
'image_download': 'enable',
'index': '12',
'ip_fragment_preventing': 'tcp-mss-adjust',
'led_state': 'enable',
'location': 'test_value_15',
'login_passwd': 'test_value_16',
'login_passwd_change': 'yes',
'mesh_bridge_enable': 'default',
'name': 'default_name_19',
'override_allowaccess': 'enable',
'override_ip_fragment': 'enable',
'override_lan': 'enable',
'override_led_state': 'enable',
'override_login_passwd_change': 'enable',
'override_split_tunnel': 'enable',
'override_wan_port_mode': 'enable',
'split_tunneling_acl_local_ap_subnet': 'enable',
'split_tunneling_acl_path': 'tunnel',
'tun_mtu_downlink': '29',
'tun_mtu_uplink': '30',
'wan_port_mode': 'wan-lan',
'wtp_id': 'test_value_32',
'wtp_mode': 'normal',
'wtp_profile': 'test_value_34'
},
'vdom': 'root'}
is_error, changed, response = fortios_wireless_controller_wtp.fortios_wireless_controller(input_data, fos_instance)
delete_method_mock.assert_called_with('wireless-controller', 'wtp', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_wireless_controller_wtp_deletion_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'wireless_controller_wtp': {
'admin': 'discovered',
'allowaccess': 'telnet',
'bonjour_profile': 'test_value_5',
'coordinate_enable': 'enable',
'coordinate_latitude': 'test_value_7',
'coordinate_longitude': 'test_value_8',
'coordinate_x': 'test_value_9',
'coordinate_y': 'test_value_10',
'image_download': 'enable',
'index': '12',
'ip_fragment_preventing': 'tcp-mss-adjust',
'led_state': 'enable',
'location': 'test_value_15',
'login_passwd': 'test_value_16',
'login_passwd_change': 'yes',
'mesh_bridge_enable': 'default',
'name': 'default_name_19',
'override_allowaccess': 'enable',
'override_ip_fragment': 'enable',
'override_lan': 'enable',
'override_led_state': 'enable',
'override_login_passwd_change': 'enable',
'override_split_tunnel': 'enable',
'override_wan_port_mode': 'enable',
'split_tunneling_acl_local_ap_subnet': 'enable',
'split_tunneling_acl_path': 'tunnel',
'tun_mtu_downlink': '29',
'tun_mtu_uplink': '30',
'wan_port_mode': 'wan-lan',
'wtp_id': 'test_value_32',
'wtp_mode': 'normal',
'wtp_profile': 'test_value_34'
},
'vdom': 'root'}
is_error, changed, response = fortios_wireless_controller_wtp.fortios_wireless_controller(input_data, fos_instance)
delete_method_mock.assert_called_with('wireless-controller', 'wtp', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_wireless_controller_wtp_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'wireless_controller_wtp': {
'admin': 'discovered',
'allowaccess': 'telnet',
'bonjour_profile': 'test_value_5',
'coordinate_enable': 'enable',
'coordinate_latitude': 'test_value_7',
'coordinate_longitude': 'test_value_8',
'coordinate_x': 'test_value_9',
'coordinate_y': 'test_value_10',
'image_download': 'enable',
'index': '12',
'ip_fragment_preventing': 'tcp-mss-adjust',
'led_state': 'enable',
'location': 'test_value_15',
'login_passwd': 'test_value_16',
'login_passwd_change': 'yes',
'mesh_bridge_enable': 'default',
'name': 'default_name_19',
'override_allowaccess': 'enable',
'override_ip_fragment': 'enable',
'override_lan': 'enable',
'override_led_state': 'enable',
'override_login_passwd_change': 'enable',
'override_split_tunnel': 'enable',
'override_wan_port_mode': 'enable',
'split_tunneling_acl_local_ap_subnet': 'enable',
'split_tunneling_acl_path': 'tunnel',
'tun_mtu_downlink': '29',
'tun_mtu_uplink': '30',
'wan_port_mode': 'wan-lan',
'wtp_id': 'test_value_32',
'wtp_mode': 'normal',
'wtp_profile': 'test_value_34'
},
'vdom': 'root'}
is_error, changed, response = fortios_wireless_controller_wtp.fortios_wireless_controller(input_data, fos_instance)
expected_data = {
'admin': 'discovered',
'allowaccess': 'telnet',
'bonjour-profile': 'test_value_5',
'coordinate-enable': 'enable',
'coordinate-latitude': 'test_value_7',
'coordinate-longitude': 'test_value_8',
'coordinate-x': 'test_value_9',
'coordinate-y': 'test_value_10',
'image-download': 'enable',
'index': '12',
'ip-fragment-preventing': 'tcp-mss-adjust',
'led-state': 'enable',
'location': 'test_value_15',
'login-passwd': 'test_value_16',
'login-passwd-change': 'yes',
'mesh-bridge-enable': 'default',
'name': 'default_name_19',
'override-allowaccess': 'enable',
'override-ip-fragment': 'enable',
'override-lan': 'enable',
'override-led-state': 'enable',
'override-login-passwd-change': 'enable',
'override-split-tunnel': 'enable',
'override-wan-port-mode': 'enable',
'split-tunneling-acl-local-ap-subnet': 'enable',
'split-tunneling-acl-path': 'tunnel',
'tun-mtu-downlink': '29',
'tun-mtu-uplink': '30',
'wan-port-mode': 'wan-lan',
'wtp-id': 'test_value_32',
'wtp-mode': 'normal',
'wtp-profile': 'test_value_34'
}
set_method_mock.assert_called_with('wireless-controller', 'wtp', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_wireless_controller_wtp_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'wireless_controller_wtp': {
'random_attribute_not_valid': 'tag',
'admin': 'discovered',
'allowaccess': 'telnet',
'bonjour_profile': 'test_value_5',
'coordinate_enable': 'enable',
'coordinate_latitude': 'test_value_7',
'coordinate_longitude': 'test_value_8',
'coordinate_x': 'test_value_9',
'coordinate_y': 'test_value_10',
'image_download': 'enable',
'index': '12',
'ip_fragment_preventing': 'tcp-mss-adjust',
'led_state': 'enable',
'location': 'test_value_15',
'login_passwd': 'test_value_16',
'login_passwd_change': 'yes',
'mesh_bridge_enable': 'default',
'name': 'default_name_19',
'override_allowaccess': 'enable',
'override_ip_fragment': 'enable',
'override_lan': 'enable',
'override_led_state': 'enable',
'override_login_passwd_change': 'enable',
'override_split_tunnel': 'enable',
'override_wan_port_mode': 'enable',
'split_tunneling_acl_local_ap_subnet': 'enable',
'split_tunneling_acl_path': 'tunnel',
'tun_mtu_downlink': '29',
'tun_mtu_uplink': '30',
'wan_port_mode': 'wan-lan',
'wtp_id': 'test_value_32',
'wtp_mode': 'normal',
'wtp_profile': 'test_value_34'
},
'vdom': 'root'}
is_error, changed, response = fortios_wireless_controller_wtp.fortios_wireless_controller(input_data, fos_instance)
expected_data = {
'admin': 'discovered',
'allowaccess': 'telnet',
'bonjour-profile': 'test_value_5',
'coordinate-enable': 'enable',
'coordinate-latitude': 'test_value_7',
'coordinate-longitude': 'test_value_8',
'coordinate-x': 'test_value_9',
'coordinate-y': 'test_value_10',
'image-download': 'enable',
'index': '12',
'ip-fragment-preventing': 'tcp-mss-adjust',
'led-state': 'enable',
'location': 'test_value_15',
'login-passwd': 'test_value_16',
'login-passwd-change': 'yes',
'mesh-bridge-enable': 'default',
'name': 'default_name_19',
'override-allowaccess': 'enable',
'override-ip-fragment': 'enable',
'override-lan': 'enable',
'override-led-state': 'enable',
'override-login-passwd-change': 'enable',
'override-split-tunnel': 'enable',
'override-wan-port-mode': 'enable',
'split-tunneling-acl-local-ap-subnet': 'enable',
'split-tunneling-acl-path': 'tunnel',
'tun-mtu-downlink': '29',
'tun-mtu-uplink': '30',
'wan-port-mode': 'wan-lan',
'wtp-id': 'test_value_32',
'wtp-mode': 'normal',
'wtp-profile': 'test_value_34'
}
set_method_mock.assert_called_with('wireless-controller', 'wtp', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,439 @@
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_wireless_controller_wtp_profile
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_wireless_controller_wtp_profile.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_wireless_controller_wtp_profile_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'wireless_controller_wtp_profile': {
'allowaccess': 'telnet',
'ap_country': 'NA',
'ble_profile': 'test_value_5',
'comment': 'Comment.',
'control_message_offload': 'ebp-frame',
'dtls_in_kernel': 'enable',
'dtls_policy': 'clear-text',
'energy_efficient_ethernet': 'enable',
'ext_info_enable': 'enable',
'handoff_roaming': 'enable',
'handoff_rssi': '13',
'handoff_sta_thresh': '14',
'ip_fragment_preventing': 'tcp-mss-adjust',
'led_state': 'enable',
'lldp': 'enable',
'login_passwd': 'test_value_18',
'login_passwd_change': 'yes',
'max_clients': '20',
'name': 'default_name_21',
'poe_mode': 'auto',
'split_tunneling_acl_local_ap_subnet': 'enable',
'split_tunneling_acl_path': 'tunnel',
'tun_mtu_downlink': '25',
'tun_mtu_uplink': '26',
'wan_port_mode': 'wan-lan'
},
'vdom': 'root'}
is_error, changed, response = fortios_wireless_controller_wtp_profile.fortios_wireless_controller(input_data, fos_instance)
expected_data = {
'allowaccess': 'telnet',
'ap-country': 'NA',
'ble-profile': 'test_value_5',
'comment': 'Comment.',
'control-message-offload': 'ebp-frame',
'dtls-in-kernel': 'enable',
'dtls-policy': 'clear-text',
'energy-efficient-ethernet': 'enable',
'ext-info-enable': 'enable',
'handoff-roaming': 'enable',
'handoff-rssi': '13',
'handoff-sta-thresh': '14',
'ip-fragment-preventing': 'tcp-mss-adjust',
'led-state': 'enable',
'lldp': 'enable',
'login-passwd': 'test_value_18',
'login-passwd-change': 'yes',
'max-clients': '20',
'name': 'default_name_21',
'poe-mode': 'auto',
'split-tunneling-acl-local-ap-subnet': 'enable',
'split-tunneling-acl-path': 'tunnel',
'tun-mtu-downlink': '25',
'tun-mtu-uplink': '26',
'wan-port-mode': 'wan-lan'
}
set_method_mock.assert_called_with('wireless-controller', 'wtp-profile', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_wireless_controller_wtp_profile_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'wireless_controller_wtp_profile': {
'allowaccess': 'telnet',
'ap_country': 'NA',
'ble_profile': 'test_value_5',
'comment': 'Comment.',
'control_message_offload': 'ebp-frame',
'dtls_in_kernel': 'enable',
'dtls_policy': 'clear-text',
'energy_efficient_ethernet': 'enable',
'ext_info_enable': 'enable',
'handoff_roaming': 'enable',
'handoff_rssi': '13',
'handoff_sta_thresh': '14',
'ip_fragment_preventing': 'tcp-mss-adjust',
'led_state': 'enable',
'lldp': 'enable',
'login_passwd': 'test_value_18',
'login_passwd_change': 'yes',
'max_clients': '20',
'name': 'default_name_21',
'poe_mode': 'auto',
'split_tunneling_acl_local_ap_subnet': 'enable',
'split_tunneling_acl_path': 'tunnel',
'tun_mtu_downlink': '25',
'tun_mtu_uplink': '26',
'wan_port_mode': 'wan-lan'
},
'vdom': 'root'}
is_error, changed, response = fortios_wireless_controller_wtp_profile.fortios_wireless_controller(input_data, fos_instance)
expected_data = {
'allowaccess': 'telnet',
'ap-country': 'NA',
'ble-profile': 'test_value_5',
'comment': 'Comment.',
'control-message-offload': 'ebp-frame',
'dtls-in-kernel': 'enable',
'dtls-policy': 'clear-text',
'energy-efficient-ethernet': 'enable',
'ext-info-enable': 'enable',
'handoff-roaming': 'enable',
'handoff-rssi': '13',
'handoff-sta-thresh': '14',
'ip-fragment-preventing': 'tcp-mss-adjust',
'led-state': 'enable',
'lldp': 'enable',
'login-passwd': 'test_value_18',
'login-passwd-change': 'yes',
'max-clients': '20',
'name': 'default_name_21',
'poe-mode': 'auto',
'split-tunneling-acl-local-ap-subnet': 'enable',
'split-tunneling-acl-path': 'tunnel',
'tun-mtu-downlink': '25',
'tun-mtu-uplink': '26',
'wan-port-mode': 'wan-lan'
}
set_method_mock.assert_called_with('wireless-controller', 'wtp-profile', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_wireless_controller_wtp_profile_removal(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'wireless_controller_wtp_profile': {
'allowaccess': 'telnet',
'ap_country': 'NA',
'ble_profile': 'test_value_5',
'comment': 'Comment.',
'control_message_offload': 'ebp-frame',
'dtls_in_kernel': 'enable',
'dtls_policy': 'clear-text',
'energy_efficient_ethernet': 'enable',
'ext_info_enable': 'enable',
'handoff_roaming': 'enable',
'handoff_rssi': '13',
'handoff_sta_thresh': '14',
'ip_fragment_preventing': 'tcp-mss-adjust',
'led_state': 'enable',
'lldp': 'enable',
'login_passwd': 'test_value_18',
'login_passwd_change': 'yes',
'max_clients': '20',
'name': 'default_name_21',
'poe_mode': 'auto',
'split_tunneling_acl_local_ap_subnet': 'enable',
'split_tunneling_acl_path': 'tunnel',
'tun_mtu_downlink': '25',
'tun_mtu_uplink': '26',
'wan_port_mode': 'wan-lan'
},
'vdom': 'root'}
is_error, changed, response = fortios_wireless_controller_wtp_profile.fortios_wireless_controller(input_data, fos_instance)
delete_method_mock.assert_called_with('wireless-controller', 'wtp-profile', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_wireless_controller_wtp_profile_deletion_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'wireless_controller_wtp_profile': {
'allowaccess': 'telnet',
'ap_country': 'NA',
'ble_profile': 'test_value_5',
'comment': 'Comment.',
'control_message_offload': 'ebp-frame',
'dtls_in_kernel': 'enable',
'dtls_policy': 'clear-text',
'energy_efficient_ethernet': 'enable',
'ext_info_enable': 'enable',
'handoff_roaming': 'enable',
'handoff_rssi': '13',
'handoff_sta_thresh': '14',
'ip_fragment_preventing': 'tcp-mss-adjust',
'led_state': 'enable',
'lldp': 'enable',
'login_passwd': 'test_value_18',
'login_passwd_change': 'yes',
'max_clients': '20',
'name': 'default_name_21',
'poe_mode': 'auto',
'split_tunneling_acl_local_ap_subnet': 'enable',
'split_tunneling_acl_path': 'tunnel',
'tun_mtu_downlink': '25',
'tun_mtu_uplink': '26',
'wan_port_mode': 'wan-lan'
},
'vdom': 'root'}
is_error, changed, response = fortios_wireless_controller_wtp_profile.fortios_wireless_controller(input_data, fos_instance)
delete_method_mock.assert_called_with('wireless-controller', 'wtp-profile', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_wireless_controller_wtp_profile_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'wireless_controller_wtp_profile': {
'allowaccess': 'telnet',
'ap_country': 'NA',
'ble_profile': 'test_value_5',
'comment': 'Comment.',
'control_message_offload': 'ebp-frame',
'dtls_in_kernel': 'enable',
'dtls_policy': 'clear-text',
'energy_efficient_ethernet': 'enable',
'ext_info_enable': 'enable',
'handoff_roaming': 'enable',
'handoff_rssi': '13',
'handoff_sta_thresh': '14',
'ip_fragment_preventing': 'tcp-mss-adjust',
'led_state': 'enable',
'lldp': 'enable',
'login_passwd': 'test_value_18',
'login_passwd_change': 'yes',
'max_clients': '20',
'name': 'default_name_21',
'poe_mode': 'auto',
'split_tunneling_acl_local_ap_subnet': 'enable',
'split_tunneling_acl_path': 'tunnel',
'tun_mtu_downlink': '25',
'tun_mtu_uplink': '26',
'wan_port_mode': 'wan-lan'
},
'vdom': 'root'}
is_error, changed, response = fortios_wireless_controller_wtp_profile.fortios_wireless_controller(input_data, fos_instance)
expected_data = {
'allowaccess': 'telnet',
'ap-country': 'NA',
'ble-profile': 'test_value_5',
'comment': 'Comment.',
'control-message-offload': 'ebp-frame',
'dtls-in-kernel': 'enable',
'dtls-policy': 'clear-text',
'energy-efficient-ethernet': 'enable',
'ext-info-enable': 'enable',
'handoff-roaming': 'enable',
'handoff-rssi': '13',
'handoff-sta-thresh': '14',
'ip-fragment-preventing': 'tcp-mss-adjust',
'led-state': 'enable',
'lldp': 'enable',
'login-passwd': 'test_value_18',
'login-passwd-change': 'yes',
'max-clients': '20',
'name': 'default_name_21',
'poe-mode': 'auto',
'split-tunneling-acl-local-ap-subnet': 'enable',
'split-tunneling-acl-path': 'tunnel',
'tun-mtu-downlink': '25',
'tun-mtu-uplink': '26',
'wan-port-mode': 'wan-lan'
}
set_method_mock.assert_called_with('wireless-controller', 'wtp-profile', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_wireless_controller_wtp_profile_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'wireless_controller_wtp_profile': {
'random_attribute_not_valid': 'tag',
'allowaccess': 'telnet',
'ap_country': 'NA',
'ble_profile': 'test_value_5',
'comment': 'Comment.',
'control_message_offload': 'ebp-frame',
'dtls_in_kernel': 'enable',
'dtls_policy': 'clear-text',
'energy_efficient_ethernet': 'enable',
'ext_info_enable': 'enable',
'handoff_roaming': 'enable',
'handoff_rssi': '13',
'handoff_sta_thresh': '14',
'ip_fragment_preventing': 'tcp-mss-adjust',
'led_state': 'enable',
'lldp': 'enable',
'login_passwd': 'test_value_18',
'login_passwd_change': 'yes',
'max_clients': '20',
'name': 'default_name_21',
'poe_mode': 'auto',
'split_tunneling_acl_local_ap_subnet': 'enable',
'split_tunneling_acl_path': 'tunnel',
'tun_mtu_downlink': '25',
'tun_mtu_uplink': '26',
'wan_port_mode': 'wan-lan'
},
'vdom': 'root'}
is_error, changed, response = fortios_wireless_controller_wtp_profile.fortios_wireless_controller(input_data, fos_instance)
expected_data = {
'allowaccess': 'telnet',
'ap-country': 'NA',
'ble-profile': 'test_value_5',
'comment': 'Comment.',
'control-message-offload': 'ebp-frame',
'dtls-in-kernel': 'enable',
'dtls-policy': 'clear-text',
'energy-efficient-ethernet': 'enable',
'ext-info-enable': 'enable',
'handoff-roaming': 'enable',
'handoff-rssi': '13',
'handoff-sta-thresh': '14',
'ip-fragment-preventing': 'tcp-mss-adjust',
'led-state': 'enable',
'lldp': 'enable',
'login-passwd': 'test_value_18',
'login-passwd-change': 'yes',
'max-clients': '20',
'name': 'default_name_21',
'poe-mode': 'auto',
'split-tunneling-acl-local-ap-subnet': 'enable',
'split-tunneling-acl-path': 'tunnel',
'tun-mtu-downlink': '25',
'tun-mtu-uplink': '26',
'wan-port-mode': 'wan-lan'
}
set_method_mock.assert_called_with('wireless-controller', 'wtp-profile', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
Loading…
Cancel
Save