~ubuntu-branches/ubuntu/saucy/nova/saucy-proposed

« back to all changes in this revision

Viewing changes to nova/api/openstack/v2/extensions.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short, Chuck Short, Adam Gandleman
  • Date: 2012-01-13 09:51:10 UTC
  • mfrom: (1.1.40)
  • Revision ID: package-import@ubuntu.com-20120113095110-ffd6163drcg77wez
Tags: 2012.1~e3~20120113.12049-0ubuntu1
[Chuck Short]
* New upstream version.
* debian/nova_sudoers, debian/nova-common.install, 
  Switch out to nova-rootwrap. (LP: #681774)
* Add "get-origsource-git" which allows developers to 
  generate a tarball from github, by doing:
  fakeroot debian/rules get-orig-source-git
* debian/debian/nova-objectstore.logrotate: Dont determine
  if we are running Debian or Ubuntu. (LP: #91379)

[Adam Gandleman]
* Removed python-nova.postinst, let dh_python2 generate instead since
  python-support is not a dependency. (LP: #907543)

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
#    License for the specific language governing permissions and limitations
17
17
#    under the License.
18
18
 
19
 
import functools
20
 
import imp
21
 
import inspect
22
 
import os
23
 
import sys
24
 
 
25
 
from lxml import etree
26
19
import routes
27
20
import webob.dec
28
21
import webob.exc
29
22
 
30
23
import nova.api.openstack.v2
31
 
from nova.api.openstack import common
32
24
from nova.api.openstack import wsgi
33
25
from nova.api.openstack import xmlutil
34
26
from nova import exception
68
60
    # '2011-01-22T13:25:27-06:00'
69
61
    updated = None
70
62
 
 
63
    # This attribute causes the extension to load only when
 
64
    # the admin api is enabled
 
65
    admin_only = False
 
66
 
71
67
    def __init__(self, ext_mgr):
72
68
        """Register extension with the extension manager."""
73
69
 
140
136
 
141
137
    def __init__(self, application):
142
138
        controller = ActionExtensionController(application)
143
 
        wsgi.Resource.__init__(self, controller)
 
139
        wsgi.Resource.__init__(self, controller,
 
140
                               serializer=wsgi.ResponseSerializer(),
 
141
                               deserializer=wsgi.RequestDeserializer())
144
142
 
145
143
    def add_action(self, action_name, handler):
146
144
        self.controller.add_action(action_name, handler)
164
162
            pre_handler(req)
165
163
 
166
164
        res = req.get_response(self.application)
 
165
        res.environ = req.environ
167
166
 
168
167
        # Don't call extensions if the main application returned an
169
168
        # unsuccessful status
191
190
 
192
191
    def __init__(self, application):
193
192
        controller = RequestExtensionController(application)
194
 
        wsgi.Resource.__init__(self, controller)
 
193
        wsgi.Resource.__init__(self, controller,
 
194
                               serializer=wsgi.ResponseSerializer(),
 
195
                               deserializer=wsgi.RequestDeserializer())
195
196
 
196
197
    def add_handler(self, handler):
197
198
        self.controller.add_handler(handler)
200
201
        self.controller.add_pre_handler(pre_handler)
201
202
 
202
203
 
 
204
def make_ext(elem):
 
205
    elem.set('name')
 
206
    elem.set('namespace')
 
207
    elem.set('alias')
 
208
    elem.set('updated')
 
209
 
 
210
    desc = xmlutil.SubTemplateElement(elem, 'description')
 
211
    desc.text = 'description'
 
212
 
 
213
    xmlutil.make_links(elem, 'links')
 
214
 
 
215
 
 
216
ext_nsmap = {None: xmlutil.XMLNS_V11, 'atom': xmlutil.XMLNS_ATOM}
 
217
 
 
218
 
 
219
class ExtensionTemplate(xmlutil.TemplateBuilder):
 
220
    def construct(self):
 
221
        root = xmlutil.TemplateElement('extension', selector='extension')
 
222
        make_ext(root)
 
223
        return xmlutil.MasterTemplate(root, 1, nsmap=ext_nsmap)
 
224
 
 
225
 
 
226
class ExtensionsTemplate(xmlutil.TemplateBuilder):
 
227
    def construct(self):
 
228
        root = xmlutil.TemplateElement('extensions')
 
229
        elem = xmlutil.SubTemplateElement(root, 'extension',
 
230
                                          selector='extensions')
 
231
        make_ext(elem)
 
232
        return xmlutil.MasterTemplate(root, 1, nsmap=ext_nsmap)
 
233
 
 
234
 
203
235
class ExtensionsResource(wsgi.Resource):
204
236
 
205
237
    def __init__(self, extension_manager):
206
238
        self.extension_manager = extension_manager
 
239
        super(ExtensionsResource, self).__init__(None)
207
240
 
208
241
    def _translate(self, ext):
209
242
        ext_data = {}
215
248
        ext_data['links'] = []  # TODO(dprince): implement extension links
216
249
        return ext_data
217
250
 
 
251
    @wsgi.serializers(xml=ExtensionsTemplate)
218
252
    def index(self, req):
219
253
        extensions = []
220
254
        for _alias, ext in self.extension_manager.extensions.iteritems():
221
255
            extensions.append(self._translate(ext))
222
256
        return dict(extensions=extensions)
223
257
 
 
258
    @wsgi.serializers(xml=ExtensionTemplate)
224
259
    def show(self, req, id):
225
260
        try:
226
261
            # NOTE(dprince): the extensions alias is used as the 'id' for show
293
328
 
294
329
        mapper = nova.api.openstack.v2.ProjectMapper()
295
330
 
296
 
        serializer = wsgi.ResponseSerializer(
297
 
            {'application/xml': wsgi.XMLDictSerializer()})
298
 
        # extended resources
299
 
        for resource in ext_mgr.get_resources():
300
 
            LOG.debug(_('Extended resource: %s'),
301
 
                        resource.collection)
302
 
            if resource.serializer is None:
303
 
                resource.serializer = serializer
304
 
 
305
 
            kargs = dict(
306
 
                controller=wsgi.Resource(
307
 
                    resource.controller, resource.deserializer,
308
 
                    resource.serializer),
309
 
                collection=resource.collection_actions,
310
 
                member=resource.member_actions)
311
 
 
312
 
            if resource.parent:
313
 
                kargs['parent_resource'] = resource.parent
314
 
 
315
 
            mapper.resource(resource.collection, resource.collection, **kargs)
316
 
 
317
331
        # extended actions
318
332
        action_resources = self._action_ext_resources(application, ext_mgr,
319
333
                                                        mapper)
368
382
 
369
383
    """
370
384
 
371
 
    def __init__(self):
372
 
        LOG.audit(_('Initializing extension manager.'))
373
 
 
374
 
        self.extensions = {}
375
 
        self._load_extensions()
 
385
    _ext_mgr = None
 
386
 
 
387
    @classmethod
 
388
    def reset(cls):
 
389
        cls._ext_mgr = None
 
390
 
 
391
    def __new__(cls):
 
392
        if cls._ext_mgr is None:
 
393
            LOG.audit(_('Initializing extension manager.'))
 
394
 
 
395
            cls._ext_mgr = super(ExtensionManager, cls).__new__(cls)
 
396
 
 
397
            cls._ext_mgr.extensions = {}
 
398
            cls._ext_mgr._load_extensions()
 
399
 
 
400
        return cls._ext_mgr
376
401
 
377
402
    def register(self, ext):
378
403
        # Do nothing if the extension doesn't check out
388
413
 
389
414
    def get_resources(self):
390
415
        """Returns a list of ResourceExtension objects."""
 
416
 
391
417
        resources = []
392
 
        serializer = wsgi.ResponseSerializer(
393
 
            {'application/xml': ExtensionsXMLSerializer()})
394
418
        resources.append(ResourceExtension('extensions',
395
 
                                           ExtensionsResource(self),
396
 
                                           serializer=serializer))
 
419
                                           ExtensionsResource(self)))
 
420
 
397
421
        for ext in self.extensions.values():
398
422
            try:
399
423
                resources.extend(ext.get_resources())
436
460
                      ' '.join(extension.__doc__.strip().split()))
437
461
            LOG.debug(_('Ext namespace: %s'), extension.namespace)
438
462
            LOG.debug(_('Ext updated: %s'), extension.updated)
 
463
            LOG.debug(_('Ext admin_only: %s'), extension.admin_only)
439
464
        except AttributeError as ex:
440
465
            LOG.exception(_("Exception loading extension: %s"), unicode(ex))
441
466
            return False
 
467
 
 
468
        # Don't load admin api extensions if the admin api isn't enabled
 
469
        if not FLAGS.allow_admin_api and extension.admin_only:
 
470
            return False
 
471
 
442
472
        return True
443
473
 
444
474
    def load_extension(self, ext_factory):
453
483
        LOG.debug(_("Loading extension %s"), ext_factory)
454
484
 
455
485
        # Load the factory
 
486
 
456
487
        factory = utils.import_class(ext_factory)
457
488
 
458
489
        # Call it
462
493
    def _load_extensions(self):
463
494
        """Load extensions specified on the command line."""
464
495
 
465
 
        for ext_factory in FLAGS.osapi_extension:
 
496
        extensions = list(FLAGS.osapi_extension)
 
497
 
 
498
        for ext_factory in extensions:
466
499
            try:
467
500
                self.load_extension(ext_factory)
468
501
            except Exception as exc:
513
546
        self.serializer = serializer
514
547
 
515
548
 
516
 
def make_ext(elem):
517
 
    elem.set('name')
518
 
    elem.set('namespace')
519
 
    elem.set('alias')
520
 
    elem.set('updated')
521
 
 
522
 
    desc = xmlutil.SubTemplateElement(elem, 'description')
523
 
    desc.text = 'description'
524
 
 
525
 
    xmlutil.make_links(elem, 'links')
526
 
 
527
 
 
528
 
ext_nsmap = {None: xmlutil.XMLNS_V11, 'atom': xmlutil.XMLNS_ATOM}
529
 
 
530
 
 
531
 
class ExtensionTemplate(xmlutil.TemplateBuilder):
532
 
    def construct(self):
533
 
        root = xmlutil.TemplateElement('extension', selector='extension')
534
 
        make_ext(root)
535
 
        return xmlutil.MasterTemplate(root, 1, nsmap=ext_nsmap)
536
 
 
537
 
 
538
 
class ExtensionsTemplate(xmlutil.TemplateBuilder):
539
 
    def construct(self):
540
 
        root = xmlutil.TemplateElement('extensions')
541
 
        elem = xmlutil.SubTemplateElement(root, 'extension',
542
 
                                          selector='extensions')
543
 
        make_ext(elem)
544
 
        return xmlutil.MasterTemplate(root, 1, nsmap=ext_nsmap)
545
 
 
546
 
 
547
549
class ExtensionsXMLSerializer(xmlutil.XMLTemplateSerializer):
548
550
    def index(self):
549
551
        return ExtensionsTemplate()
552
554
        return ExtensionTemplate()
553
555
 
554
556
 
555
 
def admin_only(fnc):
556
 
    @functools.wraps(fnc)
557
 
    def _wrapped(self, *args, **kwargs):
558
 
        if FLAGS.allow_admin_api:
559
 
            return fnc(self, *args, **kwargs)
560
 
        raise webob.exc.HTTPNotFound()
561
 
    _wrapped.func_name = fnc.func_name
562
 
    return _wrapped
 
557
def require_admin(f):
 
558
    @functools.wraps(f)
 
559
    def wraps(self, req, *args, **kwargs):
 
560
        if 'nova.context' in req.environ and\
 
561
           req.environ['nova.context'].is_admin:
 
562
            return f(self, req, *args, **kwargs)
 
563
        else:
 
564
            raise exception.AdminRequired()
 
565
    return wraps
563
566
 
564
567
 
565
568
def wrap_errors(fn):