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}(?<!-)$', re.IGNORECASE) + result = all(allowed.match(x) for x in host.split(".")) + return result + + class Noop(object): """Represent no-operation required @@ -174,6 +201,7 @@ class F5BaseClient(object): def __init__(self, *args, **kwargs): self.params = kwargs load_params(self.params) + self._client = None @property def api(self): @@ -194,7 +222,7 @@ class F5BaseClient(object): :return: :raises iControlUnexpectedHTTPError """ - self.api = self.mgmt + self._client = self.mgmt class AnsibleF5Parameters(object): @@ -202,12 +230,17 @@ class AnsibleF5Parameters(object): self._values = defaultdict(lambda: None) self._values['__warnings'] = [] self.client = kwargs.pop('client', None) + self._module = kwargs.pop('module', None) + self._params = {} + params = kwargs.pop('params', None) if params: self.update(params=params) + self._params.update(params) def update(self, params=None): if params: + self._params.update(params) for k, v in iteritems(params): if self.api_map is not None and k in self.api_map: map_key = self.api_map[k] diff --git a/lib/ansible/module_utils/network/f5/iworkflow.py b/lib/ansible/module_utils/network/f5/iworkflow.py index c4f42a685c9..2b2e995795d 100644 --- a/lib/ansible/module_utils/network/f5/iworkflow.py +++ b/lib/ansible/module_utils/network/f5/iworkflow.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']) + )