From 0499aadae67d06e1f960dca051ac81ae791428a9 Mon Sep 17 00:00:00 2001 From: Evgeni Golov Date: Tue, 17 Nov 2020 10:09:33 +0100 Subject: [PATCH] host - improve validation and conversion of MAC addresses --- changelogs/fragments/host-validate_mac.yml | 2 ++ plugins/modules/host.py | 31 +++++++++++++++++----- 2 files changed, 26 insertions(+), 7 deletions(-) create mode 100644 changelogs/fragments/host-validate_mac.yml diff --git a/changelogs/fragments/host-validate_mac.yml b/changelogs/fragments/host-validate_mac.yml new file mode 100644 index 0000000000..005359c826 --- /dev/null +++ b/changelogs/fragments/host-validate_mac.yml @@ -0,0 +1,2 @@ +minor_changes: + - host - improve validation and conversion of MAC addresses diff --git a/plugins/modules/host.py b/plugins/modules/host.py index 76764ecfb9..b614294bb4 100644 --- a/plugins/modules/host.py +++ b/plugins/modules/host.py @@ -74,9 +74,7 @@ mac: description: - MAC address of the primary interface of the host. - - Please include leading zeros and separate nibbles by colons, otherwise the execution will not be idempotent. - - Example EE:BB:01:02:03:04 - type: str + type: mac required: false comment: description: @@ -383,6 +381,8 @@ ForemanEntityAnsibleModule, HostMixin, ) +from ansible.module_utils.basic import check_type_str +import re def ensure_host_interfaces(module, entity, interfaces): @@ -433,6 +433,26 @@ class ForemanHostModule(HostMixin, ForemanEntityAnsibleModule): pass +MAC_REGEXP = r'([a-f0-9]{1,2}:){5}[a-f0-9]{1,2}' +MAC_REGEXP_64BIT = r'([a-f0-9]{1,2}:){19}[a-f0-9]{1,2}' + + +def mac(value): + final_value = check_type_str(value) + if ':' in final_value: + split_by = ':' + elif '-' in final_value: + split_by = '-' + else: + raise TypeError("'{0}' is not a valid MAC address".format(value)) + mac_parts = final_value.split(split_by) + final_value = ':'.join([part.zfill(2) for part in mac_parts]) + final_value = final_value.lower() + if (len(final_value) == 17 and re.match(MAC_REGEXP, final_value, re.IGNORECASE)) or (len(final_value) == 59 and re.match(MAC_REGEXP_64BIT, final_value)): + return final_value + raise TypeError("'{0}' is not a valid MAC address".format(value)) + + def main(): module = ForemanHostModule( foreman_spec=dict( @@ -444,7 +464,7 @@ def main(): managed=dict(type='bool'), build=dict(type='bool'), ip=dict(), - mac=dict(), + mac=dict(type=mac), comment=dict(), owner=dict(type='entity', resource_type='users', flat_name='owner_id'), owner_group=dict(type='entity', resource_type='usergroups', flat_name='owner_id'), @@ -476,9 +496,6 @@ def main(): # When 'build' is not given and 'managed'=False, have to clear 'build' context that might exist on the server. module.foreman_params['build'] = False - if 'mac' in module.foreman_params: - module.foreman_params['mac'] = module.foreman_params['mac'].lower() - if 'owner' in module.foreman_params: module.foreman_params['owner_type'] = 'User' elif 'owner_group' in module.foreman_params: