FortiOS modules for 2.9 - 4 (#60806)

* FortiOS modules for 2.9 - 4

* Update ignore.txt

* Updates from maintainers to legacy modules

* Update fortios_firewall_ssl_setting.py

* Update fortios_firewall_ssl_server.py
pull/60963/head
Miguel Angel Muñoz González 5 years ago committed by Nilashish Chakraborty
parent 2b103a2e54
commit 3cd70f53cc

@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_proxy_address
short_description: Web proxy address configuration in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure firewall feature and proxy_address category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and proxy_address category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -44,95 +41,123 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
required: true
choices:
- present
- absent
version_added: 2.9
firewall_proxy_address:
description:
- Web proxy address configuration.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
case-sensitivity:
case_sensitivity:
description:
- Enable to make the pattern case sensitive.
type: str
choices:
- disable
- enable
category:
description:
- FortiGuard category ID.
type: list
suboptions:
id:
description:
- Fortiguard category id.
required: true
type: int
color:
description:
- Integer value to determine the color of the icon in the GUI (1 - 32, default = 0, which sets value to 1).
type: int
comment:
description:
- Optional comments.
type: str
header:
description:
- HTTP header name as a regular expression.
header-group:
type: str
header_group:
description:
- HTTP header group.
type: list
suboptions:
case-sensitivity:
case_sensitivity:
description:
- Case sensitivity in pattern.
type: str
choices:
- disable
- enable
header:
description:
- HTTP header regular expression.
header-name:
type: str
header_name:
description:
- HTTP header.
type: str
id:
description:
- ID.
required: true
header-name:
type: int
header_name:
description:
- Name of HTTP header.
type: str
host:
description:
- Address object for the host. Source firewall.address.name firewall.addrgrp.name firewall.proxy-address.name.
host-regex:
type: str
host_regex:
description:
- Host name as a regular expression.
type: str
method:
description:
- HTTP request methods to be used.
type: str
choices:
- get
- post
@ -146,40 +171,50 @@ options:
description:
- Address name.
required: true
type: str
path:
description:
- URL path as a regular expression.
type: str
query:
description:
- Match the query part of the URL as a regular expression.
type: str
referrer:
description:
- Enable/disable use of referrer field in the HTTP header to match the address.
type: str
choices:
- enable
- disable
tagging:
description:
- Config object tagging.
type: list
suboptions:
category:
description:
- Tag category. Source system.object-tagging.category.
type: str
name:
description:
- Tagging entry name.
required: true
type: str
tags:
description:
- Tags.
type: list
suboptions:
name:
description:
- Tag name. Source system.object-tagging.tags.name.
required: true
type: str
type:
description:
- Proxy address type.
type: str
choices:
- host-regex
- url
@ -192,6 +227,7 @@ options:
ua:
description:
- Names of browsers to be used as user agent.
type: str
choices:
- chrome
- ms
@ -201,9 +237,11 @@ options:
uuid:
description:
- Universally Unique Identifier (UUID; automatically assigned but can be manually reset).
type: str
visibility:
description:
- Enable/disable visibility of the object in the GUI.
type: str
choices:
- enable
- disable
@ -216,6 +254,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Web proxy address configuration.
fortios_firewall_proxy_address:
@ -224,24 +263,24 @@ EXAMPLES = '''
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_proxy_address:
state: "present"
case-sensitivity: "disable"
case_sensitivity: "disable"
category:
-
id: "5"
color: "6"
comment: "Optional comments."
header: "<your_own_value>"
header-group:
header_group:
-
case-sensitivity: "disable"
case_sensitivity: "disable"
header: "<your_own_value>"
header-name: "<your_own_value>"
header_name: "<your_own_value>"
id: "13"
header-name: "<your_own_value>"
header_name: "<your_own_value>"
host: "myhostname (source firewall.address.name firewall.addrgrp.name firewall.proxy-address.name)"
host-regex: "myhostname"
host_regex: "myhostname"
method: "get"
name: "default_name_18"
path: "<your_own_value>"
@ -320,14 +359,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data):
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -335,13 +376,13 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_proxy_address_data(json):
option_list = ['case-sensitivity', 'category', 'color',
'comment', 'header', 'header-group',
'header-name', 'host', 'host-regex',
option_list = ['case_sensitivity', 'category', 'color',
'comment', 'header', 'header_group',
'header_name', 'host', 'host_regex',
'method', 'name', 'path',
'query', 'referrer', 'tagging',
'type', 'ua', 'uuid',
@ -355,49 +396,67 @@ def filter_firewall_proxy_address_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_proxy_address(data, fos):
vdom = data['vdom']
state = data['state']
firewall_proxy_address_data = data['firewall_proxy_address']
filtered_data = filter_firewall_proxy_address_data(firewall_proxy_address_data)
if firewall_proxy_address_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_firewall_proxy_address_data(firewall_proxy_address_data))
if state == "present":
return fos.set('firewall',
'proxy-address',
data=filtered_data,
vdom=vdom)
elif firewall_proxy_address_data['state'] == "absent":
elif state == "absent":
return fos.delete('firewall',
'proxy-address',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
login(data)
methodlist = ['firewall_proxy_address']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['firewall_proxy_address']:
resp = firewall_proxy_address(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"firewall_proxy_address": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"case-sensitivity": {"required": False, "type": "str",
"case_sensitivity": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"category": {"required": False, "type": "list",
"options": {
@ -406,17 +465,17 @@ def main():
"color": {"required": False, "type": "int"},
"comment": {"required": False, "type": "str"},
"header": {"required": False, "type": "str"},
"header-group": {"required": False, "type": "list",
"header_group": {"required": False, "type": "list",
"options": {
"case-sensitivity": {"required": False, "type": "str",
"case_sensitivity": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"header": {"required": False, "type": "str"},
"header-name": {"required": False, "type": "str"},
"header_name": {"required": False, "type": "str"},
"id": {"required": True, "type": "int"}
}},
"header-name": {"required": False, "type": "str"},
"header_name": {"required": False, "type": "str"},
"host": {"required": False, "type": "str"},
"host-regex": {"required": False, "type": "str"},
"host_regex": {"required": False, "type": "str"},
"method": {"required": False, "type": "str",
"choices": ["get", "post", "put",
"head", "connect", "trace",
@ -452,15 +511,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_firewall(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_proxy_addrgrp
short_description: Web proxy address group configuration in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure firewall feature and proxy_addrgrp category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and proxy_addrgrp category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -44,89 +41,115 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
required: true
choices:
- present
- absent
version_added: 2.9
firewall_proxy_addrgrp:
description:
- Web proxy address group configuration.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
color:
description:
- Integer value to determine the color of the icon in the GUI (1 - 32, default = 0, which sets value to 1).
type: int
comment:
description:
- Optional comments.
type: str
member:
description:
- Members of address group.
type: list
suboptions:
name:
description:
- Address name. Source firewall.proxy-address.name firewall.proxy-addrgrp.name.
required: true
type: str
name:
description:
- Address group name.
required: true
type: str
tagging:
description:
- Config object tagging.
type: list
suboptions:
category:
description:
- Tag category. Source system.object-tagging.category.
type: str
name:
description:
- Tagging entry name.
required: true
type: str
tags:
description:
- Tags.
type: list
suboptions:
name:
description:
- Tag name. Source system.object-tagging.tags.name.
required: true
type: str
type:
description:
- Source or destination address group type.
type: str
choices:
- src
- dst
uuid:
description:
- Universally Unique Identifier (UUID; automatically assigned but can be manually reset).
type: str
visibility:
description:
- Enable/disable visibility of the object in the GUI.
type: str
choices:
- enable
- disable
@ -139,6 +162,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Web proxy address group configuration.
fortios_firewall_proxy_addrgrp:
@ -147,8 +171,8 @@ EXAMPLES = '''
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_proxy_addrgrp:
state: "present"
color: "3"
comment: "Optional comments."
member:
@ -227,14 +251,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data):
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -242,7 +268,7 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_proxy_addrgrp_data(json):
@ -258,48 +284,66 @@ def filter_firewall_proxy_addrgrp_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_proxy_addrgrp(data, fos):
vdom = data['vdom']
state = data['state']
firewall_proxy_addrgrp_data = data['firewall_proxy_addrgrp']
filtered_data = filter_firewall_proxy_addrgrp_data(firewall_proxy_addrgrp_data)
if firewall_proxy_addrgrp_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_firewall_proxy_addrgrp_data(firewall_proxy_addrgrp_data))
if state == "present":
return fos.set('firewall',
'proxy-addrgrp',
data=filtered_data,
vdom=vdom)
elif firewall_proxy_addrgrp_data['state'] == "absent":
elif state == "absent":
return fos.delete('firewall',
'proxy-addrgrp',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
login(data)
methodlist = ['firewall_proxy_addrgrp']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['firewall_proxy_addrgrp']:
resp = firewall_proxy_addrgrp(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"firewall_proxy_addrgrp": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"color": {"required": False, "type": "int"},
"comment": {"required": False, "type": "str"},
"member": {"required": False, "type": "list",
@ -328,15 +372,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_firewall(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_proxy_policy
short_description: Configure proxy policies in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure firewall feature and proxy_policy category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and proxy_policy category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -44,163 +41,204 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
required: true
choices:
- present
- absent
version_added: 2.9
firewall_proxy_policy:
description:
- Configure proxy policies.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
action:
description:
- Accept or deny traffic matching the policy parameters.
type: str
choices:
- accept
- deny
- redirect
application-list:
application_list:
description:
- Name of an existing Application list. Source application.list.name.
av-profile:
type: str
av_profile:
description:
- Name of an existing Antivirus profile. Source antivirus.profile.name.
type: str
comments:
description:
- Optional comments.
type: str
disclaimer:
description:
- "Web proxy disclaimer setting: by domain, policy, or user."
type: str
choices:
- disable
- domain
- policy
- user
dlp-sensor:
dlp_sensor:
description:
- Name of an existing DLP sensor. Source dlp.sensor.name.
type: str
dstaddr:
description:
- Destination address objects.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address.name firewall.addrgrp.name firewall.proxy-address.name firewall.proxy-addrgrp.name
firewall.vip.name firewall.vipgrp.name firewall.vip46.name firewall.vipgrp46.name system.external-resource.name.
required: true
dstaddr-negate:
type: str
dstaddr_negate:
description:
- When enabled, destination addresses match against any address EXCEPT the specified destination addresses.
type: str
choices:
- enable
- disable
dstaddr6:
description:
- IPv6 destination address objects.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address6.name firewall.addrgrp6.name firewall.vip6.name firewall.vipgrp6.name firewall.vip64.name
firewall.vipgrp64.name system.external-resource.name.
required: true
type: str
dstintf:
description:
- Destination interface names.
type: list
suboptions:
name:
description:
- Interface name. Source system.interface.name system.zone.name.
required: true
global-label:
type: str
global_label:
description:
- Global web-based manager visible label.
type: str
groups:
description:
- Names of group objects.
type: list
suboptions:
name:
description:
- Group name. Source user.group.name.
required: true
http-tunnel-auth:
type: str
http_tunnel_auth:
description:
- Enable/disable HTTP tunnel authentication.
type: str
choices:
- enable
- disable
icap-profile:
icap_profile:
description:
- Name of an existing ICAP profile. Source icap.profile.name.
internet-service:
type: str
internet_service:
description:
- Enable/disable use of Internet Services for this policy. If enabled, destination address and service are not used.
type: str
choices:
- enable
- disable
internet-service-custom:
internet_service_custom:
description:
- Custom Internet Service name.
type: list
suboptions:
name:
description:
- Custom name. Source firewall.internet-service-custom.name.
required: true
internet-service-id:
type: str
internet_service_id:
description:
- Internet Service ID.
type: list
suboptions:
id:
description:
- Internet Service ID. Source firewall.internet-service.id.
required: true
internet-service-negate:
type: int
internet_service_negate:
description:
- When enabled, Internet Services match against any internet service EXCEPT the selected Internet Service.
type: str
choices:
- enable
- disable
ips-sensor:
ips_sensor:
description:
- Name of an existing IPS sensor. Source ips.sensor.name.
type: str
label:
description:
- VDOM-specific GUI visible label.
type: str
logtraffic:
description:
- Enable/disable logging traffic through the policy.
type: str
choices:
- all
- utm
- disable
logtraffic-start:
logtraffic_start:
description:
- Enable/disable policy log traffic start.
type: str
choices:
- enable
- disable
@ -208,29 +246,36 @@ options:
description:
- Policy ID.
required: true
type: int
poolname:
description:
- Name of IP pool object.
type: list
suboptions:
name:
description:
- IP pool name. Source firewall.ippool.name.
required: true
profile-group:
type: str
profile_group:
description:
- Name of profile group. Source firewall.profile-group.name.
profile-protocol-options:
type: str
profile_protocol_options:
description:
- Name of an existing Protocol options profile. Source firewall.profile-protocol-options.name.
profile-type:
type: str
profile_type:
description:
- Determine whether the firewall policy allows security profile groups or single profiles only.
type: str
choices:
- single
- group
proxy:
description:
- Type of explicit proxy.
type: str
choices:
- explicit-web
- transparent-web
@ -238,15 +283,18 @@ options:
- ssh
- ssh-tunnel
- wanopt
redirect-url:
redirect_url:
description:
- Redirect URL for further explicit web proxy processing.
replacemsg-override-group:
type: str
replacemsg_override_group:
description:
- Authentication replacement message override group. Source system.replacemsg-group.name.
scan-botnet-connections:
type: str
scan_botnet_connections:
description:
- Enable/disable scanning of connections to Botnet servers.
type: str
choices:
- disable
- block
@ -254,116 +302,143 @@ options:
schedule:
description:
- Name of schedule object. Source firewall.schedule.onetime.name firewall.schedule.recurring.name firewall.schedule.group.name.
type: str
service:
description:
- Name of service objects.
type: list
suboptions:
name:
description:
- Service name. Source firewall.service.custom.name firewall.service.group.name.
required: true
service-negate:
type: str
service_negate:
description:
- When enabled, services match against any service EXCEPT the specified destination services.
type: str
choices:
- enable
- disable
session-ttl:
session_ttl:
description:
- TTL in seconds for sessions accepted by this policy (0 means use the system default session TTL).
spamfilter-profile:
type: int
spamfilter_profile:
description:
- Name of an existing Spam filter profile. Source spamfilter.profile.name.
type: str
srcaddr:
description:
- Source address objects (must be set when using Web proxy).
- Source address objects.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address.name firewall.addrgrp.name firewall.proxy-address.name firewall.proxy-addrgrp.name system
.external-resource.name.
required: true
srcaddr-negate:
type: str
srcaddr_negate:
description:
- When enabled, source addresses match against any address EXCEPT the specified source addresses.
type: str
choices:
- enable
- disable
srcaddr6:
description:
- IPv6 source address objects.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address6.name firewall.addrgrp6.name system.external-resource.name.
required: true
type: str
srcintf:
description:
- Source interface names.
type: list
suboptions:
name:
description:
- Interface name. Source system.interface.name system.zone.name.
required: true
ssh-filter-profile:
type: str
ssh_filter_profile:
description:
- Name of an existing SSH filter profile. Source ssh-filter.profile.name.
ssl-ssh-profile:
type: str
ssl_ssh_profile:
description:
- Name of an existing SSL SSH profile. Source firewall.ssl-ssh-profile.name.
type: str
status:
description:
- Enable/disable the active status of the policy.
type: str
choices:
- enable
- disable
transparent:
description:
- Enable to use the IP address of the client to connect to the server.
type: str
choices:
- enable
- disable
users:
description:
- Names of user objects.
type: list
suboptions:
name:
description:
- Group name. Source user.local.name.
required: true
utm-status:
type: str
utm_status:
description:
- Enable the use of UTM profiles/sensors/lists.
type: str
choices:
- enable
- disable
uuid:
description:
- Universally Unique Identifier (UUID; automatically assigned but can be manually reset).
waf-profile:
type: str
waf_profile:
description:
- Name of an existing Web application firewall profile. Source waf.profile.name.
type: str
webcache:
description:
- Enable/disable web caching.
type: str
choices:
- enable
- disable
webcache-https:
webcache_https:
description:
- Enable/disable web caching for HTTPS (Requires deep-inspection enabled in ssl-ssh-profile).
type: str
choices:
- disable
- enable
webfilter-profile:
webfilter_profile:
description:
- Name of an existing Web filter profile. Source webfilter.profile.name.
webproxy-forward-server:
type: str
webproxy_forward_server:
description:
- Name of web proxy forward server. Source web-proxy.forward-server.name web-proxy.forward-server-group.name.
webproxy-profile:
type: str
webproxy_profile:
description:
- Name of web proxy profile. Source web-proxy.profile.name.
type: str
'''
EXAMPLES = '''
@ -373,6 +448,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure proxy policies.
fortios_firewall_proxy_policy:
@ -381,19 +457,19 @@ EXAMPLES = '''
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_proxy_policy:
state: "present"
action: "accept"
application-list: "<your_own_value> (source application.list.name)"
av-profile: "<your_own_value> (source antivirus.profile.name)"
application_list: "<your_own_value> (source application.list.name)"
av_profile: "<your_own_value> (source antivirus.profile.name)"
comments: "<your_own_value>"
disclaimer: "disable"
dlp-sensor: "<your_own_value> (source dlp.sensor.name)"
dlp_sensor: "<your_own_value> (source dlp.sensor.name)"
dstaddr:
-
name: "default_name_10 (source firewall.address.name firewall.addrgrp.name firewall.proxy-address.name firewall.proxy-addrgrp.name firewall.vip
.name firewall.vipgrp.name firewall.vip46.name firewall.vipgrp46.name system.external-resource.name)"
dstaddr-negate: "enable"
dstaddr_negate: "enable"
dstaddr6:
-
name: "default_name_13 (source firewall.address6.name firewall.addrgrp6.name firewall.vip6.name firewall.vipgrp6.name firewall.vip64.name firewall
@ -401,68 +477,68 @@ EXAMPLES = '''
dstintf:
-
name: "default_name_15 (source system.interface.name system.zone.name)"
global-label: "<your_own_value>"
global_label: "<your_own_value>"
groups:
-
name: "default_name_18 (source user.group.name)"
http-tunnel-auth: "enable"
icap-profile: "<your_own_value> (source icap.profile.name)"
internet-service: "enable"
internet-service-custom:
http_tunnel_auth: "enable"
icap_profile: "<your_own_value> (source icap.profile.name)"
internet_service: "enable"
internet_service_custom:
-
name: "default_name_23 (source firewall.internet-service-custom.name)"
internet-service-id:
internet_service_id:
-
id: "25 (source firewall.internet-service.id)"
internet-service-negate: "enable"
ips-sensor: "<your_own_value> (source ips.sensor.name)"
internet_service_negate: "enable"
ips_sensor: "<your_own_value> (source ips.sensor.name)"
label: "<your_own_value>"
logtraffic: "all"
logtraffic-start: "enable"
logtraffic_start: "enable"
policyid: "31"
poolname:
-
name: "default_name_33 (source firewall.ippool.name)"
profile-group: "<your_own_value> (source firewall.profile-group.name)"
profile-protocol-options: "<your_own_value> (source firewall.profile-protocol-options.name)"
profile-type: "single"
profile_group: "<your_own_value> (source firewall.profile-group.name)"
profile_protocol_options: "<your_own_value> (source firewall.profile-protocol-options.name)"
profile_type: "single"
proxy: "explicit-web"
redirect-url: "<your_own_value>"
replacemsg-override-group: "<your_own_value> (source system.replacemsg-group.name)"
scan-botnet-connections: "disable"
redirect_url: "<your_own_value>"
replacemsg_override_group: "<your_own_value> (source system.replacemsg-group.name)"
scan_botnet_connections: "disable"
schedule: "<your_own_value> (source firewall.schedule.onetime.name firewall.schedule.recurring.name firewall.schedule.group.name)"
service:
-
name: "default_name_43 (source firewall.service.custom.name firewall.service.group.name)"
service-negate: "enable"
session-ttl: "45"
spamfilter-profile: "<your_own_value> (source spamfilter.profile.name)"
service_negate: "enable"
session_ttl: "45"
spamfilter_profile: "<your_own_value> (source spamfilter.profile.name)"
srcaddr:
-
name: "default_name_48 (source firewall.address.name firewall.addrgrp.name firewall.proxy-address.name firewall.proxy-addrgrp.name system
.external-resource.name)"
srcaddr-negate: "enable"
srcaddr_negate: "enable"
srcaddr6:
-
name: "default_name_51 (source firewall.address6.name firewall.addrgrp6.name system.external-resource.name)"
srcintf:
-
name: "default_name_53 (source system.interface.name system.zone.name)"
ssh-filter-profile: "<your_own_value> (source ssh-filter.profile.name)"
ssl-ssh-profile: "<your_own_value> (source firewall.ssl-ssh-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)"
status: "enable"
transparent: "enable"
users:
-
name: "default_name_59 (source user.local.name)"
utm-status: "enable"
utm_status: "enable"
uuid: "<your_own_value>"
waf-profile: "<your_own_value> (source waf.profile.name)"
waf_profile: "<your_own_value> (source waf.profile.name)"
webcache: "enable"
webcache-https: "disable"
webfilter-profile: "<your_own_value> (source webfilter.profile.name)"
webproxy-forward-server: "<your_own_value> (source web-proxy.forward-server.name web-proxy.forward-server-group.name)"
webproxy-profile: "<your_own_value> (source web-proxy.profile.name)"
webcache_https: "disable"
webfilter_profile: "<your_own_value> (source webfilter.profile.name)"
webproxy_forward_server: "<your_own_value> (source web-proxy.forward-server.name web-proxy.forward-server-group.name)"
webproxy_profile: "<your_own_value> (source web-proxy.profile.name)"
'''
RETURN = '''
@ -525,14 +601,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data):
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -540,28 +618,28 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_proxy_policy_data(json):
option_list = ['action', 'application-list', 'av-profile',
'comments', 'disclaimer', 'dlp-sensor',
'dstaddr', 'dstaddr-negate', 'dstaddr6',
'dstintf', 'global-label', 'groups',
'http-tunnel-auth', 'icap-profile', 'internet-service',
'internet-service-custom', 'internet-service-id', 'internet-service-negate',
'ips-sensor', 'label', 'logtraffic',
'logtraffic-start', 'policyid', 'poolname',
'profile-group', 'profile-protocol-options', 'profile-type',
'proxy', 'redirect-url', 'replacemsg-override-group',
'scan-botnet-connections', 'schedule', 'service',
'service-negate', 'session-ttl', 'spamfilter-profile',
'srcaddr', 'srcaddr-negate', 'srcaddr6',
'srcintf', 'ssh-filter-profile', 'ssl-ssh-profile',
option_list = ['action', 'application_list', 'av_profile',
'comments', 'disclaimer', 'dlp_sensor',
'dstaddr', 'dstaddr_negate', 'dstaddr6',
'dstintf', 'global_label', 'groups',
'http_tunnel_auth', 'icap_profile', 'internet_service',
'internet_service_custom', 'internet_service_id', 'internet_service_negate',
'ips_sensor', 'label', 'logtraffic',
'logtraffic_start', 'policyid', 'poolname',
'profile_group', 'profile_protocol_options', 'profile_type',
'proxy', 'redirect_url', 'replacemsg_override_group',
'scan_botnet_connections', 'schedule', 'service',
'service_negate', 'session_ttl', 'spamfilter_profile',
'srcaddr', 'srcaddr_negate', 'srcaddr6',
'srcintf', 'ssh_filter_profile', 'ssl_ssh_profile',
'status', 'transparent', 'users',
'utm-status', 'uuid', 'waf-profile',
'webcache', 'webcache-https', 'webfilter-profile',
'webproxy-forward-server', 'webproxy-profile']
'utm_status', 'uuid', 'waf_profile',
'webcache', 'webcache_https', 'webfilter_profile',
'webproxy_forward_server', 'webproxy_profile']
dictionary = {}
for attribute in option_list:
@ -571,62 +649,80 @@ def filter_firewall_proxy_policy_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_proxy_policy(data, fos):
vdom = data['vdom']
state = data['state']
firewall_proxy_policy_data = data['firewall_proxy_policy']
filtered_data = filter_firewall_proxy_policy_data(firewall_proxy_policy_data)
if firewall_proxy_policy_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_firewall_proxy_policy_data(firewall_proxy_policy_data))
if state == "present":
return fos.set('firewall',
'proxy-policy',
data=filtered_data,
vdom=vdom)
elif firewall_proxy_policy_data['state'] == "absent":
elif state == "absent":
return fos.delete('firewall',
'proxy-policy',
mkey=filtered_data['policyid'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
login(data)
methodlist = ['firewall_proxy_policy']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['firewall_proxy_policy']:
resp = firewall_proxy_policy(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"firewall_proxy_policy": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"action": {"required": False, "type": "str",
"choices": ["accept", "deny", "redirect"]},
"application-list": {"required": False, "type": "str"},
"av-profile": {"required": False, "type": "str"},
"application_list": {"required": False, "type": "str"},
"av_profile": {"required": False, "type": "str"},
"comments": {"required": False, "type": "str"},
"disclaimer": {"required": False, "type": "str",
"choices": ["disable", "domain", "policy",
"user"]},
"dlp-sensor": {"required": False, "type": "str"},
"dlp_sensor": {"required": False, "type": "str"},
"dstaddr": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"dstaddr-negate": {"required": False, "type": "str",
"dstaddr_negate": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"dstaddr6": {"required": False, "type": "list",
"options": {
@ -636,62 +732,62 @@ def main():
"options": {
"name": {"required": True, "type": "str"}
}},
"global-label": {"required": False, "type": "str"},
"global_label": {"required": False, "type": "str"},
"groups": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"http-tunnel-auth": {"required": False, "type": "str",
"http_tunnel_auth": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"icap-profile": {"required": False, "type": "str"},
"internet-service": {"required": False, "type": "str",
"icap_profile": {"required": False, "type": "str"},
"internet_service": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"internet-service-custom": {"required": False, "type": "list",
"internet_service_custom": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"internet-service-id": {"required": False, "type": "list",
"internet_service_id": {"required": False, "type": "list",
"options": {
"id": {"required": True, "type": "int"}
}},
"internet-service-negate": {"required": False, "type": "str",
"internet_service_negate": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"ips-sensor": {"required": False, "type": "str"},
"ips_sensor": {"required": False, "type": "str"},
"label": {"required": False, "type": "str"},
"logtraffic": {"required": False, "type": "str",
"choices": ["all", "utm", "disable"]},
"logtraffic-start": {"required": False, "type": "str",
"logtraffic_start": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"policyid": {"required": True, "type": "int"},
"poolname": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"profile-group": {"required": False, "type": "str"},
"profile-protocol-options": {"required": False, "type": "str"},
"profile-type": {"required": False, "type": "str",
"profile_group": {"required": False, "type": "str"},
"profile_protocol_options": {"required": False, "type": "str"},
"profile_type": {"required": False, "type": "str",
"choices": ["single", "group"]},
"proxy": {"required": False, "type": "str",
"choices": ["explicit-web", "transparent-web", "ftp",
"ssh", "ssh-tunnel", "wanopt"]},
"redirect-url": {"required": False, "type": "str"},
"replacemsg-override-group": {"required": False, "type": "str"},
"scan-botnet-connections": {"required": False, "type": "str",
"redirect_url": {"required": False, "type": "str"},
"replacemsg_override_group": {"required": False, "type": "str"},
"scan_botnet_connections": {"required": False, "type": "str",
"choices": ["disable", "block", "monitor"]},
"schedule": {"required": False, "type": "str"},
"service": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"service-negate": {"required": False, "type": "str",
"service_negate": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"session-ttl": {"required": False, "type": "int"},
"spamfilter-profile": {"required": False, "type": "str"},
"session_ttl": {"required": False, "type": "int"},
"spamfilter_profile": {"required": False, "type": "str"},
"srcaddr": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"srcaddr-negate": {"required": False, "type": "str",
"srcaddr_negate": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"srcaddr6": {"required": False, "type": "list",
"options": {
@ -701,8 +797,8 @@ def main():
"options": {
"name": {"required": True, "type": "str"}
}},
"ssh-filter-profile": {"required": False, "type": "str"},
"ssl-ssh-profile": {"required": False, "type": "str"},
"ssh_filter_profile": {"required": False, "type": "str"},
"ssl_ssh_profile": {"required": False, "type": "str"},
"status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"transparent": {"required": False, "type": "str",
@ -711,17 +807,17 @@ def main():
"options": {
"name": {"required": True, "type": "str"}
}},
"utm-status": {"required": False, "type": "str",
"utm_status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"uuid": {"required": False, "type": "str"},
"waf-profile": {"required": False, "type": "str"},
"waf_profile": {"required": False, "type": "str"},
"webcache": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"webcache-https": {"required": False, "type": "str",
"webcache_https": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"webfilter-profile": {"required": False, "type": "str"},
"webproxy-forward-server": {"required": False, "type": "str"},
"webproxy-profile": {"required": False, "type": "str"}
"webfilter_profile": {"required": False, "type": "str"},
"webproxy_forward_server": {"required": False, "type": "str"},
"webproxy_profile": {"required": False, "type": "str"}
}
}
@ -729,15 +825,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_firewall(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_schedule_group
short_description: Schedule group configuration in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure firewall_schedule feature and group category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall_schedule feature and group category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -44,55 +41,72 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip adress.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
required: true
choices:
- present
- absent
version_added: 2.9
firewall_schedule_group:
description:
- Schedule group configuration.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
color:
description:
- Color of icon on the GUI.
type: int
member:
description:
- Schedules added to the schedule group.
type: list
suboptions:
name:
description:
- Schedule name. Source firewall.schedule.onetime.name firewall.schedule.recurring.name.
required: true
type: str
name:
description:
- Schedule group name.
required: true
type: str
'''
EXAMPLES = '''
@ -102,6 +116,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Schedule group configuration.
fortios_firewall_schedule_group:
@ -110,8 +125,8 @@ EXAMPLES = '''
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_schedule_group:
state: "present"
color: "3"
member:
-
@ -179,14 +194,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data):
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -194,7 +211,7 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_schedule_group_data(json):
@ -208,48 +225,66 @@ def filter_firewall_schedule_group_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_schedule_group(data, fos):
vdom = data['vdom']
state = data['state']
firewall_schedule_group_data = data['firewall_schedule_group']
filtered_data = filter_firewall_schedule_group_data(firewall_schedule_group_data)
if firewall_schedule_group_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_firewall_schedule_group_data(firewall_schedule_group_data))
if state == "present":
return fos.set('firewall.schedule',
'group',
data=filtered_data,
vdom=vdom)
elif firewall_schedule_group_data['state'] == "absent":
elif state == "absent":
return fos.delete('firewall.schedule',
'group',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall_schedule(data, fos):
login(data)
methodlist = ['firewall_schedule_group']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['firewall_schedule_group']:
resp = firewall_schedule_group(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"firewall_schedule_group": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"color": {"required": False, "type": "int"},
"member": {"required": False, "type": "list",
"options": {
@ -263,15 +298,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall_schedule(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_schedule(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_firewall_schedule(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_schedule_onetime
short_description: Onetime schedule configuration in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure firewall_schedule feature and onetime category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall_schedule feature and onetime category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -44,56 +41,74 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip adress.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
required: true
choices:
- present
- absent
version_added: 2.9
firewall_schedule_onetime:
description:
- Onetime schedule configuration.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
color:
description:
- Color of icon on the GUI.
type: int
end:
description:
- "Schedule end date and time, format hh:mm yyyy/mm/dd."
expiration-days:
type: str
expiration_days:
description:
- Write an event log message this many days before the schedule expires.
type: int
name:
description:
- Onetime schedule name.
required: true
type: str
start:
description:
- "Schedule start date and time, format hh:mm yyyy/mm/dd."
type: str
'''
EXAMPLES = '''
@ -103,6 +118,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Onetime schedule configuration.
fortios_firewall_schedule_onetime:
@ -111,11 +127,11 @@ EXAMPLES = '''
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_schedule_onetime:
state: "present"
color: "3"
end: "<your_own_value>"
expiration-days: "5"
expiration_days: "5"
name: "default_name_6"
start: "<your_own_value>"
'''
@ -180,14 +196,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data):
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -195,11 +213,11 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_schedule_onetime_data(json):
option_list = ['color', 'end', 'expiration-days',
option_list = ['color', 'end', 'expiration_days',
'name', 'start']
dictionary = {}
@ -210,51 +228,69 @@ def filter_firewall_schedule_onetime_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_schedule_onetime(data, fos):
vdom = data['vdom']
state = data['state']
firewall_schedule_onetime_data = data['firewall_schedule_onetime']
filtered_data = filter_firewall_schedule_onetime_data(firewall_schedule_onetime_data)
if firewall_schedule_onetime_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_firewall_schedule_onetime_data(firewall_schedule_onetime_data))
if state == "present":
return fos.set('firewall.schedule',
'onetime',
data=filtered_data,
vdom=vdom)
elif firewall_schedule_onetime_data['state'] == "absent":
elif state == "absent":
return fos.delete('firewall.schedule',
'onetime',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall_schedule(data, fos):
login(data)
methodlist = ['firewall_schedule_onetime']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['firewall_schedule_onetime']:
resp = firewall_schedule_onetime(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"firewall_schedule_onetime": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"color": {"required": False, "type": "int"},
"end": {"required": False, "type": "str"},
"expiration-days": {"required": False, "type": "int"},
"expiration_days": {"required": False, "type": "int"},
"name": {"required": True, "type": "str"},
"start": {"required": False, "type": "str"}
@ -264,15 +300,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall_schedule(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_schedule(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_firewall_schedule(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_schedule_recurring
short_description: Recurring schedule configuration in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure firewall_schedule feature and recurring category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall_schedule feature and recurring category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -44,46 +41,61 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip adress.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
required: true
choices:
- present
- absent
version_added: 2.9
firewall_schedule_recurring:
description:
- Recurring schedule configuration.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
color:
description:
- Color of icon on the GUI.
type: int
day:
description:
- One or more days of the week on which the schedule is valid. Separate the names of the days with a space.
type: str
choices:
- sunday
- monday
@ -96,13 +108,16 @@ options:
end:
description:
- "Time of day to end the schedule, format hh:mm."
type: str
name:
description:
- Recurring schedule name.
required: true
type: str
start:
description:
- "Time of day to start the schedule, format hh:mm."
type: str
'''
EXAMPLES = '''
@ -112,6 +127,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Recurring schedule configuration.
fortios_firewall_schedule_recurring:
@ -120,8 +136,8 @@ EXAMPLES = '''
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_schedule_recurring:
state: "present"
color: "3"
day: "sunday"
end: "<your_own_value>"
@ -189,14 +205,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data):
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -204,7 +222,7 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_schedule_recurring_data(json):
@ -219,48 +237,66 @@ def filter_firewall_schedule_recurring_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_schedule_recurring(data, fos):
vdom = data['vdom']
state = data['state']
firewall_schedule_recurring_data = data['firewall_schedule_recurring']
filtered_data = filter_firewall_schedule_recurring_data(firewall_schedule_recurring_data)
if firewall_schedule_recurring_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_firewall_schedule_recurring_data(firewall_schedule_recurring_data))
if state == "present":
return fos.set('firewall.schedule',
'recurring',
data=filtered_data,
vdom=vdom)
elif firewall_schedule_recurring_data['state'] == "absent":
elif state == "absent":
return fos.delete('firewall.schedule',
'recurring',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall_schedule(data, fos):
login(data)
methodlist = ['firewall_schedule_recurring']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['firewall_schedule_recurring']:
resp = firewall_schedule_recurring(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"firewall_schedule_recurring": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"color": {"required": False, "type": "int"},
"day": {"required": False, "type": "str",
"choices": ["sunday", "monday", "tuesday",
@ -276,15 +312,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall_schedule(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_schedule(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_firewall_schedule(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_service_category
short_description: Configure service categories in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure firewall_service feature and category category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall_service feature and category category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -44,47 +41,62 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip adress.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
required: true
choices:
- present
- absent
version_added: 2.9
firewall_service_category:
description:
- Configure service categories.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
comment:
description:
- Comment.
type: str
name:
description:
- Service category name.
required: true
type: str
'''
EXAMPLES = '''
@ -94,6 +106,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure service categories.
fortios_firewall_service_category:
@ -102,8 +115,8 @@ EXAMPLES = '''
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_service_category:
state: "present"
comment: "Comment."
name: "default_name_4"
'''
@ -168,14 +181,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data):
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -183,7 +198,7 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_service_category_data(json):
@ -197,48 +212,66 @@ def filter_firewall_service_category_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_service_category(data, fos):
vdom = data['vdom']
state = data['state']
firewall_service_category_data = data['firewall_service_category']
filtered_data = filter_firewall_service_category_data(firewall_service_category_data)
if firewall_service_category_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_firewall_service_category_data(firewall_service_category_data))
if state == "present":
return fos.set('firewall.service',
'category',
data=filtered_data,
vdom=vdom)
elif firewall_service_category_data['state'] == "absent":
elif state == "absent":
return fos.delete('firewall.service',
'category',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall_service(data, fos):
login(data)
methodlist = ['firewall_service_category']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['firewall_service_category']:
resp = firewall_service_category(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"firewall_service_category": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"comment": {"required": False, "type": "str"},
"name": {"required": True, "type": "str"}
@ -248,15 +281,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall_service(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_service(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_firewall_service(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_service_custom
short_description: Configure custom services in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure firewall_service feature and custom category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall_service feature and custom category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -44,51 +41,67 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip adress.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
required: true
choices:
- present
- absent
version_added: 2.9
firewall_service_custom:
description:
- Configure custom services.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
app-category:
app_category:
description:
- Application category ID.
type: list
suboptions:
id:
description:
- Application category id.
required: true
app-service-type:
type: int
app_service_type:
description:
- Application service type.
type: str
choices:
- disable
- app-id
@ -96,17 +109,21 @@ options:
application:
description:
- Application ID.
type: list
suboptions:
id:
description:
- Application id.
required: true
type: int
category:
description:
- Service category. Source firewall.service.category.name.
check-reset-range:
type: str
check_reset_range:
description:
- Configure the type of ICMP error message verification.
type: str
choices:
- disable
- strict
@ -114,15 +131,19 @@ options:
color:
description:
- Color of icon on the GUI.
type: int
comment:
description:
- Comment.
type: str
fqdn:
description:
- Fully qualified domain name.
type: str
helper:
description:
- Helper name.
type: str
choices:
- auto
- disable
@ -147,19 +168,24 @@ options:
icmpcode:
description:
- ICMP code.
type: int
icmptype:
description:
- ICMP type.
type: int
iprange:
description:
- Start and end of the IP range associated with service.
type: str
name:
description:
- Custom service name.
required: true
type: str
protocol:
description:
- Protocol type based on IANA numbers.
type: str
choices:
- TCP/UDP/SCTP
- ICMP
@ -171,42 +197,53 @@ options:
- SOCKS-TCP
- SOCKS-UDP
- ALL
protocol-number:
protocol_number:
description:
- IP protocol number.
type: int
proxy:
description:
- Enable/disable web proxy service.
type: str
choices:
- enable
- disable
sctp-portrange:
sctp_portrange:
description:
- Multiple SCTP port ranges.
session-ttl:
type: str
session_ttl:
description:
- Session TTL (300 - 604800, 0 = default).
tcp-halfclose-timer:
type: int
tcp_halfclose_timer:
description:
- Wait time to close a TCP session waiting for an unanswered FIN packet (1 - 86400 sec, 0 = default).
tcp-halfopen-timer:
type: int
tcp_halfopen_timer:
description:
- Wait time to close a TCP session waiting for an unanswered open session packet (1 - 86400 sec, 0 = default).
tcp-portrange:
type: int
tcp_portrange:
description:
- Multiple TCP port ranges.
tcp-timewait-timer:
type: str
tcp_timewait_timer:
description:
- Set the length of the TCP TIME-WAIT state in seconds (1 - 300 sec, 0 = default).
udp-idle-timer:
type: int
udp_idle_timer:
description:
- UDP half close timeout (0 - 86400 sec, 0 = default).
udp-portrange:
type: int
udp_portrange:
description:
- Multiple UDP port ranges.
type: str
visibility:
description:
- Enable/disable the visibility of the service on the GUI.
type: str
choices:
- enable
- disable
@ -219,6 +256,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure custom services.
fortios_firewall_service_custom:
@ -227,17 +265,17 @@ EXAMPLES = '''
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_service_custom:
state: "present"
app-category:
app_category:
-
id: "4"
app-service-type: "disable"
app_service_type: "disable"
application:
-
id: "7"
category: "<your_own_value> (source firewall.service.category.name)"
check-reset-range: "disable"
check_reset_range: "disable"
color: "10"
comment: "Comment."
fqdn: "<your_own_value>"
@ -247,16 +285,16 @@ EXAMPLES = '''
iprange: "<your_own_value>"
name: "default_name_17"
protocol: "TCP/UDP/SCTP"
protocol-number: "19"
protocol_number: "19"
proxy: "enable"
sctp-portrange: "<your_own_value>"
session-ttl: "22"
tcp-halfclose-timer: "23"
tcp-halfopen-timer: "24"
tcp-portrange: "<your_own_value>"
tcp-timewait-timer: "26"
udp-idle-timer: "27"
udp-portrange: "<your_own_value>"
sctp_portrange: "<your_own_value>"
session_ttl: "22"
tcp_halfclose_timer: "23"
tcp_halfopen_timer: "24"
tcp_portrange: "<your_own_value>"
tcp_timewait_timer: "26"
udp_idle_timer: "27"
udp_portrange: "<your_own_value>"
visibility: "enable"
'''
@ -320,14 +358,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data):
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -335,18 +375,18 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_service_custom_data(json):
option_list = ['app-category', 'app-service-type', 'application',
'category', 'check-reset-range', 'color',
option_list = ['app_category', 'app_service_type', 'application',
'category', 'check_reset_range', 'color',
'comment', 'fqdn', 'helper',
'icmpcode', 'icmptype', 'iprange',
'name', 'protocol', 'protocol-number',
'proxy', 'sctp-portrange', 'session-ttl',
'tcp-halfclose-timer', 'tcp-halfopen-timer', 'tcp-portrange',
'tcp-timewait-timer', 'udp-idle-timer', 'udp-portrange',
'name', 'protocol', 'protocol_number',
'proxy', 'sctp_portrange', 'session_ttl',
'tcp_halfclose_timer', 'tcp_halfopen_timer', 'tcp_portrange',
'tcp_timewait_timer', 'udp_idle_timer', 'udp_portrange',
'visibility']
dictionary = {}
@ -357,60 +397,78 @@ def filter_firewall_service_custom_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_service_custom(data, fos):
vdom = data['vdom']
state = data['state']
firewall_service_custom_data = data['firewall_service_custom']
filtered_data = filter_firewall_service_custom_data(firewall_service_custom_data)
if firewall_service_custom_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_firewall_service_custom_data(firewall_service_custom_data))
if state == "present":
return fos.set('firewall.service',
'custom',
data=filtered_data,
vdom=vdom)
elif firewall_service_custom_data['state'] == "absent":
elif state == "absent":
return fos.delete('firewall.service',
'custom',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall_service(data, fos):
login(data)
methodlist = ['firewall_service_custom']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['firewall_service_custom']:
resp = firewall_service_custom(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"firewall_service_custom": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"app-category": {"required": False, "type": "list",
"app_category": {"required": False, "type": "list",
"options": {
"id": {"required": True, "type": "int"}
}},
"app-service-type": {"required": False, "type": "str",
"app_service_type": {"required": False, "type": "str",
"choices": ["disable", "app-id", "app-category"]},
"application": {"required": False, "type": "list",
"options": {
"id": {"required": True, "type": "int"}
}},
"category": {"required": False, "type": "str"},
"check-reset-range": {"required": False, "type": "str",
"check_reset_range": {"required": False, "type": "str",
"choices": ["disable", "strict", "default"]},
"color": {"required": False, "type": "int"},
"comment": {"required": False, "type": "str"},
@ -432,17 +490,17 @@ def main():
"IP", "HTTP", "FTP",
"CONNECT", "SOCKS-TCP", "SOCKS-UDP",
"ALL"]},
"protocol-number": {"required": False, "type": "int"},
"protocol_number": {"required": False, "type": "int"},
"proxy": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"sctp-portrange": {"required": False, "type": "str"},
"session-ttl": {"required": False, "type": "int"},
"tcp-halfclose-timer": {"required": False, "type": "int"},
"tcp-halfopen-timer": {"required": False, "type": "int"},
"tcp-portrange": {"required": False, "type": "str"},
"tcp-timewait-timer": {"required": False, "type": "int"},
"udp-idle-timer": {"required": False, "type": "int"},
"udp-portrange": {"required": False, "type": "str"},
"sctp_portrange": {"required": False, "type": "str"},
"session_ttl": {"required": False, "type": "int"},
"tcp_halfclose_timer": {"required": False, "type": "int"},
"tcp_halfopen_timer": {"required": False, "type": "int"},
"tcp_portrange": {"required": False, "type": "str"},
"tcp_timewait_timer": {"required": False, "type": "int"},
"udp_idle_timer": {"required": False, "type": "int"},
"udp_portrange": {"required": False, "type": "str"},
"visibility": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
@ -452,15 +510,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall_service(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_service(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_firewall_service(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_service_group
short_description: Configure service groups in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure firewall_service feature and group category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall_service feature and group category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -44,61 +41,80 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip adress.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
required: true
choices:
- present
- absent
version_added: 2.9
firewall_service_group:
description:
- Configure service groups.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
color:
description:
- Color of icon on the GUI.
type: int
comment:
description:
- Comment.
type: str
member:
description:
- Service objects contained within the group.
type: list
suboptions:
name:
description:
- Address name. Source firewall.service.custom.name firewall.service.group.name.
required: true
type: str
name:
description:
- Address group name.
required: true
type: str
proxy:
description:
- Enable/disable web proxy service group.
type: str
choices:
- enable
- disable
@ -111,6 +127,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure service groups.
fortios_firewall_service_group:
@ -119,8 +136,8 @@ EXAMPLES = '''
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_service_group:
state: "present"
color: "3"
comment: "Comment."
member:
@ -190,14 +207,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data):
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -205,7 +224,7 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_service_group_data(json):
@ -220,48 +239,66 @@ def filter_firewall_service_group_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_service_group(data, fos):
vdom = data['vdom']
state = data['state']
firewall_service_group_data = data['firewall_service_group']
filtered_data = filter_firewall_service_group_data(firewall_service_group_data)
if firewall_service_group_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_firewall_service_group_data(firewall_service_group_data))
if state == "present":
return fos.set('firewall.service',
'group',
data=filtered_data,
vdom=vdom)
elif firewall_service_group_data['state'] == "absent":
elif state == "absent":
return fos.delete('firewall.service',
'group',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall_service(data, fos):
login(data)
methodlist = ['firewall_service_group']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['firewall_service_group']:
resp = firewall_service_group(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"firewall_service_group": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"color": {"required": False, "type": "int"},
"comment": {"required": False, "type": "str"},
"member": {"required": False, "type": "list",
@ -278,15 +315,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall_service(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_service(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_firewall_service(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_shaper_per_ip_shaper
short_description: Configure per-IP traffic shaper in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure firewall_shaper feature and per_ip_shaper category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall_shaper feature and per_ip_shaper category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -44,75 +41,96 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip adress.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
required: true
choices:
- present
- absent
version_added: 2.9
firewall_shaper_per_ip_shaper:
description:
- Configure per-IP traffic shaper.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
bandwidth-unit:
bandwidth_unit:
description:
- Unit of measurement for maximum bandwidth for this shaper (Kbps, Mbps or Gbps).
type: str
choices:
- kbps
- mbps
- gbps
diffserv-forward:
diffserv_forward:
description:
- Enable/disable changing the Forward (original) DiffServ setting applied to traffic accepted by this shaper.
type: str
choices:
- enable
- disable
diffserv-reverse:
diffserv_reverse:
description:
- Enable/disable changing the Reverse (reply) DiffServ setting applied to traffic accepted by this shaper.
type: str
choices:
- enable
- disable
diffservcode-forward:
diffservcode_forward:
description:
- Forward (original) DiffServ setting to be applied to traffic accepted by this shaper.
diffservcode-rev:
type: str
diffservcode_rev:
description:
- Reverse (reply) DiffServ setting to be applied to traffic accepted by this shaper.
max-bandwidth:
type: str
max_bandwidth:
description:
- Upper bandwidth limit enforced by this shaper (0 - 16776000). 0 means no limit. Units depend on the bandwidth-unit setting.
max-concurrent-session:
type: int
max_concurrent_session:
description:
- Maximum number of concurrent sessions allowed by this shaper (0 - 2097000). 0 means no limit.
type: int
name:
description:
- Traffic shaper name.
required: true
type: str
'''
EXAMPLES = '''
@ -122,6 +140,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure per-IP traffic shaper.
fortios_firewall_shaper_per_ip_shaper:
@ -130,15 +149,15 @@ EXAMPLES = '''
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_shaper_per_ip_shaper:
state: "present"
bandwidth-unit: "kbps"
diffserv-forward: "enable"
diffserv-reverse: "enable"
diffservcode-forward: "<your_own_value>"
diffservcode-rev: "<your_own_value>"
max-bandwidth: "8"
max-concurrent-session: "9"
bandwidth_unit: "kbps"
diffserv_forward: "enable"
diffserv_reverse: "enable"
diffservcode_forward: "<your_own_value>"
diffservcode_rev: "<your_own_value>"
max_bandwidth: "8"
max_concurrent_session: "9"
name: "default_name_10"
'''
@ -202,14 +221,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data):
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -217,13 +238,13 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_shaper_per_ip_shaper_data(json):
option_list = ['bandwidth-unit', 'diffserv-forward', 'diffserv-reverse',
'diffservcode-forward', 'diffservcode-rev', 'max-bandwidth',
'max-concurrent-session', 'name']
option_list = ['bandwidth_unit', 'diffserv_forward', 'diffserv_reverse',
'diffservcode_forward', 'diffservcode_rev', 'max_bandwidth',
'max_concurrent_session', 'name']
dictionary = {}
for attribute in option_list:
@ -233,58 +254,76 @@ def filter_firewall_shaper_per_ip_shaper_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_shaper_per_ip_shaper(data, fos):
vdom = data['vdom']
state = data['state']
firewall_shaper_per_ip_shaper_data = data['firewall_shaper_per_ip_shaper']
filtered_data = filter_firewall_shaper_per_ip_shaper_data(firewall_shaper_per_ip_shaper_data)
if firewall_shaper_per_ip_shaper_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_firewall_shaper_per_ip_shaper_data(firewall_shaper_per_ip_shaper_data))
if state == "present":
return fos.set('firewall.shaper',
'per-ip-shaper',
data=filtered_data,
vdom=vdom)
elif firewall_shaper_per_ip_shaper_data['state'] == "absent":
elif state == "absent":
return fos.delete('firewall.shaper',
'per-ip-shaper',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall_shaper(data, fos):
login(data)
methodlist = ['firewall_shaper_per_ip_shaper']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['firewall_shaper_per_ip_shaper']:
resp = firewall_shaper_per_ip_shaper(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"firewall_shaper_per_ip_shaper": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"bandwidth-unit": {"required": False, "type": "str",
"bandwidth_unit": {"required": False, "type": "str",
"choices": ["kbps", "mbps", "gbps"]},
"diffserv-forward": {"required": False, "type": "str",
"diffserv_forward": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"diffserv-reverse": {"required": False, "type": "str",
"diffserv_reverse": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"diffservcode-forward": {"required": False, "type": "str"},
"diffservcode-rev": {"required": False, "type": "str"},
"max-bandwidth": {"required": False, "type": "int"},
"max-concurrent-session": {"required": False, "type": "int"},
"diffservcode_forward": {"required": False, "type": "str"},
"diffservcode_rev": {"required": False, "type": "str"},
"max_bandwidth": {"required": False, "type": "int"},
"max_concurrent_session": {"required": False, "type": "int"},
"name": {"required": True, "type": "str"}
}
@ -293,15 +332,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall_shaper(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_shaper(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_firewall_shaper(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_shaper_traffic_shaper
short_description: Configure shared traffic shaper in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure firewall_shaper feature and traffic_shaper category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall_shaper feature and traffic_shaper category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -44,43 +41,57 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip adress.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
required: true
choices:
- present
- absent
version_added: 2.9
firewall_shaper_traffic_shaper:
description:
- Configure shared traffic shaper.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
bandwidth-unit:
bandwidth_unit:
description:
- Unit of measurement for guaranteed and maximum bandwidth for this shaper (Kbps, Mbps or Gbps).
type: str
choices:
- kbps
- mbps
@ -88,32 +99,39 @@ options:
diffserv:
description:
- Enable/disable changing the DiffServ setting applied to traffic accepted by this shaper.
type: str
choices:
- enable
- disable
diffservcode:
description:
- DiffServ setting to be applied to traffic accepted by this shaper.
guaranteed-bandwidth:
type: str
guaranteed_bandwidth:
description:
- Amount of bandwidth guaranteed for this shaper (0 - 16776000). Units depend on the bandwidth-unit setting.
maximum-bandwidth:
type: int
maximum_bandwidth:
description:
- Upper bandwidth limit enforced by this shaper (0 - 16776000). 0 means no limit. Units depend on the bandwidth-unit setting.
type: int
name:
description:
- Traffic shaper name.
required: true
per-policy:
type: str
per_policy:
description:
- Enable/disable applying a separate shaper for each policy. For example, if enabled the guaranteed bandwidth is applied separately for
each policy.
type: str
choices:
- disable
- enable
priority:
description:
- Higher priority traffic is more likely to be forwarded without delays and without compromising the guaranteed bandwidth.
type: str
choices:
- low
- medium
@ -127,6 +145,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure shared traffic shaper.
fortios_firewall_shaper_traffic_shaper:
@ -135,15 +154,15 @@ EXAMPLES = '''
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_shaper_traffic_shaper:
state: "present"
bandwidth-unit: "kbps"
bandwidth_unit: "kbps"
diffserv: "enable"
diffservcode: "<your_own_value>"
guaranteed-bandwidth: "6"
maximum-bandwidth: "7"
guaranteed_bandwidth: "6"
maximum_bandwidth: "7"
name: "default_name_8"
per-policy: "disable"
per_policy: "disable"
priority: "low"
'''
@ -207,14 +226,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data):
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -222,13 +243,13 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_shaper_traffic_shaper_data(json):
option_list = ['bandwidth-unit', 'diffserv', 'diffservcode',
'guaranteed-bandwidth', 'maximum-bandwidth', 'name',
'per-policy', 'priority']
option_list = ['bandwidth_unit', 'diffserv', 'diffservcode',
'guaranteed_bandwidth', 'maximum_bandwidth', 'name',
'per_policy', 'priority']
dictionary = {}
for attribute in option_list:
@ -238,57 +259,75 @@ def filter_firewall_shaper_traffic_shaper_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_shaper_traffic_shaper(data, fos):
vdom = data['vdom']
state = data['state']
firewall_shaper_traffic_shaper_data = data['firewall_shaper_traffic_shaper']
filtered_data = filter_firewall_shaper_traffic_shaper_data(firewall_shaper_traffic_shaper_data)
if firewall_shaper_traffic_shaper_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_firewall_shaper_traffic_shaper_data(firewall_shaper_traffic_shaper_data))
if state == "present":
return fos.set('firewall.shaper',
'traffic-shaper',
data=filtered_data,
vdom=vdom)
elif firewall_shaper_traffic_shaper_data['state'] == "absent":
elif state == "absent":
return fos.delete('firewall.shaper',
'traffic-shaper',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall_shaper(data, fos):
login(data)
methodlist = ['firewall_shaper_traffic_shaper']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['firewall_shaper_traffic_shaper']:
resp = firewall_shaper_traffic_shaper(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"firewall_shaper_traffic_shaper": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"bandwidth-unit": {"required": False, "type": "str",
"bandwidth_unit": {"required": False, "type": "str",
"choices": ["kbps", "mbps", "gbps"]},
"diffserv": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"diffservcode": {"required": False, "type": "str"},
"guaranteed-bandwidth": {"required": False, "type": "int"},
"maximum-bandwidth": {"required": False, "type": "int"},
"guaranteed_bandwidth": {"required": False, "type": "int"},
"maximum_bandwidth": {"required": False, "type": "int"},
"name": {"required": True, "type": "str"},
"per-policy": {"required": False, "type": "str",
"per_policy": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"priority": {"required": False, "type": "str",
"choices": ["low", "medium", "high"]}
@ -299,15 +338,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall_shaper(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_shaper(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_firewall_shaper(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_shaping_policy
short_description: Configure shaping policies in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure firewall feature and shaping_policy category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and shaping_policy category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -44,206 +41,260 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip adress.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
required: true
choices:
- present
- absent
version_added: 2.9
firewall_shaping_policy:
description:
- Configure shaping policies.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
app-category:
app_category:
description:
- IDs of one or more application categories that this shaper applies application control traffic shaping to.
type: list
suboptions:
id:
description:
- Category IDs.
required: true
type: int
application:
description:
- IDs of one or more applications that this shaper applies application control traffic shaping to.
type: list
suboptions:
id:
description:
- Application IDs.
required: true
class-id:
type: int
class_id:
description:
- Traffic class ID.
type: int
comment:
description:
- Comments.
type: str
dstaddr:
description:
- IPv4 destination address and address group names.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address.name firewall.addrgrp.name.
required: true
type: str
dstaddr6:
description:
- IPv6 destination address and address group names.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address6.name firewall.addrgrp6.name.
required: true
type: str
dstintf:
description:
- One or more outgoing (egress) interfaces.
type: list
suboptions:
name:
description:
- Interface name. Source system.interface.name system.zone.name.
required: true
type: str
groups:
description:
- Apply this traffic shaping policy to user groups that have authenticated with the FortiGate.
type: list
suboptions:
name:
description:
- Group name. Source user.group.name.
required: true
type: str
id:
description:
- Shaping policy ID.
required: true
internet-service:
type: int
internet_service:
description:
- Enable/disable use of Internet Services for this policy. If enabled, destination address and service are not used.
type: str
choices:
- enable
- disable
internet-service-custom:
internet_service_custom:
description:
- Custom Internet Service name.
type: list
suboptions:
name:
description:
- Custom Internet Service name. Source firewall.internet-service-custom.name.
required: true
internet-service-id:
type: str
internet_service_id:
description:
- Internet Service ID.
type: list
suboptions:
id:
description:
- Internet Service ID. Source firewall.internet-service.id.
required: true
internet-service-src:
type: int
internet_service_src:
description:
- Enable/disable use of Internet Services in source for this policy. If enabled, source address is not used.
type: str
choices:
- enable
- disable
internet-service-src-custom:
internet_service_src_custom:
description:
- Custom Internet Service source name.
type: list
suboptions:
name:
description:
- Custom Internet Service name. Source firewall.internet-service-custom.name.
required: true
internet-service-src-id:
type: str
internet_service_src_id:
description:
- Internet Service source ID.
type: list
suboptions:
id:
description:
- Internet Service ID. Source firewall.internet-service.id.
required: true
ip-version:
type: int
ip_version:
description:
- Apply this traffic shaping policy to IPv4 or IPv6 traffic.
type: str
choices:
- 4
- 6
per-ip-shaper:
per_ip_shaper:
description:
- Per-IP traffic shaper to apply with this policy. Source firewall.shaper.per-ip-shaper.name.
type: str
schedule:
description:
- Schedule name. Source firewall.schedule.onetime.name firewall.schedule.recurring.name firewall.schedule.group.name.
type: str
service:
description:
- Service and service group names.
type: list
suboptions:
name:
description:
- Service name. Source firewall.service.custom.name firewall.service.group.name.
required: true
type: str
srcaddr:
description:
- IPv4 source address and address group names.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address.name firewall.addrgrp.name.
required: true
type: str
srcaddr6:
description:
- IPv6 source address and address group names.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address6.name firewall.addrgrp6.name.
required: true
type: str
status:
description:
- Enable/disable this traffic shaping policy.
type: str
choices:
- enable
- disable
traffic-shaper:
traffic_shaper:
description:
- Traffic shaper to apply to traffic forwarded by the firewall policy. Source firewall.shaper.traffic-shaper.name.
traffic-shaper-reverse:
type: str
traffic_shaper_reverse:
description:
- Traffic shaper to apply to response traffic received by the firewall policy. Source firewall.shaper.traffic-shaper.name.
url-category:
type: str
url_category:
description:
- IDs of one or more FortiGuard Web Filtering categories that this shaper applies traffic shaping to.
type: list
suboptions:
id:
description:
- URL category ID.
required: true
type: int
users:
description:
- Apply this traffic shaping policy to individual users that have authenticated with the FortiGate.
type: list
suboptions:
name:
description:
- User name. Source user.local.name.
required: true
type: str
'''
EXAMPLES = '''
@ -253,6 +304,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure shaping policies.
fortios_firewall_shaping_policy:
@ -261,15 +313,15 @@ EXAMPLES = '''
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_shaping_policy:
state: "present"
app-category:
app_category:
-
id: "4"
application:
-
id: "6"
class-id: "7"
class_id: "7"
comment: "Comments."
dstaddr:
-
@ -284,22 +336,22 @@ EXAMPLES = '''
-
name: "default_name_16 (source user.group.name)"
id: "17"
internet-service: "enable"
internet-service-custom:
internet_service: "enable"
internet_service_custom:
-
name: "default_name_20 (source firewall.internet-service-custom.name)"
internet-service-id:
internet_service_id:
-
id: "22 (source firewall.internet-service.id)"
internet-service-src: "enable"
internet-service-src-custom:
internet_service_src: "enable"
internet_service_src_custom:
-
name: "default_name_25 (source firewall.internet-service-custom.name)"
internet-service-src-id:
internet_service_src_id:
-
id: "27 (source firewall.internet-service.id)"
ip-version: "4"
per-ip-shaper: "<your_own_value> (source firewall.shaper.per-ip-shaper.name)"
ip_version: "4"
per_ip_shaper: "<your_own_value> (source firewall.shaper.per-ip-shaper.name)"
schedule: "<your_own_value> (source firewall.schedule.onetime.name firewall.schedule.recurring.name firewall.schedule.group.name)"
service:
-
@ -311,9 +363,9 @@ EXAMPLES = '''
-
name: "default_name_36 (source firewall.address6.name firewall.addrgrp6.name)"
status: "enable"
traffic-shaper: "<your_own_value> (source firewall.shaper.traffic-shaper.name)"
traffic-shaper-reverse: "<your_own_value> (source firewall.shaper.traffic-shaper.name)"
url-category:
traffic_shaper: "<your_own_value> (source firewall.shaper.traffic-shaper.name)"
traffic_shaper_reverse: "<your_own_value> (source firewall.shaper.traffic-shaper.name)"
url_category:
-
id: "41"
users:
@ -381,14 +433,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data):
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -396,19 +450,19 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_shaping_policy_data(json):
option_list = ['app-category', 'application', 'class-id',
option_list = ['app_category', 'application', 'class_id',
'comment', 'dstaddr', 'dstaddr6',
'dstintf', 'groups', 'id',
'internet-service', 'internet-service-custom', 'internet-service-id',
'internet-service-src', 'internet-service-src-custom', 'internet-service-src-id',
'ip-version', 'per-ip-shaper', 'schedule',
'internet_service', 'internet_service_custom', 'internet_service_id',
'internet_service_src', 'internet_service_src_custom', 'internet_service_src_id',
'ip_version', 'per_ip_shaper', 'schedule',
'service', 'srcaddr', 'srcaddr6',
'status', 'traffic-shaper', 'traffic-shaper-reverse',
'url-category', 'users']
'status', 'traffic_shaper', 'traffic_shaper_reverse',
'url_category', 'users']
dictionary = {}
for attribute in option_list:
@ -418,49 +472,67 @@ def filter_firewall_shaping_policy_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_shaping_policy(data, fos):
vdom = data['vdom']
state = data['state']
firewall_shaping_policy_data = data['firewall_shaping_policy']
filtered_data = filter_firewall_shaping_policy_data(firewall_shaping_policy_data)
if firewall_shaping_policy_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_firewall_shaping_policy_data(firewall_shaping_policy_data))
if state == "present":
return fos.set('firewall',
'shaping-policy',
data=filtered_data,
vdom=vdom)
elif firewall_shaping_policy_data['state'] == "absent":
elif state == "absent":
return fos.delete('firewall',
'shaping-policy',
mkey=filtered_data['id'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
login(data)
methodlist = ['firewall_shaping_policy']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['firewall_shaping_policy']:
resp = firewall_shaping_policy(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"firewall_shaping_policy": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"app-category": {"required": False, "type": "list",
"app_category": {"required": False, "type": "list",
"options": {
"id": {"required": True, "type": "int"}
}},
@ -468,7 +540,7 @@ def main():
"options": {
"id": {"required": True, "type": "int"}
}},
"class-id": {"required": False, "type": "int"},
"class_id": {"required": False, "type": "int"},
"comment": {"required": False, "type": "str"},
"dstaddr": {"required": False, "type": "list",
"options": {
@ -487,29 +559,29 @@ def main():
"name": {"required": True, "type": "str"}
}},
"id": {"required": True, "type": "int"},
"internet-service": {"required": False, "type": "str",
"internet_service": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"internet-service-custom": {"required": False, "type": "list",
"internet_service_custom": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"internet-service-id": {"required": False, "type": "list",
"internet_service_id": {"required": False, "type": "list",
"options": {
"id": {"required": True, "type": "int"}
}},
"internet-service-src": {"required": False, "type": "str",
"internet_service_src": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"internet-service-src-custom": {"required": False, "type": "list",
"internet_service_src_custom": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"internet-service-src-id": {"required": False, "type": "list",
"internet_service_src_id": {"required": False, "type": "list",
"options": {
"id": {"required": True, "type": "int"}
}},
"ip-version": {"required": False, "type": "str",
"ip_version": {"required": False, "type": "str",
"choices": ["4", "6"]},
"per-ip-shaper": {"required": False, "type": "str"},
"per_ip_shaper": {"required": False, "type": "str"},
"schedule": {"required": False, "type": "str"},
"service": {"required": False, "type": "list",
"options": {
@ -525,9 +597,9 @@ def main():
}},
"status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"traffic-shaper": {"required": False, "type": "str"},
"traffic-shaper-reverse": {"required": False, "type": "str"},
"url-category": {"required": False, "type": "list",
"traffic_shaper": {"required": False, "type": "str"},
"traffic_shaper_reverse": {"required": False, "type": "str"},
"url_category": {"required": False, "type": "list",
"options": {
"id": {"required": True, "type": "int"}
}},
@ -542,15 +614,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_firewall(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_shaping_profile
short_description: Configure shaping profiles in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure firewall feature and shaping_profile category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and shaping_profile category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -44,70 +41,91 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip adress.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
required: true
choices:
- present
- absent
version_added: 2.9
firewall_shaping_profile:
description:
- Configure shaping profiles.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
comment:
description:
- Comment.
default-class-id:
type: str
default_class_id:
description:
- Default class ID to handle unclassified packets (including all local traffic).
profile-name:
type: int
profile_name:
description:
- Shaping profile name.
required: true
shaping-entries:
type: str
shaping_entries:
description:
- Define shaping entries of this shaping profile.
type: list
suboptions:
class-id:
class_id:
description:
- Class ID.
guaranteed-bandwidth-percentage:
type: int
guaranteed_bandwidth_percentage:
description:
- Guaranteed bandwith in percentage.
type: int
id:
description:
- ID number.
required: true
maximum-bandwidth-percentage:
type: int
maximum_bandwidth_percentage:
description:
- Maximum bandwith in percentage.
type: int
priority:
description:
- Priority.
type: str
choices:
- high
- medium
@ -121,6 +139,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure shaping profiles.
fortios_firewall_shaping_profile:
@ -129,17 +148,17 @@ EXAMPLES = '''
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_shaping_profile:
state: "present"
comment: "Comment."
default-class-id: "4"
profile-name: "<your_own_value>"
shaping-entries:
default_class_id: "4"
profile_name: "<your_own_value>"
shaping_entries:
-
class-id: "7"
guaranteed-bandwidth-percentage: "8"
class_id: "7"
guaranteed_bandwidth_percentage: "8"
id: "9"
maximum-bandwidth-percentage: "10"
maximum_bandwidth_percentage: "10"
priority: "high"
'''
@ -203,14 +222,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data):
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -218,12 +239,12 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_shaping_profile_data(json):
option_list = ['comment', 'default-class-id', 'profile-name',
'shaping-entries']
option_list = ['comment', 'default_class_id', 'profile_name',
'shaping_entries']
dictionary = {}
for attribute in option_list:
@ -233,57 +254,75 @@ def filter_firewall_shaping_profile_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_shaping_profile(data, fos):
vdom = data['vdom']
state = data['state']
firewall_shaping_profile_data = data['firewall_shaping_profile']
filtered_data = filter_firewall_shaping_profile_data(firewall_shaping_profile_data)
if firewall_shaping_profile_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_firewall_shaping_profile_data(firewall_shaping_profile_data))
if state == "present":
return fos.set('firewall',
'shaping-profile',
data=filtered_data,
vdom=vdom)
elif firewall_shaping_profile_data['state'] == "absent":
elif state == "absent":
return fos.delete('firewall',
'shaping-profile',
mkey=filtered_data['profile-name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
login(data)
methodlist = ['firewall_shaping_profile']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['firewall_shaping_profile']:
resp = firewall_shaping_profile(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"firewall_shaping_profile": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"comment": {"required": False, "type": "str"},
"default-class-id": {"required": False, "type": "int"},
"profile-name": {"required": True, "type": "str"},
"shaping-entries": {"required": False, "type": "list",
"default_class_id": {"required": False, "type": "int"},
"profile_name": {"required": False, "type": "str"},
"shaping_entries": {"required": False, "type": "list",
"options": {
"class-id": {"required": False, "type": "int"},
"guaranteed-bandwidth-percentage": {"required": False, "type": "int"},
"class_id": {"required": False, "type": "int"},
"guaranteed_bandwidth_percentage": {"required": False, "type": "int"},
"id": {"required": True, "type": "int"},
"maximum-bandwidth-percentage": {"required": False, "type": "int"},
"maximum_bandwidth_percentage": {"required": False, "type": "int"},
"priority": {"required": False, "type": "str",
"choices": ["high", "medium", "low"]}
}}
@ -294,15 +333,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_firewall(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_sniffer
short_description: Configure sniffer in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure firewall feature and sniffer category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and sniffer category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -44,53 +41,69 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip adress.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
required: true
choices:
- present
- absent
version_added: 2.9
firewall_sniffer:
description:
- Configure sniffer.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
anomaly:
description:
- Configuration method to edit Denial of Service (DoS) anomaly settings.
type: list
suboptions:
action:
description:
- Action taken when the threshold is reached.
type: str
choices:
- pass
- block
log:
description:
- Enable/disable anomaly logging.
type: str
choices:
- enable
- disable
@ -98,151 +111,184 @@ options:
description:
- Anomaly name.
required: true
type: str
quarantine:
description:
- Quarantine method.
type: str
choices:
- none
- attacker
quarantine-expiry:
quarantine_expiry:
description:
- Duration of quarantine. (Format ###d##h##m, minimum 1m, maximum 364d23h59m, default = 5m). Requires quarantine set to attacker.
quarantine-log:
type: str
quarantine_log:
description:
- Enable/disable quarantine logging.
type: str
choices:
- disable
- enable
status:
description:
- Enable/disable this anomaly.
type: str
choices:
- disable
- enable
threshold:
description:
- Anomaly threshold. Number of detected instances per minute that triggers the anomaly action.
type: int
threshold(default):
description:
- Number of detected instances per minute which triggers action (1 - 2147483647, default = 1000). Note that each anomaly has a
different threshold value assigned to it.
application-list:
type: int
application_list:
description:
- Name of an existing application list. Source application.list.name.
application-list-status:
type: str
application_list_status:
description:
- Enable/disable application control profile.
type: str
choices:
- enable
- disable
av-profile:
av_profile:
description:
- Name of an existing antivirus profile. Source antivirus.profile.name.
av-profile-status:
type: str
av_profile_status:
description:
- Enable/disable antivirus profile.
type: str
choices:
- enable
- disable
dlp-sensor:
dlp_sensor:
description:
- Name of an existing DLP sensor. Source dlp.sensor.name.
dlp-sensor-status:
type: str
dlp_sensor_status:
description:
- Enable/disable DLP sensor.
type: str
choices:
- enable
- disable
dsri:
description:
- Enable/disable DSRI.
type: str
choices:
- enable
- disable
host:
description:
- "Hosts to filter for in sniffer traffic (Format examples: 1.1.1.1, 2.2.2.0/24, 3.3.3.3/255.255.255.0, 4.4.4.0-4.4.4.240)."
type: str
id:
description:
- Sniffer ID.
required: true
type: int
interface:
description:
- Interface name that traffic sniffing will take place on. Source system.interface.name.
ips-dos-status:
type: str
ips_dos_status:
description:
- Enable/disable IPS DoS anomaly detection.
type: str
choices:
- enable
- disable
ips-sensor:
ips_sensor:
description:
- Name of an existing IPS sensor. Source ips.sensor.name.
ips-sensor-status:
type: str
ips_sensor_status:
description:
- Enable/disable IPS sensor.
type: str
choices:
- enable
- disable
ipv6:
description:
- Enable/disable sniffing IPv6 packets.
type: str
choices:
- enable
- disable
logtraffic:
description:
- Either log all sessions, only sessions that have a security profile applied, or disable all logging for this policy.
type: str
choices:
- all
- utm
- disable
max-packet-count:
max_packet_count:
description:
- Maximum packet count (1 - 1000000, default = 10000).
non-ip:
type: int
non_ip:
description:
- Enable/disable sniffing non-IP packets.
type: str
choices:
- enable
- disable
port:
description:
- "Ports to sniff (Format examples: 10, :20, 30:40, 50-, 100-200)."
type: str
protocol:
description:
- Integer value for the protocol type as defined by IANA (0 - 255).
scan-botnet-connections:
type: str
scan_botnet_connections:
description:
- Enable/disable scanning of connections to Botnet servers.
type: str
choices:
- disable
- block
- monitor
spamfilter-profile:
spamfilter_profile:
description:
- Name of an existing spam filter profile. Source spamfilter.profile.name.
spamfilter-profile-status:
type: str
spamfilter_profile_status:
description:
- Enable/disable spam filter.
type: str
choices:
- enable
- disable
status:
description:
- Enable/disable the active status of the sniffer.
type: str
choices:
- enable
- disable
vlan:
description:
- List of VLANs to sniff.
webfilter-profile:
type: str
webfilter_profile:
description:
- Name of an existing web filter profile. Source webfilter.profile.name.
webfilter-profile-status:
type: str
webfilter_profile_status:
description:
- Enable/disable web filter profile.
type: str
choices:
- enable
- disable
@ -255,6 +301,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure sniffer.
fortios_firewall_sniffer:
@ -263,45 +310,45 @@ EXAMPLES = '''
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_sniffer:
state: "present"
anomaly:
-
action: "pass"
log: "enable"
name: "default_name_6"
quarantine: "none"
quarantine-expiry: "<your_own_value>"
quarantine-log: "disable"
quarantine_expiry: "<your_own_value>"
quarantine_log: "disable"
status: "disable"
threshold: "11"
threshold(default): "12"
application-list: "<your_own_value> (source application.list.name)"
application-list-status: "enable"
av-profile: "<your_own_value> (source antivirus.profile.name)"
av-profile-status: "enable"
dlp-sensor: "<your_own_value> (source dlp.sensor.name)"
dlp-sensor-status: "enable"
application_list: "<your_own_value> (source application.list.name)"
application_list_status: "enable"
av_profile: "<your_own_value> (source antivirus.profile.name)"
av_profile_status: "enable"
dlp_sensor: "<your_own_value> (source dlp.sensor.name)"
dlp_sensor_status: "enable"
dsri: "enable"
host: "myhostname"
id: "21"
interface: "<your_own_value> (source system.interface.name)"
ips-dos-status: "enable"
ips-sensor: "<your_own_value> (source ips.sensor.name)"
ips-sensor-status: "enable"
ips_dos_status: "enable"
ips_sensor: "<your_own_value> (source ips.sensor.name)"
ips_sensor_status: "enable"
ipv6: "enable"
logtraffic: "all"
max-packet-count: "28"
non-ip: "enable"
max_packet_count: "28"
non_ip: "enable"
port: "<your_own_value>"
protocol: "<your_own_value>"
scan-botnet-connections: "disable"
spamfilter-profile: "<your_own_value> (source spamfilter.profile.name)"
spamfilter-profile-status: "enable"
scan_botnet_connections: "disable"
spamfilter_profile: "<your_own_value> (source spamfilter.profile.name)"
spamfilter_profile_status: "enable"
status: "enable"
vlan: "<your_own_value>"
webfilter-profile: "<your_own_value> (source webfilter.profile.name)"
webfilter-profile-status: "enable"
webfilter_profile: "<your_own_value> (source webfilter.profile.name)"
webfilter_profile_status: "enable"
'''
RETURN = '''
@ -364,14 +411,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data):
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -379,19 +428,19 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_sniffer_data(json):
option_list = ['anomaly', 'application-list', 'application-list-status',
'av-profile', 'av-profile-status', 'dlp-sensor',
'dlp-sensor-status', 'dsri', 'host',
'id', 'interface', 'ips-dos-status',
'ips-sensor', 'ips-sensor-status', 'ipv6',
'logtraffic', 'max-packet-count', 'non-ip',
'port', 'protocol', 'scan-botnet-connections',
'spamfilter-profile', 'spamfilter-profile-status', 'status',
'vlan', 'webfilter-profile', 'webfilter-profile-status']
option_list = ['anomaly', 'application_list', 'application_list_status',
'av_profile', 'av_profile_status', 'dlp_sensor',
'dlp_sensor_status', 'dsri', 'host',
'id', 'interface', 'ips_dos_status',
'ips_sensor', 'ips_sensor_status', 'ipv6',
'logtraffic', 'max_packet_count', 'non_ip',
'port', 'protocol', 'scan_botnet_connections',
'spamfilter_profile', 'spamfilter_profile_status', 'status',
'vlan', 'webfilter_profile', 'webfilter_profile_status']
dictionary = {}
for attribute in option_list:
@ -401,48 +450,66 @@ def filter_firewall_sniffer_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_sniffer(data, fos):
vdom = data['vdom']
state = data['state']
firewall_sniffer_data = data['firewall_sniffer']
filtered_data = filter_firewall_sniffer_data(firewall_sniffer_data)
if firewall_sniffer_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_firewall_sniffer_data(firewall_sniffer_data))
if state == "present":
return fos.set('firewall',
'sniffer',
data=filtered_data,
vdom=vdom)
elif firewall_sniffer_data['state'] == "absent":
elif state == "absent":
return fos.delete('firewall',
'sniffer',
mkey=filtered_data['id'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
login(data)
methodlist = ['firewall_sniffer']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['firewall_sniffer']:
resp = firewall_sniffer(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"firewall_sniffer": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"anomaly": {"required": False, "type": "list",
"options": {
"action": {"required": False, "type": "str",
@ -452,52 +519,52 @@ def main():
"name": {"required": True, "type": "str"},
"quarantine": {"required": False, "type": "str",
"choices": ["none", "attacker"]},
"quarantine-expiry": {"required": False, "type": "str"},
"quarantine-log": {"required": False, "type": "str",
"quarantine_expiry": {"required": False, "type": "str"},
"quarantine_log": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"status": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"threshold": {"required": False, "type": "int"},
"threshold(default)": {"required": False, "type": "int"}
}},
"application-list": {"required": False, "type": "str"},
"application-list-status": {"required": False, "type": "str",
"application_list": {"required": False, "type": "str"},
"application_list_status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"av-profile": {"required": False, "type": "str"},
"av-profile-status": {"required": False, "type": "str",
"av_profile": {"required": False, "type": "str"},
"av_profile_status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"dlp-sensor": {"required": False, "type": "str"},
"dlp-sensor-status": {"required": False, "type": "str",
"dlp_sensor": {"required": False, "type": "str"},
"dlp_sensor_status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"dsri": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"host": {"required": False, "type": "str"},
"id": {"required": True, "type": "int"},
"interface": {"required": False, "type": "str"},
"ips-dos-status": {"required": False, "type": "str",
"ips_dos_status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"ips-sensor": {"required": False, "type": "str"},
"ips-sensor-status": {"required": False, "type": "str",
"ips_sensor": {"required": False, "type": "str"},
"ips_sensor_status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"ipv6": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"logtraffic": {"required": False, "type": "str",
"choices": ["all", "utm", "disable"]},
"max-packet-count": {"required": False, "type": "int"},
"non-ip": {"required": False, "type": "str",
"max_packet_count": {"required": False, "type": "int"},
"non_ip": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"port": {"required": False, "type": "str"},
"protocol": {"required": False, "type": "str"},
"scan-botnet-connections": {"required": False, "type": "str",
"scan_botnet_connections": {"required": False, "type": "str",
"choices": ["disable", "block", "monitor"]},
"spamfilter-profile": {"required": False, "type": "str"},
"spamfilter-profile-status": {"required": False, "type": "str",
"spamfilter_profile": {"required": False, "type": "str"},
"spamfilter_profile_status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"vlan": {"required": False, "type": "str"},
"webfilter-profile": {"required": False, "type": "str"},
"webfilter-profile-status": {"required": False, "type": "str",
"webfilter_profile": {"required": False, "type": "str"},
"webfilter_profile_status": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
@ -506,15 +573,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_firewall(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_ssh_host_key
short_description: SSH proxy host public keys in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure firewall_ssh feature and host_key category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall_ssh feature and host_key category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -44,53 +41,70 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip adress.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
required: true
choices:
- present
- absent
version_added: 2.9
firewall_ssh_host_key:
description:
- SSH proxy host public keys.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
hostname:
description:
- Hostname of the SSH server.
type: str
ip:
description:
- IP address of the SSH server.
type: str
name:
description:
- SSH public key name.
required: true
type: str
nid:
description:
- Set the nid of the ECDSA key.
type: str
choices:
- 256
- 384
@ -98,18 +112,22 @@ options:
port:
description:
- Port of the SSH server.
public-key:
type: int
public_key:
description:
- SSH public key.
type: str
status:
description:
- Set the trust status of the public key.
type: str
choices:
- trusted
- revoked
type:
description:
- Set the type of the public key.
type: str
choices:
- RSA
- DSA
@ -128,6 +146,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: SSH proxy host public keys.
fortios_firewall_ssh_host_key:
@ -136,14 +155,14 @@ EXAMPLES = '''
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_ssh_host_key:
state: "present"
hostname: "myhostname"
ip: "<your_own_value>"
name: "default_name_5"
nid: "256"
port: "7"
public-key: "<your_own_value>"
public_key: "<your_own_value>"
status: "trusted"
type: "RSA"
'''
@ -208,14 +227,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data):
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -223,12 +244,12 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_ssh_host_key_data(json):
option_list = ['hostname', 'ip', 'name',
'nid', 'port', 'public-key',
'nid', 'port', 'public_key',
'status', 'type']
dictionary = {}
@ -239,55 +260,73 @@ def filter_firewall_ssh_host_key_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_ssh_host_key(data, fos):
vdom = data['vdom']
state = data['state']
firewall_ssh_host_key_data = data['firewall_ssh_host_key']
filtered_data = filter_firewall_ssh_host_key_data(firewall_ssh_host_key_data)
if firewall_ssh_host_key_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_firewall_ssh_host_key_data(firewall_ssh_host_key_data))
if state == "present":
return fos.set('firewall.ssh',
'host-key',
data=filtered_data,
vdom=vdom)
elif firewall_ssh_host_key_data['state'] == "absent":
elif state == "absent":
return fos.delete('firewall.ssh',
'host-key',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall_ssh(data, fos):
login(data)
methodlist = ['firewall_ssh_host_key']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['firewall_ssh_host_key']:
resp = firewall_ssh_host_key(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"firewall_ssh_host_key": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"hostname": {"required": False, "type": "str"},
"ip": {"required": False, "type": "str"},
"name": {"required": True, "type": "str"},
"nid": {"required": False, "type": "str",
"choices": ["256", "384", "521"]},
"port": {"required": False, "type": "int"},
"public-key": {"required": False, "type": "str"},
"public_key": {"required": False, "type": "str"},
"status": {"required": False, "type": "str",
"choices": ["trusted", "revoked"]},
"type": {"required": False, "type": "str",
@ -301,15 +340,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall_ssh(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_ssh(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_firewall_ssh(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_ssh_local_ca
short_description: SSH proxy local CA in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure firewall_ssh feature and local_ca category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall_ssh feature and local_ca category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -44,56 +41,74 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip adress.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
required: true
choices:
- present
- absent
version_added: 2.9
firewall_ssh_local_ca:
description:
- SSH proxy local CA.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
name:
description:
- SSH proxy local CA name.
required: true
type: str
password:
description:
- Password for SSH private key.
private-key:
type: str
private_key:
description:
- SSH proxy private key, encrypted with a password.
public-key:
type: str
public_key:
description:
- SSH proxy public key.
type: str
source:
description:
- SSH proxy local CA source type.
type: str
choices:
- built-in
- user
@ -106,6 +121,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: SSH proxy local CA.
fortios_firewall_ssh_local_ca:
@ -114,12 +130,12 @@ EXAMPLES = '''
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_ssh_local_ca:
state: "present"
name: "default_name_3"
password: "<your_own_value>"
private-key: "<your_own_value>"
public-key: "<your_own_value>"
private_key: "<your_own_value>"
public_key: "<your_own_value>"
source: "built-in"
'''
@ -183,14 +199,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data):
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -198,12 +216,12 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_ssh_local_ca_data(json):
option_list = ['name', 'password', 'private-key',
'public-key', 'source']
option_list = ['name', 'password', 'private_key',
'public_key', 'source']
dictionary = {}
for attribute in option_list:
@ -213,52 +231,70 @@ def filter_firewall_ssh_local_ca_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_ssh_local_ca(data, fos):
vdom = data['vdom']
state = data['state']
firewall_ssh_local_ca_data = data['firewall_ssh_local_ca']
filtered_data = filter_firewall_ssh_local_ca_data(firewall_ssh_local_ca_data)
if firewall_ssh_local_ca_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_firewall_ssh_local_ca_data(firewall_ssh_local_ca_data))
if state == "present":
return fos.set('firewall.ssh',
'local-ca',
data=filtered_data,
vdom=vdom)
elif firewall_ssh_local_ca_data['state'] == "absent":
elif state == "absent":
return fos.delete('firewall.ssh',
'local-ca',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall_ssh(data, fos):
login(data)
methodlist = ['firewall_ssh_local_ca']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['firewall_ssh_local_ca']:
resp = firewall_ssh_local_ca(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"firewall_ssh_local_ca": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"name": {"required": True, "type": "str"},
"password": {"required": False, "type": "str"},
"private-key": {"required": False, "type": "str"},
"public-key": {"required": False, "type": "str"},
"private_key": {"required": False, "type": "str"},
"public_key": {"required": False, "type": "str"},
"source": {"required": False, "type": "str",
"choices": ["built-in", "user"]}
@ -268,15 +304,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall_ssh(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_ssh(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_firewall_ssh(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_ssh_local_key
short_description: SSH proxy local keys in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure firewall_ssh feature and local_key category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall_ssh feature and local_key category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -44,56 +41,74 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip adress.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
required: true
choices:
- present
- absent
version_added: 2.9
firewall_ssh_local_key:
description:
- SSH proxy local keys.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
name:
description:
- SSH proxy local key name.
required: true
type: str
password:
description:
- Password for SSH private key.
private-key:
type: str
private_key:
description:
- SSH proxy private key, encrypted with a password.
public-key:
type: str
public_key:
description:
- SSH proxy public key.
type: str
source:
description:
- SSH proxy local key source type.
type: str
choices:
- built-in
- user
@ -106,6 +121,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: SSH proxy local keys.
fortios_firewall_ssh_local_key:
@ -114,12 +130,12 @@ EXAMPLES = '''
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_ssh_local_key:
state: "present"
name: "default_name_3"
password: "<your_own_value>"
private-key: "<your_own_value>"
public-key: "<your_own_value>"
private_key: "<your_own_value>"
public_key: "<your_own_value>"
source: "built-in"
'''
@ -183,14 +199,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data):
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -198,12 +216,12 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_ssh_local_key_data(json):
option_list = ['name', 'password', 'private-key',
'public-key', 'source']
option_list = ['name', 'password', 'private_key',
'public_key', 'source']
dictionary = {}
for attribute in option_list:
@ -213,52 +231,70 @@ def filter_firewall_ssh_local_key_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_ssh_local_key(data, fos):
vdom = data['vdom']
state = data['state']
firewall_ssh_local_key_data = data['firewall_ssh_local_key']
filtered_data = filter_firewall_ssh_local_key_data(firewall_ssh_local_key_data)
if firewall_ssh_local_key_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_firewall_ssh_local_key_data(firewall_ssh_local_key_data))
if state == "present":
return fos.set('firewall.ssh',
'local-key',
data=filtered_data,
vdom=vdom)
elif firewall_ssh_local_key_data['state'] == "absent":
elif state == "absent":
return fos.delete('firewall.ssh',
'local-key',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall_ssh(data, fos):
login(data)
methodlist = ['firewall_ssh_local_key']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['firewall_ssh_local_key']:
resp = firewall_ssh_local_key(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"firewall_ssh_local_key": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"name": {"required": True, "type": "str"},
"password": {"required": False, "type": "str"},
"private-key": {"required": False, "type": "str"},
"public-key": {"required": False, "type": "str"},
"private_key": {"required": False, "type": "str"},
"public_key": {"required": False, "type": "str"},
"source": {"required": False, "type": "str",
"choices": ["built-in", "user"]}
@ -268,15 +304,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall_ssh(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_ssh(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_firewall_ssh(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_ssh_setting
short_description: SSH proxy settings in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure firewall_ssh feature and setting category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall_ssh feature and setting category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -44,64 +41,83 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip adress.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
firewall_ssh_setting:
description:
- SSH proxy settings.
default: null
type: dict
suboptions:
caname:
description:
- CA certificate used by SSH Inspection. Source firewall.ssh.local-ca.name.
host-trusted-checking:
type: str
host_trusted_checking:
description:
- Enable/disable host trusted checking.
type: str
choices:
- enable
- disable
hostkey-dsa1024:
hostkey_dsa1024:
description:
- DSA certificate used by SSH proxy. Source firewall.ssh.local-key.name.
hostkey-ecdsa256:
type: str
hostkey_ecdsa256:
description:
- ECDSA nid256 certificate used by SSH proxy. Source firewall.ssh.local-key.name.
hostkey-ecdsa384:
type: str
hostkey_ecdsa384:
description:
- ECDSA nid384 certificate used by SSH proxy. Source firewall.ssh.local-key.name.
hostkey-ecdsa521:
type: str
hostkey_ecdsa521:
description:
- ECDSA nid384 certificate used by SSH proxy. Source firewall.ssh.local-key.name.
hostkey-ed25519:
type: str
hostkey_ed25519:
description:
- ED25519 hostkey used by SSH proxy. Source firewall.ssh.local-key.name.
hostkey-rsa2048:
type: str
hostkey_rsa2048:
description:
- RSA certificate used by SSH proxy. Source firewall.ssh.local-key.name.
untrusted-caname:
type: str
untrusted_caname:
description:
- Untrusted CA certificate used by SSH Inspection. Source firewall.ssh.local-ca.name.
type: str
'''
EXAMPLES = '''
@ -111,6 +127,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: SSH proxy settings.
fortios_firewall_ssh_setting:
@ -121,14 +138,14 @@ EXAMPLES = '''
https: "False"
firewall_ssh_setting:
caname: "<your_own_value> (source firewall.ssh.local-ca.name)"
host-trusted-checking: "enable"
hostkey-dsa1024: "myhostname (source firewall.ssh.local-key.name)"
hostkey-ecdsa256: "myhostname (source firewall.ssh.local-key.name)"
hostkey-ecdsa384: "myhostname (source firewall.ssh.local-key.name)"
hostkey-ecdsa521: "myhostname (source firewall.ssh.local-key.name)"
hostkey-ed25519: "myhostname (source firewall.ssh.local-key.name)"
hostkey-rsa2048: "myhostname (source firewall.ssh.local-key.name)"
untrusted-caname: "<your_own_value> (source firewall.ssh.local-ca.name)"
host_trusted_checking: "enable"
hostkey_dsa1024: "myhostname (source firewall.ssh.local-key.name)"
hostkey_ecdsa256: "myhostname (source firewall.ssh.local-key.name)"
hostkey_ecdsa384: "myhostname (source firewall.ssh.local-key.name)"
hostkey_ecdsa521: "myhostname (source firewall.ssh.local-key.name)"
hostkey_ed25519: "myhostname (source firewall.ssh.local-key.name)"
hostkey_rsa2048: "myhostname (source firewall.ssh.local-key.name)"
untrusted_caname: "<your_own_value> (source firewall.ssh.local-ca.name)"
'''
RETURN = '''
@ -191,14 +208,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data):
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -206,13 +225,13 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_ssh_setting_data(json):
option_list = ['caname', 'host-trusted-checking', 'hostkey-dsa1024',
'hostkey-ecdsa256', 'hostkey-ecdsa384', 'hostkey-ecdsa521',
'hostkey-ed25519', 'hostkey-rsa2048', 'untrusted-caname']
option_list = ['caname', 'host_trusted_checking', 'hostkey_dsa1024',
'hostkey_ecdsa256', 'hostkey_ecdsa384', 'hostkey_ecdsa521',
'hostkey_ed25519', 'hostkey_rsa2048', 'untrusted_caname']
dictionary = {}
for attribute in option_list:
@ -222,49 +241,66 @@ def filter_firewall_ssh_setting_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_ssh_setting(data, fos):
vdom = data['vdom']
firewall_ssh_setting_data = data['firewall_ssh_setting']
filtered_data = filter_firewall_ssh_setting_data(firewall_ssh_setting_data)
filtered_data = underscore_to_hyphen(filter_firewall_ssh_setting_data(firewall_ssh_setting_data))
return fos.set('firewall.ssh',
'setting',
data=filtered_data,
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall_ssh(data, fos):
login(data)
methodlist = ['firewall_ssh_setting']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['firewall_ssh_setting']:
resp = firewall_ssh_setting(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"firewall_ssh_setting": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"caname": {"required": False, "type": "str"},
"host-trusted-checking": {"required": False, "type": "str",
"host_trusted_checking": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"hostkey-dsa1024": {"required": False, "type": "str"},
"hostkey-ecdsa256": {"required": False, "type": "str"},
"hostkey-ecdsa384": {"required": False, "type": "str"},
"hostkey-ecdsa521": {"required": False, "type": "str"},
"hostkey-ed25519": {"required": False, "type": "str"},
"hostkey-rsa2048": {"required": False, "type": "str"},
"untrusted-caname": {"required": False, "type": "str"}
"hostkey_dsa1024": {"required": False, "type": "str"},
"hostkey_ecdsa256": {"required": False, "type": "str"},
"hostkey_ecdsa384": {"required": False, "type": "str"},
"hostkey_ecdsa521": {"required": False, "type": "str"},
"hostkey_ed25519": {"required": False, "type": "str"},
"hostkey_rsa2048": {"required": False, "type": "str"},
"untrusted_caname": {"required": False, "type": "str"}
}
}
@ -272,15 +308,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall_ssh(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_ssh(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_firewall_ssh(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_ssl_server
short_description: Configure SSL servers in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure firewall feature and ssl_server category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and ssl_server category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -44,113 +41,140 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip adress.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
required: true
choices:
- present
- absent
version_added: 2.9
firewall_ssl_server:
description:
- Configure SSL servers.
default: null
type: dict
suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
add-header-x-forwarded-proto:
add_header_x_forwarded_proto:
description:
- Enable/disable adding an X-Forwarded-Proto header to forwarded requests.
type: str
choices:
- enable
- disable
ip:
description:
- IPv4 address of the SSL server.
mapped-port:
type: str
mapped_port:
description:
- Mapped server service port (1 - 65535, default = 80).
- Mapped server service port (1 - 65535).
type: int
name:
description:
- Server name.
required: true
type: str
port:
description:
- Server service port (1 - 65535, default = 443).
ssl-algorithm:
- Server service port (1 - 65535).
type: int
ssl_algorithm:
description:
- Relative strength of encryption algorithms accepted in negotiation.
type: str
choices:
- high
- medium
- low
ssl-cert:
ssl_cert:
description:
- Name of certificate for SSL connections to this server (default = "Fortinet_CA_SSL"). Source vpn.certificate.local.name.
ssl-client-renegotiation:
- Name of certificate for SSL connections to this server. Source vpn.certificate.local.name.
type: str
ssl_client_renegotiation:
description:
- Allow or block client renegotiation by server.
type: str
choices:
- allow
- deny
- secure
ssl-dh-bits:
ssl_dh_bits:
description:
- Bit-size of Diffie-Hellman (DH) prime used in DHE-RSA negotiation (default = 2048).
- Bit-size of Diffie-Hellman (DH) prime used in DHE-RSA negotiation.
type: str
choices:
- 768
- 1024
- 1536
- 2048
ssl-max-version:
ssl_max_version:
description:
- Highest SSL/TLS version to negotiate.
type: str
choices:
- tls-1.0
- tls-1.1
- tls-1.2
ssl-min-version:
ssl_min_version:
description:
- Lowest SSL/TLS version to negotiate.
type: str
choices:
- tls-1.0
- tls-1.1
- tls-1.2
ssl-mode:
ssl_mode:
description:
- SSL/TLS mode for encryption and decryption of traffic.
type: str
choices:
- half
- full
ssl-send-empty-frags:
ssl_send_empty_frags:
description:
- Enable/disable sending empty fragments to avoid attack on CBC IV.
type: str
choices:
- enable
- disable
url-rewrite:
url_rewrite:
description:
- Enable/disable rewriting the URL.
type: str
choices:
- enable
- disable
@ -163,6 +187,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure SSL servers.
fortios_firewall_ssl_server:
@ -171,22 +196,22 @@ EXAMPLES = '''
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_ssl_server:
state: "present"
add-header-x-forwarded-proto: "enable"
add_header_x_forwarded_proto: "enable"
ip: "<your_own_value>"
mapped-port: "5"
mapped_port: "5"
name: "default_name_6"
port: "7"
ssl-algorithm: "high"
ssl-cert: "<your_own_value> (source vpn.certificate.local.name)"
ssl-client-renegotiation: "allow"
ssl-dh-bits: "768"
ssl-max-version: "tls-1.0"
ssl-min-version: "tls-1.0"
ssl-mode: "half"
ssl-send-empty-frags: "enable"
url-rewrite: "enable"
ssl_algorithm: "high"
ssl_cert: "<your_own_value> (source vpn.certificate.local.name)"
ssl_client_renegotiation: "allow"
ssl_dh_bits: "768"
ssl_max_version: "tls-1.0"
ssl_min_version: "tls-1.0"
ssl_mode: "half"
ssl_send_empty_frags: "enable"
url_rewrite: "enable"
'''
RETURN = '''
@ -249,14 +274,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data):
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -264,15 +291,15 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_ssl_server_data(json):
option_list = ['add-header-x-forwarded-proto', 'ip', 'mapped-port',
'name', 'port', 'ssl-algorithm',
'ssl-cert', 'ssl-client-renegotiation', 'ssl-dh-bits',
'ssl-max-version', 'ssl-min-version', 'ssl-mode',
'ssl-send-empty-frags', 'url-rewrite']
option_list = ['add_header_x_forwarded_proto', 'ip', 'mapped_port',
'name', 'port', 'ssl_algorithm',
'ssl_cert', 'ssl_client_renegotiation', 'ssl_dh_bits',
'ssl_max_version', 'ssl_min_version', 'ssl_mode',
'ssl_send_empty_frags', 'url_rewrite']
dictionary = {}
for attribute in option_list:
@ -282,71 +309,89 @@ def filter_firewall_ssl_server_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_ssl_server(data, fos):
vdom = data['vdom']
state = data['state']
firewall_ssl_server_data = data['firewall_ssl_server']
filtered_data = filter_firewall_ssl_server_data(firewall_ssl_server_data)
if firewall_ssl_server_data['state'] == "present":
filtered_data = underscore_to_hyphen(filter_firewall_ssl_server_data(firewall_ssl_server_data))
if state == "present":
return fos.set('firewall',
'ssl-server',
data=filtered_data,
vdom=vdom)
elif firewall_ssl_server_data['state'] == "absent":
elif state == "absent":
return fos.delete('firewall',
'ssl-server',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
login(data)
methodlist = ['firewall_ssl_server']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['firewall_ssl_server']:
resp = firewall_ssl_server(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"firewall_ssl_server": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"add-header-x-forwarded-proto": {"required": False, "type": "str",
"add_header_x_forwarded_proto": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"ip": {"required": False, "type": "str"},
"mapped-port": {"required": False, "type": "int"},
"mapped_port": {"required": False, "type": "int"},
"name": {"required": True, "type": "str"},
"port": {"required": False, "type": "int"},
"ssl-algorithm": {"required": False, "type": "str",
"ssl_algorithm": {"required": False, "type": "str",
"choices": ["high", "medium", "low"]},
"ssl-cert": {"required": False, "type": "str"},
"ssl-client-renegotiation": {"required": False, "type": "str",
"ssl_cert": {"required": False, "type": "str"},
"ssl_client_renegotiation": {"required": False, "type": "str",
"choices": ["allow", "deny", "secure"]},
"ssl-dh-bits": {"required": False, "type": "str",
"ssl_dh_bits": {"required": False, "type": "str",
"choices": ["768", "1024", "1536",
"2048"]},
"ssl-max-version": {"required": False, "type": "str",
"ssl_max_version": {"required": False, "type": "str",
"choices": ["tls-1.0", "tls-1.1", "tls-1.2"]},
"ssl-min-version": {"required": False, "type": "str",
"ssl_min_version": {"required": False, "type": "str",
"choices": ["tls-1.0", "tls-1.1", "tls-1.2"]},
"ssl-mode": {"required": False, "type": "str",
"ssl_mode": {"required": False, "type": "str",
"choices": ["half", "full"]},
"ssl-send-empty-frags": {"required": False, "type": "str",
"ssl_send_empty_frags": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"url-rewrite": {"required": False, "type": "str",
"url_rewrite": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
@ -355,15 +400,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_firewall(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_firewall_ssl_setting
short_description: SSL proxy settings in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure firewall_ssl feature and setting category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall_ssl feature and setting category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
@ -44,80 +41,99 @@ requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip adress.
required: true
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS
protocol
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
firewall_ssl_setting:
description:
- SSL proxy settings.
default: null
type: dict
suboptions:
abbreviate-handshake:
abbreviate_handshake:
description:
- Enable/disable use of SSL abbreviated handshake.
type: str
choices:
- enable
- disable
cert-cache-capacity:
cert_cache_capacity:
description:
- Maximum capacity of the host certificate cache (0 - 500, default = 200).
cert-cache-timeout:
- Maximum capacity of the host certificate cache (0 - 500).
type: int
cert_cache_timeout:
description:
- Time limit to keep certificate cache (1 - 120 min, default = 10).
kxp-queue-threshold:
- Time limit to keep certificate cache (1 - 120 min).
type: int
kxp_queue_threshold:
description:
- Maximum length of the CP KXP queue. When the queue becomes full, the proxy switches cipher functions to the main CPU (0 - 512, default =
16).
no-matching-cipher-action:
- Maximum length of the CP KXP queue. When the queue becomes full, the proxy switches cipher functions to the main CPU (0 - 512).
type: int
no_matching_cipher_action:
description:
- Bypass or drop the connection when no matching cipher is found.
type: str
choices:
- bypass
- drop
proxy-connect-timeout:
proxy_connect_timeout:
description:
- Time limit to make an internal connection to the appropriate proxy process (1 - 60 sec, default = 30).
session-cache-capacity:
- Time limit to make an internal connection to the appropriate proxy process (1 - 60 sec).
type: int
session_cache_capacity:
description:
- Capacity of the SSL session cache (--Obsolete--) (1 - 1000, default = 500).
session-cache-timeout:
- Capacity of the SSL session cache (--Obsolete--) (1 - 1000).
type: int
session_cache_timeout:
description:
- Time limit to keep SSL session state (1 - 60 min, default = 20).
ssl-dh-bits:
- Time limit to keep SSL session state (1 - 60 min).
type: int
ssl_dh_bits:
description:
- Bit-size of Diffie-Hellman (DH) prime used in DHE-RSA negotiation (default = 2048).
- Bit-size of Diffie-Hellman (DH) prime used in DHE-RSA negotiation.
type: str
choices:
- 768
- 1024
- 1536
- 2048
ssl-queue-threshold:
ssl_queue_threshold:
description:
- Maximum length of the CP SSL queue. When the queue becomes full, the proxy switches cipher functions to the main CPU (0 - 512, default =
32).
ssl-send-empty-frags:
- Maximum length of the CP SSL queue. When the queue becomes full, the proxy switches cipher functions to the main CPU (0 - 512).
type: int
ssl_send_empty_frags:
description:
- Enable/disable sending empty fragments to avoid attack on CBC IV (for SSL 3.0 and TLS 1.0 only).
type: str
choices:
- enable
- disable
@ -130,6 +146,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: SSL proxy settings.
fortios_firewall_ssl_setting:
@ -139,17 +156,17 @@ EXAMPLES = '''
vdom: "{{ vdom }}"
https: "False"
firewall_ssl_setting:
abbreviate-handshake: "enable"
cert-cache-capacity: "4"
cert-cache-timeout: "5"
kxp-queue-threshold: "6"
no-matching-cipher-action: "bypass"
proxy-connect-timeout: "8"
session-cache-capacity: "9"
session-cache-timeout: "10"
ssl-dh-bits: "768"
ssl-queue-threshold: "12"
ssl-send-empty-frags: "enable"
abbreviate_handshake: "enable"
cert_cache_capacity: "4"
cert_cache_timeout: "5"
kxp_queue_threshold: "6"
no_matching_cipher_action: "bypass"
proxy_connect_timeout: "8"
session_cache_capacity: "9"
session_cache_timeout: "10"
ssl_dh_bits: "768"
ssl_queue_threshold: "12"
ssl_send_empty_frags: "enable"
'''
RETURN = '''
@ -212,14 +229,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data):
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
@ -227,14 +246,14 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_ssl_setting_data(json):
option_list = ['abbreviate-handshake', 'cert-cache-capacity', 'cert-cache-timeout',
'kxp-queue-threshold', 'no-matching-cipher-action', 'proxy-connect-timeout',
'session-cache-capacity', 'session-cache-timeout', 'ssl-dh-bits',
'ssl-queue-threshold', 'ssl-send-empty-frags']
option_list = ['abbreviate_handshake', 'cert_cache_capacity', 'cert_cache_timeout',
'kxp_queue_threshold', 'no_matching_cipher_action', 'proxy_connect_timeout',
'session_cache_capacity', 'session_cache_timeout', 'ssl_dh_bits',
'ssl_queue_threshold', 'ssl_send_empty_frags']
dictionary = {}
for attribute in option_list:
@ -244,54 +263,71 @@ def filter_firewall_ssl_setting_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_ssl_setting(data, fos):
vdom = data['vdom']
firewall_ssl_setting_data = data['firewall_ssl_setting']
filtered_data = filter_firewall_ssl_setting_data(firewall_ssl_setting_data)
filtered_data = underscore_to_hyphen(filter_firewall_ssl_setting_data(firewall_ssl_setting_data))
return fos.set('firewall.ssl',
'setting',
data=filtered_data,
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall_ssl(data, fos):
login(data)
methodlist = ['firewall_ssl_setting']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['firewall_ssl_setting']:
resp = firewall_ssl_setting(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"firewall_ssl_setting": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"abbreviate-handshake": {"required": False, "type": "str",
"abbreviate_handshake": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"cert-cache-capacity": {"required": False, "type": "int"},
"cert-cache-timeout": {"required": False, "type": "int"},
"kxp-queue-threshold": {"required": False, "type": "int"},
"no-matching-cipher-action": {"required": False, "type": "str",
"cert_cache_capacity": {"required": False, "type": "int"},
"cert_cache_timeout": {"required": False, "type": "int"},
"kxp_queue_threshold": {"required": False, "type": "int"},
"no_matching_cipher_action": {"required": False, "type": "str",
"choices": ["bypass", "drop"]},
"proxy-connect-timeout": {"required": False, "type": "int"},
"session-cache-capacity": {"required": False, "type": "int"},
"session-cache-timeout": {"required": False, "type": "int"},
"ssl-dh-bits": {"required": False, "type": "str",
"proxy_connect_timeout": {"required": False, "type": "int"},
"session_cache_capacity": {"required": False, "type": "int"},
"session_cache_timeout": {"required": False, "type": "int"},
"ssl_dh_bits": {"required": False, "type": "str",
"choices": ["768", "1024", "1536",
"2048"]},
"ssl-queue-threshold": {"required": False, "type": "int"},
"ssl-send-empty-frags": {"required": False, "type": "str",
"ssl_queue_threshold": {"required": False, "type": "int"},
"ssl_send_empty_frags": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
@ -300,15 +336,31 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos
fos = FortiOSAPI()
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall_ssl(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_ssl(module.params, fos)
login(module.params, fos)
is_error, has_changed, result = fortios_firewall_ssl(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)

@ -3694,41 +3694,7 @@ 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_policy6.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_policy.py validate-modules:E326
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_addrgrp.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_proxy_policy.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_proxy_policy.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_schedule_group.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_schedule_onetime.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_schedule_onetime.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_schedule_recurring.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_service_category.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_service_custom.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_service_custom.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_service_group.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_shaper_per_ip_shaper.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_shaper_per_ip_shaper.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_shaper_traffic_shaper.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_shaper_traffic_shaper.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_shaping_policy.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_shaping_policy.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_shaping_profile.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_shaping_profile.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_sniffer.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_sniffer.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_ssh_host_key.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_ssh_host_key.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_ssh_local_ca.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_ssh_local_ca.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_ssh_local_key.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_ssh_local_key.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_ssh_setting.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_ssh_setting.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_ssl_server.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_ssl_server.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_ssl_setting.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_ssl_setting.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_ssl_ssh_profile.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_firewall_ssl_ssh_profile.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_firewall_ttl_policy.py validate-modules:E337

@ -0,0 +1,349 @@
# 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_proxy_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_proxy_address.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_proxy_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_proxy_address': {
'case_sensitivity': 'disable',
'color': '4',
'comment': 'Optional comments.',
'header': 'test_value_6',
'header_name': 'test_value_7',
'host': 'myhostname8',
'host_regex': 'myhostname9',
'method': 'get',
'name': 'default_name_11',
'path': 'test_value_12',
'query': 'test_value_13',
'referrer': 'enable',
'type': 'host-regex',
'ua': 'chrome',
'uuid': 'test_value_17',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_proxy_address.fortios_firewall(input_data, fos_instance)
expected_data = {
'case-sensitivity': 'disable',
'color': '4',
'comment': 'Optional comments.',
'header': 'test_value_6',
'header-name': 'test_value_7',
'host': 'myhostname8',
'host-regex': 'myhostname9',
'method': 'get',
'name': 'default_name_11',
'path': 'test_value_12',
'query': 'test_value_13',
'referrer': 'enable',
'type': 'host-regex',
'ua': 'chrome',
'uuid': 'test_value_17',
'visibility': 'enable'
}
set_method_mock.assert_called_with('firewall', 'proxy-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_proxy_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_proxy_address': {
'case_sensitivity': 'disable',
'color': '4',
'comment': 'Optional comments.',
'header': 'test_value_6',
'header_name': 'test_value_7',
'host': 'myhostname8',
'host_regex': 'myhostname9',
'method': 'get',
'name': 'default_name_11',
'path': 'test_value_12',
'query': 'test_value_13',
'referrer': 'enable',
'type': 'host-regex',
'ua': 'chrome',
'uuid': 'test_value_17',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_proxy_address.fortios_firewall(input_data, fos_instance)
expected_data = {
'case-sensitivity': 'disable',
'color': '4',
'comment': 'Optional comments.',
'header': 'test_value_6',
'header-name': 'test_value_7',
'host': 'myhostname8',
'host-regex': 'myhostname9',
'method': 'get',
'name': 'default_name_11',
'path': 'test_value_12',
'query': 'test_value_13',
'referrer': 'enable',
'type': 'host-regex',
'ua': 'chrome',
'uuid': 'test_value_17',
'visibility': 'enable'
}
set_method_mock.assert_called_with('firewall', 'proxy-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_proxy_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_proxy_address': {
'case_sensitivity': 'disable',
'color': '4',
'comment': 'Optional comments.',
'header': 'test_value_6',
'header_name': 'test_value_7',
'host': 'myhostname8',
'host_regex': 'myhostname9',
'method': 'get',
'name': 'default_name_11',
'path': 'test_value_12',
'query': 'test_value_13',
'referrer': 'enable',
'type': 'host-regex',
'ua': 'chrome',
'uuid': 'test_value_17',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_proxy_address.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'proxy-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_proxy_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_proxy_address': {
'case_sensitivity': 'disable',
'color': '4',
'comment': 'Optional comments.',
'header': 'test_value_6',
'header_name': 'test_value_7',
'host': 'myhostname8',
'host_regex': 'myhostname9',
'method': 'get',
'name': 'default_name_11',
'path': 'test_value_12',
'query': 'test_value_13',
'referrer': 'enable',
'type': 'host-regex',
'ua': 'chrome',
'uuid': 'test_value_17',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_proxy_address.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'proxy-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_proxy_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_proxy_address': {
'case_sensitivity': 'disable',
'color': '4',
'comment': 'Optional comments.',
'header': 'test_value_6',
'header_name': 'test_value_7',
'host': 'myhostname8',
'host_regex': 'myhostname9',
'method': 'get',
'name': 'default_name_11',
'path': 'test_value_12',
'query': 'test_value_13',
'referrer': 'enable',
'type': 'host-regex',
'ua': 'chrome',
'uuid': 'test_value_17',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_proxy_address.fortios_firewall(input_data, fos_instance)
expected_data = {
'case-sensitivity': 'disable',
'color': '4',
'comment': 'Optional comments.',
'header': 'test_value_6',
'header-name': 'test_value_7',
'host': 'myhostname8',
'host-regex': 'myhostname9',
'method': 'get',
'name': 'default_name_11',
'path': 'test_value_12',
'query': 'test_value_13',
'referrer': 'enable',
'type': 'host-regex',
'ua': 'chrome',
'uuid': 'test_value_17',
'visibility': 'enable'
}
set_method_mock.assert_called_with('firewall', 'proxy-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_proxy_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_proxy_address': {
'random_attribute_not_valid': 'tag',
'case_sensitivity': 'disable',
'color': '4',
'comment': 'Optional comments.',
'header': 'test_value_6',
'header_name': 'test_value_7',
'host': 'myhostname8',
'host_regex': 'myhostname9',
'method': 'get',
'name': 'default_name_11',
'path': 'test_value_12',
'query': 'test_value_13',
'referrer': 'enable',
'type': 'host-regex',
'ua': 'chrome',
'uuid': 'test_value_17',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_proxy_address.fortios_firewall(input_data, fos_instance)
expected_data = {
'case-sensitivity': 'disable',
'color': '4',
'comment': 'Optional comments.',
'header': 'test_value_6',
'header-name': 'test_value_7',
'host': 'myhostname8',
'host-regex': 'myhostname9',
'method': 'get',
'name': 'default_name_11',
'path': 'test_value_12',
'query': 'test_value_13',
'referrer': 'enable',
'type': 'host-regex',
'ua': 'chrome',
'uuid': 'test_value_17',
'visibility': 'enable'
}
set_method_mock.assert_called_with('firewall', 'proxy-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,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_proxy_addrgrp
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_proxy_addrgrp.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_proxy_addrgrp_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_proxy_addrgrp': {
'color': '3',
'comment': 'Optional comments.',
'name': 'default_name_5',
'type': 'src',
'uuid': 'test_value_7',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_proxy_addrgrp.fortios_firewall(input_data, fos_instance)
expected_data = {
'color': '3',
'comment': 'Optional comments.',
'name': 'default_name_5',
'type': 'src',
'uuid': 'test_value_7',
'visibility': 'enable'
}
set_method_mock.assert_called_with('firewall', 'proxy-addrgrp', 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_proxy_addrgrp_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_proxy_addrgrp': {
'color': '3',
'comment': 'Optional comments.',
'name': 'default_name_5',
'type': 'src',
'uuid': 'test_value_7',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_proxy_addrgrp.fortios_firewall(input_data, fos_instance)
expected_data = {
'color': '3',
'comment': 'Optional comments.',
'name': 'default_name_5',
'type': 'src',
'uuid': 'test_value_7',
'visibility': 'enable'
}
set_method_mock.assert_called_with('firewall', 'proxy-addrgrp', 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_proxy_addrgrp_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_proxy_addrgrp': {
'color': '3',
'comment': 'Optional comments.',
'name': 'default_name_5',
'type': 'src',
'uuid': 'test_value_7',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_proxy_addrgrp.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'proxy-addrgrp', 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_proxy_addrgrp_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_proxy_addrgrp': {
'color': '3',
'comment': 'Optional comments.',
'name': 'default_name_5',
'type': 'src',
'uuid': 'test_value_7',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_proxy_addrgrp.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'proxy-addrgrp', 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_proxy_addrgrp_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_proxy_addrgrp': {
'color': '3',
'comment': 'Optional comments.',
'name': 'default_name_5',
'type': 'src',
'uuid': 'test_value_7',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_proxy_addrgrp.fortios_firewall(input_data, fos_instance)
expected_data = {
'color': '3',
'comment': 'Optional comments.',
'name': 'default_name_5',
'type': 'src',
'uuid': 'test_value_7',
'visibility': 'enable'
}
set_method_mock.assert_called_with('firewall', 'proxy-addrgrp', 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_proxy_addrgrp_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_proxy_addrgrp': {
'random_attribute_not_valid': 'tag',
'color': '3',
'comment': 'Optional comments.',
'name': 'default_name_5',
'type': 'src',
'uuid': 'test_value_7',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_proxy_addrgrp.fortios_firewall(input_data, fos_instance)
expected_data = {
'color': '3',
'comment': 'Optional comments.',
'name': 'default_name_5',
'type': 'src',
'uuid': 'test_value_7',
'visibility': 'enable'
}
set_method_mock.assert_called_with('firewall', 'proxy-addrgrp', 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,599 @@
# 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_proxy_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_proxy_policy.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_proxy_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_proxy_policy': {
'action': 'accept',
'application_list': 'test_value_4',
'av_profile': 'test_value_5',
'comments': 'test_value_6',
'disclaimer': 'disable',
'dlp_sensor': 'test_value_8',
'dstaddr_negate': 'enable',
'global_label': 'test_value_10',
'http_tunnel_auth': 'enable',
'icap_profile': 'test_value_12',
'internet_service': 'enable',
'internet_service_negate': 'enable',
'ips_sensor': 'test_value_15',
'label': 'test_value_16',
'logtraffic': 'all',
'logtraffic_start': 'enable',
'policyid': '19',
'profile_group': 'test_value_20',
'profile_protocol_options': 'test_value_21',
'profile_type': 'single',
'proxy': 'explicit-web',
'redirect_url': 'test_value_24',
'replacemsg_override_group': 'test_value_25',
'scan_botnet_connections': 'disable',
'schedule': 'test_value_27',
'service_negate': 'enable',
'session_ttl': '29',
'spamfilter_profile': 'test_value_30',
'srcaddr_negate': 'enable',
'ssh_filter_profile': 'test_value_32',
'ssl_ssh_profile': 'test_value_33',
'status': 'enable',
'transparent': 'enable',
'utm_status': 'enable',
'uuid': 'test_value_37',
'waf_profile': 'test_value_38',
'webcache': 'enable',
'webcache_https': 'disable',
'webfilter_profile': 'test_value_41',
'webproxy_forward_server': 'test_value_42',
'webproxy_profile': 'test_value_43'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_proxy_policy.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'application-list': 'test_value_4',
'av-profile': 'test_value_5',
'comments': 'test_value_6',
'disclaimer': 'disable',
'dlp-sensor': 'test_value_8',
'dstaddr-negate': 'enable',
'global-label': 'test_value_10',
'http-tunnel-auth': 'enable',
'icap-profile': 'test_value_12',
'internet-service': 'enable',
'internet-service-negate': 'enable',
'ips-sensor': 'test_value_15',
'label': 'test_value_16',
'logtraffic': 'all',
'logtraffic-start': 'enable',
'policyid': '19',
'profile-group': 'test_value_20',
'profile-protocol-options': 'test_value_21',
'profile-type': 'single',
'proxy': 'explicit-web',
'redirect-url': 'test_value_24',
'replacemsg-override-group': 'test_value_25',
'scan-botnet-connections': 'disable',
'schedule': 'test_value_27',
'service-negate': 'enable',
'session-ttl': '29',
'spamfilter-profile': 'test_value_30',
'srcaddr-negate': 'enable',
'ssh-filter-profile': 'test_value_32',
'ssl-ssh-profile': 'test_value_33',
'status': 'enable',
'transparent': 'enable',
'utm-status': 'enable',
'uuid': 'test_value_37',
'waf-profile': 'test_value_38',
'webcache': 'enable',
'webcache-https': 'disable',
'webfilter-profile': 'test_value_41',
'webproxy-forward-server': 'test_value_42',
'webproxy-profile': 'test_value_43'
}
set_method_mock.assert_called_with('firewall', 'proxy-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_proxy_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_proxy_policy': {
'action': 'accept',
'application_list': 'test_value_4',
'av_profile': 'test_value_5',
'comments': 'test_value_6',
'disclaimer': 'disable',
'dlp_sensor': 'test_value_8',
'dstaddr_negate': 'enable',
'global_label': 'test_value_10',
'http_tunnel_auth': 'enable',
'icap_profile': 'test_value_12',
'internet_service': 'enable',
'internet_service_negate': 'enable',
'ips_sensor': 'test_value_15',
'label': 'test_value_16',
'logtraffic': 'all',
'logtraffic_start': 'enable',
'policyid': '19',
'profile_group': 'test_value_20',
'profile_protocol_options': 'test_value_21',
'profile_type': 'single',
'proxy': 'explicit-web',
'redirect_url': 'test_value_24',
'replacemsg_override_group': 'test_value_25',
'scan_botnet_connections': 'disable',
'schedule': 'test_value_27',
'service_negate': 'enable',
'session_ttl': '29',
'spamfilter_profile': 'test_value_30',
'srcaddr_negate': 'enable',
'ssh_filter_profile': 'test_value_32',
'ssl_ssh_profile': 'test_value_33',
'status': 'enable',
'transparent': 'enable',
'utm_status': 'enable',
'uuid': 'test_value_37',
'waf_profile': 'test_value_38',
'webcache': 'enable',
'webcache_https': 'disable',
'webfilter_profile': 'test_value_41',
'webproxy_forward_server': 'test_value_42',
'webproxy_profile': 'test_value_43'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_proxy_policy.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'application-list': 'test_value_4',
'av-profile': 'test_value_5',
'comments': 'test_value_6',
'disclaimer': 'disable',
'dlp-sensor': 'test_value_8',
'dstaddr-negate': 'enable',
'global-label': 'test_value_10',
'http-tunnel-auth': 'enable',
'icap-profile': 'test_value_12',
'internet-service': 'enable',
'internet-service-negate': 'enable',
'ips-sensor': 'test_value_15',
'label': 'test_value_16',
'logtraffic': 'all',
'logtraffic-start': 'enable',
'policyid': '19',
'profile-group': 'test_value_20',
'profile-protocol-options': 'test_value_21',
'profile-type': 'single',
'proxy': 'explicit-web',
'redirect-url': 'test_value_24',
'replacemsg-override-group': 'test_value_25',
'scan-botnet-connections': 'disable',
'schedule': 'test_value_27',
'service-negate': 'enable',
'session-ttl': '29',
'spamfilter-profile': 'test_value_30',
'srcaddr-negate': 'enable',
'ssh-filter-profile': 'test_value_32',
'ssl-ssh-profile': 'test_value_33',
'status': 'enable',
'transparent': 'enable',
'utm-status': 'enable',
'uuid': 'test_value_37',
'waf-profile': 'test_value_38',
'webcache': 'enable',
'webcache-https': 'disable',
'webfilter-profile': 'test_value_41',
'webproxy-forward-server': 'test_value_42',
'webproxy-profile': 'test_value_43'
}
set_method_mock.assert_called_with('firewall', 'proxy-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_proxy_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_proxy_policy': {
'action': 'accept',
'application_list': 'test_value_4',
'av_profile': 'test_value_5',
'comments': 'test_value_6',
'disclaimer': 'disable',
'dlp_sensor': 'test_value_8',
'dstaddr_negate': 'enable',
'global_label': 'test_value_10',
'http_tunnel_auth': 'enable',
'icap_profile': 'test_value_12',
'internet_service': 'enable',
'internet_service_negate': 'enable',
'ips_sensor': 'test_value_15',
'label': 'test_value_16',
'logtraffic': 'all',
'logtraffic_start': 'enable',
'policyid': '19',
'profile_group': 'test_value_20',
'profile_protocol_options': 'test_value_21',
'profile_type': 'single',
'proxy': 'explicit-web',
'redirect_url': 'test_value_24',
'replacemsg_override_group': 'test_value_25',
'scan_botnet_connections': 'disable',
'schedule': 'test_value_27',
'service_negate': 'enable',
'session_ttl': '29',
'spamfilter_profile': 'test_value_30',
'srcaddr_negate': 'enable',
'ssh_filter_profile': 'test_value_32',
'ssl_ssh_profile': 'test_value_33',
'status': 'enable',
'transparent': 'enable',
'utm_status': 'enable',
'uuid': 'test_value_37',
'waf_profile': 'test_value_38',
'webcache': 'enable',
'webcache_https': 'disable',
'webfilter_profile': 'test_value_41',
'webproxy_forward_server': 'test_value_42',
'webproxy_profile': 'test_value_43'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_proxy_policy.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'proxy-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_proxy_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_proxy_policy': {
'action': 'accept',
'application_list': 'test_value_4',
'av_profile': 'test_value_5',
'comments': 'test_value_6',
'disclaimer': 'disable',
'dlp_sensor': 'test_value_8',
'dstaddr_negate': 'enable',
'global_label': 'test_value_10',
'http_tunnel_auth': 'enable',
'icap_profile': 'test_value_12',
'internet_service': 'enable',
'internet_service_negate': 'enable',
'ips_sensor': 'test_value_15',
'label': 'test_value_16',
'logtraffic': 'all',
'logtraffic_start': 'enable',
'policyid': '19',
'profile_group': 'test_value_20',
'profile_protocol_options': 'test_value_21',
'profile_type': 'single',
'proxy': 'explicit-web',
'redirect_url': 'test_value_24',
'replacemsg_override_group': 'test_value_25',
'scan_botnet_connections': 'disable',
'schedule': 'test_value_27',
'service_negate': 'enable',
'session_ttl': '29',
'spamfilter_profile': 'test_value_30',
'srcaddr_negate': 'enable',
'ssh_filter_profile': 'test_value_32',
'ssl_ssh_profile': 'test_value_33',
'status': 'enable',
'transparent': 'enable',
'utm_status': 'enable',
'uuid': 'test_value_37',
'waf_profile': 'test_value_38',
'webcache': 'enable',
'webcache_https': 'disable',
'webfilter_profile': 'test_value_41',
'webproxy_forward_server': 'test_value_42',
'webproxy_profile': 'test_value_43'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_proxy_policy.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'proxy-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_proxy_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_proxy_policy': {
'action': 'accept',
'application_list': 'test_value_4',
'av_profile': 'test_value_5',
'comments': 'test_value_6',
'disclaimer': 'disable',
'dlp_sensor': 'test_value_8',
'dstaddr_negate': 'enable',
'global_label': 'test_value_10',
'http_tunnel_auth': 'enable',
'icap_profile': 'test_value_12',
'internet_service': 'enable',
'internet_service_negate': 'enable',
'ips_sensor': 'test_value_15',
'label': 'test_value_16',
'logtraffic': 'all',
'logtraffic_start': 'enable',
'policyid': '19',
'profile_group': 'test_value_20',
'profile_protocol_options': 'test_value_21',
'profile_type': 'single',
'proxy': 'explicit-web',
'redirect_url': 'test_value_24',
'replacemsg_override_group': 'test_value_25',
'scan_botnet_connections': 'disable',
'schedule': 'test_value_27',
'service_negate': 'enable',
'session_ttl': '29',
'spamfilter_profile': 'test_value_30',
'srcaddr_negate': 'enable',
'ssh_filter_profile': 'test_value_32',
'ssl_ssh_profile': 'test_value_33',
'status': 'enable',
'transparent': 'enable',
'utm_status': 'enable',
'uuid': 'test_value_37',
'waf_profile': 'test_value_38',
'webcache': 'enable',
'webcache_https': 'disable',
'webfilter_profile': 'test_value_41',
'webproxy_forward_server': 'test_value_42',
'webproxy_profile': 'test_value_43'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_proxy_policy.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'application-list': 'test_value_4',
'av-profile': 'test_value_5',
'comments': 'test_value_6',
'disclaimer': 'disable',
'dlp-sensor': 'test_value_8',
'dstaddr-negate': 'enable',
'global-label': 'test_value_10',
'http-tunnel-auth': 'enable',
'icap-profile': 'test_value_12',
'internet-service': 'enable',
'internet-service-negate': 'enable',
'ips-sensor': 'test_value_15',
'label': 'test_value_16',
'logtraffic': 'all',
'logtraffic-start': 'enable',
'policyid': '19',
'profile-group': 'test_value_20',
'profile-protocol-options': 'test_value_21',
'profile-type': 'single',
'proxy': 'explicit-web',
'redirect-url': 'test_value_24',
'replacemsg-override-group': 'test_value_25',
'scan-botnet-connections': 'disable',
'schedule': 'test_value_27',
'service-negate': 'enable',
'session-ttl': '29',
'spamfilter-profile': 'test_value_30',
'srcaddr-negate': 'enable',
'ssh-filter-profile': 'test_value_32',
'ssl-ssh-profile': 'test_value_33',
'status': 'enable',
'transparent': 'enable',
'utm-status': 'enable',
'uuid': 'test_value_37',
'waf-profile': 'test_value_38',
'webcache': 'enable',
'webcache-https': 'disable',
'webfilter-profile': 'test_value_41',
'webproxy-forward-server': 'test_value_42',
'webproxy-profile': 'test_value_43'
}
set_method_mock.assert_called_with('firewall', 'proxy-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_proxy_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_proxy_policy': {
'random_attribute_not_valid': 'tag',
'action': 'accept',
'application_list': 'test_value_4',
'av_profile': 'test_value_5',
'comments': 'test_value_6',
'disclaimer': 'disable',
'dlp_sensor': 'test_value_8',
'dstaddr_negate': 'enable',
'global_label': 'test_value_10',
'http_tunnel_auth': 'enable',
'icap_profile': 'test_value_12',
'internet_service': 'enable',
'internet_service_negate': 'enable',
'ips_sensor': 'test_value_15',
'label': 'test_value_16',
'logtraffic': 'all',
'logtraffic_start': 'enable',
'policyid': '19',
'profile_group': 'test_value_20',
'profile_protocol_options': 'test_value_21',
'profile_type': 'single',
'proxy': 'explicit-web',
'redirect_url': 'test_value_24',
'replacemsg_override_group': 'test_value_25',
'scan_botnet_connections': 'disable',
'schedule': 'test_value_27',
'service_negate': 'enable',
'session_ttl': '29',
'spamfilter_profile': 'test_value_30',
'srcaddr_negate': 'enable',
'ssh_filter_profile': 'test_value_32',
'ssl_ssh_profile': 'test_value_33',
'status': 'enable',
'transparent': 'enable',
'utm_status': 'enable',
'uuid': 'test_value_37',
'waf_profile': 'test_value_38',
'webcache': 'enable',
'webcache_https': 'disable',
'webfilter_profile': 'test_value_41',
'webproxy_forward_server': 'test_value_42',
'webproxy_profile': 'test_value_43'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_proxy_policy.fortios_firewall(input_data, fos_instance)
expected_data = {
'action': 'accept',
'application-list': 'test_value_4',
'av-profile': 'test_value_5',
'comments': 'test_value_6',
'disclaimer': 'disable',
'dlp-sensor': 'test_value_8',
'dstaddr-negate': 'enable',
'global-label': 'test_value_10',
'http-tunnel-auth': 'enable',
'icap-profile': 'test_value_12',
'internet-service': 'enable',
'internet-service-negate': 'enable',
'ips-sensor': 'test_value_15',
'label': 'test_value_16',
'logtraffic': 'all',
'logtraffic-start': 'enable',
'policyid': '19',
'profile-group': 'test_value_20',
'profile-protocol-options': 'test_value_21',
'profile-type': 'single',
'proxy': 'explicit-web',
'redirect-url': 'test_value_24',
'replacemsg-override-group': 'test_value_25',
'scan-botnet-connections': 'disable',
'schedule': 'test_value_27',
'service-negate': 'enable',
'session-ttl': '29',
'spamfilter-profile': 'test_value_30',
'srcaddr-negate': 'enable',
'ssh-filter-profile': 'test_value_32',
'ssl-ssh-profile': 'test_value_33',
'status': 'enable',
'transparent': 'enable',
'utm-status': 'enable',
'uuid': 'test_value_37',
'waf-profile': 'test_value_38',
'webcache': 'enable',
'webcache-https': 'disable',
'webfilter-profile': 'test_value_41',
'webproxy-forward-server': 'test_value_42',
'webproxy-profile': 'test_value_43'
}
set_method_mock.assert_called_with('firewall', 'proxy-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,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_schedule_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_schedule_group.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_schedule_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_schedule_group': {
'color': '3',
'name': 'default_name_4'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_schedule_group.fortios_firewall_schedule(input_data, fos_instance)
expected_data = {
'color': '3',
'name': 'default_name_4'
}
set_method_mock.assert_called_with('firewall.schedule', '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_schedule_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_schedule_group': {
'color': '3',
'name': 'default_name_4'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_schedule_group.fortios_firewall_schedule(input_data, fos_instance)
expected_data = {
'color': '3',
'name': 'default_name_4'
}
set_method_mock.assert_called_with('firewall.schedule', '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_schedule_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_schedule_group': {
'color': '3',
'name': 'default_name_4'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_schedule_group.fortios_firewall_schedule(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall.schedule', '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_schedule_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_schedule_group': {
'color': '3',
'name': 'default_name_4'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_schedule_group.fortios_firewall_schedule(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall.schedule', '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_schedule_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_schedule_group': {
'color': '3',
'name': 'default_name_4'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_schedule_group.fortios_firewall_schedule(input_data, fos_instance)
expected_data = {
'color': '3',
'name': 'default_name_4'
}
set_method_mock.assert_called_with('firewall.schedule', '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_schedule_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_schedule_group': {
'random_attribute_not_valid': 'tag',
'color': '3',
'name': 'default_name_4'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_schedule_group.fortios_firewall_schedule(input_data, fos_instance)
expected_data = {
'color': '3',
'name': 'default_name_4'
}
set_method_mock.assert_called_with('firewall.schedule', '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_schedule_onetime
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_schedule_onetime.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_schedule_onetime_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_schedule_onetime': {
'color': '3',
'end': 'test_value_4',
'expiration_days': '5',
'name': 'default_name_6',
'start': 'test_value_7'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_schedule_onetime.fortios_firewall_schedule(input_data, fos_instance)
expected_data = {
'color': '3',
'end': 'test_value_4',
'expiration-days': '5',
'name': 'default_name_6',
'start': 'test_value_7'
}
set_method_mock.assert_called_with('firewall.schedule', 'onetime', 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_schedule_onetime_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_schedule_onetime': {
'color': '3',
'end': 'test_value_4',
'expiration_days': '5',
'name': 'default_name_6',
'start': 'test_value_7'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_schedule_onetime.fortios_firewall_schedule(input_data, fos_instance)
expected_data = {
'color': '3',
'end': 'test_value_4',
'expiration-days': '5',
'name': 'default_name_6',
'start': 'test_value_7'
}
set_method_mock.assert_called_with('firewall.schedule', 'onetime', 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_schedule_onetime_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_schedule_onetime': {
'color': '3',
'end': 'test_value_4',
'expiration_days': '5',
'name': 'default_name_6',
'start': 'test_value_7'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_schedule_onetime.fortios_firewall_schedule(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall.schedule', 'onetime', 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_schedule_onetime_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_schedule_onetime': {
'color': '3',
'end': 'test_value_4',
'expiration_days': '5',
'name': 'default_name_6',
'start': 'test_value_7'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_schedule_onetime.fortios_firewall_schedule(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall.schedule', 'onetime', 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_schedule_onetime_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_schedule_onetime': {
'color': '3',
'end': 'test_value_4',
'expiration_days': '5',
'name': 'default_name_6',
'start': 'test_value_7'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_schedule_onetime.fortios_firewall_schedule(input_data, fos_instance)
expected_data = {
'color': '3',
'end': 'test_value_4',
'expiration-days': '5',
'name': 'default_name_6',
'start': 'test_value_7'
}
set_method_mock.assert_called_with('firewall.schedule', 'onetime', 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_schedule_onetime_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_schedule_onetime': {
'random_attribute_not_valid': 'tag',
'color': '3',
'end': 'test_value_4',
'expiration_days': '5',
'name': 'default_name_6',
'start': 'test_value_7'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_schedule_onetime.fortios_firewall_schedule(input_data, fos_instance)
expected_data = {
'color': '3',
'end': 'test_value_4',
'expiration-days': '5',
'name': 'default_name_6',
'start': 'test_value_7'
}
set_method_mock.assert_called_with('firewall.schedule', 'onetime', 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_schedule_recurring
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_schedule_recurring.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_schedule_recurring_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_schedule_recurring': {
'color': '3',
'day': 'sunday',
'end': 'test_value_5',
'name': 'default_name_6',
'start': 'test_value_7'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_schedule_recurring.fortios_firewall_schedule(input_data, fos_instance)
expected_data = {
'color': '3',
'day': 'sunday',
'end': 'test_value_5',
'name': 'default_name_6',
'start': 'test_value_7'
}
set_method_mock.assert_called_with('firewall.schedule', 'recurring', 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_schedule_recurring_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_schedule_recurring': {
'color': '3',
'day': 'sunday',
'end': 'test_value_5',
'name': 'default_name_6',
'start': 'test_value_7'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_schedule_recurring.fortios_firewall_schedule(input_data, fos_instance)
expected_data = {
'color': '3',
'day': 'sunday',
'end': 'test_value_5',
'name': 'default_name_6',
'start': 'test_value_7'
}
set_method_mock.assert_called_with('firewall.schedule', 'recurring', 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_schedule_recurring_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_schedule_recurring': {
'color': '3',
'day': 'sunday',
'end': 'test_value_5',
'name': 'default_name_6',
'start': 'test_value_7'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_schedule_recurring.fortios_firewall_schedule(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall.schedule', 'recurring', 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_schedule_recurring_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_schedule_recurring': {
'color': '3',
'day': 'sunday',
'end': 'test_value_5',
'name': 'default_name_6',
'start': 'test_value_7'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_schedule_recurring.fortios_firewall_schedule(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall.schedule', 'recurring', 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_schedule_recurring_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_schedule_recurring': {
'color': '3',
'day': 'sunday',
'end': 'test_value_5',
'name': 'default_name_6',
'start': 'test_value_7'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_schedule_recurring.fortios_firewall_schedule(input_data, fos_instance)
expected_data = {
'color': '3',
'day': 'sunday',
'end': 'test_value_5',
'name': 'default_name_6',
'start': 'test_value_7'
}
set_method_mock.assert_called_with('firewall.schedule', 'recurring', 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_schedule_recurring_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_schedule_recurring': {
'random_attribute_not_valid': 'tag',
'color': '3',
'day': 'sunday',
'end': 'test_value_5',
'name': 'default_name_6',
'start': 'test_value_7'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_schedule_recurring.fortios_firewall_schedule(input_data, fos_instance)
expected_data = {
'color': '3',
'day': 'sunday',
'end': 'test_value_5',
'name': 'default_name_6',
'start': 'test_value_7'
}
set_method_mock.assert_called_with('firewall.schedule', 'recurring', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,209 @@
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_firewall_service_category
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_service_category.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_service_category_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_service_category': {
'comment': 'Comment.',
'name': 'default_name_4'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_service_category.fortios_firewall_service(input_data, fos_instance)
expected_data = {
'comment': 'Comment.',
'name': 'default_name_4'
}
set_method_mock.assert_called_with('firewall.service', 'category', 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_service_category_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_service_category': {
'comment': 'Comment.',
'name': 'default_name_4'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_service_category.fortios_firewall_service(input_data, fos_instance)
expected_data = {
'comment': 'Comment.',
'name': 'default_name_4'
}
set_method_mock.assert_called_with('firewall.service', 'category', 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_service_category_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_service_category': {
'comment': 'Comment.',
'name': 'default_name_4'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_service_category.fortios_firewall_service(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall.service', 'category', 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_service_category_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_service_category': {
'comment': 'Comment.',
'name': 'default_name_4'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_service_category.fortios_firewall_service(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall.service', 'category', 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_service_category_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_service_category': {
'comment': 'Comment.',
'name': 'default_name_4'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_service_category.fortios_firewall_service(input_data, fos_instance)
expected_data = {
'comment': 'Comment.',
'name': 'default_name_4'
}
set_method_mock.assert_called_with('firewall.service', 'category', 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_service_category_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_service_category': {
'random_attribute_not_valid': 'tag',
'comment': 'Comment.',
'name': 'default_name_4'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_service_category.fortios_firewall_service(input_data, fos_instance)
expected_data = {
'comment': 'Comment.',
'name': 'default_name_4'
}
set_method_mock.assert_called_with('firewall.service', 'category', 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,409 @@
# 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_service_custom
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_firewall_service_custom.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_service_custom_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'firewall_service_custom': {'app_service_type': 'disable',
'category': 'test_value_4',
'check_reset_range': 'disable',
'color': '6',
'comment': 'Comment.',
'fqdn': 'test_value_8',
'helper': 'auto',
'icmpcode': '10',
'icmptype': '11',
'iprange': 'test_value_12',
'name': 'default_name_13',
'protocol': 'TCP/UDP/SCTP',
'protocol_number': '15',
'proxy': 'enable',
'sctp_portrange': 'test_value_17',
'session_ttl': '18',
'tcp_halfclose_timer': '19',
'tcp_halfopen_timer': '20',
'tcp_portrange': 'test_value_21',
'tcp_timewait_timer': '22',
'udp_idle_timer': '23',
'udp_portrange': 'test_value_24',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_service_custom.fortios_firewall_service(input_data, fos_instance)
expected_data = {'app-service-type': 'disable',
'category': 'test_value_4',
'check-reset-range': 'disable',
'color': '6',
'comment': 'Comment.',
'fqdn': 'test_value_8',
'helper': 'auto',
'icmpcode': '10',
'icmptype': '11',
'iprange': 'test_value_12',
'name': 'default_name_13',
'protocol': 'TCP/UDP/SCTP',
'protocol-number': '15',
'proxy': 'enable',
'sctp-portrange': 'test_value_17',
'session-ttl': '18',
'tcp-halfclose-timer': '19',
'tcp-halfopen-timer': '20',
'tcp-portrange': 'test_value_21',
'tcp-timewait-timer': '22',
'udp-idle-timer': '23',
'udp-portrange': 'test_value_24',
'visibility': 'enable'
}
set_method_mock.assert_called_with('firewall.service', 'custom', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_firewall_service_custom_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'firewall_service_custom': {'app_service_type': 'disable',
'category': 'test_value_4',
'check_reset_range': 'disable',
'color': '6',
'comment': 'Comment.',
'fqdn': 'test_value_8',
'helper': 'auto',
'icmpcode': '10',
'icmptype': '11',
'iprange': 'test_value_12',
'name': 'default_name_13',
'protocol': 'TCP/UDP/SCTP',
'protocol_number': '15',
'proxy': 'enable',
'sctp_portrange': 'test_value_17',
'session_ttl': '18',
'tcp_halfclose_timer': '19',
'tcp_halfopen_timer': '20',
'tcp_portrange': 'test_value_21',
'tcp_timewait_timer': '22',
'udp_idle_timer': '23',
'udp_portrange': 'test_value_24',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_service_custom.fortios_firewall_service(input_data, fos_instance)
expected_data = {'app-service-type': 'disable',
'category': 'test_value_4',
'check-reset-range': 'disable',
'color': '6',
'comment': 'Comment.',
'fqdn': 'test_value_8',
'helper': 'auto',
'icmpcode': '10',
'icmptype': '11',
'iprange': 'test_value_12',
'name': 'default_name_13',
'protocol': 'TCP/UDP/SCTP',
'protocol-number': '15',
'proxy': 'enable',
'sctp-portrange': 'test_value_17',
'session-ttl': '18',
'tcp-halfclose-timer': '19',
'tcp-halfopen-timer': '20',
'tcp-portrange': 'test_value_21',
'tcp-timewait-timer': '22',
'udp-idle-timer': '23',
'udp-portrange': 'test_value_24',
'visibility': 'enable'
}
set_method_mock.assert_called_with('firewall.service', 'custom', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_firewall_service_custom_removal(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'firewall_service_custom': {'app_service_type': 'disable',
'category': 'test_value_4',
'check_reset_range': 'disable',
'color': '6',
'comment': 'Comment.',
'fqdn': 'test_value_8',
'helper': 'auto',
'icmpcode': '10',
'icmptype': '11',
'iprange': 'test_value_12',
'name': 'default_name_13',
'protocol': 'TCP/UDP/SCTP',
'protocol_number': '15',
'proxy': 'enable',
'sctp_portrange': 'test_value_17',
'session_ttl': '18',
'tcp_halfclose_timer': '19',
'tcp_halfopen_timer': '20',
'tcp_portrange': 'test_value_21',
'tcp_timewait_timer': '22',
'udp_idle_timer': '23',
'udp_portrange': 'test_value_24',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_service_custom.fortios_firewall_service(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall.service', 'custom', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_firewall_service_custom_deletion_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'firewall_service_custom': {'app_service_type': 'disable',
'category': 'test_value_4',
'check_reset_range': 'disable',
'color': '6',
'comment': 'Comment.',
'fqdn': 'test_value_8',
'helper': 'auto',
'icmpcode': '10',
'icmptype': '11',
'iprange': 'test_value_12',
'name': 'default_name_13',
'protocol': 'TCP/UDP/SCTP',
'protocol_number': '15',
'proxy': 'enable',
'sctp_portrange': 'test_value_17',
'session_ttl': '18',
'tcp_halfclose_timer': '19',
'tcp_halfopen_timer': '20',
'tcp_portrange': 'test_value_21',
'tcp_timewait_timer': '22',
'udp_idle_timer': '23',
'udp_portrange': 'test_value_24',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_service_custom.fortios_firewall_service(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall.service', 'custom', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_firewall_service_custom_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'firewall_service_custom': {'app_service_type': 'disable',
'category': 'test_value_4',
'check_reset_range': 'disable',
'color': '6',
'comment': 'Comment.',
'fqdn': 'test_value_8',
'helper': 'auto',
'icmpcode': '10',
'icmptype': '11',
'iprange': 'test_value_12',
'name': 'default_name_13',
'protocol': 'TCP/UDP/SCTP',
'protocol_number': '15',
'proxy': 'enable',
'sctp_portrange': 'test_value_17',
'session_ttl': '18',
'tcp_halfclose_timer': '19',
'tcp_halfopen_timer': '20',
'tcp_portrange': 'test_value_21',
'tcp_timewait_timer': '22',
'udp_idle_timer': '23',
'udp_portrange': 'test_value_24',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_service_custom.fortios_firewall_service(input_data, fos_instance)
expected_data = {'app-service-type': 'disable',
'category': 'test_value_4',
'check-reset-range': 'disable',
'color': '6',
'comment': 'Comment.',
'fqdn': 'test_value_8',
'helper': 'auto',
'icmpcode': '10',
'icmptype': '11',
'iprange': 'test_value_12',
'name': 'default_name_13',
'protocol': 'TCP/UDP/SCTP',
'protocol-number': '15',
'proxy': 'enable',
'sctp-portrange': 'test_value_17',
'session-ttl': '18',
'tcp-halfclose-timer': '19',
'tcp-halfopen-timer': '20',
'tcp-portrange': 'test_value_21',
'tcp-timewait-timer': '22',
'udp-idle-timer': '23',
'udp-portrange': 'test_value_24',
'visibility': 'enable'
}
set_method_mock.assert_called_with('firewall.service', 'custom', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_firewall_service_custom_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'firewall_service_custom': {
'random_attribute_not_valid': 'tag', 'app_service_type': 'disable',
'category': 'test_value_4',
'check_reset_range': 'disable',
'color': '6',
'comment': 'Comment.',
'fqdn': 'test_value_8',
'helper': 'auto',
'icmpcode': '10',
'icmptype': '11',
'iprange': 'test_value_12',
'name': 'default_name_13',
'protocol': 'TCP/UDP/SCTP',
'protocol_number': '15',
'proxy': 'enable',
'sctp_portrange': 'test_value_17',
'session_ttl': '18',
'tcp_halfclose_timer': '19',
'tcp_halfopen_timer': '20',
'tcp_portrange': 'test_value_21',
'tcp_timewait_timer': '22',
'udp_idle_timer': '23',
'udp_portrange': 'test_value_24',
'visibility': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_service_custom.fortios_firewall_service(input_data, fos_instance)
expected_data = {'app-service-type': 'disable',
'category': 'test_value_4',
'check-reset-range': 'disable',
'color': '6',
'comment': 'Comment.',
'fqdn': 'test_value_8',
'helper': 'auto',
'icmpcode': '10',
'icmptype': '11',
'iprange': 'test_value_12',
'name': 'default_name_13',
'protocol': 'TCP/UDP/SCTP',
'protocol-number': '15',
'proxy': 'enable',
'sctp-portrange': 'test_value_17',
'session-ttl': '18',
'tcp-halfclose-timer': '19',
'tcp-halfopen-timer': '20',
'tcp-portrange': 'test_value_21',
'tcp-timewait-timer': '22',
'udp-idle-timer': '23',
'udp-portrange': 'test_value_24',
'visibility': 'enable'
}
set_method_mock.assert_called_with('firewall.service', 'custom', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,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_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_service_group.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_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_service_group': {
'color': '3',
'comment': 'Comment.',
'name': 'default_name_5',
'proxy': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_service_group.fortios_firewall_service(input_data, fos_instance)
expected_data = {
'color': '3',
'comment': 'Comment.',
'name': 'default_name_5',
'proxy': 'enable'
}
set_method_mock.assert_called_with('firewall.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_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_service_group': {
'color': '3',
'comment': 'Comment.',
'name': 'default_name_5',
'proxy': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_service_group.fortios_firewall_service(input_data, fos_instance)
expected_data = {
'color': '3',
'comment': 'Comment.',
'name': 'default_name_5',
'proxy': 'enable'
}
set_method_mock.assert_called_with('firewall.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_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_service_group': {
'color': '3',
'comment': 'Comment.',
'name': 'default_name_5',
'proxy': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_service_group.fortios_firewall_service(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall.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_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_service_group': {
'color': '3',
'comment': 'Comment.',
'name': 'default_name_5',
'proxy': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_service_group.fortios_firewall_service(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall.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_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_service_group': {
'color': '3',
'comment': 'Comment.',
'name': 'default_name_5',
'proxy': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_service_group.fortios_firewall_service(input_data, fos_instance)
expected_data = {
'color': '3',
'comment': 'Comment.',
'name': 'default_name_5',
'proxy': 'enable'
}
set_method_mock.assert_called_with('firewall.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_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_service_group': {
'random_attribute_not_valid': 'tag',
'color': '3',
'comment': 'Comment.',
'name': 'default_name_5',
'proxy': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_service_group.fortios_firewall_service(input_data, fos_instance)
expected_data = {
'color': '3',
'comment': 'Comment.',
'name': 'default_name_5',
'proxy': 'enable'
}
set_method_mock.assert_called_with('firewall.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,269 @@
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_firewall_shaper_per_ip_shaper
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_shaper_per_ip_shaper.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_shaper_per_ip_shaper_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_shaper_per_ip_shaper': {
'bandwidth_unit': 'kbps',
'diffserv_forward': 'enable',
'diffserv_reverse': 'enable',
'diffservcode_forward': 'test_value_6',
'diffservcode_rev': 'test_value_7',
'max_bandwidth': '8',
'max_concurrent_session': '9',
'name': 'default_name_10'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_shaper_per_ip_shaper.fortios_firewall_shaper(input_data, fos_instance)
expected_data = {
'bandwidth-unit': 'kbps',
'diffserv-forward': 'enable',
'diffserv-reverse': 'enable',
'diffservcode-forward': 'test_value_6',
'diffservcode-rev': 'test_value_7',
'max-bandwidth': '8',
'max-concurrent-session': '9',
'name': 'default_name_10'
}
set_method_mock.assert_called_with('firewall.shaper', 'per-ip-shaper', 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_shaper_per_ip_shaper_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_shaper_per_ip_shaper': {
'bandwidth_unit': 'kbps',
'diffserv_forward': 'enable',
'diffserv_reverse': 'enable',
'diffservcode_forward': 'test_value_6',
'diffservcode_rev': 'test_value_7',
'max_bandwidth': '8',
'max_concurrent_session': '9',
'name': 'default_name_10'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_shaper_per_ip_shaper.fortios_firewall_shaper(input_data, fos_instance)
expected_data = {
'bandwidth-unit': 'kbps',
'diffserv-forward': 'enable',
'diffserv-reverse': 'enable',
'diffservcode-forward': 'test_value_6',
'diffservcode-rev': 'test_value_7',
'max-bandwidth': '8',
'max-concurrent-session': '9',
'name': 'default_name_10'
}
set_method_mock.assert_called_with('firewall.shaper', 'per-ip-shaper', 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_shaper_per_ip_shaper_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_shaper_per_ip_shaper': {
'bandwidth_unit': 'kbps',
'diffserv_forward': 'enable',
'diffserv_reverse': 'enable',
'diffservcode_forward': 'test_value_6',
'diffservcode_rev': 'test_value_7',
'max_bandwidth': '8',
'max_concurrent_session': '9',
'name': 'default_name_10'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_shaper_per_ip_shaper.fortios_firewall_shaper(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall.shaper', 'per-ip-shaper', 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_shaper_per_ip_shaper_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_shaper_per_ip_shaper': {
'bandwidth_unit': 'kbps',
'diffserv_forward': 'enable',
'diffserv_reverse': 'enable',
'diffservcode_forward': 'test_value_6',
'diffservcode_rev': 'test_value_7',
'max_bandwidth': '8',
'max_concurrent_session': '9',
'name': 'default_name_10'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_shaper_per_ip_shaper.fortios_firewall_shaper(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall.shaper', 'per-ip-shaper', 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_shaper_per_ip_shaper_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_shaper_per_ip_shaper': {
'bandwidth_unit': 'kbps',
'diffserv_forward': 'enable',
'diffserv_reverse': 'enable',
'diffservcode_forward': 'test_value_6',
'diffservcode_rev': 'test_value_7',
'max_bandwidth': '8',
'max_concurrent_session': '9',
'name': 'default_name_10'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_shaper_per_ip_shaper.fortios_firewall_shaper(input_data, fos_instance)
expected_data = {
'bandwidth-unit': 'kbps',
'diffserv-forward': 'enable',
'diffserv-reverse': 'enable',
'diffservcode-forward': 'test_value_6',
'diffservcode-rev': 'test_value_7',
'max-bandwidth': '8',
'max-concurrent-session': '9',
'name': 'default_name_10'
}
set_method_mock.assert_called_with('firewall.shaper', 'per-ip-shaper', 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_shaper_per_ip_shaper_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_shaper_per_ip_shaper': {
'random_attribute_not_valid': 'tag',
'bandwidth_unit': 'kbps',
'diffserv_forward': 'enable',
'diffserv_reverse': 'enable',
'diffservcode_forward': 'test_value_6',
'diffservcode_rev': 'test_value_7',
'max_bandwidth': '8',
'max_concurrent_session': '9',
'name': 'default_name_10'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_shaper_per_ip_shaper.fortios_firewall_shaper(input_data, fos_instance)
expected_data = {
'bandwidth-unit': 'kbps',
'diffserv-forward': 'enable',
'diffserv-reverse': 'enable',
'diffservcode-forward': 'test_value_6',
'diffservcode-rev': 'test_value_7',
'max-bandwidth': '8',
'max-concurrent-session': '9',
'name': 'default_name_10'
}
set_method_mock.assert_called_with('firewall.shaper', 'per-ip-shaper', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,269 @@
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_firewall_shaper_traffic_shaper
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_shaper_traffic_shaper.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_shaper_traffic_shaper_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_shaper_traffic_shaper': {
'bandwidth_unit': 'kbps',
'diffserv': 'enable',
'diffservcode': 'test_value_5',
'guaranteed_bandwidth': '6',
'maximum_bandwidth': '7',
'name': 'default_name_8',
'per_policy': 'disable',
'priority': 'low'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_shaper_traffic_shaper.fortios_firewall_shaper(input_data, fos_instance)
expected_data = {
'bandwidth-unit': 'kbps',
'diffserv': 'enable',
'diffservcode': 'test_value_5',
'guaranteed-bandwidth': '6',
'maximum-bandwidth': '7',
'name': 'default_name_8',
'per-policy': 'disable',
'priority': 'low'
}
set_method_mock.assert_called_with('firewall.shaper', 'traffic-shaper', 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_shaper_traffic_shaper_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_shaper_traffic_shaper': {
'bandwidth_unit': 'kbps',
'diffserv': 'enable',
'diffservcode': 'test_value_5',
'guaranteed_bandwidth': '6',
'maximum_bandwidth': '7',
'name': 'default_name_8',
'per_policy': 'disable',
'priority': 'low'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_shaper_traffic_shaper.fortios_firewall_shaper(input_data, fos_instance)
expected_data = {
'bandwidth-unit': 'kbps',
'diffserv': 'enable',
'diffservcode': 'test_value_5',
'guaranteed-bandwidth': '6',
'maximum-bandwidth': '7',
'name': 'default_name_8',
'per-policy': 'disable',
'priority': 'low'
}
set_method_mock.assert_called_with('firewall.shaper', 'traffic-shaper', 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_shaper_traffic_shaper_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_shaper_traffic_shaper': {
'bandwidth_unit': 'kbps',
'diffserv': 'enable',
'diffservcode': 'test_value_5',
'guaranteed_bandwidth': '6',
'maximum_bandwidth': '7',
'name': 'default_name_8',
'per_policy': 'disable',
'priority': 'low'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_shaper_traffic_shaper.fortios_firewall_shaper(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall.shaper', 'traffic-shaper', 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_shaper_traffic_shaper_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_shaper_traffic_shaper': {
'bandwidth_unit': 'kbps',
'diffserv': 'enable',
'diffservcode': 'test_value_5',
'guaranteed_bandwidth': '6',
'maximum_bandwidth': '7',
'name': 'default_name_8',
'per_policy': 'disable',
'priority': 'low'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_shaper_traffic_shaper.fortios_firewall_shaper(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall.shaper', 'traffic-shaper', 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_shaper_traffic_shaper_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_shaper_traffic_shaper': {
'bandwidth_unit': 'kbps',
'diffserv': 'enable',
'diffservcode': 'test_value_5',
'guaranteed_bandwidth': '6',
'maximum_bandwidth': '7',
'name': 'default_name_8',
'per_policy': 'disable',
'priority': 'low'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_shaper_traffic_shaper.fortios_firewall_shaper(input_data, fos_instance)
expected_data = {
'bandwidth-unit': 'kbps',
'diffserv': 'enable',
'diffservcode': 'test_value_5',
'guaranteed-bandwidth': '6',
'maximum-bandwidth': '7',
'name': 'default_name_8',
'per-policy': 'disable',
'priority': 'low'
}
set_method_mock.assert_called_with('firewall.shaper', 'traffic-shaper', 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_shaper_traffic_shaper_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_shaper_traffic_shaper': {
'random_attribute_not_valid': 'tag',
'bandwidth_unit': 'kbps',
'diffserv': 'enable',
'diffservcode': 'test_value_5',
'guaranteed_bandwidth': '6',
'maximum_bandwidth': '7',
'name': 'default_name_8',
'per_policy': 'disable',
'priority': 'low'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_shaper_traffic_shaper.fortios_firewall_shaper(input_data, fos_instance)
expected_data = {
'bandwidth-unit': 'kbps',
'diffserv': 'enable',
'diffservcode': 'test_value_5',
'guaranteed-bandwidth': '6',
'maximum-bandwidth': '7',
'name': 'default_name_8',
'per-policy': 'disable',
'priority': 'low'
}
set_method_mock.assert_called_with('firewall.shaper', 'traffic-shaper', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,299 @@
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_firewall_shaping_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_shaping_policy.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_shaping_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_shaping_policy': {'class_id': '3',
'comment': 'Comments.',
'id': '5',
'internet_service': 'enable',
'internet_service_src': 'enable',
'ip_version': '4',
'per_ip_shaper': 'test_value_9',
'schedule': 'test_value_10',
'status': 'enable',
'traffic_shaper': 'test_value_12',
'traffic_shaper_reverse': 'test_value_13',
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_shaping_policy.fortios_firewall(input_data, fos_instance)
expected_data = {'class-id': '3',
'comment': 'Comments.',
'id': '5',
'internet-service': 'enable',
'internet-service-src': 'enable',
'ip-version': '4',
'per-ip-shaper': 'test_value_9',
'schedule': 'test_value_10',
'status': 'enable',
'traffic-shaper': 'test_value_12',
'traffic-shaper-reverse': 'test_value_13',
}
set_method_mock.assert_called_with('firewall', 'shaping-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_shaping_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_shaping_policy': {'class_id': '3',
'comment': 'Comments.',
'id': '5',
'internet_service': 'enable',
'internet_service_src': 'enable',
'ip_version': '4',
'per_ip_shaper': 'test_value_9',
'schedule': 'test_value_10',
'status': 'enable',
'traffic_shaper': 'test_value_12',
'traffic_shaper_reverse': 'test_value_13',
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_shaping_policy.fortios_firewall(input_data, fos_instance)
expected_data = {'class-id': '3',
'comment': 'Comments.',
'id': '5',
'internet-service': 'enable',
'internet-service-src': 'enable',
'ip-version': '4',
'per-ip-shaper': 'test_value_9',
'schedule': 'test_value_10',
'status': 'enable',
'traffic-shaper': 'test_value_12',
'traffic-shaper-reverse': 'test_value_13',
}
set_method_mock.assert_called_with('firewall', 'shaping-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_shaping_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_shaping_policy': {'class_id': '3',
'comment': 'Comments.',
'id': '5',
'internet_service': 'enable',
'internet_service_src': 'enable',
'ip_version': '4',
'per_ip_shaper': 'test_value_9',
'schedule': 'test_value_10',
'status': 'enable',
'traffic_shaper': 'test_value_12',
'traffic_shaper_reverse': 'test_value_13',
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_shaping_policy.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'shaping-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_shaping_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_shaping_policy': {'class_id': '3',
'comment': 'Comments.',
'id': '5',
'internet_service': 'enable',
'internet_service_src': 'enable',
'ip_version': '4',
'per_ip_shaper': 'test_value_9',
'schedule': 'test_value_10',
'status': 'enable',
'traffic_shaper': 'test_value_12',
'traffic_shaper_reverse': 'test_value_13',
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_shaping_policy.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'shaping-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_shaping_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_shaping_policy': {'class_id': '3',
'comment': 'Comments.',
'id': '5',
'internet_service': 'enable',
'internet_service_src': 'enable',
'ip_version': '4',
'per_ip_shaper': 'test_value_9',
'schedule': 'test_value_10',
'status': 'enable',
'traffic_shaper': 'test_value_12',
'traffic_shaper_reverse': 'test_value_13',
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_shaping_policy.fortios_firewall(input_data, fos_instance)
expected_data = {'class-id': '3',
'comment': 'Comments.',
'id': '5',
'internet-service': 'enable',
'internet-service-src': 'enable',
'ip-version': '4',
'per-ip-shaper': 'test_value_9',
'schedule': 'test_value_10',
'status': 'enable',
'traffic-shaper': 'test_value_12',
'traffic-shaper-reverse': 'test_value_13',
}
set_method_mock.assert_called_with('firewall', 'shaping-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_shaping_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_shaping_policy': {
'random_attribute_not_valid': 'tag', 'class_id': '3',
'comment': 'Comments.',
'id': '5',
'internet_service': 'enable',
'internet_service_src': 'enable',
'ip_version': '4',
'per_ip_shaper': 'test_value_9',
'schedule': 'test_value_10',
'status': 'enable',
'traffic_shaper': 'test_value_12',
'traffic_shaper_reverse': 'test_value_13',
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_shaping_policy.fortios_firewall(input_data, fos_instance)
expected_data = {'class-id': '3',
'comment': 'Comments.',
'id': '5',
'internet-service': 'enable',
'internet-service-src': 'enable',
'ip-version': '4',
'per-ip-shaper': 'test_value_9',
'schedule': 'test_value_10',
'status': 'enable',
'traffic-shaper': 'test_value_12',
'traffic-shaper-reverse': 'test_value_13',
}
set_method_mock.assert_called_with('firewall', 'shaping-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,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_shaping_profile
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_firewall_shaping_profile.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_shaping_profile_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'firewall_shaping_profile': {
'comment': 'Comment.',
'default_class_id': '4',
'profile_name': 'test_value_5',
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_shaping_profile.fortios_firewall(input_data, fos_instance)
expected_data = {
'comment': 'Comment.',
'default-class-id': '4',
'profile-name': 'test_value_5',
}
set_method_mock.assert_called_with('firewall', 'shaping-profile', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_firewall_shaping_profile_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'firewall_shaping_profile': {
'comment': 'Comment.',
'default_class_id': '4',
'profile_name': 'test_value_5',
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_shaping_profile.fortios_firewall(input_data, fos_instance)
expected_data = {
'comment': 'Comment.',
'default-class-id': '4',
'profile-name': 'test_value_5',
}
set_method_mock.assert_called_with('firewall', 'shaping-profile', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_firewall_shaping_profile_removal(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'firewall_shaping_profile': {
'comment': 'Comment.',
'default_class_id': '4',
'profile_name': 'test_value_5',
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_shaping_profile.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'shaping-profile', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_firewall_shaping_profile_deletion_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'firewall_shaping_profile': {
'comment': 'Comment.',
'default_class_id': '4',
'profile_name': 'test_value_5',
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_shaping_profile.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'shaping-profile', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_firewall_shaping_profile_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'firewall_shaping_profile': {
'comment': 'Comment.',
'default_class_id': '4',
'profile_name': 'test_value_5',
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_shaping_profile.fortios_firewall(input_data, fos_instance)
expected_data = {
'comment': 'Comment.',
'default-class-id': '4',
'profile-name': 'test_value_5',
}
set_method_mock.assert_called_with('firewall', 'shaping-profile', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_firewall_shaping_profile_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'firewall_shaping_profile': {
'random_attribute_not_valid': 'tag',
'comment': 'Comment.',
'default_class_id': '4',
'profile_name': 'test_value_5',
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_shaping_profile.fortios_firewall(input_data, fos_instance)
expected_data = {
'comment': 'Comment.',
'default-class-id': '4',
'profile-name': 'test_value_5',
}
set_method_mock.assert_called_with('firewall', 'shaping-profile', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,439 @@
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_firewall_sniffer
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_sniffer.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_sniffer_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_sniffer': {'application_list': 'test_value_3',
'application_list_status': 'enable',
'av_profile': 'test_value_5',
'av_profile_status': 'enable',
'dlp_sensor': 'test_value_7',
'dlp_sensor_status': 'enable',
'dsri': 'enable',
'host': 'myhostname10',
'id': '11',
'interface': 'test_value_12',
'ips_dos_status': 'enable',
'ips_sensor': 'test_value_14',
'ips_sensor_status': 'enable',
'ipv6': 'enable',
'logtraffic': 'all',
'max_packet_count': '18',
'non_ip': 'enable',
'port': 'test_value_20',
'protocol': 'test_value_21',
'scan_botnet_connections': 'disable',
'spamfilter_profile': 'test_value_23',
'spamfilter_profile_status': 'enable',
'status': 'enable',
'vlan': 'test_value_26',
'webfilter_profile': 'test_value_27',
'webfilter_profile_status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_sniffer.fortios_firewall(input_data, fos_instance)
expected_data = {'application-list': 'test_value_3',
'application-list-status': 'enable',
'av-profile': 'test_value_5',
'av-profile-status': 'enable',
'dlp-sensor': 'test_value_7',
'dlp-sensor-status': 'enable',
'dsri': 'enable',
'host': 'myhostname10',
'id': '11',
'interface': 'test_value_12',
'ips-dos-status': 'enable',
'ips-sensor': 'test_value_14',
'ips-sensor-status': 'enable',
'ipv6': 'enable',
'logtraffic': 'all',
'max-packet-count': '18',
'non-ip': 'enable',
'port': 'test_value_20',
'protocol': 'test_value_21',
'scan-botnet-connections': 'disable',
'spamfilter-profile': 'test_value_23',
'spamfilter-profile-status': 'enable',
'status': 'enable',
'vlan': 'test_value_26',
'webfilter-profile': 'test_value_27',
'webfilter-profile-status': 'enable'
}
set_method_mock.assert_called_with('firewall', 'sniffer', 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_sniffer_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_sniffer': {'application_list': 'test_value_3',
'application_list_status': 'enable',
'av_profile': 'test_value_5',
'av_profile_status': 'enable',
'dlp_sensor': 'test_value_7',
'dlp_sensor_status': 'enable',
'dsri': 'enable',
'host': 'myhostname10',
'id': '11',
'interface': 'test_value_12',
'ips_dos_status': 'enable',
'ips_sensor': 'test_value_14',
'ips_sensor_status': 'enable',
'ipv6': 'enable',
'logtraffic': 'all',
'max_packet_count': '18',
'non_ip': 'enable',
'port': 'test_value_20',
'protocol': 'test_value_21',
'scan_botnet_connections': 'disable',
'spamfilter_profile': 'test_value_23',
'spamfilter_profile_status': 'enable',
'status': 'enable',
'vlan': 'test_value_26',
'webfilter_profile': 'test_value_27',
'webfilter_profile_status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_sniffer.fortios_firewall(input_data, fos_instance)
expected_data = {'application-list': 'test_value_3',
'application-list-status': 'enable',
'av-profile': 'test_value_5',
'av-profile-status': 'enable',
'dlp-sensor': 'test_value_7',
'dlp-sensor-status': 'enable',
'dsri': 'enable',
'host': 'myhostname10',
'id': '11',
'interface': 'test_value_12',
'ips-dos-status': 'enable',
'ips-sensor': 'test_value_14',
'ips-sensor-status': 'enable',
'ipv6': 'enable',
'logtraffic': 'all',
'max-packet-count': '18',
'non-ip': 'enable',
'port': 'test_value_20',
'protocol': 'test_value_21',
'scan-botnet-connections': 'disable',
'spamfilter-profile': 'test_value_23',
'spamfilter-profile-status': 'enable',
'status': 'enable',
'vlan': 'test_value_26',
'webfilter-profile': 'test_value_27',
'webfilter-profile-status': 'enable'
}
set_method_mock.assert_called_with('firewall', 'sniffer', 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_sniffer_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_sniffer': {'application_list': 'test_value_3',
'application_list_status': 'enable',
'av_profile': 'test_value_5',
'av_profile_status': 'enable',
'dlp_sensor': 'test_value_7',
'dlp_sensor_status': 'enable',
'dsri': 'enable',
'host': 'myhostname10',
'id': '11',
'interface': 'test_value_12',
'ips_dos_status': 'enable',
'ips_sensor': 'test_value_14',
'ips_sensor_status': 'enable',
'ipv6': 'enable',
'logtraffic': 'all',
'max_packet_count': '18',
'non_ip': 'enable',
'port': 'test_value_20',
'protocol': 'test_value_21',
'scan_botnet_connections': 'disable',
'spamfilter_profile': 'test_value_23',
'spamfilter_profile_status': 'enable',
'status': 'enable',
'vlan': 'test_value_26',
'webfilter_profile': 'test_value_27',
'webfilter_profile_status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_sniffer.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'sniffer', 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_sniffer_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_sniffer': {'application_list': 'test_value_3',
'application_list_status': 'enable',
'av_profile': 'test_value_5',
'av_profile_status': 'enable',
'dlp_sensor': 'test_value_7',
'dlp_sensor_status': 'enable',
'dsri': 'enable',
'host': 'myhostname10',
'id': '11',
'interface': 'test_value_12',
'ips_dos_status': 'enable',
'ips_sensor': 'test_value_14',
'ips_sensor_status': 'enable',
'ipv6': 'enable',
'logtraffic': 'all',
'max_packet_count': '18',
'non_ip': 'enable',
'port': 'test_value_20',
'protocol': 'test_value_21',
'scan_botnet_connections': 'disable',
'spamfilter_profile': 'test_value_23',
'spamfilter_profile_status': 'enable',
'status': 'enable',
'vlan': 'test_value_26',
'webfilter_profile': 'test_value_27',
'webfilter_profile_status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_sniffer.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'sniffer', 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_sniffer_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_sniffer': {'application_list': 'test_value_3',
'application_list_status': 'enable',
'av_profile': 'test_value_5',
'av_profile_status': 'enable',
'dlp_sensor': 'test_value_7',
'dlp_sensor_status': 'enable',
'dsri': 'enable',
'host': 'myhostname10',
'id': '11',
'interface': 'test_value_12',
'ips_dos_status': 'enable',
'ips_sensor': 'test_value_14',
'ips_sensor_status': 'enable',
'ipv6': 'enable',
'logtraffic': 'all',
'max_packet_count': '18',
'non_ip': 'enable',
'port': 'test_value_20',
'protocol': 'test_value_21',
'scan_botnet_connections': 'disable',
'spamfilter_profile': 'test_value_23',
'spamfilter_profile_status': 'enable',
'status': 'enable',
'vlan': 'test_value_26',
'webfilter_profile': 'test_value_27',
'webfilter_profile_status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_sniffer.fortios_firewall(input_data, fos_instance)
expected_data = {'application-list': 'test_value_3',
'application-list-status': 'enable',
'av-profile': 'test_value_5',
'av-profile-status': 'enable',
'dlp-sensor': 'test_value_7',
'dlp-sensor-status': 'enable',
'dsri': 'enable',
'host': 'myhostname10',
'id': '11',
'interface': 'test_value_12',
'ips-dos-status': 'enable',
'ips-sensor': 'test_value_14',
'ips-sensor-status': 'enable',
'ipv6': 'enable',
'logtraffic': 'all',
'max-packet-count': '18',
'non-ip': 'enable',
'port': 'test_value_20',
'protocol': 'test_value_21',
'scan-botnet-connections': 'disable',
'spamfilter-profile': 'test_value_23',
'spamfilter-profile-status': 'enable',
'status': 'enable',
'vlan': 'test_value_26',
'webfilter-profile': 'test_value_27',
'webfilter-profile-status': 'enable'
}
set_method_mock.assert_called_with('firewall', 'sniffer', 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_sniffer_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_sniffer': {
'random_attribute_not_valid': 'tag', 'application_list': 'test_value_3',
'application_list_status': 'enable',
'av_profile': 'test_value_5',
'av_profile_status': 'enable',
'dlp_sensor': 'test_value_7',
'dlp_sensor_status': 'enable',
'dsri': 'enable',
'host': 'myhostname10',
'id': '11',
'interface': 'test_value_12',
'ips_dos_status': 'enable',
'ips_sensor': 'test_value_14',
'ips_sensor_status': 'enable',
'ipv6': 'enable',
'logtraffic': 'all',
'max_packet_count': '18',
'non_ip': 'enable',
'port': 'test_value_20',
'protocol': 'test_value_21',
'scan_botnet_connections': 'disable',
'spamfilter_profile': 'test_value_23',
'spamfilter_profile_status': 'enable',
'status': 'enable',
'vlan': 'test_value_26',
'webfilter_profile': 'test_value_27',
'webfilter_profile_status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_sniffer.fortios_firewall(input_data, fos_instance)
expected_data = {'application-list': 'test_value_3',
'application-list-status': 'enable',
'av-profile': 'test_value_5',
'av-profile-status': 'enable',
'dlp-sensor': 'test_value_7',
'dlp-sensor-status': 'enable',
'dsri': 'enable',
'host': 'myhostname10',
'id': '11',
'interface': 'test_value_12',
'ips-dos-status': 'enable',
'ips-sensor': 'test_value_14',
'ips-sensor-status': 'enable',
'ipv6': 'enable',
'logtraffic': 'all',
'max-packet-count': '18',
'non-ip': 'enable',
'port': 'test_value_20',
'protocol': 'test_value_21',
'scan-botnet-connections': 'disable',
'spamfilter-profile': 'test_value_23',
'spamfilter-profile-status': 'enable',
'status': 'enable',
'vlan': 'test_value_26',
'webfilter-profile': 'test_value_27',
'webfilter-profile-status': 'enable'
}
set_method_mock.assert_called_with('firewall', 'sniffer', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,269 @@
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_firewall_ssh_host_key
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_ssh_host_key.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_ssh_host_key_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_ssh_host_key': {
'hostname': 'myhostname3',
'ip': 'test_value_4',
'name': 'default_name_5',
'nid': '256',
'port': '7',
'public_key': 'test_value_8',
'status': 'trusted',
'type': 'RSA'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssh_host_key.fortios_firewall_ssh(input_data, fos_instance)
expected_data = {
'hostname': 'myhostname3',
'ip': 'test_value_4',
'name': 'default_name_5',
'nid': '256',
'port': '7',
'public-key': 'test_value_8',
'status': 'trusted',
'type': 'RSA'
}
set_method_mock.assert_called_with('firewall.ssh', 'host-key', 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_ssh_host_key_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_ssh_host_key': {
'hostname': 'myhostname3',
'ip': 'test_value_4',
'name': 'default_name_5',
'nid': '256',
'port': '7',
'public_key': 'test_value_8',
'status': 'trusted',
'type': 'RSA'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssh_host_key.fortios_firewall_ssh(input_data, fos_instance)
expected_data = {
'hostname': 'myhostname3',
'ip': 'test_value_4',
'name': 'default_name_5',
'nid': '256',
'port': '7',
'public-key': 'test_value_8',
'status': 'trusted',
'type': 'RSA'
}
set_method_mock.assert_called_with('firewall.ssh', 'host-key', 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_ssh_host_key_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_ssh_host_key': {
'hostname': 'myhostname3',
'ip': 'test_value_4',
'name': 'default_name_5',
'nid': '256',
'port': '7',
'public_key': 'test_value_8',
'status': 'trusted',
'type': 'RSA'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssh_host_key.fortios_firewall_ssh(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall.ssh', 'host-key', 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_ssh_host_key_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_ssh_host_key': {
'hostname': 'myhostname3',
'ip': 'test_value_4',
'name': 'default_name_5',
'nid': '256',
'port': '7',
'public_key': 'test_value_8',
'status': 'trusted',
'type': 'RSA'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssh_host_key.fortios_firewall_ssh(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall.ssh', 'host-key', 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_ssh_host_key_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_ssh_host_key': {
'hostname': 'myhostname3',
'ip': 'test_value_4',
'name': 'default_name_5',
'nid': '256',
'port': '7',
'public_key': 'test_value_8',
'status': 'trusted',
'type': 'RSA'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssh_host_key.fortios_firewall_ssh(input_data, fos_instance)
expected_data = {
'hostname': 'myhostname3',
'ip': 'test_value_4',
'name': 'default_name_5',
'nid': '256',
'port': '7',
'public-key': 'test_value_8',
'status': 'trusted',
'type': 'RSA'
}
set_method_mock.assert_called_with('firewall.ssh', 'host-key', 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_ssh_host_key_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_ssh_host_key': {
'random_attribute_not_valid': 'tag',
'hostname': 'myhostname3',
'ip': 'test_value_4',
'name': 'default_name_5',
'nid': '256',
'port': '7',
'public_key': 'test_value_8',
'status': 'trusted',
'type': 'RSA'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssh_host_key.fortios_firewall_ssh(input_data, fos_instance)
expected_data = {
'hostname': 'myhostname3',
'ip': 'test_value_4',
'name': 'default_name_5',
'nid': '256',
'port': '7',
'public-key': 'test_value_8',
'status': 'trusted',
'type': 'RSA'
}
set_method_mock.assert_called_with('firewall.ssh', 'host-key', 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_ssh_local_ca
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_ssh_local_ca.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_ssh_local_ca_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_ssh_local_ca': {
'name': 'default_name_3',
'password': 'test_value_4',
'private_key': 'test_value_5',
'public_key': 'test_value_6',
'source': 'built-in'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssh_local_ca.fortios_firewall_ssh(input_data, fos_instance)
expected_data = {
'name': 'default_name_3',
'password': 'test_value_4',
'private-key': 'test_value_5',
'public-key': 'test_value_6',
'source': 'built-in'
}
set_method_mock.assert_called_with('firewall.ssh', 'local-ca', 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_ssh_local_ca_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_ssh_local_ca': {
'name': 'default_name_3',
'password': 'test_value_4',
'private_key': 'test_value_5',
'public_key': 'test_value_6',
'source': 'built-in'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssh_local_ca.fortios_firewall_ssh(input_data, fos_instance)
expected_data = {
'name': 'default_name_3',
'password': 'test_value_4',
'private-key': 'test_value_5',
'public-key': 'test_value_6',
'source': 'built-in'
}
set_method_mock.assert_called_with('firewall.ssh', 'local-ca', 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_ssh_local_ca_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_ssh_local_ca': {
'name': 'default_name_3',
'password': 'test_value_4',
'private_key': 'test_value_5',
'public_key': 'test_value_6',
'source': 'built-in'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssh_local_ca.fortios_firewall_ssh(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall.ssh', 'local-ca', 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_ssh_local_ca_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_ssh_local_ca': {
'name': 'default_name_3',
'password': 'test_value_4',
'private_key': 'test_value_5',
'public_key': 'test_value_6',
'source': 'built-in'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssh_local_ca.fortios_firewall_ssh(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall.ssh', 'local-ca', 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_ssh_local_ca_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_ssh_local_ca': {
'name': 'default_name_3',
'password': 'test_value_4',
'private_key': 'test_value_5',
'public_key': 'test_value_6',
'source': 'built-in'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssh_local_ca.fortios_firewall_ssh(input_data, fos_instance)
expected_data = {
'name': 'default_name_3',
'password': 'test_value_4',
'private-key': 'test_value_5',
'public-key': 'test_value_6',
'source': 'built-in'
}
set_method_mock.assert_called_with('firewall.ssh', 'local-ca', 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_ssh_local_ca_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_ssh_local_ca': {
'random_attribute_not_valid': 'tag',
'name': 'default_name_3',
'password': 'test_value_4',
'private_key': 'test_value_5',
'public_key': 'test_value_6',
'source': 'built-in'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssh_local_ca.fortios_firewall_ssh(input_data, fos_instance)
expected_data = {
'name': 'default_name_3',
'password': 'test_value_4',
'private-key': 'test_value_5',
'public-key': 'test_value_6',
'source': 'built-in'
}
set_method_mock.assert_called_with('firewall.ssh', 'local-ca', 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_ssh_local_key
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_ssh_local_key.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_ssh_local_key_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_ssh_local_key': {
'name': 'default_name_3',
'password': 'test_value_4',
'private_key': 'test_value_5',
'public_key': 'test_value_6',
'source': 'built-in'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssh_local_key.fortios_firewall_ssh(input_data, fos_instance)
expected_data = {
'name': 'default_name_3',
'password': 'test_value_4',
'private-key': 'test_value_5',
'public-key': 'test_value_6',
'source': 'built-in'
}
set_method_mock.assert_called_with('firewall.ssh', 'local-key', 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_ssh_local_key_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_ssh_local_key': {
'name': 'default_name_3',
'password': 'test_value_4',
'private_key': 'test_value_5',
'public_key': 'test_value_6',
'source': 'built-in'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssh_local_key.fortios_firewall_ssh(input_data, fos_instance)
expected_data = {
'name': 'default_name_3',
'password': 'test_value_4',
'private-key': 'test_value_5',
'public-key': 'test_value_6',
'source': 'built-in'
}
set_method_mock.assert_called_with('firewall.ssh', 'local-key', 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_ssh_local_key_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_ssh_local_key': {
'name': 'default_name_3',
'password': 'test_value_4',
'private_key': 'test_value_5',
'public_key': 'test_value_6',
'source': 'built-in'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssh_local_key.fortios_firewall_ssh(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall.ssh', 'local-key', 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_ssh_local_key_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_ssh_local_key': {
'name': 'default_name_3',
'password': 'test_value_4',
'private_key': 'test_value_5',
'public_key': 'test_value_6',
'source': 'built-in'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssh_local_key.fortios_firewall_ssh(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall.ssh', 'local-key', 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_ssh_local_key_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_ssh_local_key': {
'name': 'default_name_3',
'password': 'test_value_4',
'private_key': 'test_value_5',
'public_key': 'test_value_6',
'source': 'built-in'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssh_local_key.fortios_firewall_ssh(input_data, fos_instance)
expected_data = {
'name': 'default_name_3',
'password': 'test_value_4',
'private-key': 'test_value_5',
'public-key': 'test_value_6',
'source': 'built-in'
}
set_method_mock.assert_called_with('firewall.ssh', 'local-key', 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_ssh_local_key_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_ssh_local_key': {
'random_attribute_not_valid': 'tag',
'name': 'default_name_3',
'password': 'test_value_4',
'private_key': 'test_value_5',
'public_key': 'test_value_6',
'source': 'built-in'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssh_local_key.fortios_firewall_ssh(input_data, fos_instance)
expected_data = {
'name': 'default_name_3',
'password': 'test_value_4',
'private-key': 'test_value_5',
'public-key': 'test_value_6',
'source': 'built-in'
}
set_method_mock.assert_called_with('firewall.ssh', 'local-key', 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,215 @@
# 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_ssh_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_ssh_setting.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_ssh_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_ssh_setting': {
'caname': 'test_value_3',
'host_trusted_checking': 'enable',
'hostkey_dsa1024': 'myhostname5',
'hostkey_ecdsa256': 'myhostname6',
'hostkey_ecdsa384': 'myhostname7',
'hostkey_ecdsa521': 'myhostname8',
'hostkey_ed25519': 'myhostname9',
'hostkey_rsa2048': 'myhostname10',
'untrusted_caname': 'test_value_11'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssh_setting.fortios_firewall_ssh(input_data, fos_instance)
expected_data = {
'caname': 'test_value_3',
'host-trusted-checking': 'enable',
'hostkey-dsa1024': 'myhostname5',
'hostkey-ecdsa256': 'myhostname6',
'hostkey-ecdsa384': 'myhostname7',
'hostkey-ecdsa521': 'myhostname8',
'hostkey-ed25519': 'myhostname9',
'hostkey-rsa2048': 'myhostname10',
'untrusted-caname': 'test_value_11'
}
set_method_mock.assert_called_with('firewall.ssh', '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_ssh_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_ssh_setting': {
'caname': 'test_value_3',
'host_trusted_checking': 'enable',
'hostkey_dsa1024': 'myhostname5',
'hostkey_ecdsa256': 'myhostname6',
'hostkey_ecdsa384': 'myhostname7',
'hostkey_ecdsa521': 'myhostname8',
'hostkey_ed25519': 'myhostname9',
'hostkey_rsa2048': 'myhostname10',
'untrusted_caname': 'test_value_11'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssh_setting.fortios_firewall_ssh(input_data, fos_instance)
expected_data = {
'caname': 'test_value_3',
'host-trusted-checking': 'enable',
'hostkey-dsa1024': 'myhostname5',
'hostkey-ecdsa256': 'myhostname6',
'hostkey-ecdsa384': 'myhostname7',
'hostkey-ecdsa521': 'myhostname8',
'hostkey-ed25519': 'myhostname9',
'hostkey-rsa2048': 'myhostname10',
'untrusted-caname': 'test_value_11'
}
set_method_mock.assert_called_with('firewall.ssh', '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_ssh_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_ssh_setting': {
'caname': 'test_value_3',
'host_trusted_checking': 'enable',
'hostkey_dsa1024': 'myhostname5',
'hostkey_ecdsa256': 'myhostname6',
'hostkey_ecdsa384': 'myhostname7',
'hostkey_ecdsa521': 'myhostname8',
'hostkey_ed25519': 'myhostname9',
'hostkey_rsa2048': 'myhostname10',
'untrusted_caname': 'test_value_11'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssh_setting.fortios_firewall_ssh(input_data, fos_instance)
expected_data = {
'caname': 'test_value_3',
'host-trusted-checking': 'enable',
'hostkey-dsa1024': 'myhostname5',
'hostkey-ecdsa256': 'myhostname6',
'hostkey-ecdsa384': 'myhostname7',
'hostkey-ecdsa521': 'myhostname8',
'hostkey-ed25519': 'myhostname9',
'hostkey-rsa2048': 'myhostname10',
'untrusted-caname': 'test_value_11'
}
set_method_mock.assert_called_with('firewall.ssh', '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_ssh_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_ssh_setting': {
'random_attribute_not_valid': 'tag',
'caname': 'test_value_3',
'host_trusted_checking': 'enable',
'hostkey_dsa1024': 'myhostname5',
'hostkey_ecdsa256': 'myhostname6',
'hostkey_ecdsa384': 'myhostname7',
'hostkey_ecdsa521': 'myhostname8',
'hostkey_ed25519': 'myhostname9',
'hostkey_rsa2048': 'myhostname10',
'untrusted_caname': 'test_value_11'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssh_setting.fortios_firewall_ssh(input_data, fos_instance)
expected_data = {
'caname': 'test_value_3',
'host-trusted-checking': 'enable',
'hostkey-dsa1024': 'myhostname5',
'hostkey-ecdsa256': 'myhostname6',
'hostkey-ecdsa384': 'myhostname7',
'hostkey-ecdsa521': 'myhostname8',
'hostkey-ed25519': 'myhostname9',
'hostkey-rsa2048': 'myhostname10',
'untrusted-caname': 'test_value_11'
}
set_method_mock.assert_called_with('firewall.ssh', '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,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_ssl_server
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_firewall_ssl_server.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_ssl_server_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'firewall_ssl_server': {
'add_header_x_forwarded_proto': 'enable',
'ip': 'test_value_4',
'mapped_port': '5',
'name': 'default_name_6',
'port': '7',
'ssl_algorithm': 'high',
'ssl_cert': 'test_value_9',
'ssl_client_renegotiation': 'allow',
'ssl_dh_bits': '768',
'ssl_max_version': 'tls-1.0',
'ssl_min_version': 'tls-1.0',
'ssl_mode': 'half',
'ssl_send_empty_frags': 'enable',
'url_rewrite': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssl_server.fortios_firewall(input_data, fos_instance)
expected_data = {
'add-header-x-forwarded-proto': 'enable',
'ip': 'test_value_4',
'mapped-port': '5',
'name': 'default_name_6',
'port': '7',
'ssl-algorithm': 'high',
'ssl-cert': 'test_value_9',
'ssl-client-renegotiation': 'allow',
'ssl-dh-bits': '768',
'ssl-max-version': 'tls-1.0',
'ssl-min-version': 'tls-1.0',
'ssl-mode': 'half',
'ssl-send-empty-frags': 'enable',
'url-rewrite': 'enable'
}
set_method_mock.assert_called_with('firewall', 'ssl-server', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_firewall_ssl_server_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'firewall_ssl_server': {
'add_header_x_forwarded_proto': 'enable',
'ip': 'test_value_4',
'mapped_port': '5',
'name': 'default_name_6',
'port': '7',
'ssl_algorithm': 'high',
'ssl_cert': 'test_value_9',
'ssl_client_renegotiation': 'allow',
'ssl_dh_bits': '768',
'ssl_max_version': 'tls-1.0',
'ssl_min_version': 'tls-1.0',
'ssl_mode': 'half',
'ssl_send_empty_frags': 'enable',
'url_rewrite': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssl_server.fortios_firewall(input_data, fos_instance)
expected_data = {
'add-header-x-forwarded-proto': 'enable',
'ip': 'test_value_4',
'mapped-port': '5',
'name': 'default_name_6',
'port': '7',
'ssl-algorithm': 'high',
'ssl-cert': 'test_value_9',
'ssl-client-renegotiation': 'allow',
'ssl-dh-bits': '768',
'ssl-max-version': 'tls-1.0',
'ssl-min-version': 'tls-1.0',
'ssl-mode': 'half',
'ssl-send-empty-frags': 'enable',
'url-rewrite': 'enable'
}
set_method_mock.assert_called_with('firewall', 'ssl-server', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_firewall_ssl_server_removal(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'firewall_ssl_server': {
'add_header_x_forwarded_proto': 'enable',
'ip': 'test_value_4',
'mapped_port': '5',
'name': 'default_name_6',
'port': '7',
'ssl_algorithm': 'high',
'ssl_cert': 'test_value_9',
'ssl_client_renegotiation': 'allow',
'ssl_dh_bits': '768',
'ssl_max_version': 'tls-1.0',
'ssl_min_version': 'tls-1.0',
'ssl_mode': 'half',
'ssl_send_empty_frags': 'enable',
'url_rewrite': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssl_server.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'ssl-server', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_firewall_ssl_server_deletion_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'firewall_ssl_server': {
'add_header_x_forwarded_proto': 'enable',
'ip': 'test_value_4',
'mapped_port': '5',
'name': 'default_name_6',
'port': '7',
'ssl_algorithm': 'high',
'ssl_cert': 'test_value_9',
'ssl_client_renegotiation': 'allow',
'ssl_dh_bits': '768',
'ssl_max_version': 'tls-1.0',
'ssl_min_version': 'tls-1.0',
'ssl_mode': 'half',
'ssl_send_empty_frags': 'enable',
'url_rewrite': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssl_server.fortios_firewall(input_data, fos_instance)
delete_method_mock.assert_called_with('firewall', 'ssl-server', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_firewall_ssl_server_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'firewall_ssl_server': {
'add_header_x_forwarded_proto': 'enable',
'ip': 'test_value_4',
'mapped_port': '5',
'name': 'default_name_6',
'port': '7',
'ssl_algorithm': 'high',
'ssl_cert': 'test_value_9',
'ssl_client_renegotiation': 'allow',
'ssl_dh_bits': '768',
'ssl_max_version': 'tls-1.0',
'ssl_min_version': 'tls-1.0',
'ssl_mode': 'half',
'ssl_send_empty_frags': 'enable',
'url_rewrite': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssl_server.fortios_firewall(input_data, fos_instance)
expected_data = {
'add-header-x-forwarded-proto': 'enable',
'ip': 'test_value_4',
'mapped-port': '5',
'name': 'default_name_6',
'port': '7',
'ssl-algorithm': 'high',
'ssl-cert': 'test_value_9',
'ssl-client-renegotiation': 'allow',
'ssl-dh-bits': '768',
'ssl-max-version': 'tls-1.0',
'ssl-min-version': 'tls-1.0',
'ssl-mode': 'half',
'ssl-send-empty-frags': 'enable',
'url-rewrite': 'enable'
}
set_method_mock.assert_called_with('firewall', 'ssl-server', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_firewall_ssl_server_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'firewall_ssl_server': {
'random_attribute_not_valid': 'tag',
'add_header_x_forwarded_proto': 'enable',
'ip': 'test_value_4',
'mapped_port': '5',
'name': 'default_name_6',
'port': '7',
'ssl_algorithm': 'high',
'ssl_cert': 'test_value_9',
'ssl_client_renegotiation': 'allow',
'ssl_dh_bits': '768',
'ssl_max_version': 'tls-1.0',
'ssl_min_version': 'tls-1.0',
'ssl_mode': 'half',
'ssl_send_empty_frags': 'enable',
'url_rewrite': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssl_server.fortios_firewall(input_data, fos_instance)
expected_data = {
'add-header-x-forwarded-proto': 'enable',
'ip': 'test_value_4',
'mapped-port': '5',
'name': 'default_name_6',
'port': '7',
'ssl-algorithm': 'high',
'ssl-cert': 'test_value_9',
'ssl-client-renegotiation': 'allow',
'ssl-dh-bits': '768',
'ssl-max-version': 'tls-1.0',
'ssl-min-version': 'tls-1.0',
'ssl-mode': 'half',
'ssl-send-empty-frags': 'enable',
'url-rewrite': 'enable'
}
set_method_mock.assert_called_with('firewall', 'ssl-server', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,231 @@
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_firewall_ssl_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_ssl_setting.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_firewall_ssl_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_ssl_setting': {
'abbreviate_handshake': 'enable',
'cert_cache_capacity': '4',
'cert_cache_timeout': '5',
'kxp_queue_threshold': '6',
'no_matching_cipher_action': 'bypass',
'proxy_connect_timeout': '8',
'session_cache_capacity': '9',
'session_cache_timeout': '10',
'ssl_dh_bits': '768',
'ssl_queue_threshold': '12',
'ssl_send_empty_frags': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssl_setting.fortios_firewall_ssl(input_data, fos_instance)
expected_data = {
'abbreviate-handshake': 'enable',
'cert-cache-capacity': '4',
'cert-cache-timeout': '5',
'kxp-queue-threshold': '6',
'no-matching-cipher-action': 'bypass',
'proxy-connect-timeout': '8',
'session-cache-capacity': '9',
'session-cache-timeout': '10',
'ssl-dh-bits': '768',
'ssl-queue-threshold': '12',
'ssl-send-empty-frags': 'enable'
}
set_method_mock.assert_called_with('firewall.ssl', '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_ssl_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_ssl_setting': {
'abbreviate_handshake': 'enable',
'cert_cache_capacity': '4',
'cert_cache_timeout': '5',
'kxp_queue_threshold': '6',
'no_matching_cipher_action': 'bypass',
'proxy_connect_timeout': '8',
'session_cache_capacity': '9',
'session_cache_timeout': '10',
'ssl_dh_bits': '768',
'ssl_queue_threshold': '12',
'ssl_send_empty_frags': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssl_setting.fortios_firewall_ssl(input_data, fos_instance)
expected_data = {
'abbreviate-handshake': 'enable',
'cert-cache-capacity': '4',
'cert-cache-timeout': '5',
'kxp-queue-threshold': '6',
'no-matching-cipher-action': 'bypass',
'proxy-connect-timeout': '8',
'session-cache-capacity': '9',
'session-cache-timeout': '10',
'ssl-dh-bits': '768',
'ssl-queue-threshold': '12',
'ssl-send-empty-frags': 'enable'
}
set_method_mock.assert_called_with('firewall.ssl', '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_ssl_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_ssl_setting': {
'abbreviate_handshake': 'enable',
'cert_cache_capacity': '4',
'cert_cache_timeout': '5',
'kxp_queue_threshold': '6',
'no_matching_cipher_action': 'bypass',
'proxy_connect_timeout': '8',
'session_cache_capacity': '9',
'session_cache_timeout': '10',
'ssl_dh_bits': '768',
'ssl_queue_threshold': '12',
'ssl_send_empty_frags': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssl_setting.fortios_firewall_ssl(input_data, fos_instance)
expected_data = {
'abbreviate-handshake': 'enable',
'cert-cache-capacity': '4',
'cert-cache-timeout': '5',
'kxp-queue-threshold': '6',
'no-matching-cipher-action': 'bypass',
'proxy-connect-timeout': '8',
'session-cache-capacity': '9',
'session-cache-timeout': '10',
'ssl-dh-bits': '768',
'ssl-queue-threshold': '12',
'ssl-send-empty-frags': 'enable'
}
set_method_mock.assert_called_with('firewall.ssl', '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_ssl_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_ssl_setting': {
'random_attribute_not_valid': 'tag',
'abbreviate_handshake': 'enable',
'cert_cache_capacity': '4',
'cert_cache_timeout': '5',
'kxp_queue_threshold': '6',
'no_matching_cipher_action': 'bypass',
'proxy_connect_timeout': '8',
'session_cache_capacity': '9',
'session_cache_timeout': '10',
'ssl_dh_bits': '768',
'ssl_queue_threshold': '12',
'ssl_send_empty_frags': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_firewall_ssl_setting.fortios_firewall_ssl(input_data, fos_instance)
expected_data = {
'abbreviate-handshake': 'enable',
'cert-cache-capacity': '4',
'cert-cache-timeout': '5',
'kxp-queue-threshold': '6',
'no-matching-cipher-action': 'bypass',
'proxy-connect-timeout': '8',
'session-cache-capacity': '9',
'session-cache-timeout': '10',
'ssl-dh-bits': '768',
'ssl-queue-threshold': '12',
'ssl-send-empty-frags': 'enable'
}
set_method_mock.assert_called_with('firewall.ssl', '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
Loading…
Cancel
Save