Skip to content

Commit

Permalink
multiples fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
abikouo committed Jul 27, 2021
1 parent d4b83b3 commit 576b61f
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 56 deletions.
3 changes: 3 additions & 0 deletions molecule/default/converge.yml
Expand Up @@ -169,6 +169,9 @@
file: tasks/label_selectors.yml
apply:
tags: [ label_selectors, k8s ]
tags:
- always

- name: Include diff.yml
include_tasks:
file: tasks/diff.yml
Expand Down
65 changes: 20 additions & 45 deletions plugins/module_utils/selector.py
Expand Up @@ -12,10 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.


from __future__ import absolute_import, division, print_function
__metaclass__ = type

import re


Expand All @@ -25,62 +21,41 @@ class Selector(object):

def __init__(self, data):
self._operator = None
self._data = ''
self.define_set_based_requirement(data)
if not self._set_based_requirement:
self.define_equality_based_requirement(data)

def define_set_based_requirement(self, data):
self._set_based_requirement = False
m = re.match(r'( *)([a-z0-9A-Z][a-z0-9A-Z\._-]*[a-z0-9A-Z])( *)(notin|in)( *)\((.*)\)( *)', data)
self._data = None
if not self.parse_set_based_requirement(data):
no_whitespace_data = data.replace(" ", "")
for op in self.equality_based_operators:
idx = no_whitespace_data.find(op)
if idx != -1:
self._operator = "in" if op == '==' or op == '=' else "notin"
self._key = no_whitespace_data[0:idx]
self._data = [no_whitespace_data[idx + len(op):]]
break

def parse_set_based_requirement(self, data):
m = re.match(r'( *)([a-z0-9A-Z][a-z0-9A-Z\._-]*[a-z0-9A-Z])( +)(notin|in)( +)\((.*)\)( *)', data)
if m:
self._set_based_requirement = True
self._key = m.group(2)
self._operator = m.group(4)
self._data = [x.replace(' ', '') for x in m.group(6).split(',') if x != '']
return True
elif all([x not in data for x in self.equality_based_operators]):
self._set_based_requirement = True
data = data.replace(" ", "")
self._key = data
if data.startswith("!"):
self._key = data[1:]
self._key = data.rstrip(" ").lstrip(" ")
if self._key.startswith("!"):
self._key = self._key[1:].lstrip(" ")
self._operator = "!"
return True
return False

def define_equality_based_requirement(self, data):
data_selector = data.replace(" ", "")
for sep in self.equality_based_operators:
pos = data_selector.find(sep)
if pos != -1:
break
if pos == -1:
self._key = data_selector
else:
self._key = data_selector[0:pos]
self._operator = sep
self._data = data_selector[pos + len(sep):]

def filter_equality_based_requirement(self, labels):
if self._key not in labels:
return False
if self._operator in ('=', '=='):
return self._data == labels.get(self._key)
elif self._operator == '!=':
return self._data != labels.get(self._key)
return True

def filter_set_based_requirement(self, labels):
def isMatch(self, labels):
if self._operator == "in":
return self._key in labels and labels.get(self._key) in self._data
elif self._operator == "notin":
return self._key not in labels or labels.get(self._key) not in self._data
else:
return self._key not in labels if self._operator == "!" else self._key in labels

def isMatch(self, labels):
if self._set_based_requirement:
return self.filter_set_based_requirement(labels)
return self.filter_equality_based_requirement(labels)


class LabelSelectorFilter(object):

Expand Down
6 changes: 5 additions & 1 deletion tests/sanity/ignore-2.10.txt
Expand Up @@ -240,4 +240,8 @@ plugins/modules/k8s_cp.py import-2.6!skip
plugins/modules/k8s_cp.py import-2.7!skip
molecule/default/roles/k8scopy/library/kubectl_file_compare.py compile-2.6!skip
molecule/default/roles/k8scopy/library/kubectl_file_compare.py compile-2.7!skip
molecule/default/roles/k8scopy/library/kubectl_file_compare.py compile-3.5!skip
molecule/default/roles/k8scopy/library/kubectl_file_compare.py compile-3.5!skip
tests/unit/module_utils/test_selector.py future-import-boilerplate!skip
tests/unit/module_utils/test_selector.py metaclass-boilerplate!skip
plugins/module_utils/selector.py future-import-boilerplate!skip
plugins/module_utils/selector.py metaclass-boilerplate!skip
6 changes: 5 additions & 1 deletion tests/sanity/ignore-2.11.txt
Expand Up @@ -240,4 +240,8 @@ plugins/modules/k8s_cp.py import-2.6!skip
plugins/modules/k8s_cp.py import-2.7!skip
molecule/default/roles/k8scopy/library/kubectl_file_compare.py compile-2.6!skip
molecule/default/roles/k8scopy/library/kubectl_file_compare.py compile-2.7!skip
molecule/default/roles/k8scopy/library/kubectl_file_compare.py compile-3.5!skip
molecule/default/roles/k8scopy/library/kubectl_file_compare.py compile-3.5!skip
tests/unit/module_utils/test_selector.py future-import-boilerplate!skip
tests/unit/module_utils/test_selector.py metaclass-boilerplate!skip
plugins/module_utils/selector.py future-import-boilerplate!skip
plugins/module_utils/selector.py metaclass-boilerplate!skip
4 changes: 3 additions & 1 deletion tests/sanity/ignore-2.12.txt
Expand Up @@ -238,4 +238,6 @@ tests/sanity/refresh_ignore_files shebang!skip
plugins/modules/k8s_cp.py compile-2.6!skip
plugins/modules/k8s_cp.py compile-2.7!skip
plugins/modules/k8s_cp.py import-2.6!skip
plugins/modules/k8s_cp.py import-2.7!skip
plugins/modules/k8s_cp.py import-2.7!skip
plugins/module_utils/selector.py future-import-boilerplate!skip
plugins/module_utils/selector.py metaclass-boilerplate!skip
6 changes: 5 additions & 1 deletion tests/sanity/ignore-2.9.txt
Expand Up @@ -234,4 +234,8 @@ plugins/modules/k8s_cp.py import-2.6!skip
plugins/modules/k8s_cp.py import-2.7!skip
molecule/default/roles/k8scopy/library/kubectl_file_compare.py compile-2.6!skip
molecule/default/roles/k8scopy/library/kubectl_file_compare.py compile-2.7!skip
molecule/default/roles/k8scopy/library/kubectl_file_compare.py compile-3.5!skip
molecule/default/roles/k8scopy/library/kubectl_file_compare.py compile-3.5!skip
tests/unit/module_utils/test_selector.py future-import-boilerplate!skip
tests/unit/module_utils/test_selector.py metaclass-boilerplate!skip
plugins/module_utils/selector.py future-import-boilerplate!skip
plugins/module_utils/selector.py metaclass-boilerplate!skip
43 changes: 36 additions & 7 deletions tests/unit/module_utils/test_selector.py
Expand Up @@ -12,11 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.


from __future__ import absolute_import, division, print_function
__metaclass__ = type

from ansible_collections.kubernetes.core.plugins.module_utils.selector import LabelSelectorFilter
from ansible_collections.kubernetes.core.plugins.module_utils.selector import LabelSelectorFilter, Selector

prod_definition = {
'apiVersion': 'v1',
Expand Down Expand Up @@ -67,6 +63,39 @@
}


def test_selector_parser():
f_selector = "environment==true"
sel = Selector(f_selector)
assert sel._operator == "in" and sel._data == ["true"] and sel._key == "environment"
f_selector = "environment=true"
sel = Selector(f_selector)
assert sel._operator == "in" and sel._data == ["true"] and sel._key == "environment"
f_selector = " environment == true "
sel = Selector(f_selector)
assert sel._operator == "in" and sel._data == ["true"] and sel._key == "environment"
f_selector = "environment!=false"
sel = Selector(f_selector)
assert sel._operator == "notin" and sel._data == ["false"] and sel._key == "environment"
f_selector = "environment notin (true, false)"
sel = Selector(f_selector)
assert sel._operator == "notin" and "true" in sel._data and "false" in sel._data and sel._key == "environment"
f_selector = "environment in (true, false)"
sel = Selector(f_selector)
assert sel._operator == "in" and "true" in sel._data and "false" in sel._data and sel._key == "environment"
f_selector = "environmentin(true, false)"
sel = Selector(f_selector)
assert not sel._operator and not sel._data and sel._key == f_selector
f_selector = "environment notin (true, false"
sel = Selector(f_selector)
assert not sel._operator and not sel._data and sel._key == f_selector
f_selector = "!environment"
sel = Selector(f_selector)
assert sel._operator == "!" and not sel._data and sel._key == "environment"
f_selector = "! environment "
sel = Selector(f_selector)
assert sel._operator == "!" and not sel._data and sel._key == "environment"


def test_label_selector_without_operator():
label_selector = ['environment', 'app']
assert LabelSelectorFilter(label_selector).isMatching(prod_definition)
Expand Down Expand Up @@ -100,11 +129,11 @@ def test_label_selector_equal_operator():
def test_label_selector_notequal_operator():
label_selector = ['environment!=test']
assert LabelSelectorFilter(label_selector).isMatching(prod_definition)
assert not LabelSelectorFilter(label_selector).isMatching(no_label_definition)
assert LabelSelectorFilter(label_selector).isMatching(no_label_definition)
assert not LabelSelectorFilter(label_selector).isMatching(test_definition)
label_selector = ['environment!=production']
assert not LabelSelectorFilter(label_selector).isMatching(prod_definition)
assert not LabelSelectorFilter(label_selector).isMatching(no_label_definition)
assert LabelSelectorFilter(label_selector).isMatching(no_label_definition)
assert LabelSelectorFilter(label_selector).isMatching(test_definition)
label_selector = ['environment=production', 'app!=mongodb']
assert LabelSelectorFilter(label_selector).isMatching(prod_definition)
Expand Down

0 comments on commit 576b61f

Please sign in to comment.