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 @@ -198,15 +187,6 @@ class Parameters(AnsibleF5Parameters): valid = ['enable', 'enabled'] 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']: @@ -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