FortiOS modules for 2.9 - 5 (#61062)

* FortiOS modules for 2.9 - 5

* Update fortios_firewall_vip.py

* Update fortios_firewall_vip6.py
pull/61170/head
Miguel Angel Muñoz González 5 years ago committed by Nilashish Chakraborty
parent 3373a2518a
commit 628aa3a808

@ -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_firewall_ttl_policy
short_description: Configure TTL policies in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure firewall feature and ttl_policy 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 firewall feature and ttl_policy 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,43 +41,57 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip adress.
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
firewall_ttl_policy:
description:
- Configure TTL policies.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
action:
description:
- Action to be performed on traffic matching this policy (default = deny).
- Action to be performed on traffic matching this policy .
type: str
choices:
- accept
- deny
@ -88,38 +99,47 @@ options:
description:
- ID.
required: true
type: int
schedule:
description:
- Schedule object from available options. Source firewall.schedule.onetime.name firewall.schedule.recurring.name firewall.schedule.group
.name.
type: str
service:
description:
- Service object(s) from available options. Separate multiple names with a space.
type: list
suboptions:
name:
description:
- Service name. Source firewall.service.custom.name firewall.service.group.name.
required: true
type: str
srcaddr:
description:
- Source address object(s) from available options. Separate multiple names with a space.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address.name firewall.addrgrp.name.
required: true
type: str
srcintf:
description:
- Source interface name from available interfaces. Source system.zone.name system.interface.name.
type: str
status:
description:
- Enable/disable this TTL policy.
type: str
choices:
- enable
- disable
ttl:
description:
- "Value/range to match against the packet's Time to Live value (format: ttl[ - ttl_high], 1 - 255)."
type: str
'''
EXAMPLES = '''
@ -129,6 +149,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure TTL policies.
fortios_firewall_ttl_policy:
@ -137,8 +158,8 @@ EXAMPLES = '''
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_ttl_policy:
state: "present"
action: "accept"
id: "4"
schedule: "<your_own_value> (source firewall.schedule.onetime.name firewall.schedule.recurring.name firewall.schedule.group.name)"
@ -213,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']:
@ -228,7 +251,7 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_ttl_policy_data(json):
@ -244,48 +267,66 @@ def filter_firewall_ttl_policy_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 firewall_ttl_policy(data, fos):
vdom = data['vdom']
state = data['state']
firewall_ttl_policy_data = data['firewall_ttl_policy']
filtered_data = filter_firewall_ttl_policy_data(firewall_ttl_policy_data)
if firewall_ttl_policy_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_firewall_ttl_policy_data(firewall_ttl_policy_data))
if state == "present":
return fos.set('firewall',
'ttl-policy',
data=filtered_data,
vdom=vdom)
elif firewall_ttl_policy_data['state'] == "absent":
elif state == "absent":
return fos.delete('firewall',
'ttl-policy',
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_firewall(data, fos):
login(data)
methodlist = ['firewall_ttl_policy']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['firewall_ttl_policy']:
resp = firewall_ttl_policy(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"]},
"firewall_ttl_policy": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"action": {"required": False, "type": "str",
"choices": ["accept", "deny"]},
"id": {"required": True, "type": "int"},
@ -309,15 +350,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_firewall(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_firewall(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

File diff suppressed because it is too large Load Diff

@ -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_firewall_vip46
short_description: Configure IPv4 to IPv6 virtual IPs in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure firewall feature and vip46 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 firewall feature and vip46 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,64 +41,84 @@ 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
firewall_vip46:
description:
- Configure IPv4 to IPv6 virtual IPs.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
arp-reply:
arp_reply:
description:
- Enable ARP reply.
type: str
choices:
- disable
- enable
color:
description:
- Color of icon on the GUI.
type: int
comment:
description:
- Comment.
type: str
extip:
description:
- Start-external-IP [-end-external-IP].
type: str
extport:
description:
- External service port.
type: str
id:
description:
- Custom defined id.
ldb-method:
type: int
ldb_method:
description:
- Load balance method.
type: str
choices:
- static
- round-robin
@ -112,69 +129,86 @@ options:
mappedip:
description:
- Start-mapped-IP [-end mapped-IP].
type: str
mappedport:
description:
- Mapped service port.
type: str
monitor:
description:
- Health monitors.
type: list
suboptions:
name:
description:
- Health monitor name. Source firewall.ldb-monitor.name.
required: true
type: str
name:
description:
- VIP46 name.
required: true
type: str
portforward:
description:
- Enable port forwarding.
type: str
choices:
- disable
- enable
protocol:
description:
- Mapped port protocol.
type: str
choices:
- tcp
- udp
realservers:
description:
- Real servers.
type: list
suboptions:
client-ip:
client_ip:
description:
- Restrict server to a client IP in this range.
type: str
healthcheck:
description:
- Per server health check.
type: str
choices:
- disable
- enable
- vip
holddown-interval:
holddown_interval:
description:
- Hold down interval.
type: int
id:
description:
- Real server ID.
required: true
type: int
ip:
description:
- Mapped server IPv6.
max-connections:
type: str
max_connections:
description:
- Maximum number of connections allowed to server.
type: int
monitor:
description:
- Health monitors. Source firewall.ldb-monitor.name.
type: str
port:
description:
- Mapped server port.
type: int
status:
description:
- Server administrative status.
type: str
choices:
- active
- standby
@ -182,31 +216,37 @@ options:
weight:
description:
- weight
server-type:
type: int
server_type:
description:
- Server type.
type: str
choices:
- http
- tcp
- udp
- ip
src-filter:
src_filter:
description:
- Source IP filter (x.x.x.x/x).
type: list
suboptions:
range:
description:
- Src-filter range.
required: true
type: str
type:
description:
- "VIP type: static NAT or server load balance."
type: str
choices:
- static-nat
- server-load-balance
uuid:
description:
- Universally Unique Identifier (UUID; automatically assigned but can be manually reset).
type: str
'''
EXAMPLES = '''
@ -216,6 +256,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure IPv4 to IPv6 virtual IPs.
fortios_firewall_vip46:
@ -223,15 +264,16 @@ EXAMPLES = '''
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_vip46:
state: "present"
arp-reply: "disable"
arp_reply: "disable"
color: "4"
comment: "Comment."
extip: "<your_own_value>"
extport: "<your_own_value>"
id: "8"
ldb-method: "static"
ldb_method: "static"
mappedip: "<your_own_value>"
mappedport: "<your_own_value>"
monitor:
@ -242,18 +284,18 @@ EXAMPLES = '''
protocol: "tcp"
realservers:
-
client-ip: "<your_own_value>"
client_ip: "<your_own_value>"
healthcheck: "disable"
holddown-interval: "20"
holddown_interval: "20"
id: "21"
ip: "<your_own_value>"
max-connections: "23"
max_connections: "23"
monitor: "<your_own_value> (source firewall.ldb-monitor.name)"
port: "25"
status: "active"
weight: "27"
server-type: "http"
src-filter:
server_type: "http"
src_filter:
-
range: "<your_own_value>"
type: "static-nat"
@ -280,7 +322,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
@ -320,14 +362,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']:
@ -335,16 +379,16 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_vip46_data(json):
option_list = ['arp-reply', 'color', 'comment',
option_list = ['arp_reply', 'color', 'comment',
'extip', 'extport', 'id',
'ldb-method', 'mappedip', 'mappedport',
'ldb_method', 'mappedip', 'mappedport',
'monitor', 'name', 'portforward',
'protocol', 'realservers', 'server-type',
'src-filter', 'type', 'uuid']
'protocol', 'realservers', 'server_type',
'src_filter', 'type', 'uuid']
dictionary = {}
for attribute in option_list:
@ -354,56 +398,74 @@ def filter_firewall_vip46_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 firewall_vip46(data, fos):
vdom = data['vdom']
state = data['state']
firewall_vip46_data = data['firewall_vip46']
filtered_data = filter_firewall_vip46_data(firewall_vip46_data)
if firewall_vip46_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_firewall_vip46_data(firewall_vip46_data))
if state == "present":
return fos.set('firewall',
'vip46',
data=filtered_data,
vdom=vdom)
elif firewall_vip46_data['state'] == "absent":
elif state == "absent":
return fos.delete('firewall',
'vip46',
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_firewall(data, fos):
login(data)
methodlist = ['firewall_vip46']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['firewall_vip46']:
resp = firewall_vip46(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"]},
"firewall_vip46": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"arp-reply": {"required": False, "type": "str",
"arp_reply": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"color": {"required": False, "type": "int"},
"comment": {"required": False, "type": "str"},
"extip": {"required": False, "type": "str"},
"extport": {"required": False, "type": "str"},
"id": {"required": False, "type": "int"},
"ldb-method": {"required": False, "type": "str",
"ldb_method": {"required": False, "type": "str",
"choices": ["static", "round-robin", "weighted",
"least-session", "least-rtt", "first-alive"]},
"mappedip": {"required": False, "type": "str"},
@ -419,23 +481,23 @@ def main():
"choices": ["tcp", "udp"]},
"realservers": {"required": False, "type": "list",
"options": {
"client-ip": {"required": False, "type": "str"},
"client_ip": {"required": False, "type": "str"},
"healthcheck": {"required": False, "type": "str",
"choices": ["disable", "enable", "vip"]},
"holddown-interval": {"required": False, "type": "int"},
"holddown_interval": {"required": False, "type": "int"},
"id": {"required": True, "type": "int"},
"ip": {"required": False, "type": "str"},
"max-connections": {"required": False, "type": "int"},
"max_connections": {"required": False, "type": "int"},
"monitor": {"required": False, "type": "str"},
"port": {"required": False, "type": "int"},
"status": {"required": False, "type": "str",
"choices": ["active", "standby", "disable"]},
"weight": {"required": False, "type": "int"}
}},
"server-type": {"required": False, "type": "str",
"server_type": {"required": False, "type": "str",
"choices": ["http", "tcp", "udp",
"ip"]},
"src-filter": {"required": False, "type": "list",
"src_filter": {"required": False, "type": "list",
"options": {
"range": {"required": True, "type": "str"}
}},
@ -449,15 +511,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_firewall(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_firewall(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(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_firewall_vip64
short_description: Configure IPv6 to IPv4 virtual IPs in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure firewall feature and vip64 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 firewall feature and vip64 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,64 +41,84 @@ 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
firewall_vip64:
description:
- Configure IPv6 to IPv4 virtual IPs.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
arp-reply:
arp_reply:
description:
- Enable ARP reply.
type: str
choices:
- disable
- enable
color:
description:
- Color of icon on the GUI.
type: int
comment:
description:
- Comment.
type: str
extip:
description:
- Start-external-IP [-end-external-IP].
type: str
extport:
description:
- External service port.
type: str
id:
description:
- Custom defined id.
ldb-method:
type: int
ldb_method:
description:
- Load balance method.
type: str
choices:
- static
- round-robin
@ -112,69 +129,86 @@ options:
mappedip:
description:
- Start-mapped-IP [-end-mapped-IP].
type: str
mappedport:
description:
- Mapped service port.
type: str
monitor:
description:
- Health monitors.
type: list
suboptions:
name:
description:
- Health monitor name. Source firewall.ldb-monitor.name.
required: true
type: str
name:
description:
- VIP64 name.
required: true
type: str
portforward:
description:
- Enable port forwarding.
type: str
choices:
- disable
- enable
protocol:
description:
- Mapped port protocol.
type: str
choices:
- tcp
- udp
realservers:
description:
- Real servers.
type: list
suboptions:
client-ip:
client_ip:
description:
- Restrict server to a client IP in this range.
type: str
healthcheck:
description:
- Per server health check.
type: str
choices:
- disable
- enable
- vip
holddown-interval:
holddown_interval:
description:
- Hold down interval.
type: int
id:
description:
- Real server ID.
required: true
type: int
ip:
description:
- Mapped server IP.
max-connections:
type: str
max_connections:
description:
- Maximum number of connections allowed to server.
type: int
monitor:
description:
- Health monitors. Source firewall.ldb-monitor.name.
type: str
port:
description:
- Mapped server port.
type: int
status:
description:
- Server administrative status.
type: str
choices:
- active
- standby
@ -182,31 +216,37 @@ options:
weight:
description:
- weight
server-type:
type: int
server_type:
description:
- Server type.
type: str
choices:
- http
- tcp
- udp
- ip
src-filter:
src_filter:
description:
- "Source IP6 filter (x:x:x:x:x:x:x:x/x)."
type: list
suboptions:
range:
description:
- Src-filter range.
required: true
type: str
type:
description:
- "VIP type: static NAT or server load balance."
type: str
choices:
- static-nat
- server-load-balance
uuid:
description:
- Universally Unique Identifier (UUID; automatically assigned but can be manually reset).
type: str
'''
EXAMPLES = '''
@ -216,6 +256,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure IPv6 to IPv4 virtual IPs.
fortios_firewall_vip64:
@ -223,15 +264,16 @@ EXAMPLES = '''
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_vip64:
state: "present"
arp-reply: "disable"
arp_reply: "disable"
color: "4"
comment: "Comment."
extip: "<your_own_value>"
extport: "<your_own_value>"
id: "8"
ldb-method: "static"
ldb_method: "static"
mappedip: "<your_own_value>"
mappedport: "<your_own_value>"
monitor:
@ -242,18 +284,18 @@ EXAMPLES = '''
protocol: "tcp"
realservers:
-
client-ip: "<your_own_value>"
client_ip: "<your_own_value>"
healthcheck: "disable"
holddown-interval: "20"
holddown_interval: "20"
id: "21"
ip: "<your_own_value>"
max-connections: "23"
max_connections: "23"
monitor: "<your_own_value> (source firewall.ldb-monitor.name)"
port: "25"
status: "active"
weight: "27"
server-type: "http"
src-filter:
server_type: "http"
src_filter:
-
range: "<your_own_value>"
type: "static-nat"
@ -280,7 +322,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
@ -320,14 +362,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']:
@ -335,16 +379,16 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_vip64_data(json):
option_list = ['arp-reply', 'color', 'comment',
option_list = ['arp_reply', 'color', 'comment',
'extip', 'extport', 'id',
'ldb-method', 'mappedip', 'mappedport',
'ldb_method', 'mappedip', 'mappedport',
'monitor', 'name', 'portforward',
'protocol', 'realservers', 'server-type',
'src-filter', 'type', 'uuid']
'protocol', 'realservers', 'server_type',
'src_filter', 'type', 'uuid']
dictionary = {}
for attribute in option_list:
@ -354,56 +398,74 @@ def filter_firewall_vip64_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 firewall_vip64(data, fos):
vdom = data['vdom']
state = data['state']
firewall_vip64_data = data['firewall_vip64']
filtered_data = filter_firewall_vip64_data(firewall_vip64_data)
if firewall_vip64_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_firewall_vip64_data(firewall_vip64_data))
if state == "present":
return fos.set('firewall',
'vip64',
data=filtered_data,
vdom=vdom)
elif firewall_vip64_data['state'] == "absent":
elif state == "absent":
return fos.delete('firewall',
'vip64',
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_firewall(data, fos):
login(data)
methodlist = ['firewall_vip64']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['firewall_vip64']:
resp = firewall_vip64(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"]},
"firewall_vip64": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"arp-reply": {"required": False, "type": "str",
"arp_reply": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"color": {"required": False, "type": "int"},
"comment": {"required": False, "type": "str"},
"extip": {"required": False, "type": "str"},
"extport": {"required": False, "type": "str"},
"id": {"required": False, "type": "int"},
"ldb-method": {"required": False, "type": "str",
"ldb_method": {"required": False, "type": "str",
"choices": ["static", "round-robin", "weighted",
"least-session", "least-rtt", "first-alive"]},
"mappedip": {"required": False, "type": "str"},
@ -419,23 +481,23 @@ def main():
"choices": ["tcp", "udp"]},
"realservers": {"required": False, "type": "list",
"options": {
"client-ip": {"required": False, "type": "str"},
"client_ip": {"required": False, "type": "str"},
"healthcheck": {"required": False, "type": "str",
"choices": ["disable", "enable", "vip"]},
"holddown-interval": {"required": False, "type": "int"},
"holddown_interval": {"required": False, "type": "int"},
"id": {"required": True, "type": "int"},
"ip": {"required": False, "type": "str"},
"max-connections": {"required": False, "type": "int"},
"max_connections": {"required": False, "type": "int"},
"monitor": {"required": False, "type": "str"},
"port": {"required": False, "type": "int"},
"status": {"required": False, "type": "str",
"choices": ["active", "standby", "disable"]},
"weight": {"required": False, "type": "int"}
}},
"server-type": {"required": False, "type": "str",
"server_type": {"required": False, "type": "str",
"choices": ["http", "tcp", "udp",
"ip"]},
"src-filter": {"required": False, "type": "list",
"src_filter": {"required": False, "type": "list",
"options": {
"range": {"required": True, "type": "str"}
}},
@ -449,15 +511,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_firewall(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_firewall(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(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_firewall_vipgrp
short_description: Configure IPv4 virtual IP groups in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure firewall feature and vipgrp 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 firewall feature and vipgrp 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,64 +41,84 @@ 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
firewall_vipgrp:
description:
- Configure IPv4 virtual IP groups.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
color:
description:
- Integer value to determine the color of the icon in the GUI (range 1 to 32, default = 0, which sets the value to 1).
- Integer value to determine the color of the icon in the GUI (range 1 to 32).
type: int
comments:
description:
- Comment.
type: str
interface:
description:
- interface Source system.interface.name.
type: str
member:
description:
- Member VIP objects of the group (Separate multiple objects with a space).
type: list
suboptions:
name:
description:
- VIP name. Source firewall.vip.name.
required: true
type: str
name:
description:
- VIP group name.
required: true
type: str
uuid:
description:
- Universally Unique Identifier (UUID; automatically assigned but can be manually reset).
type: str
'''
EXAMPLES = '''
@ -111,6 +128,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure IPv4 virtual IP groups.
fortios_firewall_vipgrp:
@ -118,8 +136,9 @@ EXAMPLES = '''
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_vipgrp:
state: "present"
color: "3"
comments: "<your_own_value>"
interface: "<your_own_value> (source system.interface.name)"
@ -150,7 +169,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
@ -190,14 +209,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']:
@ -205,7 +226,7 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_vipgrp_data(json):
@ -220,48 +241,66 @@ def filter_firewall_vipgrp_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 firewall_vipgrp(data, fos):
vdom = data['vdom']
state = data['state']
firewall_vipgrp_data = data['firewall_vipgrp']
filtered_data = filter_firewall_vipgrp_data(firewall_vipgrp_data)
if firewall_vipgrp_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_firewall_vipgrp_data(firewall_vipgrp_data))
if state == "present":
return fos.set('firewall',
'vipgrp',
data=filtered_data,
vdom=vdom)
elif firewall_vipgrp_data['state'] == "absent":
elif state == "absent":
return fos.delete('firewall',
'vipgrp',
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_firewall(data, fos):
login(data)
methodlist = ['firewall_vipgrp']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['firewall_vipgrp']:
resp = firewall_vipgrp(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"]},
"firewall_vipgrp": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"color": {"required": False, "type": "int"},
"comments": {"required": False, "type": "str"},
"interface": {"required": False, "type": "str"},
@ -278,15 +317,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_firewall(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_firewall(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(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_firewall_vipgrp46
short_description: Configure IPv4 to IPv6 virtual IP groups in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure firewall feature and vipgrp46 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 firewall feature and vipgrp46 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,61 +41,80 @@ 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
firewall_vipgrp46:
description:
- Configure IPv4 to IPv6 virtual IP groups.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
color:
description:
- Integer value to determine the color of the icon in the GUI (range 1 to 32, default = 0, which sets the value to 1).
- Integer value to determine the color of the icon in the GUI (range 1 to 32).
type: int
comments:
description:
- Comment.
type: str
member:
description:
- Member VIP objects of the group (Separate multiple objects with a space).
type: list
suboptions:
name:
description:
- VIP46 name. Source firewall.vip46.name.
required: true
type: str
name:
description:
- VIP46 group name.
required: true
type: str
uuid:
description:
- Universally Unique Identifier (UUID; automatically assigned but can be manually reset).
type: str
'''
EXAMPLES = '''
@ -108,6 +124,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure IPv4 to IPv6 virtual IP groups.
fortios_firewall_vipgrp46:
@ -115,8 +132,9 @@ EXAMPLES = '''
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_vipgrp46:
state: "present"
color: "3"
comments: "<your_own_value>"
member:
@ -146,7 +164,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
@ -186,14 +204,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']:
@ -201,7 +221,7 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_vipgrp46_data(json):
@ -216,48 +236,66 @@ def filter_firewall_vipgrp46_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 firewall_vipgrp46(data, fos):
vdom = data['vdom']
state = data['state']
firewall_vipgrp46_data = data['firewall_vipgrp46']
filtered_data = filter_firewall_vipgrp46_data(firewall_vipgrp46_data)
if firewall_vipgrp46_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_firewall_vipgrp46_data(firewall_vipgrp46_data))
if state == "present":
return fos.set('firewall',
'vipgrp46',
data=filtered_data,
vdom=vdom)
elif firewall_vipgrp46_data['state'] == "absent":
elif state == "absent":
return fos.delete('firewall',
'vipgrp46',
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_firewall(data, fos):
login(data)
methodlist = ['firewall_vipgrp46']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['firewall_vipgrp46']:
resp = firewall_vipgrp46(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"]},
"firewall_vipgrp46": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"color": {"required": False, "type": "int"},
"comments": {"required": False, "type": "str"},
"member": {"required": False, "type": "list",
@ -273,15 +311,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_firewall(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_firewall(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(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_firewall_vipgrp6
short_description: Configure IPv6 virtual IP groups in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure firewall feature and vipgrp6 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 firewall feature and vipgrp6 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,61 +41,80 @@ 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
firewall_vipgrp6:
description:
- Configure IPv6 virtual IP groups.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
color:
description:
- Integer value to determine the color of the icon in the GUI (range 1 to 32, default = 0, which sets the value to 1).
- Integer value to determine the color of the icon in the GUI (range 1 to 32).
type: int
comments:
description:
- Comment.
type: str
member:
description:
- Member VIP objects of the group (Separate multiple objects with a space).
type: list
suboptions:
name:
description:
- IPv6 VIP name. Source firewall.vip6.name.
required: true
type: str
name:
description:
- IPv6 VIP group name.
required: true
type: str
uuid:
description:
- Universally Unique Identifier (UUID; automatically assigned but can be manually reset).
type: str
'''
EXAMPLES = '''
@ -108,6 +124,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure IPv6 virtual IP groups.
fortios_firewall_vipgrp6:
@ -115,8 +132,9 @@ EXAMPLES = '''
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_vipgrp6:
state: "present"
color: "3"
comments: "<your_own_value>"
member:
@ -146,7 +164,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
@ -186,14 +204,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']:
@ -201,7 +221,7 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_vipgrp6_data(json):
@ -216,48 +236,66 @@ def filter_firewall_vipgrp6_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 firewall_vipgrp6(data, fos):
vdom = data['vdom']
state = data['state']
firewall_vipgrp6_data = data['firewall_vipgrp6']
filtered_data = filter_firewall_vipgrp6_data(firewall_vipgrp6_data)
if firewall_vipgrp6_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_firewall_vipgrp6_data(firewall_vipgrp6_data))
if state == "present":
return fos.set('firewall',
'vipgrp6',
data=filtered_data,
vdom=vdom)
elif firewall_vipgrp6_data['state'] == "absent":
elif state == "absent":
return fos.delete('firewall',
'vipgrp6',
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_firewall(data, fos):
login(data)
methodlist = ['firewall_vipgrp6']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['firewall_vipgrp6']:
resp = firewall_vipgrp6(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"]},
"firewall_vipgrp6": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"color": {"required": False, "type": "int"},
"comments": {"required": False, "type": "str"},
"member": {"required": False, "type": "list",
@ -273,15 +311,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_firewall(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_firewall(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(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_firewall_vipgrp64
short_description: Configure IPv6 to IPv4 virtual IP groups in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure firewall feature and vipgrp64 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 firewall feature and vipgrp64 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,61 +41,80 @@ 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
firewall_vipgrp64:
description:
- Configure IPv6 to IPv4 virtual IP groups.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
color:
description:
- Integer value to determine the color of the icon in the GUI (range 1 to 32, default = 0, which sets the value to 1).
- Integer value to determine the color of the icon in the GUI (range 1 to 32).
type: int
comments:
description:
- Comment.
type: str
member:
description:
- Member VIP objects of the group (Separate multiple objects with a space).
type: list
suboptions:
name:
description:
- VIP64 name. Source firewall.vip64.name.
required: true
type: str
name:
description:
- VIP64 group name.
required: true
type: str
uuid:
description:
- Universally Unique Identifier (UUID; automatically assigned but can be manually reset).
type: str
'''
EXAMPLES = '''
@ -108,6 +124,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure IPv6 to IPv4 virtual IP groups.
fortios_firewall_vipgrp64:
@ -115,8 +132,9 @@ EXAMPLES = '''
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_vipgrp64:
state: "present"
color: "3"
comments: "<your_own_value>"
member:
@ -146,7 +164,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
@ -186,14 +204,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']:
@ -201,7 +221,7 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_vipgrp64_data(json):
@ -216,48 +236,66 @@ def filter_firewall_vipgrp64_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 firewall_vipgrp64(data, fos):
vdom = data['vdom']
state = data['state']
firewall_vipgrp64_data = data['firewall_vipgrp64']
filtered_data = filter_firewall_vipgrp64_data(firewall_vipgrp64_data)
if firewall_vipgrp64_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_firewall_vipgrp64_data(firewall_vipgrp64_data))
if state == "present":
return fos.set('firewall',
'vipgrp64',
data=filtered_data,
vdom=vdom)
elif firewall_vipgrp64_data['state'] == "absent":
elif state == "absent":
return fos.delete('firewall',
'vipgrp64',
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_firewall(data, fos):
login(data)
methodlist = ['firewall_vipgrp64']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['firewall_vipgrp64']:
resp = firewall_vipgrp64(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"]},
"firewall_vipgrp64": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"color": {"required": False, "type": "int"},
"comments": {"required": False, "type": "str"},
"member": {"required": False, "type": "list",
@ -273,15 +311,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_firewall(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_firewall(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -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_firewall_wildcard_fqdn_custom
short_description: Config global/VDOM Wildcard FQDN address in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure firewall_wildcard_fqdn feature and custom 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 firewall_wildcard_fqdn feature and custom 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,62 +41,81 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip adress.
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
firewall_wildcard_fqdn_custom:
description:
- Config global/VDOM Wildcard FQDN address.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
color:
description:
- GUI icon color.
type: int
comment:
description:
- Comment.
type: str
name:
description:
- Address name.
required: true
type: str
uuid:
description:
- Universally Unique Identifier (UUID; automatically assigned but can be manually reset).
type: str
visibility:
description:
- Enable/disable address visibility.
type: str
choices:
- enable
- disable
wildcard-fqdn:
wildcard_fqdn:
description:
- Wildcard FQDN.
type: str
'''
EXAMPLES = '''
@ -109,6 +125,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Config global/VDOM Wildcard FQDN address.
fortios_firewall_wildcard_fqdn_custom:
@ -117,14 +134,14 @@ EXAMPLES = '''
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_wildcard_fqdn_custom:
state: "present"
color: "3"
comment: "Comment."
name: "default_name_5"
uuid: "<your_own_value>"
visibility: "enable"
wildcard-fqdn: "<your_own_value>"
wildcard_fqdn: "<your_own_value>"
'''
RETURN = '''
@ -187,14 +204,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']:
@ -202,12 +221,12 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_wildcard_fqdn_custom_data(json):
option_list = ['color', 'comment', 'name',
'uuid', 'visibility', 'wildcard-fqdn']
'uuid', 'visibility', 'wildcard_fqdn']
dictionary = {}
for attribute in option_list:
@ -217,55 +236,73 @@ def filter_firewall_wildcard_fqdn_custom_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 firewall_wildcard_fqdn_custom(data, fos):
vdom = data['vdom']
state = data['state']
firewall_wildcard_fqdn_custom_data = data['firewall_wildcard_fqdn_custom']
filtered_data = filter_firewall_wildcard_fqdn_custom_data(firewall_wildcard_fqdn_custom_data)
if firewall_wildcard_fqdn_custom_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_firewall_wildcard_fqdn_custom_data(firewall_wildcard_fqdn_custom_data))
if state == "present":
return fos.set('firewall.wildcard-fqdn',
'custom',
data=filtered_data,
vdom=vdom)
elif firewall_wildcard_fqdn_custom_data['state'] == "absent":
elif state == "absent":
return fos.delete('firewall.wildcard-fqdn',
'custom',
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_firewall_wildcard_fqdn(data, fos):
login(data)
methodlist = ['firewall_wildcard_fqdn_custom']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['firewall_wildcard_fqdn_custom']:
resp = firewall_wildcard_fqdn_custom(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"]},
"firewall_wildcard_fqdn_custom": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"color": {"required": False, "type": "int"},
"comment": {"required": False, "type": "str"},
"name": {"required": True, "type": "str"},
"uuid": {"required": False, "type": "str"},
"visibility": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"wildcard-fqdn": {"required": False, "type": "str"}
"wildcard_fqdn": {"required": False, "type": "str"}
}
}
@ -273,15 +310,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_firewall_wildcard_fqdn(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_firewall_wildcard_fqdn(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_firewall_wildcard_fqdn(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -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_firewall_wildcard_fqdn_group
short_description: Config global Wildcard FQDN address groups in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure firewall_wildcard_fqdn feature and group 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 firewall_wildcard_fqdn feature and group 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,64 +41,84 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip adress.
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
firewall_wildcard_fqdn_group:
description:
- Config global Wildcard FQDN address groups.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
color:
description:
- GUI icon color.
type: int
comment:
description:
- Comment.
type: str
member:
description:
- Address group members.
type: list
suboptions:
name:
description:
- Address name. Source firewall.wildcard-fqdn.custom.name.
required: true
type: str
name:
description:
- Address group name.
required: true
type: str
uuid:
description:
- Universally Unique Identifier (UUID; automatically assigned but can be manually reset).
type: str
visibility:
description:
- Enable/disable address visibility.
type: str
choices:
- enable
- disable
@ -114,6 +131,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Config global Wildcard FQDN address groups.
fortios_firewall_wildcard_fqdn_group:
@ -122,8 +140,8 @@ EXAMPLES = '''
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_wildcard_fqdn_group:
state: "present"
color: "3"
comment: "Comment."
member:
@ -194,14 +212,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,7 +229,7 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_wildcard_fqdn_group_data(json):
@ -224,48 +244,66 @@ def filter_firewall_wildcard_fqdn_group_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 firewall_wildcard_fqdn_group(data, fos):
vdom = data['vdom']
state = data['state']
firewall_wildcard_fqdn_group_data = data['firewall_wildcard_fqdn_group']
filtered_data = filter_firewall_wildcard_fqdn_group_data(firewall_wildcard_fqdn_group_data)
if firewall_wildcard_fqdn_group_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_firewall_wildcard_fqdn_group_data(firewall_wildcard_fqdn_group_data))
if state == "present":
return fos.set('firewall.wildcard-fqdn',
'group',
data=filtered_data,
vdom=vdom)
elif firewall_wildcard_fqdn_group_data['state'] == "absent":
elif state == "absent":
return fos.delete('firewall.wildcard-fqdn',
'group',
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_firewall_wildcard_fqdn(data, fos):
login(data)
methodlist = ['firewall_wildcard_fqdn_group']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['firewall_wildcard_fqdn_group']:
resp = firewall_wildcard_fqdn_group(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"]},
"firewall_wildcard_fqdn_group": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"color": {"required": False, "type": "int"},
"comment": {"required": False, "type": "str"},
"member": {"required": False, "type": "list",
@ -283,15 +321,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_firewall_wildcard_fqdn(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_firewall_wildcard_fqdn(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_firewall_wildcard_fqdn(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -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_ftp_proxy_explicit
short_description: Configure explicit FTP proxy settings in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure ftp_proxy feature and explicit 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 ftp_proxy feature and explicit 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,52 +41,67 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip adress.
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
ftp_proxy_explicit:
description:
- Configure explicit FTP proxy settings.
default: null
type: dict
suboptions:
incoming-ip:
incoming_ip:
description:
- Accept incoming FTP requests from this IP address. An interface must have this IP address.
incoming-port:
type: str
incoming_port:
description:
- Accept incoming FTP requests on one or more ports.
outgoing-ip:
type: str
outgoing_ip:
description:
- Outgoing FTP requests will leave from this IP address. An interface must have this IP address.
sec-default-action:
type: str
sec_default_action:
description:
- Accept or deny explicit FTP proxy sessions when no FTP proxy firewall policy exists.
type: str
choices:
- accept
- deny
status:
description:
- Enable/disable the explicit FTP proxy.
type: str
choices:
- enable
- disable
@ -102,6 +114,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure explicit FTP proxy settings.
fortios_ftp_proxy_explicit:
@ -111,10 +124,10 @@ EXAMPLES = '''
vdom: "{{ vdom }}"
https: "False"
ftp_proxy_explicit:
incoming-ip: "<your_own_value>"
incoming-port: "<your_own_value>"
outgoing-ip: "<your_own_value>"
sec-default-action: "accept"
incoming_ip: "<your_own_value>"
incoming_port: "<your_own_value>"
outgoing_ip: "<your_own_value>"
sec_default_action: "accept"
status: "enable"
'''
@ -178,14 +191,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']:
@ -193,12 +208,12 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_ftp_proxy_explicit_data(json):
option_list = ['incoming-ip', 'incoming-port', 'outgoing-ip',
'sec-default-action', 'status']
option_list = ['incoming_ip', 'incoming_port', 'outgoing_ip',
'sec_default_action', 'status']
dictionary = {}
for attribute in option_list:
@ -208,43 +223,60 @@ def filter_ftp_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 ftp_proxy_explicit(data, fos):
vdom = data['vdom']
ftp_proxy_explicit_data = data['ftp_proxy_explicit']
filtered_data = filter_ftp_proxy_explicit_data(ftp_proxy_explicit_data)
filtered_data = underscore_to_hyphen(filter_ftp_proxy_explicit_data(ftp_proxy_explicit_data))
return fos.set('ftp-proxy',
'explicit',
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_ftp_proxy(data, fos):
login(data)
methodlist = ['ftp_proxy_explicit']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['ftp_proxy_explicit']:
resp = ftp_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},
"ftp_proxy_explicit": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"incoming-ip": {"required": False, "type": "str"},
"incoming-port": {"required": False, "type": "str"},
"outgoing-ip": {"required": False, "type": "str"},
"sec-default-action": {"required": False, "type": "str",
"incoming_ip": {"required": False, "type": "str"},
"incoming_port": {"required": False, "type": "str"},
"outgoing_ip": {"required": False, "type": "str"},
"sec_default_action": {"required": False, "type": "str",
"choices": ["accept", "deny"]},
"status": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
@ -255,15 +287,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_ftp_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_ftp_proxy(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_ftp_proxy(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -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_icap_profile
short_description: Configure ICAP profiles in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure icap feature and profile 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 icap feature and profile 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,43 +41,57 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip adress.
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
icap_profile:
description:
- Configure ICAP profiles.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
methods:
description:
- The allowed HTTP methods that will be sent to ICAP server for further processing.
type: str
choices:
- delete
- get
@ -94,48 +105,59 @@ options:
description:
- ICAP profile name.
required: true
replacemsg-group:
type: str
replacemsg_group:
description:
- Replacement message group. Source system.replacemsg-group.name.
type: str
request:
description:
- Enable/disable whether an HTTP request is passed to an ICAP server.
type: str
choices:
- disable
- enable
request-failure:
request_failure:
description:
- Action to take if the ICAP server cannot be contacted when processing an HTTP request.
type: str
choices:
- error
- bypass
request-path:
request_path:
description:
- Path component of the ICAP URI that identifies the HTTP request processing service.
request-server:
type: str
request_server:
description:
- ICAP server to use for an HTTP request. Source icap.server.name.
type: str
response:
description:
- Enable/disable whether an HTTP response is passed to an ICAP server.
type: str
choices:
- disable
- enable
response-failure:
response_failure:
description:
- Action to take if the ICAP server cannot be contacted when processing an HTTP response.
type: str
choices:
- error
- bypass
response-path:
response_path:
description:
- Path component of the ICAP URI that identifies the HTTP response processing service.
response-server:
type: str
response_server:
description:
- ICAP server to use for an HTTP response. Source icap.server.name.
streaming-content-bypass:
type: str
streaming_content_bypass:
description:
- Enable/disable bypassing of ICAP server for streaming content.
type: str
choices:
- disable
- enable
@ -148,6 +170,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure ICAP profiles.
fortios_icap_profile:
@ -156,20 +179,20 @@ EXAMPLES = '''
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
icap_profile:
state: "present"
methods: "delete"
name: "default_name_4"
replacemsg-group: "<your_own_value> (source system.replacemsg-group.name)"
replacemsg_group: "<your_own_value> (source system.replacemsg-group.name)"
request: "disable"
request-failure: "error"
request-path: "<your_own_value>"
request-server: "<your_own_value> (source icap.server.name)"
request_failure: "error"
request_path: "<your_own_value>"
request_server: "<your_own_value> (source icap.server.name)"
response: "disable"
response-failure: "error"
response-path: "<your_own_value>"
response-server: "<your_own_value> (source icap.server.name)"
streaming-content-bypass: "disable"
response_failure: "error"
response_path: "<your_own_value>"
response_server: "<your_own_value> (source icap.server.name)"
streaming_content_bypass: "disable"
'''
RETURN = '''
@ -232,14 +255,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']:
@ -247,14 +272,14 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_icap_profile_data(json):
option_list = ['methods', 'name', 'replacemsg-group',
'request', 'request-failure', 'request-path',
'request-server', 'response', 'response-failure',
'response-path', 'response-server', 'streaming-content-bypass']
option_list = ['methods', 'name', 'replacemsg_group',
'request', 'request_failure', 'request_path',
'request_server', 'response', 'response_failure',
'response_path', 'response_server', 'streaming_content_bypass']
dictionary = {}
for attribute in option_list:
@ -264,67 +289,85 @@ def filter_icap_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 icap_profile(data, fos):
vdom = data['vdom']
state = data['state']
icap_profile_data = data['icap_profile']
filtered_data = filter_icap_profile_data(icap_profile_data)
if icap_profile_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_icap_profile_data(icap_profile_data))
if state == "present":
return fos.set('icap',
'profile',
data=filtered_data,
vdom=vdom)
elif icap_profile_data['state'] == "absent":
elif state == "absent":
return fos.delete('icap',
'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_icap(data, fos):
login(data)
methodlist = ['icap_profile']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['icap_profile']:
resp = icap_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"]},
"icap_profile": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"methods": {"required": False, "type": "str",
"choices": ["delete", "get", "head",
"options", "post", "put",
"trace", "other"]},
"name": {"required": True, "type": "str"},
"replacemsg-group": {"required": False, "type": "str"},
"replacemsg_group": {"required": False, "type": "str"},
"request": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"request-failure": {"required": False, "type": "str",
"request_failure": {"required": False, "type": "str",
"choices": ["error", "bypass"]},
"request-path": {"required": False, "type": "str"},
"request-server": {"required": False, "type": "str"},
"request_path": {"required": False, "type": "str"},
"request_server": {"required": False, "type": "str"},
"response": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"response-failure": {"required": False, "type": "str",
"response_failure": {"required": False, "type": "str",
"choices": ["error", "bypass"]},
"response-path": {"required": False, "type": "str"},
"response-server": {"required": False, "type": "str"},
"streaming-content-bypass": {"required": False, "type": "str",
"response_path": {"required": False, "type": "str"},
"response_server": {"required": False, "type": "str"},
"streaming_content_bypass": {"required": False, "type": "str",
"choices": ["disable", "enable"]}
}
@ -333,15 +376,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_icap(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_icap(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_icap(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -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_icap_server
short_description: Configure ICAP servers in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure icap feature and server 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 icap feature and server 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,62 +41,81 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip adress.
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
icap_server:
description:
- Configure ICAP servers.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
ip-address:
ip_address:
description:
- IPv4 address of the ICAP server.
ip-version:
type: str
ip_version:
description:
- IP version.
type: str
choices:
- 4
- 6
ip6-address:
ip6_address:
description:
- IPv6 address of the ICAP server.
max-connections:
type: str
max_connections:
description:
- Maximum number of concurrent connections to ICAP server.
type: int
name:
description:
- Server name.
required: true
type: str
port:
description:
- ICAP server port.
type: int
'''
EXAMPLES = '''
@ -109,6 +125,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure ICAP servers.
fortios_icap_server:
@ -117,12 +134,12 @@ EXAMPLES = '''
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
icap_server:
state: "present"
ip-address: "<your_own_value>"
ip-version: "4"
ip6-address: "<your_own_value>"
max-connections: "6"
ip_address: "<your_own_value>"
ip_version: "4"
ip6_address: "<your_own_value>"
max_connections: "6"
name: "default_name_7"
port: "8"
'''
@ -187,14 +204,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']:
@ -202,12 +221,12 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_icap_server_data(json):
option_list = ['ip-address', 'ip-version', 'ip6-address',
'max-connections', 'name', 'port']
option_list = ['ip_address', 'ip_version', 'ip6_address',
'max_connections', 'name', 'port']
dictionary = {}
for attribute in option_list:
@ -217,53 +236,71 @@ def filter_icap_server_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 icap_server(data, fos):
vdom = data['vdom']
state = data['state']
icap_server_data = data['icap_server']
filtered_data = filter_icap_server_data(icap_server_data)
if icap_server_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_icap_server_data(icap_server_data))
if state == "present":
return fos.set('icap',
'server',
data=filtered_data,
vdom=vdom)
elif icap_server_data['state'] == "absent":
elif state == "absent":
return fos.delete('icap',
'server',
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_icap(data, fos):
login(data)
methodlist = ['icap_server']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['icap_server']:
resp = icap_server(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"]},
"icap_server": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"ip-address": {"required": False, "type": "str"},
"ip-version": {"required": False, "type": "str",
"ip_address": {"required": False, "type": "str"},
"ip_version": {"required": False, "type": "str",
"choices": ["4", "6"]},
"ip6-address": {"required": False, "type": "str"},
"max-connections": {"required": False, "type": "int"},
"ip6_address": {"required": False, "type": "str"},
"max_connections": {"required": False, "type": "int"},
"name": {"required": True, "type": "str"},
"port": {"required": False, "type": "int"}
@ -273,15 +310,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_icap(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_icap(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_icap(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -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_ips_custom
short_description: Configure IPS custom signature in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure ips feature and custom 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 ips feature and custom 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,88 +41,114 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip adress.
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
ips_custom:
description:
- Configure IPS custom signature.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
action:
description:
- Default action (pass or block) for this signature.
type: str
choices:
- pass
- block
application:
description:
- Applications to be protected. Blank for all applications.
type: str
comment:
description:
- Comment.
type: str
location:
description:
- Protect client or server traffic.
type: str
log:
description:
- Enable/disable logging.
type: str
choices:
- disable
- enable
log-packet:
log_packet:
description:
- Enable/disable packet logging.
type: str
choices:
- disable
- enable
os:
description:
- Operating system(s) that the signature protects. Blank for all operating systems.
type: str
protocol:
description:
- Protocol(s) that the signature scans. Blank for all protocols.
rule-id:
type: str
rule_id:
description:
- Signature ID.
type: int
severity:
description:
- Relative severity of the signature, from info to critical. Log messages generated by the signature include the severity.
sig-name:
type: str
sig_name:
description:
- Signature name.
type: str
signature:
description:
- Custom signature enclosed in single quotes.
type: str
status:
description:
- Enable/disable this signature.
type: str
choices:
- disable
- enable
@ -133,6 +156,7 @@ options:
description:
- Signature tag.
required: true
type: str
'''
EXAMPLES = '''
@ -142,6 +166,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure IPS custom signature.
fortios_ips_custom:
@ -150,19 +175,19 @@ EXAMPLES = '''
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
ips_custom:
state: "present"
action: "pass"
application: "<your_own_value>"
comment: "Comment."
location: "<your_own_value>"
log: "disable"
log-packet: "disable"
log_packet: "disable"
os: "<your_own_value>"
protocol: "<your_own_value>"
rule-id: "11"
rule_id: "11"
severity: "<your_own_value>"
sig-name: "<your_own_value>"
sig_name: "<your_own_value>"
signature: "<your_own_value>"
status: "disable"
tag: "<your_own_value>"
@ -228,14 +253,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']:
@ -243,14 +270,14 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_ips_custom_data(json):
option_list = ['action', 'application', 'comment',
'location', 'log', 'log-packet',
'os', 'protocol', 'rule-id',
'severity', 'sig-name', 'signature',
'location', 'log', 'log_packet',
'os', 'protocol', 'rule_id',
'severity', 'sig_name', 'signature',
'status', 'tag']
dictionary = {}
@ -261,48 +288,66 @@ def filter_ips_custom_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 ips_custom(data, fos):
vdom = data['vdom']
state = data['state']
ips_custom_data = data['ips_custom']
filtered_data = filter_ips_custom_data(ips_custom_data)
if ips_custom_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_ips_custom_data(ips_custom_data))
if state == "present":
return fos.set('ips',
'custom',
data=filtered_data,
vdom=vdom)
elif ips_custom_data['state'] == "absent":
elif state == "absent":
return fos.delete('ips',
'custom',
mkey=filtered_data['tag'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_ips(data, fos):
login(data)
methodlist = ['ips_custom']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['ips_custom']:
resp = ips_custom(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"]},
"ips_custom": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"action": {"required": False, "type": "str",
"choices": ["pass", "block"]},
"application": {"required": False, "type": "str"},
@ -310,13 +355,13 @@ def main():
"location": {"required": False, "type": "str"},
"log": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"log-packet": {"required": False, "type": "str",
"log_packet": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"os": {"required": False, "type": "str"},
"protocol": {"required": False, "type": "str"},
"rule-id": {"required": False, "type": "int"},
"rule_id": {"required": False, "type": "int"},
"severity": {"required": False, "type": "str"},
"sig-name": {"required": False, "type": "str"},
"sig_name": {"required": False, "type": "str"},
"signature": {"required": False, "type": "str"},
"status": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
@ -328,15 +373,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_ips(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_ips(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_ips(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -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_ips_decoder
short_description: Configure IPS decoder in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure ips feature and decoder 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 ips feature and decoder 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,55 +41,72 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip adress.
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
ips_decoder:
description:
- Configure IPS decoder.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
name:
description:
- Decoder name.
required: true
type: str
parameter:
description:
- IPS group parameters.
type: list
suboptions:
name:
description:
- Parameter name.
required: true
type: str
value:
description:
- Parameter value.
type: str
'''
EXAMPLES = '''
@ -102,6 +116,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure IPS decoder.
fortios_ips_decoder:
@ -110,8 +125,8 @@ EXAMPLES = '''
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
ips_decoder:
state: "present"
name: "default_name_3"
parameter:
-
@ -179,14 +194,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']:
@ -194,7 +211,7 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_ips_decoder_data(json):
@ -208,48 +225,66 @@ def filter_ips_decoder_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 ips_decoder(data, fos):
vdom = data['vdom']
state = data['state']
ips_decoder_data = data['ips_decoder']
filtered_data = filter_ips_decoder_data(ips_decoder_data)
if ips_decoder_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_ips_decoder_data(ips_decoder_data))
if state == "present":
return fos.set('ips',
'decoder',
data=filtered_data,
vdom=vdom)
elif ips_decoder_data['state'] == "absent":
elif state == "absent":
return fos.delete('ips',
'decoder',
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_ips(data, fos):
login(data)
methodlist = ['ips_decoder']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['ips_decoder']:
resp = ips_decoder(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"]},
"ips_decoder": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"name": {"required": True, "type": "str"},
"parameter": {"required": False, "type": "list",
"options": {
@ -263,15 +298,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_ips(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_ips(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_ips(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -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_ips_global
short_description: Configure IPS global parameter in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure ips feature and global 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 ips feature and global 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,37 +41,48 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip adress.
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
ips_global:
description:
- Configure IPS global parameter.
default: null
type: dict
suboptions:
anomaly-mode:
anomaly_mode:
description:
- Global blocking mode for rate-based anomalies.
type: str
choices:
- periodical
- continuous
@ -82,59 +90,71 @@ options:
description:
- Regular or extended IPS database. Regular protects against the latest common and in-the-wild attacks. Extended includes protection from
legacy attacks.
type: str
choices:
- regular
- extended
deep-app-insp-db-limit:
deep_app_insp_db_limit:
description:
- Limit on number of entries in deep application inspection database (1 - 2147483647, 0 = use recommended setting)
deep-app-insp-timeout:
type: int
deep_app_insp_timeout:
description:
- Timeout for Deep application inspection (1 - 2147483647 sec., 0 = use recommended setting).
engine-count:
type: int
engine_count:
description:
- Number of IPS engines running. If set to the default value of 0, FortiOS sets the number to optimize performance depending on the number
of CPU cores.
exclude-signatures:
type: int
exclude_signatures:
description:
- Excluded signatures.
type: str
choices:
- none
- industrial
fail-open:
fail_open:
description:
- Enable to allow traffic if the IPS process crashes. Default is disable and IPS traffic is blocked when the IPS process crashes.
type: str
choices:
- enable
- disable
intelligent-mode:
intelligent_mode:
description:
- Enable/disable IPS adaptive scanning (intelligent mode). Intelligent mode optimizes the scanning method for the type of traffic.
type: str
choices:
- enable
- disable
session-limit-mode:
session_limit_mode:
description:
- Method of counting concurrent sessions used by session limit anomalies. Choose between greater accuracy (accurate) or improved
performance (heuristics).
type: str
choices:
- accurate
- heuristic
skype-client-public-ipaddr:
skype_client_public_ipaddr:
description:
- Public IP addresses of your network that receive Skype sessions. Helps identify Skype sessions. Separate IP addresses with commas.
socket-size:
type: str
socket_size:
description:
- IPS socket buffer size (0 - 256 MB). Default depends on available memory. Can be changed to tune performance.
sync-session-ttl:
type: int
sync_session_ttl:
description:
- Enable/disable use of kernel session TTL for IPS sessions.
type: str
choices:
- enable
- disable
traffic-submit:
traffic_submit:
description:
- Enable/disable submitting attack data found by this FortiGate to FortiGuard.
type: str
choices:
- enable
- disable
@ -147,6 +167,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure IPS global parameter.
fortios_ips_global:
@ -156,19 +177,19 @@ EXAMPLES = '''
vdom: "{{ vdom }}"
https: "False"
ips_global:
anomaly-mode: "periodical"
anomaly_mode: "periodical"
database: "regular"
deep-app-insp-db-limit: "5"
deep-app-insp-timeout: "6"
engine-count: "7"
exclude-signatures: "none"
fail-open: "enable"
intelligent-mode: "enable"
session-limit-mode: "accurate"
skype-client-public-ipaddr: "<your_own_value>"
socket-size: "13"
sync-session-ttl: "enable"
traffic-submit: "enable"
deep_app_insp_db_limit: "5"
deep_app_insp_timeout: "6"
engine_count: "7"
exclude_signatures: "none"
fail_open: "enable"
intelligent_mode: "enable"
session_limit_mode: "accurate"
skype_client_public_ipaddr: "<your_own_value>"
socket_size: "13"
sync_session_ttl: "enable"
traffic_submit: "enable"
'''
RETURN = '''
@ -231,14 +252,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']:
@ -246,15 +269,15 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_ips_global_data(json):
option_list = ['anomaly-mode', 'database', 'deep-app-insp-db-limit',
'deep-app-insp-timeout', 'engine-count', 'exclude-signatures',
'fail-open', 'intelligent-mode', 'session-limit-mode',
'skype-client-public-ipaddr', 'socket-size', 'sync-session-ttl',
'traffic-submit']
option_list = ['anomaly_mode', 'database', 'deep_app_insp_db_limit',
'deep_app_insp_timeout', 'engine_count', 'exclude_signatures',
'fail_open', 'intelligent_mode', 'session_limit_mode',
'skype_client_public_ipaddr', 'socket_size', 'sync_session_ttl',
'traffic_submit']
dictionary = {}
for attribute in option_list:
@ -264,59 +287,76 @@ def filter_ips_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 ips_global(data, fos):
vdom = data['vdom']
ips_global_data = data['ips_global']
filtered_data = filter_ips_global_data(ips_global_data)
filtered_data = underscore_to_hyphen(filter_ips_global_data(ips_global_data))
return fos.set('ips',
'global',
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_ips(data, fos):
login(data)
methodlist = ['ips_global']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['ips_global']:
resp = ips_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},
"ips_global": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"anomaly-mode": {"required": False, "type": "str",
"anomaly_mode": {"required": False, "type": "str",
"choices": ["periodical", "continuous"]},
"database": {"required": False, "type": "str",
"choices": ["regular", "extended"]},
"deep-app-insp-db-limit": {"required": False, "type": "int"},
"deep-app-insp-timeout": {"required": False, "type": "int"},
"engine-count": {"required": False, "type": "int"},
"exclude-signatures": {"required": False, "type": "str",
"deep_app_insp_db_limit": {"required": False, "type": "int"},
"deep_app_insp_timeout": {"required": False, "type": "int"},
"engine_count": {"required": False, "type": "int"},
"exclude_signatures": {"required": False, "type": "str",
"choices": ["none", "industrial"]},
"fail-open": {"required": False, "type": "str",
"fail_open": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"intelligent-mode": {"required": False, "type": "str",
"intelligent_mode": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"session-limit-mode": {"required": False, "type": "str",
"session_limit_mode": {"required": False, "type": "str",
"choices": ["accurate", "heuristic"]},
"skype-client-public-ipaddr": {"required": False, "type": "str"},
"socket-size": {"required": False, "type": "int"},
"sync-session-ttl": {"required": False, "type": "str",
"skype_client_public_ipaddr": {"required": False, "type": "str"},
"socket_size": {"required": False, "type": "int"},
"sync_session_ttl": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"traffic-submit": {"required": False, "type": "str",
"traffic_submit": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
@ -325,15 +365,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_ips(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_ips(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_ips(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -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_ips_rule
short_description: Configure IPS rules in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure ips feature and rule 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 ips feature and rule 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,106 +41,137 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip adress.
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
ips_rule:
description:
- Configure IPS rules.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
action:
description:
- Action.
type: str
choices:
- pass
- block
application:
description:
- Vulnerable applications.
type: str
date:
description:
- Date.
type: int
group:
description:
- Group.
type: str
location:
description:
- Vulnerable location.
type: str
log:
description:
- Enable/disable logging.
type: str
choices:
- disable
- enable
log-packet:
log_packet:
description:
- Enable/disable packet logging.
type: str
choices:
- disable
- enable
metadata:
description:
- Meta data.
type: list
suboptions:
id:
description:
- ID.
required: true
type: int
metaid:
description:
- Meta ID.
type: int
valueid:
description:
- Value ID.
type: int
name:
description:
- Rule name.
required: true
type: str
os:
description:
- Vulnerable operation systems.
type: str
rev:
description:
- Revision.
rule-id:
type: int
rule_id:
description:
- Rule ID.
type: int
service:
description:
- Vulnerable service.
type: str
severity:
description:
- Severity.
type: str
status:
description:
- Enable/disable status.
type: str
choices:
- disable
- enable
@ -156,6 +184,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure IPS rules.
fortios_ips_rule:
@ -164,15 +193,15 @@ EXAMPLES = '''
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
ips_rule:
state: "present"
action: "pass"
application: "<your_own_value>"
date: "5"
group: "<your_own_value>"
location: "<your_own_value>"
log: "disable"
log-packet: "disable"
log_packet: "disable"
metadata:
-
id: "11"
@ -181,7 +210,7 @@ EXAMPLES = '''
name: "default_name_14"
os: "<your_own_value>"
rev: "16"
rule-id: "17"
rule_id: "17"
service: "<your_own_value>"
severity: "<your_own_value>"
status: "disable"
@ -247,14 +276,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']:
@ -262,14 +293,14 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_ips_rule_data(json):
option_list = ['action', 'application', 'date',
'group', 'location', 'log',
'log-packet', 'metadata', 'name',
'os', 'rev', 'rule-id',
'log_packet', 'metadata', 'name',
'os', 'rev', 'rule_id',
'service', 'severity', 'status']
dictionary = {}
@ -280,48 +311,66 @@ def filter_ips_rule_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 ips_rule(data, fos):
vdom = data['vdom']
state = data['state']
ips_rule_data = data['ips_rule']
filtered_data = filter_ips_rule_data(ips_rule_data)
if ips_rule_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_ips_rule_data(ips_rule_data))
if state == "present":
return fos.set('ips',
'rule',
data=filtered_data,
vdom=vdom)
elif ips_rule_data['state'] == "absent":
elif state == "absent":
return fos.delete('ips',
'rule',
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_ips(data, fos):
login(data)
methodlist = ['ips_rule']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['ips_rule']:
resp = ips_rule(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"]},
"ips_rule": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"action": {"required": False, "type": "str",
"choices": ["pass", "block"]},
"application": {"required": False, "type": "str"},
@ -330,7 +379,7 @@ def main():
"location": {"required": False, "type": "str"},
"log": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"log-packet": {"required": False, "type": "str",
"log_packet": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"metadata": {"required": False, "type": "list",
"options": {
@ -341,7 +390,7 @@ def main():
"name": {"required": True, "type": "str"},
"os": {"required": False, "type": "str"},
"rev": {"required": False, "type": "int"},
"rule-id": {"required": False, "type": "int"},
"rule_id": {"required": False, "type": "int"},
"service": {"required": False, "type": "str"},
"severity": {"required": False, "type": "str"},
"status": {"required": False, "type": "str",
@ -353,15 +402,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_ips(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_ips(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_ips(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -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_ips_rule_settings
short_description: Configure IPS rule setting in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure ips feature and rule_settings 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 ips feature and rule_settings 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,44 +41,58 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip adress.
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
ips_rule_settings:
description:
- Configure IPS rule setting.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
id:
description:
- Rule ID.
required: true
type: int
'''
EXAMPLES = '''
@ -91,6 +102,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure IPS rule setting.
fortios_ips_rule_settings:
@ -99,8 +111,8 @@ EXAMPLES = '''
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
ips_rule_settings:
state: "present"
id: "3"
'''
@ -164,14 +176,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']:
@ -179,7 +193,7 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_ips_rule_settings_data(json):
@ -193,48 +207,66 @@ def filter_ips_rule_settings_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 ips_rule_settings(data, fos):
vdom = data['vdom']
state = data['state']
ips_rule_settings_data = data['ips_rule_settings']
filtered_data = filter_ips_rule_settings_data(ips_rule_settings_data)
if ips_rule_settings_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_ips_rule_settings_data(ips_rule_settings_data))
if state == "present":
return fos.set('ips',
'rule-settings',
data=filtered_data,
vdom=vdom)
elif ips_rule_settings_data['state'] == "absent":
elif state == "absent":
return fos.delete('ips',
'rule-settings',
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_ips(data, fos):
login(data)
methodlist = ['ips_rule_settings']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['ips_rule_settings']:
resp = ips_rule_settings(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"]},
"ips_rule_settings": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"id": {"required": True, "type": "int"}
}
@ -243,15 +275,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_ips(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_ips(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_ips(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -3693,38 +3693,6 @@ lib/ansible/modules/network/fortios/fortios_firewall_DoS_policy.py validate-modu
lib/ansible/modules/network/fortios/fortios_firewall_DoS_policy6.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_policy.py validate-modules:E326
lib/ansible/modules/network/fortios/fortios_firewall_sniffer.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_ssl_ssh_profile.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_ssl_ssh_profile.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_ttl_policy.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_vip.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_vip.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_vip46.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_vip46.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_vip6.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_vip6.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_vip64.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_vip64.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_vipgrp.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_vipgrp46.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_vipgrp6.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_vipgrp64.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_wildcard_fqdn_custom.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_wildcard_fqdn_custom.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_wildcard_fqdn_group.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_ftp_proxy_explicit.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_ftp_proxy_explicit.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_icap_profile.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_icap_profile.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_icap_server.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_icap_server.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_ips_custom.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_ips_custom.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_ips_decoder.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_ips_global.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_ips_global.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_ips_rule.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_ips_rule.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_ips_rule_settings.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_ips_sensor.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_ips_sensor.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_ips_settings.py validate-modules:E336

@ -0,0 +1,309 @@
# 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_firewall_ssl_ssh_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_firewall_ssl_ssh_profile.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_ssl_ssh_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',
'firewall_ssl_ssh_profile': {
'caname': 'test_value_3',
'comment': 'Optional comments.',
'mapi_over_https': 'enable',
'name': 'default_name_6',
'rpc_over_https': 'enable',
'server_cert': 'test_value_8',
'server_cert_mode': 're-sign',
'ssl_anomalies_log': 'disable',
'ssl_exemptions_log': 'disable',
'untrusted_caname': 'test_value_12',
'use_ssl_server': 'disable',
'whitelist': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssl_ssh_profile.fortios_firewall(input_data, fos_instance)
expected_data = {
'caname': 'test_value_3',
'comment': 'Optional comments.',
'mapi-over-https': 'enable',
'name': 'default_name_6',
'rpc-over-https': 'enable',
'server-cert': 'test_value_8',
'server-cert-mode': 're-sign',
'ssl-anomalies-log': 'disable',
'ssl-exemptions-log': 'disable',
'untrusted-caname': 'test_value_12',
'use-ssl-server': 'disable',
'whitelist': 'enable'
}
set_method_mock.assert_called_with('firewall', 'ssl-ssh-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_firewall_ssl_ssh_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',
'firewall_ssl_ssh_profile': {
'caname': 'test_value_3',
'comment': 'Optional comments.',
'mapi_over_https': 'enable',
'name': 'default_name_6',
'rpc_over_https': 'enable',
'server_cert': 'test_value_8',
'server_cert_mode': 're-sign',
'ssl_anomalies_log': 'disable',
'ssl_exemptions_log': 'disable',
'untrusted_caname': 'test_value_12',
'use_ssl_server': 'disable',
'whitelist': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssl_ssh_profile.fortios_firewall(input_data, fos_instance)
expected_data = {
'caname': 'test_value_3',
'comment': 'Optional comments.',
'mapi-over-https': 'enable',
'name': 'default_name_6',
'rpc-over-https': 'enable',
'server-cert': 'test_value_8',
'server-cert-mode': 're-sign',
'ssl-anomalies-log': 'disable',
'ssl-exemptions-log': 'disable',
'untrusted-caname': 'test_value_12',
'use-ssl-server': 'disable',
'whitelist': 'enable'
}
set_method_mock.assert_called_with('firewall', 'ssl-ssh-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_firewall_ssl_ssh_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',
'firewall_ssl_ssh_profile': {
'caname': 'test_value_3',
'comment': 'Optional comments.',
'mapi_over_https': 'enable',
'name': 'default_name_6',
'rpc_over_https': 'enable',
'server_cert': 'test_value_8',
'server_cert_mode': 're-sign',
'ssl_anomalies_log': 'disable',
'ssl_exemptions_log': 'disable',
'untrusted_caname': 'test_value_12',
'use_ssl_server': 'disable',
'whitelist': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssl_ssh_profile.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'ssl-ssh-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_firewall_ssl_ssh_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',
'firewall_ssl_ssh_profile': {
'caname': 'test_value_3',
'comment': 'Optional comments.',
'mapi_over_https': 'enable',
'name': 'default_name_6',
'rpc_over_https': 'enable',
'server_cert': 'test_value_8',
'server_cert_mode': 're-sign',
'ssl_anomalies_log': 'disable',
'ssl_exemptions_log': 'disable',
'untrusted_caname': 'test_value_12',
'use_ssl_server': 'disable',
'whitelist': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssl_ssh_profile.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'ssl-ssh-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_firewall_ssl_ssh_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',
'firewall_ssl_ssh_profile': {
'caname': 'test_value_3',
'comment': 'Optional comments.',
'mapi_over_https': 'enable',
'name': 'default_name_6',
'rpc_over_https': 'enable',
'server_cert': 'test_value_8',
'server_cert_mode': 're-sign',
'ssl_anomalies_log': 'disable',
'ssl_exemptions_log': 'disable',
'untrusted_caname': 'test_value_12',
'use_ssl_server': 'disable',
'whitelist': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssl_ssh_profile.fortios_firewall(input_data, fos_instance)
expected_data = {
'caname': 'test_value_3',
'comment': 'Optional comments.',
'mapi-over-https': 'enable',
'name': 'default_name_6',
'rpc-over-https': 'enable',
'server-cert': 'test_value_8',
'server-cert-mode': 're-sign',
'ssl-anomalies-log': 'disable',
'ssl-exemptions-log': 'disable',
'untrusted-caname': 'test_value_12',
'use-ssl-server': 'disable',
'whitelist': 'enable'
}
set_method_mock.assert_called_with('firewall', 'ssl-ssh-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_firewall_ssl_ssh_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',
'firewall_ssl_ssh_profile': {
'random_attribute_not_valid': 'tag',
'caname': 'test_value_3',
'comment': 'Optional comments.',
'mapi_over_https': 'enable',
'name': 'default_name_6',
'rpc_over_https': 'enable',
'server_cert': 'test_value_8',
'server_cert_mode': 're-sign',
'ssl_anomalies_log': 'disable',
'ssl_exemptions_log': 'disable',
'untrusted_caname': 'test_value_12',
'use_ssl_server': 'disable',
'whitelist': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssl_ssh_profile.fortios_firewall(input_data, fos_instance)
expected_data = {
'caname': 'test_value_3',
'comment': 'Optional comments.',
'mapi-over-https': 'enable',
'name': 'default_name_6',
'rpc-over-https': 'enable',
'server-cert': 'test_value_8',
'server-cert-mode': 're-sign',
'ssl-anomalies-log': 'disable',
'ssl-exemptions-log': 'disable',
'untrusted-caname': 'test_value_12',
'use-ssl-server': 'disable',
'whitelist': 'enable'
}
set_method_mock.assert_called_with('firewall', 'ssl-ssh-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,249 @@
# 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_firewall_ttl_policy
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_firewall_ttl_policy.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_ttl_policy_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',
'firewall_ttl_policy': {
'action': 'accept',
'id': '4',
'schedule': 'test_value_5',
'srcintf': 'test_value_6',
'status': 'enable',
'ttl': 'test_value_8'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ttl_policy.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'id': '4',
'schedule': 'test_value_5',
'srcintf': 'test_value_6',
'status': 'enable',
'ttl': 'test_value_8'
}
set_method_mock.assert_called_with('firewall', 'ttl-policy', 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_firewall_ttl_policy_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',
'firewall_ttl_policy': {
'action': 'accept',
'id': '4',
'schedule': 'test_value_5',
'srcintf': 'test_value_6',
'status': 'enable',
'ttl': 'test_value_8'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ttl_policy.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'id': '4',
'schedule': 'test_value_5',
'srcintf': 'test_value_6',
'status': 'enable',
'ttl': 'test_value_8'
}
set_method_mock.assert_called_with('firewall', 'ttl-policy', 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_firewall_ttl_policy_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',
'firewall_ttl_policy': {
'action': 'accept',
'id': '4',
'schedule': 'test_value_5',
'srcintf': 'test_value_6',
'status': 'enable',
'ttl': 'test_value_8'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ttl_policy.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'ttl-policy', 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_firewall_ttl_policy_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',
'firewall_ttl_policy': {
'action': 'accept',
'id': '4',
'schedule': 'test_value_5',
'srcintf': 'test_value_6',
'status': 'enable',
'ttl': 'test_value_8'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ttl_policy.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'ttl-policy', 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_firewall_ttl_policy_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',
'firewall_ttl_policy': {
'action': 'accept',
'id': '4',
'schedule': 'test_value_5',
'srcintf': 'test_value_6',
'status': 'enable',
'ttl': 'test_value_8'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ttl_policy.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'id': '4',
'schedule': 'test_value_5',
'srcintf': 'test_value_6',
'status': 'enable',
'ttl': 'test_value_8'
}
set_method_mock.assert_called_with('firewall', 'ttl-policy', 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_firewall_ttl_policy_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',
'firewall_ttl_policy': {
'random_attribute_not_valid': 'tag',
'action': 'accept',
'id': '4',
'schedule': 'test_value_5',
'srcintf': 'test_value_6',
'status': 'enable',
'ttl': 'test_value_8'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ttl_policy.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'id': '4',
'schedule': 'test_value_5',
'srcintf': 'test_value_6',
'status': 'enable',
'ttl': 'test_value_8'
}
set_method_mock.assert_called_with('firewall', 'ttl-policy', 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,839 @@
# 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_firewall_vip
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_firewall_vip.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_vip_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',
'firewall_vip': {
'arp_reply': 'disable',
'color': '4',
'comment': 'Comment.',
'dns_mapping_ttl': '6',
'extintf': 'test_value_7',
'extip': 'test_value_8',
'extport': 'test_value_9',
'gratuitous_arp_interval': '10',
'http_cookie_age': '11',
'http_cookie_domain': 'test_value_12',
'http_cookie_domain_from_host': 'disable',
'http_cookie_generation': '14',
'http_cookie_path': 'test_value_15',
'http_cookie_share': 'disable',
'http_ip_header': 'enable',
'http_ip_header_name': 'test_value_18',
'http_multiplex': 'enable',
'https_cookie_secure': 'disable',
'id': '21',
'ldb_method': 'static',
'mapped_addr': 'test_value_23',
'mappedport': 'test_value_24',
'max_embryonic_connections': '25',
'name': 'default_name_26',
'nat_source_vip': 'disable',
'outlook_web_access': 'disable',
'persistence': 'none',
'portforward': 'disable',
'portmapping_type': '1-to-1',
'protocol': 'tcp',
'server_type': 'http',
'ssl_algorithm': 'high',
'ssl_certificate': 'test_value_35',
'ssl_client_fallback': 'disable',
'ssl_client_renegotiation': 'allow',
'ssl_client_session_state_max': '38',
'ssl_client_session_state_timeout': '39',
'ssl_client_session_state_type': 'disable',
'ssl_dh_bits': '768',
'ssl_hpkp': 'disable',
'ssl_hpkp_age': '43',
'ssl_hpkp_backup': 'test_value_44',
'ssl_hpkp_include_subdomains': 'disable',
'ssl_hpkp_primary': 'test_value_46',
'ssl_hpkp_report_uri': 'test_value_47',
'ssl_hsts': 'disable',
'ssl_hsts_age': '49',
'ssl_hsts_include_subdomains': 'disable',
'ssl_http_location_conversion': 'enable',
'ssl_http_match_host': 'enable',
'ssl_max_version': 'ssl-3.0',
'ssl_min_version': 'ssl-3.0',
'ssl_mode': 'half',
'ssl_pfs': 'require',
'ssl_send_empty_frags': 'enable',
'ssl_server_algorithm': 'high',
'ssl_server_max_version': 'ssl-3.0',
'ssl_server_min_version': 'ssl-3.0',
'ssl_server_session_state_max': '61',
'ssl_server_session_state_timeout': '62',
'ssl_server_session_state_type': 'disable',
'type': 'static-nat',
'uuid': 'test_value_65',
'weblogic_server': 'disable',
'websphere_server': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vip.fortios_firewall(input_data, fos_instance)
expected_data = {
'arp-reply': 'disable',
'color': '4',
'comment': 'Comment.',
'dns-mapping-ttl': '6',
'extintf': 'test_value_7',
'extip': 'test_value_8',
'extport': 'test_value_9',
'gratuitous-arp-interval': '10',
'http-cookie-age': '11',
'http-cookie-domain': 'test_value_12',
'http-cookie-domain-from-host': 'disable',
'http-cookie-generation': '14',
'http-cookie-path': 'test_value_15',
'http-cookie-share': 'disable',
'http-ip-header': 'enable',
'http-ip-header-name': 'test_value_18',
'http-multiplex': 'enable',
'https-cookie-secure': 'disable',
'id': '21',
'ldb-method': 'static',
'mapped-addr': 'test_value_23',
'mappedport': 'test_value_24',
'max-embryonic-connections': '25',
'name': 'default_name_26',
'nat-source-vip': 'disable',
'outlook-web-access': 'disable',
'persistence': 'none',
'portforward': 'disable',
'portmapping-type': '1-to-1',
'protocol': 'tcp',
'server-type': 'http',
'ssl-algorithm': 'high',
'ssl-certificate': 'test_value_35',
'ssl-client-fallback': 'disable',
'ssl-client-renegotiation': 'allow',
'ssl-client-session-state-max': '38',
'ssl-client-session-state-timeout': '39',
'ssl-client-session-state-type': 'disable',
'ssl-dh-bits': '768',
'ssl-hpkp': 'disable',
'ssl-hpkp-age': '43',
'ssl-hpkp-backup': 'test_value_44',
'ssl-hpkp-include-subdomains': 'disable',
'ssl-hpkp-primary': 'test_value_46',
'ssl-hpkp-report-uri': 'test_value_47',
'ssl-hsts': 'disable',
'ssl-hsts-age': '49',
'ssl-hsts-include-subdomains': 'disable',
'ssl-http-location-conversion': 'enable',
'ssl-http-match-host': 'enable',
'ssl-max-version': 'ssl-3.0',
'ssl-min-version': 'ssl-3.0',
'ssl-mode': 'half',
'ssl-pfs': 'require',
'ssl-send-empty-frags': 'enable',
'ssl-server-algorithm': 'high',
'ssl-server-max-version': 'ssl-3.0',
'ssl-server-min-version': 'ssl-3.0',
'ssl-server-session-state-max': '61',
'ssl-server-session-state-timeout': '62',
'ssl-server-session-state-type': 'disable',
'type': 'static-nat',
'uuid': 'test_value_65',
'weblogic-server': 'disable',
'websphere-server': 'disable'
}
set_method_mock.assert_called_with('firewall', 'vip', 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_firewall_vip_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',
'firewall_vip': {
'arp_reply': 'disable',
'color': '4',
'comment': 'Comment.',
'dns_mapping_ttl': '6',
'extintf': 'test_value_7',
'extip': 'test_value_8',
'extport': 'test_value_9',
'gratuitous_arp_interval': '10',
'http_cookie_age': '11',
'http_cookie_domain': 'test_value_12',
'http_cookie_domain_from_host': 'disable',
'http_cookie_generation': '14',
'http_cookie_path': 'test_value_15',
'http_cookie_share': 'disable',
'http_ip_header': 'enable',
'http_ip_header_name': 'test_value_18',
'http_multiplex': 'enable',
'https_cookie_secure': 'disable',
'id': '21',
'ldb_method': 'static',
'mapped_addr': 'test_value_23',
'mappedport': 'test_value_24',
'max_embryonic_connections': '25',
'name': 'default_name_26',
'nat_source_vip': 'disable',
'outlook_web_access': 'disable',
'persistence': 'none',
'portforward': 'disable',
'portmapping_type': '1-to-1',
'protocol': 'tcp',
'server_type': 'http',
'ssl_algorithm': 'high',
'ssl_certificate': 'test_value_35',
'ssl_client_fallback': 'disable',
'ssl_client_renegotiation': 'allow',
'ssl_client_session_state_max': '38',
'ssl_client_session_state_timeout': '39',
'ssl_client_session_state_type': 'disable',
'ssl_dh_bits': '768',
'ssl_hpkp': 'disable',
'ssl_hpkp_age': '43',
'ssl_hpkp_backup': 'test_value_44',
'ssl_hpkp_include_subdomains': 'disable',
'ssl_hpkp_primary': 'test_value_46',
'ssl_hpkp_report_uri': 'test_value_47',
'ssl_hsts': 'disable',
'ssl_hsts_age': '49',
'ssl_hsts_include_subdomains': 'disable',
'ssl_http_location_conversion': 'enable',
'ssl_http_match_host': 'enable',
'ssl_max_version': 'ssl-3.0',
'ssl_min_version': 'ssl-3.0',
'ssl_mode': 'half',
'ssl_pfs': 'require',
'ssl_send_empty_frags': 'enable',
'ssl_server_algorithm': 'high',
'ssl_server_max_version': 'ssl-3.0',
'ssl_server_min_version': 'ssl-3.0',
'ssl_server_session_state_max': '61',
'ssl_server_session_state_timeout': '62',
'ssl_server_session_state_type': 'disable',
'type': 'static-nat',
'uuid': 'test_value_65',
'weblogic_server': 'disable',
'websphere_server': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vip.fortios_firewall(input_data, fos_instance)
expected_data = {
'arp-reply': 'disable',
'color': '4',
'comment': 'Comment.',
'dns-mapping-ttl': '6',
'extintf': 'test_value_7',
'extip': 'test_value_8',
'extport': 'test_value_9',
'gratuitous-arp-interval': '10',
'http-cookie-age': '11',
'http-cookie-domain': 'test_value_12',
'http-cookie-domain-from-host': 'disable',
'http-cookie-generation': '14',
'http-cookie-path': 'test_value_15',
'http-cookie-share': 'disable',
'http-ip-header': 'enable',
'http-ip-header-name': 'test_value_18',
'http-multiplex': 'enable',
'https-cookie-secure': 'disable',
'id': '21',
'ldb-method': 'static',
'mapped-addr': 'test_value_23',
'mappedport': 'test_value_24',
'max-embryonic-connections': '25',
'name': 'default_name_26',
'nat-source-vip': 'disable',
'outlook-web-access': 'disable',
'persistence': 'none',
'portforward': 'disable',
'portmapping-type': '1-to-1',
'protocol': 'tcp',
'server-type': 'http',
'ssl-algorithm': 'high',
'ssl-certificate': 'test_value_35',
'ssl-client-fallback': 'disable',
'ssl-client-renegotiation': 'allow',
'ssl-client-session-state-max': '38',
'ssl-client-session-state-timeout': '39',
'ssl-client-session-state-type': 'disable',
'ssl-dh-bits': '768',
'ssl-hpkp': 'disable',
'ssl-hpkp-age': '43',
'ssl-hpkp-backup': 'test_value_44',
'ssl-hpkp-include-subdomains': 'disable',
'ssl-hpkp-primary': 'test_value_46',
'ssl-hpkp-report-uri': 'test_value_47',
'ssl-hsts': 'disable',
'ssl-hsts-age': '49',
'ssl-hsts-include-subdomains': 'disable',
'ssl-http-location-conversion': 'enable',
'ssl-http-match-host': 'enable',
'ssl-max-version': 'ssl-3.0',
'ssl-min-version': 'ssl-3.0',
'ssl-mode': 'half',
'ssl-pfs': 'require',
'ssl-send-empty-frags': 'enable',
'ssl-server-algorithm': 'high',
'ssl-server-max-version': 'ssl-3.0',
'ssl-server-min-version': 'ssl-3.0',
'ssl-server-session-state-max': '61',
'ssl-server-session-state-timeout': '62',
'ssl-server-session-state-type': 'disable',
'type': 'static-nat',
'uuid': 'test_value_65',
'weblogic-server': 'disable',
'websphere-server': 'disable'
}
set_method_mock.assert_called_with('firewall', 'vip', 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_firewall_vip_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',
'firewall_vip': {
'arp_reply': 'disable',
'color': '4',
'comment': 'Comment.',
'dns_mapping_ttl': '6',
'extintf': 'test_value_7',
'extip': 'test_value_8',
'extport': 'test_value_9',
'gratuitous_arp_interval': '10',
'http_cookie_age': '11',
'http_cookie_domain': 'test_value_12',
'http_cookie_domain_from_host': 'disable',
'http_cookie_generation': '14',
'http_cookie_path': 'test_value_15',
'http_cookie_share': 'disable',
'http_ip_header': 'enable',
'http_ip_header_name': 'test_value_18',
'http_multiplex': 'enable',
'https_cookie_secure': 'disable',
'id': '21',
'ldb_method': 'static',
'mapped_addr': 'test_value_23',
'mappedport': 'test_value_24',
'max_embryonic_connections': '25',
'name': 'default_name_26',
'nat_source_vip': 'disable',
'outlook_web_access': 'disable',
'persistence': 'none',
'portforward': 'disable',
'portmapping_type': '1-to-1',
'protocol': 'tcp',
'server_type': 'http',
'ssl_algorithm': 'high',
'ssl_certificate': 'test_value_35',
'ssl_client_fallback': 'disable',
'ssl_client_renegotiation': 'allow',
'ssl_client_session_state_max': '38',
'ssl_client_session_state_timeout': '39',
'ssl_client_session_state_type': 'disable',
'ssl_dh_bits': '768',
'ssl_hpkp': 'disable',
'ssl_hpkp_age': '43',
'ssl_hpkp_backup': 'test_value_44',
'ssl_hpkp_include_subdomains': 'disable',
'ssl_hpkp_primary': 'test_value_46',
'ssl_hpkp_report_uri': 'test_value_47',
'ssl_hsts': 'disable',
'ssl_hsts_age': '49',
'ssl_hsts_include_subdomains': 'disable',
'ssl_http_location_conversion': 'enable',
'ssl_http_match_host': 'enable',
'ssl_max_version': 'ssl-3.0',
'ssl_min_version': 'ssl-3.0',
'ssl_mode': 'half',
'ssl_pfs': 'require',
'ssl_send_empty_frags': 'enable',
'ssl_server_algorithm': 'high',
'ssl_server_max_version': 'ssl-3.0',
'ssl_server_min_version': 'ssl-3.0',
'ssl_server_session_state_max': '61',
'ssl_server_session_state_timeout': '62',
'ssl_server_session_state_type': 'disable',
'type': 'static-nat',
'uuid': 'test_value_65',
'weblogic_server': 'disable',
'websphere_server': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vip.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'vip', 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_firewall_vip_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',
'firewall_vip': {
'arp_reply': 'disable',
'color': '4',
'comment': 'Comment.',
'dns_mapping_ttl': '6',
'extintf': 'test_value_7',
'extip': 'test_value_8',
'extport': 'test_value_9',
'gratuitous_arp_interval': '10',
'http_cookie_age': '11',
'http_cookie_domain': 'test_value_12',
'http_cookie_domain_from_host': 'disable',
'http_cookie_generation': '14',
'http_cookie_path': 'test_value_15',
'http_cookie_share': 'disable',
'http_ip_header': 'enable',
'http_ip_header_name': 'test_value_18',
'http_multiplex': 'enable',
'https_cookie_secure': 'disable',
'id': '21',
'ldb_method': 'static',
'mapped_addr': 'test_value_23',
'mappedport': 'test_value_24',
'max_embryonic_connections': '25',
'name': 'default_name_26',
'nat_source_vip': 'disable',
'outlook_web_access': 'disable',
'persistence': 'none',
'portforward': 'disable',
'portmapping_type': '1-to-1',
'protocol': 'tcp',
'server_type': 'http',
'ssl_algorithm': 'high',
'ssl_certificate': 'test_value_35',
'ssl_client_fallback': 'disable',
'ssl_client_renegotiation': 'allow',
'ssl_client_session_state_max': '38',
'ssl_client_session_state_timeout': '39',
'ssl_client_session_state_type': 'disable',
'ssl_dh_bits': '768',
'ssl_hpkp': 'disable',
'ssl_hpkp_age': '43',
'ssl_hpkp_backup': 'test_value_44',
'ssl_hpkp_include_subdomains': 'disable',
'ssl_hpkp_primary': 'test_value_46',
'ssl_hpkp_report_uri': 'test_value_47',
'ssl_hsts': 'disable',
'ssl_hsts_age': '49',
'ssl_hsts_include_subdomains': 'disable',
'ssl_http_location_conversion': 'enable',
'ssl_http_match_host': 'enable',
'ssl_max_version': 'ssl-3.0',
'ssl_min_version': 'ssl-3.0',
'ssl_mode': 'half',
'ssl_pfs': 'require',
'ssl_send_empty_frags': 'enable',
'ssl_server_algorithm': 'high',
'ssl_server_max_version': 'ssl-3.0',
'ssl_server_min_version': 'ssl-3.0',
'ssl_server_session_state_max': '61',
'ssl_server_session_state_timeout': '62',
'ssl_server_session_state_type': 'disable',
'type': 'static-nat',
'uuid': 'test_value_65',
'weblogic_server': 'disable',
'websphere_server': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vip.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'vip', 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_firewall_vip_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',
'firewall_vip': {
'arp_reply': 'disable',
'color': '4',
'comment': 'Comment.',
'dns_mapping_ttl': '6',
'extintf': 'test_value_7',
'extip': 'test_value_8',
'extport': 'test_value_9',
'gratuitous_arp_interval': '10',
'http_cookie_age': '11',
'http_cookie_domain': 'test_value_12',
'http_cookie_domain_from_host': 'disable',
'http_cookie_generation': '14',
'http_cookie_path': 'test_value_15',
'http_cookie_share': 'disable',
'http_ip_header': 'enable',
'http_ip_header_name': 'test_value_18',
'http_multiplex': 'enable',
'https_cookie_secure': 'disable',
'id': '21',
'ldb_method': 'static',
'mapped_addr': 'test_value_23',
'mappedport': 'test_value_24',
'max_embryonic_connections': '25',
'name': 'default_name_26',
'nat_source_vip': 'disable',
'outlook_web_access': 'disable',
'persistence': 'none',
'portforward': 'disable',
'portmapping_type': '1-to-1',
'protocol': 'tcp',
'server_type': 'http',
'ssl_algorithm': 'high',
'ssl_certificate': 'test_value_35',
'ssl_client_fallback': 'disable',
'ssl_client_renegotiation': 'allow',
'ssl_client_session_state_max': '38',
'ssl_client_session_state_timeout': '39',
'ssl_client_session_state_type': 'disable',
'ssl_dh_bits': '768',
'ssl_hpkp': 'disable',
'ssl_hpkp_age': '43',
'ssl_hpkp_backup': 'test_value_44',
'ssl_hpkp_include_subdomains': 'disable',
'ssl_hpkp_primary': 'test_value_46',
'ssl_hpkp_report_uri': 'test_value_47',
'ssl_hsts': 'disable',
'ssl_hsts_age': '49',
'ssl_hsts_include_subdomains': 'disable',
'ssl_http_location_conversion': 'enable',
'ssl_http_match_host': 'enable',
'ssl_max_version': 'ssl-3.0',
'ssl_min_version': 'ssl-3.0',
'ssl_mode': 'half',
'ssl_pfs': 'require',
'ssl_send_empty_frags': 'enable',
'ssl_server_algorithm': 'high',
'ssl_server_max_version': 'ssl-3.0',
'ssl_server_min_version': 'ssl-3.0',
'ssl_server_session_state_max': '61',
'ssl_server_session_state_timeout': '62',
'ssl_server_session_state_type': 'disable',
'type': 'static-nat',
'uuid': 'test_value_65',
'weblogic_server': 'disable',
'websphere_server': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vip.fortios_firewall(input_data, fos_instance)
expected_data = {
'arp-reply': 'disable',
'color': '4',
'comment': 'Comment.',
'dns-mapping-ttl': '6',
'extintf': 'test_value_7',
'extip': 'test_value_8',
'extport': 'test_value_9',
'gratuitous-arp-interval': '10',
'http-cookie-age': '11',
'http-cookie-domain': 'test_value_12',
'http-cookie-domain-from-host': 'disable',
'http-cookie-generation': '14',
'http-cookie-path': 'test_value_15',
'http-cookie-share': 'disable',
'http-ip-header': 'enable',
'http-ip-header-name': 'test_value_18',
'http-multiplex': 'enable',
'https-cookie-secure': 'disable',
'id': '21',
'ldb-method': 'static',
'mapped-addr': 'test_value_23',
'mappedport': 'test_value_24',
'max-embryonic-connections': '25',
'name': 'default_name_26',
'nat-source-vip': 'disable',
'outlook-web-access': 'disable',
'persistence': 'none',
'portforward': 'disable',
'portmapping-type': '1-to-1',
'protocol': 'tcp',
'server-type': 'http',
'ssl-algorithm': 'high',
'ssl-certificate': 'test_value_35',
'ssl-client-fallback': 'disable',
'ssl-client-renegotiation': 'allow',
'ssl-client-session-state-max': '38',
'ssl-client-session-state-timeout': '39',
'ssl-client-session-state-type': 'disable',
'ssl-dh-bits': '768',
'ssl-hpkp': 'disable',
'ssl-hpkp-age': '43',
'ssl-hpkp-backup': 'test_value_44',
'ssl-hpkp-include-subdomains': 'disable',
'ssl-hpkp-primary': 'test_value_46',
'ssl-hpkp-report-uri': 'test_value_47',
'ssl-hsts': 'disable',
'ssl-hsts-age': '49',
'ssl-hsts-include-subdomains': 'disable',
'ssl-http-location-conversion': 'enable',
'ssl-http-match-host': 'enable',
'ssl-max-version': 'ssl-3.0',
'ssl-min-version': 'ssl-3.0',
'ssl-mode': 'half',
'ssl-pfs': 'require',
'ssl-send-empty-frags': 'enable',
'ssl-server-algorithm': 'high',
'ssl-server-max-version': 'ssl-3.0',
'ssl-server-min-version': 'ssl-3.0',
'ssl-server-session-state-max': '61',
'ssl-server-session-state-timeout': '62',
'ssl-server-session-state-type': 'disable',
'type': 'static-nat',
'uuid': 'test_value_65',
'weblogic-server': 'disable',
'websphere-server': 'disable'
}
set_method_mock.assert_called_with('firewall', 'vip', 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_firewall_vip_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',
'firewall_vip': {
'random_attribute_not_valid': 'tag',
'arp_reply': 'disable',
'color': '4',
'comment': 'Comment.',
'dns_mapping_ttl': '6',
'extintf': 'test_value_7',
'extip': 'test_value_8',
'extport': 'test_value_9',
'gratuitous_arp_interval': '10',
'http_cookie_age': '11',
'http_cookie_domain': 'test_value_12',
'http_cookie_domain_from_host': 'disable',
'http_cookie_generation': '14',
'http_cookie_path': 'test_value_15',
'http_cookie_share': 'disable',
'http_ip_header': 'enable',
'http_ip_header_name': 'test_value_18',
'http_multiplex': 'enable',
'https_cookie_secure': 'disable',
'id': '21',
'ldb_method': 'static',
'mapped_addr': 'test_value_23',
'mappedport': 'test_value_24',
'max_embryonic_connections': '25',
'name': 'default_name_26',
'nat_source_vip': 'disable',
'outlook_web_access': 'disable',
'persistence': 'none',
'portforward': 'disable',
'portmapping_type': '1-to-1',
'protocol': 'tcp',
'server_type': 'http',
'ssl_algorithm': 'high',
'ssl_certificate': 'test_value_35',
'ssl_client_fallback': 'disable',
'ssl_client_renegotiation': 'allow',
'ssl_client_session_state_max': '38',
'ssl_client_session_state_timeout': '39',
'ssl_client_session_state_type': 'disable',
'ssl_dh_bits': '768',
'ssl_hpkp': 'disable',
'ssl_hpkp_age': '43',
'ssl_hpkp_backup': 'test_value_44',
'ssl_hpkp_include_subdomains': 'disable',
'ssl_hpkp_primary': 'test_value_46',
'ssl_hpkp_report_uri': 'test_value_47',
'ssl_hsts': 'disable',
'ssl_hsts_age': '49',
'ssl_hsts_include_subdomains': 'disable',
'ssl_http_location_conversion': 'enable',
'ssl_http_match_host': 'enable',
'ssl_max_version': 'ssl-3.0',
'ssl_min_version': 'ssl-3.0',
'ssl_mode': 'half',
'ssl_pfs': 'require',
'ssl_send_empty_frags': 'enable',
'ssl_server_algorithm': 'high',
'ssl_server_max_version': 'ssl-3.0',
'ssl_server_min_version': 'ssl-3.0',
'ssl_server_session_state_max': '61',
'ssl_server_session_state_timeout': '62',
'ssl_server_session_state_type': 'disable',
'type': 'static-nat',
'uuid': 'test_value_65',
'weblogic_server': 'disable',
'websphere_server': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vip.fortios_firewall(input_data, fos_instance)
expected_data = {
'arp-reply': 'disable',
'color': '4',
'comment': 'Comment.',
'dns-mapping-ttl': '6',
'extintf': 'test_value_7',
'extip': 'test_value_8',
'extport': 'test_value_9',
'gratuitous-arp-interval': '10',
'http-cookie-age': '11',
'http-cookie-domain': 'test_value_12',
'http-cookie-domain-from-host': 'disable',
'http-cookie-generation': '14',
'http-cookie-path': 'test_value_15',
'http-cookie-share': 'disable',
'http-ip-header': 'enable',
'http-ip-header-name': 'test_value_18',
'http-multiplex': 'enable',
'https-cookie-secure': 'disable',
'id': '21',
'ldb-method': 'static',
'mapped-addr': 'test_value_23',
'mappedport': 'test_value_24',
'max-embryonic-connections': '25',
'name': 'default_name_26',
'nat-source-vip': 'disable',
'outlook-web-access': 'disable',
'persistence': 'none',
'portforward': 'disable',
'portmapping-type': '1-to-1',
'protocol': 'tcp',
'server-type': 'http',
'ssl-algorithm': 'high',
'ssl-certificate': 'test_value_35',
'ssl-client-fallback': 'disable',
'ssl-client-renegotiation': 'allow',
'ssl-client-session-state-max': '38',
'ssl-client-session-state-timeout': '39',
'ssl-client-session-state-type': 'disable',
'ssl-dh-bits': '768',
'ssl-hpkp': 'disable',
'ssl-hpkp-age': '43',
'ssl-hpkp-backup': 'test_value_44',
'ssl-hpkp-include-subdomains': 'disable',
'ssl-hpkp-primary': 'test_value_46',
'ssl-hpkp-report-uri': 'test_value_47',
'ssl-hsts': 'disable',
'ssl-hsts-age': '49',
'ssl-hsts-include-subdomains': 'disable',
'ssl-http-location-conversion': 'enable',
'ssl-http-match-host': 'enable',
'ssl-max-version': 'ssl-3.0',
'ssl-min-version': 'ssl-3.0',
'ssl-mode': 'half',
'ssl-pfs': 'require',
'ssl-send-empty-frags': 'enable',
'ssl-server-algorithm': 'high',
'ssl-server-max-version': 'ssl-3.0',
'ssl-server-min-version': 'ssl-3.0',
'ssl-server-session-state-max': '61',
'ssl-server-session-state-timeout': '62',
'ssl-server-session-state-type': 'disable',
'type': 'static-nat',
'uuid': 'test_value_65',
'weblogic-server': 'disable',
'websphere-server': 'disable'
}
set_method_mock.assert_called_with('firewall', 'vip', 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,339 @@
# 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_firewall_vip46
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_firewall_vip46.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_vip46_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',
'firewall_vip46': {
'arp_reply': 'disable',
'color': '4',
'comment': 'Comment.',
'extip': 'test_value_6',
'extport': 'test_value_7',
'id': '8',
'ldb_method': 'static',
'mappedip': 'test_value_10',
'mappedport': 'test_value_11',
'name': 'default_name_12',
'portforward': 'disable',
'protocol': 'tcp',
'server_type': 'http',
'type': 'static-nat',
'uuid': 'test_value_17'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vip46.fortios_firewall(input_data, fos_instance)
expected_data = {
'arp-reply': 'disable',
'color': '4',
'comment': 'Comment.',
'extip': 'test_value_6',
'extport': 'test_value_7',
'id': '8',
'ldb-method': 'static',
'mappedip': 'test_value_10',
'mappedport': 'test_value_11',
'name': 'default_name_12',
'portforward': 'disable',
'protocol': 'tcp',
'server-type': 'http',
'type': 'static-nat',
'uuid': 'test_value_17'
}
set_method_mock.assert_called_with('firewall', 'vip46', 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_firewall_vip46_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',
'firewall_vip46': {
'arp_reply': 'disable',
'color': '4',
'comment': 'Comment.',
'extip': 'test_value_6',
'extport': 'test_value_7',
'id': '8',
'ldb_method': 'static',
'mappedip': 'test_value_10',
'mappedport': 'test_value_11',
'name': 'default_name_12',
'portforward': 'disable',
'protocol': 'tcp',
'server_type': 'http',
'type': 'static-nat',
'uuid': 'test_value_17'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vip46.fortios_firewall(input_data, fos_instance)
expected_data = {
'arp-reply': 'disable',
'color': '4',
'comment': 'Comment.',
'extip': 'test_value_6',
'extport': 'test_value_7',
'id': '8',
'ldb-method': 'static',
'mappedip': 'test_value_10',
'mappedport': 'test_value_11',
'name': 'default_name_12',
'portforward': 'disable',
'protocol': 'tcp',
'server-type': 'http',
'type': 'static-nat',
'uuid': 'test_value_17'
}
set_method_mock.assert_called_with('firewall', 'vip46', 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_firewall_vip46_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',
'firewall_vip46': {
'arp_reply': 'disable',
'color': '4',
'comment': 'Comment.',
'extip': 'test_value_6',
'extport': 'test_value_7',
'id': '8',
'ldb_method': 'static',
'mappedip': 'test_value_10',
'mappedport': 'test_value_11',
'name': 'default_name_12',
'portforward': 'disable',
'protocol': 'tcp',
'server_type': 'http',
'type': 'static-nat',
'uuid': 'test_value_17'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vip46.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'vip46', 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_firewall_vip46_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',
'firewall_vip46': {
'arp_reply': 'disable',
'color': '4',
'comment': 'Comment.',
'extip': 'test_value_6',
'extport': 'test_value_7',
'id': '8',
'ldb_method': 'static',
'mappedip': 'test_value_10',
'mappedport': 'test_value_11',
'name': 'default_name_12',
'portforward': 'disable',
'protocol': 'tcp',
'server_type': 'http',
'type': 'static-nat',
'uuid': 'test_value_17'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vip46.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'vip46', 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_firewall_vip46_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',
'firewall_vip46': {
'arp_reply': 'disable',
'color': '4',
'comment': 'Comment.',
'extip': 'test_value_6',
'extport': 'test_value_7',
'id': '8',
'ldb_method': 'static',
'mappedip': 'test_value_10',
'mappedport': 'test_value_11',
'name': 'default_name_12',
'portforward': 'disable',
'protocol': 'tcp',
'server_type': 'http',
'type': 'static-nat',
'uuid': 'test_value_17'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vip46.fortios_firewall(input_data, fos_instance)
expected_data = {
'arp-reply': 'disable',
'color': '4',
'comment': 'Comment.',
'extip': 'test_value_6',
'extport': 'test_value_7',
'id': '8',
'ldb-method': 'static',
'mappedip': 'test_value_10',
'mappedport': 'test_value_11',
'name': 'default_name_12',
'portforward': 'disable',
'protocol': 'tcp',
'server-type': 'http',
'type': 'static-nat',
'uuid': 'test_value_17'
}
set_method_mock.assert_called_with('firewall', 'vip46', 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_firewall_vip46_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',
'firewall_vip46': {
'random_attribute_not_valid': 'tag',
'arp_reply': 'disable',
'color': '4',
'comment': 'Comment.',
'extip': 'test_value_6',
'extport': 'test_value_7',
'id': '8',
'ldb_method': 'static',
'mappedip': 'test_value_10',
'mappedport': 'test_value_11',
'name': 'default_name_12',
'portforward': 'disable',
'protocol': 'tcp',
'server_type': 'http',
'type': 'static-nat',
'uuid': 'test_value_17'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vip46.fortios_firewall(input_data, fos_instance)
expected_data = {
'arp-reply': 'disable',
'color': '4',
'comment': 'Comment.',
'extip': 'test_value_6',
'extport': 'test_value_7',
'id': '8',
'ldb-method': 'static',
'mappedip': 'test_value_10',
'mappedport': 'test_value_11',
'name': 'default_name_12',
'portforward': 'disable',
'protocol': 'tcp',
'server-type': 'http',
'type': 'static-nat',
'uuid': 'test_value_17'
}
set_method_mock.assert_called_with('firewall', 'vip46', 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,789 @@
# 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_firewall_vip6
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_firewall_vip6.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_vip6_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',
'firewall_vip6': {
'arp_reply': 'disable',
'color': '4',
'comment': 'Comment.',
'extip': 'test_value_6',
'extport': 'test_value_7',
'http_cookie_age': '8',
'http_cookie_domain': 'test_value_9',
'http_cookie_domain_from_host': 'disable',
'http_cookie_generation': '11',
'http_cookie_path': 'test_value_12',
'http_cookie_share': 'disable',
'http_ip_header': 'enable',
'http_ip_header_name': 'test_value_15',
'http_multiplex': 'enable',
'https_cookie_secure': 'disable',
'id': '18',
'ldb_method': 'static',
'mappedip': 'test_value_20',
'mappedport': 'test_value_21',
'max_embryonic_connections': '22',
'name': 'default_name_23',
'outlook_web_access': 'disable',
'persistence': 'none',
'portforward': 'disable',
'protocol': 'tcp',
'server_type': 'http',
'ssl_algorithm': 'high',
'ssl_certificate': 'test_value_30',
'ssl_client_fallback': 'disable',
'ssl_client_renegotiation': 'allow',
'ssl_client_session_state_max': '33',
'ssl_client_session_state_timeout': '34',
'ssl_client_session_state_type': 'disable',
'ssl_dh_bits': '768',
'ssl_hpkp': 'disable',
'ssl_hpkp_age': '38',
'ssl_hpkp_backup': 'test_value_39',
'ssl_hpkp_include_subdomains': 'disable',
'ssl_hpkp_primary': 'test_value_41',
'ssl_hpkp_report_uri': 'test_value_42',
'ssl_hsts': 'disable',
'ssl_hsts_age': '44',
'ssl_hsts_include_subdomains': 'disable',
'ssl_http_location_conversion': 'enable',
'ssl_http_match_host': 'enable',
'ssl_max_version': 'ssl-3.0',
'ssl_min_version': 'ssl-3.0',
'ssl_mode': 'half',
'ssl_pfs': 'require',
'ssl_send_empty_frags': 'enable',
'ssl_server_algorithm': 'high',
'ssl_server_max_version': 'ssl-3.0',
'ssl_server_min_version': 'ssl-3.0',
'ssl_server_session_state_max': '56',
'ssl_server_session_state_timeout': '57',
'ssl_server_session_state_type': 'disable',
'type': 'static-nat',
'uuid': 'test_value_60',
'weblogic_server': 'disable',
'websphere_server': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vip6.fortios_firewall(input_data, fos_instance)
expected_data = {
'arp-reply': 'disable',
'color': '4',
'comment': 'Comment.',
'extip': 'test_value_6',
'extport': 'test_value_7',
'http-cookie-age': '8',
'http-cookie-domain': 'test_value_9',
'http-cookie-domain-from-host': 'disable',
'http-cookie-generation': '11',
'http-cookie-path': 'test_value_12',
'http-cookie-share': 'disable',
'http-ip-header': 'enable',
'http-ip-header-name': 'test_value_15',
'http-multiplex': 'enable',
'https-cookie-secure': 'disable',
'id': '18',
'ldb-method': 'static',
'mappedip': 'test_value_20',
'mappedport': 'test_value_21',
'max-embryonic-connections': '22',
'name': 'default_name_23',
'outlook-web-access': 'disable',
'persistence': 'none',
'portforward': 'disable',
'protocol': 'tcp',
'server-type': 'http',
'ssl-algorithm': 'high',
'ssl-certificate': 'test_value_30',
'ssl-client-fallback': 'disable',
'ssl-client-renegotiation': 'allow',
'ssl-client-session-state-max': '33',
'ssl-client-session-state-timeout': '34',
'ssl-client-session-state-type': 'disable',
'ssl-dh-bits': '768',
'ssl-hpkp': 'disable',
'ssl-hpkp-age': '38',
'ssl-hpkp-backup': 'test_value_39',
'ssl-hpkp-include-subdomains': 'disable',
'ssl-hpkp-primary': 'test_value_41',
'ssl-hpkp-report-uri': 'test_value_42',
'ssl-hsts': 'disable',
'ssl-hsts-age': '44',
'ssl-hsts-include-subdomains': 'disable',
'ssl-http-location-conversion': 'enable',
'ssl-http-match-host': 'enable',
'ssl-max-version': 'ssl-3.0',
'ssl-min-version': 'ssl-3.0',
'ssl-mode': 'half',
'ssl-pfs': 'require',
'ssl-send-empty-frags': 'enable',
'ssl-server-algorithm': 'high',
'ssl-server-max-version': 'ssl-3.0',
'ssl-server-min-version': 'ssl-3.0',
'ssl-server-session-state-max': '56',
'ssl-server-session-state-timeout': '57',
'ssl-server-session-state-type': 'disable',
'type': 'static-nat',
'uuid': 'test_value_60',
'weblogic-server': 'disable',
'websphere-server': 'disable'
}
set_method_mock.assert_called_with('firewall', 'vip6', 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_firewall_vip6_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',
'firewall_vip6': {
'arp_reply': 'disable',
'color': '4',
'comment': 'Comment.',
'extip': 'test_value_6',
'extport': 'test_value_7',
'http_cookie_age': '8',
'http_cookie_domain': 'test_value_9',
'http_cookie_domain_from_host': 'disable',
'http_cookie_generation': '11',
'http_cookie_path': 'test_value_12',
'http_cookie_share': 'disable',
'http_ip_header': 'enable',
'http_ip_header_name': 'test_value_15',
'http_multiplex': 'enable',
'https_cookie_secure': 'disable',
'id': '18',
'ldb_method': 'static',
'mappedip': 'test_value_20',
'mappedport': 'test_value_21',
'max_embryonic_connections': '22',
'name': 'default_name_23',
'outlook_web_access': 'disable',
'persistence': 'none',
'portforward': 'disable',
'protocol': 'tcp',
'server_type': 'http',
'ssl_algorithm': 'high',
'ssl_certificate': 'test_value_30',
'ssl_client_fallback': 'disable',
'ssl_client_renegotiation': 'allow',
'ssl_client_session_state_max': '33',
'ssl_client_session_state_timeout': '34',
'ssl_client_session_state_type': 'disable',
'ssl_dh_bits': '768',
'ssl_hpkp': 'disable',
'ssl_hpkp_age': '38',
'ssl_hpkp_backup': 'test_value_39',
'ssl_hpkp_include_subdomains': 'disable',
'ssl_hpkp_primary': 'test_value_41',
'ssl_hpkp_report_uri': 'test_value_42',
'ssl_hsts': 'disable',
'ssl_hsts_age': '44',
'ssl_hsts_include_subdomains': 'disable',
'ssl_http_location_conversion': 'enable',
'ssl_http_match_host': 'enable',
'ssl_max_version': 'ssl-3.0',
'ssl_min_version': 'ssl-3.0',
'ssl_mode': 'half',
'ssl_pfs': 'require',
'ssl_send_empty_frags': 'enable',
'ssl_server_algorithm': 'high',
'ssl_server_max_version': 'ssl-3.0',
'ssl_server_min_version': 'ssl-3.0',
'ssl_server_session_state_max': '56',
'ssl_server_session_state_timeout': '57',
'ssl_server_session_state_type': 'disable',
'type': 'static-nat',
'uuid': 'test_value_60',
'weblogic_server': 'disable',
'websphere_server': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vip6.fortios_firewall(input_data, fos_instance)
expected_data = {
'arp-reply': 'disable',
'color': '4',
'comment': 'Comment.',
'extip': 'test_value_6',
'extport': 'test_value_7',
'http-cookie-age': '8',
'http-cookie-domain': 'test_value_9',
'http-cookie-domain-from-host': 'disable',
'http-cookie-generation': '11',
'http-cookie-path': 'test_value_12',
'http-cookie-share': 'disable',
'http-ip-header': 'enable',
'http-ip-header-name': 'test_value_15',
'http-multiplex': 'enable',
'https-cookie-secure': 'disable',
'id': '18',
'ldb-method': 'static',
'mappedip': 'test_value_20',
'mappedport': 'test_value_21',
'max-embryonic-connections': '22',
'name': 'default_name_23',
'outlook-web-access': 'disable',
'persistence': 'none',
'portforward': 'disable',
'protocol': 'tcp',
'server-type': 'http',
'ssl-algorithm': 'high',
'ssl-certificate': 'test_value_30',
'ssl-client-fallback': 'disable',
'ssl-client-renegotiation': 'allow',
'ssl-client-session-state-max': '33',
'ssl-client-session-state-timeout': '34',
'ssl-client-session-state-type': 'disable',
'ssl-dh-bits': '768',
'ssl-hpkp': 'disable',
'ssl-hpkp-age': '38',
'ssl-hpkp-backup': 'test_value_39',
'ssl-hpkp-include-subdomains': 'disable',
'ssl-hpkp-primary': 'test_value_41',
'ssl-hpkp-report-uri': 'test_value_42',
'ssl-hsts': 'disable',
'ssl-hsts-age': '44',
'ssl-hsts-include-subdomains': 'disable',
'ssl-http-location-conversion': 'enable',
'ssl-http-match-host': 'enable',
'ssl-max-version': 'ssl-3.0',
'ssl-min-version': 'ssl-3.0',
'ssl-mode': 'half',
'ssl-pfs': 'require',
'ssl-send-empty-frags': 'enable',
'ssl-server-algorithm': 'high',
'ssl-server-max-version': 'ssl-3.0',
'ssl-server-min-version': 'ssl-3.0',
'ssl-server-session-state-max': '56',
'ssl-server-session-state-timeout': '57',
'ssl-server-session-state-type': 'disable',
'type': 'static-nat',
'uuid': 'test_value_60',
'weblogic-server': 'disable',
'websphere-server': 'disable'
}
set_method_mock.assert_called_with('firewall', 'vip6', 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_firewall_vip6_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',
'firewall_vip6': {
'arp_reply': 'disable',
'color': '4',
'comment': 'Comment.',
'extip': 'test_value_6',
'extport': 'test_value_7',
'http_cookie_age': '8',
'http_cookie_domain': 'test_value_9',
'http_cookie_domain_from_host': 'disable',
'http_cookie_generation': '11',
'http_cookie_path': 'test_value_12',
'http_cookie_share': 'disable',
'http_ip_header': 'enable',
'http_ip_header_name': 'test_value_15',
'http_multiplex': 'enable',
'https_cookie_secure': 'disable',
'id': '18',
'ldb_method': 'static',
'mappedip': 'test_value_20',
'mappedport': 'test_value_21',
'max_embryonic_connections': '22',
'name': 'default_name_23',
'outlook_web_access': 'disable',
'persistence': 'none',
'portforward': 'disable',
'protocol': 'tcp',
'server_type': 'http',
'ssl_algorithm': 'high',
'ssl_certificate': 'test_value_30',
'ssl_client_fallback': 'disable',
'ssl_client_renegotiation': 'allow',
'ssl_client_session_state_max': '33',
'ssl_client_session_state_timeout': '34',
'ssl_client_session_state_type': 'disable',
'ssl_dh_bits': '768',
'ssl_hpkp': 'disable',
'ssl_hpkp_age': '38',
'ssl_hpkp_backup': 'test_value_39',
'ssl_hpkp_include_subdomains': 'disable',
'ssl_hpkp_primary': 'test_value_41',
'ssl_hpkp_report_uri': 'test_value_42',
'ssl_hsts': 'disable',
'ssl_hsts_age': '44',
'ssl_hsts_include_subdomains': 'disable',
'ssl_http_location_conversion': 'enable',
'ssl_http_match_host': 'enable',
'ssl_max_version': 'ssl-3.0',
'ssl_min_version': 'ssl-3.0',
'ssl_mode': 'half',
'ssl_pfs': 'require',
'ssl_send_empty_frags': 'enable',
'ssl_server_algorithm': 'high',
'ssl_server_max_version': 'ssl-3.0',
'ssl_server_min_version': 'ssl-3.0',
'ssl_server_session_state_max': '56',
'ssl_server_session_state_timeout': '57',
'ssl_server_session_state_type': 'disable',
'type': 'static-nat',
'uuid': 'test_value_60',
'weblogic_server': 'disable',
'websphere_server': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vip6.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'vip6', 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_firewall_vip6_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',
'firewall_vip6': {
'arp_reply': 'disable',
'color': '4',
'comment': 'Comment.',
'extip': 'test_value_6',
'extport': 'test_value_7',
'http_cookie_age': '8',
'http_cookie_domain': 'test_value_9',
'http_cookie_domain_from_host': 'disable',
'http_cookie_generation': '11',
'http_cookie_path': 'test_value_12',
'http_cookie_share': 'disable',
'http_ip_header': 'enable',
'http_ip_header_name': 'test_value_15',
'http_multiplex': 'enable',
'https_cookie_secure': 'disable',
'id': '18',
'ldb_method': 'static',
'mappedip': 'test_value_20',
'mappedport': 'test_value_21',
'max_embryonic_connections': '22',
'name': 'default_name_23',
'outlook_web_access': 'disable',
'persistence': 'none',
'portforward': 'disable',
'protocol': 'tcp',
'server_type': 'http',
'ssl_algorithm': 'high',
'ssl_certificate': 'test_value_30',
'ssl_client_fallback': 'disable',
'ssl_client_renegotiation': 'allow',
'ssl_client_session_state_max': '33',
'ssl_client_session_state_timeout': '34',
'ssl_client_session_state_type': 'disable',
'ssl_dh_bits': '768',
'ssl_hpkp': 'disable',
'ssl_hpkp_age': '38',
'ssl_hpkp_backup': 'test_value_39',
'ssl_hpkp_include_subdomains': 'disable',
'ssl_hpkp_primary': 'test_value_41',
'ssl_hpkp_report_uri': 'test_value_42',
'ssl_hsts': 'disable',
'ssl_hsts_age': '44',
'ssl_hsts_include_subdomains': 'disable',
'ssl_http_location_conversion': 'enable',
'ssl_http_match_host': 'enable',
'ssl_max_version': 'ssl-3.0',
'ssl_min_version': 'ssl-3.0',
'ssl_mode': 'half',
'ssl_pfs': 'require',
'ssl_send_empty_frags': 'enable',
'ssl_server_algorithm': 'high',
'ssl_server_max_version': 'ssl-3.0',
'ssl_server_min_version': 'ssl-3.0',
'ssl_server_session_state_max': '56',
'ssl_server_session_state_timeout': '57',
'ssl_server_session_state_type': 'disable',
'type': 'static-nat',
'uuid': 'test_value_60',
'weblogic_server': 'disable',
'websphere_server': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vip6.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'vip6', 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_firewall_vip6_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',
'firewall_vip6': {
'arp_reply': 'disable',
'color': '4',
'comment': 'Comment.',
'extip': 'test_value_6',
'extport': 'test_value_7',
'http_cookie_age': '8',
'http_cookie_domain': 'test_value_9',
'http_cookie_domain_from_host': 'disable',
'http_cookie_generation': '11',
'http_cookie_path': 'test_value_12',
'http_cookie_share': 'disable',
'http_ip_header': 'enable',
'http_ip_header_name': 'test_value_15',
'http_multiplex': 'enable',
'https_cookie_secure': 'disable',
'id': '18',
'ldb_method': 'static',
'mappedip': 'test_value_20',
'mappedport': 'test_value_21',
'max_embryonic_connections': '22',
'name': 'default_name_23',
'outlook_web_access': 'disable',
'persistence': 'none',
'portforward': 'disable',
'protocol': 'tcp',
'server_type': 'http',
'ssl_algorithm': 'high',
'ssl_certificate': 'test_value_30',
'ssl_client_fallback': 'disable',
'ssl_client_renegotiation': 'allow',
'ssl_client_session_state_max': '33',
'ssl_client_session_state_timeout': '34',
'ssl_client_session_state_type': 'disable',
'ssl_dh_bits': '768',
'ssl_hpkp': 'disable',
'ssl_hpkp_age': '38',
'ssl_hpkp_backup': 'test_value_39',
'ssl_hpkp_include_subdomains': 'disable',
'ssl_hpkp_primary': 'test_value_41',
'ssl_hpkp_report_uri': 'test_value_42',
'ssl_hsts': 'disable',
'ssl_hsts_age': '44',
'ssl_hsts_include_subdomains': 'disable',
'ssl_http_location_conversion': 'enable',
'ssl_http_match_host': 'enable',
'ssl_max_version': 'ssl-3.0',
'ssl_min_version': 'ssl-3.0',
'ssl_mode': 'half',
'ssl_pfs': 'require',
'ssl_send_empty_frags': 'enable',
'ssl_server_algorithm': 'high',
'ssl_server_max_version': 'ssl-3.0',
'ssl_server_min_version': 'ssl-3.0',
'ssl_server_session_state_max': '56',
'ssl_server_session_state_timeout': '57',
'ssl_server_session_state_type': 'disable',
'type': 'static-nat',
'uuid': 'test_value_60',
'weblogic_server': 'disable',
'websphere_server': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vip6.fortios_firewall(input_data, fos_instance)
expected_data = {
'arp-reply': 'disable',
'color': '4',
'comment': 'Comment.',
'extip': 'test_value_6',
'extport': 'test_value_7',
'http-cookie-age': '8',
'http-cookie-domain': 'test_value_9',
'http-cookie-domain-from-host': 'disable',
'http-cookie-generation': '11',
'http-cookie-path': 'test_value_12',
'http-cookie-share': 'disable',
'http-ip-header': 'enable',
'http-ip-header-name': 'test_value_15',
'http-multiplex': 'enable',
'https-cookie-secure': 'disable',
'id': '18',
'ldb-method': 'static',
'mappedip': 'test_value_20',
'mappedport': 'test_value_21',
'max-embryonic-connections': '22',
'name': 'default_name_23',
'outlook-web-access': 'disable',
'persistence': 'none',
'portforward': 'disable',
'protocol': 'tcp',
'server-type': 'http',
'ssl-algorithm': 'high',
'ssl-certificate': 'test_value_30',
'ssl-client-fallback': 'disable',
'ssl-client-renegotiation': 'allow',
'ssl-client-session-state-max': '33',
'ssl-client-session-state-timeout': '34',
'ssl-client-session-state-type': 'disable',
'ssl-dh-bits': '768',
'ssl-hpkp': 'disable',
'ssl-hpkp-age': '38',
'ssl-hpkp-backup': 'test_value_39',
'ssl-hpkp-include-subdomains': 'disable',
'ssl-hpkp-primary': 'test_value_41',
'ssl-hpkp-report-uri': 'test_value_42',
'ssl-hsts': 'disable',
'ssl-hsts-age': '44',
'ssl-hsts-include-subdomains': 'disable',
'ssl-http-location-conversion': 'enable',
'ssl-http-match-host': 'enable',
'ssl-max-version': 'ssl-3.0',
'ssl-min-version': 'ssl-3.0',
'ssl-mode': 'half',
'ssl-pfs': 'require',
'ssl-send-empty-frags': 'enable',
'ssl-server-algorithm': 'high',
'ssl-server-max-version': 'ssl-3.0',
'ssl-server-min-version': 'ssl-3.0',
'ssl-server-session-state-max': '56',
'ssl-server-session-state-timeout': '57',
'ssl-server-session-state-type': 'disable',
'type': 'static-nat',
'uuid': 'test_value_60',
'weblogic-server': 'disable',
'websphere-server': 'disable'
}
set_method_mock.assert_called_with('firewall', 'vip6', 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_firewall_vip6_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',
'firewall_vip6': {
'random_attribute_not_valid': 'tag',
'arp_reply': 'disable',
'color': '4',
'comment': 'Comment.',
'extip': 'test_value_6',
'extport': 'test_value_7',
'http_cookie_age': '8',
'http_cookie_domain': 'test_value_9',
'http_cookie_domain_from_host': 'disable',
'http_cookie_generation': '11',
'http_cookie_path': 'test_value_12',
'http_cookie_share': 'disable',
'http_ip_header': 'enable',
'http_ip_header_name': 'test_value_15',
'http_multiplex': 'enable',
'https_cookie_secure': 'disable',
'id': '18',
'ldb_method': 'static',
'mappedip': 'test_value_20',
'mappedport': 'test_value_21',
'max_embryonic_connections': '22',
'name': 'default_name_23',
'outlook_web_access': 'disable',
'persistence': 'none',
'portforward': 'disable',
'protocol': 'tcp',
'server_type': 'http',
'ssl_algorithm': 'high',
'ssl_certificate': 'test_value_30',
'ssl_client_fallback': 'disable',
'ssl_client_renegotiation': 'allow',
'ssl_client_session_state_max': '33',
'ssl_client_session_state_timeout': '34',
'ssl_client_session_state_type': 'disable',
'ssl_dh_bits': '768',
'ssl_hpkp': 'disable',
'ssl_hpkp_age': '38',
'ssl_hpkp_backup': 'test_value_39',
'ssl_hpkp_include_subdomains': 'disable',
'ssl_hpkp_primary': 'test_value_41',
'ssl_hpkp_report_uri': 'test_value_42',
'ssl_hsts': 'disable',
'ssl_hsts_age': '44',
'ssl_hsts_include_subdomains': 'disable',
'ssl_http_location_conversion': 'enable',
'ssl_http_match_host': 'enable',
'ssl_max_version': 'ssl-3.0',
'ssl_min_version': 'ssl-3.0',
'ssl_mode': 'half',
'ssl_pfs': 'require',
'ssl_send_empty_frags': 'enable',
'ssl_server_algorithm': 'high',
'ssl_server_max_version': 'ssl-3.0',
'ssl_server_min_version': 'ssl-3.0',
'ssl_server_session_state_max': '56',
'ssl_server_session_state_timeout': '57',
'ssl_server_session_state_type': 'disable',
'type': 'static-nat',
'uuid': 'test_value_60',
'weblogic_server': 'disable',
'websphere_server': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vip6.fortios_firewall(input_data, fos_instance)
expected_data = {
'arp-reply': 'disable',
'color': '4',
'comment': 'Comment.',
'extip': 'test_value_6',
'extport': 'test_value_7',
'http-cookie-age': '8',
'http-cookie-domain': 'test_value_9',
'http-cookie-domain-from-host': 'disable',
'http-cookie-generation': '11',
'http-cookie-path': 'test_value_12',
'http-cookie-share': 'disable',
'http-ip-header': 'enable',
'http-ip-header-name': 'test_value_15',
'http-multiplex': 'enable',
'https-cookie-secure': 'disable',
'id': '18',
'ldb-method': 'static',
'mappedip': 'test_value_20',
'mappedport': 'test_value_21',
'max-embryonic-connections': '22',
'name': 'default_name_23',
'outlook-web-access': 'disable',
'persistence': 'none',
'portforward': 'disable',
'protocol': 'tcp',
'server-type': 'http',
'ssl-algorithm': 'high',
'ssl-certificate': 'test_value_30',
'ssl-client-fallback': 'disable',
'ssl-client-renegotiation': 'allow',
'ssl-client-session-state-max': '33',
'ssl-client-session-state-timeout': '34',
'ssl-client-session-state-type': 'disable',
'ssl-dh-bits': '768',
'ssl-hpkp': 'disable',
'ssl-hpkp-age': '38',
'ssl-hpkp-backup': 'test_value_39',
'ssl-hpkp-include-subdomains': 'disable',
'ssl-hpkp-primary': 'test_value_41',
'ssl-hpkp-report-uri': 'test_value_42',
'ssl-hsts': 'disable',
'ssl-hsts-age': '44',
'ssl-hsts-include-subdomains': 'disable',
'ssl-http-location-conversion': 'enable',
'ssl-http-match-host': 'enable',
'ssl-max-version': 'ssl-3.0',
'ssl-min-version': 'ssl-3.0',
'ssl-mode': 'half',
'ssl-pfs': 'require',
'ssl-send-empty-frags': 'enable',
'ssl-server-algorithm': 'high',
'ssl-server-max-version': 'ssl-3.0',
'ssl-server-min-version': 'ssl-3.0',
'ssl-server-session-state-max': '56',
'ssl-server-session-state-timeout': '57',
'ssl-server-session-state-type': 'disable',
'type': 'static-nat',
'uuid': 'test_value_60',
'weblogic-server': 'disable',
'websphere-server': 'disable'
}
set_method_mock.assert_called_with('firewall', 'vip6', 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,339 @@
# 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_firewall_vip64
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_firewall_vip64.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_vip64_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',
'firewall_vip64': {
'arp_reply': 'disable',
'color': '4',
'comment': 'Comment.',
'extip': 'test_value_6',
'extport': 'test_value_7',
'id': '8',
'ldb_method': 'static',
'mappedip': 'test_value_10',
'mappedport': 'test_value_11',
'name': 'default_name_12',
'portforward': 'disable',
'protocol': 'tcp',
'server_type': 'http',
'type': 'static-nat',
'uuid': 'test_value_17'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vip64.fortios_firewall(input_data, fos_instance)
expected_data = {
'arp-reply': 'disable',
'color': '4',
'comment': 'Comment.',
'extip': 'test_value_6',
'extport': 'test_value_7',
'id': '8',
'ldb-method': 'static',
'mappedip': 'test_value_10',
'mappedport': 'test_value_11',
'name': 'default_name_12',
'portforward': 'disable',
'protocol': 'tcp',
'server-type': 'http',
'type': 'static-nat',
'uuid': 'test_value_17'
}
set_method_mock.assert_called_with('firewall', 'vip64', 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_firewall_vip64_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',
'firewall_vip64': {
'arp_reply': 'disable',
'color': '4',
'comment': 'Comment.',
'extip': 'test_value_6',
'extport': 'test_value_7',
'id': '8',
'ldb_method': 'static',
'mappedip': 'test_value_10',
'mappedport': 'test_value_11',
'name': 'default_name_12',
'portforward': 'disable',
'protocol': 'tcp',
'server_type': 'http',
'type': 'static-nat',
'uuid': 'test_value_17'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vip64.fortios_firewall(input_data, fos_instance)
expected_data = {
'arp-reply': 'disable',
'color': '4',
'comment': 'Comment.',
'extip': 'test_value_6',
'extport': 'test_value_7',
'id': '8',
'ldb-method': 'static',
'mappedip': 'test_value_10',
'mappedport': 'test_value_11',
'name': 'default_name_12',
'portforward': 'disable',
'protocol': 'tcp',
'server-type': 'http',
'type': 'static-nat',
'uuid': 'test_value_17'
}
set_method_mock.assert_called_with('firewall', 'vip64', 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_firewall_vip64_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',
'firewall_vip64': {
'arp_reply': 'disable',
'color': '4',
'comment': 'Comment.',
'extip': 'test_value_6',
'extport': 'test_value_7',
'id': '8',
'ldb_method': 'static',
'mappedip': 'test_value_10',
'mappedport': 'test_value_11',
'name': 'default_name_12',
'portforward': 'disable',
'protocol': 'tcp',
'server_type': 'http',
'type': 'static-nat',
'uuid': 'test_value_17'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vip64.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'vip64', 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_firewall_vip64_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',
'firewall_vip64': {
'arp_reply': 'disable',
'color': '4',
'comment': 'Comment.',
'extip': 'test_value_6',
'extport': 'test_value_7',
'id': '8',
'ldb_method': 'static',
'mappedip': 'test_value_10',
'mappedport': 'test_value_11',
'name': 'default_name_12',
'portforward': 'disable',
'protocol': 'tcp',
'server_type': 'http',
'type': 'static-nat',
'uuid': 'test_value_17'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vip64.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'vip64', 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_firewall_vip64_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',
'firewall_vip64': {
'arp_reply': 'disable',
'color': '4',
'comment': 'Comment.',
'extip': 'test_value_6',
'extport': 'test_value_7',
'id': '8',
'ldb_method': 'static',
'mappedip': 'test_value_10',
'mappedport': 'test_value_11',
'name': 'default_name_12',
'portforward': 'disable',
'protocol': 'tcp',
'server_type': 'http',
'type': 'static-nat',
'uuid': 'test_value_17'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vip64.fortios_firewall(input_data, fos_instance)
expected_data = {
'arp-reply': 'disable',
'color': '4',
'comment': 'Comment.',
'extip': 'test_value_6',
'extport': 'test_value_7',
'id': '8',
'ldb-method': 'static',
'mappedip': 'test_value_10',
'mappedport': 'test_value_11',
'name': 'default_name_12',
'portforward': 'disable',
'protocol': 'tcp',
'server-type': 'http',
'type': 'static-nat',
'uuid': 'test_value_17'
}
set_method_mock.assert_called_with('firewall', 'vip64', 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_firewall_vip64_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',
'firewall_vip64': {
'random_attribute_not_valid': 'tag',
'arp_reply': 'disable',
'color': '4',
'comment': 'Comment.',
'extip': 'test_value_6',
'extport': 'test_value_7',
'id': '8',
'ldb_method': 'static',
'mappedip': 'test_value_10',
'mappedport': 'test_value_11',
'name': 'default_name_12',
'portforward': 'disable',
'protocol': 'tcp',
'server_type': 'http',
'type': 'static-nat',
'uuid': 'test_value_17'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vip64.fortios_firewall(input_data, fos_instance)
expected_data = {
'arp-reply': 'disable',
'color': '4',
'comment': 'Comment.',
'extip': 'test_value_6',
'extport': 'test_value_7',
'id': '8',
'ldb-method': 'static',
'mappedip': 'test_value_10',
'mappedport': 'test_value_11',
'name': 'default_name_12',
'portforward': 'disable',
'protocol': 'tcp',
'server-type': 'http',
'type': 'static-nat',
'uuid': 'test_value_17'
}
set_method_mock.assert_called_with('firewall', 'vip64', 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_firewall_vipgrp
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_firewall_vipgrp.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_vipgrp_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',
'firewall_vipgrp': {
'color': '3',
'comments': 'test_value_4',
'interface': 'test_value_5',
'name': 'default_name_6',
'uuid': 'test_value_7'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vipgrp.fortios_firewall(input_data, fos_instance)
expected_data = {
'color': '3',
'comments': 'test_value_4',
'interface': 'test_value_5',
'name': 'default_name_6',
'uuid': 'test_value_7'
}
set_method_mock.assert_called_with('firewall', 'vipgrp', 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_firewall_vipgrp_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',
'firewall_vipgrp': {
'color': '3',
'comments': 'test_value_4',
'interface': 'test_value_5',
'name': 'default_name_6',
'uuid': 'test_value_7'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vipgrp.fortios_firewall(input_data, fos_instance)
expected_data = {
'color': '3',
'comments': 'test_value_4',
'interface': 'test_value_5',
'name': 'default_name_6',
'uuid': 'test_value_7'
}
set_method_mock.assert_called_with('firewall', 'vipgrp', 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_firewall_vipgrp_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',
'firewall_vipgrp': {
'color': '3',
'comments': 'test_value_4',
'interface': 'test_value_5',
'name': 'default_name_6',
'uuid': 'test_value_7'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vipgrp.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'vipgrp', 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_firewall_vipgrp_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',
'firewall_vipgrp': {
'color': '3',
'comments': 'test_value_4',
'interface': 'test_value_5',
'name': 'default_name_6',
'uuid': 'test_value_7'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vipgrp.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'vipgrp', 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_firewall_vipgrp_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',
'firewall_vipgrp': {
'color': '3',
'comments': 'test_value_4',
'interface': 'test_value_5',
'name': 'default_name_6',
'uuid': 'test_value_7'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vipgrp.fortios_firewall(input_data, fos_instance)
expected_data = {
'color': '3',
'comments': 'test_value_4',
'interface': 'test_value_5',
'name': 'default_name_6',
'uuid': 'test_value_7'
}
set_method_mock.assert_called_with('firewall', 'vipgrp', 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_firewall_vipgrp_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',
'firewall_vipgrp': {
'random_attribute_not_valid': 'tag',
'color': '3',
'comments': 'test_value_4',
'interface': 'test_value_5',
'name': 'default_name_6',
'uuid': 'test_value_7'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vipgrp.fortios_firewall(input_data, fos_instance)
expected_data = {
'color': '3',
'comments': 'test_value_4',
'interface': 'test_value_5',
'name': 'default_name_6',
'uuid': 'test_value_7'
}
set_method_mock.assert_called_with('firewall', 'vipgrp', 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,229 @@
# 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_firewall_vipgrp46
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_firewall_vipgrp46.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_vipgrp46_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',
'firewall_vipgrp46': {
'color': '3',
'comments': 'test_value_4',
'name': 'default_name_5',
'uuid': 'test_value_6'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vipgrp46.fortios_firewall(input_data, fos_instance)
expected_data = {
'color': '3',
'comments': 'test_value_4',
'name': 'default_name_5',
'uuid': 'test_value_6'
}
set_method_mock.assert_called_with('firewall', 'vipgrp46', 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_firewall_vipgrp46_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',
'firewall_vipgrp46': {
'color': '3',
'comments': 'test_value_4',
'name': 'default_name_5',
'uuid': 'test_value_6'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vipgrp46.fortios_firewall(input_data, fos_instance)
expected_data = {
'color': '3',
'comments': 'test_value_4',
'name': 'default_name_5',
'uuid': 'test_value_6'
}
set_method_mock.assert_called_with('firewall', 'vipgrp46', 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_firewall_vipgrp46_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',
'firewall_vipgrp46': {
'color': '3',
'comments': 'test_value_4',
'name': 'default_name_5',
'uuid': 'test_value_6'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vipgrp46.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'vipgrp46', 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_firewall_vipgrp46_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',
'firewall_vipgrp46': {
'color': '3',
'comments': 'test_value_4',
'name': 'default_name_5',
'uuid': 'test_value_6'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vipgrp46.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'vipgrp46', 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_firewall_vipgrp46_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',
'firewall_vipgrp46': {
'color': '3',
'comments': 'test_value_4',
'name': 'default_name_5',
'uuid': 'test_value_6'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vipgrp46.fortios_firewall(input_data, fos_instance)
expected_data = {
'color': '3',
'comments': 'test_value_4',
'name': 'default_name_5',
'uuid': 'test_value_6'
}
set_method_mock.assert_called_with('firewall', 'vipgrp46', 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_firewall_vipgrp46_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',
'firewall_vipgrp46': {
'random_attribute_not_valid': 'tag',
'color': '3',
'comments': 'test_value_4',
'name': 'default_name_5',
'uuid': 'test_value_6'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vipgrp46.fortios_firewall(input_data, fos_instance)
expected_data = {
'color': '3',
'comments': 'test_value_4',
'name': 'default_name_5',
'uuid': 'test_value_6'
}
set_method_mock.assert_called_with('firewall', 'vipgrp46', 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,229 @@
# 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_firewall_vipgrp6
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_firewall_vipgrp6.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_vipgrp6_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',
'firewall_vipgrp6': {
'color': '3',
'comments': 'test_value_4',
'name': 'default_name_5',
'uuid': 'test_value_6'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vipgrp6.fortios_firewall(input_data, fos_instance)
expected_data = {
'color': '3',
'comments': 'test_value_4',
'name': 'default_name_5',
'uuid': 'test_value_6'
}
set_method_mock.assert_called_with('firewall', 'vipgrp6', 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_firewall_vipgrp6_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',
'firewall_vipgrp6': {
'color': '3',
'comments': 'test_value_4',
'name': 'default_name_5',
'uuid': 'test_value_6'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vipgrp6.fortios_firewall(input_data, fos_instance)
expected_data = {
'color': '3',
'comments': 'test_value_4',
'name': 'default_name_5',
'uuid': 'test_value_6'
}
set_method_mock.assert_called_with('firewall', 'vipgrp6', 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_firewall_vipgrp6_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',
'firewall_vipgrp6': {
'color': '3',
'comments': 'test_value_4',
'name': 'default_name_5',
'uuid': 'test_value_6'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vipgrp6.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'vipgrp6', 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_firewall_vipgrp6_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',
'firewall_vipgrp6': {
'color': '3',
'comments': 'test_value_4',
'name': 'default_name_5',
'uuid': 'test_value_6'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vipgrp6.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'vipgrp6', 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_firewall_vipgrp6_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',
'firewall_vipgrp6': {
'color': '3',
'comments': 'test_value_4',
'name': 'default_name_5',
'uuid': 'test_value_6'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vipgrp6.fortios_firewall(input_data, fos_instance)
expected_data = {
'color': '3',
'comments': 'test_value_4',
'name': 'default_name_5',
'uuid': 'test_value_6'
}
set_method_mock.assert_called_with('firewall', 'vipgrp6', 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_firewall_vipgrp6_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',
'firewall_vipgrp6': {
'random_attribute_not_valid': 'tag',
'color': '3',
'comments': 'test_value_4',
'name': 'default_name_5',
'uuid': 'test_value_6'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vipgrp6.fortios_firewall(input_data, fos_instance)
expected_data = {
'color': '3',
'comments': 'test_value_4',
'name': 'default_name_5',
'uuid': 'test_value_6'
}
set_method_mock.assert_called_with('firewall', 'vipgrp6', 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,229 @@
# 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_firewall_vipgrp64
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_firewall_vipgrp64.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_vipgrp64_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',
'firewall_vipgrp64': {
'color': '3',
'comments': 'test_value_4',
'name': 'default_name_5',
'uuid': 'test_value_6'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vipgrp64.fortios_firewall(input_data, fos_instance)
expected_data = {
'color': '3',
'comments': 'test_value_4',
'name': 'default_name_5',
'uuid': 'test_value_6'
}
set_method_mock.assert_called_with('firewall', 'vipgrp64', 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_firewall_vipgrp64_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',
'firewall_vipgrp64': {
'color': '3',
'comments': 'test_value_4',
'name': 'default_name_5',
'uuid': 'test_value_6'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vipgrp64.fortios_firewall(input_data, fos_instance)
expected_data = {
'color': '3',
'comments': 'test_value_4',
'name': 'default_name_5',
'uuid': 'test_value_6'
}
set_method_mock.assert_called_with('firewall', 'vipgrp64', 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_firewall_vipgrp64_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',
'firewall_vipgrp64': {
'color': '3',
'comments': 'test_value_4',
'name': 'default_name_5',
'uuid': 'test_value_6'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vipgrp64.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'vipgrp64', 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_firewall_vipgrp64_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',
'firewall_vipgrp64': {
'color': '3',
'comments': 'test_value_4',
'name': 'default_name_5',
'uuid': 'test_value_6'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vipgrp64.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'vipgrp64', 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_firewall_vipgrp64_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',
'firewall_vipgrp64': {
'color': '3',
'comments': 'test_value_4',
'name': 'default_name_5',
'uuid': 'test_value_6'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vipgrp64.fortios_firewall(input_data, fos_instance)
expected_data = {
'color': '3',
'comments': 'test_value_4',
'name': 'default_name_5',
'uuid': 'test_value_6'
}
set_method_mock.assert_called_with('firewall', 'vipgrp64', 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_firewall_vipgrp64_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',
'firewall_vipgrp64': {
'random_attribute_not_valid': 'tag',
'color': '3',
'comments': 'test_value_4',
'name': 'default_name_5',
'uuid': 'test_value_6'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_vipgrp64.fortios_firewall(input_data, fos_instance)
expected_data = {
'color': '3',
'comments': 'test_value_4',
'name': 'default_name_5',
'uuid': 'test_value_6'
}
set_method_mock.assert_called_with('firewall', 'vipgrp64', 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,249 @@
# 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_firewall_wildcard_fqdn_custom
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_firewall_wildcard_fqdn_custom.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_wildcard_fqdn_custom_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',
'firewall_wildcard_fqdn_custom': {
'color': '3',
'comment': 'Comment.',
'name': 'default_name_5',
'uuid': 'test_value_6',
'visibility': 'enable',
'wildcard_fqdn': 'test_value_8'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_wildcard_fqdn_custom.fortios_firewall_wildcard_fqdn(input_data, fos_instance)
expected_data = {
'color': '3',
'comment': 'Comment.',
'name': 'default_name_5',
'uuid': 'test_value_6',
'visibility': 'enable',
'wildcard-fqdn': 'test_value_8'
}
set_method_mock.assert_called_with('firewall.wildcard-fqdn', 'custom', 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_firewall_wildcard_fqdn_custom_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',
'firewall_wildcard_fqdn_custom': {
'color': '3',
'comment': 'Comment.',
'name': 'default_name_5',
'uuid': 'test_value_6',
'visibility': 'enable',
'wildcard_fqdn': 'test_value_8'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_wildcard_fqdn_custom.fortios_firewall_wildcard_fqdn(input_data, fos_instance)
expected_data = {
'color': '3',
'comment': 'Comment.',
'name': 'default_name_5',
'uuid': 'test_value_6',
'visibility': 'enable',
'wildcard-fqdn': 'test_value_8'
}
set_method_mock.assert_called_with('firewall.wildcard-fqdn', 'custom', 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_firewall_wildcard_fqdn_custom_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',
'firewall_wildcard_fqdn_custom': {
'color': '3',
'comment': 'Comment.',
'name': 'default_name_5',
'uuid': 'test_value_6',
'visibility': 'enable',
'wildcard_fqdn': 'test_value_8'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_wildcard_fqdn_custom.fortios_firewall_wildcard_fqdn(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall.wildcard-fqdn', 'custom', 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_firewall_wildcard_fqdn_custom_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',
'firewall_wildcard_fqdn_custom': {
'color': '3',
'comment': 'Comment.',
'name': 'default_name_5',
'uuid': 'test_value_6',
'visibility': 'enable',
'wildcard_fqdn': 'test_value_8'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_wildcard_fqdn_custom.fortios_firewall_wildcard_fqdn(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall.wildcard-fqdn', 'custom', 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_firewall_wildcard_fqdn_custom_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',
'firewall_wildcard_fqdn_custom': {
'color': '3',
'comment': 'Comment.',
'name': 'default_name_5',
'uuid': 'test_value_6',
'visibility': 'enable',
'wildcard_fqdn': 'test_value_8'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_wildcard_fqdn_custom.fortios_firewall_wildcard_fqdn(input_data, fos_instance)
expected_data = {
'color': '3',
'comment': 'Comment.',
'name': 'default_name_5',
'uuid': 'test_value_6',
'visibility': 'enable',
'wildcard-fqdn': 'test_value_8'
}
set_method_mock.assert_called_with('firewall.wildcard-fqdn', 'custom', 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_firewall_wildcard_fqdn_custom_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',
'firewall_wildcard_fqdn_custom': {
'random_attribute_not_valid': 'tag',
'color': '3',
'comment': 'Comment.',
'name': 'default_name_5',
'uuid': 'test_value_6',
'visibility': 'enable',
'wildcard_fqdn': 'test_value_8'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_wildcard_fqdn_custom.fortios_firewall_wildcard_fqdn(input_data, fos_instance)
expected_data = {
'color': '3',
'comment': 'Comment.',
'name': 'default_name_5',
'uuid': 'test_value_6',
'visibility': 'enable',
'wildcard-fqdn': 'test_value_8'
}
set_method_mock.assert_called_with('firewall.wildcard-fqdn', 'custom', 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_firewall_wildcard_fqdn_group
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_firewall_wildcard_fqdn_group.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_wildcard_fqdn_group_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',
'firewall_wildcard_fqdn_group': {
'color': '3',
'comment': 'Comment.',
'name': 'default_name_5',
'uuid': 'test_value_6',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_wildcard_fqdn_group.fortios_firewall_wildcard_fqdn(input_data, fos_instance)
expected_data = {
'color': '3',
'comment': 'Comment.',
'name': 'default_name_5',
'uuid': 'test_value_6',
'visibility': 'enable'
}
set_method_mock.assert_called_with('firewall.wildcard-fqdn', 'group', 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_firewall_wildcard_fqdn_group_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',
'firewall_wildcard_fqdn_group': {
'color': '3',
'comment': 'Comment.',
'name': 'default_name_5',
'uuid': 'test_value_6',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_wildcard_fqdn_group.fortios_firewall_wildcard_fqdn(input_data, fos_instance)
expected_data = {
'color': '3',
'comment': 'Comment.',
'name': 'default_name_5',
'uuid': 'test_value_6',
'visibility': 'enable'
}
set_method_mock.assert_called_with('firewall.wildcard-fqdn', 'group', 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_firewall_wildcard_fqdn_group_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',
'firewall_wildcard_fqdn_group': {
'color': '3',
'comment': 'Comment.',
'name': 'default_name_5',
'uuid': 'test_value_6',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_wildcard_fqdn_group.fortios_firewall_wildcard_fqdn(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall.wildcard-fqdn', 'group', 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_firewall_wildcard_fqdn_group_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',
'firewall_wildcard_fqdn_group': {
'color': '3',
'comment': 'Comment.',
'name': 'default_name_5',
'uuid': 'test_value_6',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_wildcard_fqdn_group.fortios_firewall_wildcard_fqdn(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall.wildcard-fqdn', 'group', 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_firewall_wildcard_fqdn_group_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',
'firewall_wildcard_fqdn_group': {
'color': '3',
'comment': 'Comment.',
'name': 'default_name_5',
'uuid': 'test_value_6',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_wildcard_fqdn_group.fortios_firewall_wildcard_fqdn(input_data, fos_instance)
expected_data = {
'color': '3',
'comment': 'Comment.',
'name': 'default_name_5',
'uuid': 'test_value_6',
'visibility': 'enable'
}
set_method_mock.assert_called_with('firewall.wildcard-fqdn', 'group', 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_firewall_wildcard_fqdn_group_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',
'firewall_wildcard_fqdn_group': {
'random_attribute_not_valid': 'tag',
'color': '3',
'comment': 'Comment.',
'name': 'default_name_5',
'uuid': 'test_value_6',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_wildcard_fqdn_group.fortios_firewall_wildcard_fqdn(input_data, fos_instance)
expected_data = {
'color': '3',
'comment': 'Comment.',
'name': 'default_name_5',
'uuid': 'test_value_6',
'visibility': 'enable'
}
set_method_mock.assert_called_with('firewall.wildcard-fqdn', 'group', 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,183 @@
# 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_ftp_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_ftp_proxy_explicit.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_ftp_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',
'ftp_proxy_explicit': {
'incoming_ip': 'test_value_3',
'incoming_port': 'test_value_4',
'outgoing_ip': 'test_value_5',
'sec_default_action': 'accept',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_ftp_proxy_explicit.fortios_ftp_proxy(input_data, fos_instance)
expected_data = {
'incoming-ip': 'test_value_3',
'incoming-port': 'test_value_4',
'outgoing-ip': 'test_value_5',
'sec-default-action': 'accept',
'status': 'enable'
}
set_method_mock.assert_called_with('ftp-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_ftp_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',
'ftp_proxy_explicit': {
'incoming_ip': 'test_value_3',
'incoming_port': 'test_value_4',
'outgoing_ip': 'test_value_5',
'sec_default_action': 'accept',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_ftp_proxy_explicit.fortios_ftp_proxy(input_data, fos_instance)
expected_data = {
'incoming-ip': 'test_value_3',
'incoming-port': 'test_value_4',
'outgoing-ip': 'test_value_5',
'sec-default-action': 'accept',
'status': 'enable'
}
set_method_mock.assert_called_with('ftp-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_ftp_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',
'ftp_proxy_explicit': {
'incoming_ip': 'test_value_3',
'incoming_port': 'test_value_4',
'outgoing_ip': 'test_value_5',
'sec_default_action': 'accept',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_ftp_proxy_explicit.fortios_ftp_proxy(input_data, fos_instance)
expected_data = {
'incoming-ip': 'test_value_3',
'incoming-port': 'test_value_4',
'outgoing-ip': 'test_value_5',
'sec-default-action': 'accept',
'status': 'enable'
}
set_method_mock.assert_called_with('ftp-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_ftp_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',
'ftp_proxy_explicit': {
'random_attribute_not_valid': 'tag',
'incoming_ip': 'test_value_3',
'incoming_port': 'test_value_4',
'outgoing_ip': 'test_value_5',
'sec_default_action': 'accept',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_ftp_proxy_explicit.fortios_ftp_proxy(input_data, fos_instance)
expected_data = {
'incoming-ip': 'test_value_3',
'incoming-port': 'test_value_4',
'outgoing-ip': 'test_value_5',
'sec-default-action': 'accept',
'status': 'enable'
}
set_method_mock.assert_called_with('ftp-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,309 @@
# 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_icap_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_icap_profile.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_icap_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',
'icap_profile': {
'methods': 'delete',
'name': 'default_name_4',
'replacemsg_group': 'test_value_5',
'request': 'disable',
'request_failure': 'error',
'request_path': 'test_value_8',
'request_server': 'test_value_9',
'response': 'disable',
'response_failure': 'error',
'response_path': 'test_value_12',
'response_server': 'test_value_13',
'streaming_content_bypass': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_icap_profile.fortios_icap(input_data, fos_instance)
expected_data = {
'methods': 'delete',
'name': 'default_name_4',
'replacemsg-group': 'test_value_5',
'request': 'disable',
'request-failure': 'error',
'request-path': 'test_value_8',
'request-server': 'test_value_9',
'response': 'disable',
'response-failure': 'error',
'response-path': 'test_value_12',
'response-server': 'test_value_13',
'streaming-content-bypass': 'disable'
}
set_method_mock.assert_called_with('icap', '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_icap_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',
'icap_profile': {
'methods': 'delete',
'name': 'default_name_4',
'replacemsg_group': 'test_value_5',
'request': 'disable',
'request_failure': 'error',
'request_path': 'test_value_8',
'request_server': 'test_value_9',
'response': 'disable',
'response_failure': 'error',
'response_path': 'test_value_12',
'response_server': 'test_value_13',
'streaming_content_bypass': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_icap_profile.fortios_icap(input_data, fos_instance)
expected_data = {
'methods': 'delete',
'name': 'default_name_4',
'replacemsg-group': 'test_value_5',
'request': 'disable',
'request-failure': 'error',
'request-path': 'test_value_8',
'request-server': 'test_value_9',
'response': 'disable',
'response-failure': 'error',
'response-path': 'test_value_12',
'response-server': 'test_value_13',
'streaming-content-bypass': 'disable'
}
set_method_mock.assert_called_with('icap', '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_icap_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',
'icap_profile': {
'methods': 'delete',
'name': 'default_name_4',
'replacemsg_group': 'test_value_5',
'request': 'disable',
'request_failure': 'error',
'request_path': 'test_value_8',
'request_server': 'test_value_9',
'response': 'disable',
'response_failure': 'error',
'response_path': 'test_value_12',
'response_server': 'test_value_13',
'streaming_content_bypass': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_icap_profile.fortios_icap(input_data, fos_instance)
delete_method_mock.assert_called_with('icap', '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_icap_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',
'icap_profile': {
'methods': 'delete',
'name': 'default_name_4',
'replacemsg_group': 'test_value_5',
'request': 'disable',
'request_failure': 'error',
'request_path': 'test_value_8',
'request_server': 'test_value_9',
'response': 'disable',
'response_failure': 'error',
'response_path': 'test_value_12',
'response_server': 'test_value_13',
'streaming_content_bypass': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_icap_profile.fortios_icap(input_data, fos_instance)
delete_method_mock.assert_called_with('icap', '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_icap_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',
'icap_profile': {
'methods': 'delete',
'name': 'default_name_4',
'replacemsg_group': 'test_value_5',
'request': 'disable',
'request_failure': 'error',
'request_path': 'test_value_8',
'request_server': 'test_value_9',
'response': 'disable',
'response_failure': 'error',
'response_path': 'test_value_12',
'response_server': 'test_value_13',
'streaming_content_bypass': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_icap_profile.fortios_icap(input_data, fos_instance)
expected_data = {
'methods': 'delete',
'name': 'default_name_4',
'replacemsg-group': 'test_value_5',
'request': 'disable',
'request-failure': 'error',
'request-path': 'test_value_8',
'request-server': 'test_value_9',
'response': 'disable',
'response-failure': 'error',
'response-path': 'test_value_12',
'response-server': 'test_value_13',
'streaming-content-bypass': 'disable'
}
set_method_mock.assert_called_with('icap', '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_icap_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',
'icap_profile': {
'random_attribute_not_valid': 'tag',
'methods': 'delete',
'name': 'default_name_4',
'replacemsg_group': 'test_value_5',
'request': 'disable',
'request_failure': 'error',
'request_path': 'test_value_8',
'request_server': 'test_value_9',
'response': 'disable',
'response_failure': 'error',
'response_path': 'test_value_12',
'response_server': 'test_value_13',
'streaming_content_bypass': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_icap_profile.fortios_icap(input_data, fos_instance)
expected_data = {
'methods': 'delete',
'name': 'default_name_4',
'replacemsg-group': 'test_value_5',
'request': 'disable',
'request-failure': 'error',
'request-path': 'test_value_8',
'request-server': 'test_value_9',
'response': 'disable',
'response-failure': 'error',
'response-path': 'test_value_12',
'response-server': 'test_value_13',
'streaming-content-bypass': 'disable'
}
set_method_mock.assert_called_with('icap', '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,249 @@
# 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_icap_server
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_icap_server.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_icap_server_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',
'icap_server': {
'ip_address': 'test_value_3',
'ip_version': '4',
'ip6_address': 'test_value_5',
'max_connections': '6',
'name': 'default_name_7',
'port': '8'
},
'vdom': 'root'}
is_error, changed, response = fortios_icap_server.fortios_icap(input_data, fos_instance)
expected_data = {
'ip-address': 'test_value_3',
'ip-version': '4',
'ip6-address': 'test_value_5',
'max-connections': '6',
'name': 'default_name_7',
'port': '8'
}
set_method_mock.assert_called_with('icap', 'server', 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_icap_server_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',
'icap_server': {
'ip_address': 'test_value_3',
'ip_version': '4',
'ip6_address': 'test_value_5',
'max_connections': '6',
'name': 'default_name_7',
'port': '8'
},
'vdom': 'root'}
is_error, changed, response = fortios_icap_server.fortios_icap(input_data, fos_instance)
expected_data = {
'ip-address': 'test_value_3',
'ip-version': '4',
'ip6-address': 'test_value_5',
'max-connections': '6',
'name': 'default_name_7',
'port': '8'
}
set_method_mock.assert_called_with('icap', 'server', 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_icap_server_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',
'icap_server': {
'ip_address': 'test_value_3',
'ip_version': '4',
'ip6_address': 'test_value_5',
'max_connections': '6',
'name': 'default_name_7',
'port': '8'
},
'vdom': 'root'}
is_error, changed, response = fortios_icap_server.fortios_icap(input_data, fos_instance)
delete_method_mock.assert_called_with('icap', 'server', 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_icap_server_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',
'icap_server': {
'ip_address': 'test_value_3',
'ip_version': '4',
'ip6_address': 'test_value_5',
'max_connections': '6',
'name': 'default_name_7',
'port': '8'
},
'vdom': 'root'}
is_error, changed, response = fortios_icap_server.fortios_icap(input_data, fos_instance)
delete_method_mock.assert_called_with('icap', 'server', 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_icap_server_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',
'icap_server': {
'ip_address': 'test_value_3',
'ip_version': '4',
'ip6_address': 'test_value_5',
'max_connections': '6',
'name': 'default_name_7',
'port': '8'
},
'vdom': 'root'}
is_error, changed, response = fortios_icap_server.fortios_icap(input_data, fos_instance)
expected_data = {
'ip-address': 'test_value_3',
'ip-version': '4',
'ip6-address': 'test_value_5',
'max-connections': '6',
'name': 'default_name_7',
'port': '8'
}
set_method_mock.assert_called_with('icap', 'server', 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_icap_server_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',
'icap_server': {
'random_attribute_not_valid': 'tag',
'ip_address': 'test_value_3',
'ip_version': '4',
'ip6_address': 'test_value_5',
'max_connections': '6',
'name': 'default_name_7',
'port': '8'
},
'vdom': 'root'}
is_error, changed, response = fortios_icap_server.fortios_icap(input_data, fos_instance)
expected_data = {
'ip-address': 'test_value_3',
'ip-version': '4',
'ip6-address': 'test_value_5',
'max-connections': '6',
'name': 'default_name_7',
'port': '8'
}
set_method_mock.assert_called_with('icap', 'server', 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,329 @@
# 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_ips_custom
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_ips_custom.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_ips_custom_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',
'ips_custom': {
'action': 'pass',
'application': 'test_value_4',
'comment': 'Comment.',
'location': 'test_value_6',
'log': 'disable',
'log_packet': 'disable',
'os': 'test_value_9',
'protocol': 'test_value_10',
'rule_id': '11',
'severity': 'test_value_12',
'sig_name': 'test_value_13',
'signature': 'test_value_14',
'status': 'disable',
'tag': 'test_value_16'
},
'vdom': 'root'}
is_error, changed, response = fortios_ips_custom.fortios_ips(input_data, fos_instance)
expected_data = {
'action': 'pass',
'application': 'test_value_4',
'comment': 'Comment.',
'location': 'test_value_6',
'log': 'disable',
'log-packet': 'disable',
'os': 'test_value_9',
'protocol': 'test_value_10',
'rule-id': '11',
'severity': 'test_value_12',
'sig-name': 'test_value_13',
'signature': 'test_value_14',
'status': 'disable',
'tag': 'test_value_16'
}
set_method_mock.assert_called_with('ips', 'custom', 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_ips_custom_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',
'ips_custom': {
'action': 'pass',
'application': 'test_value_4',
'comment': 'Comment.',
'location': 'test_value_6',
'log': 'disable',
'log_packet': 'disable',
'os': 'test_value_9',
'protocol': 'test_value_10',
'rule_id': '11',
'severity': 'test_value_12',
'sig_name': 'test_value_13',
'signature': 'test_value_14',
'status': 'disable',
'tag': 'test_value_16'
},
'vdom': 'root'}
is_error, changed, response = fortios_ips_custom.fortios_ips(input_data, fos_instance)
expected_data = {
'action': 'pass',
'application': 'test_value_4',
'comment': 'Comment.',
'location': 'test_value_6',
'log': 'disable',
'log-packet': 'disable',
'os': 'test_value_9',
'protocol': 'test_value_10',
'rule-id': '11',
'severity': 'test_value_12',
'sig-name': 'test_value_13',
'signature': 'test_value_14',
'status': 'disable',
'tag': 'test_value_16'
}
set_method_mock.assert_called_with('ips', 'custom', 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_ips_custom_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',
'ips_custom': {
'action': 'pass',
'application': 'test_value_4',
'comment': 'Comment.',
'location': 'test_value_6',
'log': 'disable',
'log_packet': 'disable',
'os': 'test_value_9',
'protocol': 'test_value_10',
'rule_id': '11',
'severity': 'test_value_12',
'sig_name': 'test_value_13',
'signature': 'test_value_14',
'status': 'disable',
'tag': 'test_value_16'
},
'vdom': 'root'}
is_error, changed, response = fortios_ips_custom.fortios_ips(input_data, fos_instance)
delete_method_mock.assert_called_with('ips', 'custom', 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_ips_custom_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',
'ips_custom': {
'action': 'pass',
'application': 'test_value_4',
'comment': 'Comment.',
'location': 'test_value_6',
'log': 'disable',
'log_packet': 'disable',
'os': 'test_value_9',
'protocol': 'test_value_10',
'rule_id': '11',
'severity': 'test_value_12',
'sig_name': 'test_value_13',
'signature': 'test_value_14',
'status': 'disable',
'tag': 'test_value_16'
},
'vdom': 'root'}
is_error, changed, response = fortios_ips_custom.fortios_ips(input_data, fos_instance)
delete_method_mock.assert_called_with('ips', 'custom', 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_ips_custom_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',
'ips_custom': {
'action': 'pass',
'application': 'test_value_4',
'comment': 'Comment.',
'location': 'test_value_6',
'log': 'disable',
'log_packet': 'disable',
'os': 'test_value_9',
'protocol': 'test_value_10',
'rule_id': '11',
'severity': 'test_value_12',
'sig_name': 'test_value_13',
'signature': 'test_value_14',
'status': 'disable',
'tag': 'test_value_16'
},
'vdom': 'root'}
is_error, changed, response = fortios_ips_custom.fortios_ips(input_data, fos_instance)
expected_data = {
'action': 'pass',
'application': 'test_value_4',
'comment': 'Comment.',
'location': 'test_value_6',
'log': 'disable',
'log-packet': 'disable',
'os': 'test_value_9',
'protocol': 'test_value_10',
'rule-id': '11',
'severity': 'test_value_12',
'sig-name': 'test_value_13',
'signature': 'test_value_14',
'status': 'disable',
'tag': 'test_value_16'
}
set_method_mock.assert_called_with('ips', 'custom', 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_ips_custom_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',
'ips_custom': {
'random_attribute_not_valid': 'tag',
'action': 'pass',
'application': 'test_value_4',
'comment': 'Comment.',
'location': 'test_value_6',
'log': 'disable',
'log_packet': 'disable',
'os': 'test_value_9',
'protocol': 'test_value_10',
'rule_id': '11',
'severity': 'test_value_12',
'sig_name': 'test_value_13',
'signature': 'test_value_14',
'status': 'disable',
'tag': 'test_value_16'
},
'vdom': 'root'}
is_error, changed, response = fortios_ips_custom.fortios_ips(input_data, fos_instance)
expected_data = {
'action': 'pass',
'application': 'test_value_4',
'comment': 'Comment.',
'location': 'test_value_6',
'log': 'disable',
'log-packet': 'disable',
'os': 'test_value_9',
'protocol': 'test_value_10',
'rule-id': '11',
'severity': 'test_value_12',
'sig-name': 'test_value_13',
'signature': 'test_value_14',
'status': 'disable',
'tag': 'test_value_16'
}
set_method_mock.assert_called_with('ips', 'custom', 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,209 @@
# 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_ips_decoder
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_ips_decoder.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_ips_decoder_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',
'ips_decoder': {
'name': 'default_name_3',
},
'vdom': 'root'}
is_error, changed, response = fortios_ips_decoder.fortios_ips(input_data, fos_instance)
expected_data = {
'name': 'default_name_3',
}
set_method_mock.assert_called_with('ips', 'decoder', 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_ips_decoder_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',
'ips_decoder': {
'name': 'default_name_3',
},
'vdom': 'root'}
is_error, changed, response = fortios_ips_decoder.fortios_ips(input_data, fos_instance)
expected_data = {
'name': 'default_name_3',
}
set_method_mock.assert_called_with('ips', 'decoder', 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_ips_decoder_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',
'ips_decoder': {
'name': 'default_name_3',
},
'vdom': 'root'}
is_error, changed, response = fortios_ips_decoder.fortios_ips(input_data, fos_instance)
delete_method_mock.assert_called_with('ips', 'decoder', 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_ips_decoder_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',
'ips_decoder': {
'name': 'default_name_3',
},
'vdom': 'root'}
is_error, changed, response = fortios_ips_decoder.fortios_ips(input_data, fos_instance)
delete_method_mock.assert_called_with('ips', 'decoder', 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_ips_decoder_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',
'ips_decoder': {
'name': 'default_name_3',
},
'vdom': 'root'}
is_error, changed, response = fortios_ips_decoder.fortios_ips(input_data, fos_instance)
expected_data = {
'name': 'default_name_3',
}
set_method_mock.assert_called_with('ips', 'decoder', 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_ips_decoder_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',
'ips_decoder': {
'random_attribute_not_valid': 'tag',
'name': 'default_name_3',
},
'vdom': 'root'}
is_error, changed, response = fortios_ips_decoder.fortios_ips(input_data, fos_instance)
expected_data = {
'name': 'default_name_3',
}
set_method_mock.assert_called_with('ips', 'decoder', 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_ips_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_ips_global.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_ips_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',
'ips_global': {
'anomaly_mode': 'periodical',
'database': 'regular',
'deep_app_insp_db_limit': '5',
'deep_app_insp_timeout': '6',
'engine_count': '7',
'exclude_signatures': 'none',
'fail_open': 'enable',
'intelligent_mode': 'enable',
'session_limit_mode': 'accurate',
'skype_client_public_ipaddr': 'test_value_12',
'socket_size': '13',
'sync_session_ttl': 'enable',
'traffic_submit': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_ips_global.fortios_ips(input_data, fos_instance)
expected_data = {
'anomaly-mode': 'periodical',
'database': 'regular',
'deep-app-insp-db-limit': '5',
'deep-app-insp-timeout': '6',
'engine-count': '7',
'exclude-signatures': 'none',
'fail-open': 'enable',
'intelligent-mode': 'enable',
'session-limit-mode': 'accurate',
'skype-client-public-ipaddr': 'test_value_12',
'socket-size': '13',
'sync-session-ttl': 'enable',
'traffic-submit': 'enable'
}
set_method_mock.assert_called_with('ips', '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_ips_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',
'ips_global': {
'anomaly_mode': 'periodical',
'database': 'regular',
'deep_app_insp_db_limit': '5',
'deep_app_insp_timeout': '6',
'engine_count': '7',
'exclude_signatures': 'none',
'fail_open': 'enable',
'intelligent_mode': 'enable',
'session_limit_mode': 'accurate',
'skype_client_public_ipaddr': 'test_value_12',
'socket_size': '13',
'sync_session_ttl': 'enable',
'traffic_submit': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_ips_global.fortios_ips(input_data, fos_instance)
expected_data = {
'anomaly-mode': 'periodical',
'database': 'regular',
'deep-app-insp-db-limit': '5',
'deep-app-insp-timeout': '6',
'engine-count': '7',
'exclude-signatures': 'none',
'fail-open': 'enable',
'intelligent-mode': 'enable',
'session-limit-mode': 'accurate',
'skype-client-public-ipaddr': 'test_value_12',
'socket-size': '13',
'sync-session-ttl': 'enable',
'traffic-submit': 'enable'
}
set_method_mock.assert_called_with('ips', '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_ips_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',
'ips_global': {
'anomaly_mode': 'periodical',
'database': 'regular',
'deep_app_insp_db_limit': '5',
'deep_app_insp_timeout': '6',
'engine_count': '7',
'exclude_signatures': 'none',
'fail_open': 'enable',
'intelligent_mode': 'enable',
'session_limit_mode': 'accurate',
'skype_client_public_ipaddr': 'test_value_12',
'socket_size': '13',
'sync_session_ttl': 'enable',
'traffic_submit': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_ips_global.fortios_ips(input_data, fos_instance)
expected_data = {
'anomaly-mode': 'periodical',
'database': 'regular',
'deep-app-insp-db-limit': '5',
'deep-app-insp-timeout': '6',
'engine-count': '7',
'exclude-signatures': 'none',
'fail-open': 'enable',
'intelligent-mode': 'enable',
'session-limit-mode': 'accurate',
'skype-client-public-ipaddr': 'test_value_12',
'socket-size': '13',
'sync-session-ttl': 'enable',
'traffic-submit': 'enable'
}
set_method_mock.assert_called_with('ips', '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_ips_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',
'ips_global': {
'random_attribute_not_valid': 'tag',
'anomaly_mode': 'periodical',
'database': 'regular',
'deep_app_insp_db_limit': '5',
'deep_app_insp_timeout': '6',
'engine_count': '7',
'exclude_signatures': 'none',
'fail_open': 'enable',
'intelligent_mode': 'enable',
'session_limit_mode': 'accurate',
'skype_client_public_ipaddr': 'test_value_12',
'socket_size': '13',
'sync_session_ttl': 'enable',
'traffic_submit': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_ips_global.fortios_ips(input_data, fos_instance)
expected_data = {
'anomaly-mode': 'periodical',
'database': 'regular',
'deep-app-insp-db-limit': '5',
'deep-app-insp-timeout': '6',
'engine-count': '7',
'exclude-signatures': 'none',
'fail-open': 'enable',
'intelligent-mode': 'enable',
'session-limit-mode': 'accurate',
'skype-client-public-ipaddr': 'test_value_12',
'socket-size': '13',
'sync-session-ttl': 'enable',
'traffic-submit': 'enable'
}
set_method_mock.assert_called_with('ips', '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,329 @@
# 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_ips_rule
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_ips_rule.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_ips_rule_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',
'ips_rule': {
'action': 'pass',
'application': 'test_value_4',
'date': '5',
'group': 'test_value_6',
'location': 'test_value_7,',
'log': 'disable',
'log_packet': 'disable',
'name': 'default_name_10',
'os': 'test_value_11',
'rev': '12',
'rule_id': '13',
'service': 'test_value_14',
'severity': 'test_value_15,',
'status': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_ips_rule.fortios_ips(input_data, fos_instance)
expected_data = {
'action': 'pass',
'application': 'test_value_4',
'date': '5',
'group': 'test_value_6',
'location': 'test_value_7,',
'log': 'disable',
'log-packet': 'disable',
'name': 'default_name_10',
'os': 'test_value_11',
'rev': '12',
'rule-id': '13',
'service': 'test_value_14',
'severity': 'test_value_15,',
'status': 'disable'
}
set_method_mock.assert_called_with('ips', 'rule', 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_ips_rule_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',
'ips_rule': {
'action': 'pass',
'application': 'test_value_4',
'date': '5',
'group': 'test_value_6',
'location': 'test_value_7,',
'log': 'disable',
'log_packet': 'disable',
'name': 'default_name_10',
'os': 'test_value_11',
'rev': '12',
'rule_id': '13',
'service': 'test_value_14',
'severity': 'test_value_15,',
'status': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_ips_rule.fortios_ips(input_data, fos_instance)
expected_data = {
'action': 'pass',
'application': 'test_value_4',
'date': '5',
'group': 'test_value_6',
'location': 'test_value_7,',
'log': 'disable',
'log-packet': 'disable',
'name': 'default_name_10',
'os': 'test_value_11',
'rev': '12',
'rule-id': '13',
'service': 'test_value_14',
'severity': 'test_value_15,',
'status': 'disable'
}
set_method_mock.assert_called_with('ips', 'rule', 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_ips_rule_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',
'ips_rule': {
'action': 'pass',
'application': 'test_value_4',
'date': '5',
'group': 'test_value_6',
'location': 'test_value_7,',
'log': 'disable',
'log_packet': 'disable',
'name': 'default_name_10',
'os': 'test_value_11',
'rev': '12',
'rule_id': '13',
'service': 'test_value_14',
'severity': 'test_value_15,',
'status': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_ips_rule.fortios_ips(input_data, fos_instance)
delete_method_mock.assert_called_with('ips', 'rule', 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_ips_rule_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',
'ips_rule': {
'action': 'pass',
'application': 'test_value_4',
'date': '5',
'group': 'test_value_6',
'location': 'test_value_7,',
'log': 'disable',
'log_packet': 'disable',
'name': 'default_name_10',
'os': 'test_value_11',
'rev': '12',
'rule_id': '13',
'service': 'test_value_14',
'severity': 'test_value_15,',
'status': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_ips_rule.fortios_ips(input_data, fos_instance)
delete_method_mock.assert_called_with('ips', 'rule', 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_ips_rule_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',
'ips_rule': {
'action': 'pass',
'application': 'test_value_4',
'date': '5',
'group': 'test_value_6',
'location': 'test_value_7,',
'log': 'disable',
'log_packet': 'disable',
'name': 'default_name_10',
'os': 'test_value_11',
'rev': '12',
'rule_id': '13',
'service': 'test_value_14',
'severity': 'test_value_15,',
'status': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_ips_rule.fortios_ips(input_data, fos_instance)
expected_data = {
'action': 'pass',
'application': 'test_value_4',
'date': '5',
'group': 'test_value_6',
'location': 'test_value_7,',
'log': 'disable',
'log-packet': 'disable',
'name': 'default_name_10',
'os': 'test_value_11',
'rev': '12',
'rule-id': '13',
'service': 'test_value_14',
'severity': 'test_value_15,',
'status': 'disable'
}
set_method_mock.assert_called_with('ips', 'rule', 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_ips_rule_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',
'ips_rule': {
'random_attribute_not_valid': 'tag',
'action': 'pass',
'application': 'test_value_4',
'date': '5',
'group': 'test_value_6',
'location': 'test_value_7,',
'log': 'disable',
'log_packet': 'disable',
'name': 'default_name_10',
'os': 'test_value_11',
'rev': '12',
'rule_id': '13',
'service': 'test_value_14',
'severity': 'test_value_15,',
'status': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_ips_rule.fortios_ips(input_data, fos_instance)
expected_data = {
'action': 'pass',
'application': 'test_value_4',
'date': '5',
'group': 'test_value_6',
'location': 'test_value_7,',
'log': 'disable',
'log-packet': 'disable',
'name': 'default_name_10',
'os': 'test_value_11',
'rev': '12',
'rule-id': '13',
'service': 'test_value_14',
'severity': 'test_value_15,',
'status': 'disable'
}
set_method_mock.assert_called_with('ips', 'rule', 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,199 @@
# 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_ips_rule_settings
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_ips_rule_settings.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_ips_rule_settings_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',
'ips_rule_settings': {
'id': '3'
},
'vdom': 'root'}
is_error, changed, response = fortios_ips_rule_settings.fortios_ips(input_data, fos_instance)
expected_data = {
'id': '3'
}
set_method_mock.assert_called_with('ips', 'rule-settings', 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_ips_rule_settings_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',
'ips_rule_settings': {
'id': '3'
},
'vdom': 'root'}
is_error, changed, response = fortios_ips_rule_settings.fortios_ips(input_data, fos_instance)
expected_data = {
'id': '3'
}
set_method_mock.assert_called_with('ips', 'rule-settings', 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_ips_rule_settings_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',
'ips_rule_settings': {
'id': '3'
},
'vdom': 'root'}
is_error, changed, response = fortios_ips_rule_settings.fortios_ips(input_data, fos_instance)
delete_method_mock.assert_called_with('ips', 'rule-settings', 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_ips_rule_settings_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',
'ips_rule_settings': {
'id': '3'
},
'vdom': 'root'}
is_error, changed, response = fortios_ips_rule_settings.fortios_ips(input_data, fos_instance)
delete_method_mock.assert_called_with('ips', 'rule-settings', 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_ips_rule_settings_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',
'ips_rule_settings': {
'id': '3'
},
'vdom': 'root'}
is_error, changed, response = fortios_ips_rule_settings.fortios_ips(input_data, fos_instance)
expected_data = {
'id': '3'
}
set_method_mock.assert_called_with('ips', 'rule-settings', 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_ips_rule_settings_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',
'ips_rule_settings': {
'random_attribute_not_valid': 'tag',
'id': '3'
},
'vdom': 'root'}
is_error, changed, response = fortios_ips_rule_settings.fortios_ips(input_data, fos_instance)
expected_data = {
'id': '3'
}
set_method_mock.assert_called_with('ips', 'rule-settings', 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