Revision bbfed756
b/lib/utils/text.py | ||
---|---|---|
74 | 74 |
if not case_sensitive: |
75 | 75 |
re_flags |= re.IGNORECASE |
76 | 76 |
key = key.upper() |
77 |
mo = re.compile("^%s(\..*)?$" % re.escape(key), re_flags) |
|
77 |
|
|
78 |
name_re = re.compile(r"^%s(\..*)?$" % re.escape(key), re_flags) |
|
79 |
|
|
78 | 80 |
names_filtered = [] |
79 | 81 |
string_matches = [] |
80 | 82 |
for name in name_list: |
81 |
if mo.match(name) is not None:
|
|
83 |
if name_re.match(name) is not None:
|
|
82 | 84 |
names_filtered.append(name) |
83 | 85 |
if not case_sensitive and key == name.upper(): |
84 | 86 |
string_matches.append(name) |
... | ... | |
87 | 89 |
return string_matches[0] |
88 | 90 |
if len(names_filtered) == 1: |
89 | 91 |
return names_filtered[0] |
92 |
|
|
90 | 93 |
return None |
91 | 94 |
|
92 | 95 |
|
96 |
def _DnsNameGlobHelper(match): |
|
97 |
"""Helper function for L{DnsNameGlobPattern}. |
|
98 |
|
|
99 |
Returns regular expression pattern for parts of the pattern. |
|
100 |
|
|
101 |
""" |
|
102 |
text = match.group(0) |
|
103 |
|
|
104 |
if text == "*": |
|
105 |
return "[^.]*" |
|
106 |
elif text == "?": |
|
107 |
return "[^.]" |
|
108 |
else: |
|
109 |
return re.escape(text) |
|
110 |
|
|
111 |
|
|
112 |
def DnsNameGlobPattern(pattern): |
|
113 |
"""Generates regular expression from DNS name globbing pattern. |
|
114 |
|
|
115 |
A DNS name globbing pattern (e.g. C{*.site}) is converted to a regular |
|
116 |
expression. Escape sequences or ranges (e.g. [a-z]) are not supported. |
|
117 |
|
|
118 |
Matching always starts at the leftmost part. An asterisk (*) matches all |
|
119 |
characters except the dot (.) separating DNS name parts. A question mark (?) |
|
120 |
matches a single character except the dot (.). |
|
121 |
|
|
122 |
@type pattern: string |
|
123 |
@param pattern: DNS name globbing pattern |
|
124 |
@rtype: string |
|
125 |
@return: Regular expression |
|
126 |
|
|
127 |
""" |
|
128 |
return r"^%s(\..*)?$" % re.sub(r"\*|\?|[^*?]*", _DnsNameGlobHelper, pattern) |
|
129 |
|
|
130 |
|
|
93 | 131 |
def FormatUnit(value, units): |
94 | 132 |
"""Formats an incoming number of MiB with the appropriate unit. |
95 | 133 |
|
b/test/ganeti.utils.text_unittest.py | ||
---|---|---|
106 | 106 |
None) |
107 | 107 |
|
108 | 108 |
|
109 |
class TestDnsNameGlobPattern(unittest.TestCase): |
|
110 |
def setUp(self): |
|
111 |
self.names = [ |
|
112 |
"node1.example.com", |
|
113 |
"node2-0.example.com", |
|
114 |
"node2-1.example.com", |
|
115 |
"node1.example.net", |
|
116 |
"web1.example.com", |
|
117 |
"web2.example.com", |
|
118 |
"sub.site.example.com", |
|
119 |
] |
|
120 |
|
|
121 |
def _Test(self, pattern): |
|
122 |
re_pat = utils.DnsNameGlobPattern(pattern) |
|
123 |
|
|
124 |
return filter(re.compile(re_pat).match, self.names) |
|
125 |
|
|
126 |
def test(self): |
|
127 |
for pattern in ["xyz", "node", " ", "example.net", "x*.example.*", |
|
128 |
"x*.example.com"]: |
|
129 |
self.assertEqual(self._Test(pattern), []) |
|
130 |
|
|
131 |
for pattern in ["*", "???*"]: |
|
132 |
self.assertEqual(self._Test(pattern), self.names) |
|
133 |
|
|
134 |
self.assertEqual(self._Test("node1.*.net"), ["node1.example.net"]) |
|
135 |
self.assertEqual(self._Test("*.example.net"), ["node1.example.net"]) |
|
136 |
self.assertEqual(self._Test("web1.example.com"), ["web1.example.com"]) |
|
137 |
|
|
138 |
for pattern in ["*.*.*.*", "???", "*.site"]: |
|
139 |
self.assertEqual(self._Test(pattern), ["sub.site.example.com"]) |
|
140 |
|
|
141 |
self.assertEqual(self._Test("node1"), [ |
|
142 |
"node1.example.com", |
|
143 |
"node1.example.net", |
|
144 |
]) |
|
145 |
self.assertEqual(self._Test("node?*.example.*"), [ |
|
146 |
"node1.example.com", |
|
147 |
"node2-0.example.com", |
|
148 |
"node2-1.example.com", |
|
149 |
"node1.example.net", |
|
150 |
]) |
|
151 |
self.assertEqual(self._Test("*-?"), [ |
|
152 |
"node2-0.example.com", |
|
153 |
"node2-1.example.com", |
|
154 |
]) |
|
155 |
self.assertEqual(self._Test("node2-?.example.com"), [ |
|
156 |
"node2-0.example.com", |
|
157 |
"node2-1.example.com", |
|
158 |
]) |
|
159 |
|
|
160 |
|
|
109 | 161 |
class TestFormatUnit(unittest.TestCase): |
110 | 162 |
"""Test case for the FormatUnit function""" |
111 | 163 |
|
Also available in: Unified diff