summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRick Harris <rick.harris@rackspace.com>2011-03-16 18:56:52 +0000
committerRick Harris <rick.harris@rackspace.com>2011-03-16 18:56:52 +0000
commit3f637a9325ffa7b0cc8a2369576b9fc4f2ebf0f5 (patch)
tree24bf410e8c0cdfcc840863a90f433777f9c137a6
parent5ca10673e77763706e7b26e30f0212930ad1f929 (diff)
parentdfd0e8a32ae40043a78c12fb871c11bb9bd0f4c3 (diff)
downloadnova-3f637a9325ffa7b0cc8a2369576b9fc4f2ebf0f5.tar.gz
nova-3f637a9325ffa7b0cc8a2369576b9fc4f2ebf0f5.tar.xz
nova-3f637a9325ffa7b0cc8a2369576b9fc4f2ebf0f5.zip
Merging trunk
-rw-r--r--.mailmap1
-rw-r--r--Authors1
-rwxr-xr-xbin/nova-manage67
-rw-r--r--nova/api/openstack/auth.py6
-rw-r--r--nova/console/manager.py2
-rw-r--r--nova/console/xvp.py4
-rw-r--r--nova/db/api.py5
-rw-r--r--nova/db/sqlalchemy/api.py16
-rw-r--r--nova/tests/api/openstack/fakes.py5
-rw-r--r--nova/tests/api/openstack/test_auth.py56
-rw-r--r--nova/tests/db/fakes.py4
-rw-r--r--nova/tests/test_compute.py20
-rw-r--r--nova/tests/test_misc.py12
-rw-r--r--nova/tests/test_xenapi.py11
-rw-r--r--nova/utils.py24
-rw-r--r--nova/virt/libvirt_conn.py2
-rw-r--r--nova/virt/xenapi/vm_utils.py3
17 files changed, 159 insertions, 80 deletions
diff --git a/.mailmap b/.mailmap
index ed4404ad5..ccf2109a7 100644
--- a/.mailmap
+++ b/.mailmap
@@ -28,6 +28,7 @@
<matt.dietz@rackspace.com> <matthewdietz@Matthew-Dietzs-MacBook-Pro.local>
<matt.dietz@rackspace.com> <mdietz@openstack>
<mordred@inaugust.com> <mordred@hudson>
+<nirmal.ranganathan@rackspace.com> <nirmal.ranganathan@rackspace.coom>
<paul@openstack.org> <paul.voccio@rackspace.com>
<paul@openstack.org> <pvoccio@castor.local>
<rconradharris@gmail.com> <rick.harris@rackspace.com>
diff --git a/Authors b/Authors
index 7993955e2..4ee0643cf 100644
--- a/Authors
+++ b/Authors
@@ -19,6 +19,7 @@ Devin Carlen <devin.carlen@gmail.com>
Ed Leafe <ed@leafe.com>
Eldar Nugaev <enugaev@griddynamics.com>
Eric Day <eday@oddments.org>
+Eric Windisch <eric@cloudscaling.com>
Ewan Mellor <ewan.mellor@citrix.com>
Hisaharu Ishii <ishii.hisaharu@lab.ntt.co.jp>
Hisaki Ohara <hisaki.ohara@intel.com>
diff --git a/bin/nova-manage b/bin/nova-manage
index 1eb4e5418..a4d820209 100755
--- a/bin/nova-manage
+++ b/bin/nova-manage
@@ -446,10 +446,15 @@ class FixedIpCommands(object):
def list(self, host=None):
"""Lists all fixed ips (optionally by host) arguments: [host]"""
ctxt = context.get_admin_context()
- if host == None:
- fixed_ips = db.fixed_ip_get_all(ctxt)
- else:
- fixed_ips = db.fixed_ip_get_all_by_host(ctxt, host)
+
+ try:
+ if host == None:
+ fixed_ips = db.fixed_ip_get_all(ctxt)
+ else:
+ fixed_ips = db.fixed_ip_get_all_by_host(ctxt, host)
+ except exception.NotFound as ex:
+ print "error: %s" % ex
+ sys.exit(2)
print "%-18s\t%-15s\t%-17s\t%-15s\t%s" % (_('network'),
_('IP address'),
@@ -466,9 +471,9 @@ class FixedIpCommands(object):
host = instance['host']
mac_address = instance['mac_address']
print "%-18s\t%-15s\t%-17s\t%-15s\t%s" % (
- fixed_ip['network']['cidr'],
- fixed_ip['address'],
- mac_address, hostname, host)
+ fixed_ip['network']['cidr'],
+ fixed_ip['address'],
+ mac_address, hostname, host)
class FloatingIpCommands(object):
@@ -572,7 +577,7 @@ class VmCommands(object):
"""
ctxt = context.get_admin_context()
- instance_id = ec2_id_to_id(ec2_id)
+ instance_id = ec2utils.ec2_id_to_id(ec2_id)
if FLAGS.connection_type != 'libvirt':
msg = _('Only KVM is supported for now. Sorry!')
@@ -716,6 +721,49 @@ class DbCommands(object):
print migration.db_version()
+class InstanceCommands(object):
+ """Class for managing instances."""
+
+ def list(self, host=None, instance=None):
+ """Show a list of all instances"""
+ print "%-10s %-15s %-10s %-10s %-19s %-12s %-12s %-12s" \
+ " %-10s %-10s %-10s %-5s" % (
+ _('instance'),
+ _('node'),
+ _('type'),
+ _('state'),
+ _('launched'),
+ _('image'),
+ _('kernel'),
+ _('ramdisk'),
+ _('project'),
+ _('user'),
+ _('zone'),
+ _('index'))
+
+ if host == None:
+ instances = db.instance_get_all(context.get_admin_context())
+ else:
+ instances = db.instance_get_all_by_host(
+ context.get_admin_context(), host)
+
+ for instance in instances:
+ print "%-10s %-15s %-10s %-10s %-19s %-12s %-12s %-12s" \
+ " %-10s %-10s %-10s %-5d" % (
+ instance['hostname'],
+ instance['host'],
+ instance['instance_type'],
+ instance['state_description'],
+ instance['launched_at'],
+ instance['image_id'],
+ instance['kernel_id'],
+ instance['ramdisk_id'],
+ instance['project_id'],
+ instance['user_id'],
+ instance['availability_zone'],
+ instance['launch_index'])
+
+
class VolumeCommands(object):
"""Methods for dealing with a cloud in an odd state"""
@@ -1002,7 +1050,8 @@ CATEGORIES = [
('volume', VolumeCommands),
('instance_type', InstanceTypeCommands),
('image', ImageCommands),
- ('flavor', InstanceTypeCommands)]
+ ('flavor', InstanceTypeCommands),
+ ('instance', InstanceCommands)]
def lazy_match(name, key_value_tuples):
diff --git a/nova/api/openstack/auth.py b/nova/api/openstack/auth.py
index 4c6b58eff..f3a9bdeca 100644
--- a/nova/api/openstack/auth.py
+++ b/nova/api/openstack/auth.py
@@ -135,7 +135,11 @@ class AuthMiddleware(wsgi.Middleware):
req - wsgi.Request object
"""
ctxt = context.get_admin_context()
- user = self.auth.get_user_from_access_key(key)
+
+ try:
+ user = self.auth.get_user_from_access_key(key)
+ except exception.NotFound:
+ user = None
if user and user.name == username:
token_hash = hashlib.sha1('%s%s%f' % (username, key,
diff --git a/nova/console/manager.py b/nova/console/manager.py
index 57c75cf4f..bfa571ea9 100644
--- a/nova/console/manager.py
+++ b/nova/console/manager.py
@@ -69,7 +69,7 @@ class ConsoleProxyManager(manager.Manager):
except exception.NotFound:
logging.debug(_("Adding console"))
if not password:
- password = self.driver.generate_password()
+ password = utils.generate_password(8)
if not port:
port = self.driver.get_port(context)
console_data = {'instance_name': name,
diff --git a/nova/console/xvp.py b/nova/console/xvp.py
index 68d8c8565..0cedfbb13 100644
--- a/nova/console/xvp.py
+++ b/nova/console/xvp.py
@@ -91,10 +91,6 @@ class XVPConsoleProxy(object):
"""Trim password to length, and encode"""
return self._xvp_encrypt(password)
- def generate_password(self, length=8):
- """Returns random console password"""
- return os.urandom(length * 2).encode('base64')[:length]
-
def _rebuild_xvp_conf(self, context):
logging.debug(_("Rebuilding xvp conf"))
pools = [pool for pool in
diff --git a/nova/db/api.py b/nova/db/api.py
index 0aa846d61..3cb0e5811 100644
--- a/nova/db/api.py
+++ b/nova/db/api.py
@@ -353,6 +353,11 @@ def fixed_ip_get_all(context):
return IMPL.fixed_ip_get_all(context)
+def fixed_ip_get_all_by_host(context, host):
+ """Get all defined fixed ips used by a host."""
+ return IMPL.fixed_ip_get_all_by_host(context, host)
+
+
def fixed_ip_get_by_address(context, address):
"""Get a fixed ip by address or raise if it does not exist."""
return IMPL.fixed_ip_get_by_address(context, address)
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 56998ce05..44540617f 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -672,6 +672,22 @@ def fixed_ip_get_all(context, session=None):
return result
+@require_admin_context
+def fixed_ip_get_all_by_host(context, host=None):
+ session = get_session()
+
+ result = session.query(models.FixedIp).\
+ join(models.FixedIp.instance).\
+ filter_by(state=1).\
+ filter_by(host=host).\
+ all()
+
+ if not result:
+ raise exception.NotFound(_('No fixed ips for this host defined'))
+
+ return result
+
+
@require_context
def fixed_ip_get_by_address(context, address, session=None):
if not session:
diff --git a/nova/tests/api/openstack/fakes.py b/nova/tests/api/openstack/fakes.py
index ef38b93ca..7f65751a6 100644
--- a/nova/tests/api/openstack/fakes.py
+++ b/nova/tests/api/openstack/fakes.py
@@ -341,7 +341,10 @@ class FakeAuthManager(object):
(user.id == p.project_manager_id)]
def get_user_from_access_key(self, key):
- return FakeAuthManager.auth_data.get(key, None)
+ try:
+ return FakeAuthManager.auth_data[key]
+ except KeyError:
+ raise exc.NotFound
class FakeRateLimiter(object):
diff --git a/nova/tests/api/openstack/test_auth.py b/nova/tests/api/openstack/test_auth.py
index aaaa4e415..0448ed701 100644
--- a/nova/tests/api/openstack/test_auth.py
+++ b/nova/tests/api/openstack/test_auth.py
@@ -51,11 +51,12 @@ class Test(test.TestCase):
def test_authorize_user(self):
f = fakes.FakeAuthManager()
- f.add_user('derp', nova.auth.manager.User(1, 'herp', None, None, None))
+ f.add_user('user1_key',
+ nova.auth.manager.User(1, 'user1', None, None, None))
req = webob.Request.blank('/v1.0/')
- req.headers['X-Auth-User'] = 'herp'
- req.headers['X-Auth-Key'] = 'derp'
+ req.headers['X-Auth-User'] = 'user1'
+ req.headers['X-Auth-Key'] = 'user1_key'
result = req.get_response(fakes.wsgi_app())
self.assertEqual(result.status, '204 No Content')
self.assertEqual(len(result.headers['X-Auth-Token']), 40)
@@ -65,13 +66,13 @@ class Test(test.TestCase):
def test_authorize_token(self):
f = fakes.FakeAuthManager()
- u = nova.auth.manager.User(1, 'herp', None, None, None)
- f.add_user('derp', u)
- f.create_project('test', u)
+ u = nova.auth.manager.User(1, 'user1', None, None, None)
+ f.add_user('user1_key', u)
+ f.create_project('user1_project', u)
req = webob.Request.blank('/v1.0/', {'HTTP_HOST': 'foo'})
- req.headers['X-Auth-User'] = 'herp'
- req.headers['X-Auth-Key'] = 'derp'
+ req.headers['X-Auth-User'] = 'user1'
+ req.headers['X-Auth-Key'] = 'user1_key'
result = req.get_response(fakes.wsgi_app())
self.assertEqual(result.status, '204 No Content')
self.assertEqual(len(result.headers['X-Auth-Token']), 40)
@@ -92,7 +93,7 @@ class Test(test.TestCase):
def test_token_expiry(self):
self.destroy_called = False
- token_hash = 'bacon'
+ token_hash = 'token_hash'
def destroy_token_mock(meh, context, token):
self.destroy_called = True
@@ -109,15 +110,26 @@ class Test(test.TestCase):
bad_token)
req = webob.Request.blank('/v1.0/')
- req.headers['X-Auth-Token'] = 'bacon'
+ req.headers['X-Auth-Token'] = 'token_hash'
result = req.get_response(fakes.wsgi_app())
self.assertEqual(result.status, '401 Unauthorized')
self.assertEqual(self.destroy_called, True)
- def test_bad_user(self):
+ def test_bad_user_bad_key(self):
+ req = webob.Request.blank('/v1.0/')
+ req.headers['X-Auth-User'] = 'unknown_user'
+ req.headers['X-Auth-Key'] = 'unknown_user_key'
+ result = req.get_response(fakes.wsgi_app())
+ self.assertEqual(result.status, '401 Unauthorized')
+
+ def test_bad_user_good_key(self):
+ f = fakes.FakeAuthManager()
+ u = nova.auth.manager.User(1, 'user1', None, None, None)
+ f.add_user('user1_key', u)
+
req = webob.Request.blank('/v1.0/')
- req.headers['X-Auth-User'] = 'herp'
- req.headers['X-Auth-Key'] = 'derp'
+ req.headers['X-Auth-User'] = 'unknown_user'
+ req.headers['X-Auth-Key'] = 'user1_key'
result = req.get_response(fakes.wsgi_app())
self.assertEqual(result.status, '401 Unauthorized')
@@ -128,7 +140,7 @@ class Test(test.TestCase):
def test_bad_token(self):
req = webob.Request.blank('/v1.0/')
- req.headers['X-Auth-Token'] = 'baconbaconbacon'
+ req.headers['X-Auth-Token'] = 'unknown_token'
result = req.get_response(fakes.wsgi_app())
self.assertEqual(result.status, '401 Unauthorized')
@@ -137,11 +149,11 @@ class TestFunctional(test.TestCase):
def test_token_expiry(self):
ctx = context.get_admin_context()
tok = db.auth_token_create(ctx, dict(
- token_hash='bacon',
+ token_hash='test_token_hash',
cdn_management_url='',
server_management_url='',
storage_url='',
- user_id='ham',
+ user_id='user1',
))
db.auth_token_update(ctx, tok.token_hash, dict(
@@ -149,13 +161,13 @@ class TestFunctional(test.TestCase):
))
req = webob.Request.blank('/v1.0/')
- req.headers['X-Auth-Token'] = 'bacon'
+ req.headers['X-Auth-Token'] = 'test_token_hash'
result = req.get_response(fakes.wsgi_app())
self.assertEqual(result.status, '401 Unauthorized')
def test_token_doesnotexist(self):
req = webob.Request.blank('/v1.0/')
- req.headers['X-Auth-Token'] = 'ham'
+ req.headers['X-Auth-Token'] = 'nonexistant_token_hash'
result = req.get_response(fakes.wsgi_app())
self.assertEqual(result.status, '401 Unauthorized')
@@ -178,13 +190,13 @@ class TestLimiter(test.TestCase):
def test_authorize_token(self):
f = fakes.FakeAuthManager()
- u = nova.auth.manager.User(1, 'herp', None, None, None)
- f.add_user('derp', u)
+ u = nova.auth.manager.User(1, 'user1', None, None, None)
+ f.add_user('user1_key', u)
f.create_project('test', u)
req = webob.Request.blank('/v1.0/')
- req.headers['X-Auth-User'] = 'herp'
- req.headers['X-Auth-Key'] = 'derp'
+ req.headers['X-Auth-User'] = 'user1'
+ req.headers['X-Auth-Key'] = 'user1_key'
result = req.get_response(fakes.wsgi_app())
self.assertEqual(len(result.headers['X-Auth-Token']), 40)
diff --git a/nova/tests/db/fakes.py b/nova/tests/db/fakes.py
index 142f6b1c6..5e9a3aa3b 100644
--- a/nova/tests/db/fakes.py
+++ b/nova/tests/db/fakes.py
@@ -77,8 +77,8 @@ def stub_out_db_instance_api(stubs):
'mac_address': values['mac_address'],
'vcpus': type_data['vcpus'],
'local_gb': type_data['local_gb'],
- 'os_type': values['os_type']
- }
+ 'os_type': values['os_type']}
+
return FakeModel(base_options)
def fake_network_get_by_instance(context, instance_id):
diff --git a/nova/tests/test_compute.py b/nova/tests/test_compute.py
index e486050be..3651f4cef 100644
--- a/nova/tests/test_compute.py
+++ b/nova/tests/test_compute.py
@@ -118,26 +118,6 @@ class ComputeTestCase(test.TestCase):
def test_create_instance_associates_security_groups(self):
"""Make sure create associates security groups"""
group = self._create_group()
- instance_ref = models.Instance()
- instance_ref['id'] = 1
- instance_ref['volumes'] = [{'id': 1}, {'id': 2}]
- instance_ref['hostname'] = 'i-00000001'
- return instance_ref
-
- def test_create_instance_defaults_display_name(self):
- """Verify that an instance cannot be created without a display_name."""
- cases = [dict(), dict(display_name=None)]
- for instance in cases:
- ref = self.compute_api.create(self.context,
- FLAGS.default_instance_type, None, **instance)
- try:
- self.assertNotEqual(ref[0]['display_name'], None)
- finally:
- db.instance_destroy(self.context, ref[0]['id'])
-
- def test_create_instance_associates_security_groups(self):
- """Make sure create associates security groups"""
- group = self._create_group()
ref = self.compute_api.create(
self.context,
instance_type=FLAGS.default_instance_type,
diff --git a/nova/tests/test_misc.py b/nova/tests/test_misc.py
index a658e4978..1fbaf304f 100644
--- a/nova/tests/test_misc.py
+++ b/nova/tests/test_misc.py
@@ -24,18 +24,19 @@ from nova.utils import parse_mailmap, str_dict_replace, synchronized
class ProjectTestCase(test.TestCase):
def test_authors_up_to_date(self):
- if os.path.exists('.bzr'):
+ topdir = os.path.normpath(os.path.dirname(__file__) + '/../../')
+ if os.path.exists(os.path.join(topdir, '.bzr')):
contributors = set()
- mailmap = parse_mailmap('.mailmap')
+ mailmap = parse_mailmap(os.path.join(topdir, '.mailmap'))
import bzrlib.workingtree
- tree = bzrlib.workingtree.WorkingTree.open('.')
+ tree = bzrlib.workingtree.WorkingTree.open(topdir)
tree.lock_read()
try:
parents = tree.get_parent_ids()
g = tree.branch.repository.get_graph()
- for p in parents[1:]:
+ for p in parents:
rev_ids = [r for r, _ in g.iter_ancestry(parents)
if r != "null:"]
revs = tree.branch.repository.get_revisions(rev_ids)
@@ -44,7 +45,8 @@ class ProjectTestCase(test.TestCase):
email = author.split(' ')[-1]
contributors.add(str_dict_replace(email, mailmap))
- authors_file = open('Authors', 'r').read()
+ authors_file = open(os.path.join(topdir, 'Authors'),
+ 'r').read()
missing = set()
for contributor in contributors:
diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py
index cd125a301..8b0affd5c 100644
--- a/nova/tests/test_xenapi.py
+++ b/nova/tests/test_xenapi.py
@@ -78,8 +78,7 @@ class XenAPIVolumeTestCase(test.TestCase):
'ramdisk_id': 3,
'instance_type': 'm1.large',
'mac_address': 'aa:bb:cc:dd:ee:ff',
- 'os_type': 'linux'
- }
+ 'os_type': 'linux'}
def _create_volume(self, size='0'):
"""Create a volume object."""
@@ -315,8 +314,8 @@ class XenAPIVMTestCase(test.TestCase):
'ramdisk_id': ramdisk_id,
'instance_type': instance_type,
'mac_address': 'aa:bb:cc:dd:ee:ff',
- 'os_type': os_type
- }
+ 'os_type': os_type}
+
conn = xenapi_conn.get_connection(False)
instance = db.instance_create(values)
conn.spawn(instance)
@@ -440,8 +439,8 @@ class XenAPIMigrateInstance(test.TestCase):
'ramdisk_id': None,
'instance_type': 'm1.large',
'mac_address': 'aa:bb:cc:dd:ee:ff',
- 'os_type': 'linux'
- }
+ 'os_type': 'linux'}
+
stubs.stub_out_migration_methods(self.stubs)
glance_stubs.stubout_glance_client(self.stubs,
glance_stubs.FakeGlance)
diff --git a/nova/utils.py b/nova/utils.py
index 87e726394..199ee8701 100644
--- a/nova/utils.py
+++ b/nova/utils.py
@@ -262,13 +262,25 @@ def generate_mac():
return ':'.join(map(lambda x: "%02x" % x, mac))
-def generate_password(length=20):
- """Generate a random sequence of letters and digits
- to be used as a password. Note that this is not intended
- to represent the ultimate in security.
+# Default symbols to use for passwords. Avoids visually confusing characters.
+# ~6 bits per symbol
+DEFAULT_PASSWORD_SYMBOLS = ("23456789" # Removed: 0,1
+ "ABCDEFGHJKLMNPQRSTUVWXYZ" # Removed: I, O
+ "abcdefghijkmnopqrstuvwxyz") # Removed: l
+
+
+# ~5 bits per symbol
+EASIER_PASSWORD_SYMBOLS = ("23456789" # Removed: 0, 1
+ "ABCDEFGHJKLMNPQRSTUVWXYZ") # Removed: I, O
+
+
+def generate_password(length=20, symbols=DEFAULT_PASSWORD_SYMBOLS):
+ """Generate a random password from the supplied symbols.
+
+ Believed to be reasonably secure (with a reasonable password length!)
"""
- chrs = string.letters + string.digits
- return "".join([random.choice(chrs) for i in xrange(length)])
+ r = random.SystemRandom()
+ return "".join([r.choice(symbols) for _i in xrange(length)])
def last_octet(address):
diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py
index 7994e9547..d7bdc3faa 100644
--- a/nova/virt/libvirt_conn.py
+++ b/nova/virt/libvirt_conn.py
@@ -502,7 +502,7 @@ class LibvirtConnection(object):
cmd = 'netcat', '0.0.0.0', port, '-w', '1'
try:
stdout, stderr = utils.execute(*cmd, process_input='')
- except ProcessExecutionError:
+ except exception.ProcessExecutionError:
return port
raise Exception(_('Unable to find an open port'))
diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py
index f07b57796..763c5fe40 100644
--- a/nova/virt/xenapi/vm_utils.py
+++ b/nova/virt/xenapi/vm_utils.py
@@ -136,8 +136,7 @@ class VMHelper(HelperBase):
'VCPUs_at_startup': vcpus,
'VCPUs_max': vcpus,
'VCPUs_params': {},
- 'xenstore_data': {}
- }
+ 'xenstore_data': {}}
# Complete VM configuration record according to the image type
# non-raw/raw with PV kernel/raw in HVM mode