From 421a5c4c91ede5899cd1846b677417d2f4c98905 Mon Sep 17 00:00:00 2001
From: ftntcorecse <43451990+ftntcorecse@users.noreply.github.com>
Date: Mon, 4 Mar 2019 05:49:50 -0500
Subject: [PATCH] New FortiManager Module: fmgr_secprof_voip (#53030)
* Auto Commit for: fmgr_secprof_voip
* Auto Commit for: fmgr_secprof_voip
---
.../network/fortimanager/fmgr_secprof_voip.py | 1203 +++++++++++++++++
.../fixtures/test_fmgr_secprof_voip.json | 257 ++++
.../fortimanager/test_fmgr_secprof_voip.py | 72 +
3 files changed, 1532 insertions(+)
create mode 100644 lib/ansible/modules/network/fortimanager/fmgr_secprof_voip.py
create mode 100644 test/units/modules/network/fortimanager/fixtures/test_fmgr_secprof_voip.json
create mode 100644 test/units/modules/network/fortimanager/test_fmgr_secprof_voip.py
diff --git a/lib/ansible/modules/network/fortimanager/fmgr_secprof_voip.py b/lib/ansible/modules/network/fortimanager/fmgr_secprof_voip.py
new file mode 100644
index 00000000000..8bad1c8e500
--- /dev/null
+++ b/lib/ansible/modules/network/fortimanager/fmgr_secprof_voip.py
@@ -0,0 +1,1203 @@
+#!/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_voip
+version_added: "2.8"
+notes:
+ - Full Documentation at U(https://ftnt-ansible-docs.readthedocs.io/en/latest/).
+author:
+ - Luke Weighall (@lweighall)
+ - Andrew Welsh (@Ghilli3)
+ - Jim Huber (@p4r4n0y1ng)
+short_description: VOIP security profiles in FMG
+description:
+ - Manage VOIP security profiles in FortiManager via API
+
+options:
+ adom:
+ description:
+ - The ADOM the configuration should belong to.
+ required: false
+ default: root
+
+ 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
+
+ name:
+ description:
+ - Profile name.
+ required: false
+
+ comment:
+ description:
+ - Comment.
+ required: false
+
+ sccp:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ sccp_block_mcast:
+ description:
+ - Enable/disable block multicast RTP connections.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sccp_log_call_summary:
+ description:
+ - Enable/disable log summary of SCCP calls.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sccp_log_violations:
+ description:
+ - Enable/disable logging of SCCP violations.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sccp_max_calls:
+ description:
+ - Maximum calls per minute per SCCP client (max 65535).
+ required: false
+
+ sccp_status:
+ description:
+ - Enable/disable SCCP.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sccp_verify_header:
+ description:
+ - Enable/disable verify SCCP header content.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ sip_ack_rate:
+ description:
+ - ACK request rate limit (per second, per policy).
+ required: false
+
+ sip_block_ack:
+ description:
+ - Enable/disable block ACK requests.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_block_bye:
+ description:
+ - Enable/disable block BYE requests.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_block_cancel:
+ description:
+ - Enable/disable block CANCEL requests.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_block_geo_red_options:
+ description:
+ - Enable/disable block OPTIONS requests, but OPTIONS requests still notify for redundancy.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_block_info:
+ description:
+ - Enable/disable block INFO requests.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_block_invite:
+ description:
+ - Enable/disable block INVITE requests.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_block_long_lines:
+ description:
+ - Enable/disable block requests with headers exceeding max-line-length.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_block_message:
+ description:
+ - Enable/disable block MESSAGE requests.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_block_notify:
+ description:
+ - Enable/disable block NOTIFY requests.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_block_options:
+ description:
+ - Enable/disable block OPTIONS requests and no OPTIONS as notifying message for redundancy either.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_block_prack:
+ description:
+ - Enable/disable block prack requests.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_block_publish:
+ description:
+ - Enable/disable block PUBLISH requests.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_block_refer:
+ description:
+ - Enable/disable block REFER requests.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_block_register:
+ description:
+ - Enable/disable block REGISTER requests.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_block_subscribe:
+ description:
+ - Enable/disable block SUBSCRIBE requests.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_block_unknown:
+ description:
+ - Block unrecognized SIP requests (enabled by default).
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_block_update:
+ description:
+ - Enable/disable block UPDATE requests.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_bye_rate:
+ description:
+ - BYE request rate limit (per second, per policy).
+ required: false
+
+ sip_call_keepalive:
+ description:
+ - Continue tracking calls with no RTP for this many minutes.
+ required: false
+
+ sip_cancel_rate:
+ description:
+ - CANCEL request rate limit (per second, per policy).
+ required: false
+
+ sip_contact_fixup:
+ description:
+ - Fixup contact anyway even if contact's IP|port doesn't match session's IP|port.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_hnt_restrict_source_ip:
+ description:
+ - Enable/disable restrict RTP source IP to be the same as SIP source IP when HNT is enabled.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_hosted_nat_traversal:
+ description:
+ - Hosted NAT Traversal (HNT).
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_info_rate:
+ description:
+ - INFO request rate limit (per second, per policy).
+ required: false
+
+ sip_invite_rate:
+ description:
+ - INVITE request rate limit (per second, per policy).
+ required: false
+
+ sip_ips_rtp:
+ description:
+ - Enable/disable allow IPS on RTP.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_log_call_summary:
+ description:
+ - Enable/disable logging of SIP call summary.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_log_violations:
+ description:
+ - Enable/disable logging of SIP violations.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_malformed_header_allow:
+ description:
+ - Action for malformed Allow header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_call_id:
+ description:
+ - Action for malformed Call-ID header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_contact:
+ description:
+ - Action for malformed Contact header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_content_length:
+ description:
+ - Action for malformed Content-Length header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_content_type:
+ description:
+ - Action for malformed Content-Type header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_cseq:
+ description:
+ - Action for malformed CSeq header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_expires:
+ description:
+ - Action for malformed Expires header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_from:
+ description:
+ - Action for malformed From header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_max_forwards:
+ description:
+ - Action for malformed Max-Forwards header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_p_asserted_identity:
+ description:
+ - Action for malformed P-Asserted-Identity header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_rack:
+ description:
+ - Action for malformed RAck header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_record_route:
+ description:
+ - Action for malformed Record-Route header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_route:
+ description:
+ - Action for malformed Route header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_rseq:
+ description:
+ - Action for malformed RSeq header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_sdp_a:
+ description:
+ - Action for malformed SDP a line.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_sdp_b:
+ description:
+ - Action for malformed SDP b line.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_sdp_c:
+ description:
+ - Action for malformed SDP c line.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_sdp_i:
+ description:
+ - Action for malformed SDP i line.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_sdp_k:
+ description:
+ - Action for malformed SDP k line.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_sdp_m:
+ description:
+ - Action for malformed SDP m line.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_sdp_o:
+ description:
+ - Action for malformed SDP o line.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_sdp_r:
+ description:
+ - Action for malformed SDP r line.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_sdp_s:
+ description:
+ - Action for malformed SDP s line.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_sdp_t:
+ description:
+ - Action for malformed SDP t line.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_sdp_v:
+ description:
+ - Action for malformed SDP v line.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_sdp_z:
+ description:
+ - Action for malformed SDP z line.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_to:
+ description:
+ - Action for malformed To header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_via:
+ description:
+ - Action for malformed VIA header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_request_line:
+ description:
+ - Action for malformed request line.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_max_body_length:
+ description:
+ - Maximum SIP message body length (0 meaning no limit).
+ required: false
+
+ sip_max_dialogs:
+ description:
+ - Maximum number of concurrent calls/dialogs (per policy).
+ required: false
+
+ sip_max_idle_dialogs:
+ description:
+ - Maximum number established but idle dialogs to retain (per policy).
+ required: false
+
+ sip_max_line_length:
+ description:
+ - Maximum SIP header line length (78-4096).
+ required: false
+
+ sip_message_rate:
+ description:
+ - MESSAGE request rate limit (per second, per policy).
+ required: false
+
+ sip_nat_trace:
+ description:
+ - Enable/disable preservation of original IP in SDP i line.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_no_sdp_fixup:
+ description:
+ - Enable/disable no SDP fix-up.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_notify_rate:
+ description:
+ - NOTIFY request rate limit (per second, per policy).
+ required: false
+
+ sip_open_contact_pinhole:
+ description:
+ - Enable/disable open pinhole for non-REGISTER Contact port.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_open_record_route_pinhole:
+ description:
+ - Enable/disable open pinhole for Record-Route port.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_open_register_pinhole:
+ description:
+ - Enable/disable open pinhole for REGISTER Contact port.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_open_via_pinhole:
+ description:
+ - Enable/disable open pinhole for Via port.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_options_rate:
+ description:
+ - OPTIONS request rate limit (per second, per policy).
+ required: false
+
+ sip_prack_rate:
+ description:
+ - PRACK request rate limit (per second, per policy).
+ required: false
+
+ sip_preserve_override:
+ description:
+ - Override i line to preserve original IPS (default| append).
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_provisional_invite_expiry_time:
+ description:
+ - Expiry time for provisional INVITE (10 - 3600 sec).
+ required: false
+
+ sip_publish_rate:
+ description:
+ - PUBLISH request rate limit (per second, per policy).
+ required: false
+
+ sip_refer_rate:
+ description:
+ - REFER request rate limit (per second, per policy).
+ required: false
+
+ sip_register_contact_trace:
+ description:
+ - Enable/disable trace original IP/port within the contact header of REGISTER requests.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_register_rate:
+ description:
+ - REGISTER request rate limit (per second, per policy).
+ required: false
+
+ sip_rfc2543_branch:
+ description:
+ - Enable/disable support via branch compliant with RFC 2543.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_rtp:
+ description:
+ - Enable/disable create pinholes for RTP traffic to traverse firewall.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_ssl_algorithm:
+ description:
+ - Relative strength of encryption algorithms accepted in negotiation.
+ - choice | high | High encryption. Allow only AES and ChaCha.
+ - choice | medium | Medium encryption. Allow AES, ChaCha, 3DES, and RC4.
+ - choice | low | Low encryption. Allow AES, ChaCha, 3DES, RC4, and DES.
+ required: false
+ choices: ["high", "medium", "low"]
+
+ sip_ssl_auth_client:
+ description:
+ - Require a client certificate and authenticate it with the peer/peergrp.
+ required: false
+
+ sip_ssl_auth_server:
+ description:
+ - Authenticate the server's certificate with the peer/peergrp.
+ required: false
+
+ sip_ssl_client_certificate:
+ description:
+ - Name of Certificate to offer to server if requested.
+ required: false
+
+ sip_ssl_client_renegotiation:
+ description:
+ - Allow/block client renegotiation by server.
+ - choice | allow | Allow a SSL client to renegotiate.
+ - choice | deny | Abort any SSL connection that attempts to renegotiate.
+ - choice | secure | Reject any SSL connection that does not offer a RFC 5746 Secure Renegotiation Indication.
+ required: false
+ choices: ["allow", "deny", "secure"]
+
+ sip_ssl_max_version:
+ description:
+ - Highest SSL/TLS version to negotiate.
+ - choice | ssl-3.0 | SSL 3.0.
+ - choice | tls-1.0 | TLS 1.0.
+ - choice | tls-1.1 | TLS 1.1.
+ - choice | tls-1.2 | TLS 1.2.
+ required: false
+ choices: ["ssl-3.0", "tls-1.0", "tls-1.1", "tls-1.2"]
+
+ sip_ssl_min_version:
+ description:
+ - Lowest SSL/TLS version to negotiate.
+ - choice | ssl-3.0 | SSL 3.0.
+ - choice | tls-1.0 | TLS 1.0.
+ - choice | tls-1.1 | TLS 1.1.
+ - choice | tls-1.2 | TLS 1.2.
+ required: false
+ choices: ["ssl-3.0", "tls-1.0", "tls-1.1", "tls-1.2"]
+
+ sip_ssl_mode:
+ description:
+ - SSL/TLS mode for encryption & decryption of traffic.
+ - choice | off | No SSL.
+ - choice | full | Client to FortiGate and FortiGate to Server SSL.
+ required: false
+ choices: ["off", "full"]
+
+ sip_ssl_pfs:
+ description:
+ - SSL Perfect Forward Secrecy.
+ - choice | require | PFS mandatory.
+ - choice | deny | PFS rejected.
+ - choice | allow | PFS allowed.
+ required: false
+ choices: ["require", "deny", "allow"]
+
+ sip_ssl_send_empty_frags:
+ description:
+ - Send empty fragments to avoid attack on CBC IV (SSL 3.0 & TLS 1.0 only).
+ - choice | disable | Do not send empty fragments.
+ - choice | enable | Send empty fragments.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_ssl_server_certificate:
+ description:
+ - Name of Certificate return to the client in every SSL connection.
+ required: false
+
+ sip_status:
+ description:
+ - Enable/disable SIP.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_strict_register:
+ description:
+ - Enable/disable only allow the registrar to connect.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_subscribe_rate:
+ description:
+ - SUBSCRIBE request rate limit (per second, per policy).
+ required: false
+
+ sip_unknown_header:
+ description:
+ - Action for unknown SIP header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_update_rate:
+ description:
+ - UPDATE request rate limit (per second, per policy).
+ required: false
+
+
+'''
+
+EXAMPLES = '''
+ - name: DELETE Profile
+ fmgr_secprof_voip:
+ name: "Ansible_VOIP_Profile"
+ mode: "delete"
+
+ - name: Create FMGR_VOIP_PROFILE
+ fmgr_secprof_voip:
+ mode: "set"
+ adom: "root"
+ name: "Ansible_VOIP_Profile"
+ comment: "Created by Ansible"
+ sccp: {block-mcast: "enable", log-call-summary: "enable", log-violations: "enable", status: "enable"}
+'''
+
+RETURN = """
+api_result:
+ description: full API response, includes status code and message
+ returned: always
+ type: str
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.connection import Connection
+from ansible.module_utils.network.fortimanager.fortimanager import FortiManagerHandler
+from ansible.module_utils.network.fortimanager.common import FMGBaseException
+from ansible.module_utils.network.fortimanager.common import FMGRCommon
+from ansible.module_utils.network.fortimanager.common import DEFAULT_RESULT_OBJ
+from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
+from ansible.module_utils.network.fortimanager.common import prepare_dict
+from ansible.module_utils.network.fortimanager.common import scrub_dict
+
+
+###############
+# START METHODS
+###############
+
+
+def fmgr_voip_profile_modify(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+
+ mode = paramgram["mode"]
+ adom = paramgram["adom"]
+
+ response = DEFAULT_RESULT_OBJ
+ url = ""
+ datagram = {}
+
+ # EVAL THE MODE PARAMETER FOR SET OR ADD
+ if mode in ['set', 'add', 'update']:
+ url = '/pm/config/adom/{adom}/obj/voip/profile'.format(adom=adom)
+ datagram = scrub_dict(prepare_dict(paramgram))
+
+ # EVAL THE MODE PARAMETER FOR DELETE
+ elif mode == "delete":
+ # SET THE CORRECT URL FOR DELETE
+ url = '/pm/config/adom/{adom}/obj/voip/profile/{name}'.format(adom=adom, name=paramgram["name"])
+ datagram = {}
+
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+
+ return response
+
+
+#############
+# END METHODS
+#############
+
+
+def main():
+ argument_spec = dict(
+ adom=dict(type="str", default="root"),
+ mode=dict(choices=["add", "set", "delete", "update"], type="str", default="add"),
+
+ name=dict(required=False, type="str"),
+ comment=dict(required=False, type="str"),
+ sccp=dict(required=False, type="dict"),
+ sccp_block_mcast=dict(required=False, type="str", choices=["disable", "enable"]),
+ sccp_log_call_summary=dict(required=False, type="str", choices=["disable", "enable"]),
+ sccp_log_violations=dict(required=False, type="str", choices=["disable", "enable"]),
+ sccp_max_calls=dict(required=False, type="int"),
+ sccp_status=dict(required=False, type="str", choices=["disable", "enable"]),
+ sccp_verify_header=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip=dict(required=False, type="dict"),
+ sip_ack_rate=dict(required=False, type="int"),
+ sip_block_ack=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_block_bye=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_block_cancel=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_block_geo_red_options=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_block_info=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_block_invite=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_block_long_lines=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_block_message=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_block_notify=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_block_options=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_block_prack=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_block_publish=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_block_refer=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_block_register=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_block_subscribe=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_block_unknown=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_block_update=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_bye_rate=dict(required=False, type="int"),
+ sip_call_keepalive=dict(required=False, type="int"),
+ sip_cancel_rate=dict(required=False, type="int"),
+ sip_contact_fixup=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_hnt_restrict_source_ip=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_hosted_nat_traversal=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_info_rate=dict(required=False, type="int"),
+ sip_invite_rate=dict(required=False, type="int"),
+ sip_ips_rtp=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_log_call_summary=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_log_violations=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_malformed_header_allow=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_call_id=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_contact=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_content_length=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_content_type=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_cseq=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_expires=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_from=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_max_forwards=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_p_asserted_identity=dict(required=False, type="str", choices=["pass",
+ "discard",
+ "respond"]),
+ sip_malformed_header_rack=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_record_route=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_route=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_rseq=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_sdp_a=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_sdp_b=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_sdp_c=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_sdp_i=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_sdp_k=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_sdp_m=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_sdp_o=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_sdp_r=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_sdp_s=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_sdp_t=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_sdp_v=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_sdp_z=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_to=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_via=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_request_line=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_max_body_length=dict(required=False, type="int"),
+ sip_max_dialogs=dict(required=False, type="int"),
+ sip_max_idle_dialogs=dict(required=False, type="int"),
+ sip_max_line_length=dict(required=False, type="int"),
+ sip_message_rate=dict(required=False, type="int"),
+ sip_nat_trace=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_no_sdp_fixup=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_notify_rate=dict(required=False, type="int"),
+ sip_open_contact_pinhole=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_open_record_route_pinhole=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_open_register_pinhole=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_open_via_pinhole=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_options_rate=dict(required=False, type="int"),
+ sip_prack_rate=dict(required=False, type="int"),
+ sip_preserve_override=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_provisional_invite_expiry_time=dict(required=False, type="int"),
+ sip_publish_rate=dict(required=False, type="int"),
+ sip_refer_rate=dict(required=False, type="int"),
+ sip_register_contact_trace=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_register_rate=dict(required=False, type="int"),
+ sip_rfc2543_branch=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_rtp=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_ssl_algorithm=dict(required=False, type="str", choices=["high", "medium", "low"]),
+ sip_ssl_auth_client=dict(required=False, type="str"),
+ sip_ssl_auth_server=dict(required=False, type="str"),
+ sip_ssl_client_certificate=dict(required=False, type="str"),
+ sip_ssl_client_renegotiation=dict(required=False, type="str", choices=["allow", "deny", "secure"]),
+ sip_ssl_max_version=dict(required=False, type="str", choices=["ssl-3.0", "tls-1.0", "tls-1.1", "tls-1.2"]),
+ sip_ssl_min_version=dict(required=False, type="str", choices=["ssl-3.0", "tls-1.0", "tls-1.1", "tls-1.2"]),
+ sip_ssl_mode=dict(required=False, type="str", choices=["off", "full"]),
+ sip_ssl_pfs=dict(required=False, type="str", choices=["require", "deny", "allow"]),
+ sip_ssl_send_empty_frags=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_ssl_server_certificate=dict(required=False, type="str"),
+ sip_status=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_strict_register=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_subscribe_rate=dict(required=False, type="int"),
+ sip_unknown_header=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_update_rate=dict(required=False, type="int"),
+
+ )
+
+ module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, )
+ # MODULE PARAMGRAM
+ paramgram = {
+ "mode": module.params["mode"],
+ "adom": module.params["adom"],
+ "name": module.params["name"],
+ "comment": module.params["comment"],
+ "sccp": {
+ "block-mcast": module.params["sccp_block_mcast"],
+ "log-call-summary": module.params["sccp_log_call_summary"],
+ "log-violations": module.params["sccp_log_violations"],
+ "max-calls": module.params["sccp_max_calls"],
+ "status": module.params["sccp_status"],
+ "verify-header": module.params["sccp_verify_header"],
+ },
+ "sip": {
+ "ack-rate": module.params["sip_ack_rate"],
+ "block-ack": module.params["sip_block_ack"],
+ "block-bye": module.params["sip_block_bye"],
+ "block-cancel": module.params["sip_block_cancel"],
+ "block-geo-red-options": module.params["sip_block_geo_red_options"],
+ "block-info": module.params["sip_block_info"],
+ "block-invite": module.params["sip_block_invite"],
+ "block-long-lines": module.params["sip_block_long_lines"],
+ "block-message": module.params["sip_block_message"],
+ "block-notify": module.params["sip_block_notify"],
+ "block-options": module.params["sip_block_options"],
+ "block-prack": module.params["sip_block_prack"],
+ "block-publish": module.params["sip_block_publish"],
+ "block-refer": module.params["sip_block_refer"],
+ "block-register": module.params["sip_block_register"],
+ "block-subscribe": module.params["sip_block_subscribe"],
+ "block-unknown": module.params["sip_block_unknown"],
+ "block-update": module.params["sip_block_update"],
+ "bye-rate": module.params["sip_bye_rate"],
+ "call-keepalive": module.params["sip_call_keepalive"],
+ "cancel-rate": module.params["sip_cancel_rate"],
+ "contact-fixup": module.params["sip_contact_fixup"],
+ "hnt-restrict-source-ip": module.params["sip_hnt_restrict_source_ip"],
+ "hosted-nat-traversal": module.params["sip_hosted_nat_traversal"],
+ "info-rate": module.params["sip_info_rate"],
+ "invite-rate": module.params["sip_invite_rate"],
+ "ips-rtp": module.params["sip_ips_rtp"],
+ "log-call-summary": module.params["sip_log_call_summary"],
+ "log-violations": module.params["sip_log_violations"],
+ "malformed-header-allow": module.params["sip_malformed_header_allow"],
+ "malformed-header-call-id": module.params["sip_malformed_header_call_id"],
+ "malformed-header-contact": module.params["sip_malformed_header_contact"],
+ "malformed-header-content-length": module.params["sip_malformed_header_content_length"],
+ "malformed-header-content-type": module.params["sip_malformed_header_content_type"],
+ "malformed-header-cseq": module.params["sip_malformed_header_cseq"],
+ "malformed-header-expires": module.params["sip_malformed_header_expires"],
+ "malformed-header-from": module.params["sip_malformed_header_from"],
+ "malformed-header-max-forwards": module.params["sip_malformed_header_max_forwards"],
+ "malformed-header-p-asserted-identity": module.params["sip_malformed_header_p_asserted_identity"],
+ "malformed-header-rack": module.params["sip_malformed_header_rack"],
+ "malformed-header-record-route": module.params["sip_malformed_header_record_route"],
+ "malformed-header-route": module.params["sip_malformed_header_route"],
+ "malformed-header-rseq": module.params["sip_malformed_header_rseq"],
+ "malformed-header-sdp-a": module.params["sip_malformed_header_sdp_a"],
+ "malformed-header-sdp-b": module.params["sip_malformed_header_sdp_b"],
+ "malformed-header-sdp-c": module.params["sip_malformed_header_sdp_c"],
+ "malformed-header-sdp-i": module.params["sip_malformed_header_sdp_i"],
+ "malformed-header-sdp-k": module.params["sip_malformed_header_sdp_k"],
+ "malformed-header-sdp-m": module.params["sip_malformed_header_sdp_m"],
+ "malformed-header-sdp-o": module.params["sip_malformed_header_sdp_o"],
+ "malformed-header-sdp-r": module.params["sip_malformed_header_sdp_r"],
+ "malformed-header-sdp-s": module.params["sip_malformed_header_sdp_s"],
+ "malformed-header-sdp-t": module.params["sip_malformed_header_sdp_t"],
+ "malformed-header-sdp-v": module.params["sip_malformed_header_sdp_v"],
+ "malformed-header-sdp-z": module.params["sip_malformed_header_sdp_z"],
+ "malformed-header-to": module.params["sip_malformed_header_to"],
+ "malformed-header-via": module.params["sip_malformed_header_via"],
+ "malformed-request-line": module.params["sip_malformed_request_line"],
+ "max-body-length": module.params["sip_max_body_length"],
+ "max-dialogs": module.params["sip_max_dialogs"],
+ "max-idle-dialogs": module.params["sip_max_idle_dialogs"],
+ "max-line-length": module.params["sip_max_line_length"],
+ "message-rate": module.params["sip_message_rate"],
+ "nat-trace": module.params["sip_nat_trace"],
+ "no-sdp-fixup": module.params["sip_no_sdp_fixup"],
+ "notify-rate": module.params["sip_notify_rate"],
+ "open-contact-pinhole": module.params["sip_open_contact_pinhole"],
+ "open-record-route-pinhole": module.params["sip_open_record_route_pinhole"],
+ "open-register-pinhole": module.params["sip_open_register_pinhole"],
+ "open-via-pinhole": module.params["sip_open_via_pinhole"],
+ "options-rate": module.params["sip_options_rate"],
+ "prack-rate": module.params["sip_prack_rate"],
+ "preserve-override": module.params["sip_preserve_override"],
+ "provisional-invite-expiry-time": module.params["sip_provisional_invite_expiry_time"],
+ "publish-rate": module.params["sip_publish_rate"],
+ "refer-rate": module.params["sip_refer_rate"],
+ "register-contact-trace": module.params["sip_register_contact_trace"],
+ "register-rate": module.params["sip_register_rate"],
+ "rfc2543-branch": module.params["sip_rfc2543_branch"],
+ "rtp": module.params["sip_rtp"],
+ "ssl-algorithm": module.params["sip_ssl_algorithm"],
+ "ssl-auth-client": module.params["sip_ssl_auth_client"],
+ "ssl-auth-server": module.params["sip_ssl_auth_server"],
+ "ssl-client-certificate": module.params["sip_ssl_client_certificate"],
+ "ssl-client-renegotiation": module.params["sip_ssl_client_renegotiation"],
+ "ssl-max-version": module.params["sip_ssl_max_version"],
+ "ssl-min-version": module.params["sip_ssl_min_version"],
+ "ssl-mode": module.params["sip_ssl_mode"],
+ "ssl-pfs": module.params["sip_ssl_pfs"],
+ "ssl-send-empty-frags": module.params["sip_ssl_send_empty_frags"],
+ "ssl-server-certificate": module.params["sip_ssl_server_certificate"],
+ "status": module.params["sip_status"],
+ "strict-register": module.params["sip_strict_register"],
+ "subscribe-rate": module.params["sip_subscribe_rate"],
+ "unknown-header": module.params["sip_unknown_header"],
+ "update-rate": module.params["sip_update_rate"],
+ }
+ }
+
+ module.paramgram = paramgram
+ fmgr = None
+ if module._socket_path:
+ connection = Connection(module._socket_path)
+ fmgr = FortiManagerHandler(connection, module)
+ fmgr.tools = FMGRCommon()
+ else:
+ module.fail_json(**FAIL_SOCKET_MSG)
+
+ list_overrides = ['sccp', 'sip']
+ paramgram = fmgr.tools.paramgram_child_list_override(list_overrides=list_overrides,
+ paramgram=paramgram, module=module)
+ module.paramgram = paramgram
+
+ results = DEFAULT_RESULT_OBJ
+ try:
+
+ results = fmgr_voip_profile_modify(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ return module.exit_json(**results[1])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/test/units/modules/network/fortimanager/fixtures/test_fmgr_secprof_voip.json b/test/units/modules/network/fortimanager/fixtures/test_fmgr_secprof_voip.json
new file mode 100644
index 00000000000..3513e14f712
--- /dev/null
+++ b/test/units/modules/network/fortimanager/fixtures/test_fmgr_secprof_voip.json
@@ -0,0 +1,257 @@
+{
+ "fmgr_voip_profile_modify": [
+ {
+ "paramgram_used": {
+ "comment": null,
+ "sip": {
+ "block-publish": null,
+ "ssl-max-version": null,
+ "malformed-header-rack": null,
+ "rtp": null,
+ "publish-rate": null,
+ "ssl-client-renegotiation": null,
+ "malformed-header-from": null,
+ "open-contact-pinhole": null,
+ "ssl-client-certificate": null,
+ "malformed-header-p-asserted-identity": null,
+ "rfc2543-branch": null,
+ "malformed-header-via": null,
+ "notify-rate": null,
+ "preserve-override": null,
+ "block-info": null,
+ "options-rate": null,
+ "block-update": null,
+ "max-body-length": null,
+ "block-subscribe": null,
+ "ssl-pfs": null,
+ "ssl-send-empty-frags": null,
+ "ssl-auth-client": null,
+ "malformed-header-record-route": null,
+ "refer-rate": null,
+ "info-rate": null,
+ "open-record-route-pinhole": null,
+ "register-rate": null,
+ "unknown-header": null,
+ "block-unknown": null,
+ "ssl-server-certificate": null,
+ "block-invite": null,
+ "strict-register": null,
+ "max-dialogs": null,
+ "block-cancel": null,
+ "no-sdp-fixup": null,
+ "open-register-pinhole": null,
+ "block-notify": null,
+ "max-idle-dialogs": null,
+ "malformed-request-line": null,
+ "block-long-lines": null,
+ "log-violations": null,
+ "ssl-min-version": null,
+ "provisional-invite-expiry-time": null,
+ "block-prack": null,
+ "malformed-header-max-forwards": null,
+ "block-message": null,
+ "malformed-header-call-id": null,
+ "invite-rate": null,
+ "cancel-rate": null,
+ "register-contact-trace": null,
+ "block-register": null,
+ "ssl-mode": null,
+ "prack-rate": null,
+ "block-bye": null,
+ "ssl-algorithm": null,
+ "malformed-header-to": null,
+ "block-geo-red-options": null,
+ "call-keepalive": null,
+ "message-rate": null,
+ "malformed-header-expires": null,
+ "block-options": null,
+ "log-call-summary": null,
+ "hnt-restrict-source-ip": null,
+ "ssl-auth-server": null,
+ "contact-fixup": null,
+ "ack-rate": null,
+ "malformed-header-allow": null,
+ "malformed-header-sdp-v": null,
+ "malformed-header-sdp-t": null,
+ "malformed-header-contact": null,
+ "malformed-header-sdp-s": null,
+ "hosted-nat-traversal": null,
+ "subscribe-rate": null,
+ "malformed-header-content-length": null,
+ "malformed-header-sdp-z": null,
+ "malformed-header-route": null,
+ "malformed-header-sdp-b": null,
+ "malformed-header-sdp-c": null,
+ "malformed-header-sdp-a": null,
+ "malformed-header-sdp-o": null,
+ "malformed-header-sdp-m": null,
+ "malformed-header-sdp-k": null,
+ "malformed-header-sdp-i": null,
+ "status": null,
+ "open-via-pinhole": null,
+ "bye-rate": null,
+ "block-ack": null,
+ "malformed-header-sdp-r": null,
+ "block-refer": null,
+ "ips-rtp": null,
+ "malformed-header-content-type": null,
+ "nat-trace": null,
+ "malformed-header-rseq": null,
+ "max-line-length": null,
+ "update-rate": null,
+ "malformed-header-cseq": null
+ },
+ "name": "Ansible_VOIP_Profile",
+ "adom": "root",
+ "sccp": {
+ "status": null,
+ "log-call-summary": null,
+ "block-mcast": null,
+ "max-calls": null,
+ "verify-header": null,
+ "log-violations": null
+ },
+ "mode": "delete"
+ },
+ "datagram_sent": {},
+ "raw_response": {
+ "status": {
+ "message": "OK",
+ "code": 0
+ },
+ "url": "/pm/config/adom/root/obj/voip/profile/Ansible_VOIP_Profile"
+ },
+ "post_method": "delete"
+ },
+ {
+ "raw_response": {
+ "status": {
+ "message": "OK",
+ "code": 0
+ },
+ "url": "/pm/config/adom/root/obj/voip/profile"
+ },
+ "datagram_sent": {
+ "comment": "Created by Ansible",
+ "sccp": {
+ "status": "enable",
+ "log-call-summary": "enable",
+ "log-violations": "enable",
+ "block-mcast": "enable"
+ },
+ "name": "Ansible_VOIP_Profile"
+ },
+ "paramgram_used": {
+ "comment": "Created by Ansible",
+ "sip": {
+ "block-publish": null,
+ "ssl-max-version": null,
+ "malformed-header-rack": null,
+ "rtp": null,
+ "publish-rate": null,
+ "ssl-client-renegotiation": null,
+ "malformed-header-from": null,
+ "ssl-client-certificate": null,
+ "malformed-header-p-asserted-identity": null,
+ "info-rate": null,
+ "malformed-header-via": null,
+ "notify-rate": null,
+ "preserve-override": null,
+ "block-info": null,
+ "options-rate": null,
+ "block-update": null,
+ "max-body-length": null,
+ "block-subscribe": null,
+ "ssl-pfs": null,
+ "ssl-send-empty-frags": null,
+ "ssl-auth-client": null,
+ "malformed-header-record-route": null,
+ "refer-rate": null,
+ "open-record-route-pinhole": null,
+ "register-rate": null,
+ "unknown-header": null,
+ "block-unknown": null,
+ "ssl-server-certificate": null,
+ "block-invite": null,
+ "malformed-request-line": null,
+ "max-dialogs": null,
+ "block-cancel": null,
+ "no-sdp-fixup": null,
+ "open-register-pinhole": null,
+ "block-options": null,
+ "max-idle-dialogs": null,
+ "strict-register": null,
+ "block-long-lines": null,
+ "log-violations": null,
+ "ssl-min-version": null,
+ "provisional-invite-expiry-time": null,
+ "rfc2543-branch": null,
+ "block-ack": null,
+ "malformed-header-max-forwards": null,
+ "block-message": null,
+ "malformed-header-call-id": null,
+ "invite-rate": null,
+ "cancel-rate": null,
+ "register-contact-trace": null,
+ "block-refer": null,
+ "block-register": null,
+ "ssl-mode": null,
+ "prack-rate": null,
+ "block-bye": null,
+ "ssl-algorithm": null,
+ "malformed-header-to": null,
+ "block-geo-red-options": null,
+ "call-keepalive": null,
+ "message-rate": null,
+ "malformed-header-expires": null,
+ "log-call-summary": null,
+ "hnt-restrict-source-ip": null,
+ "ssl-auth-server": null,
+ "contact-fixup": null,
+ "ack-rate": null,
+ "malformed-header-allow": null,
+ "malformed-header-sdp-v": null,
+ "malformed-header-sdp-t": null,
+ "malformed-header-contact": null,
+ "malformed-header-sdp-s": null,
+ "hosted-nat-traversal": null,
+ "subscribe-rate": null,
+ "malformed-header-content-length": null,
+ "malformed-header-sdp-z": null,
+ "malformed-header-route": null,
+ "block-notify": null,
+ "malformed-header-sdp-b": null,
+ "malformed-header-sdp-c": null,
+ "malformed-header-sdp-a": null,
+ "malformed-header-sdp-o": null,
+ "malformed-header-sdp-m": null,
+ "malformed-header-sdp-k": null,
+ "malformed-header-sdp-i": null,
+ "status": null,
+ "open-via-pinhole": null,
+ "bye-rate": null,
+ "block-prack": null,
+ "malformed-header-sdp-r": null,
+ "open-contact-pinhole": null,
+ "ips-rtp": null,
+ "malformed-header-content-type": null,
+ "nat-trace": null,
+ "malformed-header-rseq": null,
+ "max-line-length": null,
+ "update-rate": null,
+ "malformed-header-cseq": null
+ },
+ "name": "Ansible_VOIP_Profile",
+ "adom": "root",
+ "sccp": {
+ "status": "enable",
+ "log-call-summary": "enable",
+ "log-violations": "enable",
+ "block-mcast": "enable"
+ },
+ "mode": "set"
+ },
+ "post_method": "set"
+ }
+ ]
+}
diff --git a/test/units/modules/network/fortimanager/test_fmgr_secprof_voip.py b/test/units/modules/network/fortimanager/test_fmgr_secprof_voip.py
new file mode 100644
index 00000000000..aec91ac22a8
--- /dev/null
+++ b/test/units/modules/network/fortimanager/test_fmgr_secprof_voip.py
@@ -0,0 +1,72 @@
+# 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 ansible.module_utils.network.fortimanager.fortimanager import FortiManagerHandler
+import pytest
+
+try:
+ from ansible.modules.network.fortimanager import fmgr_secprof_voip
+except ImportError:
+ pytest.skip("Could not load required modules for testing", allow_module_level=True)
+
+
+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(autouse=True)
+def module_mock(mocker):
+ connection_class_mock = mocker.patch('ansible.module_utils.basic.AnsibleModule')
+ return connection_class_mock
+
+
+@pytest.fixture(autouse=True)
+def connection_mock(mocker):
+ connection_class_mock = mocker.patch('ansible.modules.network.fortimanager.fmgr_secprof_voip.Connection')
+ return connection_class_mock
+
+
+@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)
+
+
+fmg_instance = FortiManagerHandler(connection_mock, module_mock)
+
+
+def test_fmgr_voip_profile_modify(fixture_data, mocker):
+ mocker.patch("ansible.module_utils.network.fortimanager.fortimanager.FortiManagerHandler.process_request",
+ side_effect=fixture_data)
+
+ # Test using fixture 1 #
+ output = fmgr_secprof_voip.fmgr_voip_profile_modify(fmg_instance, fixture_data[0]['paramgram_used'])
+ assert output['raw_response']['status']['code'] == 0
+ # Test using fixture 2 #
+ output = fmgr_secprof_voip.fmgr_voip_profile_modify(fmg_instance, fixture_data[1]['paramgram_used'])
+ assert output['raw_response']['status']['code'] == 0