Skip to content

Commit cd000a0

Browse files
authored
Merge pull request #49 from ezh/feature/tag-regex
Add regex to simple groups
2 parents f0337ba + b57c6c9 commit cd000a0

File tree

4 files changed

+45
-62
lines changed

4 files changed

+45
-62
lines changed

cloudselect/cloudselect.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
# except according to those terms.
88
"""CloudSelect module loads configuration, plugins and invokes Select module."""
99
import argparse
10+
import copy
1011
import inspect
1112
import json
1213
import logging
@@ -197,7 +198,7 @@ def merge(dict1, dict2, path=None):
197198
def options(self, name, metadata=None):
198199
"""Get plugin/block options."""
199200
group = Container.group()
200-
base = Container.config().get(name, {})
201+
base = copy.deepcopy(Container.config().get(name, {}))
201202
override = group.run(name, metadata)
202203
return self.merge(base, override)
203204

cloudselect/group/simple.py

Lines changed: 29 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
# except according to those terms.
88
"""Module returning appropriate options per group of instances."""
99
import logging
10+
import re
1011

1112
from . import GroupService
1213

@@ -21,52 +22,34 @@ def __init__(self):
2122

2223
def run(self, name, metadata):
2324
"""Return dictionary with options for the group of instances."""
24-
groups_by_priority = list(self.get_groups_with_priority(self.config()))
25-
26-
for priority, filters, group in sorted(groups_by_priority, key=lambda x: x[0]):
27-
self.logger.debug("Process group %s %s", priority, filters)
28-
for entry in filters:
29-
if entry == "*":
25+
for group in self.config().get("options", []):
26+
self.logger.debug("Process group %s", group)
27+
entry = group.get("match")
28+
if not entry:
29+
self.logger.warning("Unable to find 'match' key in %s", group)
30+
continue
31+
if ":" not in entry:
32+
self.logger.warning(
33+
"Unable to parse 'match' value %s for %s", entry, group,
34+
)
35+
continue
36+
key, pattern = entry.split(":", 1)
37+
regex = re.compile(pattern)
38+
value = metadata
39+
for key_part in key.split("."):
40+
try:
41+
value = value.get(key_part)
42+
if not value:
43+
self.logger.debug("Unable to find key %s", key_part)
44+
break
45+
except (AttributeError, NameError):
46+
self.logger.debug("Unable to find key %s", key_part)
47+
break
48+
if isinstance(value, str) and regex.match(value):
49+
self.logger.debug(
50+
"Match pattern %s and value %s", pattern, value,
51+
)
3052
result = group.get(name)
31-
if result:
53+
if result is not None:
3254
return result
33-
elif ":" in entry:
34-
key, pattern = entry.split(":", 1)
35-
value = metadata
36-
for key_part in key.split("."):
37-
try:
38-
value = value.get(key_part)
39-
if not value:
40-
self.logger.debug("Unable to find key %s", key_part)
41-
break
42-
except Exception:
43-
self.logger.debug("Unable to find key %s", key_part)
44-
break
45-
if pattern in value:
46-
self.logger.debug(
47-
"Match pattern %s and value %s", pattern, value,
48-
)
49-
result = group.get(name)
50-
if result is not None:
51-
return result
52-
else:
53-
self.logger.warning(
54-
"Unable to find filter definition for %s", group,
55-
)
5655
return {}
57-
58-
def get_groups_with_priority(self, groups):
59-
"""Extract priority for groups."""
60-
for pattern in groups:
61-
group = groups[pattern]
62-
if not isinstance(group, dict):
63-
logging.debug("Skip group with pattern %s", pattern)
64-
continue
65-
filters = pattern.split(" ", 1)
66-
priority = self.default_priority
67-
if len(filters) == 2 and filters[0].isdigit():
68-
priority = int(filters[0])
69-
filters = filters[-1].split(",")
70-
else:
71-
filters = pattern
72-
yield [priority, filters, group]

tasks.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ def release(ctx, version):
4848
),
4949
)
5050
ctx.run("git push")
51+
ctx.run("gren release --tags={}".format(version))
5152
except Failure as e:
5253
print(e)
5354

test/group/test_simple.py

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ def test_options(tmpdir):
1717
1818
It should returns {} if there is no options.
1919
It should returns shared dictionary if there is no any matched filters.
20-
It should returns clarified dictionary if there is * filter.
2120
It should returns clarified dictionary if there is matched filter.
2221
"""
2322
cloud = CloudSelect(tmpdir)
@@ -39,19 +38,18 @@ def test_options(tmpdir):
3938
configuration["option"] = options_a
4039
assert Container.options("option") == options_a
4140

42-
configuration["group"]["*"] = {"option": options_a}
41+
configuration["group"]["options"] = [{"match": "x:y", "option": options_a}]
4342
assert Container.options("option") == options_a
44-
assert Container.options("option", {"a": {"b": "c"}}) == options_a
45-
46-
configuration["group"]["*"] = {"option": options_b}
47-
assert Container.options("option") == options_b
48-
assert Container.options("option", {"a": {"b": "c"}}) == options_b
49-
50-
configuration["group"]["0 a.b:c"] = {"option": options_c}
51-
assert Container.options("option") == options_b
52-
assert Container.options("option", {"a": {"b": "c"}}) == options_c
53-
assert Container.options("option", {"a": {"b": "d"}}) == options_b
54-
assert (
55-
Container.options("option", {"a": {"b": "long string with c inside"}})
56-
== options_c
43+
assert Container.options("option", {"a": {"b": "c123"}}) == options_a
44+
45+
configuration["group"]["options"].append({"match": "a.b:c123", "option": options_b})
46+
assert Container.options("option") == options_a
47+
assert Container.options("option", {"a": {"b": "c123"}}) == options_b
48+
49+
configuration["group"]["options"].append(
50+
{"match": "a.b:c(.*3|111)", "option": options_c},
5751
)
52+
assert Container.options("option") == options_a
53+
assert Container.options("option", {"a": {"b": "c1nnnn3"}}) == options_c
54+
assert Container.options("option", {"a": {"b": "c111111"}}) == options_c
55+
assert Container.options("option", {"a": {"b": "c112111"}}) == options_a

0 commit comments

Comments
 (0)