Initial commit for fortios_webfilter (#37196)

* Initial commit for fortios_webfilter
This commit is contained in:
Miguel Angel Muñoz González 2018-04-27 11:47:58 +02:00 committed by John R Barker
parent a3f2e99864
commit 19e1f41837

View file

@ -0,0 +1,548 @@
#!/usr/bin/python
# 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 this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_webfilter
short_description: Configure webfilter capabilities of FortiGate and FortiOS.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure webfilter feature. For now it
is able to handle url and content filtering capabilities. The
module uses FortiGate REST API internally to configure the device.
version_added: "2.6"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate ip adress.
required: true
username:
description:
- FortiOS or FortiGate username.
required: true
password:
description:
- FortiOS or FortiGate password.
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.
default: "root"
webfilter_url:
description:
- Container for a group of url entries that the FortiGate
must act upon
default: null
suboptions:
id:
description:
- Id of URL filter list.
required: true
name:
description:
- Name of URL filter list.
required: true
comment:
description:
- Optional comments.
default: null
one-arm-ips-urlfilter:
description:
- Enable/disable DNS resolver for one-arm IPS URL filter operation.
choices:
- enable
- disable
default: disable
ip-addr-block:
description:
- Enable/disable blocking URLs when the hostname appears as an IP address.
choices:
- enable
- disable
default: disable
entries:
description:
- URL filter entries.
default: []
suboptions:
id:
description:
- Id of URL.
required: true
url:
description:
- URL to be filtered.
required: true
type:
description:
- Filter type (simple, regex, or wildcard).
required: true
choices:
- simple
- regex
- wildcard
action:
description:
- Action to take for URL filter matches.
required: true
choices:
- exempt
- block
- allow
- monitor
status:
description:
- Enable/disable this URL filter.
required: true
choices:
- enable
- disable
exempt:
description:
- If action is set to exempt, select the security profile
operations that exempt URLs skip. Separate multiple
options with a space.
required: true
choices:
- av
- web-content
- activex-java-cookie
- dlp
- fortiguard
- range-block
- pass
- all
web-proxy-profile:
description:
- Web proxy profile.
required: true
referrer-host:
description:
- Referrer host name.
required: true
state:
description:
- Configures the intended state of this object on the FortiGate.
When this value is set to I(present), the object is configured
on the device and when this value is set to I(absent) the
object is removed from the device.
required: true
choices:
- absent
- present
webfilter_content:
description:
- Container for a group of content-filtering entries that
the FortiGate must act upon
default: null
suboptions:
id:
description:
- Id of content-filter list.
required: true
name:
description:
- Name of content-filter list.
comment:
description:
- Optional comments.
default: null
entries:
description:
- Content filter entries.
default: []
suboptions:
name:
description:
- Banned word.
required: true
pattern-type:
description:
- Banned word pattern type. It can be a wildcard pattern or Perl regular expression.
required: true
choices:
- wildcard
- regexp
status:
description:
- Enable/disable banned word.
required: true
choices:
- enable
- disable
lang:
description:
- Language of banned word.
required: true
choices:
- western
- simch
- trach
- japanese
- korean
- french
- thai
- spanish
- cyrillic
score:
description:
- Score, to be applied every time the word appears on a web page.
required: true
action:
description:
- Block or exempt word when a match is found.
required: true
choices:
- block
- exempt
state:
description:
- Configures the intended state of this object on the FortiGate.
When this value is set to I(present), the object is configured
on the device and when this value is set to I(absent) the
object is removed from the device.
required: true
choices:
- absent
- present
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
tasks:
- name: Configure url to be filtered by fortigate
fortios_webfilter:
host: "{{ host }}"
username: "{{ username}}"
password: "{{ password }}"
vdom: "{{ vdom }}"
webfilter_url:
state: "present"
id: "1"
name: "default"
comment: "mycomment"
one-arm-ips-url-filter: "disable"
ip-addr-block: "disable"
entries:
- id: "1"
url: "www.test1.com"
type: "simple"
action: "exempt"
status: "enable"
exempt: "pass"
web-proxy-profile: ""
referrrer-host: ""
- id: "2"
url: "www.test2.com"
type: "simple"
action: "exempt"
status: "enable"
exempt: "pass"
web-proxy-profile: ""
referrrer-host: ""
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
tasks:
- name: Configure web content filtering in fortigate
fortios_webfilter:
host: "{{ host }}"
username: "{{ username}}"
password: "{{ password }}"
vdom: "{{ vdom }}"
webfilter_content:
id: "1"
name: "default"
comment: ""
entries:
- name: "1"
pattern-type: "www.test45.com"
status: "enable"
lang: "western"
score: 40
action: "block"
- name: "2"
pattern-type: "www.test46.com"
status: "enable"
lang: "western"
score: 42
action: "block"
state: "present"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: string
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: string
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: string
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: string
sample: "key1"
name:
description: Name of the table used to fulfill the request
returned: always
type: string
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: string
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: string
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: string
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: string
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: string
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: string
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
def login(data):
host = data['host']
username = data['username']
password = data['password']
fos.debug('on')
fos.https('off')
fos.login(host, username, password)
def filter_wf_url_data(json):
option_list = ['id', 'name', 'comment',
'one-arm-ips-urlfilter',
'ip-addr-block', 'entries']
dictionary = {}
for attribute in option_list:
if attribute in json:
dictionary[attribute] = json[attribute]
return dictionary
def filter_wf_content_data(json):
option_list = ['id', 'name', 'comment',
'entries']
dictionary = {}
for attribute in option_list:
if attribute in json:
dictionary[attribute] = json[attribute]
return dictionary
def webfilter_url(data, fos):
vdom = data['vdom']
wf_url_data = data['webfilter_url']
url_data = filter_wf_url_data(wf_url_data)
if wf_url_data['state'] == "present":
return fos.set('webfilter',
'urlfilter',
data=url_data,
vdom=vdom)
elif wf_url_data['state'] == "absent":
return fos.delete('webfilter',
'urlfilter',
mkey=url_data['id'],
vdom=vdom)
def webfilter_content(data, fos):
vdom = data['vdom']
wf_content_data = data['webfilter_content']
content_data = filter_wf_content_data(wf_content_data)
if wf_content_data['state'] == "present":
return fos.set('webfilter',
'content',
data=content_data,
vdom=vdom)
elif wf_content_data['state'] == "absent":
return fos.delete('webfilter',
'content',
mkey=content_data['id'],
vdom=vdom)
def fortios_webfilter(data, fos):
host = data['host']
username = data['username']
password = data['password']
fos.https('off')
fos.login(host, username, password)
methodlist = ['webfilter_url', 'webfilter_content', 'webfilter_profile']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
fos.logout()
return not resp['status'] == "success", 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},
"vdom": {"required": False, "type": "str", "default": "root"},
"webfilter_url": {
"required": False, "type": "dict",
"options": {
"state": {"required": True, "type": "str"},
"id": {"required": True, "type": "str"},
"name": {"required": True, "type": "str"},
"comment": {"required": False, "type": "str", "default": ""},
"one-arm-ips-urlfilter": {"required": False, "type": "str", "default": "disable",
"choices": ["enable", "disable"]},
"ip-addr-block": {"required": False, "type": "str", "default": "disable",
"choices": ["enable", "disable"]},
"entries": {
"required": False, "type": "list", "default": [],
"options": {
"id": {"required": True, "type": "integer"},
"url": {"required": True, "type": "string"},
"type": {"required": True, "type": "string", "choices": ["simple", "regex", "wildcard"]},
"action": {"required": True, "type": "string",
"choices": ["exempt", "block", "allow", "monitor"]},
"status": {"required": True, "type": "string", "choices": ["enable", "disable"]},
"exempt": {"required": True, "type": "string",
"choices": ["av", "web-content", "activex-java-cookie", "dlp", "fortiguard",
"range-block", "pass", "all"]},
"web-proxy-profile": {"required": True, "type": "string"},
"referrer-host": {"required": True, "type": "string"}
}
}
}
},
"webfilter_content": {
"required": False, "type": "dict",
"options": {
"state": {"required": True, "type": "str"},
"id": {"required": True, "type": "str"},
"name": {"required": True, "type": "str"},
"comment": {"required": False, "type": "str", "default": ""},
"entries": {
"required": False, "type": "list", "default": [],
"options": {
"name": {"required": True, "type": "string"},
"pattern-type": {"required": True, "type": "string", "choices": ["wildcard", "regexp"]},
"status": {"required": True, "type": "string", "choices": ["enable", "disable"]},
"lang": {"required": True, "type": "string",
"choices": ["western", "simch", "trach", "japanese", "korean", "french", "thai",
"spanish", "cyrillic"]},
"score": {"required": True, "type": "integer"},
"action": {"required": True, "type": "string", "choices": ["block", "exempt"]},
}
}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_webfilter(module.params, fos)
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()