From 0db398d6e89e811f3900f236faf07f6055f46276 Mon Sep 17 00:00:00 2001 From: Michal Opala Date: Mon, 25 May 2026 01:06:18 +0200 Subject: [PATCH] M #-: Move 'match_address' to module_utils (fix) - Move match_address test to module_utils - Remove hardcoded python shebang (fix) - Add missing 'pattern' argument description (fix) Signed-off-by: Michal Opala --- plugins/module_utils/main.py | 26 ++++++++++++++++++++++++++ plugins/test/main.py | 30 ++---------------------------- plugins/test/match_address.yml | 5 +++++ 3 files changed, 33 insertions(+), 28 deletions(-) diff --git a/plugins/module_utils/main.py b/plugins/module_utils/main.py index 4a3946a5..f697eaf9 100644 --- a/plugins/module_utils/main.py +++ b/plugins/module_utils/main.py @@ -3,6 +3,32 @@ # Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) +# NOTE: It does not validate character classes or character count! +# EXAMPLES: +# pci -> match_address('0000:0*:00.*', sep='[:.]') +# mac -> match_address('52:54:*:*:*:0*', sep='[:]') +def match_address(address, pattern, sep=None): + """Tests if a split string matches a set of simple glob patterns.""" + + import fnmatch + import re + + # In case no separator is provided simply match the whole string. + if sep is None: + return fnmatch.fnmatch(address, pattern) + + # Make sure both address and pattern contain identical separators. + if re.findall(sep, address) != re.findall(sep, pattern): + return False + + # Try matching (glob) each segment separately. + for x, y in zip(re.split(sep, address), re.split(sep, pattern)): + if not fnmatch.fnmatch(x, y): + return False + + return True + + def flatten(to_flatten, extract=False): """Flattens nested lists (with optional value extraction).""" diff --git a/plugins/test/main.py b/plugins/test/main.py index b8b2d9a8..65a392e7 100644 --- a/plugins/test/main.py +++ b/plugins/test/main.py @@ -1,32 +1,6 @@ -#!/usr/bin/env python +from ansible_collections.opennebula.deploy.plugins.module_utils.main import match_address -import fnmatch -import re class TestModule(object): def tests(self): - return { - 'match_address': self.match_address, - } - - # NOTE: It does not validate character classes or character count! - # EXAMPLES: - # pci -> match_address('0000:0*:00.*', sep='[:.]') - # mac -> match_address('52:54:*:*:*:0*', sep='[:]') - def match_address(self, address, pattern, sep=None): - """Tests if a split string matches a set of simple glob patterns.""" - - # In case no separator is provided simply match the whole string. - if sep is None: - return fnmatch.fnmatch(address, pattern) - - # Make sure both address and pattern contain identical separators. - if re.findall(sep, address) != re.findall(sep, pattern): - return False - - # Try matching (glob) each segment separately. - for x, y in zip(re.split(sep, address), re.split(sep, pattern)): - if not fnmatch.fnmatch(x, y): - return False - - return True + return dict(match_address=match_address) diff --git a/plugins/test/match_address.yml b/plugins/test/match_address.yml index 56cb543e..ce889591 100644 --- a/plugins/test/match_address.yml +++ b/plugins/test/match_address.yml @@ -13,6 +13,11 @@ DOCUMENTATION: - An address to match. type: string required: true + pattern: + description: + - A string containing a sequence of glob patterns. + type: string + required: true sep: description: - A regex expression used to split the input string (optional).