summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Rupp <caphrim007@gmail.com>2018-05-10 10:59:49 -0700
committerGitHub <noreply@github.com>2018-05-10 10:59:49 -0700
commit4d691e9d7b5386b29345ca45168d9b4c6caa5d34 (patch)
treebac01541339f54d67b63baa7ec141b4af7514559
parent67f387bc3bf1408a5dcd5e55ce16420a42c652ae (diff)
downloadansible-4d691e9d7b5386b29345ca45168d9b4c6caa5d34.tar.gz
Various fixes and features for bigip modules (#39972)
* Removed forwarders parameter that did not work * Updated coding conventions * Added ssl_cipher_suite and ssl_protocols to bigip_device_httpd * Added more unit tests
-rw-r--r--lib/ansible/modules/network/f5/bigip_device_dns.py29
-rw-r--r--lib/ansible/modules/network/f5/bigip_device_group.py9
-rw-r--r--lib/ansible/modules/network/f5/bigip_device_group_member.py9
-rw-r--r--lib/ansible/modules/network/f5/bigip_device_httpd.py179
-rw-r--r--lib/ansible/modules/network/f5/bigip_device_ntp.py9
-rw-r--r--lib/ansible/modules/network/f5/bigip_device_sshd.py39
-rw-r--r--lib/ansible/modules/network/f5/bigip_device_trust.py11
-rw-r--r--lib/ansible/modules/network/f5/bigip_gtm_datacenter.py9
-rw-r--r--test/units/modules/network/f5/fixtures/load_sys_httpd_non_default.json36
-rw-r--r--test/units/modules/network/f5/test_bigip_device_dns.py17
-rw-r--r--test/units/modules/network/f5/test_bigip_device_group.py6
-rw-r--r--test/units/modules/network/f5/test_bigip_device_group_member.py6
-rw-r--r--test/units/modules/network/f5/test_bigip_device_httpd.py168
-rw-r--r--test/units/modules/network/f5/test_bigip_device_ntp.py6
-rw-r--r--test/units/modules/network/f5/test_bigip_device_sshd.py16
-rw-r--r--test/units/modules/network/f5/test_bigip_device_trust.py26
-rw-r--r--test/units/modules/network/f5/test_bigip_gtm_datacenter.py8
17 files changed, 445 insertions, 138 deletions
diff --git a/lib/ansible/modules/network/f5/bigip_device_dns.py b/lib/ansible/modules/network/f5/bigip_device_dns.py
index 9e5a9f69c0..42aef16b2a 100644
--- a/lib/ansible/modules/network/f5/bigip_device_dns.py
+++ b/lib/ansible/modules/network/f5/bigip_device_dns.py
@@ -18,7 +18,7 @@ module: bigip_device_dns
short_description: Manage BIG-IP device DNS settings
description:
- Manage BIG-IP device DNS settings
-version_added: "2.2"
+version_added: 2.2
options:
cache:
description:
@@ -33,10 +33,6 @@ options:
name_servers:
description:
- A list of name servers that the system uses to validate DNS lookups
- forwarders:
- description:
- - A list of BIND servers that the system can use to perform DNS lookups
- - Deprecated in 2.4. Use the GUI or edit named.conf.
search:
description:
- A list of domains that the system searches for local domain lookups,
@@ -106,30 +102,23 @@ warnings:
from ansible.module_utils.basic import AnsibleModule
-HAS_DEVEL_IMPORTS = False
-
try:
- # Sideband repository used for dev
from library.module_utils.network.f5.bigip import HAS_F5SDK
from library.module_utils.network.f5.bigip import F5Client
from library.module_utils.network.f5.common import F5ModuleError
from library.module_utils.network.f5.common import AnsibleF5Parameters
from library.module_utils.network.f5.common import cleanup_tokens
- from library.module_utils.network.f5.common import fqdn_name
from library.module_utils.network.f5.common import f5_argument_spec
try:
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError
except ImportError:
HAS_F5SDK = False
- HAS_DEVEL_IMPORTS = True
except ImportError:
- # Upstream Ansible
from ansible.module_utils.network.f5.bigip import HAS_F5SDK
from ansible.module_utils.network.f5.bigip import F5Client
from ansible.module_utils.network.f5.common import F5ModuleError
from ansible.module_utils.network.f5.common import AnsibleF5Parameters
from ansible.module_utils.network.f5.common import cleanup_tokens
- from ansible.module_utils.network.f5.common import fqdn_name
from ansible.module_utils.network.f5.common import f5_argument_spec
try:
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError
@@ -199,15 +188,6 @@ class Parameters(AnsibleF5Parameters):
return True if self._values['dhcp'] in valid else False
@property
- def forwarders(self):
- if self._values['forwarders'] is None:
- return None
- else:
- raise F5ModuleError(
- "The modifying of forwarders is not supported."
- )
-
- @property
def ip_version(self):
if self._values['ip_version'] in [6, '6', 'options inet6']:
return "options inet6"
@@ -344,11 +324,6 @@ class ArgumentSpec(object):
default=None,
type='list'
),
- forwarders=dict(
- required=False,
- default=None,
- type='list'
- ),
search=dict(
required=False,
default=None,
@@ -369,7 +344,7 @@ class ArgumentSpec(object):
self.argument_spec.update(f5_argument_spec)
self.argument_spec.update(argument_spec)
self.required_one_of = [
- ['name_servers', 'search', 'forwarders', 'ip_version', 'cache']
+ ['name_servers', 'search', 'ip_version', 'cache']
]
diff --git a/lib/ansible/modules/network/f5/bigip_device_group.py b/lib/ansible/modules/network/f5/bigip_device_group.py
index d270a6202e..7bd9e5dfc9 100644
--- a/lib/ansible/modules/network/f5/bigip_device_group.py
+++ b/lib/ansible/modules/network/f5/bigip_device_group.py
@@ -21,7 +21,7 @@ description:
of BIG-IP devices. Usage of this module should be done in conjunction
with the C(bigip_configsync_actions) to sync configuration across
the pair or cluster if auto-sync is disabled.
-version_added: "2.5"
+version_added: 2.5
options:
name:
description:
@@ -149,30 +149,23 @@ max_incremental_sync_size:
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.parsing.convert_bool import BOOLEANS_TRUE
-HAS_DEVEL_IMPORTS = False
-
try:
- # Sideband repository used for dev
from library.module_utils.network.f5.bigip import HAS_F5SDK
from library.module_utils.network.f5.bigip import F5Client
from library.module_utils.network.f5.common import F5ModuleError
from library.module_utils.network.f5.common import AnsibleF5Parameters
from library.module_utils.network.f5.common import cleanup_tokens
- from library.module_utils.network.f5.common import fqdn_name
from library.module_utils.network.f5.common import f5_argument_spec
try:
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError
except ImportError:
HAS_F5SDK = False
- HAS_DEVEL_IMPORTS = True
except ImportError:
- # Upstream Ansible
from ansible.module_utils.network.f5.bigip import HAS_F5SDK
from ansible.module_utils.network.f5.bigip import F5Client
from ansible.module_utils.network.f5.common import F5ModuleError
from ansible.module_utils.network.f5.common import AnsibleF5Parameters
from ansible.module_utils.network.f5.common import cleanup_tokens
- from ansible.module_utils.network.f5.common import fqdn_name
from ansible.module_utils.network.f5.common import f5_argument_spec
try:
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError
diff --git a/lib/ansible/modules/network/f5/bigip_device_group_member.py b/lib/ansible/modules/network/f5/bigip_device_group_member.py
index b6a1bf912d..dbd6af57b6 100644
--- a/lib/ansible/modules/network/f5/bigip_device_group_member.py
+++ b/lib/ansible/modules/network/f5/bigip_device_group_member.py
@@ -20,7 +20,7 @@ description:
be added or removed, never updated. This is because the members are
identified by unique name values and changing that name would invalidate
the uniqueness.
-version_added: "2.5"
+version_added: 2.5
options:
name:
description:
@@ -77,30 +77,23 @@ RETURN = r'''
from ansible.module_utils.basic import AnsibleModule
-HAS_DEVEL_IMPORTS = False
-
try:
- # Sideband repository used for dev
from library.module_utils.network.f5.bigip import HAS_F5SDK
from library.module_utils.network.f5.bigip import F5Client
from library.module_utils.network.f5.common import F5ModuleError
from library.module_utils.network.f5.common import AnsibleF5Parameters
from library.module_utils.network.f5.common import cleanup_tokens
- from library.module_utils.network.f5.common import fqdn_name
from library.module_utils.network.f5.common import f5_argument_spec
try:
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError
except ImportError:
HAS_F5SDK = False
- HAS_DEVEL_IMPORTS = True
except ImportError:
- # Upstream Ansible
from ansible.module_utils.network.f5.bigip import HAS_F5SDK
from ansible.module_utils.network.f5.bigip import F5Client
from ansible.module_utils.network.f5.common import F5ModuleError
from ansible.module_utils.network.f5.common import AnsibleF5Parameters
from ansible.module_utils.network.f5.common import cleanup_tokens
- from ansible.module_utils.network.f5.common import fqdn_name
from ansible.module_utils.network.f5.common import f5_argument_spec
try:
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError
diff --git a/lib/ansible/modules/network/f5/bigip_device_httpd.py b/lib/ansible/modules/network/f5/bigip_device_httpd.py
index 7c5802e570..c87a0fe3fa 100644
--- a/lib/ansible/modules/network/f5/bigip_device_httpd.py
+++ b/lib/ansible/modules/network/f5/bigip_device_httpd.py
@@ -19,7 +19,7 @@ short_description: Manage HTTPD related settings on BIG-IP
description:
- Manages HTTPD related settings on the BIG-IP. These settings are interesting
to change when you want to set GUI timeouts and other TMUI related settings.
-version_added: "2.5"
+version_added: 2.5
options:
allow:
description:
@@ -64,6 +64,31 @@ options:
ssl_port:
description:
- The HTTPS port to listen on.
+ ssl_cipher_suite:
+ description:
+ - Specifies the ciphers that the system uses.
+ - The values in the suite are separated by colons (:).
+ - Can be specified in either a string or list form. The list form is the
+ recommended way to provide the cipher suite. See examples for usage.
+ - Use the value C(default) to set the cipher suite to the system default.
+ This value is equivalent to specifying a list of C(ECDHE-RSA-AES128-GCM-SHA256,
+ ECDHE-RSA-AES256-GCM-SHA384,ECDHE-RSA-AES128-SHA,ECDHE-RSA-AES256-SHA,
+ ECDHE-RSA-AES128-SHA256,ECDHE-RSA-AES256-SHA384,ECDHE-ECDSA-AES128-GCM-SHA256,
+ ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-ECDSA-AES128-SHA,ECDHE-ECDSA-AES256-SHA,
+ ECDHE-ECDSA-AES128-SHA256,ECDHE-ECDSA-AES256-SHA384,AES128-GCM-SHA256,
+ AES256-GCM-SHA384,AES128-SHA,AES256-SHA,AES128-SHA256,AES256-SHA256,
+ ECDHE-RSA-DES-CBC3-SHA,ECDHE-ECDSA-DES-CBC3-SHA,DES-CBC3-SHA).
+ version_added: 2.6
+ ssl_protocols:
+ description:
+ - The list of SSL protocols to accept on the management console.
+ - A space-separated list of tokens in the format accepted by the Apache
+ mod_ssl SSLProtocol directive.
+ - Can be specified in either a string or list form. The list form is the
+ recommended way to provide the cipher suite. See examples for usage.
+ - Use the value C(default) to set the SSL protocols to the system default.
+ This value is equivalent to specifying a list of C(all,-SSLv2,-SSLv3).
+ version_added: 2.6
notes:
- Requires the requests Python package on the host. This is as easy as
C(pip install requests).
@@ -99,6 +124,45 @@ EXAMPLES = r'''
server: lb.mydomain.com
user: admin
delegate_to: localhost
+
+- name: Set SSL cipher suite by list
+ bigip_device_httpd:
+ password: secret
+ server: lb.mydomain.com
+ user: admin
+ ssl_cipher_suite:
+ - ECDHE-RSA-AES128-GCM-SHA256
+ - ECDHE-RSA-AES256-GCM-SHA384
+ - ECDHE-RSA-AES128-SHA
+ - AES256-SHA256
+ delegate_to: localhost
+
+- name: Set SSL cipher suite by string
+ bigip_device_httpd:
+ password: secret
+ server: lb.mydomain.com
+ user: admin
+ ssl_cipher_suite: ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA:AES256-SHA256
+ delegate_to: localhost
+
+- name: Set SSL protocols by list
+ bigip_device_httpd:
+ password: secret
+ server: lb.mydomain.com
+ user: admin
+ ssl_protocols:
+ - all
+ - -SSLv2
+ - -SSLv3
+ delegate_to: localhost
+
+- name: Set SSL protocols by string
+ bigip_device_httpd:
+ password: secret
+ server: lb.mydomain.com
+ user: admin
+ ssl_cipher_suite: all -SSLv2 -SSLv3
+ delegate_to: localhost
'''
RETURN = r'''
@@ -152,36 +216,40 @@ ssl_port:
returned: changed
type: int
sample: 10443
+ssl_cipher_suite:
+ description: The new ciphers that the system uses.
+ returned: changed
+ type: string
+ sample: ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA
+ssl_protocols:
+ description: The new list of SSL protocols to accept on the management console.
+ returned: changed
+ type: string
+ sample: all -SSLv2 -SSLv3
'''
import time
from ansible.module_utils.basic import AnsibleModule
-
-HAS_DEVEL_IMPORTS = False
+from ansible.module_utils.six import string_types
try:
- # Sideband repository used for dev
from library.module_utils.network.f5.bigip import HAS_F5SDK
from library.module_utils.network.f5.bigip import F5Client
from library.module_utils.network.f5.common import F5ModuleError
from library.module_utils.network.f5.common import AnsibleF5Parameters
from library.module_utils.network.f5.common import cleanup_tokens
- from library.module_utils.network.f5.common import fqdn_name
from library.module_utils.network.f5.common import f5_argument_spec
try:
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError
except ImportError:
HAS_F5SDK = False
- HAS_DEVEL_IMPORTS = True
except ImportError:
- # Upstream Ansible
from ansible.module_utils.network.f5.bigip import HAS_F5SDK
from ansible.module_utils.network.f5.bigip import F5Client
from ansible.module_utils.network.f5.common import F5ModuleError
from ansible.module_utils.network.f5.common import AnsibleF5Parameters
from ansible.module_utils.network.f5.common import cleanup_tokens
- from ansible.module_utils.network.f5.common import fqdn_name
from ansible.module_utils.network.f5.common import f5_argument_spec
try:
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError
@@ -206,29 +274,55 @@ class Parameters(AnsibleF5Parameters):
'logLevel': 'log_level',
'maxClients': 'max_clients',
'redirectHttpToHttps': 'redirect_http_to_https',
- 'sslPort': 'ssl_port'
+ 'sslPort': 'ssl_port',
+ 'sslCiphersuite': 'ssl_cipher_suite',
+ 'sslProtocol': 'ssl_protocols'
}
api_attributes = [
'authPamIdleTimeout', 'authPamValidateIp', 'authName', 'authPamDashboardTimeout',
'fastcgiTimeout', 'hostnameLookup', 'logLevel', 'maxClients', 'sslPort',
- 'redirectHttpToHttps', 'allow'
+ 'redirectHttpToHttps', 'allow', 'sslCiphersuite', 'sslProtocol'
]
returnables = [
'auth_pam_idle_timeout', 'auth_pam_validate_ip', 'auth_name',
'auth_pam_dashboard_timeout', 'fast_cgi_timeout', 'hostname_lookup',
'log_level', 'max_clients', 'redirect_http_to_https', 'ssl_port',
- 'allow'
+ 'allow', 'ssl_cipher_suite', 'ssl_protocols'
]
updatables = [
'auth_pam_idle_timeout', 'auth_pam_validate_ip', 'auth_name',
'auth_pam_dashboard_timeout', 'fast_cgi_timeout', 'hostname_lookup',
'log_level', 'max_clients', 'redirect_http_to_https', 'ssl_port',
- 'allow'
+ 'allow', 'ssl_cipher_suite', 'ssl_protocols'
]
+ _ciphers = "ECDHE-RSA-AES128-GCM-SHA256:" \
+ "ECDHE-RSA-AES256-GCM-SHA384:" \
+ "ECDHE-RSA-AES128-SHA:" \
+ "ECDHE-RSA-AES256-SHA:" \
+ "ECDHE-RSA-AES128-SHA256:" \
+ "ECDHE-RSA-AES256-SHA384:" \
+ "ECDHE-ECDSA-AES128-GCM-SHA256:" \
+ "ECDHE-ECDSA-AES256-GCM-SHA384:" \
+ "ECDHE-ECDSA-AES128-SHA:" \
+ "ECDHE-ECDSA-AES256-SHA:" \
+ "ECDHE-ECDSA-AES128-SHA256:" \
+ "ECDHE-ECDSA-AES256-SHA384:" \
+ "AES128-GCM-SHA256:" \
+ "AES256-GCM-SHA384:" \
+ "AES128-SHA:" \
+ "AES256-SHA:" \
+ "AES128-SHA256:" \
+ "AES256-SHA256:" \
+ "ECDHE-RSA-DES-CBC3-SHA:" \
+ "ECDHE-ECDSA-DES-CBC3-SHA:" \
+ "DES-CBC3-SHA"
+
+ _protocols = 'all -SSLv2 -SSLv3'
+
@property
def auth_pam_idle_timeout(self):
if self._values['auth_pam_idle_timeout'] is None:
@@ -300,6 +394,46 @@ class ModuleParameters(Parameters):
result = sorted(result)
return result
+ @property
+ def ssl_cipher_suite(self):
+ if self._values['ssl_cipher_suite'] is None:
+ return None
+ if isinstance(self._values['ssl_cipher_suite'], string_types):
+ ciphers = self._values['ssl_cipher_suite'].strip()
+ else:
+ ciphers = self._values['ssl_cipher_suite']
+ if not ciphers:
+ raise F5ModuleError(
+ "ssl_cipher_suite may not be set to 'none'"
+ )
+ if ciphers == 'default':
+ ciphers = ':'.join(sorted(Parameters._ciphers.split(':')))
+ elif isinstance(self._values['ssl_cipher_suite'], string_types):
+ ciphers = ':'.join(sorted(ciphers.split(':')))
+ else:
+ ciphers = ':'.join(sorted(ciphers))
+ return ciphers
+
+ @property
+ def ssl_protocols(self):
+ if self._values['ssl_protocols'] is None:
+ return None
+ if isinstance(self._values['ssl_protocols'], string_types):
+ protocols = self._values['ssl_protocols'].strip()
+ else:
+ protocols = self._values['ssl_protocols']
+ if not protocols:
+ raise F5ModuleError(
+ "ssl_protocols may not be set to 'none'"
+ )
+ if protocols == 'default':
+ protocols = ' '.join(sorted(Parameters._protocols.split(' ')))
+ elif isinstance(protocols, string_types):
+ protocols = ' '.join(sorted(protocols.split(' ')))
+ else:
+ protocols = ' '.join(sorted(protocols))
+ return protocols
+
class ApiParameters(Parameters):
@property
@@ -331,7 +465,21 @@ class UsableChanges(Changes):
class ReportableChanges(Changes):
- pass
+ @property
+ def ssl_cipher_suite(self):
+ default = ':'.join(sorted(Parameters._ciphers.split(':')))
+ if self._values['ssl_cipher_suite'] == default:
+ return 'default'
+ else:
+ return self._values['ssl_cipher_suite']
+
+ @property
+ def ssl_protocols(self):
+ default = ' '.join(sorted(Parameters._protocols.split(' ')))
+ if self._values['ssl_protocols'] == default:
+ return 'default'
+ else:
+ return self._values['ssl_protocols']
class Difference(object):
@@ -449,7 +597,6 @@ class ModuleManager(object):
def update_on_device(self):
params = self.changes.api_params()
resource = self.client.api.tm.sys.httpd.load()
-
try:
resource.modify(**params)
return True
@@ -504,7 +651,9 @@ class ArgumentSpec(object):
),
redirect_http_to_https=dict(
type='bool'
- )
+ ),
+ ssl_cipher_suite=dict(type='raw'),
+ ssl_protocols=dict(type='raw')
)
self.argument_spec = {}
self.argument_spec.update(f5_argument_spec)
diff --git a/lib/ansible/modules/network/f5/bigip_device_ntp.py b/lib/ansible/modules/network/f5/bigip_device_ntp.py
index cf1b7f3c13..32cc50d327 100644
--- a/lib/ansible/modules/network/f5/bigip_device_ntp.py
+++ b/lib/ansible/modules/network/f5/bigip_device_ntp.py
@@ -17,7 +17,7 @@ module: bigip_device_ntp
short_description: Manage NTP servers on a BIG-IP
description:
- Manage NTP servers on a BIG-IP.
-version_added: "2.2"
+version_added: 2.2
options:
ntp_servers:
description:
@@ -79,30 +79,23 @@ timezone:
from ansible.module_utils.basic import AnsibleModule
-HAS_DEVEL_IMPORTS = False
-
try:
- # Sideband repository used for dev
from library.module_utils.network.f5.bigip import HAS_F5SDK
from library.module_utils.network.f5.bigip import F5Client
from library.module_utils.network.f5.common import F5ModuleError
from library.module_utils.network.f5.common import AnsibleF5Parameters
from library.module_utils.network.f5.common import cleanup_tokens
- from library.module_utils.network.f5.common import fqdn_name
from library.module_utils.network.f5.common import f5_argument_spec
try:
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError
except ImportError:
HAS_F5SDK = False
- HAS_DEVEL_IMPORTS = True
except ImportError:
- # Upstream Ansible
from ansible.module_utils.network.f5.bigip import HAS_F5SDK
from ansible.module_utils.network.f5.bigip import F5Client
from ansible.module_utils.network.f5.common import F5ModuleError
from ansible.module_utils.network.f5.common import AnsibleF5Parameters
from ansible.module_utils.network.f5.common import cleanup_tokens
- from ansible.module_utils.network.f5.common import fqdn_name
from ansible.module_utils.network.f5.common import f5_argument_spec
try:
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError
diff --git a/lib/ansible/modules/network/f5/bigip_device_sshd.py b/lib/ansible/modules/network/f5/bigip_device_sshd.py
index af180702b5..68591be02f 100644
--- a/lib/ansible/modules/network/f5/bigip_device_sshd.py
+++ b/lib/ansible/modules/network/f5/bigip_device_sshd.py
@@ -17,7 +17,7 @@ module: bigip_device_sshd
short_description: Manage the SSHD settings of a BIG-IP
description:
- Manage the SSHD settings of a BIG-IP.
-version_added: "2.2"
+version_added: 2.2
options:
allow:
description:
@@ -147,30 +147,23 @@ port:
from ansible.module_utils.basic import AnsibleModule
-HAS_DEVEL_IMPORTS = False
-
try:
- # Sideband repository used for dev
from library.module_utils.network.f5.bigip import HAS_F5SDK
from library.module_utils.network.f5.bigip import F5Client
from library.module_utils.network.f5.common import F5ModuleError
from library.module_utils.network.f5.common import AnsibleF5Parameters
from library.module_utils.network.f5.common import cleanup_tokens
- from library.module_utils.network.f5.common import fqdn_name
from library.module_utils.network.f5.common import f5_argument_spec
try:
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError
except ImportError:
HAS_F5SDK = False
- HAS_DEVEL_IMPORTS = True
except ImportError:
- # Upstream Ansible
from ansible.module_utils.network.f5.bigip import HAS_F5SDK
from ansible.module_utils.network.f5.bigip import F5Client
from ansible.module_utils.network.f5.common import F5ModuleError
from ansible.module_utils.network.f5.common import AnsibleF5Parameters
from ansible.module_utils.network.f5.common import cleanup_tokens
- from ansible.module_utils.network.f5.common import fqdn_name
from ansible.module_utils.network.f5.common import f5_argument_spec
try:
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError
@@ -229,13 +222,33 @@ class Parameters(AnsibleF5Parameters):
return result
+class ApiParameters(Parameters):
+ pass
+
+
+class ModuleParameters(Parameters):
+ pass
+
+
+class Changes(Parameters):
+ pass
+
+
+class UsableChanges(Changes):
+ pass
+
+
+class ReportableChanges(Changes):
+ pass
+
+
class ModuleManager(object):
def __init__(self, *args, **kwargs):
self.module = kwargs.get('module', None)
self.client = kwargs.get('client', None)
self.have = None
- self.want = Parameters(params=self.module.params)
- self.changes = Parameters()
+ self.want = ModuleParameters(params=self.module.params)
+ self.changes = UsableChanges()
def _update_changed_options(self):
changed = {}
@@ -246,7 +259,7 @@ class ModuleManager(object):
if attr1 != attr2:
changed[key] = attr1
if changed:
- self.changes = Parameters(params=changed)
+ self.changes = UsableChanges(params=changed)
return True
return False
@@ -266,7 +279,7 @@ class ModuleManager(object):
def read_current_from_device(self):
resource = self.client.api.tm.sys.sshd.load()
result = resource.attrs
- return Parameters(params=result)
+ return ApiParameters(params=result)
def update(self):
self.have = self.read_current_from_device()
@@ -284,7 +297,7 @@ class ModuleManager(object):
return False
def update_on_device(self):
- params = self.want.api_params()
+ params = self.changes.api_params()
resource = self.client.api.tm.sys.sshd.load()
resource.update(**params)
diff --git a/lib/ansible/modules/network/f5/bigip_device_trust.py b/lib/ansible/modules/network/f5/bigip_device_trust.py
index 22bd0bf897..2b6e24c85f 100644
--- a/lib/ansible/modules/network/f5/bigip_device_trust.py
+++ b/lib/ansible/modules/network/f5/bigip_device_trust.py
@@ -19,7 +19,7 @@ description:
- Manage the trust relationships between BIG-IPs. Devices, once peered, cannot
be updated. If updating is needed, the peer must first be removed before it
can be re-added to the trust.
-version_added: "2.5"
+version_added: 2.5
options:
peer_server:
description:
@@ -107,30 +107,23 @@ import re
from ansible.module_utils.basic import AnsibleModule
-HAS_DEVEL_IMPORTS = False
-
try:
- # Sideband repository used for dev
from library.module_utils.network.f5.bigip import HAS_F5SDK
from library.module_utils.network.f5.bigip import F5Client
from library.module_utils.network.f5.common import F5ModuleError
from library.module_utils.network.f5.common import AnsibleF5Parameters
from library.module_utils.network.f5.common import cleanup_tokens
- from library.module_utils.network.f5.common import fqdn_name
from library.module_utils.network.f5.common import f5_argument_spec
try:
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError
except ImportError:
HAS_F5SDK = False
- HAS_DEVEL_IMPORTS = True
except ImportError:
- # Upstream Ansible
from ansible.module_utils.network.f5.bigip import HAS_F5SDK
from ansible.module_utils.network.f5.bigip import F5Client
from ansible.module_utils.network.f5.common import F5ModuleError
from ansible.module_utils.network.f5.common import AnsibleF5Parameters
from ansible.module_utils.network.f5.common import cleanup_tokens
- from ansible.module_utils.network.f5.common import fqdn_name
from ansible.module_utils.network.f5.common import f5_argument_spec
try:
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError
@@ -189,7 +182,7 @@ class Parameters(AnsibleF5Parameters):
def peer_hostname(self):
if self._values['peer_hostname'] is None:
return self.peer_server
- regex = re.compile('[^a-zA-Z.-_]')
+ regex = re.compile(r'[^a-zA-Z0-9.\-_]')
result = regex.sub('_', self._values['peer_hostname'])
return result
diff --git a/lib/ansible/modules/network/f5/bigip_gtm_datacenter.py b/lib/ansible/modules/network/f5/bigip_gtm_datacenter.py
index d1860b728e..6b7b056e68 100644
--- a/lib/ansible/modules/network/f5/bigip_gtm_datacenter.py
+++ b/lib/ansible/modules/network/f5/bigip_gtm_datacenter.py
@@ -21,7 +21,7 @@ description:
where the physical network components reside, such as the server and link
objects that share the same subnet on the network. This module is able to
manipulate the data center definitions in a BIG-IP.
-version_added: "2.2"
+version_added: 2.2
options:
contact:
description:
@@ -107,30 +107,23 @@ location:
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.basic import env_fallback
-HAS_DEVEL_IMPORTS = False
-
try:
- # Sideband repository used for dev
from library.module_utils.network.f5.bigip import HAS_F5SDK
from library.module_utils.network.f5.bigip import F5Client
from library.module_utils.network.f5.common import F5ModuleError
from library.module_utils.network.f5.common import AnsibleF5Parameters
from library.module_utils.network.f5.common import cleanup_tokens
- from library.module_utils.network.f5.common import fqdn_name
from library.module_utils.network.f5.common import f5_argument_spec
try:
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError
except ImportError:
HAS_F5SDK = False
- HAS_DEVEL_IMPORTS = True
except ImportError:
- # Upstream Ansible
from ansible.module_utils.network.f5.bigip import HAS_F5SDK
from ansible.module_utils.network.f5.bigip import F5Client
from ansible.module_utils.network.f5.common import F5ModuleError
from ansible.module_utils.network.f5.common import AnsibleF5Parameters
from ansible.module_utils.network.f5.common import cleanup_tokens
- from ansible.module_utils.network.f5.common import fqdn_name
from ansible.module_utils.network.f5.common import f5_argument_spec
try:
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError
diff --git a/test/units/modules/network/f5/fixtures/load_sys_httpd_non_default.json b/test/units/modules/network/f5/fixtures/load_sys_httpd_non_default.json
new file mode 100644
index 0000000000..05051b9c08
--- /dev/null
+++ b/test/units/modules/network/f5/fixtures/load_sys_httpd_non_default.json
@@ -0,0 +1,36 @@
+{
+ "kind": "tm:sys:httpd:httpdstate",
+ "selfLink": "https://localhost/mgmt/tm/sys/httpd?ver=12.1.2",
+ "allow": [
+ "All"
+ ],
+ "authName": "BIG-IP",
+ "authPamDashboardTimeout": "off",
+ "authPamIdleTimeout": 1200,
+ "authPamValidateIp": "on",
+ "fastcgiTimeout": 300,
+ "fipsCipherVersion": 0,
+ "hostnameLookup": "off",
+ "logLevel": "warn",
+ "maxClients": 10,
+ "redirectHttpToHttps": "disabled",
+ "requestBodyMaxTimeout": 0,
+ "requestBodyMinRate": 500,
+ "requestBodyTimeout": 60,
+ "requestHeaderMaxTimeout": 40,
+ "requestHeaderMinRate": 500,
+ "requestHeaderTimeout": 20,
+ "sslCertfile": "/etc/httpd/conf/ssl.crt/server.crt",
+ "sslCertkeyfile": "/etc/httpd/conf/ssl.key/server.key",
+ "sslCiphersuite": "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384",
+ "sslOcspDefaultResponder": "http://127.0.0.1",
+ "sslOcspEnable": "off",
+ "sslOcspOverrideResponder": "off",
+ "sslOcspResponderTimeout": 300,
+ "sslOcspResponseMaxAge": -1,
+ "sslOcspResponseTimeSkew": 300,
+ "sslPort": 443,
+ "sslProtocol": "all -SSLv2",
+ "sslVerifyClient": "no",
+ "sslVerifyDepth": 10
+}
diff --git a/test/units/modules/network/f5/test_bigip_device_dns.py b/test/units/modules/network/f5/test_bigip_device_dns.py
index 6859352854..895bb69ba5 100644
--- a/test/units/modules/network/f5/test_bigip_device_dns.py
+++ b/test/units/modules/network/f5/test_bigip_device_dns.py
@@ -21,9 +21,9 @@ from ansible.compat.tests.mock import patch
from ansible.module_utils.basic import AnsibleModule
try:
- from library.bigip_device_dns import Parameters
- from library.bigip_device_dns import ModuleManager
- from library.bigip_device_dns import ArgumentSpec
+ from library.modules.bigip_device_dns import Parameters
+ from library.modules.bigip_device_dns import ModuleManager
+ from library.modules.bigip_device_dns import ArgumentSpec
from library.module_utils.network.f5.common import F5ModuleError
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError
from test.unit.modules.utils import set_module_args
@@ -64,7 +64,6 @@ class TestParameters(unittest.TestCase):
def test_module_parameters(self):
args = dict(
cache='disable',
- forwarders=['12.12.12.12', '13.13.13.13'],
ip_version=4,
name_servers=['10.10.10.10', '11.11.11.11'],
search=['14.14.14.14', '15.15.15.15'],
@@ -87,15 +86,6 @@ class TestParameters(unittest.TestCase):
p = Parameters(params=args)
assert p.ip_version == 'options inet6'
- def test_ensure_forwards_raises_exception(self):
- args = dict(
- forwarders=['12.12.12.12', '13.13.13.13'],
- )
- p = Parameters(params=args)
- with pytest.raises(F5ModuleError) as ex:
- p.forwarders
- assert 'The modifying of forwarders is not supported' in str(ex)
-
class TestManager(unittest.TestCase):
@@ -105,7 +95,6 @@ class TestManager(unittest.TestCase):
def test_update_settings(self, *args):
set_module_args(dict(
cache='disable',
- forwarders=['12.12.12.12', '13.13.13.13'],
ip_version=4,
name_servers=['10.10.10.10', '11.11.11.11'],
search=['14.14.14.14', '15.15.15.15'],
diff --git a/test/units/modules/network/f5/test_bigip_device_group.py b/test/units/modules/network/f5/test_bigip_device_group.py
index a707940945..789327c22f 100644
--- a/test/units/modules/network/f5/test_bigip_device_group.py
+++ b/test/units/modules/network/f5/test_bigip_device_group.py
@@ -20,9 +20,9 @@ from ansible.compat.tests.mock import patch
from ansible.module_utils.basic import AnsibleModule
try:
- from library.bigip_device_group import Parameters
- from library.bigip_device_group import ModuleManager
- from library.bigip_device_group import ArgumentSpec
+ from library.modules.bigip_device_group import Parameters
+ from library.modules.bigip_device_group import ModuleManager
+ from library.modules.bigip_device_group import ArgumentSpec
from library.module_utils.network.f5.common import F5ModuleError
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError
from test.unit.modules.utils import set_module_args
diff --git a/test/units/modules/network/f5/test_bigip_device_group_member.py b/test/units/modules/network/f5/test_bigip_device_group_member.py
index d83c37274b..84b523192b 100644
--- a/test/units/modules/network/f5/test_bigip_device_group_member.py
+++ b/test/units/modules/network/f5/test_bigip_device_group_member.py
@@ -21,9 +21,9 @@ from ansible.compat.tests.mock import patch
from ansible.module_utils.basic import AnsibleModule
try:
- from library.bigip_device_group_member import Parameters
- from library.bigip_device_group_member import ModuleManager
- from library.bigip_device_group_member import ArgumentSpec
+ from library.modules.bigip_device_group_member import Parameters
+ from library.modules.bigip_device_group_member import ModuleManager
+ from library.modules.bigip_device_group_member import ArgumentSpec
from library.module_utils.network.f5.common import F5ModuleError
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError
from test.unit.modules.utils import set_module_args
diff --git a/test/units/modules/network/f5/test_bigip_device_httpd.py b/test/units/modules/network/f5/test_bigip_device_httpd.py
index 49545d9637..0bbac049eb 100644
--- a/test/units/modules/network/f5/test_bigip_device_httpd.py
+++ b/test/units/modules/network/f5/test_bigip_device_httpd.py
@@ -20,9 +20,9 @@ from ansible.compat.tests.mock import patch
from ansible.module_utils.basic import AnsibleModule
try:
- from library.bigip_device_httpd import Parameters
- from library.bigip_device_httpd import ModuleManager
- from library.bigip_device_httpd import ArgumentSpec
+ from library.modules.bigip_device_httpd import Parameters
+ from library.modules.bigip_device_httpd import ModuleManager
+ from library.modules.bigip_device_httpd import ArgumentSpec
from library.module_utils.network.f5.common import F5ModuleError
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError
from test.unit.modules.utils import set_module_args
@@ -122,3 +122,165 @@ class TestModuleManager(unittest.TestCase):
results = mm.exec_module()
assert results['changed'] is True
+
+ def test_update_issue_00522(self, *args):
+ set_module_args(
+ dict(
+ ssl_cipher_suite='ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384',
+ server='localhost',
+ user='admin',
+ password='password'
+ )
+ )
+
+ current = Parameters(params=load_fixture('load_sys_httpd.json'))
+
+ module = AnsibleModule(
+ argument_spec=self.spec.argument_spec,
+ supports_check_mode=self.spec.supports_check_mode
+ )
+ mm = ModuleManager(module=module)
+
+ # Override methods to force specific logic in the module to happen
+ mm.update_on_device = Mock(return_value=True)
+ mm.read_current_from_device = Mock(return_value=current)
+
+ results = mm.exec_module()
+ assert results['changed'] is True
+ assert results['ssl_cipher_suite'] == 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384'
+
+ def test_update_issue_00522_as_list(self, *args):
+ set_module_args(
+ dict(
+ ssl_cipher_suite=[
+ 'ECDHE-RSA-AES128-GCM-SHA256',
+ 'ECDHE-RSA-AES256-GCM-SHA384'
+ ],
+ server='localhost',
+ user='admin',
+ password='password'
+ )
+ )
+
+ current = Parameters(params=load_fixture('load_sys_httpd.json'))
+
+ module = AnsibleModule(
+ argument_spec=self.spec.argument_spec,
+ supports_check_mode=self.spec.supports_check_mode
+ )
+ mm = ModuleManager(module=module)
+
+ # Override methods to force specific logic in the module to happen
+ mm.update_on_device = Mock(return_value=True)
+ mm.read_current_from_device = Mock(return_value=current)
+
+ results = mm.exec_module()
+ assert results['changed'] is True
+ assert results['ssl_cipher_suite'] == 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384'
+
+ def test_update_issue_00522_default(self, *args):
+ set_module_args(
+ dict(
+ ssl_cipher_suite='default',
+ server='localhost',
+ user='admin',
+ password='password'
+ )
+ )
+
+ current = Parameters(params=load_fixture('load_sys_httpd_non_default.json'))
+
+ module = AnsibleModule(
+ argument_spec=self.spec.argument_spec,
+ supports_check_mode=self.spec.supports_check_mode
+ )
+ mm = ModuleManager(module=module)
+
+ # Override methods to force specific logic in the module to happen
+ mm.update_on_device = Mock(return_value=True)
+ mm.read_current_from_device = Mock(return_value=current)
+
+ results = mm.exec_module()
+ assert results['changed'] is True
+ assert results['ssl_cipher_suite'] == 'default'
+
+ def test_update_issue_00587(self, *args):
+ set_module_args(
+ dict(
+ ssl_protocols='all -SSLv2',
+ server='localhost',
+ user='admin',
+ password='password'
+ )
+ )
+
+ current = Parameters(params=load_fixture('load_sys_httpd.json'))
+
+ module = AnsibleModule(
+ argument_spec=self.spec.argument_spec,
+ supports_check_mode=self.spec.supports_check_mode
+ )
+ mm = ModuleManager(module=module)
+
+ # Override methods to force specific logic in the module to happen
+ mm.update_on_device = Mock(return_value=True)
+ mm.read_current_from_device = Mock(return_value=current)
+
+ results = mm.exec_module()
+ assert results['changed'] is True
+ assert results['ssl_protocols'] == '-SSLv2 all'
+
+ def test_update_issue_00587_as_list(self, *args):
+ set_module_args(
+ dict(
+ ssl_protocols=[
+ 'all',
+ '-SSLv2'
+ ],
+ server='localhost',
+ user='admin',
+ password='password'
+ )
+ )
+
+ current = Parameters(params=load_fixture('load_sys_httpd.json'))
+
+ module = AnsibleModule(
+ argument_spec=self.spec.argument_spec,
+ supports_check_mode=self.spec.supports_check_mode
+ )
+ mm = ModuleManager(module=module)
+
+ # Override methods to force specific logic in the module to happen
+ mm.update_on_device = Mock(return_value=True)
+ mm.read_current_from_device = Mock(return_value=current)
+
+ results = mm.exec_module()
+ assert results['changed'] is True
+ assert results['ssl_protocols'] == '-SSLv2 all'
+
+ def test_update_issue_00587_default(self, *args):
+ set_module_args(
+ dict(
+ ssl_protocols='default',
+ server='localhost',
+ user='admin',
+ password='password'
+ )
+ )
+
+ current = Parameters(params=load_fixture('load_sys_httpd_non_default.json'))
+
+ module = AnsibleModule(
+ argument_spec=self.spec.argument_spec,
+ supports_check_mode=self.spec.supports_check_mode
+ )
+ mm = ModuleManager(module=module)
+
+ # Override methods to force specific logic in the module to happen
+ mm.update_on_device = Mock(return_value=True)
+ mm.read_current_from_device = Mock(return_value=current)
+
+ results = mm.exec_module()
+ assert results['changed'] is True
+ assert results['ssl_protocols'] == 'default'
diff --git a/test/units/modules/network/f5/test_bigip_device_ntp.py b/test/units/modules/network/f5/test_bigip_device_ntp.py
index ddd0297f56..ce84c9173b 100644
--- a/test/units/modules/network/f5/test_bigip_device_ntp.py
+++ b/test/units/modules/network/f5/test_bigip_device_ntp.py
@@ -20,9 +20,9 @@ from ansible.compat.tests.mock import patch
from ansible.module_utils.basic import AnsibleModule
try:
- from library.bigip_device_ntp import Parameters
- from library.bigip_device_ntp import ModuleManager
- from library.bigip_device_ntp import ArgumentSpec
+ from library.modules.bigip_device_ntp import Parameters
+ from library.modules.bigip_device_ntp import ModuleManager
+ from library.modules.bigip_device_ntp import ArgumentSpec
from library.module_utils.network.f5.common import F5ModuleError
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError
from test.unit.modules.utils import set_module_args
diff --git a/test/units/modules/network/f5/test_bigip_device_sshd.py b/test/units/modules/network/f5/test_bigip_device_sshd.py
index 923259f3ab..341c80dece 100644
--- a/test/units/modules/network/f5/test_bigip_device_sshd.py
+++ b/test/units/modules/network/f5/test_bigip_device_sshd.py
@@ -20,15 +20,17 @@ from ansible.compat.tests.mock import patch
from ansible.module_utils.basic import AnsibleModule
try:
- from library.bigip_device_sshd import Parameters
- from library.bigip_device_sshd import ModuleManager
- from library.bigip_device_sshd import ArgumentSpec
+ from library.modules.bigip_device_sshd import ApiParameters
+ from library.modules.bigip_device_sshd import ModuleParameters
+ from library.modules.bigip_device_sshd import ModuleManager
+ from library.modules.bigip_device_sshd import ArgumentSpec
from library.module_utils.network.f5.common import F5ModuleError
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError
from test.unit.modules.utils import set_module_args
except ImportError:
try:
- from ansible.modules.network.f5.bigip_device_sshd import Parameters
+ from ansible.modules.network.f5.bigip_device_sshd import ApiParameters
+ from ansible.modules.network.f5.bigip_device_sshd import ModuleParameters
from ansible.modules.network.f5.bigip_device_sshd import ModuleManager
from ansible.modules.network.f5.bigip_device_sshd import ArgumentSpec
from ansible.module_utils.network.f5.common import F5ModuleError
@@ -73,7 +75,7 @@ class TestParameters(unittest.TestCase):
user='admin',
password='password'
)
- p = Parameters(params=args)
+ p = ModuleParameters(params=args)
assert p.allow == ['all']
assert p.banner == 'enabled'
assert p.banner_text == 'asdf'
@@ -104,8 +106,8 @@ class TestManager(unittest.TestCase):
# Configure the parameters that would be returned by querying the
# remote device
- current = Parameters(
- dict(
+ current = ApiParameters(
+ params=dict(
allow=['172.27.1.1']
)
)
diff --git a/test/units/modules/network/f5/test_bigip_device_trust.py b/test/units/modules/network/f5/test_bigip_device_trust.py
index 3191d3a69b..3d93977ae4 100644
--- a/test/units/modules/network/f5/test_bigip_device_trust.py
+++ b/test/units/modules/network/f5/test_bigip_device_trust.py
@@ -20,11 +20,11 @@ from ansible.compat.tests.mock import patch
from ansible.module_utils.basic import AnsibleModule
try:
- from library.bigip_device_trust import Parameters
- from library.bigip_device_trust import ModuleManager
- from library.bigip_device_trust import ArgumentSpec
- from library.bigip_device_trust import HAS_F5SDK
- from library.bigip_device_trust import HAS_NETADDR
+ from library.modules.bigip_device_trust import Parameters
+ from library.modules.bigip_device_trust import ModuleManager
+ from library.modules.bigip_device_trust import ArgumentSpec
+ from library.modules.bigip_device_trust import HAS_F5SDK
+ from library.modules.bigip_device_trust import HAS_NETADDR
from library.module_utils.network.f5.common import F5ModuleError
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError
from test.unit.modules.utils import set_module_args
@@ -114,6 +114,22 @@ class TestParameters(unittest.TestCase):
assert p.peer_password == 'secret'
assert p.type is False
+ def test_hyphenated_peer_hostname(self):
+ args = dict(
+ peer_hostname='hn---hyphen____underscore.hmatsuda.local',
+ )
+
+ p = Parameters(params=args)
+ assert p.peer_hostname == 'hn---hyphen____underscore.hmatsuda.local'
+
+ def test_numbered_peer_hostname(self):
+ args = dict(
+ peer_hostname='BIG-IP_12x_ans2.example.local',
+ )
+
+ p = Parameters(params=args)
+ assert p.peer_hostname == 'BIG-IP_12x_ans2.example.local'
+
class TestManager(unittest.TestCase):
diff --git a/test/units/modules/network/f5/test_bigip_gtm_datacenter.py b/test/units/modules/network/f5/test_bigip_gtm_datacenter.py
index 1484b8ece8..79d2c80d83 100644
--- a/test/units/modules/network/f5/test_bigip_gtm_datacenter.py
+++ b/test/units/modules/network/f5/test_bigip_gtm_datacenter.py
@@ -20,10 +20,10 @@ from ansible.compat.tests.mock import patch
from ansible.module_utils.basic import AnsibleModule
try:
- from library.bigip_gtm_datacenter import ApiParameters
- from library.bigip_gtm_datacenter import ModuleParameters
- from library.bigip_gtm_datacenter import ModuleManager
- from library.bigip_gtm_datacenter import ArgumentSpec
+ from library.modules.bigip_gtm_datacenter import ApiParameters
+ from library.modules.bigip_gtm_datacenter import ModuleParameters
+ from library.modules.bigip_gtm_datacenter import ModuleManager
+ from library.modules.bigip_gtm_datacenter import ArgumentSpec
from library.module_utils.network.f5.common import F5ModuleError
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError
from test.unit.modules.utils import set_module_args