diff --git a/lib/ansible/modules/network/fortios/fortios_firewall_proxy_address.py b/lib/ansible/modules/network/fortios/fortios_firewall_proxy_address.py
index 441bab74e7c..fe62a698a06 100644
--- a/lib/ansible/modules/network/fortios/fortios_firewall_proxy_address.py
+++ b/lib/ansible/modules/network/fortios/fortios_firewall_proxy_address.py
@@ -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 .
-#
-# 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: ""
- header-group:
+ header_group:
-
- case-sensitivity: "disable"
+ case_sensitivity: "disable"
header: ""
- header-name: ""
+ header_name: ""
id: "13"
- header-name: ""
+ header_name: ""
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: ""
@@ -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)
diff --git a/lib/ansible/modules/network/fortios/fortios_firewall_proxy_addrgrp.py b/lib/ansible/modules/network/fortios/fortios_firewall_proxy_addrgrp.py
index 1184ddbc430..1a6c541c58e 100644
--- a/lib/ansible/modules/network/fortios/fortios_firewall_proxy_addrgrp.py
+++ b/lib/ansible/modules/network/fortios/fortios_firewall_proxy_addrgrp.py
@@ -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 .
-#
-# 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)
diff --git a/lib/ansible/modules/network/fortios/fortios_firewall_proxy_policy.py b/lib/ansible/modules/network/fortios/fortios_firewall_proxy_policy.py
index 2a820709c65..50190585673 100644
--- a/lib/ansible/modules/network/fortios/fortios_firewall_proxy_policy.py
+++ b/lib/ansible/modules/network/fortios/fortios_firewall_proxy_policy.py
@@ -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 .
-#
-# 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: " (source application.list.name)"
- av-profile: " (source antivirus.profile.name)"
+ application_list: " (source application.list.name)"
+ av_profile: " (source antivirus.profile.name)"
comments: ""
disclaimer: "disable"
- dlp-sensor: " (source dlp.sensor.name)"
+ dlp_sensor: " (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: ""
+ global_label: ""
groups:
-
name: "default_name_18 (source user.group.name)"
- http-tunnel-auth: "enable"
- icap-profile: " (source icap.profile.name)"
- internet-service: "enable"
- internet-service-custom:
+ http_tunnel_auth: "enable"
+ icap_profile: " (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: " (source ips.sensor.name)"
+ internet_service_negate: "enable"
+ ips_sensor: " (source ips.sensor.name)"
label: ""
logtraffic: "all"
- logtraffic-start: "enable"
+ logtraffic_start: "enable"
policyid: "31"
poolname:
-
name: "default_name_33 (source firewall.ippool.name)"
- profile-group: " (source firewall.profile-group.name)"
- profile-protocol-options: " (source firewall.profile-protocol-options.name)"
- profile-type: "single"
+ profile_group: " (source firewall.profile-group.name)"
+ profile_protocol_options: " (source firewall.profile-protocol-options.name)"
+ profile_type: "single"
proxy: "explicit-web"
- redirect-url: ""
- replacemsg-override-group: " (source system.replacemsg-group.name)"
- scan-botnet-connections: "disable"
+ redirect_url: ""
+ replacemsg_override_group: " (source system.replacemsg-group.name)"
+ scan_botnet_connections: "disable"
schedule: " (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: " (source spamfilter.profile.name)"
+ service_negate: "enable"
+ session_ttl: "45"
+ spamfilter_profile: " (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: " (source ssh-filter.profile.name)"
- ssl-ssh-profile: " (source firewall.ssl-ssh-profile.name)"
+ ssh_filter_profile: " (source ssh-filter.profile.name)"
+ ssl_ssh_profile: " (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: ""
- waf-profile: " (source waf.profile.name)"
+ waf_profile: " (source waf.profile.name)"
webcache: "enable"
- webcache-https: "disable"
- webfilter-profile: " (source webfilter.profile.name)"
- webproxy-forward-server: " (source web-proxy.forward-server.name web-proxy.forward-server-group.name)"
- webproxy-profile: " (source web-proxy.profile.name)"
+ webcache_https: "disable"
+ webfilter_profile: " (source webfilter.profile.name)"
+ webproxy_forward_server: " (source web-proxy.forward-server.name web-proxy.forward-server-group.name)"
+ webproxy_profile: " (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)
diff --git a/lib/ansible/modules/network/fortios/fortios_firewall_schedule_group.py b/lib/ansible/modules/network/fortios/fortios_firewall_schedule_group.py
index 13968f340a3..6793203816c 100644
--- a/lib/ansible/modules/network/fortios/fortios_firewall_schedule_group.py
+++ b/lib/ansible/modules/network/fortios/fortios_firewall_schedule_group.py
@@ -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 .
-#
-# 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)
diff --git a/lib/ansible/modules/network/fortios/fortios_firewall_schedule_onetime.py b/lib/ansible/modules/network/fortios/fortios_firewall_schedule_onetime.py
index 545556b8146..1d0f0a18291 100644
--- a/lib/ansible/modules/network/fortios/fortios_firewall_schedule_onetime.py
+++ b/lib/ansible/modules/network/fortios/fortios_firewall_schedule_onetime.py
@@ -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 .
-#
-# 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: ""
- expiration-days: "5"
+ expiration_days: "5"
name: "default_name_6"
start: ""
'''
@@ -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)
diff --git a/lib/ansible/modules/network/fortios/fortios_firewall_schedule_recurring.py b/lib/ansible/modules/network/fortios/fortios_firewall_schedule_recurring.py
index 97d676aa181..bc350a1d357 100644
--- a/lib/ansible/modules/network/fortios/fortios_firewall_schedule_recurring.py
+++ b/lib/ansible/modules/network/fortios/fortios_firewall_schedule_recurring.py
@@ -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 .
-#
-# 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: ""
@@ -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)
diff --git a/lib/ansible/modules/network/fortios/fortios_firewall_service_category.py b/lib/ansible/modules/network/fortios/fortios_firewall_service_category.py
index c41e5538aa2..2e4d237fc77 100644
--- a/lib/ansible/modules/network/fortios/fortios_firewall_service_category.py
+++ b/lib/ansible/modules/network/fortios/fortios_firewall_service_category.py
@@ -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 .
-#
-# 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)
diff --git a/lib/ansible/modules/network/fortios/fortios_firewall_service_custom.py b/lib/ansible/modules/network/fortios/fortios_firewall_service_custom.py
index 3b906dc7834..719b4dd2af1 100644
--- a/lib/ansible/modules/network/fortios/fortios_firewall_service_custom.py
+++ b/lib/ansible/modules/network/fortios/fortios_firewall_service_custom.py
@@ -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 .
-#
-# 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: " (source firewall.service.category.name)"
- check-reset-range: "disable"
+ check_reset_range: "disable"
color: "10"
comment: "Comment."
fqdn: ""
@@ -247,16 +285,16 @@ EXAMPLES = '''
iprange: ""
name: "default_name_17"
protocol: "TCP/UDP/SCTP"
- protocol-number: "19"
+ protocol_number: "19"
proxy: "enable"
- sctp-portrange: ""
- session-ttl: "22"
- tcp-halfclose-timer: "23"
- tcp-halfopen-timer: "24"
- tcp-portrange: ""
- tcp-timewait-timer: "26"
- udp-idle-timer: "27"
- udp-portrange: ""
+ sctp_portrange: ""
+ session_ttl: "22"
+ tcp_halfclose_timer: "23"
+ tcp_halfopen_timer: "24"
+ tcp_portrange: ""
+ tcp_timewait_timer: "26"
+ udp_idle_timer: "27"
+ udp_portrange: ""
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)
diff --git a/lib/ansible/modules/network/fortios/fortios_firewall_service_group.py b/lib/ansible/modules/network/fortios/fortios_firewall_service_group.py
index 5ed8196e928..d724e640c4c 100644
--- a/lib/ansible/modules/network/fortios/fortios_firewall_service_group.py
+++ b/lib/ansible/modules/network/fortios/fortios_firewall_service_group.py
@@ -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 .
-#
-# 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)
diff --git a/lib/ansible/modules/network/fortios/fortios_firewall_shaper_per_ip_shaper.py b/lib/ansible/modules/network/fortios/fortios_firewall_shaper_per_ip_shaper.py
index a65fbad8448..737e7759913 100644
--- a/lib/ansible/modules/network/fortios/fortios_firewall_shaper_per_ip_shaper.py
+++ b/lib/ansible/modules/network/fortios/fortios_firewall_shaper_per_ip_shaper.py
@@ -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 .
-#
-# 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: ""
- diffservcode-rev: ""
- max-bandwidth: "8"
- max-concurrent-session: "9"
+ bandwidth_unit: "kbps"
+ diffserv_forward: "enable"
+ diffserv_reverse: "enable"
+ diffservcode_forward: ""
+ diffservcode_rev: ""
+ 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)
diff --git a/lib/ansible/modules/network/fortios/fortios_firewall_shaper_traffic_shaper.py b/lib/ansible/modules/network/fortios/fortios_firewall_shaper_traffic_shaper.py
index 6e1e111382e..e9f23e9d2c2 100644
--- a/lib/ansible/modules/network/fortios/fortios_firewall_shaper_traffic_shaper.py
+++ b/lib/ansible/modules/network/fortios/fortios_firewall_shaper_traffic_shaper.py
@@ -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 .
-#
-# 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: ""
- 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)
diff --git a/lib/ansible/modules/network/fortios/fortios_firewall_shaping_policy.py b/lib/ansible/modules/network/fortios/fortios_firewall_shaping_policy.py
index dd65e202aa7..54534e91e95 100644
--- a/lib/ansible/modules/network/fortios/fortios_firewall_shaping_policy.py
+++ b/lib/ansible/modules/network/fortios/fortios_firewall_shaping_policy.py
@@ -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 .
-#
-# 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: " (source firewall.shaper.per-ip-shaper.name)"
+ ip_version: "4"
+ per_ip_shaper: " (source firewall.shaper.per-ip-shaper.name)"
schedule: " (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: " (source firewall.shaper.traffic-shaper.name)"
- traffic-shaper-reverse: " (source firewall.shaper.traffic-shaper.name)"
- url-category:
+ traffic_shaper: " (source firewall.shaper.traffic-shaper.name)"
+ traffic_shaper_reverse: " (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)
diff --git a/lib/ansible/modules/network/fortios/fortios_firewall_shaping_profile.py b/lib/ansible/modules/network/fortios/fortios_firewall_shaping_profile.py
index 70a19e3802d..9ddc70e6353 100644
--- a/lib/ansible/modules/network/fortios/fortios_firewall_shaping_profile.py
+++ b/lib/ansible/modules/network/fortios/fortios_firewall_shaping_profile.py
@@ -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 .
-#
-# 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: ""
- shaping-entries:
+ default_class_id: "4"
+ profile_name: ""
+ 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)
diff --git a/lib/ansible/modules/network/fortios/fortios_firewall_sniffer.py b/lib/ansible/modules/network/fortios/fortios_firewall_sniffer.py
index a4253bec448..50f785c9bc5 100644
--- a/lib/ansible/modules/network/fortios/fortios_firewall_sniffer.py
+++ b/lib/ansible/modules/network/fortios/fortios_firewall_sniffer.py
@@ -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 .
-#
-# 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: ""
- quarantine-log: "disable"
+ quarantine_expiry: ""
+ quarantine_log: "disable"
status: "disable"
threshold: "11"
threshold(default): "12"
- application-list: " (source application.list.name)"
- application-list-status: "enable"
- av-profile: " (source antivirus.profile.name)"
- av-profile-status: "enable"
- dlp-sensor: " (source dlp.sensor.name)"
- dlp-sensor-status: "enable"
+ application_list: " (source application.list.name)"
+ application_list_status: "enable"
+ av_profile: " (source antivirus.profile.name)"
+ av_profile_status: "enable"
+ dlp_sensor: " (source dlp.sensor.name)"
+ dlp_sensor_status: "enable"
dsri: "enable"
host: "myhostname"
id: "21"
interface: " (source system.interface.name)"
- ips-dos-status: "enable"
- ips-sensor: " (source ips.sensor.name)"
- ips-sensor-status: "enable"
+ ips_dos_status: "enable"
+ ips_sensor: " (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: ""
protocol: ""
- scan-botnet-connections: "disable"
- spamfilter-profile: " (source spamfilter.profile.name)"
- spamfilter-profile-status: "enable"
+ scan_botnet_connections: "disable"
+ spamfilter_profile: " (source spamfilter.profile.name)"
+ spamfilter_profile_status: "enable"
status: "enable"
vlan: ""
- webfilter-profile: " (source webfilter.profile.name)"
- webfilter-profile-status: "enable"
+ webfilter_profile: " (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)
diff --git a/lib/ansible/modules/network/fortios/fortios_firewall_ssh_host_key.py b/lib/ansible/modules/network/fortios/fortios_firewall_ssh_host_key.py
index 71767fe257d..390897dc7b1 100644
--- a/lib/ansible/modules/network/fortios/fortios_firewall_ssh_host_key.py
+++ b/lib/ansible/modules/network/fortios/fortios_firewall_ssh_host_key.py
@@ -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 .
-#
-# 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: ""
name: "default_name_5"
nid: "256"
port: "7"
- public-key: ""
+ public_key: ""
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)
diff --git a/lib/ansible/modules/network/fortios/fortios_firewall_ssh_local_ca.py b/lib/ansible/modules/network/fortios/fortios_firewall_ssh_local_ca.py
index 4b3ce7332b0..6322f921b5f 100644
--- a/lib/ansible/modules/network/fortios/fortios_firewall_ssh_local_ca.py
+++ b/lib/ansible/modules/network/fortios/fortios_firewall_ssh_local_ca.py
@@ -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 .
-#
-# 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: ""
- private-key: ""
- public-key: ""
+ private_key: ""
+ public_key: ""
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)
diff --git a/lib/ansible/modules/network/fortios/fortios_firewall_ssh_local_key.py b/lib/ansible/modules/network/fortios/fortios_firewall_ssh_local_key.py
index 6f29cfe81f3..5405c7618c6 100644
--- a/lib/ansible/modules/network/fortios/fortios_firewall_ssh_local_key.py
+++ b/lib/ansible/modules/network/fortios/fortios_firewall_ssh_local_key.py
@@ -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 .
-#
-# 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: ""
- private-key: ""
- public-key: ""
+ private_key: ""
+ public_key: ""
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)
diff --git a/lib/ansible/modules/network/fortios/fortios_firewall_ssh_setting.py b/lib/ansible/modules/network/fortios/fortios_firewall_ssh_setting.py
index d6eb451f7e5..3a6f79f55bc 100644
--- a/lib/ansible/modules/network/fortios/fortios_firewall_ssh_setting.py
+++ b/lib/ansible/modules/network/fortios/fortios_firewall_ssh_setting.py
@@ -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 .
-#
-# 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: " (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: " (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: " (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)
diff --git a/lib/ansible/modules/network/fortios/fortios_firewall_ssl_server.py b/lib/ansible/modules/network/fortios/fortios_firewall_ssl_server.py
index ffd1de7ad84..4f24cab4dd3 100644
--- a/lib/ansible/modules/network/fortios/fortios_firewall_ssl_server.py
+++ b/lib/ansible/modules/network/fortios/fortios_firewall_ssl_server.py
@@ -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 .
-#
-# 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: ""
- mapped-port: "5"
+ mapped_port: "5"
name: "default_name_6"
port: "7"
- ssl-algorithm: "high"
- ssl-cert: " (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: " (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)
diff --git a/lib/ansible/modules/network/fortios/fortios_firewall_ssl_setting.py b/lib/ansible/modules/network/fortios/fortios_firewall_ssl_setting.py
index 4778f431f42..836c2c8087c 100644
--- a/lib/ansible/modules/network/fortios/fortios_firewall_ssl_setting.py
+++ b/lib/ansible/modules/network/fortios/fortios_firewall_ssl_setting.py
@@ -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 .
-#
-# 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)
diff --git a/test/sanity/ignore.txt b/test/sanity/ignore.txt
index 8a0b6db580b..8089d597d68 100644
--- a/test/sanity/ignore.txt
+++ b/test/sanity/ignore.txt
@@ -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
diff --git a/test/units/modules/network/fortios/test_fortios_firewall_proxy_address.py b/test/units/modules/network/fortios/test_fortios_firewall_proxy_address.py
new file mode 100644
index 00000000000..c0e77cbb8d6
--- /dev/null
+++ b/test/units/modules/network/fortios/test_fortios_firewall_proxy_address.py
@@ -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 .
+
+# 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
diff --git a/test/units/modules/network/fortios/test_fortios_firewall_proxy_addrgrp.py b/test/units/modules/network/fortios/test_fortios_firewall_proxy_addrgrp.py
new file mode 100644
index 00000000000..7bc4477485b
--- /dev/null
+++ b/test/units/modules/network/fortios/test_fortios_firewall_proxy_addrgrp.py
@@ -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 .
+
+# 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
diff --git a/test/units/modules/network/fortios/test_fortios_firewall_proxy_policy.py b/test/units/modules/network/fortios/test_fortios_firewall_proxy_policy.py
new file mode 100644
index 00000000000..72609465efc
--- /dev/null
+++ b/test/units/modules/network/fortios/test_fortios_firewall_proxy_policy.py
@@ -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 .
+
+# 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
diff --git a/test/units/modules/network/fortios/test_fortios_firewall_schedule_group.py b/test/units/modules/network/fortios/test_fortios_firewall_schedule_group.py
new file mode 100644
index 00000000000..5d0ffac12b8
--- /dev/null
+++ b/test/units/modules/network/fortios/test_fortios_firewall_schedule_group.py
@@ -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 .
+
+# 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
diff --git a/test/units/modules/network/fortios/test_fortios_firewall_schedule_onetime.py b/test/units/modules/network/fortios/test_fortios_firewall_schedule_onetime.py
new file mode 100644
index 00000000000..ff6f09434a8
--- /dev/null
+++ b/test/units/modules/network/fortios/test_fortios_firewall_schedule_onetime.py
@@ -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 .
+
+# 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
diff --git a/test/units/modules/network/fortios/test_fortios_firewall_schedule_recurring.py b/test/units/modules/network/fortios/test_fortios_firewall_schedule_recurring.py
new file mode 100644
index 00000000000..8a1463a683e
--- /dev/null
+++ b/test/units/modules/network/fortios/test_fortios_firewall_schedule_recurring.py
@@ -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 .
+
+# 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
diff --git a/test/units/modules/network/fortios/test_fortios_firewall_service_category.py b/test/units/modules/network/fortios/test_fortios_firewall_service_category.py
new file mode 100644
index 00000000000..2c896c3c4a9
--- /dev/null
+++ b/test/units/modules/network/fortios/test_fortios_firewall_service_category.py
@@ -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 .
+
+# 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
diff --git a/test/units/modules/network/fortios/test_fortios_firewall_service_custom.py b/test/units/modules/network/fortios/test_fortios_firewall_service_custom.py
new file mode 100644
index 00000000000..15eae37fdb0
--- /dev/null
+++ b/test/units/modules/network/fortios/test_fortios_firewall_service_custom.py
@@ -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 .
+
+# 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
diff --git a/test/units/modules/network/fortios/test_fortios_firewall_service_group.py b/test/units/modules/network/fortios/test_fortios_firewall_service_group.py
new file mode 100644
index 00000000000..51b36bdba58
--- /dev/null
+++ b/test/units/modules/network/fortios/test_fortios_firewall_service_group.py
@@ -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 .
+
+# 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
diff --git a/test/units/modules/network/fortios/test_fortios_firewall_shaper_per_ip_shaper.py b/test/units/modules/network/fortios/test_fortios_firewall_shaper_per_ip_shaper.py
new file mode 100644
index 00000000000..54fc4a35137
--- /dev/null
+++ b/test/units/modules/network/fortios/test_fortios_firewall_shaper_per_ip_shaper.py
@@ -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 .
+
+# 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
diff --git a/test/units/modules/network/fortios/test_fortios_firewall_shaper_traffic_shaper.py b/test/units/modules/network/fortios/test_fortios_firewall_shaper_traffic_shaper.py
new file mode 100644
index 00000000000..fb62200ae8a
--- /dev/null
+++ b/test/units/modules/network/fortios/test_fortios_firewall_shaper_traffic_shaper.py
@@ -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 .
+
+# 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
diff --git a/test/units/modules/network/fortios/test_fortios_firewall_shaping_policy.py b/test/units/modules/network/fortios/test_fortios_firewall_shaping_policy.py
new file mode 100644
index 00000000000..d8812a76e57
--- /dev/null
+++ b/test/units/modules/network/fortios/test_fortios_firewall_shaping_policy.py
@@ -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 .
+
+# 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
diff --git a/test/units/modules/network/fortios/test_fortios_firewall_shaping_profile.py b/test/units/modules/network/fortios/test_fortios_firewall_shaping_profile.py
new file mode 100644
index 00000000000..d9522bc7b0c
--- /dev/null
+++ b/test/units/modules/network/fortios/test_fortios_firewall_shaping_profile.py
@@ -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 .
+
+# 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
diff --git a/test/units/modules/network/fortios/test_fortios_firewall_sniffer.py b/test/units/modules/network/fortios/test_fortios_firewall_sniffer.py
new file mode 100644
index 00000000000..b69e26785c4
--- /dev/null
+++ b/test/units/modules/network/fortios/test_fortios_firewall_sniffer.py
@@ -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 .
+
+# 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
diff --git a/test/units/modules/network/fortios/test_fortios_firewall_ssh_host_key.py b/test/units/modules/network/fortios/test_fortios_firewall_ssh_host_key.py
new file mode 100644
index 00000000000..f403cd8a964
--- /dev/null
+++ b/test/units/modules/network/fortios/test_fortios_firewall_ssh_host_key.py
@@ -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 .
+
+# 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
diff --git a/test/units/modules/network/fortios/test_fortios_firewall_ssh_local_ca.py b/test/units/modules/network/fortios/test_fortios_firewall_ssh_local_ca.py
new file mode 100644
index 00000000000..8105cf00310
--- /dev/null
+++ b/test/units/modules/network/fortios/test_fortios_firewall_ssh_local_ca.py
@@ -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 .
+
+# 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
diff --git a/test/units/modules/network/fortios/test_fortios_firewall_ssh_local_key.py b/test/units/modules/network/fortios/test_fortios_firewall_ssh_local_key.py
new file mode 100644
index 00000000000..6b7d03e477e
--- /dev/null
+++ b/test/units/modules/network/fortios/test_fortios_firewall_ssh_local_key.py
@@ -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 .
+
+# 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
diff --git a/test/units/modules/network/fortios/test_fortios_firewall_ssh_setting.py b/test/units/modules/network/fortios/test_fortios_firewall_ssh_setting.py
new file mode 100644
index 00000000000..e4b55f1c527
--- /dev/null
+++ b/test/units/modules/network/fortios/test_fortios_firewall_ssh_setting.py
@@ -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 .
+
+# 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
diff --git a/test/units/modules/network/fortios/test_fortios_firewall_ssl_server.py b/test/units/modules/network/fortios/test_fortios_firewall_ssl_server.py
new file mode 100644
index 00000000000..6e6625e1778
--- /dev/null
+++ b/test/units/modules/network/fortios/test_fortios_firewall_ssl_server.py
@@ -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 .
+
+# 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
diff --git a/test/units/modules/network/fortios/test_fortios_firewall_ssl_setting.py b/test/units/modules/network/fortios/test_fortios_firewall_ssl_setting.py
new file mode 100644
index 00000000000..363d47768c2
--- /dev/null
+++ b/test/units/modules/network/fortios/test_fortios_firewall_ssl_setting.py
@@ -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 .
+
+# 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