diff options
| author | termie <github@anarkystic.com> | 2011-03-24 12:42:46 -0700 |
|---|---|---|
| committer | termie <github@anarkystic.com> | 2011-03-24 12:42:46 -0700 |
| commit | ef5c9e11595a00de468783adbb60cfbc2cbbf13d (patch) | |
| tree | a4ff720fb7bbbd4dd74eca4ae24950e2bf0c2449 | |
| parent | ac44b8a9c5ed6a761793e1fa997768bd00a6c2da (diff) | |
| download | nova-ef5c9e11595a00de468783adbb60cfbc2cbbf13d.tar.gz nova-ef5c9e11595a00de468783adbb60cfbc2cbbf13d.tar.xz nova-ef5c9e11595a00de468783adbb60cfbc2cbbf13d.zip | |
add Limited, an API limiting/versioning wrapper
| -rwxr-xr-x | bin/nova-direct-api | 7 | ||||
| -rw-r--r-- | nova/api/direct.py | 36 |
2 files changed, 43 insertions, 0 deletions
diff --git a/bin/nova-direct-api b/bin/nova-direct-api index 1a78fb0c0..ac0b5b51c 100755 --- a/bin/nova-direct-api +++ b/bin/nova-direct-api @@ -53,12 +53,19 @@ flags.DEFINE_flag(flags.HelpXMLFlag()) +class ReadOnlyCompute(direct.Limited): + """Read-only Compute API.""" + + _allowed = ['get', 'get_all', 'get_console_output'] + + if __name__ == '__main__': utils.default_flagfile() FLAGS(sys.argv) logging.setup() direct.register_service('compute', compute.API()) + direct.register_service('compute-readonly', ReadOnlyCompute(compute.API())) direct.register_service('volume', volume.API()) direct.register_service('network', network.API()) direct.register_service('reflect', direct.Reflection()) diff --git a/nova/api/direct.py b/nova/api/direct.py index dfca250e0..1011091a6 100644 --- a/nova/api/direct.py +++ b/nova/api/direct.py @@ -211,6 +211,42 @@ class ServiceWrapper(wsgi.Controller): return result +class Limited(object): + __notdoc = """Limit the available methods on a given object. + + (Not a docstring so that the docstring can be conditionally overriden.) + + Useful when defining a public API that only exposes a subset of an + internal API. + + Expected usage of this class is to define a subclass that lists the allowed + methods in the 'allowed' variable. + + Additionally where appropriate methods can be added or overwritten, for + example to provide backwards compatibility. + + """ + + _allowed = None + + def __init__(self, proxy): + self._proxy = proxy + if not self.__doc__: + self.__doc__ = proxy.__doc__ + if not self._allowed: + self._allowed = [] + + def __getattr__(self, key): + """Only return methods that are named in self._allowed.""" + if key not in self._allowed: + raise AttributeError() + return getattr(self._proxy, key) + + def __dir__(self): + """Only return methods that are named in self._allowed.""" + return [x for x in dir(self._proxy) if x in self._allowed] + + class Proxy(object): """Pretend a Direct API endpoint is an object.""" def __init__(self, app, prefix=None): |
