diff --git a/lib/ansible/modules/network/fortimanager/fmgr_secprof_dns.py b/lib/ansible/modules/network/fortimanager/fmgr_secprof_dns.py
new file mode 100644
index 00000000000..1f87a8df344
--- /dev/null
+++ b/lib/ansible/modules/network/fortimanager/fmgr_secprof_dns.py
@@ -0,0 +1,483 @@
+#!/usr/bin/python
+#
+# This file is part of Ansible
+#
+# Ansible 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.
+#
+# Ansible 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 .
+#
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+ANSIBLE_METADATA = {'status': ['preview'],
+ 'supported_by': 'community',
+ 'metadata_version': '1.1'}
+
+DOCUMENTATION = '''
+---
+module: fmgr_secprof_dns
+version_added: "2.8"
+author:
+ - Luke Weighall (@lweighall)
+ - Andrew Welsh (@Ghilli3)
+ - Jim Huber (@p4r4n0y1ng)
+short_description: Manage DNS security profiles in FortiManager
+description:
+ - Manage DNS security profiles in FortiManager
+
+options:
+ adom:
+ description:
+ - The ADOM the configuration should belong to.
+ required: false
+ default: root
+
+ host:
+ description:
+ - The FortiManager's address.
+ required: true
+
+ username:
+ description:
+ - The username associated with the account.
+ required: true
+
+ password:
+ description:
+ - The password associated with the username account.
+ required: true
+
+ mode:
+ description:
+ - Sets one of three modes for managing the object.
+ - Allows use of soft-adds instead of overwriting existing values.
+ choices: ['add', 'set', 'delete', 'update']
+ required: false
+ default: add
+
+ youtube_restrict:
+ type: str
+ description:
+ - Set safe search for YouTube restriction level.
+ - choice | strict | Enable strict safe seach for YouTube.
+ - choice | moderate | Enable moderate safe search for YouTube.
+ required: false
+ choices: ["strict", "moderate"]
+
+ sdns_ftgd_err_log:
+ type: str
+ description:
+ - Enable/disable FortiGuard SDNS rating error logging.
+ - choice | disable | Disable FortiGuard SDNS rating error logging.
+ - choice | enable | Enable FortiGuard SDNS rating error logging.
+ required: false
+ choices: ["disable", "enable"]
+
+ sdns_domain_log:
+ type: str
+ description:
+ - Enable/disable domain filtering and botnet domain logging.
+ - choice | disable | Disable domain filtering and botnet domain logging.
+ - choice | enable | Enable domain filtering and botnet domain logging.
+ required: false
+ choices: ["disable", "enable"]
+
+ safe_search:
+ type: str
+ description:
+ - Enable/disable Google, Bing, and YouTube safe search.
+ - choice | disable | Disable Google, Bing, and YouTube safe search.
+ - choice | enable | Enable Google, Bing, and YouTube safe search.
+ required: false
+ choices: ["disable", "enable"]
+
+ redirect_portal:
+ type: str
+ description:
+ - IP address of the SDNS redirect portal.
+ required: false
+
+ name:
+ type: str
+ description:
+ - Profile name.
+ required: false
+
+ log_all_domain:
+ type: str
+ description:
+ - Enable/disable logging of all domains visited (detailed DNS logging).
+ - choice | disable | Disable logging of all domains visited.
+ - choice | enable | Enable logging of all domains visited.
+ required: false
+ choices: ["disable", "enable"]
+
+ external_ip_blocklist:
+ type: str
+ description:
+ - One or more external IP block lists.
+ required: false
+
+ comment:
+ type: str
+ description:
+ - Comment for the security profile to show in the FortiManager GUI.
+ required: false
+
+ block_botnet:
+ type: str
+ description:
+ - Enable/disable blocking botnet C&C; DNS lookups.
+ - choice | disable | Disable blocking botnet C&C; DNS lookups.
+ - choice | enable | Enable blocking botnet C&C; DNS lookups.
+ required: false
+ choices: ["disable", "enable"]
+
+ block_action:
+ type: str
+ description:
+ - Action to take for blocked domains.
+ - choice | block | Return NXDOMAIN for blocked domains.
+ - choice | redirect | Redirect blocked domains to SDNS portal.
+ required: false
+ choices: ["block", "redirect"]
+
+ domain_filter_domain_filter_table:
+ type: str
+ description:
+ - DNS domain filter table ID.
+ required: false
+
+ ftgd_dns_options:
+ type: str
+ description:
+ - FortiGuard DNS filter options.
+ - FLAG Based Options. Specify multiple in list form.
+ - flag | error-allow | Allow all domains when FortiGuard DNS servers fail.
+ - flag | ftgd-disable | Disable FortiGuard DNS domain rating.
+ required: false
+ choices: ["error-allow", "ftgd-disable"]
+
+ ftgd_dns_filters_action:
+ type: str
+ description:
+ - Action to take for DNS requests matching the category.
+ - choice | monitor | Allow DNS requests matching the category and log the result.
+ - choice | block | Block DNS requests matching the category.
+ required: false
+ choices: ["monitor", "block"]
+
+ ftgd_dns_filters_category:
+ type: str
+ description:
+ - Category number.
+ required: false
+
+ ftgd_dns_filters_log:
+ type: str
+ description:
+ - Enable/disable DNS filter logging for this DNS profile.
+ - choice | disable | Disable DNS filter logging.
+ - choice | enable | Enable DNS filter logging.
+ required: false
+ choices: ["disable", "enable"]
+
+
+'''
+
+EXAMPLES = '''
+ - name: DELETE Profile
+ fmgr_secprof_dns:
+ host: "{{inventory_hostname}}"
+ username: "{{ username }}"
+ password: "{{ password }}"
+ name: "Ansible_DNS_Profile"
+ comment: "Created by Ansible Module TEST"
+ mode: "delete"
+
+ - name: CREATE Profile
+ fmgr_secprof_dns:
+ host: "{{inventory_hostname}}"
+ username: "{{ username }}"
+ password: "{{ password }}"
+ name: "Ansible_DNS_Profile"
+ comment: "Created by Ansible Module TEST"
+ mode: "set"
+ block_action: "block"
+
+
+'''
+
+RETURN = """
+api_result:
+ description: full API response, includes status code and message
+ returned: always
+ type: string
+"""
+
+from ansible.module_utils.basic import AnsibleModule, env_fallback
+from ansible.module_utils.network.fortimanager.fortimanager import AnsibleFortiManager
+
+# check for pyFMG lib
+try:
+ from pyFMG.fortimgr import FortiManager
+
+ HAS_PYFMGR = True
+except ImportError:
+ HAS_PYFMGR = False
+
+
+###############
+# START METHODS
+###############
+
+
+def fmgr_dnsfilter_profile_addsetdelete(fmg, paramgram):
+ """
+ fmgr_dnsfilter_profile -- Your Description here, bruh
+ """
+
+ mode = paramgram["mode"]
+ adom = paramgram["adom"]
+ url = ""
+ datagram = {}
+
+ response = (-100000, {"msg": "Illegal or malformed paramgram discovered. System Exception"})
+
+ # EVAL THE MODE PARAMETER FOR SET OR ADD
+ if mode in ['set', 'add', 'update']:
+ url = '/pm/config/adom/{adom}/obj/dnsfilter/profile'.format(adom=adom)
+ datagram = fmgr_del_none(fmgr_prepare_dict(paramgram))
+
+ # EVAL THE MODE PARAMETER FOR DELETE
+ elif mode == "delete":
+ # SET THE CORRECT URL FOR DELETE
+ url = '/pm/config/adom/{adom}/obj/dnsfilter/profile/{name}'.format(adom=adom, name=paramgram["name"])
+ datagram = {}
+
+ # IF MODE = SET -- USE THE 'SET' API CALL MODE
+ if mode == "set":
+ response = fmg.set(url, datagram)
+ # IF MODE = UPDATE -- USER THE 'UPDATE' API CALL MODE
+ elif mode == "update":
+ response = fmg.update(url, datagram)
+ # IF MODE = ADD -- USE THE 'ADD' API CALL MODE
+ elif mode == "add":
+ response = fmg.add(url, datagram)
+ # IF MODE = DELETE -- USE THE DELETE URL AND API CALL MODE
+ elif mode == "delete":
+ response = fmg.delete(url, datagram)
+
+ return response
+
+
+# ADDITIONAL COMMON FUNCTIONS
+# FUNCTION/METHOD FOR LOGGING OUT AND ANALYZING ERROR CODES
+def fmgr_logout(fmg, module, msg="NULL", results=(), good_codes=(0,), logout_on_fail=True, logout_on_success=False):
+ """
+ THIS METHOD CONTROLS THE LOGOUT AND ERROR REPORTING AFTER AN METHOD OR FUNCTION RUNS
+ """
+
+ # VALIDATION ERROR (NO RESULTS, JUST AN EXIT)
+ if msg != "NULL" and len(results) == 0:
+ try:
+ fmg.logout()
+ except BaseException:
+ pass
+ module.fail_json(msg=msg)
+
+ # SUBMISSION ERROR
+ if len(results) > 0:
+ if msg == "NULL":
+ try:
+ msg = results[1]['status']['message']
+ except BaseException:
+ msg = "No status message returned from pyFMG. Possible that this was a GET with a tuple result."
+
+ if results[0] not in good_codes:
+ if logout_on_fail:
+ fmg.logout()
+ module.fail_json(msg=msg, **results[1])
+ else:
+ return msg
+ else:
+ if logout_on_success:
+ fmg.logout()
+ module.exit_json(msg=msg, **results[1])
+ else:
+ return msg
+
+
+# FUNCTION/METHOD FOR CONVERTING CIDR TO A NETMASK
+# DID NOT USE IP ADDRESS MODULE TO KEEP INCLUDES TO A MINIMUM
+def fmgr_cidr_to_netmask(cidr):
+ cidr = int(cidr)
+ mask = (0xffffffff >> (32 - cidr)) << (32 - cidr)
+ return (str((0xff000000 & mask) >> 24) + '.' +
+ str((0x00ff0000 & mask) >> 16) + '.' +
+ str((0x0000ff00 & mask) >> 8) + '.' +
+ str((0x000000ff & mask)))
+
+
+# utility function: removing keys wih value of None, nothing in playbook for that key
+def fmgr_del_none(obj):
+ if isinstance(obj, dict):
+ return type(obj)((fmgr_del_none(k), fmgr_del_none(v))
+ for k, v in obj.items() if k is not None and (v is not None and not fmgr_is_empty_dict(v)))
+ else:
+ return obj
+
+
+# utility function: remove keys that are need for the logic but the FMG API won't accept them
+def fmgr_prepare_dict(obj):
+ list_of_elems = ["mode", "adom", "host", "username", "password"]
+ if isinstance(obj, dict):
+ obj = dict((key, fmgr_prepare_dict(value)) for (key, value) in obj.items() if key not in list_of_elems)
+ return obj
+
+
+def fmgr_is_empty_dict(obj):
+ return_val = False
+ if isinstance(obj, dict):
+ if len(obj) > 0:
+ for k, v in obj.items():
+ if isinstance(v, dict):
+ if len(v) == 0:
+ return_val = True
+ elif len(v) > 0:
+ for k1, v1 in v.items():
+ if v1 is None:
+ return_val = True
+ elif v1 is not None:
+ return_val = False
+ return return_val
+ elif v is None:
+ return_val = True
+ elif v is not None:
+ return_val = False
+ return return_val
+ elif len(obj) == 0:
+ return_val = True
+
+ return return_val
+
+
+def fmgr_split_comma_strings_into_lists(obj):
+ if isinstance(obj, dict):
+ if len(obj) > 0:
+ for k, v in obj.items():
+ if isinstance(v, str):
+ new_list = list()
+ if "," in v:
+ new_items = v.split(",")
+ for item in new_items:
+ new_list.append(item.strip())
+ obj[k] = new_list
+
+ return obj
+
+
+#############
+# END METHODS
+#############
+
+
+def main():
+ argument_spec = dict(
+ adom=dict(type="str", default="root"),
+ host=dict(required=True, type="str"),
+ password=dict(fallback=(env_fallback, ["ANSIBLE_NET_PASSWORD"]), no_log=True, required=True),
+ username=dict(fallback=(env_fallback, ["ANSIBLE_NET_USERNAME"]), no_log=True, required=True),
+ mode=dict(choices=["add", "set", "delete", "update"], type="str", default="add"),
+
+ youtube_restrict=dict(required=False, type="str", choices=["strict", "moderate"]),
+ sdns_ftgd_err_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ sdns_domain_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ safe_search=dict(required=False, type="str", choices=["disable", "enable"]),
+ redirect_portal=dict(required=False, type="str"),
+ name=dict(required=False, type="str"),
+ log_all_domain=dict(required=False, type="str", choices=["disable", "enable"]),
+ external_ip_blocklist=dict(required=False, type="str"),
+ comment=dict(required=False, type="str"),
+ block_botnet=dict(required=False, type="str", choices=["disable", "enable"]),
+ block_action=dict(required=False, type="str", choices=["block", "redirect"]),
+
+ domain_filter_domain_filter_table=dict(required=False, type="str"),
+
+ ftgd_dns_options=dict(required=False, type="str", choices=["error-allow", "ftgd-disable"]),
+
+ ftgd_dns_filters_action=dict(required=False, type="str", choices=["monitor", "block"]),
+ ftgd_dns_filters_category=dict(required=False, type="str"),
+ ftgd_dns_filters_log=dict(required=False, type="str", choices=["disable", "enable"]),
+
+ )
+
+ module = AnsibleModule(argument_spec, supports_check_mode=False)
+
+ # MODULE PARAMGRAM
+ paramgram = {
+ "mode": module.params["mode"],
+ "adom": module.params["adom"],
+ "youtube-restrict": module.params["youtube_restrict"],
+ "sdns-ftgd-err-log": module.params["sdns_ftgd_err_log"],
+ "sdns-domain-log": module.params["sdns_domain_log"],
+ "safe-search": module.params["safe_search"],
+ "redirect-portal": module.params["redirect_portal"],
+ "name": module.params["name"],
+ "log-all-domain": module.params["log_all_domain"],
+ "external-ip-blocklist": module.params["external_ip_blocklist"],
+ "comment": module.params["comment"],
+ "block-botnet": module.params["block_botnet"],
+ "block-action": module.params["block_action"],
+ "domain-filter": {
+ "domain-filter-table": module.params["domain_filter_domain_filter_table"],
+ },
+ "ftgd-dns": {
+ "options": module.params["ftgd_dns_options"],
+ "filters": {
+ "action": module.params["ftgd_dns_filters_action"],
+ "category": module.params["ftgd_dns_filters_category"],
+ "log": module.params["ftgd_dns_filters_log"],
+ }
+ }
+ }
+
+ # CHECK IF THE HOST/USERNAME/PW EXISTS, AND IF IT DOES, LOGIN.
+ host = module.params["host"]
+ password = module.params["password"]
+ username = module.params["username"]
+ if host is None or username is None or password is None:
+ module.fail_json(msg="Host and username and password are required")
+
+ # CHECK IF LOGIN FAILED
+ fmg = AnsibleFortiManager(module, module.params["host"], module.params["username"], module.params["password"])
+
+ response = fmg.login()
+ if response[1]['status']['code'] != 0:
+ module.fail_json(msg="Connection to FortiManager Failed")
+
+ results = fmgr_dnsfilter_profile_addsetdelete(fmg, paramgram)
+ if results[0] != 0:
+ fmgr_logout(fmg, module, results=results, good_codes=[0])
+
+ fmg.logout()
+
+ if results is not None:
+ return module.exit_json(**results[1])
+ else:
+ return module.exit_json(msg="No results were returned from the API call.")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/lib/ansible/modules/network/fortimanager/fmgr_sys_proxy.py b/lib/ansible/modules/network/fortimanager/fmgr_sys_proxy.py
deleted file mode 100644
index 988b898fbb7..00000000000
--- a/lib/ansible/modules/network/fortimanager/fmgr_sys_proxy.py
+++ /dev/null
@@ -1,192 +0,0 @@
-#!/usr/bin/python
-#
-# This file is part of Ansible
-#
-# Ansible 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.
-#
-# Ansible 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 .
-#
-
-from __future__ import absolute_import, division, print_function
-
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'status': ['preview'],
- 'supported_by': 'community',
- 'metadata_version': '1.1'}
-
-DOCUMENTATION = '''
----
-module: fmgr_sys_proxy
-version_added: "2.8"
-author: Andrew Welsh
-short_description: Make FortiGate API calls via the FortiMananger
-description:
- - The FMG proxies FOS API calls via the FMG. Review FortiGate API documentation to ensure you are passing correct
- parameters for both the FortiManager and FortiGate
-
-options:
- adom:
- description:
- - The administrative domain (admon) the configuration belongs to
- required: true
- host:
- description:
- - The FortiManager's Address.
- required: true
- username:
- description:
- - The username to log into the FortiManager
- required: true
- password:
- description:
- - The password associated with the username account.
- required: false
-
- action:
- description:
- - Specify HTTP action for the request. Either 'get' or 'post'
- required: True
- payload:
- description:
- - JSON payload of the request. The payload will be URL-encoded and becomes the "json" field in the query string for both GET and POST request.
- required: False
- resource:
- description:
- - URL on the remote device to be accessed, string
- required: True
- target:
- description:
- - FOS datasource, either device or group object
- required: True
-
-'''
-
-EXAMPLES = '''
-- name: Proxy FOS requests via FMG
- hosts: FortiManager
- connection: local
- gather_facts: False
-
- tasks:
-
- - name: Get upgrade path for FGT1
- fmgr_provision:
- host: "{{ inventory_hostname }}"
- username: "{{ username }}"
- password: "{{ password }}"
- adom: "root"
- action: "get"
- resource: "/api/v2/monitor/system/firmware/upgrade-paths?vdom=root"
- target: ["/adom/root/device/FGT1"]
- - name: Upgrade firmware of FGT1
- fmgr_provision:
- host: "{{ inventory_hostname }}"
- username: "{{ username }}"
- password: "{{ password }}"
- adom: "root"
- action: "post"
- payload: {source: upload, file_content: b64_encoded_string, file_name: file_name}
- resource: "/api/v2/monitor/system/firmware/upgrade?vdom=vdom"
- target: ["/adom/root/device/FGT1"]
-
-'''
-
-RETURN = """
-api_result:
- description: full API response, includes status code and message
- returned: always
- type: string
-"""
-
-
-from ansible.module_utils.basic import AnsibleModule, env_fallback
-from ansible.module_utils.network.fortimanager.fortimanager import AnsibleFortiManager
-
-
-# check for pyFMG lib
-try:
- from pyFMG.fortimgr import FortiManager
- HAS_PYFMGR = True
-except ImportError:
- HAS_PYFMGR = False
-
-
-def fos_request(fmg, action, resource, target, payload, adom='root'):
-
- datagram = {
- "data": {
- # get or post
- "action": action,
- # dictionary of data
- "payload": payload,
- # FOS API URL including vdom params
- "resource": resource,
- # FMG device to make API calls to
- "target": target
- },
-
- }
- url = "/sys/proxy/json"
-
- status, response = fmg.execute(url, datagram)
- return status, response
-
-
-def main():
-
- argument_spec = dict(
- adom=dict(required=False, type="str"),
- host=dict(required=True, type="str"),
- password=dict(fallback=(env_fallback, ["ANSIBLE_NET_PASSWORD"]), no_log=True),
- username=dict(fallback=(env_fallback, ["ANSIBLE_NET_USERNAME"]), no_log=True),
-
- action=dict(required=False, type="str"),
- resource=dict(required=False, type="str"),
- target=dict(required=False, type="str"),
- payload=dict(required=False, type="str"),
- )
-
- module = AnsibleModule(argument_spec, supports_check_mode=True, )
-
- action = module.params["action"]
- resource = module.params["resource"]
- target = module.params["target"]
- payload = module.params["payload"]
-
- # check if params are set
- if module.params["host"] is None or module.params["username"] is None:
- module.fail_json(msg="Host and username are required for connection")
-
- # check if login failed
- fmg = AnsibleFortiManager(module, module.params["host"], module.params["username"], module.params["password"])
- response = fmg.login()
-
- if response[1]['status']['code'] != 0:
- module.fail_json(msg="Connection to FortiManager Failed")
- else:
- if module.params["adom"] is None:
- module.params["adom"] = 'root'
-
- status, result = fos_request(fmg, action, resource, target, payload, module.params["adom"])
-
- if not status == 0:
- module.fail_json(msg="Failure showing upgrade path", **result)
-
- fmg.logout()
-
- # results is returned as a tuple
- return module.exit_json(changed=True, **result)
-
-
-if __name__ == "__main__":
- main()
diff --git a/test/units/modules/network/fortimanager/fixtures/test_fmgr_secprof_dns.json b/test/units/modules/network/fortimanager/fixtures/test_fmgr_secprof_dns.json
new file mode 100644
index 00000000000..eac142b6e12
--- /dev/null
+++ b/test/units/modules/network/fortimanager/fixtures/test_fmgr_secprof_dns.json
@@ -0,0 +1,76 @@
+{
+ "fmgr_dnsfilter_profile_addsetdelete": [
+ {
+ "paramgram_used": {
+ "comment": "Created by Ansible Module TEST",
+ "ftgd-dns": {
+ "options": null,
+ "filters": {
+ "action": null,
+ "category": null,
+ "log": null
+ }
+ },
+ "name": "Ansible_DNS_Profile",
+ "adom": "root",
+ "redirect-portal": null,
+ "sdns-ftgd-err-log": null,
+ "youtube-restrict": null,
+ "sdns-domain-log": null,
+ "domain-filter": {
+ "domain-filter-table": null
+ },
+ "log-all-domain": null,
+ "mode": "delete",
+ "block-botnet": null,
+ "safe-search": null,
+ "external-ip-blocklist": null,
+ "block-action": null
+ },
+ "raw_response": {
+ "status": {
+ "message": "OK",
+ "code": 0
+ },
+ "url": "/pm/config/adom/root/obj/dnsfilter/profile/Ansible_DNS_Profile"
+ },
+ "post_method": "delete"
+ },
+ {
+ "raw_response": {
+ "status": {
+ "message": "OK",
+ "code": 0
+ },
+ "url": "/pm/config/adom/root/obj/dnsfilter/profile"
+ },
+ "paramgram_used": {
+ "comment": "Created by Ansible Module TEST",
+ "ftgd-dns": {
+ "options": null,
+ "filters": {
+ "action": null,
+ "category": null,
+ "log": null
+ }
+ },
+ "adom": "root",
+ "youtube-restrict": null,
+ "sdns-domain-log": null,
+ "block-botnet": null,
+ "external-ip-blocklist": null,
+ "block-action": "block",
+ "name": "Ansible_DNS_Profile",
+ "redirect-portal": null,
+ "sdns-ftgd-err-log": null,
+ "safe-search": null,
+ "domain-filter": {
+ "domain-filter-table": null
+ },
+ "log-all-domain": null,
+ "mode": "set"
+ },
+ "post_method": "set"
+ }
+ ]
+}
diff --git a/test/units/modules/network/fortimanager/test_fmgr_secprof_dns.py b/test/units/modules/network/fortimanager/test_fmgr_secprof_dns.py
new file mode 100644
index 00000000000..f621bbcff42
--- /dev/null
+++ b/test/units/modules/network/fortimanager/test_fmgr_secprof_dns.py
@@ -0,0 +1,94 @@
+# Copyright 2018 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
+from pyFMG.fortimgr import FortiManager
+import pytest
+
+try:
+ from ansible.modules.network.fortimanager import fmgr_secprof_dns
+except ImportError:
+ pytest.skip("Could not load required modules for testing", allow_module_level=True)
+
+fmg_instance = FortiManager("1.1.1.1", "admin", "")
+
+
+def load_fixtures():
+ fixture_path = os.path.join(os.path.dirname(__file__), 'fixtures') + "/{filename}.json".format(
+ filename=os.path.splitext(os.path.basename(__file__))[0])
+ try:
+ with open(fixture_path, "r") as fixture_file:
+ fixture_data = json.load(fixture_file)
+ except IOError:
+ return []
+ return [fixture_data]
+
+
+@pytest.fixture(scope="function", params=load_fixtures())
+def fixture_data(request):
+ func_name = request.function.__name__.replace("test_", "")
+ return request.param.get(func_name, None)
+
+
+def test_fmgr_dnsfilter_profile_addsetdelete(fixture_data, mocker):
+ mocker.patch("pyFMG.fortimgr.FortiManager._post_request", side_effect=fixture_data)
+ # Fixture sets used:###########################
+
+ ##################################################
+ # comment: Created by Ansible Module TEST
+ # ftgd-dns: {'options': None, 'filters': {'action': None, 'category': None, 'log': None}}
+ # name: Ansible_DNS_Profile
+ # adom: root
+ # redirect-portal: None
+ # sdns-ftgd-err-log: None
+ # youtube-restrict: None
+ # sdns-domain-log: None
+ # domain-filter: {'domain-filter-table': None}
+ # log-all-domain: None
+ # mode: delete
+ # block-botnet: None
+ # safe-search: None
+ # external-ip-blocklist: None
+ # block-action: None
+ ##################################################
+ ##################################################
+ # comment: Created by Ansible Module TEST
+ # ftgd-dns: {'options': None, 'filters': {'action': None, 'category': None, 'log': None}}
+ # adom: root
+ # youtube-restrict: None
+ # sdns-domain-log: None
+ # block-botnet: None
+ # external-ip-blocklist: None
+ # block-action: block
+ # name: Ansible_DNS_Profile
+ # redirect-portal: None
+ # sdns-ftgd-err-log: None
+ # safe-search: None
+ # domain-filter: {'domain-filter-table': None}
+ # log-all-domain: None
+ # mode: set
+ ##################################################
+
+ # Test using fixture 1 #
+ output = fmgr_secprof_dns.fmgr_dnsfilter_profile_addsetdelete(fmg_instance, fixture_data[0]['paramgram_used'])
+ assert output['raw_response']['status']['code'] == 0
+ # Test using fixture 2 #
+ output = fmgr_secprof_dns.fmgr_dnsfilter_profile_addsetdelete(fmg_instance, fixture_data[1]['paramgram_used'])
+ assert output['raw_response']['status']['code'] == 0