FortiOS modules for 2.9 - 3 (#60678)

* FortiOS modules for 2.9 - 3

* Remove default values in doc, as suggested from review

* Retriggering due to shippable failure

* Update fortios_firewall_ipv6_eh_filter.py

* Update fortios_firewall_ipmacbinding_setting.py

* Update fortios_firewall_ippool.py

* Update fortios_firewall_local_in_policy6.py

* Update fortios_firewall_local_in_policy.py
pull/60806/head
Miguel Angel Muñoz González 5 years ago committed by Nilashish Chakraborty
parent d8f9904f43
commit decb016a2d

@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_internet_service_group module: fortios_firewall_internet_service_group
short_description: Configure group of Internet Service in Fortinet's FortiOS and FortiGate. short_description: Configure group of Internet Service in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by - This module is able to configure a FortiGate or FortiOS device by allowing the
allowing the user to configure firewall feature and internet_service_group category. user to set and modify firewall feature and internet_service_group category.
Examples includes all options and need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,55 +41,71 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol
type: bool type: bool
default: false default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
choices:
- present
- absent
version_added: 2.9
firewall_internet_service_group: firewall_internet_service_group:
description: description:
- Configure group of Internet Service. - Configure group of Internet Service.
default: null default: null
type: dict
suboptions: suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
comment: comment:
description: description:
- Comment. - Comment.
type: str
member: member:
description: description:
- Internet Service group member. - Internet Service group member.
type: list
suboptions: suboptions:
id: id:
description: description:
- Internet Service ID. Source firewall.internet-service.id. - Internet Service ID. Source firewall.internet-service.id.
required: true required: true
type: int
name: name:
description: description:
- Internet Service group name. - Internet Service group name.
required: true required: true
type: str
''' '''
EXAMPLES = ''' EXAMPLES = '''
@ -102,6 +115,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Configure group of Internet Service. - name: Configure group of Internet Service.
fortios_firewall_internet_service_group: fortios_firewall_internet_service_group:
@ -109,8 +123,9 @@ EXAMPLES = '''
username: "{{ username }}" username: "{{ username }}"
password: "{{ password }}" password: "{{ password }}"
vdom: "{{ vdom }}" vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_internet_service_group: firewall_internet_service_group:
state: "present"
comment: "Comment." comment: "Comment."
member: member:
- -
@ -178,14 +193,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
fos = None 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'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -193,7 +210,7 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_internet_service_group_data(json): def filter_firewall_internet_service_group_data(json):
@ -207,48 +224,66 @@ def filter_firewall_internet_service_group_data(json):
return dictionary 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_internet_service_group(data, fos): def firewall_internet_service_group(data, fos):
vdom = data['vdom'] vdom = data['vdom']
state = data['state']
firewall_internet_service_group_data = data['firewall_internet_service_group'] firewall_internet_service_group_data = data['firewall_internet_service_group']
filtered_data = filter_firewall_internet_service_group_data(firewall_internet_service_group_data) filtered_data = underscore_to_hyphen(filter_firewall_internet_service_group_data(firewall_internet_service_group_data))
if firewall_internet_service_group_data['state'] == "present":
if state == "present":
return fos.set('firewall', return fos.set('firewall',
'internet-service-group', 'internet-service-group',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
elif firewall_internet_service_group_data['state'] == "absent": elif state == "absent":
return fos.delete('firewall', return fos.delete('firewall',
'internet-service-group', 'internet-service-group',
mkey=filtered_data['name'], mkey=filtered_data['name'],
vdom=vdom) 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): def fortios_firewall(data, fos):
login(data)
methodlist = ['firewall_internet_service_group'] if data['firewall_internet_service_group']:
for method in methodlist: resp = firewall_internet_service_group(data, fos)
if data[method]:
resp = eval(method)(data, fos)
break
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "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_internet_service_group": { "firewall_internet_service_group": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"comment": {"required": False, "type": "str"}, "comment": {"required": False, "type": "str"},
"member": {"required": False, "type": "list", "member": {"required": False, "type": "list",
"options": { "options": {
@ -262,15 +297,30 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos legacy_mode = 'host' in module.params and module.params['host'] is not None and \
fos = FortiOSAPI() '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: if not is_error:
module.exit_json(changed=has_changed, meta=result) 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_ip_translation module: fortios_firewall_ip_translation
short_description: Configure firewall IP-translation in Fortinet's FortiOS and FortiGate. short_description: Configure firewall IP-translation in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by - This module is able to configure a FortiGate or FortiOS device by allowing the
allowing the user to configure firewall feature and ip_translation category. user to set and modify firewall feature and ip_translation category.
Examples includes all options and need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,56 +41,73 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol
type: bool type: bool
default: false default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
choices:
- present
- absent
version_added: 2.9
firewall_ip_translation: firewall_ip_translation:
description: description:
- Configure firewall IP-translation. - Configure firewall IP-translation.
default: null default: null
type: dict
suboptions: suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
endip: endip:
description: description:
- "Final IPv4 address (inclusive) in the range of the addresses to be translated (format xxx.xxx.xxx.xxx, default: 0.0.0.0)." - "Final IPv4 address (inclusive) in the range of the addresses to be translated (format xxx.xxx.xxx.xxx, default: 0.0.0.0)."
map-startip: type: str
map_startip:
description: description:
- "Address to be used as the starting point for translation in the range (format xxx.xxx.xxx.xxx, default: 0.0.0.0)." - "Address to be used as the starting point for translation in the range (format xxx.xxx.xxx.xxx, default: 0.0.0.0)."
type: str
startip: startip:
description: description:
- "First IPv4 address (inclusive) in the range of the addresses to be translated (format xxx.xxx.xxx.xxx, default: 0.0.0.0)." - "First IPv4 address (inclusive) in the range of the addresses to be translated (format xxx.xxx.xxx.xxx, default: 0.0.0.0)."
type: str
transid: transid:
description: description:
- IP translation ID. - IP translation ID.
required: true required: true
type: int
type: type:
description: description:
- "IP translation type (option: SCTP)." - "IP translation type (option: SCTP)."
type: str
choices: choices:
- SCTP - SCTP
''' '''
@ -105,6 +119,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Configure firewall IP-translation. - name: Configure firewall IP-translation.
fortios_firewall_ip_translation: fortios_firewall_ip_translation:
@ -112,10 +127,11 @@ EXAMPLES = '''
username: "{{ username }}" username: "{{ username }}"
password: "{{ password }}" password: "{{ password }}"
vdom: "{{ vdom }}" vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_ip_translation: firewall_ip_translation:
state: "present"
endip: "<your_own_value>" endip: "<your_own_value>"
map-startip: "<your_own_value>" map_startip: "<your_own_value>"
startip: "<your_own_value>" startip: "<your_own_value>"
transid: "6" transid: "6"
type: "SCTP" type: "SCTP"
@ -181,14 +197,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule 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, fos):
def login(data):
host = data['host'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -196,11 +214,11 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_ip_translation_data(json): def filter_firewall_ip_translation_data(json):
option_list = ['endip', 'map-startip', 'startip', option_list = ['endip', 'map_startip', 'startip',
'transid', 'type'] 'transid', 'type']
dictionary = {} dictionary = {}
@ -211,50 +229,68 @@ def filter_firewall_ip_translation_data(json):
return dictionary 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_ip_translation(data, fos): def firewall_ip_translation(data, fos):
vdom = data['vdom'] vdom = data['vdom']
state = data['state']
firewall_ip_translation_data = data['firewall_ip_translation'] firewall_ip_translation_data = data['firewall_ip_translation']
filtered_data = filter_firewall_ip_translation_data(firewall_ip_translation_data) filtered_data = underscore_to_hyphen(filter_firewall_ip_translation_data(firewall_ip_translation_data))
if firewall_ip_translation_data['state'] == "present":
if state == "present":
return fos.set('firewall', return fos.set('firewall',
'ip-translation', 'ip-translation',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
elif firewall_ip_translation_data['state'] == "absent": elif state == "absent":
return fos.delete('firewall', return fos.delete('firewall',
'ip-translation', 'ip-translation',
mkey=filtered_data['transid'], mkey=filtered_data['transid'],
vdom=vdom) 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): def fortios_firewall(data, fos):
login(data)
methodlist = ['firewall_ip_translation'] if data['firewall_ip_translation']:
for method in methodlist: resp = firewall_ip_translation(data, fos)
if data[method]:
resp = eval(method)(data, fos)
break
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "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_ip_translation": { "firewall_ip_translation": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"endip": {"required": False, "type": "str"}, "endip": {"required": False, "type": "str"},
"map-startip": {"required": False, "type": "str"}, "map_startip": {"required": False, "type": "str"},
"startip": {"required": False, "type": "str"}, "startip": {"required": False, "type": "str"},
"transid": {"required": True, "type": "int"}, "transid": {"required": True, "type": "int"},
"type": {"required": False, "type": "str", "type": {"required": False, "type": "str",
@ -266,15 +302,30 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos legacy_mode = 'host' in module.params and module.params['host'] is not None and \
fos = FortiOSAPI() '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: if not is_error:
module.exit_json(changed=has_changed, meta=result) 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_ipmacbinding_setting module: fortios_firewall_ipmacbinding_setting
short_description: Configure IP to MAC binding settings in Fortinet's FortiOS and FortiGate. short_description: Configure IP to MAC binding settings in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by - This module is able to configure a FortiGate or FortiOS device by allowing the
allowing the user to configure firewall_ipmacbinding feature and setting category. user to set and modify firewall_ipmacbinding feature and setting category.
Examples includes all options and need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,49 +41,62 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool type: bool
default: false default: true
version_added: 2.9
firewall_ipmacbinding_setting: firewall_ipmacbinding_setting:
description: description:
- Configure IP to MAC binding settings. - Configure IP to MAC binding settings.
default: null default: null
type: dict
suboptions: suboptions:
bindthroughfw: bindthroughfw:
description: description:
- Enable/disable use of IP/MAC binding to filter packets that would normally go through the firewall. - Enable/disable use of IP/MAC binding to filter packets that would normally go through the firewall.
type: str
choices: choices:
- enable - enable
- disable - disable
bindtofw: bindtofw:
description: description:
- Enable/disable use of IP/MAC binding to filter packets that would normally go to the firewall. - Enable/disable use of IP/MAC binding to filter packets that would normally go to the firewall.
type: str
choices: choices:
- enable - enable
- disable - disable
undefinedhost: undefinedhost:
description: description:
- Select action to take on packets with IP/MAC addresses not in the binding list (default = block). - Select action to take on packets with IP/MAC addresses not in the binding list.
type: str
choices: choices:
- allow - allow
- block - block
@ -99,6 +109,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Configure IP to MAC binding settings. - name: Configure IP to MAC binding settings.
fortios_firewall_ipmacbinding_setting: fortios_firewall_ipmacbinding_setting:
@ -106,6 +117,7 @@ EXAMPLES = '''
username: "{{ username }}" username: "{{ username }}"
password: "{{ password }}" password: "{{ password }}"
vdom: "{{ vdom }}" vdom: "{{ vdom }}"
https: "False"
firewall_ipmacbinding_setting: firewall_ipmacbinding_setting:
bindthroughfw: "enable" bindthroughfw: "enable"
bindtofw: "enable" bindtofw: "enable"
@ -172,14 +184,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule 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, fos):
def login(data):
host = data['host'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -187,7 +201,7 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_ipmacbinding_setting_data(json): def filter_firewall_ipmacbinding_setting_data(json):
@ -201,38 +215,55 @@ def filter_firewall_ipmacbinding_setting_data(json):
return dictionary 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_ipmacbinding_setting(data, fos): def firewall_ipmacbinding_setting(data, fos):
vdom = data['vdom'] vdom = data['vdom']
firewall_ipmacbinding_setting_data = data['firewall_ipmacbinding_setting'] firewall_ipmacbinding_setting_data = data['firewall_ipmacbinding_setting']
filtered_data = filter_firewall_ipmacbinding_setting_data(firewall_ipmacbinding_setting_data) filtered_data = underscore_to_hyphen(filter_firewall_ipmacbinding_setting_data(firewall_ipmacbinding_setting_data))
return fos.set('firewall.ipmacbinding', return fos.set('firewall.ipmacbinding',
'setting', 'setting',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall_ipmacbinding(data, fos): def fortios_firewall_ipmacbinding(data, fos):
login(data)
methodlist = ['firewall_ipmacbinding_setting'] if data['firewall_ipmacbinding_setting']:
for method in methodlist: resp = firewall_ipmacbinding_setting(data, fos)
if data[method]:
resp = eval(method)(data, fos)
break
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "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},
"firewall_ipmacbinding_setting": { "firewall_ipmacbinding_setting": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"bindthroughfw": {"required": False, "type": "str", "bindthroughfw": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
@ -247,15 +278,30 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos legacy_mode = 'host' in module.params and module.params['host'] is not None and \
fos = FortiOSAPI() '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_ipmacbinding(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_ipmacbinding(module.params, fos) login(module.params, fos)
is_error, has_changed, result = fortios_firewall_ipmacbinding(module.params, fos)
fos.logout()
if not is_error: if not is_error:
module.exit_json(changed=has_changed, meta=result) 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_ipmacbinding_table module: fortios_firewall_ipmacbinding_table
short_description: Configure IP to MAC address pairs in the IP/MAC binding table in Fortinet's FortiOS and FortiGate. short_description: Configure IP to MAC address pairs in the IP/MAC binding table in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by - This module is able to configure a FortiGate or FortiOS device by allowing the
allowing the user to configure firewall_ipmacbinding feature and table category. user to set and modify firewall_ipmacbinding feature and table category.
Examples includes all options and need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,56 +41,72 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol
type: bool type: bool
default: false default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
choices:
- present
- absent
version_added: 2.9
firewall_ipmacbinding_table: firewall_ipmacbinding_table:
description: description:
- Configure IP to MAC address pairs in the IP/MAC binding table. - Configure IP to MAC address pairs in the IP/MAC binding table.
default: null default: null
type: dict
suboptions: suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
ip: ip:
description: description:
- "IPv4 address portion of the pair (format: xxx.xxx.xxx.xxx)." - "IPv4 address portion of the pair (format: xxx.xxx.xxx.xxx)."
type: str
mac: mac:
description: description:
- "MAC address portion of the pair (format: xx:xx:xx:xx:xx:xx in hexidecimal)." - "MAC address portion of the pair (format: xx:xx:xx:xx:xx:xx in hexidecimal)."
type: str
name: name:
description: description:
- Name of the pair (optional, default = no name). - Name of the pair (optional, default = no name).
seq-num: type: str
seq_num:
description: description:
- Entry number. - Entry number.
required: true type: int
status: status:
description: description:
- Enable/disable this IP-mac binding pair. - Enable/disable this IP-mac binding pair.
type: str
choices: choices:
- enable - enable
- disable - disable
@ -106,6 +119,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Configure IP to MAC address pairs in the IP/MAC binding table. - name: Configure IP to MAC address pairs in the IP/MAC binding table.
fortios_firewall_ipmacbinding_table: fortios_firewall_ipmacbinding_table:
@ -113,12 +127,13 @@ EXAMPLES = '''
username: "{{ username }}" username: "{{ username }}"
password: "{{ password }}" password: "{{ password }}"
vdom: "{{ vdom }}" vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_ipmacbinding_table: firewall_ipmacbinding_table:
state: "present"
ip: "<your_own_value>" ip: "<your_own_value>"
mac: "<your_own_value>" mac: "<your_own_value>"
name: "default_name_5" name: "default_name_5"
seq-num: "6" seq_num: "6"
status: "enable" status: "enable"
''' '''
@ -182,14 +197,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule 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, fos):
def login(data):
host = data['host'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -197,12 +214,12 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_ipmacbinding_table_data(json): def filter_firewall_ipmacbinding_table_data(json):
option_list = ['ip', 'mac', 'name', option_list = ['ip', 'mac', 'name',
'seq-num', 'status'] 'seq_num', 'status']
dictionary = {} dictionary = {}
for attribute in option_list: for attribute in option_list:
@ -212,52 +229,70 @@ def filter_firewall_ipmacbinding_table_data(json):
return dictionary 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_ipmacbinding_table(data, fos): def firewall_ipmacbinding_table(data, fos):
vdom = data['vdom'] vdom = data['vdom']
state = data['state']
firewall_ipmacbinding_table_data = data['firewall_ipmacbinding_table'] firewall_ipmacbinding_table_data = data['firewall_ipmacbinding_table']
filtered_data = filter_firewall_ipmacbinding_table_data(firewall_ipmacbinding_table_data) filtered_data = underscore_to_hyphen(filter_firewall_ipmacbinding_table_data(firewall_ipmacbinding_table_data))
if firewall_ipmacbinding_table_data['state'] == "present":
if state == "present":
return fos.set('firewall.ipmacbinding', return fos.set('firewall.ipmacbinding',
'table', 'table',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
elif firewall_ipmacbinding_table_data['state'] == "absent": elif state == "absent":
return fos.delete('firewall.ipmacbinding', return fos.delete('firewall.ipmacbinding',
'table', 'table',
mkey=filtered_data['seq-num'], mkey=filtered_data['seq-num'],
vdom=vdom) vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall_ipmacbinding(data, fos): def fortios_firewall_ipmacbinding(data, fos):
login(data)
methodlist = ['firewall_ipmacbinding_table'] if data['firewall_ipmacbinding_table']:
for method in methodlist: resp = firewall_ipmacbinding_table(data, fos)
if data[method]:
resp = eval(method)(data, fos)
break
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "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_ipmacbinding_table": { "firewall_ipmacbinding_table": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"ip": {"required": False, "type": "str"}, "ip": {"required": False, "type": "str"},
"mac": {"required": False, "type": "str"}, "mac": {"required": False, "type": "str"},
"name": {"required": False, "type": "str"}, "name": {"required": False, "type": "str"},
"seq-num": {"required": True, "type": "int"}, "seq_num": {"required": False, "type": "int"},
"status": {"required": False, "type": "str", "status": {"required": False, "type": "str",
"choices": ["enable", "disable"]} "choices": ["enable", "disable"]}
@ -267,15 +302,30 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos legacy_mode = 'host' in module.params and module.params['host'] is not None and \
fos = FortiOSAPI() '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_ipmacbinding(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_ipmacbinding(module.params, fos) login(module.params, fos)
is_error, has_changed, result = fortios_firewall_ipmacbinding(module.params, fos)
fos.logout()
if not is_error: if not is_error:
module.exit_json(changed=has_changed, meta=result) module.exit_json(changed=has_changed, meta=result)

@ -1,6 +1,6 @@
#!/usr/bin/python #!/usr/bin/python
from __future__ import (absolute_import, division, print_function) 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 # 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 # 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_ippool module: fortios_firewall_ippool
short_description: Configure IPv4 IP pools in Fortinet's FortiOS and FortiGate. short_description: Configure IPv4 IP pools in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by - This module is able to configure a FortiGate or FortiOS device by allowing the
allowing the user to configure firewall feature and ippool category. user to set and modify firewall feature and ippool category.
Examples includes all options and need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,89 +41,115 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol
type: bool type: bool
default: false default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
choices:
- present
- absent
version_added: 2.9
firewall_ippool: firewall_ippool:
description: description:
- Configure IPv4 IP pools. - Configure IPv4 IP pools.
default: null default: null
type: dict
suboptions: suboptions:
state: arp_intf:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
arp-intf:
description: description:
- Select an interface from available options that will reply to ARP requests. (If blank, any is selected). Source system.interface.name. - Select an interface from available options that will reply to ARP requests. (If blank, any is selected). Source system.interface.name.
arp-reply: type: str
arp_reply:
description: description:
- Enable/disable replying to ARP requests when an IP Pool is added to a policy (default = enable). - Enable/disable replying to ARP requests when an IP Pool is added to a policy.
type: str
choices: choices:
- disable - disable
- enable - enable
associated-interface: associated_interface:
description: description:
- Associated interface name. Source system.interface.name. - Associated interface name. Source system.interface.name.
block-size: type: str
block_size:
description: description:
- Number of addresses in a block (64 to 4096, default = 128). - Number of addresses in a block (64 to 4096).
type: int
comments: comments:
description: description:
- Comment. - Comment.
type: str
endip: endip:
description: description:
- "Final IPv4 address (inclusive) in the range for the address pool (format xxx.xxx.xxx.xxx, Default: 0.0.0.0)." - "Final IPv4 address (inclusive) in the range for the address pool (format xxx.xxx.xxx.xxx)."
type: str
name: name:
description: description:
- IP pool name. - IP pool name.
required: true required: true
num-blocks-per-user: type: str
num_blocks_per_user:
description: description:
- Number of addresses blocks that can be used by a user (1 to 128, default = 8). - Number of addresses blocks that can be used by a user (1 to 128).
pba-timeout: type: int
pba_timeout:
description: description:
- Port block allocation timeout (seconds). - Port block allocation timeout (seconds).
permit-any-host: type: int
permit_any_host:
description: description:
- Enable/disable full cone NAT. - Enable/disable full cone NAT.
type: str
choices: choices:
- disable - disable
- enable - enable
source-endip: source_endip:
description: description:
- "Final IPv4 address (inclusive) in the range of the source addresses to be translated (format xxx.xxx.xxx.xxx, Default: 0.0.0.0)." - "Final IPv4 address (inclusive) in the range of the source addresses to be translated (format xxx.xxx.xxx.xxx)."
source-startip: type: str
source_startip:
description: description:
- " First IPv4 address (inclusive) in the range of the source addresses to be translated (format xxx.xxx.xxx.xxx, Default: 0.0.0.0)." - " First IPv4 address (inclusive) in the range of the source addresses to be translated (format xxx.xxx.xxx.xxx)."
type: str
startip: startip:
description: description:
- "First IPv4 address (inclusive) in the range for the address pool (format xxx.xxx.xxx.xxx, Default: 0.0.0.0)." - "First IPv4 address (inclusive) in the range for the address pool (format xxx.xxx.xxx.xxx)."
type: str
type: type:
description: description:
- IP pool type (overload, one-to-one, fixed port range, or port block allocation). - IP pool type (overload, one-to-one, fixed port range, or port block allocation).
type: str
choices: choices:
- overload - overload
- one-to-one - one-to-one
@ -141,6 +164,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Configure IPv4 IP pools. - name: Configure IPv4 IP pools.
fortios_firewall_ippool: fortios_firewall_ippool:
@ -148,20 +172,21 @@ EXAMPLES = '''
username: "{{ username }}" username: "{{ username }}"
password: "{{ password }}" password: "{{ password }}"
vdom: "{{ vdom }}" vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_ippool: firewall_ippool:
state: "present" arp_intf: "<your_own_value> (source system.interface.name)"
arp-intf: "<your_own_value> (source system.interface.name)" arp_reply: "disable"
arp-reply: "disable" associated_interface: "<your_own_value> (source system.interface.name)"
associated-interface: "<your_own_value> (source system.interface.name)" block_size: "6"
block-size: "6"
comments: "<your_own_value>" comments: "<your_own_value>"
endip: "<your_own_value>" endip: "<your_own_value>"
name: "default_name_9" name: "default_name_9"
num-blocks-per-user: "10" num_blocks_per_user: "10"
pba-timeout: "11" pba_timeout: "11"
permit-any-host: "disable" permit_any_host: "disable"
source-endip: "<your_own_value>" source_endip: "<your_own_value>"
source-startip: "<your_own_value>" source_startip: "<your_own_value>"
startip: "<your_own_value>" startip: "<your_own_value>"
type: "overload" type: "overload"
''' '''
@ -186,7 +211,7 @@ mkey:
description: Master key (id) used in the last call to FortiGate description: Master key (id) used in the last call to FortiGate
returned: success returned: success
type: str type: str
sample: "key1" sample: "id"
name: name:
description: Name of the table used to fulfill the request description: Name of the table used to fulfill the request
returned: always returned: always
@ -226,14 +251,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule 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, fos):
def login(data):
host = data['host'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -241,14 +268,14 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_ippool_data(json): def filter_firewall_ippool_data(json):
option_list = ['arp-intf', 'arp-reply', 'associated-interface', option_list = ['arp_intf', 'arp_reply', 'associated_interface',
'block-size', 'comments', 'endip', 'block_size', 'comments', 'endip',
'name', 'num-blocks-per-user', 'pba-timeout', 'name', 'num_blocks_per_user', 'pba_timeout',
'permit-any-host', 'source-endip', 'source-startip', 'permit_any_host', 'source_endip', 'source_startip',
'startip', 'type'] 'startip', 'type']
dictionary = {} dictionary = {}
@ -259,62 +286,80 @@ def filter_firewall_ippool_data(json):
return dictionary 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_ippool(data, fos): def firewall_ippool(data, fos):
vdom = data['vdom'] vdom = data['vdom']
state = data['state']
firewall_ippool_data = data['firewall_ippool'] firewall_ippool_data = data['firewall_ippool']
filtered_data = filter_firewall_ippool_data(firewall_ippool_data) filtered_data = underscore_to_hyphen(filter_firewall_ippool_data(firewall_ippool_data))
if firewall_ippool_data['state'] == "present":
if state == "present":
return fos.set('firewall', return fos.set('firewall',
'ippool', 'ippool',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
elif firewall_ippool_data['state'] == "absent": elif state == "absent":
return fos.delete('firewall', return fos.delete('firewall',
'ippool', 'ippool',
mkey=filtered_data['name'], mkey=filtered_data['name'],
vdom=vdom) 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): def fortios_firewall(data, fos):
login(data)
methodlist = ['firewall_ippool'] if data['firewall_ippool']:
for method in methodlist: resp = firewall_ippool(data, fos)
if data[method]:
resp = eval(method)(data, fos)
break
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "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_ippool": { "firewall_ippool": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"state": {"required": True, "type": "str", "arp_intf": {"required": False, "type": "str"},
"choices": ["present", "absent"]}, "arp_reply": {"required": False, "type": "str",
"arp-intf": {"required": False, "type": "str"},
"arp-reply": {"required": False, "type": "str",
"choices": ["disable", "enable"]}, "choices": ["disable", "enable"]},
"associated-interface": {"required": False, "type": "str"}, "associated_interface": {"required": False, "type": "str"},
"block-size": {"required": False, "type": "int"}, "block_size": {"required": False, "type": "int"},
"comments": {"required": False, "type": "str"}, "comments": {"required": False, "type": "str"},
"endip": {"required": False, "type": "str"}, "endip": {"required": False, "type": "str"},
"name": {"required": True, "type": "str"}, "name": {"required": True, "type": "str"},
"num-blocks-per-user": {"required": False, "type": "int"}, "num_blocks_per_user": {"required": False, "type": "int"},
"pba-timeout": {"required": False, "type": "int"}, "pba_timeout": {"required": False, "type": "int"},
"permit-any-host": {"required": False, "type": "str", "permit_any_host": {"required": False, "type": "str",
"choices": ["disable", "enable"]}, "choices": ["disable", "enable"]},
"source-endip": {"required": False, "type": "str"}, "source_endip": {"required": False, "type": "str"},
"source-startip": {"required": False, "type": "str"}, "source_startip": {"required": False, "type": "str"},
"startip": {"required": False, "type": "str"}, "startip": {"required": False, "type": "str"},
"type": {"required": False, "type": "str", "type": {"required": False, "type": "str",
"choices": ["overload", "one-to-one", "fixed-port-range", "choices": ["overload", "one-to-one", "fixed-port-range",
@ -326,15 +371,30 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos legacy_mode = 'host' in module.params and module.params['host'] is not None and \
fos = FortiOSAPI() '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: if not is_error:
module.exit_json(changed=has_changed, meta=result) module.exit_json(changed=has_changed, meta=result)

@ -1,6 +1,6 @@
#!/usr/bin/python #!/usr/bin/python
from __future__ import (absolute_import, division, print_function) 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 # 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 # 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_ippool6 module: fortios_firewall_ippool6
short_description: Configure IPv6 IP pools in Fortinet's FortiOS and FortiGate. short_description: Configure IPv6 IP pools in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by - This module is able to configure a FortiGate or FortiOS device by allowing the
allowing the user to configure firewall feature and ippool6 category. user to set and modify firewall feature and ippool6 category.
Examples includes all options and need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,53 +41,69 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol
type: bool type: bool
default: false default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
choices:
- present
- absent
version_added: 2.9
firewall_ippool6: firewall_ippool6:
description: description:
- Configure IPv6 IP pools. - Configure IPv6 IP pools.
default: null default: null
type: dict
suboptions: suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
comments: comments:
description: description:
- Comment. - Comment.
type: str
endip: endip:
description: description:
- "Final IPv6 address (inclusive) in the range for the address pool (format xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx, Default: ::)." - "Final IPv6 address (inclusive) in the range for the address pool (format xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx, Default: ::)."
type: str
name: name:
description: description:
- IPv6 IP pool name. - IPv6 IP pool name.
required: true required: true
type: str
startip: startip:
description: description:
- "First IPv6 address (inclusive) in the range for the address pool (format xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx, Default: ::)." - "First IPv6 address (inclusive) in the range for the address pool (format xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx, Default: ::)."
type: str
''' '''
EXAMPLES = ''' EXAMPLES = '''
@ -100,6 +113,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Configure IPv6 IP pools. - name: Configure IPv6 IP pools.
fortios_firewall_ippool6: fortios_firewall_ippool6:
@ -107,9 +121,10 @@ EXAMPLES = '''
username: "{{ username }}" username: "{{ username }}"
password: "{{ password }}" password: "{{ password }}"
vdom: "{{ vdom }}" vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_ippool6: firewall_ippool6:
state: "present" comments: "<your_own_value>"
comments: "<your_own_comment>"
endip: "<your_own_value>" endip: "<your_own_value>"
name: "default_name_5" name: "default_name_5"
startip: "<your_own_value>" startip: "<your_own_value>"
@ -135,7 +150,7 @@ mkey:
description: Master key (id) used in the last call to FortiGate description: Master key (id) used in the last call to FortiGate
returned: success returned: success
type: str type: str
sample: "key1" sample: "id"
name: name:
description: Name of the table used to fulfill the request description: Name of the table used to fulfill the request
returned: always returned: always
@ -175,14 +190,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
fos = None 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'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -190,7 +207,7 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_ippool6_data(json): def filter_firewall_ippool6_data(json):
@ -205,48 +222,66 @@ def filter_firewall_ippool6_data(json):
return dictionary 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_ippool6(data, fos): def firewall_ippool6(data, fos):
vdom = data['vdom'] vdom = data['vdom']
state = data['state']
firewall_ippool6_data = data['firewall_ippool6'] firewall_ippool6_data = data['firewall_ippool6']
filtered_data = filter_firewall_ippool6_data(firewall_ippool6_data) filtered_data = underscore_to_hyphen(filter_firewall_ippool6_data(firewall_ippool6_data))
if firewall_ippool6_data['state'] == "present":
if state == "present":
return fos.set('firewall', return fos.set('firewall',
'ippool6', 'ippool6',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
elif firewall_ippool6_data['state'] == "absent": elif state == "absent":
return fos.delete('firewall', return fos.delete('firewall',
'ippool6', 'ippool6',
mkey=filtered_data['name'], mkey=filtered_data['name'],
vdom=vdom) 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): def fortios_firewall(data, fos):
login(data)
methodlist = ['firewall_ippool6'] if data['firewall_ippool6']:
for method in methodlist: resp = firewall_ippool6(data, fos)
if data[method]:
resp = eval(method)(data, fos)
break
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "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_ippool6": { "firewall_ippool6": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"comments": {"required": False, "type": "str"}, "comments": {"required": False, "type": "str"},
"endip": {"required": False, "type": "str"}, "endip": {"required": False, "type": "str"},
"name": {"required": True, "type": "str"}, "name": {"required": True, "type": "str"},
@ -258,15 +293,30 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos legacy_mode = 'host' in module.params and module.params['host'] is not None and \
fos = FortiOSAPI() '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: if not is_error:
module.exit_json(changed=has_changed, meta=result) 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_ipv6_eh_filter module: fortios_firewall_ipv6_eh_filter
short_description: Configure IPv6 extension header filter in Fortinet's FortiOS and FortiGate. short_description: Configure IPv6 extension header filter in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by - This module is able to configure a FortiGate or FortiOS device by allowing the
allowing the user to configure firewall feature and ipv6_eh_filter category. user to set and modify firewall feature and ipv6_eh_filter category.
Examples includes all options and need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,76 +41,94 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool type: bool
default: false default: true
version_added: 2.9
firewall_ipv6_eh_filter: firewall_ipv6_eh_filter:
description: description:
- Configure IPv6 extension header filter. - Configure IPv6 extension header filter.
default: null default: null
type: dict
suboptions: suboptions:
auth: auth:
description: description:
- Enable/disable blocking packets with the Authentication header (default = disable). - Enable/disable blocking packets with the Authentication header.
type: str
choices: choices:
- enable - enable
- disable - disable
dest-opt: dest_opt:
description: description:
- Enable/disable blocking packets with Destination Options headers (default = disable). - Enable/disable blocking packets with Destination Options headers.
type: str
choices: choices:
- enable - enable
- disable - disable
fragment: fragment:
description: description:
- Enable/disable blocking packets with the Fragment header (default = disable). - Enable/disable blocking packets with the Fragment header.
type: str
choices: choices:
- enable - enable
- disable - disable
hdopt-type: hdopt_type:
description: description:
- Block specific Hop-by-Hop and/or Destination Option types (max. 7 types, each between 0 and 255, default = 0). - Block specific Hop-by-Hop and/or Destination Option types (max. 7 types, each between 0 and 255).
hop-opt: type: int
hop_opt:
description: description:
- Enable/disable blocking packets with the Hop-by-Hop Options header (default = disable). - Enable/disable blocking packets with the Hop-by-Hop Options header.
type: str
choices: choices:
- enable - enable
- disable - disable
no-next: no_next:
description: description:
- Enable/disable blocking packets with the No Next header (default = disable) - Enable/disable blocking packets with the No Next header.
type: str
choices: choices:
- enable - enable
- disable - disable
routing: routing:
description: description:
- Enable/disable blocking packets with Routing headers (default = enable). - Enable/disable blocking packets with Routing headers.
type: str
choices: choices:
- enable - enable
- disable - disable
routing-type: routing_type:
description: description:
- Block specific Routing header types (max. 7 types, each between 0 and 255, default = 0). - Block specific Routing header types (max. 7 types, each between 0 and 255).
type: int
''' '''
EXAMPLES = ''' EXAMPLES = '''
@ -123,6 +138,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Configure IPv6 extension header filter. - name: Configure IPv6 extension header filter.
fortios_firewall_ipv6_eh_filter: fortios_firewall_ipv6_eh_filter:
@ -130,15 +146,16 @@ EXAMPLES = '''
username: "{{ username }}" username: "{{ username }}"
password: "{{ password }}" password: "{{ password }}"
vdom: "{{ vdom }}" vdom: "{{ vdom }}"
https: "False"
firewall_ipv6_eh_filter: firewall_ipv6_eh_filter:
auth: "enable" auth: "enable"
dest-opt: "enable" dest_opt: "enable"
fragment: "enable" fragment: "enable"
hdopt-type: "6" hdopt_type: "6"
hop-opt: "enable" hop_opt: "enable"
no-next: "enable" no_next: "enable"
routing: "enable" routing: "enable"
routing-type: "10" routing_type: "10"
''' '''
RETURN = ''' RETURN = '''
@ -201,14 +218,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule 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, fos):
def login(data):
host = data['host'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -216,13 +235,13 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_ipv6_eh_filter_data(json): def filter_firewall_ipv6_eh_filter_data(json):
option_list = ['auth', 'dest-opt', 'fragment', option_list = ['auth', 'dest_opt', 'fragment',
'hdopt-type', 'hop-opt', 'no-next', 'hdopt_type', 'hop_opt', 'no_next',
'routing', 'routing-type'] 'routing', 'routing_type']
dictionary = {} dictionary = {}
for attribute in option_list: for attribute in option_list:
@ -232,53 +251,70 @@ def filter_firewall_ipv6_eh_filter_data(json):
return dictionary 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_ipv6_eh_filter(data, fos): def firewall_ipv6_eh_filter(data, fos):
vdom = data['vdom'] vdom = data['vdom']
firewall_ipv6_eh_filter_data = data['firewall_ipv6_eh_filter'] firewall_ipv6_eh_filter_data = data['firewall_ipv6_eh_filter']
filtered_data = filter_firewall_ipv6_eh_filter_data(firewall_ipv6_eh_filter_data) filtered_data = underscore_to_hyphen(filter_firewall_ipv6_eh_filter_data(firewall_ipv6_eh_filter_data))
return fos.set('firewall', return fos.set('firewall',
'ipv6-eh-filter', 'ipv6-eh-filter',
data=filtered_data, data=filtered_data,
vdom=vdom) 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): def fortios_firewall(data, fos):
login(data)
methodlist = ['firewall_ipv6_eh_filter'] if data['firewall_ipv6_eh_filter']:
for method in methodlist: resp = firewall_ipv6_eh_filter(data, fos)
if data[method]:
resp = eval(method)(data, fos)
break
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "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},
"firewall_ipv6_eh_filter": { "firewall_ipv6_eh_filter": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"auth": {"required": False, "type": "str", "auth": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"dest-opt": {"required": False, "type": "str", "dest_opt": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"fragment": {"required": False, "type": "str", "fragment": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"hdopt-type": {"required": False, "type": "int"}, "hdopt_type": {"required": False, "type": "int"},
"hop-opt": {"required": False, "type": "str", "hop_opt": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"no-next": {"required": False, "type": "str", "no_next": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"routing": {"required": False, "type": "str", "routing": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"routing-type": {"required": False, "type": "int"} "routing_type": {"required": False, "type": "int"}
} }
} }
@ -286,15 +322,30 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos legacy_mode = 'host' in module.params and module.params['host'] is not None and \
fos = FortiOSAPI() '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: if not is_error:
module.exit_json(changed=has_changed, meta=result) 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_ldb_monitor module: fortios_firewall_ldb_monitor
short_description: Configure server load balancing health monitors in Fortinet's FortiOS and FortiGate. short_description: Configure server load balancing health monitors in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by - This module is able to configure a FortiGate or FortiOS device by allowing the
allowing the user to configure firewall feature and ldb_monitor category. user to set and modify firewall feature and ldb_monitor category.
Examples includes all options and need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,70 +41,91 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol
type: bool type: bool
default: false default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
choices:
- present
- absent
version_added: 2.9
firewall_ldb_monitor: firewall_ldb_monitor:
description: description:
- Configure server load balancing health monitors. - Configure server load balancing health monitors.
default: null default: null
type: dict
suboptions: suboptions:
state: http_get:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
http-get:
description: description:
- URL used to send a GET request to check the health of an HTTP server. - URL used to send a GET request to check the health of an HTTP server.
http-match: type: str
http_match:
description: description:
- String to match the value expected in response to an HTTP-GET request. - String to match the value expected in response to an HTTP-GET request.
http-max-redirects: type: str
http_max_redirects:
description: description:
- The maximum number of HTTP redirects to be allowed (0 - 5, default = 0). - The maximum number of HTTP redirects to be allowed (0 - 5, default = 0).
type: int
interval: interval:
description: description:
- Time between health checks (5 - 65635 sec, default = 10). - Time between health checks (5 - 65635 sec, default = 10).
type: int
name: name:
description: description:
- Monitor name. - Monitor name.
required: true required: true
type: str
port: port:
description: description:
- Service port used to perform the health check. If 0, health check monitor inherits port configured for the server (0 - 65635, default = - Service port used to perform the health check. If 0, health check monitor inherits port configured for the server (0 - 65635, default =
0). 0).
type: int
retry: retry:
description: description:
- Number health check attempts before the server is considered down (1 - 255, default = 3). - Number health check attempts before the server is considered down (1 - 255, default = 3).
type: int
timeout: timeout:
description: description:
- Time to wait to receive response to a health check from a server. Reaching the timeout means the health check failed (1 - 255 sec, - Time to wait to receive response to a health check from a server. Reaching the timeout means the health check failed (1 - 255 sec,
default = 2). default = 2).
type: int
type: type:
description: description:
- Select the Monitor type used by the health check monitor to check the health of the server (PING | TCP | HTTP). - Select the Monitor type used by the health check monitor to check the health of the server (PING | TCP | HTTP).
type: str
choices: choices:
- ping - ping
- tcp - tcp
@ -122,6 +140,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Configure server load balancing health monitors. - name: Configure server load balancing health monitors.
fortios_firewall_ldb_monitor: fortios_firewall_ldb_monitor:
@ -129,11 +148,12 @@ EXAMPLES = '''
username: "{{ username }}" username: "{{ username }}"
password: "{{ password }}" password: "{{ password }}"
vdom: "{{ vdom }}" vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_ldb_monitor: firewall_ldb_monitor:
state: "present" http_get: "<your_own_value>"
http-get: "<your_own_value>" http_match: "<your_own_value>"
http-match: "<your_own_value>" http_max_redirects: "5"
http-max-redirects: "5"
interval: "6" interval: "6"
name: "default_name_7" name: "default_name_7"
port: "8" port: "8"
@ -202,14 +222,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule 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, fos):
def login(data):
host = data['host'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -217,11 +239,11 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_ldb_monitor_data(json): def filter_firewall_ldb_monitor_data(json):
option_list = ['http-get', 'http-match', 'http-max-redirects', option_list = ['http_get', 'http_match', 'http_max_redirects',
'interval', 'name', 'port', 'interval', 'name', 'port',
'retry', 'timeout', 'type'] 'retry', 'timeout', 'type']
dictionary = {} dictionary = {}
@ -233,51 +255,69 @@ def filter_firewall_ldb_monitor_data(json):
return dictionary 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_ldb_monitor(data, fos): def firewall_ldb_monitor(data, fos):
vdom = data['vdom'] vdom = data['vdom']
state = data['state']
firewall_ldb_monitor_data = data['firewall_ldb_monitor'] firewall_ldb_monitor_data = data['firewall_ldb_monitor']
filtered_data = filter_firewall_ldb_monitor_data(firewall_ldb_monitor_data) filtered_data = underscore_to_hyphen(filter_firewall_ldb_monitor_data(firewall_ldb_monitor_data))
if firewall_ldb_monitor_data['state'] == "present":
if state == "present":
return fos.set('firewall', return fos.set('firewall',
'ldb-monitor', 'ldb-monitor',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
elif firewall_ldb_monitor_data['state'] == "absent": elif state == "absent":
return fos.delete('firewall', return fos.delete('firewall',
'ldb-monitor', 'ldb-monitor',
mkey=filtered_data['name'], mkey=filtered_data['name'],
vdom=vdom) 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): def fortios_firewall(data, fos):
login(data)
methodlist = ['firewall_ldb_monitor'] if data['firewall_ldb_monitor']:
for method in methodlist: resp = firewall_ldb_monitor(data, fos)
if data[method]:
resp = eval(method)(data, fos)
break
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "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_ldb_monitor": { "firewall_ldb_monitor": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"state": {"required": True, "type": "str", "http_get": {"required": False, "type": "str"},
"choices": ["present", "absent"]}, "http_match": {"required": False, "type": "str"},
"http-get": {"required": False, "type": "str"}, "http_max_redirects": {"required": False, "type": "int"},
"http-match": {"required": False, "type": "str"},
"http-max-redirects": {"required": False, "type": "int"},
"interval": {"required": False, "type": "int"}, "interval": {"required": False, "type": "int"},
"name": {"required": True, "type": "str"}, "name": {"required": True, "type": "str"},
"port": {"required": False, "type": "int"}, "port": {"required": False, "type": "int"},
@ -293,15 +333,30 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos legacy_mode = 'host' in module.params and module.params['host'] is not None and \
fos = FortiOSAPI() '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: if not is_error:
module.exit_json(changed=has_changed, meta=result) 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_local_in_policy module: fortios_firewall_local_in_policy
short_description: Configure user defined IPv4 local-in policies in Fortinet's FortiOS and FortiGate. short_description: Configure user defined IPv4 local-in policies in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by - This module is able to configure a FortiGate or FortiOS device by allowing the
allowing the user to configure firewall feature and local_in_policy category. user to set and modify firewall feature and local_in_policy category.
Examples includes all options and need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,93 +41,118 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool type: bool
default: true default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
choices:
- present
- absent
version_added: 2.9
firewall_local_in_policy: firewall_local_in_policy:
description: description:
- Configure user defined IPv4 local-in policies. - Configure user defined IPv4 local-in policies.
default: null default: null
type: dict
suboptions: suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
action: action:
description: description:
- Action performed on traffic matching the policy (default = deny). - Action performed on traffic matching the policy.
type: str
choices: choices:
- accept - accept
- deny - deny
comments: comments:
description: description:
- Comment. - Comment.
type: str
dstaddr: dstaddr:
description: description:
- Destination address object from available options. - Destination address object from available options.
type: list
suboptions: suboptions:
name: name:
description: description:
- Address name. Source firewall.address.name firewall.addrgrp.name. - Address name. Source firewall.address.name firewall.addrgrp.name.
required: true required: true
ha-mgmt-intf-only: type: str
ha_mgmt_intf_only:
description: description:
- Enable/disable dedicating the HA management interface only for local-in policy. - Enable/disable dedicating the HA management interface only for local-in policy.
type: str
choices: choices:
- enable - enable
- disable - disable
intf: intf:
description: description:
- Incoming interface name from available options. Source system.zone.name system.interface.name. - Incoming interface name from available options. Source system.zone.name system.interface.name.
type: str
policyid: policyid:
description: description:
- User defined local in policy ID. - User defined local in policy ID.
required: true required: true
type: int
schedule: schedule:
description: description:
- Schedule object from available options. Source firewall.schedule.onetime.name firewall.schedule.recurring.name firewall.schedule.group - Schedule object from available options. Source firewall.schedule.onetime.name firewall.schedule.recurring.name firewall.schedule.group
.name. .name.
type: str
service: service:
description: description:
- Service object from available options. - Service object from available options.
type: list
suboptions: suboptions:
name: name:
description: description:
- Service name. Source firewall.service.custom.name firewall.service.group.name. - Service name. Source firewall.service.custom.name firewall.service.group.name.
required: true required: true
type: str
srcaddr: srcaddr:
description: description:
- Source address object from available options. - Source address object from available options.
type: list
suboptions: suboptions:
name: name:
description: description:
- Address name. Source firewall.address.name firewall.addrgrp.name. - Address name. Source firewall.address.name firewall.addrgrp.name.
required: true required: true
type: str
status: status:
description: description:
- Enable/disable this local-in policy. - Enable/disable this local-in policy.
type: str
choices: choices:
- enable - enable
- disable - disable
@ -143,6 +165,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Configure user defined IPv4 local-in policies. - name: Configure user defined IPv4 local-in policies.
fortios_firewall_local_in_policy: fortios_firewall_local_in_policy:
@ -151,14 +174,14 @@ EXAMPLES = '''
password: "{{ password }}" password: "{{ password }}"
vdom: "{{ vdom }}" vdom: "{{ vdom }}"
https: "False" https: "False"
state: "present"
firewall_local_in_policy: firewall_local_in_policy:
state: "present"
action: "accept" action: "accept"
comments: "<your_own_value>" comments: "<your_own_value>"
dstaddr: dstaddr:
- -
name: "default_name_6 (source firewall.address.name firewall.addrgrp.name)" name: "default_name_6 (source firewall.address.name firewall.addrgrp.name)"
ha-mgmt-intf-only: "enable" ha_mgmt_intf_only: "enable"
intf: "<your_own_value> (source system.zone.name system.interface.name)" intf: "<your_own_value> (source system.zone.name system.interface.name)"
policyid: "9" policyid: "9"
schedule: "<your_own_value> (source firewall.schedule.onetime.name firewall.schedule.recurring.name firewall.schedule.group.name)" schedule: "<your_own_value> (source firewall.schedule.onetime.name firewall.schedule.recurring.name firewall.schedule.group.name)"
@ -231,14 +254,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule 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, fos):
def login(data):
host = data['host'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -246,12 +271,12 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_local_in_policy_data(json): def filter_firewall_local_in_policy_data(json):
option_list = ['action', 'comments', 'dstaddr', option_list = ['action', 'comments', 'dstaddr',
'ha-mgmt-intf-only', 'intf', 'policyid', 'ha_mgmt_intf_only', 'intf', 'policyid',
'schedule', 'service', 'srcaddr', 'schedule', 'service', 'srcaddr',
'status'] 'status']
dictionary = {} dictionary = {}
@ -263,48 +288,66 @@ def filter_firewall_local_in_policy_data(json):
return dictionary 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_local_in_policy(data, fos): def firewall_local_in_policy(data, fos):
vdom = data['vdom'] vdom = data['vdom']
state = data['state']
firewall_local_in_policy_data = data['firewall_local_in_policy'] firewall_local_in_policy_data = data['firewall_local_in_policy']
filtered_data = filter_firewall_local_in_policy_data(firewall_local_in_policy_data) filtered_data = underscore_to_hyphen(filter_firewall_local_in_policy_data(firewall_local_in_policy_data))
if firewall_local_in_policy_data['state'] == "present":
if state == "present":
return fos.set('firewall', return fos.set('firewall',
'local-in-policy', 'local-in-policy',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
elif firewall_local_in_policy_data['state'] == "absent": elif state == "absent":
return fos.delete('firewall', return fos.delete('firewall',
'local-in-policy', 'local-in-policy',
mkey=filtered_data['policyid'], mkey=filtered_data['policyid'],
vdom=vdom) 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): def fortios_firewall(data, fos):
login(data)
methodlist = ['firewall_local_in_policy'] if data['firewall_local_in_policy']:
for method in methodlist: resp = firewall_local_in_policy(data, fos)
if data[method]:
resp = eval(method)(data, fos)
break
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True}, "https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"firewall_local_in_policy": { "firewall_local_in_policy": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"action": {"required": False, "type": "str", "action": {"required": False, "type": "str",
"choices": ["accept", "deny"]}, "choices": ["accept", "deny"]},
"comments": {"required": False, "type": "str"}, "comments": {"required": False, "type": "str"},
@ -312,7 +355,7 @@ def main():
"options": { "options": {
"name": {"required": True, "type": "str"} "name": {"required": True, "type": "str"}
}}, }},
"ha-mgmt-intf-only": {"required": False, "type": "str", "ha_mgmt_intf_only": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"intf": {"required": False, "type": "str"}, "intf": {"required": False, "type": "str"},
"policyid": {"required": True, "type": "int"}, "policyid": {"required": True, "type": "int"},
@ -334,15 +377,30 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos legacy_mode = 'host' in module.params and module.params['host'] is not None and \
fos = FortiOSAPI() '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: if not is_error:
module.exit_json(changed=has_changed, meta=result) 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_local_in_policy6 module: fortios_firewall_local_in_policy6
short_description: Configure user defined IPv6 local-in policies in Fortinet's FortiOS and FortiGate. short_description: Configure user defined IPv6 local-in policies in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by - This module is able to configure a FortiGate or FortiOS device by allowing the
allowing the user to configure firewall feature and local_in_policy6 category. user to set and modify firewall feature and local_in_policy6 category.
Examples includes all options and need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,87 +41,111 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool type: bool
default: true default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
choices:
- present
- absent
version_added: 2.9
firewall_local_in_policy6: firewall_local_in_policy6:
description: description:
- Configure user defined IPv6 local-in policies. - Configure user defined IPv6 local-in policies.
default: null default: null
type: dict
suboptions: suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
action: action:
description: description:
- Action performed on traffic matching the policy (default = deny). - Action performed on traffic matching the policy.
type: str
choices: choices:
- accept - accept
- deny - deny
comments: comments:
description: description:
- Comment. - Comment.
type: str
dstaddr: dstaddr:
description: description:
- Destination address object from available options. - Destination address object from available options.
type: list
suboptions: suboptions:
name: name:
description: description:
- Address name. Source firewall.address6.name firewall.addrgrp6.name. - Address name. Source firewall.address6.name firewall.addrgrp6.name.
required: true required: true
type: str
intf: intf:
description: description:
- Incoming interface name from available options. Source system.zone.name system.interface.name. - Incoming interface name from available options. Source system.zone.name system.interface.name.
type: str
policyid: policyid:
description: description:
- User defined local in policy ID. - User defined local in policy ID.
required: true required: true
type: int
schedule: schedule:
description: description:
- Schedule object from available options. Source firewall.schedule.onetime.name firewall.schedule.recurring.name firewall.schedule.group - Schedule object from available options. Source firewall.schedule.onetime.name firewall.schedule.recurring.name firewall.schedule.group
.name. .name.
type: str
service: service:
description: description:
- Service object from available options. Separate names with a space. - Service object from available options. Separate names with a space.
type: list
suboptions: suboptions:
name: name:
description: description:
- Service name. Source firewall.service.custom.name firewall.service.group.name. - Service name. Source firewall.service.custom.name firewall.service.group.name.
required: true required: true
type: str
srcaddr: srcaddr:
description: description:
- Source address object from available options. - Source address object from available options.
type: list
suboptions: suboptions:
name: name:
description: description:
- Address name. Source firewall.address6.name firewall.addrgrp6.name. - Address name. Source firewall.address6.name firewall.addrgrp6.name.
required: true required: true
type: str
status: status:
description: description:
- Enable/disable this local-in policy. - Enable/disable this local-in policy.
type: str
choices: choices:
- enable - enable
- disable - disable
@ -137,6 +158,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Configure user defined IPv6 local-in policies. - name: Configure user defined IPv6 local-in policies.
fortios_firewall_local_in_policy6: fortios_firewall_local_in_policy6:
@ -145,8 +167,8 @@ EXAMPLES = '''
password: "{{ password }}" password: "{{ password }}"
vdom: "{{ vdom }}" vdom: "{{ vdom }}"
https: "False" https: "False"
state: "present"
firewall_local_in_policy6: firewall_local_in_policy6:
state: "present"
action: "accept" action: "accept"
comments: "<your_own_value>" comments: "<your_own_value>"
dstaddr: dstaddr:
@ -224,14 +246,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule 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, fos):
def login(data):
host = data['host'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -239,7 +263,7 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_local_in_policy6_data(json): def filter_firewall_local_in_policy6_data(json):
@ -255,48 +279,66 @@ def filter_firewall_local_in_policy6_data(json):
return dictionary 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_local_in_policy6(data, fos): def firewall_local_in_policy6(data, fos):
vdom = data['vdom'] vdom = data['vdom']
state = data['state']
firewall_local_in_policy6_data = data['firewall_local_in_policy6'] firewall_local_in_policy6_data = data['firewall_local_in_policy6']
filtered_data = filter_firewall_local_in_policy6_data(firewall_local_in_policy6_data) filtered_data = underscore_to_hyphen(filter_firewall_local_in_policy6_data(firewall_local_in_policy6_data))
if firewall_local_in_policy6_data['state'] == "present":
if state == "present":
return fos.set('firewall', return fos.set('firewall',
'local-in-policy6', 'local-in-policy6',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
elif firewall_local_in_policy6_data['state'] == "absent": elif state == "absent":
return fos.delete('firewall', return fos.delete('firewall',
'local-in-policy6', 'local-in-policy6',
mkey=filtered_data['policyid'], mkey=filtered_data['policyid'],
vdom=vdom) 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): def fortios_firewall(data, fos):
login(data)
methodlist = ['firewall_local_in_policy6'] if data['firewall_local_in_policy6']:
for method in methodlist: resp = firewall_local_in_policy6(data, fos)
if data[method]:
resp = eval(method)(data, fos)
break
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True}, "https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"firewall_local_in_policy6": { "firewall_local_in_policy6": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"action": {"required": False, "type": "str", "action": {"required": False, "type": "str",
"choices": ["accept", "deny"]}, "choices": ["accept", "deny"]},
"comments": {"required": False, "type": "str"}, "comments": {"required": False, "type": "str"},
@ -324,15 +366,30 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos legacy_mode = 'host' in module.params and module.params['host'] is not None and \
fos = FortiOSAPI() '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: if not is_error:
module.exit_json(changed=has_changed, meta=result) 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_multicast_address module: fortios_firewall_multicast_address
short_description: Configure multicast addresses in Fortinet's FortiOS and FortiGate. short_description: Configure multicast addresses in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by - This module is able to configure a FortiGate or FortiOS device by allowing the
allowing the user to configure firewall feature and multicast_address category. user to set and modify firewall feature and multicast_address category.
Examples includes all options and need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,91 +41,117 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool type: bool
default: true default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
choices:
- present
- absent
version_added: 2.9
firewall_multicast_address: firewall_multicast_address:
description: description:
- Configure multicast addresses. - Configure multicast addresses.
default: null default: null
type: dict
suboptions: suboptions:
state: associated_interface:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
associated-interface:
description: description:
- Interface associated with the address object. When setting up a policy, only addresses associated with this interface are available. - Interface associated with the address object. When setting up a policy, only addresses associated with this interface are available.
Source system.interface.name. Source system.interface.name.
type: str
color: color:
description: description:
- Integer value to determine the color of the icon in the GUI (1 - 32, default = 0, which sets value to 1). - Integer value to determine the color of the icon in the GUI (1 - 32, default = 0, which sets value to 1).
type: int
comment: comment:
description: description:
- Comment. - Comment.
end-ip: type: str
end_ip:
description: description:
- Final IPv4 address (inclusive) in the range for the address. - Final IPv4 address (inclusive) in the range for the address.
type: str
name: name:
description: description:
- Multicast address name. - Multicast address name.
required: true required: true
start-ip: type: str
start_ip:
description: description:
- First IPv4 address (inclusive) in the range for the address. - First IPv4 address (inclusive) in the range for the address.
type: str
subnet: subnet:
description: description:
- Broadcast address and subnet. - Broadcast address and subnet.
type: str
tagging: tagging:
description: description:
- Config object tagging. - Config object tagging.
type: list
suboptions: suboptions:
category: category:
description: description:
- Tag category. Source system.object-tagging.category. - Tag category. Source system.object-tagging.category.
type: str
name: name:
description: description:
- Tagging entry name. - Tagging entry name.
required: true required: true
type: str
tags: tags:
description: description:
- Tags. - Tags.
type: list
suboptions: suboptions:
name: name:
description: description:
- Tag name. Source system.object-tagging.tags.name. - Tag name. Source system.object-tagging.tags.name.
required: true required: true
type: str
type: type:
description: description:
- "Type of address object: multicast IP address range or broadcast IP/mask to be treated as a multicast address." - "Type of address object: multicast IP address range or broadcast IP/mask to be treated as a multicast address."
type: str
choices: choices:
- multicastrange - multicastrange
- broadcastmask - broadcastmask
visibility: visibility:
description: description:
- Enable/disable visibility of the multicast address on the GUI. - Enable/disable visibility of the multicast address on the GUI.
type: str
choices: choices:
- enable - enable
- disable - disable
@ -141,6 +164,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Configure multicast addresses. - name: Configure multicast addresses.
fortios_firewall_multicast_address: fortios_firewall_multicast_address:
@ -149,14 +173,14 @@ EXAMPLES = '''
password: "{{ password }}" password: "{{ password }}"
vdom: "{{ vdom }}" vdom: "{{ vdom }}"
https: "False" https: "False"
state: "present"
firewall_multicast_address: firewall_multicast_address:
state: "present" associated_interface: "<your_own_value> (source system.interface.name)"
associated-interface: "<your_own_value> (source system.interface.name)"
color: "4" color: "4"
comment: "Comment." comment: "Comment."
end-ip: "<your_own_value>" end_ip: "<your_own_value>"
name: "default_name_7" name: "default_name_7"
start-ip: "<your_own_value>" start_ip: "<your_own_value>"
subnet: "<your_own_value>" subnet: "<your_own_value>"
tagging: tagging:
- -
@ -229,14 +253,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule 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, fos):
def login(data):
host = data['host'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -244,12 +270,12 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_multicast_address_data(json): def filter_firewall_multicast_address_data(json):
option_list = ['associated-interface', 'color', 'comment', option_list = ['associated_interface', 'color', 'comment',
'end-ip', 'name', 'start-ip', 'end_ip', 'name', 'start_ip',
'subnet', 'tagging', 'type', 'subnet', 'tagging', 'type',
'visibility'] 'visibility']
dictionary = {} dictionary = {}
@ -261,54 +287,72 @@ def filter_firewall_multicast_address_data(json):
return dictionary 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_multicast_address(data, fos): def firewall_multicast_address(data, fos):
vdom = data['vdom'] vdom = data['vdom']
state = data['state']
firewall_multicast_address_data = data['firewall_multicast_address'] firewall_multicast_address_data = data['firewall_multicast_address']
filtered_data = filter_firewall_multicast_address_data(firewall_multicast_address_data) filtered_data = underscore_to_hyphen(filter_firewall_multicast_address_data(firewall_multicast_address_data))
if firewall_multicast_address_data['state'] == "present":
if state == "present":
return fos.set('firewall', return fos.set('firewall',
'multicast-address', 'multicast-address',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
elif firewall_multicast_address_data['state'] == "absent": elif state == "absent":
return fos.delete('firewall', return fos.delete('firewall',
'multicast-address', 'multicast-address',
mkey=filtered_data['name'], mkey=filtered_data['name'],
vdom=vdom) 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): def fortios_firewall(data, fos):
login(data)
methodlist = ['firewall_multicast_address'] if data['firewall_multicast_address']:
for method in methodlist: resp = firewall_multicast_address(data, fos)
if data[method]:
resp = eval(method)(data, fos)
break
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True}, "https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"firewall_multicast_address": { "firewall_multicast_address": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"state": {"required": True, "type": "str", "associated_interface": {"required": False, "type": "str"},
"choices": ["present", "absent"]},
"associated-interface": {"required": False, "type": "str"},
"color": {"required": False, "type": "int"}, "color": {"required": False, "type": "int"},
"comment": {"required": False, "type": "str"}, "comment": {"required": False, "type": "str"},
"end-ip": {"required": False, "type": "str"}, "end_ip": {"required": False, "type": "str"},
"name": {"required": True, "type": "str"}, "name": {"required": True, "type": "str"},
"start-ip": {"required": False, "type": "str"}, "start_ip": {"required": False, "type": "str"},
"subnet": {"required": False, "type": "str"}, "subnet": {"required": False, "type": "str"},
"tagging": {"required": False, "type": "list", "tagging": {"required": False, "type": "list",
"options": { "options": {
@ -330,15 +374,30 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos legacy_mode = 'host' in module.params and module.params['host'] is not None and \
fos = FortiOSAPI() '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: if not is_error:
module.exit_json(changed=has_changed, meta=result) 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_multicast_address6 module: fortios_firewall_multicast_address6
short_description: Configure IPv6 multicast address in Fortinet's FortiOS and FortiGate. short_description: Configure IPv6 multicast address in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by - This module is able to configure a FortiGate or FortiOS device by allowing the
allowing the user to configure firewall feature and multicast_address6 category. user to set and modify firewall feature and multicast_address6 category.
Examples includes all options and need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,75 +41,97 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool type: bool
default: true default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
choices:
- present
- absent
version_added: 2.9
firewall_multicast_address6: firewall_multicast_address6:
description: description:
- Configure IPv6 multicast address. - Configure IPv6 multicast address.
default: null default: null
type: dict
suboptions: suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
color: color:
description: description:
- Color of icon on the GUI. - Color of icon on the GUI.
type: int
comment: comment:
description: description:
- Comment. - Comment.
type: str
ip6: ip6:
description: description:
- "IPv6 address prefix (format: xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx/xxx)." - "IPv6 address prefix (format: xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx/xxx)."
type: str
name: name:
description: description:
- IPv6 multicast address name. - IPv6 multicast address name.
required: true required: true
type: str
tagging: tagging:
description: description:
- Config object tagging. - Config object tagging.
type: list
suboptions: suboptions:
category: category:
description: description:
- Tag category. Source system.object-tagging.category. - Tag category. Source system.object-tagging.category.
type: str
name: name:
description: description:
- Tagging entry name. - Tagging entry name.
required: true required: true
type: str
tags: tags:
description: description:
- Tags. - Tags.
type: list
suboptions: suboptions:
name: name:
description: description:
- Tag name. Source system.object-tagging.tags.name. - Tag name. Source system.object-tagging.tags.name.
required: true required: true
type: str
visibility: visibility:
description: description:
- Enable/disable visibility of the IPv6 multicast address on the GUI. - Enable/disable visibility of the IPv6 multicast address on the GUI.
type: str
choices: choices:
- enable - enable
- disable - disable
@ -125,6 +144,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Configure IPv6 multicast address. - name: Configure IPv6 multicast address.
fortios_firewall_multicast_address6: fortios_firewall_multicast_address6:
@ -133,8 +153,8 @@ EXAMPLES = '''
password: "{{ password }}" password: "{{ password }}"
vdom: "{{ vdom }}" vdom: "{{ vdom }}"
https: "False" https: "False"
state: "present"
firewall_multicast_address6: firewall_multicast_address6:
state: "present"
color: "3" color: "3"
comment: "Comment." comment: "Comment."
ip6: "<your_own_value>" ip6: "<your_own_value>"
@ -209,14 +229,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule 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, fos):
def login(data):
host = data['host'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -224,7 +246,7 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_multicast_address6_data(json): def filter_firewall_multicast_address6_data(json):
@ -239,48 +261,66 @@ def filter_firewall_multicast_address6_data(json):
return dictionary 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_multicast_address6(data, fos): def firewall_multicast_address6(data, fos):
vdom = data['vdom'] vdom = data['vdom']
state = data['state']
firewall_multicast_address6_data = data['firewall_multicast_address6'] firewall_multicast_address6_data = data['firewall_multicast_address6']
filtered_data = filter_firewall_multicast_address6_data(firewall_multicast_address6_data) filtered_data = underscore_to_hyphen(filter_firewall_multicast_address6_data(firewall_multicast_address6_data))
if firewall_multicast_address6_data['state'] == "present":
if state == "present":
return fos.set('firewall', return fos.set('firewall',
'multicast-address6', 'multicast-address6',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
elif firewall_multicast_address6_data['state'] == "absent": elif state == "absent":
return fos.delete('firewall', return fos.delete('firewall',
'multicast-address6', 'multicast-address6',
mkey=filtered_data['name'], mkey=filtered_data['name'],
vdom=vdom) 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): def fortios_firewall(data, fos):
login(data)
methodlist = ['firewall_multicast_address6'] if data['firewall_multicast_address6']:
for method in methodlist: resp = firewall_multicast_address6(data, fos)
if data[method]:
resp = eval(method)(data, fos)
break
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True}, "https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"firewall_multicast_address6": { "firewall_multicast_address6": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"color": {"required": False, "type": "int"}, "color": {"required": False, "type": "int"},
"comment": {"required": False, "type": "str"}, "comment": {"required": False, "type": "str"},
"ip6": {"required": False, "type": "str"}, "ip6": {"required": False, "type": "str"},
@ -303,15 +343,30 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos legacy_mode = 'host' in module.params and module.params['host'] is not None and \
fos = FortiOSAPI() '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: if not is_error:
module.exit_json(changed=has_changed, meta=result) 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_multicast_policy module: fortios_firewall_multicast_policy
short_description: Configure multicast NAT policies in Fortinet's FortiOS and FortiGate. short_description: Configure multicast NAT policies in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by - This module is able to configure a FortiGate or FortiOS device by allowing the
allowing the user to configure firewall feature and multicast_policy category. user to set and modify firewall feature and multicast_policy category.
Examples includes all options and need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,102 +41,130 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool type: bool
default: true default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
choices:
- present
- absent
version_added: 2.9
firewall_multicast_policy: firewall_multicast_policy:
description: description:
- Configure multicast NAT policies. - Configure multicast NAT policies.
default: null default: null
type: dict
suboptions: suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
action: action:
description: description:
- Accept or deny traffic matching the policy. - Accept or deny traffic matching the policy.
type: str
choices: choices:
- accept - accept
- deny - deny
dnat: dnat:
description: description:
- IPv4 DNAT address used for multicast destination addresses. - IPv4 DNAT address used for multicast destination addresses.
type: str
dstaddr: dstaddr:
description: description:
- Destination address objects. - Destination address objects.
type: list
suboptions: suboptions:
name: name:
description: description:
- Destination address objects. Source firewall.multicast-address.name. - Destination address objects. Source firewall.multicast-address.name.
required: true required: true
type: str
dstintf: dstintf:
description: description:
- Destination interface name. Source system.interface.name system.zone.name. - Destination interface name. Source system.interface.name system.zone.name.
end-port: type: str
end_port:
description: description:
- Integer value for ending TCP/UDP/SCTP destination port in range (1 - 65535, default = 1). - Integer value for ending TCP/UDP/SCTP destination port in range (1 - 65535, default = 1).
type: int
id: id:
description: description:
- Policy ID. - Policy ID.
required: true required: true
type: int
logtraffic: logtraffic:
description: description:
- Enable/disable logging traffic accepted by this policy. - Enable/disable logging traffic accepted by this policy.
type: str
choices: choices:
- enable - enable
- disable - disable
protocol: protocol:
description: description:
- Integer value for the protocol type as defined by IANA (0 - 255, default = 0). - Integer value for the protocol type as defined by IANA (0 - 255, default = 0).
type: int
snat: snat:
description: description:
- Enable/disable substitution of the outgoing interface IP address for the original source IP address (called source NAT or SNAT). - Enable/disable substitution of the outgoing interface IP address for the original source IP address (called source NAT or SNAT).
type: str
choices: choices:
- enable - enable
- disable - disable
snat-ip: snat_ip:
description: description:
- IPv4 address to be used as the source address for NATed traffic. - IPv4 address to be used as the source address for NATed traffic.
type: str
srcaddr: srcaddr:
description: description:
- Source address objects. - Source address objects.
type: list
suboptions: suboptions:
name: name:
description: description:
- Source address objects. Source firewall.address.name firewall.addrgrp.name. - Source address objects. Source firewall.address.name firewall.addrgrp.name.
required: true required: true
type: str
srcintf: srcintf:
description: description:
- Source interface name. Source system.interface.name system.zone.name. - Source interface name. Source system.interface.name system.zone.name.
start-port: type: str
start_port:
description: description:
- Integer value for starting TCP/UDP/SCTP destination port in range (1 - 65535, default = 1). - Integer value for starting TCP/UDP/SCTP destination port in range (1 - 65535, default = 1).
type: int
status: status:
description: description:
- Enable/disable this policy. - Enable/disable this policy.
type: str
choices: choices:
- enable - enable
- disable - disable
@ -152,6 +177,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Configure multicast NAT policies. - name: Configure multicast NAT policies.
fortios_firewall_multicast_policy: fortios_firewall_multicast_policy:
@ -160,25 +186,25 @@ EXAMPLES = '''
password: "{{ password }}" password: "{{ password }}"
vdom: "{{ vdom }}" vdom: "{{ vdom }}"
https: "False" https: "False"
state: "present"
firewall_multicast_policy: firewall_multicast_policy:
state: "present"
action: "accept" action: "accept"
dnat: "<your_own_value>" dnat: "<your_own_value>"
dstaddr: dstaddr:
- -
name: "default_name_6 (source firewall.multicast-address.name)" name: "default_name_6 (source firewall.multicast-address.name)"
dstintf: "<your_own_value> (source system.interface.name system.zone.name)" dstintf: "<your_own_value> (source system.interface.name system.zone.name)"
end-port: "8" end_port: "8"
id: "9" id: "9"
logtraffic: "enable" logtraffic: "enable"
protocol: "11" protocol: "11"
snat: "enable" snat: "enable"
snat-ip: "<your_own_value>" snat_ip: "<your_own_value>"
srcaddr: srcaddr:
- -
name: "default_name_15 (source firewall.address.name firewall.addrgrp.name)" name: "default_name_15 (source firewall.address.name firewall.addrgrp.name)"
srcintf: "<your_own_value> (source system.interface.name system.zone.name)" srcintf: "<your_own_value> (source system.interface.name system.zone.name)"
start-port: "17" start_port: "17"
status: "enable" status: "enable"
''' '''
@ -242,14 +268,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule 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, fos):
def login(data):
host = data['host'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -257,15 +285,15 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_multicast_policy_data(json): def filter_firewall_multicast_policy_data(json):
option_list = ['action', 'dnat', 'dstaddr', option_list = ['action', 'dnat', 'dstaddr',
'dstintf', 'end-port', 'id', 'dstintf', 'end_port', 'id',
'logtraffic', 'protocol', 'snat', 'logtraffic', 'protocol', 'snat',
'snat-ip', 'srcaddr', 'srcintf', 'snat_ip', 'srcaddr', 'srcintf',
'start-port', 'status'] 'start_port', 'status']
dictionary = {} dictionary = {}
for attribute in option_list: for attribute in option_list:
@ -275,48 +303,66 @@ def filter_firewall_multicast_policy_data(json):
return dictionary 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_multicast_policy(data, fos): def firewall_multicast_policy(data, fos):
vdom = data['vdom'] vdom = data['vdom']
state = data['state']
firewall_multicast_policy_data = data['firewall_multicast_policy'] firewall_multicast_policy_data = data['firewall_multicast_policy']
filtered_data = filter_firewall_multicast_policy_data(firewall_multicast_policy_data) filtered_data = underscore_to_hyphen(filter_firewall_multicast_policy_data(firewall_multicast_policy_data))
if firewall_multicast_policy_data['state'] == "present":
if state == "present":
return fos.set('firewall', return fos.set('firewall',
'multicast-policy', 'multicast-policy',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
elif firewall_multicast_policy_data['state'] == "absent": elif state == "absent":
return fos.delete('firewall', return fos.delete('firewall',
'multicast-policy', 'multicast-policy',
mkey=filtered_data['id'], mkey=filtered_data['id'],
vdom=vdom) 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): def fortios_firewall(data, fos):
login(data)
methodlist = ['firewall_multicast_policy'] if data['firewall_multicast_policy']:
for method in methodlist: resp = firewall_multicast_policy(data, fos)
if data[method]:
resp = eval(method)(data, fos)
break
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True}, "https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"firewall_multicast_policy": { "firewall_multicast_policy": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"action": {"required": False, "type": "str", "action": {"required": False, "type": "str",
"choices": ["accept", "deny"]}, "choices": ["accept", "deny"]},
"dnat": {"required": False, "type": "str"}, "dnat": {"required": False, "type": "str"},
@ -325,20 +371,20 @@ def main():
"name": {"required": True, "type": "str"} "name": {"required": True, "type": "str"}
}}, }},
"dstintf": {"required": False, "type": "str"}, "dstintf": {"required": False, "type": "str"},
"end-port": {"required": False, "type": "int"}, "end_port": {"required": False, "type": "int"},
"id": {"required": True, "type": "int"}, "id": {"required": True, "type": "int"},
"logtraffic": {"required": False, "type": "str", "logtraffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"protocol": {"required": False, "type": "int"}, "protocol": {"required": False, "type": "int"},
"snat": {"required": False, "type": "str", "snat": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"snat-ip": {"required": False, "type": "str"}, "snat_ip": {"required": False, "type": "str"},
"srcaddr": {"required": False, "type": "list", "srcaddr": {"required": False, "type": "list",
"options": { "options": {
"name": {"required": True, "type": "str"} "name": {"required": True, "type": "str"}
}}, }},
"srcintf": {"required": False, "type": "str"}, "srcintf": {"required": False, "type": "str"},
"start-port": {"required": False, "type": "int"}, "start_port": {"required": False, "type": "int"},
"status": {"required": False, "type": "str", "status": {"required": False, "type": "str",
"choices": ["enable", "disable"]} "choices": ["enable", "disable"]}
@ -348,15 +394,30 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos legacy_mode = 'host' in module.params and module.params['host'] is not None and \
fos = FortiOSAPI() '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: if not is_error:
module.exit_json(changed=has_changed, meta=result) 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_multicast_policy6 module: fortios_firewall_multicast_policy6
short_description: Configure IPv6 multicast NAT policies in Fortinet's FortiOS and FortiGate. short_description: Configure IPv6 multicast NAT policies in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by - This module is able to configure a FortiGate or FortiOS device by allowing the
allowing the user to configure firewall feature and multicast_policy6 category. user to set and modify firewall feature and multicast_policy6 category.
Examples includes all options and need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,90 +41,115 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool type: bool
default: true default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
choices:
- present
- absent
version_added: 2.9
firewall_multicast_policy6: firewall_multicast_policy6:
description: description:
- Configure IPv6 multicast NAT policies. - Configure IPv6 multicast NAT policies.
default: null default: null
type: dict
suboptions: suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
action: action:
description: description:
- Accept or deny traffic matching the policy. - Accept or deny traffic matching the policy.
type: str
choices: choices:
- accept - accept
- deny - deny
dstaddr: dstaddr:
description: description:
- IPv6 destination address name. - IPv6 destination address name.
type: list
suboptions: suboptions:
name: name:
description: description:
- Address name. Source firewall.multicast-address6.name. - Address name. Source firewall.multicast-address6.name.
required: true required: true
type: str
dstintf: dstintf:
description: description:
- IPv6 destination interface name. Source system.interface.name system.zone.name. - IPv6 destination interface name. Source system.interface.name system.zone.name.
end-port: type: str
end_port:
description: description:
- Integer value for ending TCP/UDP/SCTP destination port in range (1 - 65535, default = 65535). - Integer value for ending TCP/UDP/SCTP destination port in range (1 - 65535, default = 65535).
type: int
id: id:
description: description:
- Policy ID. - Policy ID.
required: true required: true
type: int
logtraffic: logtraffic:
description: description:
- Enable/disable logging traffic accepted by this policy. - Enable/disable logging traffic accepted by this policy.
type: str
choices: choices:
- enable - enable
- disable - disable
protocol: protocol:
description: description:
- Integer value for the protocol type as defined by IANA (0 - 255, default = 0). - Integer value for the protocol type as defined by IANA (0 - 255, default = 0).
type: int
srcaddr: srcaddr:
description: description:
- IPv6 source address name. - IPv6 source address name.
type: list
suboptions: suboptions:
name: name:
description: description:
- Address name. Source firewall.address6.name firewall.addrgrp6.name. - Address name. Source firewall.address6.name firewall.addrgrp6.name.
required: true required: true
type: str
srcintf: srcintf:
description: description:
- IPv6 source interface name. Source system.interface.name system.zone.name. - IPv6 source interface name. Source system.interface.name system.zone.name.
start-port: type: str
start_port:
description: description:
- Integer value for starting TCP/UDP/SCTP destination port in range (1 - 65535, default = 1). - Integer value for starting TCP/UDP/SCTP destination port in range (1 - 65535, default = 1).
type: int
status: status:
description: description:
- Enable/disable this policy. - Enable/disable this policy.
type: str
choices: choices:
- enable - enable
- disable - disable
@ -140,6 +162,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Configure IPv6 multicast NAT policies. - name: Configure IPv6 multicast NAT policies.
fortios_firewall_multicast_policy6: fortios_firewall_multicast_policy6:
@ -148,14 +171,14 @@ EXAMPLES = '''
password: "{{ password }}" password: "{{ password }}"
vdom: "{{ vdom }}" vdom: "{{ vdom }}"
https: "False" https: "False"
state: "present"
firewall_multicast_policy6: firewall_multicast_policy6:
state: "present"
action: "accept" action: "accept"
dstaddr: dstaddr:
- -
name: "default_name_5 (source firewall.multicast-address6.name)" name: "default_name_5 (source firewall.multicast-address6.name)"
dstintf: "<your_own_value> (source system.interface.name system.zone.name)" dstintf: "<your_own_value> (source system.interface.name system.zone.name)"
end-port: "7" end_port: "7"
id: "8" id: "8"
logtraffic: "enable" logtraffic: "enable"
protocol: "10" protocol: "10"
@ -163,7 +186,7 @@ EXAMPLES = '''
- -
name: "default_name_12 (source firewall.address6.name firewall.addrgrp6.name)" name: "default_name_12 (source firewall.address6.name firewall.addrgrp6.name)"
srcintf: "<your_own_value> (source system.interface.name system.zone.name)" srcintf: "<your_own_value> (source system.interface.name system.zone.name)"
start-port: "14" start_port: "14"
status: "enable" status: "enable"
''' '''
@ -227,14 +250,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule 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, fos):
def login(data):
host = data['host'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -242,14 +267,14 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_multicast_policy6_data(json): def filter_firewall_multicast_policy6_data(json):
option_list = ['action', 'dstaddr', 'dstintf', option_list = ['action', 'dstaddr', 'dstintf',
'end-port', 'id', 'logtraffic', 'end_port', 'id', 'logtraffic',
'protocol', 'srcaddr', 'srcintf', 'protocol', 'srcaddr', 'srcintf',
'start-port', 'status'] 'start_port', 'status']
dictionary = {} dictionary = {}
for attribute in option_list: for attribute in option_list:
@ -259,48 +284,66 @@ def filter_firewall_multicast_policy6_data(json):
return dictionary 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_multicast_policy6(data, fos): def firewall_multicast_policy6(data, fos):
vdom = data['vdom'] vdom = data['vdom']
state = data['state']
firewall_multicast_policy6_data = data['firewall_multicast_policy6'] firewall_multicast_policy6_data = data['firewall_multicast_policy6']
filtered_data = filter_firewall_multicast_policy6_data(firewall_multicast_policy6_data) filtered_data = underscore_to_hyphen(filter_firewall_multicast_policy6_data(firewall_multicast_policy6_data))
if firewall_multicast_policy6_data['state'] == "present":
if state == "present":
return fos.set('firewall', return fos.set('firewall',
'multicast-policy6', 'multicast-policy6',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
elif firewall_multicast_policy6_data['state'] == "absent": elif state == "absent":
return fos.delete('firewall', return fos.delete('firewall',
'multicast-policy6', 'multicast-policy6',
mkey=filtered_data['id'], mkey=filtered_data['id'],
vdom=vdom) 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): def fortios_firewall(data, fos):
login(data)
methodlist = ['firewall_multicast_policy6'] if data['firewall_multicast_policy6']:
for method in methodlist: resp = firewall_multicast_policy6(data, fos)
if data[method]:
resp = eval(method)(data, fos)
break
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True}, "https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"firewall_multicast_policy6": { "firewall_multicast_policy6": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"action": {"required": False, "type": "str", "action": {"required": False, "type": "str",
"choices": ["accept", "deny"]}, "choices": ["accept", "deny"]},
"dstaddr": {"required": False, "type": "list", "dstaddr": {"required": False, "type": "list",
@ -308,7 +351,7 @@ def main():
"name": {"required": True, "type": "str"} "name": {"required": True, "type": "str"}
}}, }},
"dstintf": {"required": False, "type": "str"}, "dstintf": {"required": False, "type": "str"},
"end-port": {"required": False, "type": "int"}, "end_port": {"required": False, "type": "int"},
"id": {"required": True, "type": "int"}, "id": {"required": True, "type": "int"},
"logtraffic": {"required": False, "type": "str", "logtraffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
@ -318,7 +361,7 @@ def main():
"name": {"required": True, "type": "str"} "name": {"required": True, "type": "str"}
}}, }},
"srcintf": {"required": False, "type": "str"}, "srcintf": {"required": False, "type": "str"},
"start-port": {"required": False, "type": "int"}, "start_port": {"required": False, "type": "int"},
"status": {"required": False, "type": "str", "status": {"required": False, "type": "str",
"choices": ["enable", "disable"]} "choices": ["enable", "disable"]}
@ -328,15 +371,30 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos legacy_mode = 'host' in module.params and module.params['host'] is not None and \
fos = FortiOSAPI() '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: if not is_error:
module.exit_json(changed=has_changed, meta=result) module.exit_json(changed=has_changed, meta=result)

@ -1,6 +1,6 @@
#!/usr/bin/python #!/usr/bin/python
from __future__ import (absolute_import, division, print_function) 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 # 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 # 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_policy46 module: fortios_firewall_policy46
short_description: Configure IPv4 to IPv6 policies in Fortinet's FortiOS and FortiGate. short_description: Configure IPv4 to IPv6 policies in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by - This module is able to configure a FortiGate or FortiOS device by allowing the
allowing the user to configure firewall feature and policy46 category. user to set and modify firewall feature and policy46 category.
Examples includes all options and need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,84 +41,106 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol
type: bool type: bool
default: false default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
choices:
- present
- absent
version_added: 2.9
firewall_policy46: firewall_policy46:
description: description:
- Configure IPv4 to IPv6 policies. - Configure IPv4 to IPv6 policies.
default: null default: null
type: dict
suboptions: suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
action: action:
description: description:
- Accept or deny traffic matching the policy. - Accept or deny traffic matching the policy.
type: str
choices: choices:
- accept - accept
- deny - deny
comments: comments:
description: description:
- Comment. - Comment.
type: str
dstaddr: dstaddr:
description: description:
- Destination address objects. - Destination address objects.
type: list
suboptions: suboptions:
name: name:
description: description:
- Address name. Source firewall.vip46.name firewall.vipgrp46.name. - Address name. Source firewall.vip46.name firewall.vipgrp46.name.
required: true required: true
type: str
dstintf: dstintf:
description: description:
- Destination interface name. Source system.interface.name system.zone.name. - Destination interface name. Source system.interface.name system.zone.name.
type: str
fixedport: fixedport:
description: description:
- Enable/disable fixed port for this policy. - Enable/disable fixed port for this policy.
type: str
choices: choices:
- enable - enable
- disable - disable
ippool: ippool:
description: description:
- Enable/disable use of IP Pools for source NAT. - Enable/disable use of IP Pools for source NAT.
type: str
choices: choices:
- enable - enable
- disable - disable
logtraffic: logtraffic:
description: description:
- Enable/disable traffic logging for this policy. - Enable/disable traffic logging for this policy.
type: str
choices: choices:
- enable - enable
- disable - disable
per-ip-shaper: per_ip_shaper:
description: description:
- Per IP traffic shaper. Source firewall.shaper.per-ip-shaper.name. - Per IP traffic shaper. Source firewall.shaper.per-ip-shaper.name.
permit-any-host: type: str
permit_any_host:
description: description:
- Enable/disable allowing any host. - Enable/disable allowing any host.
type: str
choices: choices:
- enable - enable
- disable - disable
@ -129,57 +148,72 @@ options:
description: description:
- Policy ID. - Policy ID.
required: true required: true
type: int
poolname: poolname:
description: description:
- IP Pool names. - IP Pool names.
type: list
suboptions: suboptions:
name: name:
description: description:
- IP pool name. Source firewall.ippool6.name. - IP pool name. Source firewall.ippool6.name.
required: true required: true
type: str
schedule: schedule:
description: description:
- Schedule name. Source firewall.schedule.onetime.name firewall.schedule.recurring.name firewall.schedule.group.name. - Schedule name. Source firewall.schedule.onetime.name firewall.schedule.recurring.name firewall.schedule.group.name.
type: str
service: service:
description: description:
- Service name. - Service name.
type: list
suboptions: suboptions:
name: name:
description: description:
- Service name. Source firewall.service.custom.name firewall.service.group.name. - Service name. Source firewall.service.custom.name firewall.service.group.name.
required: true required: true
type: str
srcaddr: srcaddr:
description: description:
- Source address objects. - Source address objects.
type: list
suboptions: suboptions:
name: name:
description: description:
- Address name. Source firewall.address.name firewall.addrgrp.name. - Address name. Source firewall.address.name firewall.addrgrp.name.
required: true required: true
type: str
srcintf: srcintf:
description: description:
- Source interface name. Source system.zone.name system.interface.name. - Source interface name. Source system.zone.name system.interface.name.
type: str
status: status:
description: description:
- Enable/disable this policy. - Enable/disable this policy.
type: str
choices: choices:
- enable - enable
- disable - disable
tcp-mss-receiver: tcp_mss_receiver:
description: description:
- TCP Maximum Segment Size value of receiver (0 - 65535, default = 0) - TCP Maximum Segment Size value of receiver (0 - 65535, default = 0)
tcp-mss-sender: type: int
tcp_mss_sender:
description: description:
- TCP Maximum Segment Size value of sender (0 - 65535, default = 0). - TCP Maximum Segment Size value of sender (0 - 65535, default = 0).
traffic-shaper: type: int
traffic_shaper:
description: description:
- Traffic shaper. Source firewall.shaper.traffic-shaper.name. - Traffic shaper. Source firewall.shaper.traffic-shaper.name.
traffic-shaper-reverse: type: str
traffic_shaper_reverse:
description: description:
- Reverse traffic shaper. Source firewall.shaper.traffic-shaper.name. - Reverse traffic shaper. Source firewall.shaper.traffic-shaper.name.
type: str
uuid: uuid:
description: description:
- Universally Unique Identifier (UUID; automatically assigned but can be manually reset). - Universally Unique Identifier (UUID; automatically assigned but can be manually reset).
type: str
''' '''
EXAMPLES = ''' EXAMPLES = '''
@ -189,6 +223,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Configure IPv4 to IPv6 policies. - name: Configure IPv4 to IPv6 policies.
fortios_firewall_policy46: fortios_firewall_policy46:
@ -196,8 +231,9 @@ EXAMPLES = '''
username: "{{ username }}" username: "{{ username }}"
password: "{{ password }}" password: "{{ password }}"
vdom: "{{ vdom }}" vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_policy46: firewall_policy46:
state: "present"
action: "accept" action: "accept"
comments: "<your_own_value>" comments: "<your_own_value>"
dstaddr: dstaddr:
@ -207,8 +243,8 @@ EXAMPLES = '''
fixedport: "enable" fixedport: "enable"
ippool: "enable" ippool: "enable"
logtraffic: "enable" logtraffic: "enable"
per-ip-shaper: "<your_own_value> (source firewall.shaper.per-ip-shaper.name)" per_ip_shaper: "<your_own_value> (source firewall.shaper.per-ip-shaper.name)"
permit-any-host: "enable" permit_any_host: "enable"
policyid: "13" policyid: "13"
poolname: poolname:
- -
@ -222,10 +258,10 @@ EXAMPLES = '''
name: "default_name_20 (source firewall.address.name firewall.addrgrp.name)" name: "default_name_20 (source firewall.address.name firewall.addrgrp.name)"
srcintf: "<your_own_value> (source system.zone.name system.interface.name)" srcintf: "<your_own_value> (source system.zone.name system.interface.name)"
status: "enable" status: "enable"
tcp-mss-receiver: "23" tcp_mss_receiver: "23"
tcp-mss-sender: "24" tcp_mss_sender: "24"
traffic-shaper: "<your_own_value> (source firewall.shaper.traffic-shaper.name)" traffic_shaper: "<your_own_value> (source firewall.shaper.traffic-shaper.name)"
traffic-shaper-reverse: "<your_own_value> (source firewall.shaper.traffic-shaper.name)" traffic_shaper_reverse: "<your_own_value> (source firewall.shaper.traffic-shaper.name)"
uuid: "<your_own_value>" uuid: "<your_own_value>"
''' '''
@ -249,7 +285,7 @@ mkey:
description: Master key (id) used in the last call to FortiGate description: Master key (id) used in the last call to FortiGate
returned: success returned: success
type: str type: str
sample: "key1" sample: "id"
name: name:
description: Name of the table used to fulfill the request description: Name of the table used to fulfill the request
returned: always returned: always
@ -289,14 +325,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule 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, fos):
def login(data):
host = data['host'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -304,17 +342,17 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_policy46_data(json): def filter_firewall_policy46_data(json):
option_list = ['action', 'comments', 'dstaddr', option_list = ['action', 'comments', 'dstaddr',
'dstintf', 'fixedport', 'ippool', 'dstintf', 'fixedport', 'ippool',
'logtraffic', 'per-ip-shaper', 'permit-any-host', 'logtraffic', 'per_ip_shaper', 'permit_any_host',
'policyid', 'poolname', 'schedule', 'policyid', 'poolname', 'schedule',
'service', 'srcaddr', 'srcintf', 'service', 'srcaddr', 'srcintf',
'status', 'tcp-mss-receiver', 'tcp-mss-sender', 'status', 'tcp_mss_receiver', 'tcp_mss_sender',
'traffic-shaper', 'traffic-shaper-reverse', 'uuid'] 'traffic_shaper', 'traffic_shaper_reverse', 'uuid']
dictionary = {} dictionary = {}
for attribute in option_list: for attribute in option_list:
@ -324,48 +362,66 @@ def filter_firewall_policy46_data(json):
return dictionary 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_policy46(data, fos): def firewall_policy46(data, fos):
vdom = data['vdom'] vdom = data['vdom']
state = data['state']
firewall_policy46_data = data['firewall_policy46'] firewall_policy46_data = data['firewall_policy46']
filtered_data = filter_firewall_policy46_data(firewall_policy46_data) filtered_data = underscore_to_hyphen(filter_firewall_policy46_data(firewall_policy46_data))
if firewall_policy46_data['state'] == "present":
if state == "present":
return fos.set('firewall', return fos.set('firewall',
'policy46', 'policy46',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
elif firewall_policy46_data['state'] == "absent": elif state == "absent":
return fos.delete('firewall', return fos.delete('firewall',
'policy46', 'policy46',
mkey=filtered_data['policyid'], mkey=filtered_data['policyid'],
vdom=vdom) 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): def fortios_firewall(data, fos):
login(data)
methodlist = ['firewall_policy46'] if data['firewall_policy46']:
for method in methodlist: resp = firewall_policy46(data, fos)
if data[method]:
resp = eval(method)(data, fos)
break
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "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_policy46": { "firewall_policy46": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"action": {"required": False, "type": "str", "action": {"required": False, "type": "str",
"choices": ["accept", "deny"]}, "choices": ["accept", "deny"]},
"comments": {"required": False, "type": "str"}, "comments": {"required": False, "type": "str"},
@ -380,8 +436,8 @@ def main():
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"logtraffic": {"required": False, "type": "str", "logtraffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"per-ip-shaper": {"required": False, "type": "str"}, "per_ip_shaper": {"required": False, "type": "str"},
"permit-any-host": {"required": False, "type": "str", "permit_any_host": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"policyid": {"required": True, "type": "int"}, "policyid": {"required": True, "type": "int"},
"poolname": {"required": False, "type": "list", "poolname": {"required": False, "type": "list",
@ -400,10 +456,10 @@ def main():
"srcintf": {"required": False, "type": "str"}, "srcintf": {"required": False, "type": "str"},
"status": {"required": False, "type": "str", "status": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"tcp-mss-receiver": {"required": False, "type": "int"}, "tcp_mss_receiver": {"required": False, "type": "int"},
"tcp-mss-sender": {"required": False, "type": "int"}, "tcp_mss_sender": {"required": False, "type": "int"},
"traffic-shaper": {"required": False, "type": "str"}, "traffic_shaper": {"required": False, "type": "str"},
"traffic-shaper-reverse": {"required": False, "type": "str"}, "traffic_shaper_reverse": {"required": False, "type": "str"},
"uuid": {"required": False, "type": "str"} "uuid": {"required": False, "type": "str"}
} }
@ -412,15 +468,30 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos legacy_mode = 'host' in module.params and module.params['host'] is not None and \
fos = FortiOSAPI() '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: if not is_error:
module.exit_json(changed=has_changed, meta=result) module.exit_json(changed=has_changed, meta=result)

@ -1,6 +1,6 @@
#!/usr/bin/python #!/usr/bin/python
from __future__ import (absolute_import, division, print_function) 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 # 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 # 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_policy64 module: fortios_firewall_policy64
short_description: Configure IPv6 to IPv4 policies in Fortinet's FortiOS and FortiGate. short_description: Configure IPv6 to IPv4 policies in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by - This module is able to configure a FortiGate or FortiOS device by allowing the
allowing the user to configure firewall feature and policy64 category. user to set and modify firewall feature and policy64 category.
Examples includes all options and need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,84 +41,106 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol
type: bool type: bool
default: false default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
choices:
- present
- absent
version_added: 2.9
firewall_policy64: firewall_policy64:
description: description:
- Configure IPv6 to IPv4 policies. - Configure IPv6 to IPv4 policies.
default: null default: null
type: dict
suboptions: suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
action: action:
description: description:
- Policy action. - Policy action.
type: str
choices: choices:
- accept - accept
- deny - deny
comments: comments:
description: description:
- Comment. - Comment.
type: str
dstaddr: dstaddr:
description: description:
- Destination address name. - Destination address name.
type: list
suboptions: suboptions:
name: name:
description: description:
- Address name. Source firewall.address.name firewall.addrgrp.name firewall.vip64.name firewall.vipgrp64.name. - Address name. Source firewall.address.name firewall.addrgrp.name firewall.vip64.name firewall.vipgrp64.name.
required: true required: true
type: str
dstintf: dstintf:
description: description:
- Destination interface name. Source system.interface.name system.zone.name. - Destination interface name. Source system.interface.name system.zone.name.
type: str
fixedport: fixedport:
description: description:
- Enable/disable policy fixed port. - Enable/disable policy fixed port.
type: str
choices: choices:
- enable - enable
- disable - disable
ippool: ippool:
description: description:
- Enable/disable policy64 IP pool. - Enable/disable policy64 IP pool.
type: str
choices: choices:
- enable - enable
- disable - disable
logtraffic: logtraffic:
description: description:
- Enable/disable policy log traffic. - Enable/disable policy log traffic.
type: str
choices: choices:
- enable - enable
- disable - disable
per-ip-shaper: per_ip_shaper:
description: description:
- Per-IP traffic shaper. Source firewall.shaper.per-ip-shaper.name. - Per-IP traffic shaper. Source firewall.shaper.per-ip-shaper.name.
permit-any-host: type: str
permit_any_host:
description: description:
- Enable/disable permit any host in. - Enable/disable permit any host in.
type: str
choices: choices:
- enable - enable
- disable - disable
@ -129,57 +148,72 @@ options:
description: description:
- Policy ID. - Policy ID.
required: true required: true
type: int
poolname: poolname:
description: description:
- Policy IP pool names. - Policy IP pool names.
type: list
suboptions: suboptions:
name: name:
description: description:
- IP pool name. Source firewall.ippool.name. - IP pool name. Source firewall.ippool.name.
required: true required: true
type: str
schedule: schedule:
description: description:
- Schedule name. Source firewall.schedule.onetime.name firewall.schedule.recurring.name firewall.schedule.group.name. - Schedule name. Source firewall.schedule.onetime.name firewall.schedule.recurring.name firewall.schedule.group.name.
type: str
service: service:
description: description:
- Service name. - Service name.
type: list
suboptions: suboptions:
name: name:
description: description:
- Address name. Source firewall.service.custom.name firewall.service.group.name. - Address name. Source firewall.service.custom.name firewall.service.group.name.
required: true required: true
type: str
srcaddr: srcaddr:
description: description:
- Source address name. - Source address name.
type: list
suboptions: suboptions:
name: name:
description: description:
- Address name. Source firewall.address6.name firewall.addrgrp6.name. - Address name. Source firewall.address6.name firewall.addrgrp6.name.
required: true required: true
type: str
srcintf: srcintf:
description: description:
- Source interface name. Source system.zone.name system.interface.name. - Source interface name. Source system.zone.name system.interface.name.
type: str
status: status:
description: description:
- Enable/disable policy status. - Enable/disable policy status.
type: str
choices: choices:
- enable - enable
- disable - disable
tcp-mss-receiver: tcp_mss_receiver:
description: description:
- TCP MSS value of receiver. - TCP MSS value of receiver.
tcp-mss-sender: type: int
tcp_mss_sender:
description: description:
- TCP MSS value of sender. - TCP MSS value of sender.
traffic-shaper: type: int
traffic_shaper:
description: description:
- Traffic shaper. Source firewall.shaper.traffic-shaper.name. - Traffic shaper. Source firewall.shaper.traffic-shaper.name.
traffic-shaper-reverse: type: str
traffic_shaper_reverse:
description: description:
- Reverse traffic shaper. Source firewall.shaper.traffic-shaper.name. - Reverse traffic shaper. Source firewall.shaper.traffic-shaper.name.
type: str
uuid: uuid:
description: description:
- Universally Unique Identifier (UUID; automatically assigned but can be manually reset). - Universally Unique Identifier (UUID; automatically assigned but can be manually reset).
type: str
''' '''
EXAMPLES = ''' EXAMPLES = '''
@ -189,6 +223,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Configure IPv6 to IPv4 policies. - name: Configure IPv6 to IPv4 policies.
fortios_firewall_policy64: fortios_firewall_policy64:
@ -196,8 +231,9 @@ EXAMPLES = '''
username: "{{ username }}" username: "{{ username }}"
password: "{{ password }}" password: "{{ password }}"
vdom: "{{ vdom }}" vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_policy64: firewall_policy64:
state: "present"
action: "accept" action: "accept"
comments: "<your_own_value>" comments: "<your_own_value>"
dstaddr: dstaddr:
@ -207,8 +243,8 @@ EXAMPLES = '''
fixedport: "enable" fixedport: "enable"
ippool: "enable" ippool: "enable"
logtraffic: "enable" logtraffic: "enable"
per-ip-shaper: "<your_own_value> (source firewall.shaper.per-ip-shaper.name)" per_ip_shaper: "<your_own_value> (source firewall.shaper.per-ip-shaper.name)"
permit-any-host: "enable" permit_any_host: "enable"
policyid: "13" policyid: "13"
poolname: poolname:
- -
@ -222,10 +258,10 @@ EXAMPLES = '''
name: "default_name_20 (source firewall.address6.name firewall.addrgrp6.name)" name: "default_name_20 (source firewall.address6.name firewall.addrgrp6.name)"
srcintf: "<your_own_value> (source system.zone.name system.interface.name)" srcintf: "<your_own_value> (source system.zone.name system.interface.name)"
status: "enable" status: "enable"
tcp-mss-receiver: "23" tcp_mss_receiver: "23"
tcp-mss-sender: "24" tcp_mss_sender: "24"
traffic-shaper: "<your_own_value> (source firewall.shaper.traffic-shaper.name)" traffic_shaper: "<your_own_value> (source firewall.shaper.traffic-shaper.name)"
traffic-shaper-reverse: "<your_own_value> (source firewall.shaper.traffic-shaper.name)" traffic_shaper_reverse: "<your_own_value> (source firewall.shaper.traffic-shaper.name)"
uuid: "<your_own_value>" uuid: "<your_own_value>"
''' '''
@ -249,7 +285,7 @@ mkey:
description: Master key (id) used in the last call to FortiGate description: Master key (id) used in the last call to FortiGate
returned: success returned: success
type: str type: str
sample: "key1" sample: "id"
name: name:
description: Name of the table used to fulfill the request description: Name of the table used to fulfill the request
returned: always returned: always
@ -289,14 +325,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule 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, fos):
def login(data):
host = data['host'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -304,17 +342,17 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_policy64_data(json): def filter_firewall_policy64_data(json):
option_list = ['action', 'comments', 'dstaddr', option_list = ['action', 'comments', 'dstaddr',
'dstintf', 'fixedport', 'ippool', 'dstintf', 'fixedport', 'ippool',
'logtraffic', 'per-ip-shaper', 'permit-any-host', 'logtraffic', 'per_ip_shaper', 'permit_any_host',
'policyid', 'poolname', 'schedule', 'policyid', 'poolname', 'schedule',
'service', 'srcaddr', 'srcintf', 'service', 'srcaddr', 'srcintf',
'status', 'tcp-mss-receiver', 'tcp-mss-sender', 'status', 'tcp_mss_receiver', 'tcp_mss_sender',
'traffic-shaper', 'traffic-shaper-reverse', 'uuid'] 'traffic_shaper', 'traffic_shaper_reverse', 'uuid']
dictionary = {} dictionary = {}
for attribute in option_list: for attribute in option_list:
@ -324,48 +362,66 @@ def filter_firewall_policy64_data(json):
return dictionary 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_policy64(data, fos): def firewall_policy64(data, fos):
vdom = data['vdom'] vdom = data['vdom']
state = data['state']
firewall_policy64_data = data['firewall_policy64'] firewall_policy64_data = data['firewall_policy64']
filtered_data = filter_firewall_policy64_data(firewall_policy64_data) filtered_data = underscore_to_hyphen(filter_firewall_policy64_data(firewall_policy64_data))
if firewall_policy64_data['state'] == "present":
if state == "present":
return fos.set('firewall', return fos.set('firewall',
'policy64', 'policy64',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
elif firewall_policy64_data['state'] == "absent": elif state == "absent":
return fos.delete('firewall', return fos.delete('firewall',
'policy64', 'policy64',
mkey=filtered_data['policyid'], mkey=filtered_data['policyid'],
vdom=vdom) 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): def fortios_firewall(data, fos):
login(data)
methodlist = ['firewall_policy64'] if data['firewall_policy64']:
for method in methodlist: resp = firewall_policy64(data, fos)
if data[method]:
resp = eval(method)(data, fos)
break
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "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_policy64": { "firewall_policy64": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"action": {"required": False, "type": "str", "action": {"required": False, "type": "str",
"choices": ["accept", "deny"]}, "choices": ["accept", "deny"]},
"comments": {"required": False, "type": "str"}, "comments": {"required": False, "type": "str"},
@ -380,8 +436,8 @@ def main():
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"logtraffic": {"required": False, "type": "str", "logtraffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"per-ip-shaper": {"required": False, "type": "str"}, "per_ip_shaper": {"required": False, "type": "str"},
"permit-any-host": {"required": False, "type": "str", "permit_any_host": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"policyid": {"required": True, "type": "int"}, "policyid": {"required": True, "type": "int"},
"poolname": {"required": False, "type": "list", "poolname": {"required": False, "type": "list",
@ -400,10 +456,10 @@ def main():
"srcintf": {"required": False, "type": "str"}, "srcintf": {"required": False, "type": "str"},
"status": {"required": False, "type": "str", "status": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"tcp-mss-receiver": {"required": False, "type": "int"}, "tcp_mss_receiver": {"required": False, "type": "int"},
"tcp-mss-sender": {"required": False, "type": "int"}, "tcp_mss_sender": {"required": False, "type": "int"},
"traffic-shaper": {"required": False, "type": "str"}, "traffic_shaper": {"required": False, "type": "str"},
"traffic-shaper-reverse": {"required": False, "type": "str"}, "traffic_shaper_reverse": {"required": False, "type": "str"},
"uuid": {"required": False, "type": "str"} "uuid": {"required": False, "type": "str"}
} }
@ -412,15 +468,30 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos legacy_mode = 'host' in module.params and module.params['host'] is not None and \
fos = FortiOSAPI() '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: if not is_error:
module.exit_json(changed=has_changed, meta=result) 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_profile_group module: fortios_firewall_profile_group
short_description: Configure profile groups in Fortinet's FortiOS and FortiGate. short_description: Configure profile groups in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by - This module is able to configure a FortiGate or FortiOS device by allowing the
allowing the user to configure firewall feature and profile_group category. user to set and modify firewall feature and profile_group category.
Examples includes all options and need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,83 +41,109 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool type: bool
default: true default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
choices:
- present
- absent
version_added: 2.9
firewall_profile_group: firewall_profile_group:
description: description:
- Configure profile groups. - Configure profile groups.
default: null default: null
type: dict
suboptions: suboptions:
state: application_list:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
application-list:
description: description:
- Name of an existing Application list. Source application.list.name. - Name of an existing Application list. Source application.list.name.
av-profile: type: str
av_profile:
description: description:
- Name of an existing Antivirus profile. Source antivirus.profile.name. - Name of an existing Antivirus profile. Source antivirus.profile.name.
dlp-sensor: type: str
dlp_sensor:
description: description:
- Name of an existing DLP sensor. Source dlp.sensor.name. - Name of an existing DLP sensor. Source dlp.sensor.name.
dnsfilter-profile: type: str
dnsfilter_profile:
description: description:
- Name of an existing DNS filter profile. Source dnsfilter.profile.name. - Name of an existing DNS filter profile. Source dnsfilter.profile.name.
icap-profile: type: str
icap_profile:
description: description:
- Name of an existing ICAP profile. Source icap.profile.name. - Name of an existing ICAP profile. Source icap.profile.name.
ips-sensor: type: str
ips_sensor:
description: description:
- Name of an existing IPS sensor. Source ips.sensor.name. - Name of an existing IPS sensor. Source ips.sensor.name.
type: str
name: name:
description: description:
- Profile group name. - Profile group name.
required: true required: true
profile-protocol-options: type: str
profile_protocol_options:
description: description:
- Name of an existing Protocol options profile. Source firewall.profile-protocol-options.name. - Name of an existing Protocol options profile. Source firewall.profile-protocol-options.name.
spamfilter-profile: type: str
spamfilter_profile:
description: description:
- Name of an existing Spam filter profile. Source spamfilter.profile.name. - Name of an existing Spam filter profile. Source spamfilter.profile.name.
ssh-filter-profile: type: str
ssh_filter_profile:
description: description:
- Name of an existing SSH filter profile. Source ssh-filter.profile.name. - Name of an existing SSH filter profile. Source ssh-filter.profile.name.
ssl-ssh-profile: type: str
ssl_ssh_profile:
description: description:
- Name of an existing SSL SSH profile. Source firewall.ssl-ssh-profile.name. - Name of an existing SSL SSH profile. Source firewall.ssl-ssh-profile.name.
voip-profile: type: str
voip_profile:
description: description:
- Name of an existing VoIP profile. Source voip.profile.name. - Name of an existing VoIP profile. Source voip.profile.name.
waf-profile: type: str
waf_profile:
description: description:
- Name of an existing Web application firewall profile. Source waf.profile.name. - Name of an existing Web application firewall profile. Source waf.profile.name.
webfilter-profile: type: str
webfilter_profile:
description: description:
- Name of an existing Web filter profile. Source webfilter.profile.name. - Name of an existing Web filter profile. Source webfilter.profile.name.
type: str
''' '''
EXAMPLES = ''' EXAMPLES = '''
@ -130,6 +153,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Configure profile groups. - name: Configure profile groups.
fortios_firewall_profile_group: fortios_firewall_profile_group:
@ -138,22 +162,22 @@ EXAMPLES = '''
password: "{{ password }}" password: "{{ password }}"
vdom: "{{ vdom }}" vdom: "{{ vdom }}"
https: "False" https: "False"
state: "present"
firewall_profile_group: firewall_profile_group:
state: "present" application_list: "<your_own_value> (source application.list.name)"
application-list: "<your_own_value> (source application.list.name)" av_profile: "<your_own_value> (source antivirus.profile.name)"
av-profile: "<your_own_value> (source antivirus.profile.name)" dlp_sensor: "<your_own_value> (source dlp.sensor.name)"
dlp-sensor: "<your_own_value> (source dlp.sensor.name)" dnsfilter_profile: "<your_own_value> (source dnsfilter.profile.name)"
dnsfilter-profile: "<your_own_value> (source dnsfilter.profile.name)" icap_profile: "<your_own_value> (source icap.profile.name)"
icap-profile: "<your_own_value> (source icap.profile.name)" ips_sensor: "<your_own_value> (source ips.sensor.name)"
ips-sensor: "<your_own_value> (source ips.sensor.name)"
name: "default_name_9" name: "default_name_9"
profile-protocol-options: "<your_own_value> (source firewall.profile-protocol-options.name)" profile_protocol_options: "<your_own_value> (source firewall.profile-protocol-options.name)"
spamfilter-profile: "<your_own_value> (source spamfilter.profile.name)" spamfilter_profile: "<your_own_value> (source spamfilter.profile.name)"
ssh-filter-profile: "<your_own_value> (source ssh-filter.profile.name)" ssh_filter_profile: "<your_own_value> (source ssh-filter.profile.name)"
ssl-ssh-profile: "<your_own_value> (source firewall.ssl-ssh-profile.name)" ssl_ssh_profile: "<your_own_value> (source firewall.ssl-ssh-profile.name)"
voip-profile: "<your_own_value> (source voip.profile.name)" voip_profile: "<your_own_value> (source voip.profile.name)"
waf-profile: "<your_own_value> (source waf.profile.name)" waf_profile: "<your_own_value> (source waf.profile.name)"
webfilter-profile: "<your_own_value> (source webfilter.profile.name)" webfilter_profile: "<your_own_value> (source webfilter.profile.name)"
''' '''
RETURN = ''' RETURN = '''
@ -216,14 +240,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule 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, fos):
def login(data):
host = data['host'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -231,15 +257,15 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_profile_group_data(json): def filter_firewall_profile_group_data(json):
option_list = ['application-list', 'av-profile', 'dlp-sensor', option_list = ['application_list', 'av_profile', 'dlp_sensor',
'dnsfilter-profile', 'icap-profile', 'ips-sensor', 'dnsfilter_profile', 'icap_profile', 'ips_sensor',
'name', 'profile-protocol-options', 'spamfilter-profile', 'name', 'profile_protocol_options', 'spamfilter_profile',
'ssh-filter-profile', 'ssl-ssh-profile', 'voip-profile', 'ssh_filter_profile', 'ssl_ssh_profile', 'voip_profile',
'waf-profile', 'webfilter-profile'] 'waf_profile', 'webfilter_profile']
dictionary = {} dictionary = {}
for attribute in option_list: for attribute in option_list:
@ -249,62 +275,80 @@ def filter_firewall_profile_group_data(json):
return dictionary 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_profile_group(data, fos): def firewall_profile_group(data, fos):
vdom = data['vdom'] vdom = data['vdom']
state = data['state']
firewall_profile_group_data = data['firewall_profile_group'] firewall_profile_group_data = data['firewall_profile_group']
filtered_data = filter_firewall_profile_group_data(firewall_profile_group_data) filtered_data = underscore_to_hyphen(filter_firewall_profile_group_data(firewall_profile_group_data))
if firewall_profile_group_data['state'] == "present":
if state == "present":
return fos.set('firewall', return fos.set('firewall',
'profile-group', 'profile-group',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
elif firewall_profile_group_data['state'] == "absent": elif state == "absent":
return fos.delete('firewall', return fos.delete('firewall',
'profile-group', 'profile-group',
mkey=filtered_data['name'], mkey=filtered_data['name'],
vdom=vdom) 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): def fortios_firewall(data, fos):
login(data)
methodlist = ['firewall_profile_group'] if data['firewall_profile_group']:
for method in methodlist: resp = firewall_profile_group(data, fos)
if data[method]:
resp = eval(method)(data, fos)
break
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True}, "https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"firewall_profile_group": { "firewall_profile_group": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"state": {"required": True, "type": "str", "application_list": {"required": False, "type": "str"},
"choices": ["present", "absent"]}, "av_profile": {"required": False, "type": "str"},
"application-list": {"required": False, "type": "str"}, "dlp_sensor": {"required": False, "type": "str"},
"av-profile": {"required": False, "type": "str"}, "dnsfilter_profile": {"required": False, "type": "str"},
"dlp-sensor": {"required": False, "type": "str"}, "icap_profile": {"required": False, "type": "str"},
"dnsfilter-profile": {"required": False, "type": "str"}, "ips_sensor": {"required": False, "type": "str"},
"icap-profile": {"required": False, "type": "str"},
"ips-sensor": {"required": False, "type": "str"},
"name": {"required": True, "type": "str"}, "name": {"required": True, "type": "str"},
"profile-protocol-options": {"required": False, "type": "str"}, "profile_protocol_options": {"required": False, "type": "str"},
"spamfilter-profile": {"required": False, "type": "str"}, "spamfilter_profile": {"required": False, "type": "str"},
"ssh-filter-profile": {"required": False, "type": "str"}, "ssh_filter_profile": {"required": False, "type": "str"},
"ssl-ssh-profile": {"required": False, "type": "str"}, "ssl_ssh_profile": {"required": False, "type": "str"},
"voip-profile": {"required": False, "type": "str"}, "voip_profile": {"required": False, "type": "str"},
"waf-profile": {"required": False, "type": "str"}, "waf_profile": {"required": False, "type": "str"},
"webfilter-profile": {"required": False, "type": "str"} "webfilter_profile": {"required": False, "type": "str"}
} }
} }
@ -312,15 +356,30 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos legacy_mode = 'host' in module.params and module.params['host'] is not None and \
fos = FortiOSAPI() '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: if not is_error:
module.exit_json(changed=has_changed, meta=result) module.exit_json(changed=has_changed, meta=result)

@ -3693,42 +3693,7 @@ lib/ansible/modules/network/fortios/fortios_antivirus_quarantine.py validate-mod
lib/ansible/modules/network/fortios/fortios_config.py validate-modules:E337 lib/ansible/modules/network/fortios/fortios_config.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_DoS_policy.py validate-modules:E336 lib/ansible/modules/network/fortios/fortios_firewall_DoS_policy.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_DoS_policy6.py validate-modules:E336 lib/ansible/modules/network/fortios/fortios_firewall_DoS_policy6.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_internet_service_group.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_ip_translation.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_ip_translation.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_ipmacbinding_setting.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_ipmacbinding_table.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_ipmacbinding_table.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_ippool.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_ippool.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_ippool6.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_ipv6_eh_filter.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_ipv6_eh_filter.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_ldb_monitor.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_ldb_monitor.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_local_in_policy.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_local_in_policy.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_local_in_policy6.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_multicast_address.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_multicast_address.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_multicast_address6.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_multicast_policy.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_multicast_policy.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_multicast_policy6.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_multicast_policy6.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_policy.py validate-modules:E326 lib/ansible/modules/network/fortios/fortios_firewall_policy.py validate-modules:E326
lib/ansible/modules/network/fortios/fortios_firewall_policy.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_policy.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_policy46.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_policy46.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_policy6.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_policy6.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_policy64.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_policy64.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_profile_group.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_profile_group.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_profile_protocol_options.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_profile_protocol_options.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_proxy_address.py validate-modules:E336 lib/ansible/modules/network/fortios/fortios_firewall_proxy_address.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_proxy_address.py validate-modules:E337 lib/ansible/modules/network/fortios/fortios_firewall_proxy_address.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_proxy_addrgrp.py validate-modules:E337 lib/ansible/modules/network/fortios/fortios_firewall_proxy_addrgrp.py validate-modules:E337

@ -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_firewall_internet_service_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_internet_service_group.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_internet_service_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_internet_service_group': {
'comment': 'Comment.',
'name': 'default_name_4'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_internet_service_group.fortios_firewall(input_data, fos_instance)
expected_data = {
'comment': 'Comment.',
'name': 'default_name_4'
}
set_method_mock.assert_called_with('firewall', 'internet-service-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_internet_service_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_internet_service_group': {
'comment': 'Comment.',
'name': 'default_name_4'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_internet_service_group.fortios_firewall(input_data, fos_instance)
expected_data = {
'comment': 'Comment.',
'name': 'default_name_4'
}
set_method_mock.assert_called_with('firewall', 'internet-service-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_internet_service_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_internet_service_group': {
'comment': 'Comment.',
'name': 'default_name_4'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_internet_service_group.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'internet-service-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_internet_service_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_internet_service_group': {
'comment': 'Comment.',
'name': 'default_name_4'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_internet_service_group.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'internet-service-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_internet_service_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_internet_service_group': {
'comment': 'Comment.',
'name': 'default_name_4'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_internet_service_group.fortios_firewall(input_data, fos_instance)
expected_data = {
'comment': 'Comment.',
'name': 'default_name_4'
}
set_method_mock.assert_called_with('firewall', 'internet-service-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_internet_service_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_internet_service_group': {
'random_attribute_not_valid': 'tag',
'comment': 'Comment.',
'name': 'default_name_4'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_internet_service_group.fortios_firewall(input_data, fos_instance)
expected_data = {
'comment': 'Comment.',
'name': 'default_name_4'
}
set_method_mock.assert_called_with('firewall', 'internet-service-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,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_ip_translation
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_ip_translation.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_ip_translation_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_ip_translation': {
'endip': 'test_value_3',
'map_startip': 'test_value_4',
'startip': 'test_value_5',
'transid': '6',
'type': 'SCTP'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ip_translation.fortios_firewall(input_data, fos_instance)
expected_data = {
'endip': 'test_value_3',
'map-startip': 'test_value_4',
'startip': 'test_value_5',
'transid': '6',
'type': 'SCTP'
}
set_method_mock.assert_called_with('firewall', 'ip-translation', 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_ip_translation_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_ip_translation': {
'endip': 'test_value_3',
'map_startip': 'test_value_4',
'startip': 'test_value_5',
'transid': '6',
'type': 'SCTP'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ip_translation.fortios_firewall(input_data, fos_instance)
expected_data = {
'endip': 'test_value_3',
'map-startip': 'test_value_4',
'startip': 'test_value_5',
'transid': '6',
'type': 'SCTP'
}
set_method_mock.assert_called_with('firewall', 'ip-translation', 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_ip_translation_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_ip_translation': {
'endip': 'test_value_3',
'map_startip': 'test_value_4',
'startip': 'test_value_5',
'transid': '6',
'type': 'SCTP'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ip_translation.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'ip-translation', 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_ip_translation_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_ip_translation': {
'endip': 'test_value_3',
'map_startip': 'test_value_4',
'startip': 'test_value_5',
'transid': '6',
'type': 'SCTP'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ip_translation.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'ip-translation', 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_ip_translation_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_ip_translation': {
'endip': 'test_value_3',
'map_startip': 'test_value_4',
'startip': 'test_value_5',
'transid': '6',
'type': 'SCTP'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ip_translation.fortios_firewall(input_data, fos_instance)
expected_data = {
'endip': 'test_value_3',
'map-startip': 'test_value_4',
'startip': 'test_value_5',
'transid': '6',
'type': 'SCTP'
}
set_method_mock.assert_called_with('firewall', 'ip-translation', 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_ip_translation_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_ip_translation': {
'random_attribute_not_valid': 'tag',
'endip': 'test_value_3',
'map_startip': 'test_value_4',
'startip': 'test_value_5',
'transid': '6',
'type': 'SCTP'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ip_translation.fortios_firewall(input_data, fos_instance)
expected_data = {
'endip': 'test_value_3',
'map-startip': 'test_value_4',
'startip': 'test_value_5',
'transid': '6',
'type': 'SCTP'
}
set_method_mock.assert_called_with('firewall', 'ip-translation', 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,167 @@
# 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_ipmacbinding_setting
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_firewall_ipmacbinding_setting.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_ipmacbinding_setting_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'firewall_ipmacbinding_setting': {
'bindthroughfw': 'enable',
'bindtofw': 'enable',
'undefinedhost': 'allow'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ipmacbinding_setting.fortios_firewall_ipmacbinding(input_data, fos_instance)
expected_data = {
'bindthroughfw': 'enable',
'bindtofw': 'enable',
'undefinedhost': 'allow'
}
set_method_mock.assert_called_with('firewall.ipmacbinding', 'setting', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_firewall_ipmacbinding_setting_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'firewall_ipmacbinding_setting': {
'bindthroughfw': 'enable',
'bindtofw': 'enable',
'undefinedhost': 'allow'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ipmacbinding_setting.fortios_firewall_ipmacbinding(input_data, fos_instance)
expected_data = {
'bindthroughfw': 'enable',
'bindtofw': 'enable',
'undefinedhost': 'allow'
}
set_method_mock.assert_called_with('firewall.ipmacbinding', 'setting', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_firewall_ipmacbinding_setting_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'firewall_ipmacbinding_setting': {
'bindthroughfw': 'enable',
'bindtofw': 'enable',
'undefinedhost': 'allow'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ipmacbinding_setting.fortios_firewall_ipmacbinding(input_data, fos_instance)
expected_data = {
'bindthroughfw': 'enable',
'bindtofw': 'enable',
'undefinedhost': 'allow'
}
set_method_mock.assert_called_with('firewall.ipmacbinding', 'setting', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_firewall_ipmacbinding_setting_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'firewall_ipmacbinding_setting': {
'random_attribute_not_valid': 'tag',
'bindthroughfw': 'enable',
'bindtofw': 'enable',
'undefinedhost': 'allow'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ipmacbinding_setting.fortios_firewall_ipmacbinding(input_data, fos_instance)
expected_data = {
'bindthroughfw': 'enable',
'bindtofw': 'enable',
'undefinedhost': 'allow'
}
set_method_mock.assert_called_with('firewall.ipmacbinding', 'setting', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,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_ipmacbinding_table
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_ipmacbinding_table.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_ipmacbinding_table_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_ipmacbinding_table': {
'ip': 'test_value_3',
'mac': 'test_value_4',
'name': 'default_name_5',
'seq_num': '6',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ipmacbinding_table.fortios_firewall_ipmacbinding(input_data, fos_instance)
expected_data = {
'ip': 'test_value_3',
'mac': 'test_value_4',
'name': 'default_name_5',
'seq-num': '6',
'status': 'enable'
}
set_method_mock.assert_called_with('firewall.ipmacbinding', 'table', 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_ipmacbinding_table_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_ipmacbinding_table': {
'ip': 'test_value_3',
'mac': 'test_value_4',
'name': 'default_name_5',
'seq_num': '6',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ipmacbinding_table.fortios_firewall_ipmacbinding(input_data, fos_instance)
expected_data = {
'ip': 'test_value_3',
'mac': 'test_value_4',
'name': 'default_name_5',
'seq-num': '6',
'status': 'enable'
}
set_method_mock.assert_called_with('firewall.ipmacbinding', 'table', 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_ipmacbinding_table_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_ipmacbinding_table': {
'ip': 'test_value_3',
'mac': 'test_value_4',
'name': 'default_name_5',
'seq_num': '6',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ipmacbinding_table.fortios_firewall_ipmacbinding(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall.ipmacbinding', 'table', 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_ipmacbinding_table_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_ipmacbinding_table': {
'ip': 'test_value_3',
'mac': 'test_value_4',
'name': 'default_name_5',
'seq_num': '6',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ipmacbinding_table.fortios_firewall_ipmacbinding(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall.ipmacbinding', 'table', 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_ipmacbinding_table_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_ipmacbinding_table': {
'ip': 'test_value_3',
'mac': 'test_value_4',
'name': 'default_name_5',
'seq_num': '6',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ipmacbinding_table.fortios_firewall_ipmacbinding(input_data, fos_instance)
expected_data = {
'ip': 'test_value_3',
'mac': 'test_value_4',
'name': 'default_name_5',
'seq-num': '6',
'status': 'enable'
}
set_method_mock.assert_called_with('firewall.ipmacbinding', 'table', 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_ipmacbinding_table_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_ipmacbinding_table': {
'random_attribute_not_valid': 'tag',
'ip': 'test_value_3',
'mac': 'test_value_4',
'name': 'default_name_5',
'seq_num': '6',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ipmacbinding_table.fortios_firewall_ipmacbinding(input_data, fos_instance)
expected_data = {
'ip': 'test_value_3',
'mac': 'test_value_4',
'name': 'default_name_5',
'seq-num': '6',
'status': 'enable'
}
set_method_mock.assert_called_with('firewall.ipmacbinding', 'table', 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_firewall_ippool
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_ippool.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_ippool_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_ippool': {
'arp_intf': 'test_value_3',
'arp_reply': 'disable',
'associated_interface': 'test_value_5',
'block_size': '6',
'comments': 'test_value_7',
'endip': 'test_value_8',
'name': 'default_name_9',
'num_blocks_per_user': '10',
'pba_timeout': '11',
'permit_any_host': 'disable',
'source_endip': 'test_value_13',
'source_startip': 'test_value_14',
'startip': 'test_value_15',
'type': 'overload'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ippool.fortios_firewall(input_data, fos_instance)
expected_data = {
'arp-intf': 'test_value_3',
'arp-reply': 'disable',
'associated-interface': 'test_value_5',
'block-size': '6',
'comments': 'test_value_7',
'endip': 'test_value_8',
'name': 'default_name_9',
'num-blocks-per-user': '10',
'pba-timeout': '11',
'permit-any-host': 'disable',
'source-endip': 'test_value_13',
'source-startip': 'test_value_14',
'startip': 'test_value_15',
'type': 'overload'
}
set_method_mock.assert_called_with('firewall', 'ippool', 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_ippool_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_ippool': {
'arp_intf': 'test_value_3',
'arp_reply': 'disable',
'associated_interface': 'test_value_5',
'block_size': '6',
'comments': 'test_value_7',
'endip': 'test_value_8',
'name': 'default_name_9',
'num_blocks_per_user': '10',
'pba_timeout': '11',
'permit_any_host': 'disable',
'source_endip': 'test_value_13',
'source_startip': 'test_value_14',
'startip': 'test_value_15',
'type': 'overload'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ippool.fortios_firewall(input_data, fos_instance)
expected_data = {
'arp-intf': 'test_value_3',
'arp-reply': 'disable',
'associated-interface': 'test_value_5',
'block-size': '6',
'comments': 'test_value_7',
'endip': 'test_value_8',
'name': 'default_name_9',
'num-blocks-per-user': '10',
'pba-timeout': '11',
'permit-any-host': 'disable',
'source-endip': 'test_value_13',
'source-startip': 'test_value_14',
'startip': 'test_value_15',
'type': 'overload'
}
set_method_mock.assert_called_with('firewall', 'ippool', 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_ippool_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_ippool': {
'arp_intf': 'test_value_3',
'arp_reply': 'disable',
'associated_interface': 'test_value_5',
'block_size': '6',
'comments': 'test_value_7',
'endip': 'test_value_8',
'name': 'default_name_9',
'num_blocks_per_user': '10',
'pba_timeout': '11',
'permit_any_host': 'disable',
'source_endip': 'test_value_13',
'source_startip': 'test_value_14',
'startip': 'test_value_15',
'type': 'overload'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ippool.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'ippool', 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_ippool_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_ippool': {
'arp_intf': 'test_value_3',
'arp_reply': 'disable',
'associated_interface': 'test_value_5',
'block_size': '6',
'comments': 'test_value_7',
'endip': 'test_value_8',
'name': 'default_name_9',
'num_blocks_per_user': '10',
'pba_timeout': '11',
'permit_any_host': 'disable',
'source_endip': 'test_value_13',
'source_startip': 'test_value_14',
'startip': 'test_value_15',
'type': 'overload'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ippool.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'ippool', 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_ippool_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_ippool': {
'arp_intf': 'test_value_3',
'arp_reply': 'disable',
'associated_interface': 'test_value_5',
'block_size': '6',
'comments': 'test_value_7',
'endip': 'test_value_8',
'name': 'default_name_9',
'num_blocks_per_user': '10',
'pba_timeout': '11',
'permit_any_host': 'disable',
'source_endip': 'test_value_13',
'source_startip': 'test_value_14',
'startip': 'test_value_15',
'type': 'overload'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ippool.fortios_firewall(input_data, fos_instance)
expected_data = {
'arp-intf': 'test_value_3',
'arp-reply': 'disable',
'associated-interface': 'test_value_5',
'block-size': '6',
'comments': 'test_value_7',
'endip': 'test_value_8',
'name': 'default_name_9',
'num-blocks-per-user': '10',
'pba-timeout': '11',
'permit-any-host': 'disable',
'source-endip': 'test_value_13',
'source-startip': 'test_value_14',
'startip': 'test_value_15',
'type': 'overload'
}
set_method_mock.assert_called_with('firewall', 'ippool', 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_ippool_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_ippool': {
'random_attribute_not_valid': 'tag',
'arp_intf': 'test_value_3',
'arp_reply': 'disable',
'associated_interface': 'test_value_5',
'block_size': '6',
'comments': 'test_value_7',
'endip': 'test_value_8',
'name': 'default_name_9',
'num_blocks_per_user': '10',
'pba_timeout': '11',
'permit_any_host': 'disable',
'source_endip': 'test_value_13',
'source_startip': 'test_value_14',
'startip': 'test_value_15',
'type': 'overload'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ippool.fortios_firewall(input_data, fos_instance)
expected_data = {
'arp-intf': 'test_value_3',
'arp-reply': 'disable',
'associated-interface': 'test_value_5',
'block-size': '6',
'comments': 'test_value_7',
'endip': 'test_value_8',
'name': 'default_name_9',
'num-blocks-per-user': '10',
'pba-timeout': '11',
'permit-any-host': 'disable',
'source-endip': 'test_value_13',
'source-startip': 'test_value_14',
'startip': 'test_value_15',
'type': 'overload'
}
set_method_mock.assert_called_with('firewall', 'ippool', 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_ippool6
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_ippool6.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_ippool6_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_ippool6': {
'comments': 'test_value_3',
'endip': 'test_value_4',
'name': 'default_name_5',
'startip': 'test_value_6'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ippool6.fortios_firewall(input_data, fos_instance)
expected_data = {
'comments': 'test_value_3',
'endip': 'test_value_4',
'name': 'default_name_5',
'startip': 'test_value_6'
}
set_method_mock.assert_called_with('firewall', 'ippool6', 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_ippool6_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_ippool6': {
'comments': 'test_value_3',
'endip': 'test_value_4',
'name': 'default_name_5',
'startip': 'test_value_6'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ippool6.fortios_firewall(input_data, fos_instance)
expected_data = {
'comments': 'test_value_3',
'endip': 'test_value_4',
'name': 'default_name_5',
'startip': 'test_value_6'
}
set_method_mock.assert_called_with('firewall', 'ippool6', 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_ippool6_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_ippool6': {
'comments': 'test_value_3',
'endip': 'test_value_4',
'name': 'default_name_5',
'startip': 'test_value_6'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ippool6.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'ippool6', 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_ippool6_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_ippool6': {
'comments': 'test_value_3',
'endip': 'test_value_4',
'name': 'default_name_5',
'startip': 'test_value_6'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ippool6.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'ippool6', 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_ippool6_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_ippool6': {
'comments': 'test_value_3',
'endip': 'test_value_4',
'name': 'default_name_5',
'startip': 'test_value_6'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ippool6.fortios_firewall(input_data, fos_instance)
expected_data = {
'comments': 'test_value_3',
'endip': 'test_value_4',
'name': 'default_name_5',
'startip': 'test_value_6'
}
set_method_mock.assert_called_with('firewall', 'ippool6', 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_ippool6_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_ippool6': {
'random_attribute_not_valid': 'tag',
'comments': 'test_value_3',
'endip': 'test_value_4',
'name': 'default_name_5',
'startip': 'test_value_6'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ippool6.fortios_firewall(input_data, fos_instance)
expected_data = {
'comments': 'test_value_3',
'endip': 'test_value_4',
'name': 'default_name_5',
'startip': 'test_value_6'
}
set_method_mock.assert_called_with('firewall', 'ippool6', 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,207 @@
# 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_ipv6_eh_filter
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_ipv6_eh_filter.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_ipv6_eh_filter_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_ipv6_eh_filter': {
'auth': 'enable',
'dest_opt': 'enable',
'fragment': 'enable',
'hdopt_type': '6',
'hop_opt': 'enable',
'no_next': 'enable',
'routing': 'enable',
'routing_type': '10'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ipv6_eh_filter.fortios_firewall(input_data, fos_instance)
expected_data = {
'auth': 'enable',
'dest-opt': 'enable',
'fragment': 'enable',
'hdopt-type': '6',
'hop-opt': 'enable',
'no-next': 'enable',
'routing': 'enable',
'routing-type': '10'
}
set_method_mock.assert_called_with('firewall', 'ipv6-eh-filter', 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_ipv6_eh_filter_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_ipv6_eh_filter': {
'auth': 'enable',
'dest_opt': 'enable',
'fragment': 'enable',
'hdopt_type': '6',
'hop_opt': 'enable',
'no_next': 'enable',
'routing': 'enable',
'routing_type': '10'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ipv6_eh_filter.fortios_firewall(input_data, fos_instance)
expected_data = {
'auth': 'enable',
'dest-opt': 'enable',
'fragment': 'enable',
'hdopt-type': '6',
'hop-opt': 'enable',
'no-next': 'enable',
'routing': 'enable',
'routing-type': '10'
}
set_method_mock.assert_called_with('firewall', 'ipv6-eh-filter', 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_ipv6_eh_filter_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_ipv6_eh_filter': {
'auth': 'enable',
'dest_opt': 'enable',
'fragment': 'enable',
'hdopt_type': '6',
'hop_opt': 'enable',
'no_next': 'enable',
'routing': 'enable',
'routing_type': '10'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ipv6_eh_filter.fortios_firewall(input_data, fos_instance)
expected_data = {
'auth': 'enable',
'dest-opt': 'enable',
'fragment': 'enable',
'hdopt-type': '6',
'hop-opt': 'enable',
'no-next': 'enable',
'routing': 'enable',
'routing-type': '10'
}
set_method_mock.assert_called_with('firewall', 'ipv6-eh-filter', 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_ipv6_eh_filter_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_ipv6_eh_filter': {
'random_attribute_not_valid': 'tag',
'auth': 'enable',
'dest_opt': 'enable',
'fragment': 'enable',
'hdopt_type': '6',
'hop_opt': 'enable',
'no_next': 'enable',
'routing': 'enable',
'routing_type': '10'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ipv6_eh_filter.fortios_firewall(input_data, fos_instance)
expected_data = {
'auth': 'enable',
'dest-opt': 'enable',
'fragment': 'enable',
'hdopt-type': '6',
'hop-opt': 'enable',
'no-next': 'enable',
'routing': 'enable',
'routing-type': '10'
}
set_method_mock.assert_called_with('firewall', 'ipv6-eh-filter', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,279 @@
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_firewall_ldb_monitor
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_ldb_monitor.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_ldb_monitor_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_ldb_monitor': {
'http_get': 'test_value_3',
'http_match': 'test_value_4',
'http_max_redirects': '5',
'interval': '6',
'name': 'default_name_7',
'port': '8',
'retry': '9',
'timeout': '10',
'type': 'ping'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ldb_monitor.fortios_firewall(input_data, fos_instance)
expected_data = {
'http-get': 'test_value_3',
'http-match': 'test_value_4',
'http-max-redirects': '5',
'interval': '6',
'name': 'default_name_7',
'port': '8',
'retry': '9',
'timeout': '10',
'type': 'ping'
}
set_method_mock.assert_called_with('firewall', 'ldb-monitor', 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_ldb_monitor_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_ldb_monitor': {
'http_get': 'test_value_3',
'http_match': 'test_value_4',
'http_max_redirects': '5',
'interval': '6',
'name': 'default_name_7',
'port': '8',
'retry': '9',
'timeout': '10',
'type': 'ping'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ldb_monitor.fortios_firewall(input_data, fos_instance)
expected_data = {
'http-get': 'test_value_3',
'http-match': 'test_value_4',
'http-max-redirects': '5',
'interval': '6',
'name': 'default_name_7',
'port': '8',
'retry': '9',
'timeout': '10',
'type': 'ping'
}
set_method_mock.assert_called_with('firewall', 'ldb-monitor', 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_ldb_monitor_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_ldb_monitor': {
'http_get': 'test_value_3',
'http_match': 'test_value_4',
'http_max_redirects': '5',
'interval': '6',
'name': 'default_name_7',
'port': '8',
'retry': '9',
'timeout': '10',
'type': 'ping'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ldb_monitor.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'ldb-monitor', 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_ldb_monitor_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_ldb_monitor': {
'http_get': 'test_value_3',
'http_match': 'test_value_4',
'http_max_redirects': '5',
'interval': '6',
'name': 'default_name_7',
'port': '8',
'retry': '9',
'timeout': '10',
'type': 'ping'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ldb_monitor.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'ldb-monitor', 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_ldb_monitor_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_ldb_monitor': {
'http_get': 'test_value_3',
'http_match': 'test_value_4',
'http_max_redirects': '5',
'interval': '6',
'name': 'default_name_7',
'port': '8',
'retry': '9',
'timeout': '10',
'type': 'ping'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ldb_monitor.fortios_firewall(input_data, fos_instance)
expected_data = {
'http-get': 'test_value_3',
'http-match': 'test_value_4',
'http-max-redirects': '5',
'interval': '6',
'name': 'default_name_7',
'port': '8',
'retry': '9',
'timeout': '10',
'type': 'ping'
}
set_method_mock.assert_called_with('firewall', 'ldb-monitor', 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_ldb_monitor_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_ldb_monitor': {
'random_attribute_not_valid': 'tag',
'http_get': 'test_value_3',
'http_match': 'test_value_4',
'http_max_redirects': '5',
'interval': '6',
'name': 'default_name_7',
'port': '8',
'retry': '9',
'timeout': '10',
'type': 'ping'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ldb_monitor.fortios_firewall(input_data, fos_instance)
expected_data = {
'http-get': 'test_value_3',
'http-match': 'test_value_4',
'http-max-redirects': '5',
'interval': '6',
'name': 'default_name_7',
'port': '8',
'retry': '9',
'timeout': '10',
'type': 'ping'
}
set_method_mock.assert_called_with('firewall', 'ldb-monitor', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,259 @@
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_firewall_local_in_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_local_in_policy.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_local_in_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_local_in_policy': {
'action': 'accept',
'comments': 'test_value_4',
'ha_mgmt_intf_only': 'enable',
'intf': 'test_value_6',
'policyid': '7',
'schedule': 'test_value_8',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_local_in_policy.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'comments': 'test_value_4',
'ha-mgmt-intf-only': 'enable',
'intf': 'test_value_6',
'policyid': '7',
'schedule': 'test_value_8',
'status': 'enable'
}
set_method_mock.assert_called_with('firewall', 'local-in-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_local_in_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_local_in_policy': {
'action': 'accept',
'comments': 'test_value_4',
'ha_mgmt_intf_only': 'enable',
'intf': 'test_value_6',
'policyid': '7',
'schedule': 'test_value_8',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_local_in_policy.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'comments': 'test_value_4',
'ha-mgmt-intf-only': 'enable',
'intf': 'test_value_6',
'policyid': '7',
'schedule': 'test_value_8',
'status': 'enable'
}
set_method_mock.assert_called_with('firewall', 'local-in-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_local_in_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_local_in_policy': {
'action': 'accept',
'comments': 'test_value_4',
'ha_mgmt_intf_only': 'enable',
'intf': 'test_value_6',
'policyid': '7',
'schedule': 'test_value_8',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_local_in_policy.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'local-in-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_local_in_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_local_in_policy': {
'action': 'accept',
'comments': 'test_value_4',
'ha_mgmt_intf_only': 'enable',
'intf': 'test_value_6',
'policyid': '7',
'schedule': 'test_value_8',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_local_in_policy.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'local-in-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_local_in_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_local_in_policy': {
'action': 'accept',
'comments': 'test_value_4',
'ha_mgmt_intf_only': 'enable',
'intf': 'test_value_6',
'policyid': '7',
'schedule': 'test_value_8',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_local_in_policy.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'comments': 'test_value_4',
'ha-mgmt-intf-only': 'enable',
'intf': 'test_value_6',
'policyid': '7',
'schedule': 'test_value_8',
'status': 'enable'
}
set_method_mock.assert_called_with('firewall', 'local-in-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_local_in_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_local_in_policy': {
'random_attribute_not_valid': 'tag',
'action': 'accept',
'comments': 'test_value_4',
'ha_mgmt_intf_only': 'enable',
'intf': 'test_value_6',
'policyid': '7',
'schedule': 'test_value_8',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_local_in_policy.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'comments': 'test_value_4',
'ha-mgmt-intf-only': 'enable',
'intf': 'test_value_6',
'policyid': '7',
'schedule': 'test_value_8',
'status': 'enable'
}
set_method_mock.assert_called_with('firewall', 'local-in-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,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_local_in_policy6
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_local_in_policy6.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_local_in_policy6_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_local_in_policy6': {
'action': 'accept',
'comments': 'test_value_4',
'intf': 'test_value_5',
'policyid': '6',
'schedule': 'test_value_7',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_local_in_policy6.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'comments': 'test_value_4',
'intf': 'test_value_5',
'policyid': '6',
'schedule': 'test_value_7',
'status': 'enable'
}
set_method_mock.assert_called_with('firewall', 'local-in-policy6', 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_local_in_policy6_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_local_in_policy6': {
'action': 'accept',
'comments': 'test_value_4',
'intf': 'test_value_5',
'policyid': '6',
'schedule': 'test_value_7',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_local_in_policy6.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'comments': 'test_value_4',
'intf': 'test_value_5',
'policyid': '6',
'schedule': 'test_value_7',
'status': 'enable'
}
set_method_mock.assert_called_with('firewall', 'local-in-policy6', 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_local_in_policy6_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_local_in_policy6': {
'action': 'accept',
'comments': 'test_value_4',
'intf': 'test_value_5',
'policyid': '6',
'schedule': 'test_value_7',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_local_in_policy6.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'local-in-policy6', 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_local_in_policy6_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_local_in_policy6': {
'action': 'accept',
'comments': 'test_value_4',
'intf': 'test_value_5',
'policyid': '6',
'schedule': 'test_value_7',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_local_in_policy6.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'local-in-policy6', 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_local_in_policy6_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_local_in_policy6': {
'action': 'accept',
'comments': 'test_value_4',
'intf': 'test_value_5',
'policyid': '6',
'schedule': 'test_value_7',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_local_in_policy6.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'comments': 'test_value_4',
'intf': 'test_value_5',
'policyid': '6',
'schedule': 'test_value_7',
'status': 'enable'
}
set_method_mock.assert_called_with('firewall', 'local-in-policy6', 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_local_in_policy6_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_local_in_policy6': {
'random_attribute_not_valid': 'tag',
'action': 'accept',
'comments': 'test_value_4',
'intf': 'test_value_5',
'policyid': '6',
'schedule': 'test_value_7',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_local_in_policy6.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'comments': 'test_value_4',
'intf': 'test_value_5',
'policyid': '6',
'schedule': 'test_value_7',
'status': 'enable'
}
set_method_mock.assert_called_with('firewall', 'local-in-policy6', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,279 @@
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_firewall_multicast_address
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_multicast_address.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_multicast_address_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_multicast_address': {
'associated_interface': 'test_value_3',
'color': '4',
'comment': 'Comment.',
'end_ip': 'test_value_6',
'name': 'default_name_7',
'start_ip': 'test_value_8',
'subnet': 'test_value_9',
'type': 'multicastrange',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_multicast_address.fortios_firewall(input_data, fos_instance)
expected_data = {
'associated-interface': 'test_value_3',
'color': '4',
'comment': 'Comment.',
'end-ip': 'test_value_6',
'name': 'default_name_7',
'start-ip': 'test_value_8',
'subnet': 'test_value_9',
'type': 'multicastrange',
'visibility': 'enable'
}
set_method_mock.assert_called_with('firewall', 'multicast-address', 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_multicast_address_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_multicast_address': {
'associated_interface': 'test_value_3',
'color': '4',
'comment': 'Comment.',
'end_ip': 'test_value_6',
'name': 'default_name_7',
'start_ip': 'test_value_8',
'subnet': 'test_value_9',
'type': 'multicastrange',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_multicast_address.fortios_firewall(input_data, fos_instance)
expected_data = {
'associated-interface': 'test_value_3',
'color': '4',
'comment': 'Comment.',
'end-ip': 'test_value_6',
'name': 'default_name_7',
'start-ip': 'test_value_8',
'subnet': 'test_value_9',
'type': 'multicastrange',
'visibility': 'enable'
}
set_method_mock.assert_called_with('firewall', 'multicast-address', 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_multicast_address_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_multicast_address': {
'associated_interface': 'test_value_3',
'color': '4',
'comment': 'Comment.',
'end_ip': 'test_value_6',
'name': 'default_name_7',
'start_ip': 'test_value_8',
'subnet': 'test_value_9',
'type': 'multicastrange',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_multicast_address.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'multicast-address', 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_multicast_address_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_multicast_address': {
'associated_interface': 'test_value_3',
'color': '4',
'comment': 'Comment.',
'end_ip': 'test_value_6',
'name': 'default_name_7',
'start_ip': 'test_value_8',
'subnet': 'test_value_9',
'type': 'multicastrange',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_multicast_address.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'multicast-address', 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_multicast_address_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_multicast_address': {
'associated_interface': 'test_value_3',
'color': '4',
'comment': 'Comment.',
'end_ip': 'test_value_6',
'name': 'default_name_7',
'start_ip': 'test_value_8',
'subnet': 'test_value_9',
'type': 'multicastrange',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_multicast_address.fortios_firewall(input_data, fos_instance)
expected_data = {
'associated-interface': 'test_value_3',
'color': '4',
'comment': 'Comment.',
'end-ip': 'test_value_6',
'name': 'default_name_7',
'start-ip': 'test_value_8',
'subnet': 'test_value_9',
'type': 'multicastrange',
'visibility': 'enable'
}
set_method_mock.assert_called_with('firewall', 'multicast-address', 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_multicast_address_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_multicast_address': {
'random_attribute_not_valid': 'tag',
'associated_interface': 'test_value_3',
'color': '4',
'comment': 'Comment.',
'end_ip': 'test_value_6',
'name': 'default_name_7',
'start_ip': 'test_value_8',
'subnet': 'test_value_9',
'type': 'multicastrange',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_multicast_address.fortios_firewall(input_data, fos_instance)
expected_data = {
'associated-interface': 'test_value_3',
'color': '4',
'comment': 'Comment.',
'end-ip': 'test_value_6',
'name': 'default_name_7',
'start-ip': 'test_value_8',
'subnet': 'test_value_9',
'type': 'multicastrange',
'visibility': 'enable'
}
set_method_mock.assert_called_with('firewall', 'multicast-address', 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_multicast_address6
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_multicast_address6.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_multicast_address6_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_multicast_address6': {
'color': '3',
'comment': 'Comment.',
'ip6': 'test_value_5',
'name': 'default_name_6',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_multicast_address6.fortios_firewall(input_data, fos_instance)
expected_data = {
'color': '3',
'comment': 'Comment.',
'ip6': 'test_value_5',
'name': 'default_name_6',
'visibility': 'enable'
}
set_method_mock.assert_called_with('firewall', 'multicast-address6', 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_multicast_address6_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_multicast_address6': {
'color': '3',
'comment': 'Comment.',
'ip6': 'test_value_5',
'name': 'default_name_6',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_multicast_address6.fortios_firewall(input_data, fos_instance)
expected_data = {
'color': '3',
'comment': 'Comment.',
'ip6': 'test_value_5',
'name': 'default_name_6',
'visibility': 'enable'
}
set_method_mock.assert_called_with('firewall', 'multicast-address6', 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_multicast_address6_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_multicast_address6': {
'color': '3',
'comment': 'Comment.',
'ip6': 'test_value_5',
'name': 'default_name_6',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_multicast_address6.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'multicast-address6', 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_multicast_address6_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_multicast_address6': {
'color': '3',
'comment': 'Comment.',
'ip6': 'test_value_5',
'name': 'default_name_6',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_multicast_address6.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'multicast-address6', 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_multicast_address6_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_multicast_address6': {
'color': '3',
'comment': 'Comment.',
'ip6': 'test_value_5',
'name': 'default_name_6',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_multicast_address6.fortios_firewall(input_data, fos_instance)
expected_data = {
'color': '3',
'comment': 'Comment.',
'ip6': 'test_value_5',
'name': 'default_name_6',
'visibility': 'enable'
}
set_method_mock.assert_called_with('firewall', 'multicast-address6', 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_multicast_address6_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_multicast_address6': {
'random_attribute_not_valid': 'tag',
'color': '3',
'comment': 'Comment.',
'ip6': 'test_value_5',
'name': 'default_name_6',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_multicast_address6.fortios_firewall(input_data, fos_instance)
expected_data = {
'color': '3',
'comment': 'Comment.',
'ip6': 'test_value_5',
'name': 'default_name_6',
'visibility': 'enable'
}
set_method_mock.assert_called_with('firewall', 'multicast-address6', 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_firewall_multicast_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_multicast_policy.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_multicast_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_multicast_policy': {
'action': 'accept',
'dnat': 'test_value_4',
'dstintf': 'test_value_5',
'end_port': '6',
'id': '7',
'logtraffic': 'enable',
'protocol': '9',
'snat': 'enable',
'snat_ip': 'test_value_11',
'srcintf': 'test_value_12',
'start_port': '13',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_multicast_policy.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'dnat': 'test_value_4',
'dstintf': 'test_value_5',
'end-port': '6',
'id': '7',
'logtraffic': 'enable',
'protocol': '9',
'snat': 'enable',
'snat-ip': 'test_value_11',
'srcintf': 'test_value_12',
'start-port': '13',
'status': 'enable'
}
set_method_mock.assert_called_with('firewall', 'multicast-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_multicast_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_multicast_policy': {
'action': 'accept',
'dnat': 'test_value_4',
'dstintf': 'test_value_5',
'end_port': '6',
'id': '7',
'logtraffic': 'enable',
'protocol': '9',
'snat': 'enable',
'snat_ip': 'test_value_11',
'srcintf': 'test_value_12',
'start_port': '13',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_multicast_policy.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'dnat': 'test_value_4',
'dstintf': 'test_value_5',
'end-port': '6',
'id': '7',
'logtraffic': 'enable',
'protocol': '9',
'snat': 'enable',
'snat-ip': 'test_value_11',
'srcintf': 'test_value_12',
'start-port': '13',
'status': 'enable'
}
set_method_mock.assert_called_with('firewall', 'multicast-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_multicast_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_multicast_policy': {
'action': 'accept',
'dnat': 'test_value_4',
'dstintf': 'test_value_5',
'end_port': '6',
'id': '7',
'logtraffic': 'enable',
'protocol': '9',
'snat': 'enable',
'snat_ip': 'test_value_11',
'srcintf': 'test_value_12',
'start_port': '13',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_multicast_policy.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'multicast-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_multicast_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_multicast_policy': {
'action': 'accept',
'dnat': 'test_value_4',
'dstintf': 'test_value_5',
'end_port': '6',
'id': '7',
'logtraffic': 'enable',
'protocol': '9',
'snat': 'enable',
'snat_ip': 'test_value_11',
'srcintf': 'test_value_12',
'start_port': '13',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_multicast_policy.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'multicast-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_multicast_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_multicast_policy': {
'action': 'accept',
'dnat': 'test_value_4',
'dstintf': 'test_value_5',
'end_port': '6',
'id': '7',
'logtraffic': 'enable',
'protocol': '9',
'snat': 'enable',
'snat_ip': 'test_value_11',
'srcintf': 'test_value_12',
'start_port': '13',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_multicast_policy.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'dnat': 'test_value_4',
'dstintf': 'test_value_5',
'end-port': '6',
'id': '7',
'logtraffic': 'enable',
'protocol': '9',
'snat': 'enable',
'snat-ip': 'test_value_11',
'srcintf': 'test_value_12',
'start-port': '13',
'status': 'enable'
}
set_method_mock.assert_called_with('firewall', 'multicast-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_multicast_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_multicast_policy': {
'random_attribute_not_valid': 'tag',
'action': 'accept',
'dnat': 'test_value_4',
'dstintf': 'test_value_5',
'end_port': '6',
'id': '7',
'logtraffic': 'enable',
'protocol': '9',
'snat': 'enable',
'snat_ip': 'test_value_11',
'srcintf': 'test_value_12',
'start_port': '13',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_multicast_policy.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'dnat': 'test_value_4',
'dstintf': 'test_value_5',
'end-port': '6',
'id': '7',
'logtraffic': 'enable',
'protocol': '9',
'snat': 'enable',
'snat-ip': 'test_value_11',
'srcintf': 'test_value_12',
'start-port': '13',
'status': 'enable'
}
set_method_mock.assert_called_with('firewall', 'multicast-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,279 @@
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_firewall_multicast_policy6
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_multicast_policy6.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_multicast_policy6_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_multicast_policy6': {
'action': 'accept',
'dstintf': 'test_value_4',
'end_port': '5',
'id': '6',
'logtraffic': 'enable',
'protocol': '8',
'srcintf': 'test_value_9',
'start_port': '10',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_multicast_policy6.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'dstintf': 'test_value_4',
'end-port': '5',
'id': '6',
'logtraffic': 'enable',
'protocol': '8',
'srcintf': 'test_value_9',
'start-port': '10',
'status': 'enable'
}
set_method_mock.assert_called_with('firewall', 'multicast-policy6', 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_multicast_policy6_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_multicast_policy6': {
'action': 'accept',
'dstintf': 'test_value_4',
'end_port': '5',
'id': '6',
'logtraffic': 'enable',
'protocol': '8',
'srcintf': 'test_value_9',
'start_port': '10',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_multicast_policy6.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'dstintf': 'test_value_4',
'end-port': '5',
'id': '6',
'logtraffic': 'enable',
'protocol': '8',
'srcintf': 'test_value_9',
'start-port': '10',
'status': 'enable'
}
set_method_mock.assert_called_with('firewall', 'multicast-policy6', 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_multicast_policy6_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_multicast_policy6': {
'action': 'accept',
'dstintf': 'test_value_4',
'end_port': '5',
'id': '6',
'logtraffic': 'enable',
'protocol': '8',
'srcintf': 'test_value_9',
'start_port': '10',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_multicast_policy6.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'multicast-policy6', 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_multicast_policy6_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_multicast_policy6': {
'action': 'accept',
'dstintf': 'test_value_4',
'end_port': '5',
'id': '6',
'logtraffic': 'enable',
'protocol': '8',
'srcintf': 'test_value_9',
'start_port': '10',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_multicast_policy6.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'multicast-policy6', 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_multicast_policy6_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_multicast_policy6': {
'action': 'accept',
'dstintf': 'test_value_4',
'end_port': '5',
'id': '6',
'logtraffic': 'enable',
'protocol': '8',
'srcintf': 'test_value_9',
'start_port': '10',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_multicast_policy6.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'dstintf': 'test_value_4',
'end-port': '5',
'id': '6',
'logtraffic': 'enable',
'protocol': '8',
'srcintf': 'test_value_9',
'start-port': '10',
'status': 'enable'
}
set_method_mock.assert_called_with('firewall', 'multicast-policy6', 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_multicast_policy6_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_multicast_policy6': {
'random_attribute_not_valid': 'tag',
'action': 'accept',
'dstintf': 'test_value_4',
'end_port': '5',
'id': '6',
'logtraffic': 'enable',
'protocol': '8',
'srcintf': 'test_value_9',
'start_port': '10',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_multicast_policy6.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'dstintf': 'test_value_4',
'end-port': '5',
'id': '6',
'logtraffic': 'enable',
'protocol': '8',
'srcintf': 'test_value_9',
'start-port': '10',
'status': 'enable'
}
set_method_mock.assert_called_with('firewall', 'multicast-policy6', 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,359 @@
# 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_policy46
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_policy46.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_policy46_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_policy46': {
'action': 'accept',
'comments': 'test_value_4',
'dstintf': 'test_value_5',
'fixedport': 'enable',
'ippool': 'enable',
'logtraffic': 'enable',
'per_ip_shaper': 'test_value_9',
'permit_any_host': 'enable',
'policyid': '11',
'schedule': 'test_value_12',
'srcintf': 'test_value_13',
'status': 'enable',
'tcp_mss_receiver': '15',
'tcp_mss_sender': '16',
'traffic_shaper': 'test_value_17',
'traffic_shaper_reverse': 'test_value_18',
'uuid': 'test_value_19'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_policy46.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'comments': 'test_value_4',
'dstintf': 'test_value_5',
'fixedport': 'enable',
'ippool': 'enable',
'logtraffic': 'enable',
'per-ip-shaper': 'test_value_9',
'permit-any-host': 'enable',
'policyid': '11',
'schedule': 'test_value_12',
'srcintf': 'test_value_13',
'status': 'enable',
'tcp-mss-receiver': '15',
'tcp-mss-sender': '16',
'traffic-shaper': 'test_value_17',
'traffic-shaper-reverse': 'test_value_18',
'uuid': 'test_value_19'
}
set_method_mock.assert_called_with('firewall', 'policy46', 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_policy46_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_policy46': {
'action': 'accept',
'comments': 'test_value_4',
'dstintf': 'test_value_5',
'fixedport': 'enable',
'ippool': 'enable',
'logtraffic': 'enable',
'per_ip_shaper': 'test_value_9',
'permit_any_host': 'enable',
'policyid': '11',
'schedule': 'test_value_12',
'srcintf': 'test_value_13',
'status': 'enable',
'tcp_mss_receiver': '15',
'tcp_mss_sender': '16',
'traffic_shaper': 'test_value_17',
'traffic_shaper_reverse': 'test_value_18',
'uuid': 'test_value_19'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_policy46.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'comments': 'test_value_4',
'dstintf': 'test_value_5',
'fixedport': 'enable',
'ippool': 'enable',
'logtraffic': 'enable',
'per-ip-shaper': 'test_value_9',
'permit-any-host': 'enable',
'policyid': '11',
'schedule': 'test_value_12',
'srcintf': 'test_value_13',
'status': 'enable',
'tcp-mss-receiver': '15',
'tcp-mss-sender': '16',
'traffic-shaper': 'test_value_17',
'traffic-shaper-reverse': 'test_value_18',
'uuid': 'test_value_19'
}
set_method_mock.assert_called_with('firewall', 'policy46', 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_policy46_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_policy46': {
'action': 'accept',
'comments': 'test_value_4',
'dstintf': 'test_value_5',
'fixedport': 'enable',
'ippool': 'enable',
'logtraffic': 'enable',
'per_ip_shaper': 'test_value_9',
'permit_any_host': 'enable',
'policyid': '11',
'schedule': 'test_value_12',
'srcintf': 'test_value_13',
'status': 'enable',
'tcp_mss_receiver': '15',
'tcp_mss_sender': '16',
'traffic_shaper': 'test_value_17',
'traffic_shaper_reverse': 'test_value_18',
'uuid': 'test_value_19'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_policy46.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'policy46', 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_policy46_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_policy46': {
'action': 'accept',
'comments': 'test_value_4',
'dstintf': 'test_value_5',
'fixedport': 'enable',
'ippool': 'enable',
'logtraffic': 'enable',
'per_ip_shaper': 'test_value_9',
'permit_any_host': 'enable',
'policyid': '11',
'schedule': 'test_value_12',
'srcintf': 'test_value_13',
'status': 'enable',
'tcp_mss_receiver': '15',
'tcp_mss_sender': '16',
'traffic_shaper': 'test_value_17',
'traffic_shaper_reverse': 'test_value_18',
'uuid': 'test_value_19'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_policy46.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'policy46', 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_policy46_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_policy46': {
'action': 'accept',
'comments': 'test_value_4',
'dstintf': 'test_value_5',
'fixedport': 'enable',
'ippool': 'enable',
'logtraffic': 'enable',
'per_ip_shaper': 'test_value_9',
'permit_any_host': 'enable',
'policyid': '11',
'schedule': 'test_value_12',
'srcintf': 'test_value_13',
'status': 'enable',
'tcp_mss_receiver': '15',
'tcp_mss_sender': '16',
'traffic_shaper': 'test_value_17',
'traffic_shaper_reverse': 'test_value_18',
'uuid': 'test_value_19'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_policy46.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'comments': 'test_value_4',
'dstintf': 'test_value_5',
'fixedport': 'enable',
'ippool': 'enable',
'logtraffic': 'enable',
'per-ip-shaper': 'test_value_9',
'permit-any-host': 'enable',
'policyid': '11',
'schedule': 'test_value_12',
'srcintf': 'test_value_13',
'status': 'enable',
'tcp-mss-receiver': '15',
'tcp-mss-sender': '16',
'traffic-shaper': 'test_value_17',
'traffic-shaper-reverse': 'test_value_18',
'uuid': 'test_value_19'
}
set_method_mock.assert_called_with('firewall', 'policy46', 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_policy46_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_policy46': {
'random_attribute_not_valid': 'tag',
'action': 'accept',
'comments': 'test_value_4',
'dstintf': 'test_value_5',
'fixedport': 'enable',
'ippool': 'enable',
'logtraffic': 'enable',
'per_ip_shaper': 'test_value_9',
'permit_any_host': 'enable',
'policyid': '11',
'schedule': 'test_value_12',
'srcintf': 'test_value_13',
'status': 'enable',
'tcp_mss_receiver': '15',
'tcp_mss_sender': '16',
'traffic_shaper': 'test_value_17',
'traffic_shaper_reverse': 'test_value_18',
'uuid': 'test_value_19'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_policy46.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'comments': 'test_value_4',
'dstintf': 'test_value_5',
'fixedport': 'enable',
'ippool': 'enable',
'logtraffic': 'enable',
'per-ip-shaper': 'test_value_9',
'permit-any-host': 'enable',
'policyid': '11',
'schedule': 'test_value_12',
'srcintf': 'test_value_13',
'status': 'enable',
'tcp-mss-receiver': '15',
'tcp-mss-sender': '16',
'traffic-shaper': 'test_value_17',
'traffic-shaper-reverse': 'test_value_18',
'uuid': 'test_value_19'
}
set_method_mock.assert_called_with('firewall', 'policy46', 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_policy6
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_policy6.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_policy6_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_policy6': {
'action': 'accept',
'application_list': 'test_value_4',
'av_profile': 'test_value_5',
'comments': 'test_value_6',
'diffserv_forward': 'enable',
'diffserv_reverse': 'enable',
'diffservcode_forward': 'test_value_9',
'diffservcode_rev': 'test_value_10',
'dlp_sensor': 'test_value_11',
'dscp_match': 'enable',
'dscp_negate': 'enable',
'dscp_value': 'test_value_14',
'dsri': 'enable',
'dstaddr_negate': 'enable',
'firewall_session_dirty': 'check-all',
'fixedport': 'enable',
'global_label': 'test_value_19',
'icap_profile': 'test_value_20',
'inbound': 'enable',
'ippool': 'enable',
'ips_sensor': 'test_value_23',
'label': 'test_value_24',
'logtraffic': 'all',
'logtraffic_start': 'enable',
'name': 'default_name_27',
'nat': 'enable',
'natinbound': 'enable',
'natoutbound': 'enable',
'outbound': 'enable',
'per_ip_shaper': 'test_value_32',
'policyid': '33',
'profile_group': 'test_value_34',
'profile_protocol_options': 'test_value_35',
'profile_type': 'single',
'replacemsg_override_group': 'test_value_37',
'rsso': 'enable',
'schedule': 'test_value_39',
'send_deny_packet': 'enable',
'service_negate': 'enable',
'session_ttl': '42',
'spamfilter_profile': 'test_value_43',
'srcaddr_negate': 'enable',
'ssh_filter_profile': 'test_value_45',
'ssl_mirror': 'enable',
'ssl_ssh_profile': 'test_value_47',
'status': 'enable',
'tcp_mss_receiver': '49',
'tcp_mss_sender': '50',
'tcp_session_without_syn': 'all',
'timeout_send_rst': 'enable',
'traffic_shaper': 'test_value_53',
'traffic_shaper_reverse': 'test_value_54',
'utm_status': 'enable',
'uuid': 'test_value_56',
'vlan_cos_fwd': '57',
'vlan_cos_rev': '58',
'vlan_filter': 'test_value_59',
'voip_profile': 'test_value_60',
'vpntunnel': 'test_value_61',
'webfilter_profile': 'test_value_62'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_policy6.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'application-list': 'test_value_4',
'av-profile': 'test_value_5',
'comments': 'test_value_6',
'diffserv-forward': 'enable',
'diffserv-reverse': 'enable',
'diffservcode-forward': 'test_value_9',
'diffservcode-rev': 'test_value_10',
'dlp-sensor': 'test_value_11',
'dscp-match': 'enable',
'dscp-negate': 'enable',
'dscp-value': 'test_value_14',
'dsri': 'enable',
'dstaddr-negate': 'enable',
'firewall-session-dirty': 'check-all',
'fixedport': 'enable',
'global-label': 'test_value_19',
'icap-profile': 'test_value_20',
'inbound': 'enable',
'ippool': 'enable',
'ips-sensor': 'test_value_23',
'label': 'test_value_24',
'logtraffic': 'all',
'logtraffic-start': 'enable',
'name': 'default_name_27',
'nat': 'enable',
'natinbound': 'enable',
'natoutbound': 'enable',
'outbound': 'enable',
'per-ip-shaper': 'test_value_32',
'policyid': '33',
'profile-group': 'test_value_34',
'profile-protocol-options': 'test_value_35',
'profile-type': 'single',
'replacemsg-override-group': 'test_value_37',
'rsso': 'enable',
'schedule': 'test_value_39',
'send-deny-packet': 'enable',
'service-negate': 'enable',
'session-ttl': '42',
'spamfilter-profile': 'test_value_43',
'srcaddr-negate': 'enable',
'ssh-filter-profile': 'test_value_45',
'ssl-mirror': 'enable',
'ssl-ssh-profile': 'test_value_47',
'status': 'enable',
'tcp-mss-receiver': '49',
'tcp-mss-sender': '50',
'tcp-session-without-syn': 'all',
'timeout-send-rst': 'enable',
'traffic-shaper': 'test_value_53',
'traffic-shaper-reverse': 'test_value_54',
'utm-status': 'enable',
'uuid': 'test_value_56',
'vlan-cos-fwd': '57',
'vlan-cos-rev': '58',
'vlan-filter': 'test_value_59',
'voip-profile': 'test_value_60',
'vpntunnel': 'test_value_61',
'webfilter-profile': 'test_value_62'
}
set_method_mock.assert_called_with('firewall', 'policy6', 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_policy6_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_policy6': {
'action': 'accept',
'application_list': 'test_value_4',
'av_profile': 'test_value_5',
'comments': 'test_value_6',
'diffserv_forward': 'enable',
'diffserv_reverse': 'enable',
'diffservcode_forward': 'test_value_9',
'diffservcode_rev': 'test_value_10',
'dlp_sensor': 'test_value_11',
'dscp_match': 'enable',
'dscp_negate': 'enable',
'dscp_value': 'test_value_14',
'dsri': 'enable',
'dstaddr_negate': 'enable',
'firewall_session_dirty': 'check-all',
'fixedport': 'enable',
'global_label': 'test_value_19',
'icap_profile': 'test_value_20',
'inbound': 'enable',
'ippool': 'enable',
'ips_sensor': 'test_value_23',
'label': 'test_value_24',
'logtraffic': 'all',
'logtraffic_start': 'enable',
'name': 'default_name_27',
'nat': 'enable',
'natinbound': 'enable',
'natoutbound': 'enable',
'outbound': 'enable',
'per_ip_shaper': 'test_value_32',
'policyid': '33',
'profile_group': 'test_value_34',
'profile_protocol_options': 'test_value_35',
'profile_type': 'single',
'replacemsg_override_group': 'test_value_37',
'rsso': 'enable',
'schedule': 'test_value_39',
'send_deny_packet': 'enable',
'service_negate': 'enable',
'session_ttl': '42',
'spamfilter_profile': 'test_value_43',
'srcaddr_negate': 'enable',
'ssh_filter_profile': 'test_value_45',
'ssl_mirror': 'enable',
'ssl_ssh_profile': 'test_value_47',
'status': 'enable',
'tcp_mss_receiver': '49',
'tcp_mss_sender': '50',
'tcp_session_without_syn': 'all',
'timeout_send_rst': 'enable',
'traffic_shaper': 'test_value_53',
'traffic_shaper_reverse': 'test_value_54',
'utm_status': 'enable',
'uuid': 'test_value_56',
'vlan_cos_fwd': '57',
'vlan_cos_rev': '58',
'vlan_filter': 'test_value_59',
'voip_profile': 'test_value_60',
'vpntunnel': 'test_value_61',
'webfilter_profile': 'test_value_62'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_policy6.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'application-list': 'test_value_4',
'av-profile': 'test_value_5',
'comments': 'test_value_6',
'diffserv-forward': 'enable',
'diffserv-reverse': 'enable',
'diffservcode-forward': 'test_value_9',
'diffservcode-rev': 'test_value_10',
'dlp-sensor': 'test_value_11',
'dscp-match': 'enable',
'dscp-negate': 'enable',
'dscp-value': 'test_value_14',
'dsri': 'enable',
'dstaddr-negate': 'enable',
'firewall-session-dirty': 'check-all',
'fixedport': 'enable',
'global-label': 'test_value_19',
'icap-profile': 'test_value_20',
'inbound': 'enable',
'ippool': 'enable',
'ips-sensor': 'test_value_23',
'label': 'test_value_24',
'logtraffic': 'all',
'logtraffic-start': 'enable',
'name': 'default_name_27',
'nat': 'enable',
'natinbound': 'enable',
'natoutbound': 'enable',
'outbound': 'enable',
'per-ip-shaper': 'test_value_32',
'policyid': '33',
'profile-group': 'test_value_34',
'profile-protocol-options': 'test_value_35',
'profile-type': 'single',
'replacemsg-override-group': 'test_value_37',
'rsso': 'enable',
'schedule': 'test_value_39',
'send-deny-packet': 'enable',
'service-negate': 'enable',
'session-ttl': '42',
'spamfilter-profile': 'test_value_43',
'srcaddr-negate': 'enable',
'ssh-filter-profile': 'test_value_45',
'ssl-mirror': 'enable',
'ssl-ssh-profile': 'test_value_47',
'status': 'enable',
'tcp-mss-receiver': '49',
'tcp-mss-sender': '50',
'tcp-session-without-syn': 'all',
'timeout-send-rst': 'enable',
'traffic-shaper': 'test_value_53',
'traffic-shaper-reverse': 'test_value_54',
'utm-status': 'enable',
'uuid': 'test_value_56',
'vlan-cos-fwd': '57',
'vlan-cos-rev': '58',
'vlan-filter': 'test_value_59',
'voip-profile': 'test_value_60',
'vpntunnel': 'test_value_61',
'webfilter-profile': 'test_value_62'
}
set_method_mock.assert_called_with('firewall', 'policy6', 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_policy6_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_policy6': {
'action': 'accept',
'application_list': 'test_value_4',
'av_profile': 'test_value_5',
'comments': 'test_value_6',
'diffserv_forward': 'enable',
'diffserv_reverse': 'enable',
'diffservcode_forward': 'test_value_9',
'diffservcode_rev': 'test_value_10',
'dlp_sensor': 'test_value_11',
'dscp_match': 'enable',
'dscp_negate': 'enable',
'dscp_value': 'test_value_14',
'dsri': 'enable',
'dstaddr_negate': 'enable',
'firewall_session_dirty': 'check-all',
'fixedport': 'enable',
'global_label': 'test_value_19',
'icap_profile': 'test_value_20',
'inbound': 'enable',
'ippool': 'enable',
'ips_sensor': 'test_value_23',
'label': 'test_value_24',
'logtraffic': 'all',
'logtraffic_start': 'enable',
'name': 'default_name_27',
'nat': 'enable',
'natinbound': 'enable',
'natoutbound': 'enable',
'outbound': 'enable',
'per_ip_shaper': 'test_value_32',
'policyid': '33',
'profile_group': 'test_value_34',
'profile_protocol_options': 'test_value_35',
'profile_type': 'single',
'replacemsg_override_group': 'test_value_37',
'rsso': 'enable',
'schedule': 'test_value_39',
'send_deny_packet': 'enable',
'service_negate': 'enable',
'session_ttl': '42',
'spamfilter_profile': 'test_value_43',
'srcaddr_negate': 'enable',
'ssh_filter_profile': 'test_value_45',
'ssl_mirror': 'enable',
'ssl_ssh_profile': 'test_value_47',
'status': 'enable',
'tcp_mss_receiver': '49',
'tcp_mss_sender': '50',
'tcp_session_without_syn': 'all',
'timeout_send_rst': 'enable',
'traffic_shaper': 'test_value_53',
'traffic_shaper_reverse': 'test_value_54',
'utm_status': 'enable',
'uuid': 'test_value_56',
'vlan_cos_fwd': '57',
'vlan_cos_rev': '58',
'vlan_filter': 'test_value_59',
'voip_profile': 'test_value_60',
'vpntunnel': 'test_value_61',
'webfilter_profile': 'test_value_62'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_policy6.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'policy6', 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_policy6_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_policy6': {
'action': 'accept',
'application_list': 'test_value_4',
'av_profile': 'test_value_5',
'comments': 'test_value_6',
'diffserv_forward': 'enable',
'diffserv_reverse': 'enable',
'diffservcode_forward': 'test_value_9',
'diffservcode_rev': 'test_value_10',
'dlp_sensor': 'test_value_11',
'dscp_match': 'enable',
'dscp_negate': 'enable',
'dscp_value': 'test_value_14',
'dsri': 'enable',
'dstaddr_negate': 'enable',
'firewall_session_dirty': 'check-all',
'fixedport': 'enable',
'global_label': 'test_value_19',
'icap_profile': 'test_value_20',
'inbound': 'enable',
'ippool': 'enable',
'ips_sensor': 'test_value_23',
'label': 'test_value_24',
'logtraffic': 'all',
'logtraffic_start': 'enable',
'name': 'default_name_27',
'nat': 'enable',
'natinbound': 'enable',
'natoutbound': 'enable',
'outbound': 'enable',
'per_ip_shaper': 'test_value_32',
'policyid': '33',
'profile_group': 'test_value_34',
'profile_protocol_options': 'test_value_35',
'profile_type': 'single',
'replacemsg_override_group': 'test_value_37',
'rsso': 'enable',
'schedule': 'test_value_39',
'send_deny_packet': 'enable',
'service_negate': 'enable',
'session_ttl': '42',
'spamfilter_profile': 'test_value_43',
'srcaddr_negate': 'enable',
'ssh_filter_profile': 'test_value_45',
'ssl_mirror': 'enable',
'ssl_ssh_profile': 'test_value_47',
'status': 'enable',
'tcp_mss_receiver': '49',
'tcp_mss_sender': '50',
'tcp_session_without_syn': 'all',
'timeout_send_rst': 'enable',
'traffic_shaper': 'test_value_53',
'traffic_shaper_reverse': 'test_value_54',
'utm_status': 'enable',
'uuid': 'test_value_56',
'vlan_cos_fwd': '57',
'vlan_cos_rev': '58',
'vlan_filter': 'test_value_59',
'voip_profile': 'test_value_60',
'vpntunnel': 'test_value_61',
'webfilter_profile': 'test_value_62'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_policy6.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'policy6', 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_policy6_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_policy6': {
'action': 'accept',
'application_list': 'test_value_4',
'av_profile': 'test_value_5',
'comments': 'test_value_6',
'diffserv_forward': 'enable',
'diffserv_reverse': 'enable',
'diffservcode_forward': 'test_value_9',
'diffservcode_rev': 'test_value_10',
'dlp_sensor': 'test_value_11',
'dscp_match': 'enable',
'dscp_negate': 'enable',
'dscp_value': 'test_value_14',
'dsri': 'enable',
'dstaddr_negate': 'enable',
'firewall_session_dirty': 'check-all',
'fixedport': 'enable',
'global_label': 'test_value_19',
'icap_profile': 'test_value_20',
'inbound': 'enable',
'ippool': 'enable',
'ips_sensor': 'test_value_23',
'label': 'test_value_24',
'logtraffic': 'all',
'logtraffic_start': 'enable',
'name': 'default_name_27',
'nat': 'enable',
'natinbound': 'enable',
'natoutbound': 'enable',
'outbound': 'enable',
'per_ip_shaper': 'test_value_32',
'policyid': '33',
'profile_group': 'test_value_34',
'profile_protocol_options': 'test_value_35',
'profile_type': 'single',
'replacemsg_override_group': 'test_value_37',
'rsso': 'enable',
'schedule': 'test_value_39',
'send_deny_packet': 'enable',
'service_negate': 'enable',
'session_ttl': '42',
'spamfilter_profile': 'test_value_43',
'srcaddr_negate': 'enable',
'ssh_filter_profile': 'test_value_45',
'ssl_mirror': 'enable',
'ssl_ssh_profile': 'test_value_47',
'status': 'enable',
'tcp_mss_receiver': '49',
'tcp_mss_sender': '50',
'tcp_session_without_syn': 'all',
'timeout_send_rst': 'enable',
'traffic_shaper': 'test_value_53',
'traffic_shaper_reverse': 'test_value_54',
'utm_status': 'enable',
'uuid': 'test_value_56',
'vlan_cos_fwd': '57',
'vlan_cos_rev': '58',
'vlan_filter': 'test_value_59',
'voip_profile': 'test_value_60',
'vpntunnel': 'test_value_61',
'webfilter_profile': 'test_value_62'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_policy6.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'application-list': 'test_value_4',
'av-profile': 'test_value_5',
'comments': 'test_value_6',
'diffserv-forward': 'enable',
'diffserv-reverse': 'enable',
'diffservcode-forward': 'test_value_9',
'diffservcode-rev': 'test_value_10',
'dlp-sensor': 'test_value_11',
'dscp-match': 'enable',
'dscp-negate': 'enable',
'dscp-value': 'test_value_14',
'dsri': 'enable',
'dstaddr-negate': 'enable',
'firewall-session-dirty': 'check-all',
'fixedport': 'enable',
'global-label': 'test_value_19',
'icap-profile': 'test_value_20',
'inbound': 'enable',
'ippool': 'enable',
'ips-sensor': 'test_value_23',
'label': 'test_value_24',
'logtraffic': 'all',
'logtraffic-start': 'enable',
'name': 'default_name_27',
'nat': 'enable',
'natinbound': 'enable',
'natoutbound': 'enable',
'outbound': 'enable',
'per-ip-shaper': 'test_value_32',
'policyid': '33',
'profile-group': 'test_value_34',
'profile-protocol-options': 'test_value_35',
'profile-type': 'single',
'replacemsg-override-group': 'test_value_37',
'rsso': 'enable',
'schedule': 'test_value_39',
'send-deny-packet': 'enable',
'service-negate': 'enable',
'session-ttl': '42',
'spamfilter-profile': 'test_value_43',
'srcaddr-negate': 'enable',
'ssh-filter-profile': 'test_value_45',
'ssl-mirror': 'enable',
'ssl-ssh-profile': 'test_value_47',
'status': 'enable',
'tcp-mss-receiver': '49',
'tcp-mss-sender': '50',
'tcp-session-without-syn': 'all',
'timeout-send-rst': 'enable',
'traffic-shaper': 'test_value_53',
'traffic-shaper-reverse': 'test_value_54',
'utm-status': 'enable',
'uuid': 'test_value_56',
'vlan-cos-fwd': '57',
'vlan-cos-rev': '58',
'vlan-filter': 'test_value_59',
'voip-profile': 'test_value_60',
'vpntunnel': 'test_value_61',
'webfilter-profile': 'test_value_62'
}
set_method_mock.assert_called_with('firewall', 'policy6', 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_policy6_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_policy6': {
'random_attribute_not_valid': 'tag',
'action': 'accept',
'application_list': 'test_value_4',
'av_profile': 'test_value_5',
'comments': 'test_value_6',
'diffserv_forward': 'enable',
'diffserv_reverse': 'enable',
'diffservcode_forward': 'test_value_9',
'diffservcode_rev': 'test_value_10',
'dlp_sensor': 'test_value_11',
'dscp_match': 'enable',
'dscp_negate': 'enable',
'dscp_value': 'test_value_14',
'dsri': 'enable',
'dstaddr_negate': 'enable',
'firewall_session_dirty': 'check-all',
'fixedport': 'enable',
'global_label': 'test_value_19',
'icap_profile': 'test_value_20',
'inbound': 'enable',
'ippool': 'enable',
'ips_sensor': 'test_value_23',
'label': 'test_value_24',
'logtraffic': 'all',
'logtraffic_start': 'enable',
'name': 'default_name_27',
'nat': 'enable',
'natinbound': 'enable',
'natoutbound': 'enable',
'outbound': 'enable',
'per_ip_shaper': 'test_value_32',
'policyid': '33',
'profile_group': 'test_value_34',
'profile_protocol_options': 'test_value_35',
'profile_type': 'single',
'replacemsg_override_group': 'test_value_37',
'rsso': 'enable',
'schedule': 'test_value_39',
'send_deny_packet': 'enable',
'service_negate': 'enable',
'session_ttl': '42',
'spamfilter_profile': 'test_value_43',
'srcaddr_negate': 'enable',
'ssh_filter_profile': 'test_value_45',
'ssl_mirror': 'enable',
'ssl_ssh_profile': 'test_value_47',
'status': 'enable',
'tcp_mss_receiver': '49',
'tcp_mss_sender': '50',
'tcp_session_without_syn': 'all',
'timeout_send_rst': 'enable',
'traffic_shaper': 'test_value_53',
'traffic_shaper_reverse': 'test_value_54',
'utm_status': 'enable',
'uuid': 'test_value_56',
'vlan_cos_fwd': '57',
'vlan_cos_rev': '58',
'vlan_filter': 'test_value_59',
'voip_profile': 'test_value_60',
'vpntunnel': 'test_value_61',
'webfilter_profile': 'test_value_62'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_policy6.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'application-list': 'test_value_4',
'av-profile': 'test_value_5',
'comments': 'test_value_6',
'diffserv-forward': 'enable',
'diffserv-reverse': 'enable',
'diffservcode-forward': 'test_value_9',
'diffservcode-rev': 'test_value_10',
'dlp-sensor': 'test_value_11',
'dscp-match': 'enable',
'dscp-negate': 'enable',
'dscp-value': 'test_value_14',
'dsri': 'enable',
'dstaddr-negate': 'enable',
'firewall-session-dirty': 'check-all',
'fixedport': 'enable',
'global-label': 'test_value_19',
'icap-profile': 'test_value_20',
'inbound': 'enable',
'ippool': 'enable',
'ips-sensor': 'test_value_23',
'label': 'test_value_24',
'logtraffic': 'all',
'logtraffic-start': 'enable',
'name': 'default_name_27',
'nat': 'enable',
'natinbound': 'enable',
'natoutbound': 'enable',
'outbound': 'enable',
'per-ip-shaper': 'test_value_32',
'policyid': '33',
'profile-group': 'test_value_34',
'profile-protocol-options': 'test_value_35',
'profile-type': 'single',
'replacemsg-override-group': 'test_value_37',
'rsso': 'enable',
'schedule': 'test_value_39',
'send-deny-packet': 'enable',
'service-negate': 'enable',
'session-ttl': '42',
'spamfilter-profile': 'test_value_43',
'srcaddr-negate': 'enable',
'ssh-filter-profile': 'test_value_45',
'ssl-mirror': 'enable',
'ssl-ssh-profile': 'test_value_47',
'status': 'enable',
'tcp-mss-receiver': '49',
'tcp-mss-sender': '50',
'tcp-session-without-syn': 'all',
'timeout-send-rst': 'enable',
'traffic-shaper': 'test_value_53',
'traffic-shaper-reverse': 'test_value_54',
'utm-status': 'enable',
'uuid': 'test_value_56',
'vlan-cos-fwd': '57',
'vlan-cos-rev': '58',
'vlan-filter': 'test_value_59',
'voip-profile': 'test_value_60',
'vpntunnel': 'test_value_61',
'webfilter-profile': 'test_value_62'
}
set_method_mock.assert_called_with('firewall', 'policy6', 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,359 @@
# 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_policy64
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_policy64.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_policy64_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_policy64': {
'action': 'accept',
'comments': 'test_value_4',
'dstintf': 'test_value_5',
'fixedport': 'enable',
'ippool': 'enable',
'logtraffic': 'enable',
'per_ip_shaper': 'test_value_9',
'permit_any_host': 'enable',
'policyid': '11',
'schedule': 'test_value_12',
'srcintf': 'test_value_13',
'status': 'enable',
'tcp_mss_receiver': '15',
'tcp_mss_sender': '16',
'traffic_shaper': 'test_value_17',
'traffic_shaper_reverse': 'test_value_18',
'uuid': 'test_value_19'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_policy64.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'comments': 'test_value_4',
'dstintf': 'test_value_5',
'fixedport': 'enable',
'ippool': 'enable',
'logtraffic': 'enable',
'per-ip-shaper': 'test_value_9',
'permit-any-host': 'enable',
'policyid': '11',
'schedule': 'test_value_12',
'srcintf': 'test_value_13',
'status': 'enable',
'tcp-mss-receiver': '15',
'tcp-mss-sender': '16',
'traffic-shaper': 'test_value_17',
'traffic-shaper-reverse': 'test_value_18',
'uuid': 'test_value_19'
}
set_method_mock.assert_called_with('firewall', 'policy64', 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_policy64_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_policy64': {
'action': 'accept',
'comments': 'test_value_4',
'dstintf': 'test_value_5',
'fixedport': 'enable',
'ippool': 'enable',
'logtraffic': 'enable',
'per_ip_shaper': 'test_value_9',
'permit_any_host': 'enable',
'policyid': '11',
'schedule': 'test_value_12',
'srcintf': 'test_value_13',
'status': 'enable',
'tcp_mss_receiver': '15',
'tcp_mss_sender': '16',
'traffic_shaper': 'test_value_17',
'traffic_shaper_reverse': 'test_value_18',
'uuid': 'test_value_19'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_policy64.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'comments': 'test_value_4',
'dstintf': 'test_value_5',
'fixedport': 'enable',
'ippool': 'enable',
'logtraffic': 'enable',
'per-ip-shaper': 'test_value_9',
'permit-any-host': 'enable',
'policyid': '11',
'schedule': 'test_value_12',
'srcintf': 'test_value_13',
'status': 'enable',
'tcp-mss-receiver': '15',
'tcp-mss-sender': '16',
'traffic-shaper': 'test_value_17',
'traffic-shaper-reverse': 'test_value_18',
'uuid': 'test_value_19'
}
set_method_mock.assert_called_with('firewall', 'policy64', 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_policy64_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_policy64': {
'action': 'accept',
'comments': 'test_value_4',
'dstintf': 'test_value_5',
'fixedport': 'enable',
'ippool': 'enable',
'logtraffic': 'enable',
'per_ip_shaper': 'test_value_9',
'permit_any_host': 'enable',
'policyid': '11',
'schedule': 'test_value_12',
'srcintf': 'test_value_13',
'status': 'enable',
'tcp_mss_receiver': '15',
'tcp_mss_sender': '16',
'traffic_shaper': 'test_value_17',
'traffic_shaper_reverse': 'test_value_18',
'uuid': 'test_value_19'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_policy64.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'policy64', 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_policy64_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_policy64': {
'action': 'accept',
'comments': 'test_value_4',
'dstintf': 'test_value_5',
'fixedport': 'enable',
'ippool': 'enable',
'logtraffic': 'enable',
'per_ip_shaper': 'test_value_9',
'permit_any_host': 'enable',
'policyid': '11',
'schedule': 'test_value_12',
'srcintf': 'test_value_13',
'status': 'enable',
'tcp_mss_receiver': '15',
'tcp_mss_sender': '16',
'traffic_shaper': 'test_value_17',
'traffic_shaper_reverse': 'test_value_18',
'uuid': 'test_value_19'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_policy64.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'policy64', 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_policy64_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_policy64': {
'action': 'accept',
'comments': 'test_value_4',
'dstintf': 'test_value_5',
'fixedport': 'enable',
'ippool': 'enable',
'logtraffic': 'enable',
'per_ip_shaper': 'test_value_9',
'permit_any_host': 'enable',
'policyid': '11',
'schedule': 'test_value_12',
'srcintf': 'test_value_13',
'status': 'enable',
'tcp_mss_receiver': '15',
'tcp_mss_sender': '16',
'traffic_shaper': 'test_value_17',
'traffic_shaper_reverse': 'test_value_18',
'uuid': 'test_value_19'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_policy64.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'comments': 'test_value_4',
'dstintf': 'test_value_5',
'fixedport': 'enable',
'ippool': 'enable',
'logtraffic': 'enable',
'per-ip-shaper': 'test_value_9',
'permit-any-host': 'enable',
'policyid': '11',
'schedule': 'test_value_12',
'srcintf': 'test_value_13',
'status': 'enable',
'tcp-mss-receiver': '15',
'tcp-mss-sender': '16',
'traffic-shaper': 'test_value_17',
'traffic-shaper-reverse': 'test_value_18',
'uuid': 'test_value_19'
}
set_method_mock.assert_called_with('firewall', 'policy64', 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_policy64_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_policy64': {
'random_attribute_not_valid': 'tag',
'action': 'accept',
'comments': 'test_value_4',
'dstintf': 'test_value_5',
'fixedport': 'enable',
'ippool': 'enable',
'logtraffic': 'enable',
'per_ip_shaper': 'test_value_9',
'permit_any_host': 'enable',
'policyid': '11',
'schedule': 'test_value_12',
'srcintf': 'test_value_13',
'status': 'enable',
'tcp_mss_receiver': '15',
'tcp_mss_sender': '16',
'traffic_shaper': 'test_value_17',
'traffic_shaper_reverse': 'test_value_18',
'uuid': 'test_value_19'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_policy64.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'comments': 'test_value_4',
'dstintf': 'test_value_5',
'fixedport': 'enable',
'ippool': 'enable',
'logtraffic': 'enable',
'per-ip-shaper': 'test_value_9',
'permit-any-host': 'enable',
'policyid': '11',
'schedule': 'test_value_12',
'srcintf': 'test_value_13',
'status': 'enable',
'tcp-mss-receiver': '15',
'tcp-mss-sender': '16',
'traffic-shaper': 'test_value_17',
'traffic-shaper-reverse': 'test_value_18',
'uuid': 'test_value_19'
}
set_method_mock.assert_called_with('firewall', 'policy64', 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_firewall_profile_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_profile_group.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_profile_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_profile_group': {
'application_list': 'test_value_3',
'av_profile': 'test_value_4',
'dlp_sensor': 'test_value_5',
'dnsfilter_profile': 'test_value_6',
'icap_profile': 'test_value_7',
'ips_sensor': 'test_value_8',
'name': 'default_name_9',
'profile_protocol_options': 'test_value_10',
'spamfilter_profile': 'test_value_11',
'ssh_filter_profile': 'test_value_12',
'ssl_ssh_profile': 'test_value_13',
'voip_profile': 'test_value_14',
'waf_profile': 'test_value_15',
'webfilter_profile': 'test_value_16'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_profile_group.fortios_firewall(input_data, fos_instance)
expected_data = {
'application-list': 'test_value_3',
'av-profile': 'test_value_4',
'dlp-sensor': 'test_value_5',
'dnsfilter-profile': 'test_value_6',
'icap-profile': 'test_value_7',
'ips-sensor': 'test_value_8',
'name': 'default_name_9',
'profile-protocol-options': 'test_value_10',
'spamfilter-profile': 'test_value_11',
'ssh-filter-profile': 'test_value_12',
'ssl-ssh-profile': 'test_value_13',
'voip-profile': 'test_value_14',
'waf-profile': 'test_value_15',
'webfilter-profile': 'test_value_16'
}
set_method_mock.assert_called_with('firewall', 'profile-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_profile_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_profile_group': {
'application_list': 'test_value_3',
'av_profile': 'test_value_4',
'dlp_sensor': 'test_value_5',
'dnsfilter_profile': 'test_value_6',
'icap_profile': 'test_value_7',
'ips_sensor': 'test_value_8',
'name': 'default_name_9',
'profile_protocol_options': 'test_value_10',
'spamfilter_profile': 'test_value_11',
'ssh_filter_profile': 'test_value_12',
'ssl_ssh_profile': 'test_value_13',
'voip_profile': 'test_value_14',
'waf_profile': 'test_value_15',
'webfilter_profile': 'test_value_16'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_profile_group.fortios_firewall(input_data, fos_instance)
expected_data = {
'application-list': 'test_value_3',
'av-profile': 'test_value_4',
'dlp-sensor': 'test_value_5',
'dnsfilter-profile': 'test_value_6',
'icap-profile': 'test_value_7',
'ips-sensor': 'test_value_8',
'name': 'default_name_9',
'profile-protocol-options': 'test_value_10',
'spamfilter-profile': 'test_value_11',
'ssh-filter-profile': 'test_value_12',
'ssl-ssh-profile': 'test_value_13',
'voip-profile': 'test_value_14',
'waf-profile': 'test_value_15',
'webfilter-profile': 'test_value_16'
}
set_method_mock.assert_called_with('firewall', 'profile-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_profile_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_profile_group': {
'application_list': 'test_value_3',
'av_profile': 'test_value_4',
'dlp_sensor': 'test_value_5',
'dnsfilter_profile': 'test_value_6',
'icap_profile': 'test_value_7',
'ips_sensor': 'test_value_8',
'name': 'default_name_9',
'profile_protocol_options': 'test_value_10',
'spamfilter_profile': 'test_value_11',
'ssh_filter_profile': 'test_value_12',
'ssl_ssh_profile': 'test_value_13',
'voip_profile': 'test_value_14',
'waf_profile': 'test_value_15',
'webfilter_profile': 'test_value_16'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_profile_group.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'profile-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_profile_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_profile_group': {
'application_list': 'test_value_3',
'av_profile': 'test_value_4',
'dlp_sensor': 'test_value_5',
'dnsfilter_profile': 'test_value_6',
'icap_profile': 'test_value_7',
'ips_sensor': 'test_value_8',
'name': 'default_name_9',
'profile_protocol_options': 'test_value_10',
'spamfilter_profile': 'test_value_11',
'ssh_filter_profile': 'test_value_12',
'ssl_ssh_profile': 'test_value_13',
'voip_profile': 'test_value_14',
'waf_profile': 'test_value_15',
'webfilter_profile': 'test_value_16'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_profile_group.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'profile-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_profile_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_profile_group': {
'application_list': 'test_value_3',
'av_profile': 'test_value_4',
'dlp_sensor': 'test_value_5',
'dnsfilter_profile': 'test_value_6',
'icap_profile': 'test_value_7',
'ips_sensor': 'test_value_8',
'name': 'default_name_9',
'profile_protocol_options': 'test_value_10',
'spamfilter_profile': 'test_value_11',
'ssh_filter_profile': 'test_value_12',
'ssl_ssh_profile': 'test_value_13',
'voip_profile': 'test_value_14',
'waf_profile': 'test_value_15',
'webfilter_profile': 'test_value_16'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_profile_group.fortios_firewall(input_data, fos_instance)
expected_data = {
'application-list': 'test_value_3',
'av-profile': 'test_value_4',
'dlp-sensor': 'test_value_5',
'dnsfilter-profile': 'test_value_6',
'icap-profile': 'test_value_7',
'ips-sensor': 'test_value_8',
'name': 'default_name_9',
'profile-protocol-options': 'test_value_10',
'spamfilter-profile': 'test_value_11',
'ssh-filter-profile': 'test_value_12',
'ssl-ssh-profile': 'test_value_13',
'voip-profile': 'test_value_14',
'waf-profile': 'test_value_15',
'webfilter-profile': 'test_value_16'
}
set_method_mock.assert_called_with('firewall', 'profile-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_profile_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_profile_group': {
'random_attribute_not_valid': 'tag',
'application_list': 'test_value_3',
'av_profile': 'test_value_4',
'dlp_sensor': 'test_value_5',
'dnsfilter_profile': 'test_value_6',
'icap_profile': 'test_value_7',
'ips_sensor': 'test_value_8',
'name': 'default_name_9',
'profile_protocol_options': 'test_value_10',
'spamfilter_profile': 'test_value_11',
'ssh_filter_profile': 'test_value_12',
'ssl_ssh_profile': 'test_value_13',
'voip_profile': 'test_value_14',
'waf_profile': 'test_value_15',
'webfilter_profile': 'test_value_16'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_profile_group.fortios_firewall(input_data, fos_instance)
expected_data = {
'application-list': 'test_value_3',
'av-profile': 'test_value_4',
'dlp-sensor': 'test_value_5',
'dnsfilter-profile': 'test_value_6',
'icap-profile': 'test_value_7',
'ips-sensor': 'test_value_8',
'name': 'default_name_9',
'profile-protocol-options': 'test_value_10',
'spamfilter-profile': 'test_value_11',
'ssh-filter-profile': 'test_value_12',
'ssl-ssh-profile': 'test_value_13',
'voip-profile': 'test_value_14',
'waf-profile': 'test_value_15',
'webfilter-profile': 'test_value_16'
}
set_method_mock.assert_called_with('firewall', 'profile-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,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_profile_protocol_options
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_profile_protocol_options.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_profile_protocol_options_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_profile_protocol_options': {
'comment': 'Optional comments.',
'name': 'default_name_4',
'oversize_log': 'disable',
'replacemsg_group': 'test_value_6',
'rpc_over_http': 'enable',
'switching_protocols_log': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_profile_protocol_options.fortios_firewall(input_data, fos_instance)
expected_data = {
'comment': 'Optional comments.',
'name': 'default_name_4',
'oversize-log': 'disable',
'replacemsg-group': 'test_value_6',
'rpc-over-http': 'enable',
'switching-protocols-log': 'disable'
}
set_method_mock.assert_called_with('firewall', 'profile-protocol-options', 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_profile_protocol_options_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_profile_protocol_options': {
'comment': 'Optional comments.',
'name': 'default_name_4',
'oversize_log': 'disable',
'replacemsg_group': 'test_value_6',
'rpc_over_http': 'enable',
'switching_protocols_log': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_profile_protocol_options.fortios_firewall(input_data, fos_instance)
expected_data = {
'comment': 'Optional comments.',
'name': 'default_name_4',
'oversize-log': 'disable',
'replacemsg-group': 'test_value_6',
'rpc-over-http': 'enable',
'switching-protocols-log': 'disable'
}
set_method_mock.assert_called_with('firewall', 'profile-protocol-options', 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_profile_protocol_options_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_profile_protocol_options': {
'comment': 'Optional comments.',
'name': 'default_name_4',
'oversize_log': 'disable',
'replacemsg_group': 'test_value_6',
'rpc_over_http': 'enable',
'switching_protocols_log': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_profile_protocol_options.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'profile-protocol-options', 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_profile_protocol_options_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_profile_protocol_options': {
'comment': 'Optional comments.',
'name': 'default_name_4',
'oversize_log': 'disable',
'replacemsg_group': 'test_value_6',
'rpc_over_http': 'enable',
'switching_protocols_log': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_profile_protocol_options.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'profile-protocol-options', 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_profile_protocol_options_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_profile_protocol_options': {
'comment': 'Optional comments.',
'name': 'default_name_4',
'oversize_log': 'disable',
'replacemsg_group': 'test_value_6',
'rpc_over_http': 'enable',
'switching_protocols_log': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_profile_protocol_options.fortios_firewall(input_data, fos_instance)
expected_data = {
'comment': 'Optional comments.',
'name': 'default_name_4',
'oversize-log': 'disable',
'replacemsg-group': 'test_value_6',
'rpc-over-http': 'enable',
'switching-protocols-log': 'disable'
}
set_method_mock.assert_called_with('firewall', 'profile-protocol-options', 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_profile_protocol_options_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_profile_protocol_options': {
'random_attribute_not_valid': 'tag',
'comment': 'Optional comments.',
'name': 'default_name_4',
'oversize_log': 'disable',
'replacemsg_group': 'test_value_6',
'rpc_over_http': 'enable',
'switching_protocols_log': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_profile_protocol_options.fortios_firewall(input_data, fos_instance)
expected_data = {
'comment': 'Optional comments.',
'name': 'default_name_4',
'oversize-log': 'disable',
'replacemsg-group': 'test_value_6',
'rpc-over-http': 'enable',
'switching-protocols-log': 'disable'
}
set_method_mock.assert_called_with('firewall', 'profile-protocol-options', 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