removed deprecated parameters (#61071)
fixed multiple issues with integration tests added RD support for source parameter fixed a problem with name parameter in bigip_user module
This commit is contained in:
parent
e5243ef1d7
commit
8bfa7569b5
2 changed files with 100 additions and 93 deletions
|
@ -638,7 +638,7 @@ class UnpartitionedManager(BaseManager):
|
|||
uri = "https://{0}:{1}/mgmt/tm/auth/user/{2}".format(
|
||||
self.client.provider['server'],
|
||||
self.client.provider['server_port'],
|
||||
self.want.name
|
||||
self.want.username_credential
|
||||
)
|
||||
resp = self.client.api.get(uri)
|
||||
try:
|
||||
|
@ -651,7 +651,7 @@ class UnpartitionedManager(BaseManager):
|
|||
|
||||
def create_on_device(self):
|
||||
params = self.changes.api_params()
|
||||
params['name'] = self.want.name
|
||||
params['name'] = self.want.username_credential
|
||||
uri = "https://{0}:{1}/mgmt/tm/auth/user/".format(
|
||||
self.client.provider['server'],
|
||||
self.client.provider['server_port']
|
||||
|
@ -674,7 +674,7 @@ class UnpartitionedManager(BaseManager):
|
|||
uri = "https://{0}:{1}/mgmt/tm/auth/user/{2}".format(
|
||||
self.client.provider['server'],
|
||||
self.client.provider['server_port'],
|
||||
self.want.name
|
||||
self.want.username_credential
|
||||
)
|
||||
resp = self.client.api.patch(uri, json=params)
|
||||
try:
|
||||
|
@ -692,7 +692,7 @@ class UnpartitionedManager(BaseManager):
|
|||
uri = "https://{0}:{1}/mgmt/tm/auth/user/{2}".format(
|
||||
self.client.provider['server'],
|
||||
self.client.provider['server_port'],
|
||||
self.want.name
|
||||
self.want.username_credential
|
||||
)
|
||||
response = self.client.api.delete(uri)
|
||||
if response.status == 200:
|
||||
|
@ -703,7 +703,7 @@ class UnpartitionedManager(BaseManager):
|
|||
uri = "https://{0}:{1}/mgmt/tm/auth/user/{2}".format(
|
||||
self.client.provider['server'],
|
||||
self.client.provider['server_port'],
|
||||
self.want.name
|
||||
self.want.username_credential
|
||||
)
|
||||
resp = self.client.api.get(uri)
|
||||
try:
|
||||
|
@ -723,7 +723,7 @@ class PartitionedManager(BaseManager):
|
|||
def exists(self):
|
||||
response = self.list_users_on_device()
|
||||
if 'items' in response:
|
||||
collection = [x for x in response['items'] if x['name'] == self.want.name]
|
||||
collection = [x for x in response['items'] if x['name'] == self.want.username_credential]
|
||||
if len(collection) == 1:
|
||||
return True
|
||||
elif len(collection) == 0:
|
||||
|
@ -736,7 +736,7 @@ class PartitionedManager(BaseManager):
|
|||
|
||||
def create_on_device(self):
|
||||
params = self.changes.api_params()
|
||||
params['name'] = self.want.name
|
||||
params['name'] = self.want.username_credential
|
||||
params['partition'] = self.want.partition
|
||||
uri = "https://{0}:{1}/mgmt/tm/auth/user/".format(
|
||||
self.client.provider['server'],
|
||||
|
@ -747,17 +747,16 @@ class PartitionedManager(BaseManager):
|
|||
response = resp.json()
|
||||
except ValueError as ex:
|
||||
raise F5ModuleError(str(ex))
|
||||
|
||||
if 'code' in response and response['code'] in [400, 404, 409]:
|
||||
if 'code' in response and response['code'] in [400, 404, 409, 403]:
|
||||
if 'message' in response:
|
||||
raise F5ModuleError(response['message'])
|
||||
else:
|
||||
raise F5ModuleError(resp.content)
|
||||
return response['selfLink']
|
||||
return True
|
||||
|
||||
def read_current_from_device(self):
|
||||
response = self.list_users_on_device()
|
||||
collection = [x for x in response['items'] if x['name'] == self.want.name]
|
||||
collection = [x for x in response['items'] if x['name'] == self.want.username_credential]
|
||||
if len(collection) == 1:
|
||||
user = collection.pop()
|
||||
return ApiParameters(params=user)
|
||||
|
@ -775,7 +774,7 @@ class PartitionedManager(BaseManager):
|
|||
uri = "https://{0}:{1}/mgmt/tm/auth/user/{2}".format(
|
||||
self.client.provider['server'],
|
||||
self.client.provider['server_port'],
|
||||
self.want.name
|
||||
self.want.username_credential
|
||||
)
|
||||
resp = self.client.api.patch(uri, json=params)
|
||||
try:
|
||||
|
@ -783,7 +782,7 @@ class PartitionedManager(BaseManager):
|
|||
except ValueError as ex:
|
||||
raise F5ModuleError(str(ex))
|
||||
|
||||
if 'code' in response and response['code'] in [400, 404, 409]:
|
||||
if 'code' in response and response['code'] in [400, 404, 409, 403]:
|
||||
if 'message' in response:
|
||||
if 'updated successfully' not in response['message']:
|
||||
raise F5ModuleError(response['message'])
|
||||
|
@ -794,7 +793,7 @@ class PartitionedManager(BaseManager):
|
|||
uri = "https://{0}:{1}/mgmt/tm/auth/user/{2}".format(
|
||||
self.client.provider['server'],
|
||||
self.client.provider['server_port'],
|
||||
self.want.name
|
||||
self.want.username_credential
|
||||
)
|
||||
response = self.client.api.delete(uri)
|
||||
if response.status == 200:
|
||||
|
|
|
@ -892,6 +892,7 @@ try:
|
|||
from library.module_utils.network.f5.common import flatten_boolean
|
||||
from library.module_utils.network.f5.compare import cmp_simple_list
|
||||
from library.module_utils.network.f5.ipaddress import is_valid_ip
|
||||
from library.module_utils.network.f5.ipaddress import is_valid_ip_interface
|
||||
from library.module_utils.network.f5.ipaddress import ip_interface
|
||||
from library.module_utils.network.f5.ipaddress import validate_ip_v6_address
|
||||
from library.module_utils.network.f5.ipaddress import get_netmask
|
||||
|
@ -911,6 +912,7 @@ except ImportError:
|
|||
from ansible.module_utils.network.f5.common import flatten_boolean
|
||||
from ansible.module_utils.network.f5.compare import cmp_simple_list
|
||||
from ansible.module_utils.network.f5.ipaddress import is_valid_ip
|
||||
from ansible.module_utils.network.f5.ipaddress import is_valid_ip_interface
|
||||
from ansible.module_utils.network.f5.ipaddress import ip_interface
|
||||
from ansible.module_utils.network.f5.ipaddress import validate_ip_v6_address
|
||||
from ansible.module_utils.network.f5.ipaddress import get_netmask
|
||||
|
@ -1108,10 +1110,7 @@ class Parameters(AnsibleF5Parameters):
|
|||
|
||||
def _format_port_for_destination(self, ip, port):
|
||||
if validate_ip_v6_address(ip):
|
||||
if port == 0:
|
||||
result = '.any'
|
||||
else:
|
||||
result = '.{0}'.format(port)
|
||||
result = '.{0}'.format(port)
|
||||
else:
|
||||
result = ':{0}'.format(port)
|
||||
return result
|
||||
|
@ -1158,19 +1157,6 @@ class Parameters(AnsibleF5Parameters):
|
|||
"Specified ip_protocol was neither a number nor in the list of common protocols."
|
||||
)
|
||||
|
||||
@property
|
||||
def source(self):
|
||||
if self._values['source'] is None:
|
||||
return None
|
||||
try:
|
||||
addr = ip_interface(u'{0}'.format(self._values['source']))
|
||||
result = '{0}/{1}'.format(str(addr.ip), addr.network.prefixlen)
|
||||
return result
|
||||
except ValueError:
|
||||
raise F5ModuleError(
|
||||
"The source IP address must be specified in CIDR format: address/prefix"
|
||||
)
|
||||
|
||||
@property
|
||||
def has_message_routing_profiles(self):
|
||||
if self.profiles is None:
|
||||
|
@ -1528,6 +1514,18 @@ class ApiParameters(Parameters):
|
|||
)
|
||||
return result
|
||||
|
||||
# match IPv6 wildcard with port without RD
|
||||
pattern = r'(?P<ip>[^.]+).(?P<port>[0-9]+|any)'
|
||||
matches = re.search(pattern, destination)
|
||||
if matches:
|
||||
result = Destination(
|
||||
ip=matches.group('ip'),
|
||||
port=matches.group('port'),
|
||||
route_domain=None,
|
||||
mask=self.mask
|
||||
)
|
||||
return result
|
||||
|
||||
result = Destination(ip=None, port=None, route_domain=None, mask=None)
|
||||
return result
|
||||
|
||||
|
@ -1779,15 +1777,65 @@ class ModuleParameters(Parameters):
|
|||
'You must specify only one clone pool for each context.'
|
||||
)
|
||||
|
||||
@property
|
||||
def source(self):
|
||||
if self._values['source'] is None:
|
||||
return None
|
||||
source = self.source_tuple
|
||||
if is_valid_ip_interface(u'{0}/{1}'.format(source.ip, source.cidr)):
|
||||
if source.route_domain:
|
||||
result = '{0}%{1}/{2}'.format(source.ip, source.route_domain, source.cidr)
|
||||
else:
|
||||
result = '{0}/{1}'.format(source.ip, source.cidr)
|
||||
return result
|
||||
raise F5ModuleError(
|
||||
"The source IP address must be a valid CIDR format: address/prefix."
|
||||
)
|
||||
|
||||
@property
|
||||
def source_tuple(self):
|
||||
Source = namedtuple('Source', ['ip', 'route_domain', 'cidr'])
|
||||
if self._values['source'] is None:
|
||||
result = Source(ip=None, route_domain=None, cidr=None)
|
||||
return result
|
||||
# match source with RD
|
||||
pattern = r'(?P<ip>[^%]+)%(?P<route_domain>[0-9]+)/(?P<cidr>[0-9]+)'
|
||||
matches = re.search(pattern, self._values['source'])
|
||||
if matches:
|
||||
result = Source(
|
||||
ip=matches.group('ip'),
|
||||
route_domain=matches.group('route_domain'),
|
||||
cidr=matches.group('cidr')
|
||||
)
|
||||
return result
|
||||
# match source without RD
|
||||
pattern = r'(?P<ip>[^%]+)/(?P<cidr>[0-9]+)'
|
||||
matches = re.search(pattern, self._values['source'])
|
||||
if matches:
|
||||
result = Source(
|
||||
ip=matches.group('ip'),
|
||||
route_domain=None,
|
||||
cidr=matches.group('cidr')
|
||||
)
|
||||
return result
|
||||
|
||||
result = Source(ip=None, route_domain=None, cidr=None)
|
||||
return result
|
||||
|
||||
@property
|
||||
def destination(self):
|
||||
pattern = r'^[a-zA-Z0-9_.-]+'
|
||||
addr = self._values['destination'].split("%")[0].split('/')[0]
|
||||
if len(self._values['destination'].split('/')) > 1:
|
||||
addr, dud = self._values['destination'].split('/')
|
||||
if '%' in addr:
|
||||
addr = addr.split('%')[0]
|
||||
else:
|
||||
addr = self._values['destination'].split('%')[0]
|
||||
if not is_valid_ip(addr):
|
||||
matches = re.search(pattern, addr)
|
||||
if not matches:
|
||||
raise F5ModuleError(
|
||||
"The provided destination is not a valid IP address or a Virtual Address name"
|
||||
"The provided destination is not a valid IP address or a Virtual Address name."
|
||||
)
|
||||
result = self._format_destination(addr, self.port, self.route_domain)
|
||||
return result
|
||||
|
@ -1796,8 +1844,14 @@ class ModuleParameters(Parameters):
|
|||
def route_domain(self):
|
||||
if self._values['destination'] is None:
|
||||
return None
|
||||
result = self._values['destination'].split("%")
|
||||
if len(result) > 1:
|
||||
result = None
|
||||
if len(self._values['destination'].split('/')) > 1:
|
||||
addr, dud = self._values['destination'].split('/')
|
||||
if '%' in addr:
|
||||
result = addr.split('%')
|
||||
else:
|
||||
result = self._values['destination'].split('%')
|
||||
if result and len(result) > 1:
|
||||
pattern = r'^[a-zA-Z0-9_.-]+'
|
||||
matches = re.search(pattern, result[0])
|
||||
if matches and not is_valid_ip(result[0]):
|
||||
|
@ -1822,13 +1876,20 @@ class ModuleParameters(Parameters):
|
|||
def mask(self):
|
||||
if self._values['destination'] is None:
|
||||
return None
|
||||
addr = self._values['destination'].split("%")[0]
|
||||
if len(self._values['destination'].split('/')) > 1:
|
||||
addr, cidr = self._values['destination'].split('/')
|
||||
if '%' in addr:
|
||||
addr = addr.split('%')[0] + '/' + cidr
|
||||
else:
|
||||
addr = self._values['destination']
|
||||
else:
|
||||
addr = self._values['destination'].split('%')[0]
|
||||
if addr in ['0.0.0.0', '0.0.0.0/any', '0.0.0.0/0']:
|
||||
return 'any'
|
||||
if addr in ['::', '::/0', '::/any6']:
|
||||
return 'any6'
|
||||
if self._values['mask'] is None:
|
||||
if is_valid_ip(addr):
|
||||
if is_valid_ip_interface(addr):
|
||||
return get_netmask(addr)
|
||||
else:
|
||||
return None
|
||||
|
@ -1838,7 +1899,7 @@ class ModuleParameters(Parameters):
|
|||
def port(self):
|
||||
if self._values['port'] is None:
|
||||
return None
|
||||
if self._values['port'] in ['*', 'any']:
|
||||
if self._values['port'] in ['*', 'any', '0']:
|
||||
return 0
|
||||
if self._values['port'] in self.services_map:
|
||||
port = self._values['port']
|
||||
|
@ -1948,15 +2009,6 @@ class ModuleParameters(Parameters):
|
|||
return None
|
||||
elif any(x.lower() for x in self._values['enabled_vlans'] if x.lower() in ['all', '*']):
|
||||
result = [fq_name(self.partition, 'all')]
|
||||
if result[0].endswith('/all'):
|
||||
if self._values['__warnings'] is None:
|
||||
self._values['__warnings'] = []
|
||||
self._values['__warnings'].append(
|
||||
dict(
|
||||
msg="Usage of the 'ALL' value for 'enabled_vlans' parameter is deprecated. Use '*' instead",
|
||||
version='2.9'
|
||||
)
|
||||
)
|
||||
return result
|
||||
results = list(set([fq_name(self.partition, x) for x in self._values['enabled_vlans']]))
|
||||
results.sort()
|
||||
|
@ -2436,9 +2488,6 @@ class VirtualServerValidator(object):
|
|||
self.module = module
|
||||
|
||||
def check_update(self):
|
||||
# TODO(Remove in Ansible 2.9)
|
||||
self._override_standard_type_from_profiles()
|
||||
|
||||
# Regular checks
|
||||
self._override_port_by_type()
|
||||
self._override_protocol_by_type()
|
||||
|
@ -2455,9 +2504,6 @@ class VirtualServerValidator(object):
|
|||
self._verify_stateless_profile()
|
||||
|
||||
def check_create(self):
|
||||
# TODO(Remove in Ansible 2.9)
|
||||
self._override_standard_type_from_profiles()
|
||||
|
||||
# Regular checks
|
||||
self._set_default_ip_protocol()
|
||||
self._set_default_profiles()
|
||||
|
@ -2528,44 +2574,6 @@ class VirtualServerValidator(object):
|
|||
if self.want.type in ['stateless']:
|
||||
self.want.update({'ip_protocol': 17})
|
||||
|
||||
def _override_standard_type_from_profiles(self):
|
||||
"""Overrides a standard virtual server type given the specified profiles
|
||||
|
||||
For legacy purposes, this module will do some basic overriding of the default
|
||||
``type`` parameter to support cases where changing the ``type`` only requires
|
||||
specifying a different set of profiles.
|
||||
|
||||
Ideally, ``type`` would always be specified, but in the past, this module only
|
||||
supported an implicit "standard" type. Module users would specify some different
|
||||
types of profiles and this would change the type...in some circumstances.
|
||||
|
||||
Now that this module supports a ``type`` param, the implicit ``type`` changing
|
||||
that used to happen is technically deprecated (and will be warned on). Users
|
||||
should always specify a ``type`` now, or, accept the default standard type.
|
||||
|
||||
Returns:
|
||||
void
|
||||
"""
|
||||
if self.want.type == 'standard':
|
||||
if self.want.has_fastl4_profiles:
|
||||
self.want.update({'type': 'performance-l4'})
|
||||
self.module.deprecate(
|
||||
msg="Specifying 'performance-l4' profiles on a 'standard' type is deprecated and will be removed.",
|
||||
version='2.10'
|
||||
)
|
||||
if self.want.has_fasthttp_profiles:
|
||||
self.want.update({'type': 'performance-http'})
|
||||
self.module.deprecate(
|
||||
msg="Specifying 'performance-http' profiles on a 'standard' type is deprecated and will be removed.",
|
||||
version='2.10'
|
||||
)
|
||||
if self.want.has_message_routing_profiles:
|
||||
self.want.update({'type': 'message-routing'})
|
||||
self.module.deprecate(
|
||||
msg="Specifying 'message-routing' profiles on a 'standard' type is deprecated and will be removed.",
|
||||
version='2.10'
|
||||
)
|
||||
|
||||
def _check_source_and_destination_match(self):
|
||||
"""Verify that destination and source are of the same IP version
|
||||
|
||||
|
@ -2580,7 +2588,7 @@ class VirtualServerValidator(object):
|
|||
F5ModuleError: Raised when the IP versions of source and destination differ.
|
||||
"""
|
||||
if self.want.source and self.want.destination:
|
||||
want = ip_interface(u'{0}'.format(self.want.source))
|
||||
want = ip_interface(u'{0}/{1}'.format(self.want.source_tuple.ip, self.want.source_tuple.cidr))
|
||||
have = ip_interface(u'{0}'.format(self.want.destination_tuple.ip))
|
||||
if want.version != have.version:
|
||||
raise F5ModuleError(
|
||||
|
@ -3025,7 +3033,7 @@ class Difference(object):
|
|||
return
|
||||
|
||||
addr_tuple = [self.want.destination, self.want.port, self.want.route_domain]
|
||||
if all(x for x in addr_tuple if x is None):
|
||||
if all(x is None for x in addr_tuple):
|
||||
return None
|
||||
|
||||
have = self.have.destination_tuple
|
||||
|
|
Loading…
Reference in a new issue