From 95188ed35cb6bf00ca382b2a5084f2696f2c492c Mon Sep 17 00:00:00 2001 From: Tim Rupp Date: Tue, 6 Feb 2018 22:16:26 -0800 Subject: [PATCH] Fixes repeated calls to create an API object (#35816) This patch fixes repeated attempts that the module would make to re-create an API object. The change stores a copy for later lookup instead. This prevents uncontrolled tokens from being created. --- lib/ansible/module_utils/network/f5/bigip.py | 17 +++++---- lib/ansible/module_utils/network/f5/bigiq.py | 17 +++++---- lib/ansible/module_utils/network/f5/common.py | 35 ++++++++++++++++++- .../module_utils/network/f5/iworkflow.py | 17 +++++---- 4 files changed, 58 insertions(+), 28 deletions(-) diff --git a/lib/ansible/module_utils/network/f5/bigip.py b/lib/ansible/module_utils/network/f5/bigip.py index 7df358b7e1b..63887fac5d7 100644 --- a/lib/ansible/module_utils/network/f5/bigip.py +++ b/lib/ansible/module_utils/network/f5/bigip.py @@ -27,7 +27,8 @@ except ImportError: class F5Client(F5BaseClient): @property def api(self): - result = None + if self._client: + return self._client for x in range(0, 10): try: result = ManagementRoot( @@ -38,13 +39,11 @@ class F5Client(F5BaseClient): verify=self.params['validate_certs'], token='tmos' ) - break + self._client = result + return self._client except Exception: time.sleep(3) - if result: - return result - else: - raise F5ModuleError( - 'Unable to connect to {0} on port {1}. ' - 'Is "validate_certs" preventing this?'.format(self.params['server'], self.params['server_port']) - ) + raise F5ModuleError( + 'Unable to connect to {0} on port {1}. ' + 'Is "validate_certs" preventing this?'.format(self.params['server'], self.params['server_port']) + ) diff --git a/lib/ansible/module_utils/network/f5/bigiq.py b/lib/ansible/module_utils/network/f5/bigiq.py index dff9913f072..458f2696fae 100644 --- a/lib/ansible/module_utils/network/f5/bigiq.py +++ b/lib/ansible/module_utils/network/f5/bigiq.py @@ -27,7 +27,8 @@ except ImportError: class F5Client(F5BaseClient): @property def api(self): - result = None + if self._client: + return self._client for x in range(0, 10): try: result = ManagementRoot( @@ -38,13 +39,11 @@ class F5Client(F5BaseClient): verify=self.params['validate_certs'], token='local' ) - break + self._client = result + return self._client except Exception: time.sleep(3) - if result: - return result - else: - raise F5ModuleError( - 'Unable to connect to {0} on port {1}. ' - 'Is "validate_certs" preventing this?'.format(self.params['server'], self.params['server_port']) - ) + raise F5ModuleError( + 'Unable to connect to {0} on port {1}. ' + 'Is "validate_certs" preventing this?'.format(self.params['server'], self.params['server_port']) + ) diff --git a/lib/ansible/module_utils/network/f5/common.py b/lib/ansible/module_utils/network/f5/common.py index 43563992246..0f6c2c5b62e 100644 --- a/lib/ansible/module_utils/network/f5/common.py +++ b/lib/ansible/module_utils/network/f5/common.py @@ -6,6 +6,8 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type +import re + from ansible.module_utils._text import to_text from ansible.module_utils.basic import env_fallback from ansible.module_utils.connection import exec_command @@ -156,6 +158,31 @@ def is_cli(module): return result +def is_valid_hostname(host): + """Reasonable attempt at validating a hostname + + Compiled from various paragraphs outlined here + https://tools.ietf.org/html/rfc3696#section-2 + https://tools.ietf.org/html/rfc1123 + + Notably, + * Host software MUST handle host names of up to 63 characters and + SHOULD handle host names of up to 255 characters. + * The "LDH rule", after the characters that it permits. (letters, digits, hyphen) + * If the hyphen is used, it is not permitted to appear at + either the beginning or end of a label + + :param host: + :return: + """ + if len(host) > 255: + return False + host = host.rstrip(".") + allowed = re.compile(r'(?!-)[A-Z0-9-]{1,63}(?