Files from PR#60621, continue working on fortios_facts modules (#61405)
* Files from PR#60621, continue working on fortios_facts modules * PR#61405 unit test module test_fortios_facts.py * sanity fixed in test_fortios_facts unit test module
This commit is contained in:
parent
add33ccbdc
commit
7a1237781d
11 changed files with 613 additions and 0 deletions
|
@ -0,0 +1,45 @@
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
# 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
"""
|
||||||
|
The arg spec for the fortios monitor module.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class FactsArgs(object):
|
||||||
|
""" The arg spec for the fortios monitor module
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
pass
|
||||||
|
|
||||||
|
argument_spec = {
|
||||||
|
"host": {"required": False, "type": "str"},
|
||||||
|
"username": {"required": False, "type": "str"},
|
||||||
|
"password": {"required": False, "type": "str", "no_log": True},
|
||||||
|
"vdom": {"required": False, "type": "str", "default": "root"},
|
||||||
|
"https": {"required": False, "type": "bool", "default": True},
|
||||||
|
"ssl_verify": {"required": False, "type": "bool", "default": False},
|
||||||
|
"gather_subset": {
|
||||||
|
"required": True, "type": "list", "elements": "dict",
|
||||||
|
"options": {
|
||||||
|
"fact": {"required": True, "type": "str"},
|
||||||
|
"filters": {"required": False, "type": "list", "elements": "dict"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
#
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright 2019 Fortinet, Inc.
|
||||||
|
# GNU General Public License v3.0+
|
||||||
|
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
"""
|
||||||
|
The arg spec for the fortios_facts module
|
||||||
|
"""
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
|
||||||
|
class SystemArgs(object):
|
||||||
|
"""The arg spec for the fortios_facts module
|
||||||
|
"""
|
||||||
|
|
||||||
|
FACT_SYSTEM_SUBSETS = frozenset([
|
||||||
|
'system_current-admins_select',
|
||||||
|
'system_firmware_select',
|
||||||
|
'system_fortimanager_status',
|
||||||
|
'system_ha-checksums_select',
|
||||||
|
'system_interface_select',
|
||||||
|
'system_status_select',
|
||||||
|
'system_time_select',
|
||||||
|
])
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
pass
|
92
lib/ansible/module_utils/network/fortios/facts/facts.py
Normal file
92
lib/ansible/module_utils/network/fortios/facts/facts.py
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
# 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
"""
|
||||||
|
The facts class for fortios
|
||||||
|
this file validates each subset of monitor and selectively
|
||||||
|
calls the appropriate facts gathering and monitoring function
|
||||||
|
"""
|
||||||
|
|
||||||
|
from ansible.module_utils.network.fortios.argspec.facts.facts import FactsArgs
|
||||||
|
from ansible.module_utils.network.fortios.argspec.system.system import SystemArgs
|
||||||
|
from ansible.module_utils.network.common.facts.facts import FactsBase
|
||||||
|
from ansible.module_utils.network.fortios.facts.system.system import SystemFacts
|
||||||
|
|
||||||
|
|
||||||
|
class Facts(FactsBase):
|
||||||
|
""" The facts class for fortios
|
||||||
|
"""
|
||||||
|
|
||||||
|
FACT_SUBSETS = {
|
||||||
|
"system": SystemFacts
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self, module, fos=None, subset=None):
|
||||||
|
super(Facts, self).__init__(module)
|
||||||
|
self._fos = fos
|
||||||
|
self._subset = subset
|
||||||
|
|
||||||
|
def gen_runable(self, subsets, valid_subsets):
|
||||||
|
""" Generate the runable subset
|
||||||
|
|
||||||
|
:param module: The module instance
|
||||||
|
:param subsets: The provided subsets
|
||||||
|
:param valid_subsets: The valid subsets
|
||||||
|
:rtype: list
|
||||||
|
:returns: The runable subsets
|
||||||
|
"""
|
||||||
|
runable_subsets = []
|
||||||
|
FACT_DETAIL_SUBSETS = []
|
||||||
|
FACT_DETAIL_SUBSETS.extend(SystemArgs.FACT_SYSTEM_SUBSETS)
|
||||||
|
|
||||||
|
for subset in subsets:
|
||||||
|
if subset['fact'] not in FACT_DETAIL_SUBSETS:
|
||||||
|
self._module.fail_json(msg='Subset must be one of [%s], got %s' %
|
||||||
|
(', '.join(sorted([item for item in FACT_DETAIL_SUBSETS])), subset['fact']))
|
||||||
|
|
||||||
|
for valid_subset in frozenset(self.FACT_SUBSETS.keys()):
|
||||||
|
if subset['fact'].startswith(valid_subset):
|
||||||
|
runable_subsets.append((subset, valid_subset))
|
||||||
|
|
||||||
|
return runable_subsets
|
||||||
|
|
||||||
|
def get_network_legacy_facts(self, fact_legacy_obj_map, legacy_facts_type=None):
|
||||||
|
if not legacy_facts_type:
|
||||||
|
legacy_facts_type = self._gather_subset
|
||||||
|
|
||||||
|
runable_subsets = self.gen_runable(legacy_facts_type, frozenset(fact_legacy_obj_map.keys()))
|
||||||
|
if runable_subsets:
|
||||||
|
self.ansible_facts['ansible_net_gather_subset'] = []
|
||||||
|
|
||||||
|
instances = list()
|
||||||
|
for (subset, valid_subset) in runable_subsets:
|
||||||
|
instances.append(fact_legacy_obj_map[valid_subset](self._module, self._fos, subset))
|
||||||
|
|
||||||
|
for inst in instances:
|
||||||
|
inst.populate_facts(self._connection, self.ansible_facts)
|
||||||
|
|
||||||
|
def get_facts(self, facts_type=None, data=None):
|
||||||
|
""" Collect the facts for fortios
|
||||||
|
:param facts_type: List of facts types
|
||||||
|
:param data: previously collected conf
|
||||||
|
:rtype: dict
|
||||||
|
:return: the facts gathered
|
||||||
|
"""
|
||||||
|
self.get_network_legacy_facts(self.FACT_SUBSETS, facts_type)
|
||||||
|
|
||||||
|
return self.ansible_facts, self._warnings
|
|
@ -0,0 +1,63 @@
|
||||||
|
#
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright 2019 Fortinet, Inc.
|
||||||
|
# GNU General Public License v3.0+
|
||||||
|
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
"""
|
||||||
|
The fortios system facts class
|
||||||
|
It is in this file the runtime information is collected from the device
|
||||||
|
for a given resource, parsed, and the facts tree is populated
|
||||||
|
based on the configuration.
|
||||||
|
"""
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
import re
|
||||||
|
from ansible.module_utils.network.common import utils
|
||||||
|
from ansible.module_utils.network.fortios.argspec.system.system import SystemArgs
|
||||||
|
|
||||||
|
|
||||||
|
class SystemFacts(object):
|
||||||
|
""" The fortios system facts class
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, module, fos=None, subset=None, subspec='config', options='options'):
|
||||||
|
self._module = module
|
||||||
|
self._fos = fos
|
||||||
|
self._subset = subset
|
||||||
|
|
||||||
|
def populate_facts(self, connection, ansible_facts, data=None):
|
||||||
|
""" Populate the facts for system
|
||||||
|
:param connection: the device connection
|
||||||
|
:param ansible_facts: Facts dictionary
|
||||||
|
:rtype: dictionary
|
||||||
|
:returns: facts
|
||||||
|
"""
|
||||||
|
ansible_facts['ansible_network_resources'].pop('system', None)
|
||||||
|
facts = {}
|
||||||
|
if self._subset['fact'].startswith(tuple(SystemArgs.FACT_SYSTEM_SUBSETS)):
|
||||||
|
gather_method = getattr(self, self._subset['fact'].replace('-', '_'), self.system_fact)
|
||||||
|
resp = gather_method()
|
||||||
|
facts.update({self._subset['fact']: resp})
|
||||||
|
|
||||||
|
ansible_facts['ansible_network_resources'].update(facts)
|
||||||
|
return ansible_facts
|
||||||
|
|
||||||
|
def system_fact(self):
|
||||||
|
fos = self._fos
|
||||||
|
vdom = self._module.params['vdom']
|
||||||
|
return fos.monitor('system', self._subset['fact'][len('system_'):].replace('_', '/'), vdom=vdom)
|
||||||
|
|
||||||
|
def system_interface_select(self):
|
||||||
|
fos = self._fos
|
||||||
|
vdom = self._module.params['vdom']
|
||||||
|
|
||||||
|
query_string = '?vdom=' + vdom
|
||||||
|
system_interface_select_param = self._subset['filters']
|
||||||
|
if system_interface_select_param:
|
||||||
|
for filter in system_interface_select_param:
|
||||||
|
for key, val in filter.items():
|
||||||
|
if val:
|
||||||
|
query_string += '&' + str(key) + '=' + str(val)
|
||||||
|
|
||||||
|
return fos.monitor('system', self._subset['fact'][len('system_'):].replace('_', '/') + query_string, vdom=None)
|
282
lib/ansible/modules/network/fortios/fortios_facts.py
Normal file
282
lib/ansible/modules/network/fortios/fortios_facts.py
Normal file
|
@ -0,0 +1,282 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
# 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
ANSIBLE_METADATA = {'status': ['preview'],
|
||||||
|
'supported_by': 'community',
|
||||||
|
'metadata_version': '1.1'}
|
||||||
|
|
||||||
|
DOCUMENTATION = '''
|
||||||
|
---
|
||||||
|
module: fortios_facts
|
||||||
|
version_added: "2.9"
|
||||||
|
short_description: Get facts about fortios devices.
|
||||||
|
description:
|
||||||
|
- Collects facts from network devices running the fortios operating
|
||||||
|
system. This module places the facts gathered in the fact tree keyed by the
|
||||||
|
respective resource name. This facts module will only collect those
|
||||||
|
facts which user specified in playbook.
|
||||||
|
author:
|
||||||
|
- Don Yao (@fortinetps)
|
||||||
|
- Miguel Angel Munoz (@mamunozgonzalez)
|
||||||
|
- Nicolas Thomas (@thomnico)
|
||||||
|
notes:
|
||||||
|
- Support both legacy mode (local_action) and httpapi
|
||||||
|
- Legacy mode run as a local_action in your playbook, requires fortiosapi library developed by Fortinet
|
||||||
|
- httpapi mode is the new recommend way for network modules
|
||||||
|
requirements:
|
||||||
|
- fortiosapi>=0.9.8
|
||||||
|
options:
|
||||||
|
host:
|
||||||
|
description:
|
||||||
|
- FortiOS or FortiGate IP address.
|
||||||
|
type: str
|
||||||
|
required: false
|
||||||
|
username:
|
||||||
|
description:
|
||||||
|
- FortiOS or FortiGate username.
|
||||||
|
type: str
|
||||||
|
required: false
|
||||||
|
password:
|
||||||
|
description:
|
||||||
|
- FortiOS or FortiGate password.
|
||||||
|
type: str
|
||||||
|
default: ""
|
||||||
|
required: false
|
||||||
|
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
|
||||||
|
required: false
|
||||||
|
https:
|
||||||
|
description:
|
||||||
|
- Indicates if the requests towards FortiGate must use HTTPS protocol.
|
||||||
|
type: bool
|
||||||
|
default: true
|
||||||
|
required: false
|
||||||
|
ssl_verify:
|
||||||
|
description:
|
||||||
|
- Ensures FortiGate certificate must be verified by a proper CA.
|
||||||
|
type: bool
|
||||||
|
default: false
|
||||||
|
required: false
|
||||||
|
gather_subset:
|
||||||
|
description:
|
||||||
|
- When supplied, this argument will restrict the facts collected
|
||||||
|
to a given subset. Possible values for this argument include
|
||||||
|
system_current-admins_select, system_firmware_select,
|
||||||
|
system_fortimanager_status, system_ha-checksums_select,
|
||||||
|
system_interface_select, system_status_select and system_time_select
|
||||||
|
type: list
|
||||||
|
elements: dict
|
||||||
|
required: true
|
||||||
|
suboptions:
|
||||||
|
fact:
|
||||||
|
description:
|
||||||
|
- Name of the facts to gather
|
||||||
|
type: str
|
||||||
|
required: true
|
||||||
|
filters:
|
||||||
|
description:
|
||||||
|
- Filters apply when gathering facts
|
||||||
|
type: list
|
||||||
|
elements: dict
|
||||||
|
required: false
|
||||||
|
'''
|
||||||
|
|
||||||
|
EXAMPLES = '''
|
||||||
|
- hosts: localhost
|
||||||
|
vars:
|
||||||
|
host: "192.168.122.40"
|
||||||
|
username: "admin"
|
||||||
|
password: ""
|
||||||
|
vdom: "root"
|
||||||
|
ssl_verify: "False"
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: gather basic system status facts
|
||||||
|
fortios_facts:
|
||||||
|
host: "{{ host }}"
|
||||||
|
username: "{{ username }}"
|
||||||
|
password: "{{ password }}"
|
||||||
|
vdom: "{{ vdom }}"
|
||||||
|
gather_subset:
|
||||||
|
- fact: 'system_status_select'
|
||||||
|
|
||||||
|
- name: gather all pysical interfaces status facts
|
||||||
|
fortios_facts:
|
||||||
|
host: "{{ host }}"
|
||||||
|
username: "{{ username }}"
|
||||||
|
password: "{{ password }}"
|
||||||
|
vdom: "{{ vdom }}"
|
||||||
|
gather_subset:
|
||||||
|
- fact: 'system_interface_select'
|
||||||
|
|
||||||
|
- name: gather gather all pysical and vlan interfaces status facts
|
||||||
|
fortios_facts:
|
||||||
|
host: "{{ host }}"
|
||||||
|
username: "{{ username }}"
|
||||||
|
password: "{{ password }}"
|
||||||
|
vdom: "{{ vdom }}"
|
||||||
|
gather_subset:
|
||||||
|
- fact: 'system_interface_select'
|
||||||
|
filters:
|
||||||
|
- include_vlan: true
|
||||||
|
|
||||||
|
- name: gather basic system info and physical interface port3 status facts
|
||||||
|
fortios_facts:
|
||||||
|
host: "{{ host }}"
|
||||||
|
username: "{{ username }}"
|
||||||
|
password: "{{ password }}"
|
||||||
|
vdom: "{{ vdom }}"
|
||||||
|
gather_subset:
|
||||||
|
- fact: 'system_status_select'
|
||||||
|
- fact: 'system_interface_select'
|
||||||
|
filters:
|
||||||
|
- interface_name: 'port3'
|
||||||
|
'''
|
||||||
|
|
||||||
|
RETURN = '''
|
||||||
|
build:
|
||||||
|
description: Build number of the fortigate image
|
||||||
|
returned: always
|
||||||
|
type: str
|
||||||
|
sample: '1547'
|
||||||
|
http_method:
|
||||||
|
description: Last method used to provision the content into FortiGate
|
||||||
|
returned: always
|
||||||
|
type: str
|
||||||
|
sample: 'GET'
|
||||||
|
name:
|
||||||
|
description: Name of the table used to fulfill the request
|
||||||
|
returned: always
|
||||||
|
type: str
|
||||||
|
sample: "firmware"
|
||||||
|
path:
|
||||||
|
description: Path of the table used to fulfill the request
|
||||||
|
returned: always
|
||||||
|
type: str
|
||||||
|
sample: "system"
|
||||||
|
revision:
|
||||||
|
description: Internal revision number
|
||||||
|
returned: always
|
||||||
|
type: str
|
||||||
|
sample: "17.0.2.10658"
|
||||||
|
serial:
|
||||||
|
description: Serial number of the unit
|
||||||
|
returned: always
|
||||||
|
type: str
|
||||||
|
sample: "FGVMEVYYQT3AB5352"
|
||||||
|
status:
|
||||||
|
description: Indication of the operation's result
|
||||||
|
returned: always
|
||||||
|
type: str
|
||||||
|
sample: "success"
|
||||||
|
vdom:
|
||||||
|
description: Virtual domain used
|
||||||
|
returned: always
|
||||||
|
type: str
|
||||||
|
sample: "root"
|
||||||
|
version:
|
||||||
|
description: Version of the FortiGate
|
||||||
|
returned: always
|
||||||
|
type: str
|
||||||
|
sample: "v5.6.3"
|
||||||
|
ansible_facts:
|
||||||
|
description: The list of fact subsets collected from the device
|
||||||
|
returned: always
|
||||||
|
type: dict
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils.connection import Connection
|
||||||
|
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
|
||||||
|
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
|
||||||
|
from ansible.module_utils.network.fortios.argspec.facts.facts import FactsArgs
|
||||||
|
from ansible.module_utils.network.fortios.facts.facts import Facts
|
||||||
|
|
||||||
|
|
||||||
|
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']:
|
||||||
|
fos.https('off')
|
||||||
|
else:
|
||||||
|
fos.https('on')
|
||||||
|
|
||||||
|
fos.login(host, username, password, verify=ssl_verify)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
""" Main entry point for AnsibleModule
|
||||||
|
"""
|
||||||
|
argument_spec = FactsArgs.argument_spec
|
||||||
|
|
||||||
|
module = AnsibleModule(argument_spec=argument_spec,
|
||||||
|
supports_check_mode=False)
|
||||||
|
|
||||||
|
# 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:
|
||||||
|
warnings = []
|
||||||
|
connection = Connection(module._socket_path)
|
||||||
|
module._connection = connection
|
||||||
|
fos = FortiOSHandler(connection)
|
||||||
|
|
||||||
|
result = Facts(module, fos).get_facts()
|
||||||
|
|
||||||
|
ansible_facts, additional_warnings = result
|
||||||
|
warnings.extend(additional_warnings)
|
||||||
|
|
||||||
|
module.exit_json(ansible_facts=ansible_facts, warnings=warnings)
|
||||||
|
else:
|
||||||
|
module.fail_json(**FAIL_SOCKET_MSG)
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
from fortiosapi import FortiOSAPI
|
||||||
|
except ImportError:
|
||||||
|
module.fail_json(msg="fortiosapi module is required")
|
||||||
|
|
||||||
|
warnings = []
|
||||||
|
|
||||||
|
fos = FortiOSAPI()
|
||||||
|
login(module.params, fos)
|
||||||
|
module._connection = fos
|
||||||
|
|
||||||
|
result = Facts(module, fos).get_facts()
|
||||||
|
|
||||||
|
ansible_facts, additional_warnings = result
|
||||||
|
warnings.extend(additional_warnings)
|
||||||
|
|
||||||
|
module.exit_json(ansible_facts=ansible_facts, warnings=warnings)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
103
test/units/modules/network/fortios/test_fortios_facts.py
Normal file
103
test/units/modules/network/fortios/test_fortios_facts.py
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
# Copyright 2019 Fortinet, Inc.
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with Ansible. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# Make coding more python3-ish
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
import pytest
|
||||||
|
from mock import ANY
|
||||||
|
from units.modules.utils import exit_json, fail_json
|
||||||
|
from units.compat import unittest
|
||||||
|
from units.compat.mock import patch
|
||||||
|
from ansible.module_utils import basic
|
||||||
|
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
|
||||||
|
|
||||||
|
try:
|
||||||
|
from ansible.module_utils.network.fortios.facts.facts import Facts
|
||||||
|
from ansible.modules.network.fortios import fortios_facts
|
||||||
|
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_facts.Connection')
|
||||||
|
return connection_class_mock
|
||||||
|
|
||||||
|
|
||||||
|
fos_instance = FortiOSHandler(connection_mock)
|
||||||
|
|
||||||
|
|
||||||
|
def test_facts_get(mocker):
|
||||||
|
monitor_method_result = {'status': 'success', 'http_method': 'GET', 'http_status': 200}
|
||||||
|
monitor_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.monitor', return_value=monitor_method_result)
|
||||||
|
mock_module = patch.multiple(basic.AnsibleModule, exit_json=exit_json, fail_json=fail_json)
|
||||||
|
mock_module._connection = connection_mock
|
||||||
|
|
||||||
|
# test case 01, args with single gather_subset
|
||||||
|
args = {
|
||||||
|
'vdom': 'root',
|
||||||
|
'gather_subset': [
|
||||||
|
{'fact': 'system_status_select'},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
mock_module.params = args
|
||||||
|
|
||||||
|
response, ignore = Facts(mock_module, fos_instance).get_facts()
|
||||||
|
|
||||||
|
monitor_method_mock.assert_called_with('system', 'status/select', vdom='root')
|
||||||
|
assert response['ansible_network_resources']['system_status_select']['status'] == 'success'
|
||||||
|
assert response['ansible_network_resources']['system_status_select']['http_status'] == 200
|
||||||
|
|
||||||
|
# test case 02, args with single gather_subset with filters
|
||||||
|
args = {
|
||||||
|
'vdom': 'root',
|
||||||
|
'gather_subset': [
|
||||||
|
{'fact': 'system_interface_select', 'filters': [{'include_vlan': 'true'}, {'interface_name': 'port3'}]},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
mock_module.params = args
|
||||||
|
|
||||||
|
response, ignore = Facts(mock_module, fos_instance).get_facts()
|
||||||
|
|
||||||
|
monitor_method_mock.assert_called_with('system', 'interface/select?vdom=root&include_vlan=true&interface_name=port3', vdom=None)
|
||||||
|
assert response['ansible_network_resources']['system_interface_select']['status'] == 'success'
|
||||||
|
assert response['ansible_network_resources']['system_interface_select']['http_status'] == 200
|
||||||
|
|
||||||
|
# test case 03, args with multiple gather_subset
|
||||||
|
args = {
|
||||||
|
'vdom': 'root',
|
||||||
|
'gather_subset': [
|
||||||
|
{'fact': 'system_current-admins_select'},
|
||||||
|
{'fact': 'system_firmware_select'},
|
||||||
|
{'fact': 'system_fortimanager_status'},
|
||||||
|
{'fact': 'system_ha-checksums_select'},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
mock_module.params = args
|
||||||
|
|
||||||
|
response, ignore = Facts(mock_module, fos_instance).get_facts()
|
||||||
|
|
||||||
|
monitor_method_mock.assert_any_call('system', 'current-admins/select', vdom='root')
|
||||||
|
monitor_method_mock.assert_any_call('system', 'firmware/select', vdom='root')
|
||||||
|
monitor_method_mock.assert_any_call('system', 'fortimanager/status', vdom='root')
|
||||||
|
monitor_method_mock.assert_any_call('system', 'ha-checksums/select', vdom='root')
|
||||||
|
assert response['ansible_network_resources']['system_ha-checksums_select']['status'] == 'success'
|
||||||
|
assert response['ansible_network_resources']['system_ha-checksums_select']['http_status'] == 200
|
Loading…
Reference in a new issue