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:
Wojciech Wypior 2019-08-22 04:58:11 +01:00 committed by Tim Rupp
parent e5243ef1d7
commit 8bfa7569b5
2 changed files with 100 additions and 93 deletions

View file

@ -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:

View file

@ -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