merged trunk rev569
This commit is contained in:
		
							
								
								
									
										6
									
								
								Authors
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								Authors
									
									
									
									
									
								
							| @@ -4,8 +4,8 @@ Anthony Young <sleepsonthefloor@gmail.com> | ||||
| Antony Messerli <ant@openstack.org> | ||||
| Armando Migliaccio <Armando.Migliaccio@eu.citrix.com> | ||||
| Chiradeep Vittal <chiradeep@cloud.com> | ||||
| Chris Behrens <cbehrens@codestud.com> | ||||
| Chmouel Boudjnah <chmouel@chmouel.com> | ||||
| Chris Behrens <cbehrens@codestud.com> | ||||
| Cory Wright <corywright@gmail.com> | ||||
| David Pravec <David.Pravec@danix.org> | ||||
| Dean Troyer <dtroyer@gmail.com> | ||||
| @@ -14,6 +14,7 @@ Ed Leafe <ed@leafe.com> | ||||
| Eldar Nugaev <enugaev@griddynamics.com> | ||||
| Eric Day <eday@oddments.org> | ||||
| Ewan Mellor <ewan.mellor@citrix.com> | ||||
| Hisaharu Ishii <ishii.hisaharu@lab.ntt.co.jp> | ||||
| Hisaki Ohara <hisaki.ohara@intel.com> | ||||
| Ilya Alekseyev <ialekseev@griddynamics.com> | ||||
| Jay Pipes <jaypipes@gmail.com> | ||||
| @@ -27,12 +28,15 @@ Joshua McKenty <jmckenty@gmail.com> | ||||
| Justin Santa Barbara <justin@fathomdb.com> | ||||
| Kei Masumoto <masumotok@nttdata.co.jp> | ||||
| Ken Pepple <ken.pepple@gmail.com> | ||||
| Koji Iida <iida.koji@lab.ntt.co.jp> | ||||
| Lorin Hochstein <lorin@isi.edu> | ||||
| Matt Dietz <matt.dietz@rackspace.com> | ||||
| Michael Gundlach <michael.gundlach@rackspace.com> | ||||
| Monsyne Dragon <mdragon@rackspace.com> | ||||
| Monty Taylor <mordred@inaugust.com> | ||||
| MORITA Kazutaka <morita.kazutaka@gmail.com> | ||||
| Muneyuki Noguchi <noguchimn@nttdata.co.jp> | ||||
| Nachi Ueno <ueno.nachi@lab.ntt.co.jp> <openstack@lab.ntt.co.jp> <nati.ueno@gmail.com> <nova@u4> | ||||
| Paul Voccio <paul@openstack.org> | ||||
| Rick Clark <rick@openstack.org> | ||||
| Rick Harris <rconradharris@gmail.com> | ||||
|   | ||||
							
								
								
									
										61
									
								
								bin/nova-direct-api
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										61
									
								
								bin/nova-direct-api
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,61 @@ | ||||
| #!/usr/bin/env python | ||||
| # pylint: disable-msg=C0103 | ||||
| # vim: tabstop=4 shiftwidth=4 softtabstop=4 | ||||
|  | ||||
| # Copyright 2010 United States Government as represented by the | ||||
| # Administrator of the National Aeronautics and Space Administration. | ||||
| # All Rights Reserved. | ||||
| # | ||||
| #    Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| #    you may not use this file except in compliance with the License. | ||||
| #    You may obtain a copy of the License at | ||||
| # | ||||
| #        http://www.apache.org/licenses/LICENSE-2.0 | ||||
| # | ||||
| #    Unless required by applicable law or agreed to in writing, software | ||||
| #    distributed under the License is distributed on an "AS IS" BASIS, | ||||
| #    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| #    See the License for the specific language governing permissions and | ||||
| #    limitations under the License. | ||||
|  | ||||
| """Starter script for Nova Direct API.""" | ||||
|  | ||||
| import gettext | ||||
| import os | ||||
| import sys | ||||
|  | ||||
| # If ../nova/__init__.py exists, add ../ to Python search path, so that | ||||
| # it will override what happens to be installed in /usr/(local/)lib/python... | ||||
| possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), | ||||
|                                    os.pardir, | ||||
|                                    os.pardir)) | ||||
| if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')): | ||||
|     sys.path.insert(0, possible_topdir) | ||||
|  | ||||
| gettext.install('nova', unicode=1) | ||||
|  | ||||
| from nova import flags | ||||
| from nova import utils | ||||
| from nova import wsgi | ||||
| from nova.api import direct | ||||
| from nova.compute import api as compute_api | ||||
|  | ||||
|  | ||||
| FLAGS = flags.FLAGS | ||||
| flags.DEFINE_integer('direct_port', 8001, 'Direct API port') | ||||
| flags.DEFINE_string('direct_host', '0.0.0.0', 'Direct API host') | ||||
|  | ||||
| if __name__ == '__main__': | ||||
|     utils.default_flagfile() | ||||
|     FLAGS(sys.argv) | ||||
|  | ||||
|     direct.register_service('compute', compute_api.ComputeAPI()) | ||||
|     direct.register_service('reflect', direct.Reflection()) | ||||
|     router = direct.Router() | ||||
|     with_json = direct.JsonParamsMiddleware(router) | ||||
|     with_req = direct.PostParamsMiddleware(with_json) | ||||
|     with_auth = direct.DelegatedAuthMiddleware(with_req) | ||||
|  | ||||
|     server = wsgi.Server() | ||||
|     server.start(with_auth, FLAGS.direct_port, host=FLAGS.direct_host) | ||||
|     server.wait() | ||||
| @@ -93,6 +93,7 @@ flags.DECLARE('num_networks', 'nova.network.manager') | ||||
| flags.DECLARE('network_size', 'nova.network.manager') | ||||
| flags.DECLARE('vlan_start', 'nova.network.manager') | ||||
| flags.DECLARE('vpn_start', 'nova.network.manager') | ||||
| flags.DECLARE('fixed_range_v6', 'nova.network.manager') | ||||
|  | ||||
|  | ||||
| class VpnCommands(object): | ||||
| @@ -441,11 +442,12 @@ class NetworkCommands(object): | ||||
|     """Class for managing networks.""" | ||||
|  | ||||
|     def create(self, fixed_range=None, num_networks=None, | ||||
|                network_size=None, vlan_start=None, vpn_start=None): | ||||
|                network_size=None, vlan_start=None, vpn_start=None, | ||||
|                fixed_range_v6=None): | ||||
|         """Creates fixed ips for host by range | ||||
|         arguments: [fixed_range=FLAG], [num_networks=FLAG], | ||||
|                    [network_size=FLAG], [vlan_start=FLAG], | ||||
|                    [vpn_start=FLAG]""" | ||||
|                    [vpn_start=FLAG], [fixed_range_v6=FLAG]""" | ||||
|         if not fixed_range: | ||||
|             fixed_range = FLAGS.fixed_range | ||||
|         if not num_networks: | ||||
| @@ -456,11 +458,13 @@ class NetworkCommands(object): | ||||
|             vlan_start = FLAGS.vlan_start | ||||
|         if not vpn_start: | ||||
|             vpn_start = FLAGS.vpn_start | ||||
|         if not fixed_range_v6: | ||||
|             fixed_range_v6 = FLAGS.fixed_range_v6 | ||||
|         net_manager = utils.import_object(FLAGS.network_manager) | ||||
|         net_manager.create_networks(context.get_admin_context(), | ||||
|                                     fixed_range, int(num_networks), | ||||
|                                     int(network_size), int(vlan_start), | ||||
|                                     int(vpn_start)) | ||||
|                                     int(vpn_start), fixed_range_v6) | ||||
|  | ||||
|  | ||||
| class InstanceCommands(object): | ||||
| @@ -477,7 +481,7 @@ class InstanceCommands(object): | ||||
|             raise exception.Error(msg) | ||||
|  | ||||
|         if FLAGS.volume_driver != 'nova.volume.driver.AOEDriver': | ||||
|             instance_ref = db.instance_get(instance_id) | ||||
|             instance_ref = db.instance_get(ctxt, instance_id) | ||||
|             if len(instance_ref['volumes']) != 0: | ||||
|                 msg = _(("""Volumes attached by ISCSIDriver""" | ||||
|                          """ are not supported. Sorry!""")) | ||||
| @@ -505,7 +509,7 @@ class HostCommands(object): | ||||
|         logging.basicConfig() | ||||
|  | ||||
|         service_refs = db.service_get_all(context.get_admin_context()) | ||||
|         hosts = [ h['host'] for h in service_refs] | ||||
|         hosts = [h['host'] for h in service_refs] | ||||
|         hosts = list(set(hosts)) | ||||
|         for host in hosts: | ||||
|             print host | ||||
|   | ||||
							
								
								
									
										145
									
								
								bin/stack
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										145
									
								
								bin/stack
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,145 @@ | ||||
| #!/usr/bin/env python | ||||
| # vim: tabstop=4 shiftwidth=4 softtabstop=4 | ||||
|  | ||||
| # Copyright 2010 United States Government as represented by the | ||||
| # Administrator of the National Aeronautics and Space Administration. | ||||
| # All Rights Reserved. | ||||
| # | ||||
| #    Licensed under the Apache License, Version 2.0 (the "License"); you may | ||||
| #    not use this file except in compliance with the License. You may obtain | ||||
| #    a copy of the License at | ||||
| # | ||||
| #         http://www.apache.org/licenses/LICENSE-2.0 | ||||
| # | ||||
| #    Unless required by applicable law or agreed to in writing, software | ||||
| #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
| #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
| #    License for the specific language governing permissions and limitations | ||||
| #    under the License. | ||||
|  | ||||
| """CLI for the Direct API.""" | ||||
|  | ||||
| import eventlet | ||||
| eventlet.monkey_patch() | ||||
|  | ||||
| import os | ||||
| import pprint | ||||
| import sys | ||||
| import textwrap | ||||
| import urllib | ||||
| import urllib2 | ||||
|  | ||||
| # If ../nova/__init__.py exists, add ../ to Python search path, so that | ||||
| # it will override what happens to be installed in /usr/(local/)lib/python... | ||||
| possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), | ||||
|                                    os.pardir, | ||||
|                                    os.pardir)) | ||||
| if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')): | ||||
|     sys.path.insert(0, possible_topdir) | ||||
|  | ||||
| import gflags | ||||
| from nova import utils | ||||
|  | ||||
|  | ||||
| FLAGS = gflags.FLAGS | ||||
| gflags.DEFINE_string('host', '127.0.0.1', 'Direct API host') | ||||
| gflags.DEFINE_integer('port', 8001, 'Direct API host') | ||||
| gflags.DEFINE_string('user', 'user1', 'Direct API username') | ||||
| gflags.DEFINE_string('project', 'proj1', 'Direct API project') | ||||
|  | ||||
|  | ||||
| USAGE = """usage: stack [options] <controller> <method> [arg1=value arg2=value] | ||||
|  | ||||
|   `stack help` should output the list of available controllers | ||||
|   `stack <controller>` should output the available methods for that controller | ||||
|   `stack help <controller>` should do the same | ||||
|   `stack help <controller> <method>` should output info for a method | ||||
| """ | ||||
|  | ||||
|  | ||||
| def format_help(d): | ||||
|     """Format help text, keys are labels and values are descriptions.""" | ||||
|     indent = max([len(k) for k in d]) | ||||
|     out = [] | ||||
|     for k, v in d.iteritems(): | ||||
|         t = textwrap.TextWrapper(initial_indent='   %s   ' % k.ljust(indent), | ||||
|                                  subsequent_indent=' ' * (indent + 6)) | ||||
|         out.extend(t.wrap(v)) | ||||
|     return out | ||||
|  | ||||
|  | ||||
| def help_all(): | ||||
|     rv = do_request('reflect', 'get_controllers') | ||||
|     out = format_help(rv) | ||||
|     return (USAGE + str(FLAGS.MainModuleHelp()) + | ||||
|             '\n\nAvailable controllers:\n' + | ||||
|             '\n'.join(out) + '\n') | ||||
|  | ||||
|  | ||||
| def help_controller(controller): | ||||
|     rv = do_request('reflect', 'get_methods') | ||||
|     methods = dict([(k.split('/')[2], v) for k, v in rv.iteritems() | ||||
|                if k.startswith('/%s' % controller)]) | ||||
|     return ('Available methods for %s:\n' % controller + | ||||
|             '\n'.join(format_help(methods))) | ||||
|  | ||||
|  | ||||
| def help_method(controller, method): | ||||
|     rv = do_request('reflect', | ||||
|                     'get_method_info', | ||||
|                     {'method': '/%s/%s' % (controller, method)}) | ||||
|  | ||||
|     sig = '%s(%s):' % (method, ', '.join(['='.join(x) for x in rv['args']])) | ||||
|     out = textwrap.wrap(sig, subsequent_indent=' ' * len('%s(' % method)) | ||||
|     out.append('\n' + rv['doc']) | ||||
|     return '\n'.join(out) | ||||
|  | ||||
|  | ||||
| def do_request(controller, method, params=None): | ||||
|     if params: | ||||
|         data = urllib.urlencode(params) | ||||
|     else: | ||||
|         data = None | ||||
|  | ||||
|     url = 'http://%s:%s/%s/%s' % (FLAGS.host, FLAGS.port, controller, method) | ||||
|     headers = {'X-OpenStack-User': FLAGS.user, | ||||
|                'X-OpenStack-Project': FLAGS.project} | ||||
|  | ||||
|     req = urllib2.Request(url, data, headers) | ||||
|     resp = urllib2.urlopen(req) | ||||
|     return utils.loads(resp.read()) | ||||
|  | ||||
|  | ||||
| if __name__ == '__main__': | ||||
|     args = FLAGS(sys.argv) | ||||
|  | ||||
|     cmd = args.pop(0) | ||||
|     if not args: | ||||
|         print help_all() | ||||
|         sys.exit() | ||||
|  | ||||
|     first = args.pop(0) | ||||
|     if first == 'help': | ||||
|         action = help_all | ||||
|         params = [] | ||||
|         if args: | ||||
|             params.append(args.pop(0)) | ||||
|             action = help_controller | ||||
|         if args: | ||||
|             params.append(args.pop(0)) | ||||
|             action = help_method | ||||
|         print action(*params) | ||||
|         sys.exit(0) | ||||
|  | ||||
|     controller = first | ||||
|     if not args: | ||||
|         print help_controller(controller) | ||||
|         sys.exit() | ||||
|  | ||||
|     method = args.pop(0) | ||||
|     params = {} | ||||
|     for x in args: | ||||
|         key, value = x.split('=', 1) | ||||
|         params[key] = value | ||||
|  | ||||
|     pprint.pprint(do_request(controller, method, params)) | ||||
| @@ -76,6 +76,10 @@ class InvalidInputException(Error): | ||||
|     pass | ||||
|  | ||||
|  | ||||
| class TimeoutException(Error): | ||||
|     pass | ||||
|  | ||||
|  | ||||
| def wrap_exception(f): | ||||
|     def _wrap(*args, **kw): | ||||
|         try: | ||||
|   | ||||
| @@ -111,7 +111,8 @@ class Scheduler(object): | ||||
|             ec2_id = instance_ref['hostname'] | ||||
|             raise exception.Invalid(msg % ec2_id) | ||||
|  | ||||
|         # Checing volume node is running when any volumes are mounted to the instance. | ||||
|         # Checing volume node is running when any volumes are mounted | ||||
|         # to the instance. | ||||
|         if len(instance_ref['volumes']) != 0: | ||||
|             services = db.service_get_all_by_topic(context, 'volume') | ||||
|             if len(services) < 1 or  not self.service_is_up(services[0]): | ||||
| @@ -126,13 +127,12 @@ class Scheduler(object): | ||||
|             msg = _('%s is not alive(time synchronize problem?)') | ||||
|             raise exception.Invalid(msg % src) | ||||
|  | ||||
|  | ||||
|     def _live_migration_dest_check(self, context, instance_ref, dest): | ||||
|         """Live migration check routine (for destination host)""" | ||||
|  | ||||
|         # Checking dest exists and compute node. | ||||
|         dservice_refs = db.service_get_all_by_host(context, dest) | ||||
|         if len(dservice_refs) <= 0 :  | ||||
|         if len(dservice_refs) <= 0: | ||||
|             msg = _('%s does not exists.') | ||||
|             raise exception.Invalid(msg % dest) | ||||
|  | ||||
| @@ -167,7 +167,7 @@ class Scheduler(object): | ||||
|  | ||||
|         # Checking dest exists. | ||||
|         dservice_refs = db.service_get_all_by_host(context, dest) | ||||
|         if len(dservice_refs) <= 0 :  | ||||
|         if len(dservice_refs) <= 0: | ||||
|             msg = _('%s does not exists.') | ||||
|             raise exception.Invalid(msg % dest) | ||||
|         dservice_ref = dservice_refs[0] | ||||
| @@ -175,7 +175,7 @@ class Scheduler(object): | ||||
|         # Checking original host( where instance was launched at) exists. | ||||
|         orighost = instance_ref['launched_on'] | ||||
|         oservice_refs = db.service_get_all_by_host(context, orighost) | ||||
|         if len(oservice_refs) <= 0 :  | ||||
|         if len(oservice_refs) <= 0: | ||||
|             msg = _('%s(where instance was launched at) does not exists.') | ||||
|             raise exception.Invalid(msg % orighost) | ||||
|         oservice_ref = oservice_refs[0] | ||||
| @@ -203,7 +203,8 @@ class Scheduler(object): | ||||
|                       "args": {'cpu_info': cpu_info}}) | ||||
|  | ||||
|         except rpc.RemoteError, e: | ||||
|             msg = _('%s doesnt have compatibility to %s(where %s launching at)') | ||||
|             msg = _(("""%s doesnt have compatibility to %s""" | ||||
|                      """(where %s was launched at)""")) | ||||
|             ec2_id = instance_ref['hostname'] | ||||
|             src = instance_ref['host'] | ||||
|             logging.error(msg % (dest, src, ec2_id)) | ||||
| @@ -220,7 +221,7 @@ class Scheduler(object): | ||||
|  | ||||
|         # Gettin host information | ||||
|         service_refs = db.service_get_all_by_host(context, dest) | ||||
|         if len(service_refs) <= 0 :  | ||||
|         if len(service_refs) <= 0: | ||||
|             msg = _('%s does not exists.') | ||||
|             raise exception.Invalid(msg % dest) | ||||
|         service_ref = service_refs[0] | ||||
|   | ||||
| @@ -75,12 +75,9 @@ class SchedulerManager(manager.Manager): | ||||
|     def show_host_resource(self, context, host, *args): | ||||
|         """ show the physical/usage resource given by hosts.""" | ||||
|  | ||||
|         try: | ||||
|             services = db.service_get_all_by_host(context, host) | ||||
|         except exception.NotFound: | ||||
|         services = db.service_get_all_by_host(context, host) | ||||
|         if len(services) == 0: | ||||
|             return {'ret': False, 'msg': 'No such Host'} | ||||
|         except: | ||||
|             raise | ||||
|  | ||||
|         compute = [ s for s in services if s['topic'] == 'compute'] | ||||
|         if 0 == len(compute):  | ||||
| @@ -93,6 +90,7 @@ class SchedulerManager(manager.Manager): | ||||
|                      'memory_mb': service_ref['memory_mb'], | ||||
|                      'local_gb': service_ref['local_gb']} | ||||
|  | ||||
|          | ||||
|         # Getting usage resource information | ||||
|         u_resource = {} | ||||
|         instances_ref = db.instance_get_all_by_host(context,  | ||||
|   | ||||
| @@ -119,11 +119,11 @@ class Service(object): | ||||
|     def _create_service_ref(self, context): | ||||
|         zone = FLAGS.node_availability_zone | ||||
|         service_ref = db.service_create(context, | ||||
|                                         {'host': self.host, | ||||
|                                          'binary': self.binary, | ||||
|                                          'topic': self.topic, | ||||
|                                         {'host':self.host, | ||||
|                                          'binary':self.binary, | ||||
|                                          'topic':self.topic, | ||||
|                                          'report_count': 0, | ||||
|                                          'availability_zone': zone}) | ||||
|                                          'availability_zone':zone}) | ||||
|         self.service_id = service_ref['id'] | ||||
|  | ||||
|     def __getattr__(self, key): | ||||
|   | ||||
							
								
								
									
										99
									
								
								nova/test.py
									
									
									
									
									
								
							
							
						
						
									
										99
									
								
								nova/test.py
									
									
									
									
									
								
							| @@ -23,14 +23,10 @@ and some black magic for inline callbacks. | ||||
| """ | ||||
|  | ||||
| import datetime | ||||
| import sys | ||||
| import time | ||||
| import unittest | ||||
|  | ||||
| import mox | ||||
| import stubout | ||||
| from twisted.internet import defer | ||||
| from twisted.trial import unittest as trial_unittest | ||||
|  | ||||
| from nova import context | ||||
| from nova import db | ||||
| @@ -74,7 +70,8 @@ class TestCase(unittest.TestCase): | ||||
|                                                           FLAGS.fixed_range, | ||||
|                                                           5, 16, | ||||
|                                                           FLAGS.vlan_start, | ||||
|                                                           FLAGS.vpn_start) | ||||
|                                                           FLAGS.vpn_start, | ||||
|                                                           FLAGS.fixed_range_v6) | ||||
|  | ||||
|         # emulate some of the mox stuff, we can't use the metaclass | ||||
|         # because it screws with our generators | ||||
| @@ -139,95 +136,3 @@ class TestCase(unittest.TestCase): | ||||
|  | ||||
|         _wrapped.func_name = self.originalAttach.func_name | ||||
|         rpc.Consumer.attach_to_eventlet = _wrapped | ||||
|  | ||||
|  | ||||
| class TrialTestCase(trial_unittest.TestCase): | ||||
|     """Test case base class for all unit tests""" | ||||
|     def setUp(self): | ||||
|         """Run before each test method to initialize test environment""" | ||||
|         super(TrialTestCase, self).setUp() | ||||
|         # NOTE(vish): We need a better method for creating fixtures for tests | ||||
|         #             now that we have some required db setup for the system | ||||
|         #             to work properly. | ||||
|         self.start = datetime.datetime.utcnow() | ||||
|         ctxt = context.get_admin_context() | ||||
|         if db.network_count(ctxt) != 5: | ||||
|             network_manager.VlanManager().create_networks(ctxt, | ||||
|                                                           FLAGS.fixed_range, | ||||
|                                                           5, 16, | ||||
|                                                           FLAGS.vlan_start, | ||||
|                                                           FLAGS.vpn_start) | ||||
|  | ||||
|         # emulate some of the mox stuff, we can't use the metaclass | ||||
|         # because it screws with our generators | ||||
|         self.mox = mox.Mox() | ||||
|         self.stubs = stubout.StubOutForTesting() | ||||
|         self.flag_overrides = {} | ||||
|         self.injected = [] | ||||
|         self._original_flags = FLAGS.FlagValuesDict() | ||||
|  | ||||
|     def tearDown(self): | ||||
|         """Runs after each test method to finalize/tear down test | ||||
|         environment.""" | ||||
|         try: | ||||
|             self.mox.UnsetStubs() | ||||
|             self.stubs.UnsetAll() | ||||
|             self.stubs.SmartUnsetAll() | ||||
|             self.mox.VerifyAll() | ||||
|             # NOTE(vish): Clean up any ips associated during the test. | ||||
|             ctxt = context.get_admin_context() | ||||
|             db.fixed_ip_disassociate_all_by_timeout(ctxt, FLAGS.host, | ||||
|                                                     self.start) | ||||
|             db.network_disassociate_all(ctxt) | ||||
|             for x in self.injected: | ||||
|                 try: | ||||
|                     x.stop() | ||||
|                 except AssertionError: | ||||
|                     pass | ||||
|  | ||||
|             if FLAGS.fake_rabbit: | ||||
|                 fakerabbit.reset_all() | ||||
|  | ||||
|             db.security_group_destroy_all(ctxt) | ||||
|             super(TrialTestCase, self).tearDown() | ||||
|         finally: | ||||
|             self.reset_flags() | ||||
|  | ||||
|     def flags(self, **kw): | ||||
|         """Override flag variables for a test""" | ||||
|         for k, v in kw.iteritems(): | ||||
|             if k in self.flag_overrides: | ||||
|                 self.reset_flags() | ||||
|                 raise Exception( | ||||
|                         'trying to override already overriden flag: %s' % k) | ||||
|             self.flag_overrides[k] = getattr(FLAGS, k) | ||||
|             setattr(FLAGS, k, v) | ||||
|  | ||||
|     def reset_flags(self): | ||||
|         """Resets all flag variables for the test.  Runs after each test""" | ||||
|         FLAGS.Reset() | ||||
|         for k, v in self._original_flags.iteritems(): | ||||
|             setattr(FLAGS, k, v) | ||||
|  | ||||
|     def run(self, result=None): | ||||
|         test_method = getattr(self, self._testMethodName) | ||||
|         setattr(self, | ||||
|                 self._testMethodName, | ||||
|                 self._maybeInlineCallbacks(test_method, result)) | ||||
|         rv = super(TrialTestCase, self).run(result) | ||||
|         setattr(self, self._testMethodName, test_method) | ||||
|         return rv | ||||
|  | ||||
|     def _maybeInlineCallbacks(self, func, result): | ||||
|         def _wrapped(): | ||||
|             g = func() | ||||
|             if isinstance(g, defer.Deferred): | ||||
|                 return g | ||||
|             if not hasattr(g, 'send'): | ||||
|                 return defer.succeed(g) | ||||
|  | ||||
|             inlined = defer.inlineCallbacks(func) | ||||
|             d = inlined() | ||||
|             return d | ||||
|         _wrapped.func_name = func.func_name | ||||
|         return _wrapped | ||||
|   | ||||
| @@ -79,7 +79,7 @@ class FakeHttplibConnection(object): | ||||
|         pass | ||||
|  | ||||
|  | ||||
| class XmlConversionTestCase(test.TrialTestCase): | ||||
| class XmlConversionTestCase(test.TestCase): | ||||
|     """Unit test api xml conversion""" | ||||
|     def test_number_conversion(self): | ||||
|         conv = apirequest._try_convert | ||||
| @@ -96,7 +96,7 @@ class XmlConversionTestCase(test.TrialTestCase): | ||||
|         self.assertEqual(conv('-0'), 0) | ||||
|  | ||||
|  | ||||
| class ApiEc2TestCase(test.TrialTestCase): | ||||
| class ApiEc2TestCase(test.TestCase): | ||||
|     """Unit test for the cloud controller on an EC2 API""" | ||||
|     def setUp(self): | ||||
|         super(ApiEc2TestCase, self).setUp() | ||||
| @@ -265,6 +265,72 @@ class ApiEc2TestCase(test.TrialTestCase): | ||||
|  | ||||
|         return | ||||
|  | ||||
|     def test_authorize_revoke_security_group_cidr_v6(self): | ||||
|         """ | ||||
|         Test that we can add and remove CIDR based rules | ||||
|         to a security group for IPv6 | ||||
|         """ | ||||
|         self.expect_http() | ||||
|         self.mox.ReplayAll() | ||||
|         user = self.manager.create_user('fake', 'fake', 'fake') | ||||
|         project = self.manager.create_project('fake', 'fake', 'fake') | ||||
|  | ||||
|         # At the moment, you need both of these to actually be netadmin | ||||
|         self.manager.add_role('fake', 'netadmin') | ||||
|         project.add_role('fake', 'netadmin') | ||||
|  | ||||
|         security_group_name = "".join(random.choice("sdiuisudfsdcnpaqwertasd") | ||||
|                                       for x in range(random.randint(4, 8))) | ||||
|  | ||||
|         group = self.ec2.create_security_group(security_group_name, | ||||
|                                                'test group') | ||||
|  | ||||
|         self.expect_http() | ||||
|         self.mox.ReplayAll() | ||||
|         group.connection = self.ec2 | ||||
|  | ||||
|         group.authorize('tcp', 80, 81, '::/0') | ||||
|  | ||||
|         self.expect_http() | ||||
|         self.mox.ReplayAll() | ||||
|  | ||||
|         rv = self.ec2.get_all_security_groups() | ||||
|         # I don't bother checkng that we actually find it here, | ||||
|         # because the create/delete unit test further up should | ||||
|         # be good enough for that. | ||||
|         for group in rv: | ||||
|             if group.name == security_group_name: | ||||
|                 self.assertEquals(len(group.rules), 1) | ||||
|                 self.assertEquals(int(group.rules[0].from_port), 80) | ||||
|                 self.assertEquals(int(group.rules[0].to_port), 81) | ||||
|                 self.assertEquals(len(group.rules[0].grants), 1) | ||||
|                 self.assertEquals(str(group.rules[0].grants[0]), '::/0') | ||||
|  | ||||
|         self.expect_http() | ||||
|         self.mox.ReplayAll() | ||||
|         group.connection = self.ec2 | ||||
|  | ||||
|         group.revoke('tcp', 80, 81, '::/0') | ||||
|  | ||||
|         self.expect_http() | ||||
|         self.mox.ReplayAll() | ||||
|  | ||||
|         self.ec2.delete_security_group(security_group_name) | ||||
|  | ||||
|         self.expect_http() | ||||
|         self.mox.ReplayAll() | ||||
|         group.connection = self.ec2 | ||||
|  | ||||
|         rv = self.ec2.get_all_security_groups() | ||||
|  | ||||
|         self.assertEqual(len(rv), 1) | ||||
|         self.assertEqual(rv[0].name, 'default') | ||||
|  | ||||
|         self.manager.delete_project(project) | ||||
|         self.manager.delete_user(user) | ||||
|  | ||||
|         return | ||||
|  | ||||
|     def test_authorize_revoke_security_group_foreign_group(self): | ||||
|         """ | ||||
|         Test that we can grant and revoke another security group access | ||||
|   | ||||
| @@ -21,6 +21,7 @@ import json | ||||
| from M2Crypto import BIO | ||||
| from M2Crypto import RSA | ||||
| import os | ||||
| import shutil | ||||
| import tempfile | ||||
| import time | ||||
|  | ||||
| @@ -50,6 +51,8 @@ IMAGES_PATH = os.path.join(OSS_TEMPDIR, 'images') | ||||
| os.makedirs(IMAGES_PATH) | ||||
|  | ||||
|  | ||||
| # TODO(termie): these tests are rather fragile, they should at the lest be | ||||
| #               wiping database state after each run | ||||
| class CloudTestCase(test.TestCase): | ||||
|     def setUp(self): | ||||
|         super(CloudTestCase, self).setUp() | ||||
| @@ -287,6 +290,7 @@ class CloudTestCase(test.TestCase): | ||||
|         db.service_destroy(self.context, comp1['id']) | ||||
|  | ||||
|     def test_instance_update_state(self): | ||||
|         # TODO(termie): what is this code even testing? | ||||
|         def instance(num): | ||||
|             return { | ||||
|                 'reservation_id': 'r-1', | ||||
| @@ -305,7 +309,8 @@ class CloudTestCase(test.TestCase): | ||||
|                 'state': 0x01, | ||||
|                 'user_data': ''} | ||||
|         rv = self.cloud._format_describe_instances(self.context) | ||||
|         self.assert_(len(rv['reservationSet']) == 0) | ||||
|         logging.error(str(rv)) | ||||
|         self.assertEqual(len(rv['reservationSet']), 0) | ||||
|  | ||||
|         # simulate launch of 5 instances | ||||
|         # self.cloud.instances['pending'] = {} | ||||
| @@ -368,6 +373,7 @@ class CloudTestCase(test.TestCase): | ||||
|         self.assertEqual('Foo Img', img.metadata['description']) | ||||
|         self._fake_set_image_description(self.context, 'ami-testing', '') | ||||
|         self.assertEqual('', img.metadata['description']) | ||||
|         shutil.rmtree(pathdir) | ||||
|  | ||||
|     def test_update_of_instance_display_fields(self): | ||||
|         inst = db.instance_create(self.context, {}) | ||||
|   | ||||
| @@ -75,7 +75,7 @@ class ComputeTestCase(test.TestCase): | ||||
|             ref = self.compute_api.create(self.context, | ||||
|                 FLAGS.default_instance_type, None, **instance) | ||||
|             try: | ||||
|                 self.assertNotEqual(ref[0].display_name, None) | ||||
|                 self.assertNotEqual(ref[0]['display_name'], None) | ||||
|             finally: | ||||
|                 db.instance_destroy(self.context, ref[0]['id']) | ||||
|  | ||||
| @@ -86,10 +86,14 @@ class ComputeTestCase(test.TestCase): | ||||
|                   'user_id': self.user.id, | ||||
|                   'project_id': self.project.id} | ||||
|         group = db.security_group_create(self.context, values) | ||||
|         ref = self.compute_api.create(self.context, | ||||
|             FLAGS.default_instance_type, None, security_group=['default']) | ||||
|         ref = self.compute_api.create( | ||||
|                 self.context, | ||||
|                 instance_type=FLAGS.default_instance_type, | ||||
|                 image_id=None, | ||||
|                 security_group=['default']) | ||||
|         try: | ||||
|             self.assertEqual(len(ref[0]['security_groups']), 1) | ||||
|             self.assertEqual(len(db.security_group_get_by_instance( | ||||
|                 self.context, ref[0]['id'])), 1) | ||||
|         finally: | ||||
|             db.security_group_destroy(self.context, group['id']) | ||||
|             db.instance_destroy(self.context, ref[0]['id']) | ||||
| @@ -151,6 +155,13 @@ class ComputeTestCase(test.TestCase): | ||||
|         self.compute.reboot_instance(self.context, instance_id) | ||||
|         self.compute.terminate_instance(self.context, instance_id) | ||||
|  | ||||
|     def test_set_admin_password(self): | ||||
|         """Ensure instance can have its admin password set""" | ||||
|         instance_id = self._create_instance() | ||||
|         self.compute.run_instance(self.context, instance_id) | ||||
|         self.compute.set_admin_password(self.context, instance_id) | ||||
|         self.compute.terminate_instance(self.context, instance_id) | ||||
|  | ||||
|     def test_snapshot(self): | ||||
|         """Ensure instance can be snapshotted""" | ||||
|         instance_id = self._create_instance() | ||||
|   | ||||
| @@ -111,12 +111,14 @@ class ConsoleTestCase(test.TestCase): | ||||
|  | ||||
|         console_instances = [con['instance_id'] for con in pool.consoles] | ||||
|         self.assert_(instance_id in console_instances) | ||||
|         db.instance_destroy(self.context, instance_id) | ||||
|  | ||||
|     def test_add_console_does_not_duplicate(self): | ||||
|         instance_id = self._create_instance() | ||||
|         cons1 = self.console.add_console(self.context, instance_id) | ||||
|         cons2 = self.console.add_console(self.context, instance_id) | ||||
|         self.assertEqual(cons1, cons2) | ||||
|         db.instance_destroy(self.context, instance_id) | ||||
|  | ||||
|     def test_remove_console(self): | ||||
|         instance_id = self._create_instance() | ||||
| @@ -127,3 +129,4 @@ class ConsoleTestCase(test.TestCase): | ||||
|                           db.console_get, | ||||
|                           self.context, | ||||
|                           console_id) | ||||
|         db.instance_destroy(self.context, instance_id) | ||||
|   | ||||
							
								
								
									
										103
									
								
								nova/tests/test_direct.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								nova/tests/test_direct.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,103 @@ | ||||
| # vim: tabstop=4 shiftwidth=4 softtabstop=4 | ||||
|  | ||||
| # Copyright 2010 United States Government as represented by the | ||||
| # Administrator of the National Aeronautics and Space Administration. | ||||
| # All Rights Reserved. | ||||
| # | ||||
| #    Licensed under the Apache License, Version 2.0 (the "License"); you may | ||||
| #    not use this file except in compliance with the License. You may obtain | ||||
| #    a copy of the License at | ||||
| # | ||||
| #         http://www.apache.org/licenses/LICENSE-2.0 | ||||
| # | ||||
| #    Unless required by applicable law or agreed to in writing, software | ||||
| #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
| #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
| #    License for the specific language governing permissions and limitations | ||||
| #    under the License. | ||||
|  | ||||
| """Tests for Direct API.""" | ||||
|  | ||||
| import json | ||||
| import logging | ||||
|  | ||||
| import webob | ||||
|  | ||||
| from nova import compute | ||||
| from nova import context | ||||
| from nova import exception | ||||
| from nova import test | ||||
| from nova import utils | ||||
| from nova.api import direct | ||||
| from nova.tests import test_cloud | ||||
|  | ||||
|  | ||||
| class FakeService(object): | ||||
|     def echo(self, context, data): | ||||
|         return {'data': data} | ||||
|  | ||||
|     def context(self, context): | ||||
|         return {'user': context.user_id, | ||||
|                 'project': context.project_id} | ||||
|  | ||||
|  | ||||
| class DirectTestCase(test.TestCase): | ||||
|     def setUp(self): | ||||
|         super(DirectTestCase, self).setUp() | ||||
|         direct.register_service('fake', FakeService()) | ||||
|         self.router = direct.PostParamsMiddleware( | ||||
|                 direct.JsonParamsMiddleware( | ||||
|                         direct.Router())) | ||||
|         self.auth_router = direct.DelegatedAuthMiddleware(self.router) | ||||
|         self.context = context.RequestContext('user1', 'proj1') | ||||
|  | ||||
|     def tearDown(self): | ||||
|         direct.ROUTES = {} | ||||
|  | ||||
|     def test_delegated_auth(self): | ||||
|         req = webob.Request.blank('/fake/context') | ||||
|         req.headers['X-OpenStack-User'] = 'user1' | ||||
|         req.headers['X-OpenStack-Project'] = 'proj1' | ||||
|         resp = req.get_response(self.auth_router) | ||||
|         data = json.loads(resp.body) | ||||
|         self.assertEqual(data['user'], 'user1') | ||||
|         self.assertEqual(data['project'], 'proj1') | ||||
|  | ||||
|     def test_json_params(self): | ||||
|         req = webob.Request.blank('/fake/echo') | ||||
|         req.environ['openstack.context'] = self.context | ||||
|         req.method = 'POST' | ||||
|         req.body = 'json=%s' % json.dumps({'data': 'foo'}) | ||||
|         resp = req.get_response(self.router) | ||||
|         resp_parsed = json.loads(resp.body) | ||||
|         self.assertEqual(resp_parsed['data'], 'foo') | ||||
|  | ||||
|     def test_post_params(self): | ||||
|         req = webob.Request.blank('/fake/echo') | ||||
|         req.environ['openstack.context'] = self.context | ||||
|         req.method = 'POST' | ||||
|         req.body = 'data=foo' | ||||
|         resp = req.get_response(self.router) | ||||
|         resp_parsed = json.loads(resp.body) | ||||
|         self.assertEqual(resp_parsed['data'], 'foo') | ||||
|  | ||||
|     def test_proxy(self): | ||||
|         proxy = direct.Proxy(self.router) | ||||
|         rv = proxy.fake.echo(self.context, data='baz') | ||||
|         self.assertEqual(rv['data'], 'baz') | ||||
|  | ||||
|  | ||||
| class DirectCloudTestCase(test_cloud.CloudTestCase): | ||||
|     def setUp(self): | ||||
|         super(DirectCloudTestCase, self).setUp() | ||||
|         compute_handle = compute.API(image_service=self.cloud.image_service, | ||||
|                                      network_api=self.cloud.network_api, | ||||
|                                      volume_api=self.cloud.volume_api) | ||||
|         direct.register_service('compute', compute_handle) | ||||
|         self.router = direct.JsonParamsMiddleware(direct.Router()) | ||||
|         proxy = direct.Proxy(self.router) | ||||
|         self.cloud.compute_api = proxy.compute | ||||
|  | ||||
|     def tearDown(self): | ||||
|         super(DirectCloudTestCase, self).tearDown() | ||||
|         direct.ROUTES = {} | ||||
| @@ -9,7 +9,7 @@ def _fake_context(): | ||||
|     return context.RequestContext(1, 1) | ||||
|  | ||||
|  | ||||
| class RootLoggerTestCase(test.TrialTestCase): | ||||
| class RootLoggerTestCase(test.TestCase): | ||||
|     def setUp(self): | ||||
|         super(RootLoggerTestCase, self).setUp() | ||||
|         self.log = log.logging.root | ||||
| @@ -46,7 +46,7 @@ class RootLoggerTestCase(test.TrialTestCase): | ||||
|         self.assert_(True)  # didn't raise exception | ||||
|  | ||||
|  | ||||
| class NovaFormatterTestCase(test.TrialTestCase): | ||||
| class NovaFormatterTestCase(test.TestCase): | ||||
|     def setUp(self): | ||||
|         super(NovaFormatterTestCase, self).setUp() | ||||
|         self.flags(logging_context_format_string="HAS CONTEXT "\ | ||||
| @@ -78,7 +78,7 @@ class NovaFormatterTestCase(test.TrialTestCase): | ||||
|         self.assertEqual("NOCTXT: baz --DBG\n", self.stream.getvalue()) | ||||
|  | ||||
|  | ||||
| class NovaLoggerTestCase(test.TrialTestCase): | ||||
| class NovaLoggerTestCase(test.TestCase): | ||||
|     def setUp(self): | ||||
|         super(NovaLoggerTestCase, self).setUp() | ||||
|         self.flags(default_log_levels=["nova-test=AUDIT"], verbose=False) | ||||
| @@ -96,7 +96,7 @@ class NovaLoggerTestCase(test.TrialTestCase): | ||||
|         self.assertEqual(log.AUDIT, l.level) | ||||
|  | ||||
|  | ||||
| class VerboseLoggerTestCase(test.TrialTestCase): | ||||
| class VerboseLoggerTestCase(test.TestCase): | ||||
|     def setUp(self): | ||||
|         super(VerboseLoggerTestCase, self).setUp() | ||||
|         self.flags(default_log_levels=["nova.test=AUDIT"], verbose=True) | ||||
|   | ||||
| @@ -38,7 +38,7 @@ def conditional_forbid(req): | ||||
|     return 'OK' | ||||
|  | ||||
|  | ||||
| class LockoutTestCase(test.TrialTestCase): | ||||
| class LockoutTestCase(test.TestCase): | ||||
|     """Test case for the Lockout middleware.""" | ||||
|     def setUp(self):  # pylint: disable-msg=C0103 | ||||
|         super(LockoutTestCase, self).setUp() | ||||
|   | ||||
| @@ -96,6 +96,28 @@ class NetworkTestCase(test.TestCase): | ||||
|         self.context.project_id = self.projects[project_num].id | ||||
|         self.network.deallocate_fixed_ip(self.context, address) | ||||
|  | ||||
|     def test_private_ipv6(self): | ||||
|         """Make sure ipv6 is OK""" | ||||
|         if FLAGS.use_ipv6: | ||||
|             instance_ref = self._create_instance(0) | ||||
|             address = self._create_address(0, instance_ref['id']) | ||||
|             network_ref = db.project_get_network( | ||||
|                                                  context.get_admin_context(), | ||||
|                                                  self.context.project_id) | ||||
|             address_v6 = db.instance_get_fixed_address_v6( | ||||
|                                                  context.get_admin_context(), | ||||
|                                                  instance_ref['id']) | ||||
|             self.assertEqual(instance_ref['mac_address'], | ||||
|                              utils.to_mac(address_v6)) | ||||
|             instance_ref2 = db.fixed_ip_get_instance_v6( | ||||
|                                                  context.get_admin_context(), | ||||
|                                                  address_v6) | ||||
|             self.assertEqual(instance_ref['id'], instance_ref2['id']) | ||||
|             self.assertEqual(address_v6, | ||||
|                              utils.to_global_ipv6( | ||||
|                                                  network_ref['cidr_v6'], | ||||
|                                                  instance_ref['mac_address'])) | ||||
|  | ||||
|     def test_public_network_association(self): | ||||
|         """Makes sure that we can allocaate a public ip""" | ||||
|         # TODO(vish): better way of adding floating ips | ||||
|   | ||||
| @@ -28,7 +28,7 @@ from nova import test | ||||
| FLAGS = flags.FLAGS | ||||
|  | ||||
|  | ||||
| class TwistdTestCase(test.TrialTestCase): | ||||
| class TwistdTestCase(test.TestCase): | ||||
|     def setUp(self): | ||||
|         super(TwistdTestCase, self).setUp() | ||||
|         self.Options = twistd.WrapTwistedOptions(twistd.TwistdServerOptions) | ||||
|   | ||||
| @@ -31,6 +31,7 @@ from nova.compute import power_state | ||||
| from nova.virt import xenapi_conn | ||||
| from nova.virt.xenapi import fake as xenapi_fake | ||||
| from nova.virt.xenapi import volume_utils | ||||
| from nova.virt.xenapi.vmops import SimpleDH | ||||
| from nova.tests.db import fakes as db_fakes | ||||
| from nova.tests.xenapi import stubs | ||||
|  | ||||
| @@ -262,3 +263,29 @@ class XenAPIVMTestCase(test.TestCase): | ||||
|         instance = db.instance_create(values) | ||||
|         self.conn.spawn(instance) | ||||
|         return instance | ||||
|  | ||||
|  | ||||
| class XenAPIDiffieHellmanTestCase(test.TestCase): | ||||
|     """ | ||||
|     Unit tests for Diffie-Hellman code | ||||
|     """ | ||||
|     def setUp(self): | ||||
|         super(XenAPIDiffieHellmanTestCase, self).setUp() | ||||
|         self.alice = SimpleDH() | ||||
|         self.bob = SimpleDH() | ||||
|  | ||||
|     def test_shared(self): | ||||
|         alice_pub = self.alice.get_public() | ||||
|         bob_pub = self.bob.get_public() | ||||
|         alice_shared = self.alice.compute_shared(bob_pub) | ||||
|         bob_shared = self.bob.compute_shared(alice_pub) | ||||
|         self.assertEquals(alice_shared, bob_shared) | ||||
|  | ||||
|     def test_encryption(self): | ||||
|         msg = "This is a top-secret message" | ||||
|         enc = self.alice.encrypt(msg) | ||||
|         dec = self.bob.decrypt(enc) | ||||
|         self.assertEquals(dec, msg) | ||||
|  | ||||
|     def tearDown(self): | ||||
|         super(XenAPIDiffieHellmanTestCase, self).tearDown() | ||||
|   | ||||
| @@ -22,6 +22,7 @@ System-level utilities and helper functions. | ||||
|  | ||||
| import datetime | ||||
| import inspect | ||||
| import json | ||||
| import os | ||||
| import random | ||||
| import subprocess | ||||
| @@ -30,6 +31,8 @@ import struct | ||||
| import sys | ||||
| import time | ||||
| from xml.sax import saxutils | ||||
| import re | ||||
| import netaddr | ||||
|  | ||||
| from eventlet import event | ||||
| from eventlet import greenthread | ||||
| @@ -200,6 +203,40 @@ def last_octet(address): | ||||
|     return int(address.split(".")[-1]) | ||||
|  | ||||
|  | ||||
| def  get_my_linklocal(interface): | ||||
|     try: | ||||
|         if_str = execute("ip -f inet6 -o addr show %s" % interface) | ||||
|         condition = "\s+inet6\s+([0-9a-f:]+/\d+)\s+scope\s+link" | ||||
|         links = [re.search(condition, x) for x in if_str[0].split('\n')] | ||||
|         address = [w.group(1) for w in links if w is not None] | ||||
|         if address[0] is not None: | ||||
|             return address[0] | ||||
|         else: | ||||
|             return 'fe00::' | ||||
|     except IndexError as ex: | ||||
|         LOG.warn(_("Couldn't get Link Local IP of %s :%s"), interface, ex) | ||||
|     except ProcessExecutionError as ex: | ||||
|         LOG.warn(_("Couldn't get Link Local IP of %s :%s"), interface, ex) | ||||
|     except: | ||||
|         return 'fe00::' | ||||
|  | ||||
|  | ||||
| def to_global_ipv6(prefix, mac): | ||||
|     mac64 = netaddr.EUI(mac).eui64().words | ||||
|     int_addr = int(''.join(['%02x' % i for i in mac64]), 16) | ||||
|     mac64_addr = netaddr.IPAddress(int_addr) | ||||
|     maskIP = netaddr.IPNetwork(prefix).ip | ||||
|     return (mac64_addr ^ netaddr.IPAddress('::0200:0:0:0') | maskIP).format() | ||||
|  | ||||
|  | ||||
| def to_mac(ipv6_address): | ||||
|     address = netaddr.IPAddress(ipv6_address) | ||||
|     mask1 = netaddr.IPAddress("::ffff:ffff:ffff:ffff") | ||||
|     mask2 = netaddr.IPAddress("::0200:0:0:0") | ||||
|     mac64 = netaddr.EUI(int(address & mask1 ^ mask2)).words | ||||
|     return ":".join(["%02x" % i for i in mac64[0:3] + mac64[5:8]]) | ||||
|  | ||||
|  | ||||
| def utcnow(): | ||||
|     """Overridable version of datetime.datetime.utcnow.""" | ||||
|     if utcnow.override_time: | ||||
| @@ -355,3 +392,36 @@ def utf8(value): | ||||
|         return value.encode("utf-8") | ||||
|     assert isinstance(value, str) | ||||
|     return value | ||||
|  | ||||
|  | ||||
| def to_primitive(value): | ||||
|     if type(value) is type([]) or type(value) is type((None,)): | ||||
|         o = [] | ||||
|         for v in value: | ||||
|             o.append(to_primitive(v)) | ||||
|         return o | ||||
|     elif type(value) is type({}): | ||||
|         o = {} | ||||
|         for k, v in value.iteritems(): | ||||
|             o[k] = to_primitive(v) | ||||
|         return o | ||||
|     elif isinstance(value, datetime.datetime): | ||||
|         return str(value) | ||||
|     elif hasattr(value, 'iteritems'): | ||||
|         return to_primitive(dict(value.iteritems())) | ||||
|     elif hasattr(value, '__iter__'): | ||||
|         return to_primitive(list(value)) | ||||
|     else: | ||||
|         return value | ||||
|  | ||||
|  | ||||
| def dumps(value): | ||||
|     try: | ||||
|         return json.dumps(value) | ||||
|     except TypeError: | ||||
|         pass | ||||
|     return json.dumps(to_primitive(value)) | ||||
|  | ||||
|  | ||||
| def loads(s): | ||||
|     return json.loads(s) | ||||
|   | ||||
							
								
								
									
										36
									
								
								nova/wsgi.py
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								nova/wsgi.py
									
									
									
									
									
								
							| @@ -21,7 +21,6 @@ | ||||
| Utility methods for working with WSGI servers | ||||
| """ | ||||
|  | ||||
| import json | ||||
| import sys | ||||
| from xml.dom import minidom | ||||
|  | ||||
| @@ -35,6 +34,7 @@ import webob.dec | ||||
| import webob.exc | ||||
|  | ||||
| from nova import log as logging | ||||
| from nova import utils | ||||
|  | ||||
|  | ||||
| class WritableLogger(object): | ||||
| @@ -117,20 +117,38 @@ class Application(object): | ||||
|  | ||||
|  | ||||
| class Middleware(Application): | ||||
|     """ | ||||
|     Base WSGI middleware wrapper. These classes require an application to be | ||||
|     """Base WSGI middleware. | ||||
|  | ||||
|     These classes require an application to be | ||||
|     initialized that will be called next.  By default the middleware will | ||||
|     simply call its wrapped app, or you can override __call__ to customize its | ||||
|     behavior. | ||||
|     """ | ||||
|  | ||||
|     def __init__(self, application):  # pylint: disable-msg=W0231 | ||||
|     def __init__(self, application): | ||||
|         self.application = application | ||||
|  | ||||
|     def process_request(self, req): | ||||
|         """Called on each request. | ||||
|  | ||||
|         If this returns None, the next application down the stack will be | ||||
|         executed. If it returns a response then that response will be returned | ||||
|         and execution will stop here. | ||||
|  | ||||
|         """ | ||||
|         return None | ||||
|  | ||||
|     def process_response(self, response): | ||||
|         """Do whatever you'd like to the response.""" | ||||
|         return response | ||||
|  | ||||
|     @webob.dec.wsgify | ||||
|     def __call__(self, req):  # pylint: disable-msg=W0221 | ||||
|         """Override to implement middleware behavior.""" | ||||
|         return self.application | ||||
|     def __call__(self, req): | ||||
|         response = self.process_request(req) | ||||
|         if response: | ||||
|             return response | ||||
|         response = req.get_response(self.application) | ||||
|         return self.process_response(response) | ||||
|  | ||||
|  | ||||
| class Debug(Middleware): | ||||
| @@ -316,7 +334,7 @@ class Serializer(object): | ||||
|         try: | ||||
|             is_xml = (datastring[0] == '<') | ||||
|             if not is_xml: | ||||
|                 return json.loads(datastring) | ||||
|                 return utils.loads(datastring) | ||||
|             return self._from_xml(datastring) | ||||
|         except: | ||||
|             return None | ||||
| @@ -349,7 +367,7 @@ class Serializer(object): | ||||
|             return result | ||||
|  | ||||
|     def _to_json(self, data): | ||||
|         return json.dumps(data) | ||||
|         return utils.dumps(data) | ||||
|  | ||||
|     def _to_xml(self, data): | ||||
|         metadata = self.metadata.get('application/xml', {}) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Kei Masumoto
					Kei Masumoto