merged trunk

This commit is contained in:
Vishvananda Ishaya
2010-08-06 14:27:48 -07:00
8 changed files with 47 additions and 39 deletions

View File

@@ -21,8 +21,6 @@
Twisted daemon for nova objectstore. Supports S3 API. Twisted daemon for nova objectstore. Supports S3 API.
""" """
import logging
from nova import flags from nova import flags
from nova import utils from nova import utils
from nova import twistd from nova import twistd
@@ -33,9 +31,6 @@ FLAGS = flags.FLAGS
def main(): def main():
# FIXME: if this log statement isn't here, no logging
# appears from other files and app won't start daemonized
logging.debug('Started HTTP server on %s' % (FLAGS.s3_port))
app = handler.get_application() app = handler.get_application()
print app print app
return app return app

View File

@@ -292,9 +292,13 @@ class NovaAdminClient(object):
'Operation': operation} 'Operation': operation}
return self.apiconn.get_status('ModifyProjectMember', params) return self.apiconn.get_status('ModifyProjectMember', params)
def get_zip(self, username): def get_zip(self, user, project):
""" returns the content of a zip file containing novarc and access credentials. """ """
return self.apiconn.get_object('GenerateX509ForUser', {'Name': username}, UserInfo).file Returns the content of a zip file containing novarc and access credentials.
"""
params = {'Name': user, 'Project': project}
zip = self.apiconn.get_object('GenerateX509ForUser', params, UserInfo)
return zip.file
def get_hosts(self): def get_hosts(self):
return self.apiconn.get_list('DescribeHosts', {}, [('item', HostInfo)]) return self.apiconn.get_list('DescribeHosts', {}, [('item', HostInfo)])

View File

@@ -24,7 +24,6 @@ import logging
import os import os
import shutil import shutil
import string import string
import sys
import tempfile import tempfile
import uuid import uuid
import zipfile import zipfile
@@ -239,8 +238,7 @@ class AuthManager(object):
def __new__(cls, *args, **kwargs): def __new__(cls, *args, **kwargs):
"""Returns the AuthManager singleton""" """Returns the AuthManager singleton"""
if not cls._instance: if not cls._instance:
cls._instance = super(AuthManager, cls).__new__( cls._instance = super(AuthManager, cls).__new__(cls)
cls, *args, **kwargs)
return cls._instance return cls._instance
def __init__(self, driver=None, *args, **kwargs): def __init__(self, driver=None, *args, **kwargs):
@@ -333,6 +331,12 @@ class AuthManager(object):
raise exception.NotAuthorized('Signature does not match') raise exception.NotAuthorized('Signature does not match')
return (user, project) return (user, project)
def get_access_key(self, user, project):
"""Get an access key that includes user and project"""
if not isinstance(user, User):
user = self.get_user(user)
return "%s:%s" % (user.access, Project.safe_id(project))
def is_superuser(self, user): def is_superuser(self, user):
"""Checks for superuser status, allowing user to bypass rbac """Checks for superuser status, allowing user to bypass rbac

View File

@@ -48,7 +48,8 @@ import hashlib
import hmac import hmac
import logging import logging
import urllib import urllib
import boto.utils import boto # NOTE(vish): for new boto
import boto.utils # NOTE(vish): for old boto
from nova.exception import Error from nova.exception import Error

View File

@@ -294,17 +294,16 @@ class CloudController(object):
return v return v
@rbac.allow('projectmanager', 'sysadmin') @rbac.allow('projectmanager', 'sysadmin')
@defer.inlineCallbacks
def create_volume(self, context, size, **kwargs): def create_volume(self, context, size, **kwargs):
# TODO(vish): refactor this to create the volume object here and tell service to create it # TODO(vish): refactor this to create the volume object here and tell service to create it
res = rpc.call(FLAGS.volume_topic, {"method": "create_volume", result = yield rpc.call(FLAGS.volume_topic, {"method": "create_volume",
"args" : {"size": size, "args" : {"size": size,
"user_id": context.user.id, "user_id": context.user.id,
"project_id": context.project.id}}) "project_id": context.project.id}})
def _format_result(result): # NOTE(vish): rpc returned value is in the result key in the dictionary
volume = self._get_volume(context, result['result']) volume = self._get_volume(context, result['result'])
return {'volumeSet': [self.format_volume(context, volume)]} defer.returnValue({'volumeSet': [self.format_volume(context, volume)]})
res.addCallback(_format_result)
return res
def _get_address(self, context, public_ip): def _get_address(self, context, public_ip):
# FIXME(vish) this should move into network.py # FIXME(vish) this should move into network.py

View File

@@ -21,14 +21,13 @@ Proxy AMI-related calls from the cloud controller, to the running
objectstore daemon. objectstore daemon.
""" """
import boto import boto.s3.connection
import boto.s3
import json import json
import random
import urllib import urllib
from nova import flags from nova import flags
from nova import utils from nova import utils
from nova.auth import manager
FLAGS = flags.FLAGS FLAGS = flags.FLAGS
@@ -77,11 +76,14 @@ def deregister(context, image_id):
query_args=qs({'image_id': image_id})) query_args=qs({'image_id': image_id}))
def conn(context): def conn(context):
return boto.s3.connection.S3Connection ( access = manager.AuthManager().get_access_key(context.user,
aws_access_key_id=str('%s:%s' % (context.user.access, context.project.name)), context.project)
aws_secret_access_key=str(context.user.secret), secret = str(context.user.secret)
calling = boto.s3.connection.OrdinaryCallingFormat()
return boto.s3.connection.S3Connection(aws_access_key_id=access,
aws_secret_access_key=secret,
is_secure=False, is_secure=False,
calling_format=boto.s3.connection.OrdinaryCallingFormat(), calling_format=calling,
port=FLAGS.s3_port, port=FLAGS.s3_port,
host=FLAGS.s3_host) host=FLAGS.s3_host)

View File

@@ -42,15 +42,14 @@ class VolumeTestCase(test.TrialTestCase):
vol_size = '0' vol_size = '0'
user_id = 'fake' user_id = 'fake'
project_id = 'fake' project_id = 'fake'
volume_id = self.volume.create_volume(vol_size, user_id, project_id) volume_id = yield self.volume.create_volume(vol_size, user_id, project_id)
# TODO(termie): get_volume returns differently than create_volume # TODO(termie): get_volume returns differently than create_volume
self.assertEqual(volume_id, self.assertEqual(volume_id,
volume_service.get_volume(volume_id)['volume_id']) volume_service.get_volume(volume_id)['volume_id'])
rv = self.volume.delete_volume(volume_id) rv = self.volume.delete_volume(volume_id)
self.assertRaises(exception.Error, self.assertFailure(volume_service.get_volume(volume_id),
volume_service.get_volume, exception.Error)
volume_id)
def test_too_big_volume(self): def test_too_big_volume(self):
vol_size = '1001' vol_size = '1001'
@@ -68,13 +67,14 @@ class VolumeTestCase(test.TrialTestCase):
total_slots = FLAGS.slots_per_shelf * num_shelves total_slots = FLAGS.slots_per_shelf * num_shelves
vols = [] vols = []
for i in xrange(total_slots): for i in xrange(total_slots):
vid = self.volume.create_volume(vol_size, user_id, project_id) vid = yield self.volume.create_volume(vol_size, user_id, project_id)
vols.append(vid) vols.append(vid)
self.assertRaises(volume_service.NoMoreVolumes, self.assertFailure(self.volume.create_volume(vol_size,
self.volume.create_volume, user_id,
vol_size, user_id, project_id) project_id),
volume_service.NoMoreVolumes)
for id in vols: for id in vols:
self.volume.delete_volume(id) yield self.volume.delete_volume(id)
def test_run_attach_detach_volume(self): def test_run_attach_detach_volume(self):
# Create one volume and one compute to test with # Create one volume and one compute to test with
@@ -83,7 +83,7 @@ class VolumeTestCase(test.TrialTestCase):
user_id = "fake" user_id = "fake"
project_id = 'fake' project_id = 'fake'
mountpoint = "/dev/sdf" mountpoint = "/dev/sdf"
volume_id = self.volume.create_volume(vol_size, user_id, project_id) volume_id = yield self.volume.create_volume(vol_size, user_id, project_id)
volume_obj = volume_service.get_volume(volume_id) volume_obj = volume_service.get_volume(volume_id)
volume_obj.start_attach(instance_id, mountpoint) volume_obj.start_attach(instance_id, mountpoint)

View File

@@ -214,6 +214,9 @@ def serve(filename):
FLAGS.pidfile = '%s.pid' % name FLAGS.pidfile = '%s.pid' % name
elif FLAGS.pidfile.endswith('twistd.pid'): elif FLAGS.pidfile.endswith('twistd.pid'):
FLAGS.pidfile = FLAGS.pidfile.replace('twistd.pid', '%s.pid' % name) FLAGS.pidfile = FLAGS.pidfile.replace('twistd.pid', '%s.pid' % name)
# NOTE(vish): if we're running nodaemon, redirect the log to stdout
if FLAGS.nodaemon and not FLAGS.logfile:
FLAGS.logfile = "-"
if not FLAGS.logfile: if not FLAGS.logfile:
FLAGS.logfile = '%s.log' % name FLAGS.logfile = '%s.log' % name
elif FLAGS.logfile.endswith('twistd.log'): elif FLAGS.logfile.endswith('twistd.log'):