[PATCH phosphor-rest-server v2 2/2] Convert all tabs to 4 spaces.
OpenBMC Patches
openbmc-patches at stwcx.xyz
Mon Feb 1 12:30:31 AEDT 2016
From: shgoupf <shgoupf at cn.ibm.com>
Make python indent convention to 4 spaces accroding to PEP8.
---
obmc-rest | 1458 ++++++++++++++++++++++++++++++-------------------------------
1 file changed, 729 insertions(+), 729 deletions(-)
diff --git a/obmc-rest b/obmc-rest
index 481dafa..3070f9e 100755
--- a/obmc-rest
+++ b/obmc-rest
@@ -30,113 +30,113 @@ DELETE_IFACE = 'org.openbmc.Object.Delete'
_4034_msg = "The specified %s cannot be %s: '%s'"
def valid_user(session, *a, **kw):
- ''' Authorization plugin callback that checks that the user is logged in. '''
- if session is None:
- abort(403, 'Login required')
+ ''' Authorization plugin callback that checks that the user is logged in. '''
+ if session is None:
+ abort(403, 'Login required')
class UserInGroup:
- ''' Authorization plugin callback that checks that the user is logged in
- and a member of a group. '''
- def __init__(self, group):
- self.group = group
+ ''' Authorization plugin callback that checks that the user is logged in
+ and a member of a group. '''
+ def __init__(self, group):
+ self.group = group
- def __call__(self, session, *a, **kw):
- valid_user(session, *a, **kw)
- res = False
+ def __call__(self, session, *a, **kw):
+ valid_user(session, *a, **kw)
+ res = False
- try:
- res = session['user'] in grp.getgrnam(self.group)[3]
- except KeyError:
- pass
+ try:
+ res = session['user'] in grp.getgrnam(self.group)[3]
+ except KeyError:
+ pass
- if not res:
- abort(403, 'Insufficient access')
+ if not res:
+ abort(403, 'Insufficient access')
def find_case_insensitive(value, lst):
- return next((x for x in lst if x.lower() == value.lower()), None)
+ return next((x for x in lst if x.lower() == value.lower()), None)
def makelist(data):
- if isinstance(data, list):
- return data
- elif data:
- return [data]
- else:
- return []
+ if isinstance(data, list):
+ return data
+ elif data:
+ return [data]
+ else:
+ return []
class RouteHandler(object):
- _require_auth = makelist(valid_user)
- def __init__(self, app, bus, verbs, rules, skips = []):
- self.app = app
- self.bus = bus
- self.mapper = Mapper(bus)
- self._verbs = makelist(verbs)
- self._rules = rules
- self._skips = skips
-
- def _setup(self, **kw):
- request.route_data = {}
- if request.method in self._verbs:
- return self.setup(**kw)
- else:
- self.find(**kw)
- raise HTTPError(405, "Method not allowed.",
- Allow=','.join(self._verbs))
-
- def __call__(self, **kw):
- return getattr(self, 'do_' + request.method.lower())(**kw)
-
- def install(self):
- self.app.route(self._rules, callback = self, skip = self._skips,
- method = ['GET', 'PUT', 'PATCH', 'POST', 'DELETE'])
-
- @staticmethod
- def try_mapper_call(f, callback = None, **kw):
- try:
- return f(**kw)
- except dbus.exceptions.DBusException, e:
- if e.get_dbus_name() != OpenBMCMapper.MAPPER_NOT_FOUND:
- raise
- if callback is None:
- def callback(e, **kw):
- abort(404, str(e))
-
- callback(e, **kw)
-
- @staticmethod
- def try_properties_interface(f, *a):
- try:
- return f(*a)
- except dbus.exceptions.DBusException, e:
- if DBUS_UNKNOWN_INTERFACE in e.get_dbus_message():
- # interface doesn't have any properties
- return None
- if DBUS_UNKNOWN_METHOD == e.get_dbus_name():
- # properties interface not implemented at all
- return None
- raise
+ _require_auth = makelist(valid_user)
+ def __init__(self, app, bus, verbs, rules, skips = []):
+ self.app = app
+ self.bus = bus
+ self.mapper = Mapper(bus)
+ self._verbs = makelist(verbs)
+ self._rules = rules
+ self._skips = skips
+
+ def _setup(self, **kw):
+ request.route_data = {}
+ if request.method in self._verbs:
+ return self.setup(**kw)
+ else:
+ self.find(**kw)
+ raise HTTPError(405, "Method not allowed.",
+ Allow=','.join(self._verbs))
+
+ def __call__(self, **kw):
+ return getattr(self, 'do_' + request.method.lower())(**kw)
+
+ def install(self):
+ self.app.route(self._rules, callback = self, skip = self._skips,
+ method = ['GET', 'PUT', 'PATCH', 'POST', 'DELETE'])
+
+ @staticmethod
+ def try_mapper_call(f, callback = None, **kw):
+ try:
+ return f(**kw)
+ except dbus.exceptions.DBusException, e:
+ if e.get_dbus_name() != OpenBMCMapper.MAPPER_NOT_FOUND:
+ raise
+ if callback is None:
+ def callback(e, **kw):
+ abort(404, str(e))
+
+ callback(e, **kw)
+
+ @staticmethod
+ def try_properties_interface(f, *a):
+ try:
+ return f(*a)
+ except dbus.exceptions.DBusException, e:
+ if DBUS_UNKNOWN_INTERFACE in e.get_dbus_message():
+ # interface doesn't have any properties
+ return None
+ if DBUS_UNKNOWN_METHOD == e.get_dbus_name():
+ # properties interface not implemented at all
+ return None
+ raise
class SignalHandler(RouteHandler):
- verbs = ['GET']
- rules = '<path:path>/stream/<signal>'
+ verbs = ['GET']
+ rules = '<path:path>/stream/<signal>'
- def __init__(self, app, bus):
- super(SignalHandler, self).__init__(
- app, bus, self.verbs, self.rules)
+ def __init__(self, app, bus):
+ super(SignalHandler, self).__init__(
+ app, bus, self.verbs, self.rules)
- def find(self, path, signal):
- busses = self.try_mapper_call(self.mapper.get_object,
- path = path)
- for items in busses.iteritems():
- s = self.find_signal_on_bus(path, signal, *items)
- if s:
- return s
+ def find(self, path, signal):
+ busses = self.try_mapper_call(self.mapper.get_object,
+ path = path)
+ for items in busses.iteritems():
+ s = self.find_signal_on_bus(path, signal, *items)
+ if s:
+ return s
- abort(404, _4034_msg %('signal', 'found', signal))
+ abort(404, _4034_msg %('signal', 'found', signal))
- def setup(self, path, signal):
- request.route_data['map'] = self.find(path, signal)
+ def setup(self, path, signal):
+ request.route_data['map'] = self.find(path, signal)
- def do_get(self, path, signal):
+ def do_get(self, path, signal):
body = Queue()
dsignal = DbusSignal(bus, request.route_data['map'][0],
request.route_data['map'][1], path)
@@ -145,692 +145,692 @@ class SignalHandler(RouteHandler):
dsignal.signalSnooping()
return body
- @staticmethod
- def find_signal(signal, signals):
- if signals is None:
- return None
+ @staticmethod
+ def find_signal(signal, signals):
+ if signals is None:
+ return None
- signal = find_case_insensitive(signal, signals.keys())
- if signal is not None:
+ signal = find_case_insensitive(signal, signals.keys())
+ if signal is not None:
return signal
- def find_signal_on_bus(self, path, signal, bus, interfaces):
- obj = self.bus.get_object(bus, path, introspect = False)
- iface = dbus.Interface(obj, dbus.INTROSPECTABLE_IFACE)
- data = iface.Introspect()
- parser = IntrospectionNodeParser(
- ElementTree.fromstring(data),
- intf_match = ListMatch(interfaces))
- for x,y in parser.get_interfaces().iteritems():
- s = self.find_signal(signal,
+ def find_signal_on_bus(self, path, signal, bus, interfaces):
+ obj = self.bus.get_object(bus, path, introspect = False)
+ iface = dbus.Interface(obj, dbus.INTROSPECTABLE_IFACE)
+ data = iface.Introspect()
+ parser = IntrospectionNodeParser(
+ ElementTree.fromstring(data),
+ intf_match = ListMatch(interfaces))
+ for x,y in parser.get_interfaces().iteritems():
+ s = self.find_signal(signal,
y.get('signal'))
- if s:
- return (x,s)
+ if s:
+ return (x,s)
class DirectoryHandler(RouteHandler):
- verbs = 'GET'
- rules = '<path:path>/'
+ verbs = 'GET'
+ rules = '<path:path>/'
- def __init__(self, app, bus):
- super(DirectoryHandler, self).__init__(
- app, bus, self.verbs, self.rules)
+ def __init__(self, app, bus):
+ super(DirectoryHandler, self).__init__(
+ app, bus, self.verbs, self.rules)
- def find(self, path = '/'):
- return self.try_mapper_call(
- self.mapper.get_subtree_paths,
- path = path, depth = 1)
+ def find(self, path = '/'):
+ return self.try_mapper_call(
+ self.mapper.get_subtree_paths,
+ path = path, depth = 1)
- def setup(self, path = '/'):
- request.route_data['map'] = self.find(path)
+ def setup(self, path = '/'):
+ request.route_data['map'] = self.find(path)
- def do_get(self, path = '/'):
- return request.route_data['map']
+ def do_get(self, path = '/'):
+ return request.route_data['map']
class ListNamesHandler(RouteHandler):
- verbs = 'GET'
- rules = ['/list', '<path:path>/list']
+ verbs = 'GET'
+ rules = ['/list', '<path:path>/list']
- def __init__(self, app, bus):
- super(ListNamesHandler, self).__init__(
- app, bus, self.verbs, self.rules)
+ def __init__(self, app, bus):
+ super(ListNamesHandler, self).__init__(
+ app, bus, self.verbs, self.rules)
- def find(self, path = '/'):
- return self.try_mapper_call(
- self.mapper.get_subtree, path = path).keys()
+ def find(self, path = '/'):
+ return self.try_mapper_call(
+ self.mapper.get_subtree, path = path).keys()
- def setup(self, path = '/'):
- request.route_data['map'] = self.find(path)
+ def setup(self, path = '/'):
+ request.route_data['map'] = self.find(path)
- def do_get(self, path = '/'):
- return request.route_data['map']
+ def do_get(self, path = '/'):
+ return request.route_data['map']
class ListHandler(RouteHandler):
- verbs = 'GET'
- rules = ['/enumerate', '<path:path>/enumerate']
-
- def __init__(self, app, bus):
- super(ListHandler, self).__init__(
- app, bus, self.verbs, self.rules)
-
- def find(self, path = '/'):
- return self.try_mapper_call(
- self.mapper.get_subtree, path = path)
-
- def setup(self, path = '/'):
- request.route_data['map'] = self.find(path)
-
- def do_get(self, path = '/'):
- objs = {}
- mapper_data = request.route_data['map']
- tree = PathTree()
- for x,y in mapper_data.iteritems():
- tree[x] = y
-
- try:
- # Check to see if the root path implements
- # enumerate in addition to any sub tree
- # objects.
- root = self.try_mapper_call(self.mapper.get_object,
- path = path)
- mapper_data[path] = root
- except:
- pass
-
- have_enumerate = [ (x[0], self.enumerate_capable(*x)) \
- for x in mapper_data.iteritems() \
- if self.enumerate_capable(*x) ]
-
- for x,y in have_enumerate:
- objs.update(self.call_enumerate(x, y))
- tmp = tree[x]
- # remove the subtree
- del tree[x]
- # add the new leaf back since enumerate results don't
- # include the object enumerate is being invoked on
- tree[x] = tmp
-
- # make dbus calls for any remaining objects
- for x,y in tree.dataitems():
- objs[x] = self.app.instance_handler.do_get(x)
-
- return objs
-
- @staticmethod
- def enumerate_capable(path, bus_data):
- busses = []
- for name, ifaces in bus_data.iteritems():
- if OpenBMCMapper.ENUMERATE_IFACE in ifaces:
- busses.append(name)
- return busses
-
- def call_enumerate(self, path, busses):
- objs = {}
- for b in busses:
- obj = self.bus.get_object(b, path, introspect = False)
- iface = dbus.Interface(obj, OpenBMCMapper.ENUMERATE_IFACE)
- objs.update(iface.enumerate())
- return objs
+ verbs = 'GET'
+ rules = ['/enumerate', '<path:path>/enumerate']
+
+ def __init__(self, app, bus):
+ super(ListHandler, self).__init__(
+ app, bus, self.verbs, self.rules)
+
+ def find(self, path = '/'):
+ return self.try_mapper_call(
+ self.mapper.get_subtree, path = path)
+
+ def setup(self, path = '/'):
+ request.route_data['map'] = self.find(path)
+
+ def do_get(self, path = '/'):
+ objs = {}
+ mapper_data = request.route_data['map']
+ tree = PathTree()
+ for x,y in mapper_data.iteritems():
+ tree[x] = y
+
+ try:
+ # Check to see if the root path implements
+ # enumerate in addition to any sub tree
+ # objects.
+ root = self.try_mapper_call(self.mapper.get_object,
+ path = path)
+ mapper_data[path] = root
+ except:
+ pass
+
+ have_enumerate = [ (x[0], self.enumerate_capable(*x)) \
+ for x in mapper_data.iteritems() \
+ if self.enumerate_capable(*x) ]
+
+ for x,y in have_enumerate:
+ objs.update(self.call_enumerate(x, y))
+ tmp = tree[x]
+ # remove the subtree
+ del tree[x]
+ # add the new leaf back since enumerate results don't
+ # include the object enumerate is being invoked on
+ tree[x] = tmp
+
+ # make dbus calls for any remaining objects
+ for x,y in tree.dataitems():
+ objs[x] = self.app.instance_handler.do_get(x)
+
+ return objs
+
+ @staticmethod
+ def enumerate_capable(path, bus_data):
+ busses = []
+ for name, ifaces in bus_data.iteritems():
+ if OpenBMCMapper.ENUMERATE_IFACE in ifaces:
+ busses.append(name)
+ return busses
+
+ def call_enumerate(self, path, busses):
+ objs = {}
+ for b in busses:
+ obj = self.bus.get_object(b, path, introspect = False)
+ iface = dbus.Interface(obj, OpenBMCMapper.ENUMERATE_IFACE)
+ objs.update(iface.enumerate())
+ return objs
class MethodHandler(RouteHandler):
- verbs = 'POST'
- rules = '<path:path>/action/<method>'
- request_type = list
-
- def __init__(self, app, bus):
- super(MethodHandler, self).__init__(
- app, bus, self.verbs, self.rules)
-
- def find(self, path, method):
- busses = self.try_mapper_call(self.mapper.get_object,
- path = path)
- for items in busses.iteritems():
- m = self.find_method_on_bus(path, method, *items)
- if m:
- return m
-
- abort(404, _4034_msg %('method', 'found', method))
-
- def setup(self, path, method):
- request.route_data['method'] = self.find(path, method)
-
- def do_post(self, path, method):
- try:
- if request.parameter_list:
- return request.route_data['method'](*request.parameter_list)
- else:
- return request.route_data['method']()
-
- except dbus.exceptions.DBusException, e:
- if e.get_dbus_name() == DBUS_INVALID_ARGS:
- abort(400, str(e))
- if e.get_dbus_name() == DBUS_TYPE_ERROR:
- abort(400, str(e))
- raise
-
- @staticmethod
- def find_method_in_interface(method, obj, interface, methods):
- if methods is None:
- return None
-
- method = find_case_insensitive(method, methods.keys())
- if method is not None:
- iface = dbus.Interface(obj, interface)
- return iface.get_dbus_method(method)
-
- def find_method_on_bus(self, path, method, bus, interfaces):
- obj = self.bus.get_object(bus, path, introspect = False)
- iface = dbus.Interface(obj, dbus.INTROSPECTABLE_IFACE)
- data = iface.Introspect()
- parser = IntrospectionNodeParser(
- ElementTree.fromstring(data),
- intf_match = ListMatch(interfaces))
- for x,y in parser.get_interfaces().iteritems():
- m = self.find_method_in_interface(method, obj, x,
- y.get('method'))
- if m:
- return m
+ verbs = 'POST'
+ rules = '<path:path>/action/<method>'
+ request_type = list
+
+ def __init__(self, app, bus):
+ super(MethodHandler, self).__init__(
+ app, bus, self.verbs, self.rules)
+
+ def find(self, path, method):
+ busses = self.try_mapper_call(self.mapper.get_object,
+ path = path)
+ for items in busses.iteritems():
+ m = self.find_method_on_bus(path, method, *items)
+ if m:
+ return m
+
+ abort(404, _4034_msg %('method', 'found', method))
+
+ def setup(self, path, method):
+ request.route_data['method'] = self.find(path, method)
+
+ def do_post(self, path, method):
+ try:
+ if request.parameter_list:
+ return request.route_data['method'](*request.parameter_list)
+ else:
+ return request.route_data['method']()
+
+ except dbus.exceptions.DBusException, e:
+ if e.get_dbus_name() == DBUS_INVALID_ARGS:
+ abort(400, str(e))
+ if e.get_dbus_name() == DBUS_TYPE_ERROR:
+ abort(400, str(e))
+ raise
+
+ @staticmethod
+ def find_method_in_interface(method, obj, interface, methods):
+ if methods is None:
+ return None
+
+ method = find_case_insensitive(method, methods.keys())
+ if method is not None:
+ iface = dbus.Interface(obj, interface)
+ return iface.get_dbus_method(method)
+
+ def find_method_on_bus(self, path, method, bus, interfaces):
+ obj = self.bus.get_object(bus, path, introspect = False)
+ iface = dbus.Interface(obj, dbus.INTROSPECTABLE_IFACE)
+ data = iface.Introspect()
+ parser = IntrospectionNodeParser(
+ ElementTree.fromstring(data),
+ intf_match = ListMatch(interfaces))
+ for x,y in parser.get_interfaces().iteritems():
+ m = self.find_method_in_interface(method, obj, x,
+ y.get('method'))
+ if m:
+ return m
class PropertyHandler(RouteHandler):
- verbs = ['PUT', 'GET']
- rules = '<path:path>/attr/<prop>'
-
- def __init__(self, app, bus):
- super(PropertyHandler, self).__init__(
- app, bus, self.verbs, self.rules)
-
- def find(self, path, prop):
- self.app.instance_handler.setup(path)
- obj = self.app.instance_handler.do_get(path)
- try:
- obj[prop]
- except KeyError, e:
- if request.method == 'PUT':
- abort(403, _4034_msg %('property', 'created', str(e)))
- else:
- abort(404, _4034_msg %('property', 'found', str(e)))
-
- return { path: obj }
-
- def setup(self, path, prop):
- request.route_data['obj'] = self.find(path, prop)
-
- def do_get(self, path, prop):
- return request.route_data['obj'][path][prop]
-
- def do_put(self, path, prop, value = None):
- if value is None:
- value = request.parameter_list
-
- prop, iface, properties_iface = self.get_host_interface(
- path, prop, request.route_data['map'][path])
- try:
- properties_iface.Set(iface, prop, value)
- except ValueError, e:
- abort(400, str(e))
- except dbus.exceptions.DBusException, e:
- if e.get_dbus_name() == DBUS_INVALID_ARGS:
- abort(403, str(e))
- raise
-
- def get_host_interface(self, path, prop, bus_info):
- for bus, interfaces in bus_info.iteritems():
- obj = self.bus.get_object(bus, path, introspect = True)
- properties_iface = dbus.Interface(
- obj, dbus_interface=dbus.PROPERTIES_IFACE)
-
- info = self.get_host_interface_on_bus(
- path, prop, properties_iface,
- bus, interfaces)
- if info is not None:
- prop, iface = info
- return prop, iface, properties_iface
-
- def get_host_interface_on_bus(self, path, prop, iface, bus, interfaces):
- for i in interfaces:
- properties = self.try_properties_interface(iface.GetAll, i)
- if properties is None:
- continue
- prop = find_case_insensitive(prop, properties.keys())
- if prop is None:
- continue
- return prop, i
+ verbs = ['PUT', 'GET']
+ rules = '<path:path>/attr/<prop>'
+
+ def __init__(self, app, bus):
+ super(PropertyHandler, self).__init__(
+ app, bus, self.verbs, self.rules)
+
+ def find(self, path, prop):
+ self.app.instance_handler.setup(path)
+ obj = self.app.instance_handler.do_get(path)
+ try:
+ obj[prop]
+ except KeyError, e:
+ if request.method == 'PUT':
+ abort(403, _4034_msg %('property', 'created', str(e)))
+ else:
+ abort(404, _4034_msg %('property', 'found', str(e)))
+
+ return { path: obj }
+
+ def setup(self, path, prop):
+ request.route_data['obj'] = self.find(path, prop)
+
+ def do_get(self, path, prop):
+ return request.route_data['obj'][path][prop]
+
+ def do_put(self, path, prop, value = None):
+ if value is None:
+ value = request.parameter_list
+
+ prop, iface, properties_iface = self.get_host_interface(
+ path, prop, request.route_data['map'][path])
+ try:
+ properties_iface.Set(iface, prop, value)
+ except ValueError, e:
+ abort(400, str(e))
+ except dbus.exceptions.DBusException, e:
+ if e.get_dbus_name() == DBUS_INVALID_ARGS:
+ abort(403, str(e))
+ raise
+
+ def get_host_interface(self, path, prop, bus_info):
+ for bus, interfaces in bus_info.iteritems():
+ obj = self.bus.get_object(bus, path, introspect = True)
+ properties_iface = dbus.Interface(
+ obj, dbus_interface=dbus.PROPERTIES_IFACE)
+
+ info = self.get_host_interface_on_bus(
+ path, prop, properties_iface,
+ bus, interfaces)
+ if info is not None:
+ prop, iface = info
+ return prop, iface, properties_iface
+
+ def get_host_interface_on_bus(self, path, prop, iface, bus, interfaces):
+ for i in interfaces:
+ properties = self.try_properties_interface(iface.GetAll, i)
+ if properties is None:
+ continue
+ prop = find_case_insensitive(prop, properties.keys())
+ if prop is None:
+ continue
+ return prop, i
class SchemaHandler(RouteHandler):
- verbs = ['GET']
- rules = '<path:path>/schema'
-
- def __init__(self, app, bus):
- super(SchemaHandler, self).__init__(
- app, bus, self.verbs, self.rules)
-
- def find(self, path):
- return self.try_mapper_call(
- self.mapper.get_object,
- path = path)
-
- def setup(self, path):
- request.route_data['map'] = self.find(path)
-
- def do_get(self, path):
- schema = {}
- for x in request.route_data['map'].iterkeys():
- obj = self.bus.get_object(
- x, path, introspect = False)
- iface = dbus.Interface(obj, dbus.INTROSPECTABLE_IFACE)
- data = iface.Introspect()
- parser = IntrospectionNodeParser(
- ElementTree.fromstring(data))
- for x,y in parser.get_interfaces().iteritems():
- schema[x] = y
-
- return schema
+ verbs = ['GET']
+ rules = '<path:path>/schema'
+
+ def __init__(self, app, bus):
+ super(SchemaHandler, self).__init__(
+ app, bus, self.verbs, self.rules)
+
+ def find(self, path):
+ return self.try_mapper_call(
+ self.mapper.get_object,
+ path = path)
+
+ def setup(self, path):
+ request.route_data['map'] = self.find(path)
+
+ def do_get(self, path):
+ schema = {}
+ for x in request.route_data['map'].iterkeys():
+ obj = self.bus.get_object(
+ x, path, introspect = False)
+ iface = dbus.Interface(obj, dbus.INTROSPECTABLE_IFACE)
+ data = iface.Introspect()
+ parser = IntrospectionNodeParser(
+ ElementTree.fromstring(data))
+ for x,y in parser.get_interfaces().iteritems():
+ schema[x] = y
+
+ return schema
class InstanceHandler(RouteHandler):
- verbs = ['GET', 'PUT', 'DELETE']
- rules = '<path:path>'
- request_type = dict
-
- def __init__(self, app, bus):
- super(InstanceHandler, self).__init__(
- app, bus, self.verbs, self.rules)
-
- def find(self, path, callback = None):
- return { path: self.try_mapper_call(
- self.mapper.get_object,
- callback,
- path = path) }
-
- def setup(self, path):
- callback = None
- if request.method == 'PUT':
- def callback(e, **kw):
- abort(403, _4034_msg %('resource',
- 'created', path))
-
- if request.route_data.get('map') is None:
- request.route_data['map'] = self.find(path, callback)
-
- def do_get(self, path):
- properties = {}
- for item in request.route_data['map'][path].iteritems():
- properties.update(self.get_properties_on_bus(
- path, *item))
-
- return properties
-
- @staticmethod
- def get_properties_on_iface(properties_iface, iface):
- properties = InstanceHandler.try_properties_interface(
- properties_iface.GetAll, iface)
- if properties is None:
- return {}
- return properties
-
- def get_properties_on_bus(self, path, bus, interfaces):
- properties = {}
- obj = self.bus.get_object(bus, path, introspect = False)
- properties_iface = dbus.Interface(
- obj, dbus_interface=dbus.PROPERTIES_IFACE)
- for i in interfaces:
- properties.update(self.get_properties_on_iface(
- properties_iface, i))
-
- return properties
-
- def do_put(self, path):
- # make sure all properties exist in the request
- obj = set(self.do_get(path).keys())
- req = set(request.parameter_list.keys())
-
- diff = list(obj.difference(req))
- if diff:
- abort(403, _4034_msg %('resource', 'removed',
- '%s/attr/%s' %(path, diff[0])))
-
- diff = list(req.difference(obj))
- if diff:
- abort(403, _4034_msg %('resource', 'created',
- '%s/attr/%s' %(path, diff[0])))
-
- for p,v in request.parameter_list.iteritems():
- self.app.property_handler.do_put(
- path, p, v)
-
- def do_delete(self, path):
- for bus_info in request.route_data['map'][path].iteritems():
- if self.bus_missing_delete(path, *bus_info):
- abort(403, _4034_msg %('resource', 'removed',
- path))
-
- for bus in request.route_data['map'][path].iterkeys():
- self.delete_on_bus(path, bus)
-
- def bus_missing_delete(self, path, bus, interfaces):
- return DELETE_IFACE not in interfaces
-
- def delete_on_bus(self, path, bus):
- obj = self.bus.get_object(bus, path, introspect = False)
- delete_iface = dbus.Interface(
- obj, dbus_interface = DELETE_IFACE)
- delete_iface.Delete()
+ verbs = ['GET', 'PUT', 'DELETE']
+ rules = '<path:path>'
+ request_type = dict
+
+ def __init__(self, app, bus):
+ super(InstanceHandler, self).__init__(
+ app, bus, self.verbs, self.rules)
+
+ def find(self, path, callback = None):
+ return { path: self.try_mapper_call(
+ self.mapper.get_object,
+ callback,
+ path = path) }
+
+ def setup(self, path):
+ callback = None
+ if request.method == 'PUT':
+ def callback(e, **kw):
+ abort(403, _4034_msg %('resource',
+ 'created', path))
+
+ if request.route_data.get('map') is None:
+ request.route_data['map'] = self.find(path, callback)
+
+ def do_get(self, path):
+ properties = {}
+ for item in request.route_data['map'][path].iteritems():
+ properties.update(self.get_properties_on_bus(
+ path, *item))
+
+ return properties
+
+ @staticmethod
+ def get_properties_on_iface(properties_iface, iface):
+ properties = InstanceHandler.try_properties_interface(
+ properties_iface.GetAll, iface)
+ if properties is None:
+ return {}
+ return properties
+
+ def get_properties_on_bus(self, path, bus, interfaces):
+ properties = {}
+ obj = self.bus.get_object(bus, path, introspect = False)
+ properties_iface = dbus.Interface(
+ obj, dbus_interface=dbus.PROPERTIES_IFACE)
+ for i in interfaces:
+ properties.update(self.get_properties_on_iface(
+ properties_iface, i))
+
+ return properties
+
+ def do_put(self, path):
+ # make sure all properties exist in the request
+ obj = set(self.do_get(path).keys())
+ req = set(request.parameter_list.keys())
+
+ diff = list(obj.difference(req))
+ if diff:
+ abort(403, _4034_msg %('resource', 'removed',
+ '%s/attr/%s' %(path, diff[0])))
+
+ diff = list(req.difference(obj))
+ if diff:
+ abort(403, _4034_msg %('resource', 'created',
+ '%s/attr/%s' %(path, diff[0])))
+
+ for p,v in request.parameter_list.iteritems():
+ self.app.property_handler.do_put(
+ path, p, v)
+
+ def do_delete(self, path):
+ for bus_info in request.route_data['map'][path].iteritems():
+ if self.bus_missing_delete(path, *bus_info):
+ abort(403, _4034_msg %('resource', 'removed',
+ path))
+
+ for bus in request.route_data['map'][path].iterkeys():
+ self.delete_on_bus(path, bus)
+
+ def bus_missing_delete(self, path, bus, interfaces):
+ return DELETE_IFACE not in interfaces
+
+ def delete_on_bus(self, path, bus):
+ obj = self.bus.get_object(bus, path, introspect = False)
+ delete_iface = dbus.Interface(
+ obj, dbus_interface = DELETE_IFACE)
+ delete_iface.Delete()
class SessionHandler(MethodHandler):
- ''' Handles the /login and /logout routes, manages server side session store and
- session cookies. '''
-
- rules = ['/login', '/logout']
- login_str = "User '%s' logged %s"
- bad_passwd_str = "Invalid username or password"
- no_user_str = "No user logged in"
- bad_json_str = "Expecting request format { 'data': [<username>, <password>] }, got '%s'"
- _require_auth = None
- MAX_SESSIONS = 16
-
- def __init__(self, app, bus):
- super(SessionHandler, self).__init__(
- app, bus)
- self.hmac_key = os.urandom(128)
- self.session_store = []
-
- @staticmethod
- def authenticate(username, clear):
- try:
- encoded = spwd.getspnam(username)[1]
- return encoded == crypt.crypt(clear, encoded)
- except KeyError:
- return False
-
- def invalidate_session(self, session):
- try:
- self.session_store.remove(session)
- except ValueError:
- pass
-
- def new_session(self):
- sid = os.urandom(32)
- if self.MAX_SESSIONS <= len(self.session_store):
- self.session_store.pop()
- self.session_store.insert(0, {'sid': sid})
-
- return self.session_store[0]
-
- def get_session(self, sid):
- sids = [ x['sid'] for x in self.session_store ]
- try:
- return self.session_store[sids.index(sid)]
- except ValueError:
- return None
-
- def get_session_from_cookie(self):
- return self.get_session(
- request.get_cookie('sid',
- secret = self.hmac_key))
-
- def do_post(self, **kw):
- if request.path == '/login':
- return self.do_login(**kw)
- else:
- return self.do_logout(**kw)
-
- def do_logout(self, **kw):
- session = self.get_session_from_cookie()
- if session is not None:
- user = session['user']
- self.invalidate_session(session)
- response.delete_cookie('sid')
- return self.login_str %(user, 'out')
-
- return self.no_user_str
-
- def do_login(self, **kw):
- session = self.get_session_from_cookie()
- if session is not None:
- return self.login_str %(session['user'], 'in')
-
- if len(request.parameter_list) != 2:
- abort(400, self.bad_json_str %(request.json))
-
- if not self.authenticate(*request.parameter_list):
- return self.bad_passwd_str
-
- user = request.parameter_list[0]
- session = self.new_session()
- session['user'] = user
- response.set_cookie('sid', session['sid'], secret = self.hmac_key,
- secure = True,
- httponly = True)
- return self.login_str %(user, 'in')
-
- def find(self, **kw):
- pass
-
- def setup(self, **kw):
- pass
+ ''' Handles the /login and /logout routes, manages server side session store and
+ session cookies. '''
+
+ rules = ['/login', '/logout']
+ login_str = "User '%s' logged %s"
+ bad_passwd_str = "Invalid username or password"
+ no_user_str = "No user logged in"
+ bad_json_str = "Expecting request format { 'data': [<username>, <password>] }, got '%s'"
+ _require_auth = None
+ MAX_SESSIONS = 16
+
+ def __init__(self, app, bus):
+ super(SessionHandler, self).__init__(
+ app, bus)
+ self.hmac_key = os.urandom(128)
+ self.session_store = []
+
+ @staticmethod
+ def authenticate(username, clear):
+ try:
+ encoded = spwd.getspnam(username)[1]
+ return encoded == crypt.crypt(clear, encoded)
+ except KeyError:
+ return False
+
+ def invalidate_session(self, session):
+ try:
+ self.session_store.remove(session)
+ except ValueError:
+ pass
+
+ def new_session(self):
+ sid = os.urandom(32)
+ if self.MAX_SESSIONS <= len(self.session_store):
+ self.session_store.pop()
+ self.session_store.insert(0, {'sid': sid})
+
+ return self.session_store[0]
+
+ def get_session(self, sid):
+ sids = [ x['sid'] for x in self.session_store ]
+ try:
+ return self.session_store[sids.index(sid)]
+ except ValueError:
+ return None
+
+ def get_session_from_cookie(self):
+ return self.get_session(
+ request.get_cookie('sid',
+ secret = self.hmac_key))
+
+ def do_post(self, **kw):
+ if request.path == '/login':
+ return self.do_login(**kw)
+ else:
+ return self.do_logout(**kw)
+
+ def do_logout(self, **kw):
+ session = self.get_session_from_cookie()
+ if session is not None:
+ user = session['user']
+ self.invalidate_session(session)
+ response.delete_cookie('sid')
+ return self.login_str %(user, 'out')
+
+ return self.no_user_str
+
+ def do_login(self, **kw):
+ session = self.get_session_from_cookie()
+ if session is not None:
+ return self.login_str %(session['user'], 'in')
+
+ if len(request.parameter_list) != 2:
+ abort(400, self.bad_json_str %(request.json))
+
+ if not self.authenticate(*request.parameter_list):
+ return self.bad_passwd_str
+
+ user = request.parameter_list[0]
+ session = self.new_session()
+ session['user'] = user
+ response.set_cookie('sid', session['sid'], secret = self.hmac_key,
+ secure = True,
+ httponly = True)
+ return self.login_str %(user, 'in')
+
+ def find(self, **kw):
+ pass
+
+ def setup(self, **kw):
+ pass
class AuthorizationPlugin(object):
- ''' Invokes an optional list of authorization callbacks. '''
+ ''' Invokes an optional list of authorization callbacks. '''
- name = 'authorization'
- api = 2
+ name = 'authorization'
+ api = 2
- class Compose:
- def __init__(self, validators, callback, session_mgr):
- self.validators = validators
- self.callback = callback
- self.session_mgr = session_mgr
+ class Compose:
+ def __init__(self, validators, callback, session_mgr):
+ self.validators = validators
+ self.callback = callback
+ self.session_mgr = session_mgr
- def __call__(self, *a, **kw):
- sid = request.get_cookie('sid', secret = self.session_mgr.hmac_key)
- session = self.session_mgr.get_session(sid)
- for x in self.validators:
- x(session, *a, **kw)
+ def __call__(self, *a, **kw):
+ sid = request.get_cookie('sid', secret = self.session_mgr.hmac_key)
+ session = self.session_mgr.get_session(sid)
+ for x in self.validators:
+ x(session, *a, **kw)
- return self.callback(*a, **kw)
+ return self.callback(*a, **kw)
- def apply(self, callback, route):
- undecorated = route.get_undecorated_callback()
- if not isinstance(undecorated, RouteHandler):
- return callback
+ def apply(self, callback, route):
+ undecorated = route.get_undecorated_callback()
+ if not isinstance(undecorated, RouteHandler):
+ return callback
- auth_types = getattr(undecorated,
- '_require_auth', None)
- if not auth_types:
- return callback
+ auth_types = getattr(undecorated,
+ '_require_auth', None)
+ if not auth_types:
+ return callback
- return self.Compose(auth_types, callback,
- undecorated.app.session_handler)
+ return self.Compose(auth_types, callback,
+ undecorated.app.session_handler)
class JsonApiRequestPlugin(object):
- ''' Ensures request content satisfies the OpenBMC json api format. '''
- name = 'json_api_request'
- api = 2
-
- error_str = "Expecting request format { 'data': <value> }, got '%s'"
- type_error_str = "Unsupported Content-Type: '%s'"
- json_type = "application/json"
- request_methods = ['PUT', 'POST', 'PATCH']
-
- @staticmethod
- def content_expected():
- return request.method in JsonApiRequestPlugin.request_methods
-
- def validate_request(self):
- if request.content_length > 0 and \
- request.content_type != self.json_type:
- abort(415, self.type_error_str %(request.content_type))
-
- try:
- request.parameter_list = request.json.get('data')
- except ValueError, e:
- abort(400, str(e))
- except (AttributeError, KeyError, TypeError):
- abort(400, self.error_str %(request.json))
-
- def apply(self, callback, route):
- verbs = getattr(route.get_undecorated_callback(),
- '_verbs', None)
- if verbs is None:
- return callback
-
- if not set(self.request_methods).intersection(verbs):
- return callback
-
- def wrap(*a, **kw):
- if self.content_expected():
- self.validate_request()
- return callback(*a, **kw)
-
- return wrap
+ ''' Ensures request content satisfies the OpenBMC json api format. '''
+ name = 'json_api_request'
+ api = 2
+
+ error_str = "Expecting request format { 'data': <value> }, got '%s'"
+ type_error_str = "Unsupported Content-Type: '%s'"
+ json_type = "application/json"
+ request_methods = ['PUT', 'POST', 'PATCH']
+
+ @staticmethod
+ def content_expected():
+ return request.method in JsonApiRequestPlugin.request_methods
+
+ def validate_request(self):
+ if request.content_length > 0 and \
+ request.content_type != self.json_type:
+ abort(415, self.type_error_str %(request.content_type))
+
+ try:
+ request.parameter_list = request.json.get('data')
+ except ValueError, e:
+ abort(400, str(e))
+ except (AttributeError, KeyError, TypeError):
+ abort(400, self.error_str %(request.json))
+
+ def apply(self, callback, route):
+ verbs = getattr(route.get_undecorated_callback(),
+ '_verbs', None)
+ if verbs is None:
+ return callback
+
+ if not set(self.request_methods).intersection(verbs):
+ return callback
+
+ def wrap(*a, **kw):
+ if self.content_expected():
+ self.validate_request()
+ return callback(*a, **kw)
+
+ return wrap
class JsonApiRequestTypePlugin(object):
- ''' Ensures request content type satisfies the OpenBMC json api format. '''
- name = 'json_api_method_request'
- api = 2
+ ''' Ensures request content type satisfies the OpenBMC json api format. '''
+ name = 'json_api_method_request'
+ api = 2
- error_str = "Expecting request format { 'data': %s }, got '%s'"
+ error_str = "Expecting request format { 'data': %s }, got '%s'"
- def apply(self, callback, route):
- request_type = getattr(route.get_undecorated_callback(),
- 'request_type', None)
- if request_type is None:
- return callback
+ def apply(self, callback, route):
+ request_type = getattr(route.get_undecorated_callback(),
+ 'request_type', None)
+ if request_type is None:
+ return callback
- def validate_request():
- if not isinstance(request.parameter_list, request_type):
- abort(400, self.error_str %(str(request_type), request.json))
+ def validate_request():
+ if not isinstance(request.parameter_list, request_type):
+ abort(400, self.error_str %(str(request_type), request.json))
- def wrap(*a, **kw):
- if JsonApiRequestPlugin.content_expected():
- validate_request()
- return callback(*a, **kw)
+ def wrap(*a, **kw):
+ if JsonApiRequestPlugin.content_expected():
+ validate_request()
+ return callback(*a, **kw)
- return wrap
+ return wrap
class JsonApiResponsePlugin(object):
- ''' Emits normal responses in the OpenBMC json api format. '''
- name = 'json_api_response'
- api = 2
-
- def apply(self, callback, route):
- def wrap(*a, **kw):
- resp = { 'data': callback(*a, **kw) }
- resp['status'] = 'ok'
- resp['message'] = response.status_line
- return resp
- return wrap
+ ''' Emits normal responses in the OpenBMC json api format. '''
+ name = 'json_api_response'
+ api = 2
+
+ def apply(self, callback, route):
+ def wrap(*a, **kw):
+ resp = { 'data': callback(*a, **kw) }
+ resp['status'] = 'ok'
+ resp['message'] = response.status_line
+ return resp
+ return wrap
class JsonApiErrorsPlugin(object):
- ''' Emits error responses in the OpenBMC json api format. '''
- name = 'json_api_errors'
- api = 2
-
- def __init__(self, **kw):
- self.app = None
- self.function_type = None
- self.original = None
- self.json_opts = { x:y for x,y in kw.iteritems() \
- if x in ['indent','sort_keys'] }
-
- def setup(self, app):
- self.app = app
- self.function_type = type(app.default_error_handler)
- self.original = app.default_error_handler
- self.app.default_error_handler = self.function_type(
- self.json_errors, app, Bottle)
-
- def apply(self, callback, route):
- return callback
-
- def close(self):
- self.app.default_error_handler = self.function_type(
- self.original, self.app, Bottle)
-
- def json_errors(self, res, error):
- response_object = {'status': 'error', 'data': {} }
- response_object['message'] = error.status_line
- response_object['data']['description'] = str(error.body)
- if error.status_code == 500:
- response_object['data']['exception'] = repr(error.exception)
- response_object['data']['traceback'] = error.traceback.splitlines()
-
- json_response = json.dumps(response_object, **self.json_opts)
- response.content_type = 'application/json'
- return json_response
+ ''' Emits error responses in the OpenBMC json api format. '''
+ name = 'json_api_errors'
+ api = 2
+
+ def __init__(self, **kw):
+ self.app = None
+ self.function_type = None
+ self.original = None
+ self.json_opts = { x:y for x,y in kw.iteritems() \
+ if x in ['indent','sort_keys'] }
+
+ def setup(self, app):
+ self.app = app
+ self.function_type = type(app.default_error_handler)
+ self.original = app.default_error_handler
+ self.app.default_error_handler = self.function_type(
+ self.json_errors, app, Bottle)
+
+ def apply(self, callback, route):
+ return callback
+
+ def close(self):
+ self.app.default_error_handler = self.function_type(
+ self.original, self.app, Bottle)
+
+ def json_errors(self, res, error):
+ response_object = {'status': 'error', 'data': {} }
+ response_object['message'] = error.status_line
+ response_object['data']['description'] = str(error.body)
+ if error.status_code == 500:
+ response_object['data']['exception'] = repr(error.exception)
+ response_object['data']['traceback'] = error.traceback.splitlines()
+
+ json_response = json.dumps(response_object, **self.json_opts)
+ response.content_type = 'application/json'
+ return json_response
class RestApp(Bottle):
- def __init__(self, bus):
- super(RestApp, self).__init__(autojson = False)
- self.bus = bus
- self.mapper = Mapper(bus)
-
- self.install_hooks()
- self.install_plugins()
- self.create_handlers()
- self.install_handlers()
-
- def install_plugins(self):
- # install json api plugins
- json_kw = {'indent': 2, 'sort_keys': True}
- self.install(JSONPlugin(**json_kw))
- self.install(JsonApiErrorsPlugin(**json_kw))
- self.install(AuthorizationPlugin())
- self.json_response_plugin = JsonApiResponsePlugin()
- self.install(self.json_response_plugin)
- self.install(JsonApiRequestPlugin())
- self.install(JsonApiRequestTypePlugin())
-
- def install_hooks(self):
- self.real_router_match = self.router.match
- self.router.match = self.custom_router_match
- self.add_hook('before_request', self.strip_extra_slashes)
-
- def create_handlers(self):
- # create route handlers
- self.signal_handler = SignalHandler(self, self.bus)
- self.session_handler = SessionHandler(self, self.bus)
- self.directory_handler = DirectoryHandler(self, self.bus)
- self.list_names_handler = ListNamesHandler(self, self.bus)
- self.list_handler = ListHandler(self, self.bus)
- self.method_handler = MethodHandler(self, self.bus)
- self.property_handler = PropertyHandler(self, self.bus)
- self.schema_handler = SchemaHandler(self, self.bus)
- self.instance_handler = InstanceHandler(self, self.bus)
-
- def install_handlers(self):
- # Skip json response for signal handler because it requires to
- # return a gevent iterable which cannot be handled by json
- # response plugin
- self.signal_handler._skips = [self.json_response_plugin]
- self.signal_handler.install()
- self.session_handler.install()
- self.directory_handler.install()
- self.list_names_handler.install()
- self.list_handler.install()
- self.method_handler.install()
- self.property_handler.install()
- self.schema_handler.install()
- # this has to come last, since it matches everything
- self.instance_handler.install()
-
- def custom_router_match(self, environ):
- ''' The built-in Bottle algorithm for figuring out if a 404 or 405 is
+ def __init__(self, bus):
+ super(RestApp, self).__init__(autojson = False)
+ self.bus = bus
+ self.mapper = Mapper(bus)
+
+ self.install_hooks()
+ self.install_plugins()
+ self.create_handlers()
+ self.install_handlers()
+
+ def install_plugins(self):
+ # install json api plugins
+ json_kw = {'indent': 2, 'sort_keys': True}
+ self.install(JSONPlugin(**json_kw))
+ self.install(JsonApiErrorsPlugin(**json_kw))
+ self.install(AuthorizationPlugin())
+ self.json_response_plugin = JsonApiResponsePlugin()
+ self.install(self.json_response_plugin)
+ self.install(JsonApiRequestPlugin())
+ self.install(JsonApiRequestTypePlugin())
+
+ def install_hooks(self):
+ self.real_router_match = self.router.match
+ self.router.match = self.custom_router_match
+ self.add_hook('before_request', self.strip_extra_slashes)
+
+ def create_handlers(self):
+ # create route handlers
+ self.signal_handler = SignalHandler(self, self.bus)
+ self.session_handler = SessionHandler(self, self.bus)
+ self.directory_handler = DirectoryHandler(self, self.bus)
+ self.list_names_handler = ListNamesHandler(self, self.bus)
+ self.list_handler = ListHandler(self, self.bus)
+ self.method_handler = MethodHandler(self, self.bus)
+ self.property_handler = PropertyHandler(self, self.bus)
+ self.schema_handler = SchemaHandler(self, self.bus)
+ self.instance_handler = InstanceHandler(self, self.bus)
+
+ def install_handlers(self):
+ # Skip json response for signal handler because it requires to
+ # return a gevent iterable which cannot be handled by json
+ # response plugin
+ self.signal_handler._skips = [self.json_response_plugin]
+ self.signal_handler.install()
+ self.session_handler.install()
+ self.directory_handler.install()
+ self.list_names_handler.install()
+ self.list_handler.install()
+ self.method_handler.install()
+ self.property_handler.install()
+ self.schema_handler.install()
+ # this has to come last, since it matches everything
+ self.instance_handler.install()
+
+ def custom_router_match(self, environ):
+ ''' The built-in Bottle algorithm for figuring out if a 404 or 405 is
needed doesn't work for us since the instance rules match everything.
This monkey-patch lets the route handler figure out which response is
needed. This could be accomplished with a hook but that would require
- calling the router match function twice.
- '''
- route, args = self.real_router_match(environ)
- if isinstance(route.callback, RouteHandler):
- route.callback._setup(**args)
+ calling the router match function twice.
+ '''
+ route, args = self.real_router_match(environ)
+ if isinstance(route.callback, RouteHandler):
+ route.callback._setup(**args)
- return route, args
+ return route, args
- @staticmethod
- def strip_extra_slashes():
- path = request.environ['PATH_INFO']
- trailing = ("","/")[path[-1] == '/']
- parts = filter(bool, path.split('/'))
- request.environ['PATH_INFO'] = '/' + '/'.join(parts) + trailing
+ @staticmethod
+ def strip_extra_slashes():
+ path = request.environ['PATH_INFO']
+ trailing = ("","/")[path[-1] == '/']
+ parts = filter(bool, path.split('/'))
+ request.environ['PATH_INFO'] = '/' + '/'.join(parts) + trailing
class DbusSignal():
def __init__(self, bus, dbus_interface, signal_name, path):
@@ -862,18 +862,18 @@ class DbusSignal():
self.finish()
if __name__ == '__main__':
- log = logging.getLogger('Rocket.Errors')
- log.setLevel(logging.INFO)
- log.addHandler(logging.StreamHandler(sys.stdout))
+ log = logging.getLogger('Rocket.Errors')
+ log.setLevel(logging.INFO)
+ log.addHandler(logging.StreamHandler(sys.stdout))
- dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
- bus = dbus.SystemBus()
- app = RestApp(bus)
+ dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
+ bus = dbus.SystemBus()
+ app = RestApp(bus)
- default_cert = os.path.join(sys.prefix, 'share',
- os.path.basename(__file__), 'cert.pem')
+ default_cert = os.path.join(sys.prefix, 'share',
+ os.path.basename(__file__), 'cert.pem')
- server = WSGIServer(("0.0.0.0", 443), app, keyfile = default_cert,
- certfile = default_cert)
+ server = WSGIServer(("0.0.0.0", 443), app, keyfile = default_cert,
+ certfile = default_cert)
- server.serve_forever()
+ server.serve_forever()
--
2.6.4
More information about the openbmc
mailing list