Revision 691c81b7

b/lib/rapi/connector.py
31 31

  
32 32
from ganeti import constants
33 33
from ganeti import http
34
from ganeti import utils
34 35

  
35 36
from ganeti.rapi import baserlib
36 37
from ganeti.rapi import rlib2
......
76 77
      query = None
77 78
      args = {}
78 79

  
79
    result = None
80
    # Try to find handler for request path
81
    result = utils.FindMatch(self._connector, path)
80 82

  
81
    for key, handler in self._connector.iteritems():
82
      # Regex objects
83
      if hasattr(key, "match"):
84
        m = key.match(path)
85
        if m:
86
          result = (handler, list(m.groups()), args)
87
          break
83
    if result is None:
84
      raise http.HttpNotFound()
88 85

  
89
      # String objects
90
      elif key == path:
91
        result = (handler, [], args)
92
        break
86
    (handler, groups) = result
93 87

  
94
    if result:
95
      return result
96
    else:
97
      raise http.HttpNotFound()
88
    return (handler, groups, args)
98 89

  
99 90

  
100 91
class R_root(baserlib.R_Generic):
b/lib/utils.py
2959 2959
  return ", ".join([str(val) for val in names])
2960 2960

  
2961 2961

  
2962
def FindMatch(data, name):
2963
  """Tries to find an item in a dictionary matching a name.
2964

  
2965
  Callers have to ensure the data names aren't contradictory (e.g. a regexp
2966
  that matches a string). If the name isn't a direct key, all regular
2967
  expression objects in the dictionary are matched against it.
2968

  
2969
  @type data: dict
2970
  @param data: Dictionary containing data
2971
  @type name: string
2972
  @param name: Name to look for
2973
  @rtype: tuple; (value in dictionary, matched groups as list)
2974

  
2975
  """
2976
  if name in data:
2977
    return (data[name], [])
2978

  
2979
  for key, value in data.items():
2980
    # Regex objects
2981
    if hasattr(key, "match"):
2982
      m = key.match(name)
2983
      if m:
2984
        return (value, list(m.groups()))
2985

  
2986
  return None
2987

  
2988

  
2962 2989
def BytesToMebibyte(value):
2963 2990
  """Converts bytes to mebibytes.
2964 2991

  
b/test/ganeti.utils_unittest.py
2326 2326
                     "Hello, World, 99")
2327 2327

  
2328 2328

  
2329
class TestFindMatch(unittest.TestCase):
2330
  def test(self):
2331
    data = {
2332
      "aaaa": "Four A",
2333
      "bb": {"Two B": True},
2334
      re.compile(r"^x(foo|bar|bazX)([0-9]+)$"): (1, 2, 3),
2335
      }
2336

  
2337
    self.assertEqual(utils.FindMatch(data, "aaaa"), ("Four A", []))
2338
    self.assertEqual(utils.FindMatch(data, "bb"), ({"Two B": True}, []))
2339

  
2340
    for i in ["foo", "bar", "bazX"]:
2341
      for j in range(1, 100, 7):
2342
        self.assertEqual(utils.FindMatch(data, "x%s%s" % (i, j)),
2343
                         ((1, 2, 3), [i, str(j)]))
2344

  
2345
  def testNoMatch(self):
2346
    self.assert_(utils.FindMatch({}, "") is None)
2347
    self.assert_(utils.FindMatch({}, "foo") is None)
2348
    self.assert_(utils.FindMatch({}, 1234) is None)
2349

  
2350
    data = {
2351
      "X": "Hello World",
2352
      re.compile("^(something)$"): "Hello World",
2353
      }
2354

  
2355
    self.assert_(utils.FindMatch(data, "") is None)
2356
    self.assert_(utils.FindMatch(data, "Hello World") is None)
2357

  
2358

  
2329 2359
if __name__ == '__main__':
2330 2360
  testutils.GanetiTestProgram()

Also available in: Unified diff