Merge from trunk
This commit is contained in:
commit
89dbaf4f26
|
@ -34,10 +34,12 @@ if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
|
|||
|
||||
from nova import service
|
||||
from nova import twistd
|
||||
from nova import utils
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
twistd.serve(__file__)
|
||||
|
||||
if __name__ == '__builtin__':
|
||||
utils.default_flagfile()
|
||||
application = service.Service.create() # pylint: disable=C0103
|
||||
|
|
|
@ -34,6 +34,7 @@ possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
|
|||
if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
|
||||
sys.path.insert(0, possible_topdir)
|
||||
|
||||
from nova import utils
|
||||
from nova import twistd
|
||||
from nova.compute import monitor
|
||||
|
||||
|
@ -44,6 +45,7 @@ if __name__ == '__main__':
|
|||
twistd.serve(__file__)
|
||||
|
||||
if __name__ == '__builtin__':
|
||||
utils.default_flagfile()
|
||||
logging.warn('Starting instance monitor')
|
||||
# pylint: disable-msg=C0103
|
||||
monitor = monitor.InstanceMonitor()
|
||||
|
|
|
@ -467,7 +467,7 @@ def methods_of(obj):
|
|||
|
||||
def main():
|
||||
"""Parse options and call the appropriate class/method."""
|
||||
utils.default_flagfile('/etc/nova/nova-manage.conf')
|
||||
utils.default_flagfile()
|
||||
argv = FLAGS(sys.argv)
|
||||
|
||||
if FLAGS.verbose:
|
||||
|
|
|
@ -34,10 +34,12 @@ if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
|
|||
|
||||
from nova import service
|
||||
from nova import twistd
|
||||
from nova import utils
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
twistd.serve(__file__)
|
||||
|
||||
if __name__ == '__builtin__':
|
||||
utils.default_flagfile()
|
||||
application = service.Service.create() # pylint: disable-msg=C0103
|
||||
|
|
|
@ -34,10 +34,12 @@ if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
|
|||
|
||||
from nova import service
|
||||
from nova import twistd
|
||||
from nova import utils
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
twistd.serve(__file__)
|
||||
|
||||
if __name__ == '__builtin__':
|
||||
utils.default_flagfile()
|
||||
application = service.Service.create()
|
||||
|
|
|
@ -34,10 +34,12 @@ if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
|
|||
|
||||
from nova import service
|
||||
from nova import twistd
|
||||
from nova import utils
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
twistd.serve(__file__)
|
||||
|
||||
if __name__ == '__builtin__':
|
||||
utils.default_flagfile()
|
||||
application = service.Service.create() # pylint: disable-msg=C0103
|
||||
|
|
|
@ -17,11 +17,17 @@ if [ ! -n "$HOST_IP" ]; then
|
|||
# you should explicitly set HOST_IP in your environment
|
||||
HOST_IP=`ifconfig | grep -m 1 'inet addr:'| cut -d: -f2 | awk '{print $1}'`
|
||||
fi
|
||||
TEST=0
|
||||
USE_MYSQL=0
|
||||
MYSQL_PASS=nova
|
||||
USE_LDAP=0
|
||||
LIBVIRT_TYPE=qemu
|
||||
|
||||
USE_MYSQL=${USE_MYSQL:-0}
|
||||
MYSQL_PASS=${MYSQL_PASS:-nova}
|
||||
TEST=${TEST:-0}
|
||||
USE_LDAP=${USE_LDAP:-0}
|
||||
LIBVIRT_TYPE=${LIBVIRT_TYPE:-qemu}
|
||||
NET_MAN=${NET_MAN:-VlanManager}
|
||||
# NOTE(vish): If you are using FlatDHCP on multiple hosts, set the interface
|
||||
# below but make sure that the interface doesn't already have an
|
||||
# ip or you risk breaking things.
|
||||
# FLAT_INTERFACE=eth0
|
||||
|
||||
if [ "$USE_MYSQL" == 1 ]; then
|
||||
SQL_CONN=mysql://root:$MYSQL_PASS@localhost/nova
|
||||
|
@ -36,10 +42,11 @@ else
|
|||
fi
|
||||
|
||||
mkdir -p /etc/nova
|
||||
cat >/etc/nova/nova-manage.conf << NOVA_CONF_EOF
|
||||
cat >$NOVA_DIR/bin/nova.conf << NOVA_CONF_EOF
|
||||
--verbose
|
||||
--nodaemon
|
||||
--dhcpbridge_flagfile=/etc/nova/nova-manage.conf
|
||||
--dhcpbridge_flagfile=$NOVA_DIR/bin/nova.conf
|
||||
--network_manager=nova.network.manager.$NET_MAN
|
||||
--cc_host=$HOST_IP
|
||||
--routing_source_ip=$HOST_IP
|
||||
--sql_connection=$SQL_CONN
|
||||
|
@ -47,6 +54,10 @@ cat >/etc/nova/nova-manage.conf << NOVA_CONF_EOF
|
|||
--libvirt_type=$LIBVIRT_TYPE
|
||||
NOVA_CONF_EOF
|
||||
|
||||
if [ -n "$FLAT_INTERFACE" ]; then
|
||||
echo "--flat_interface=$FLAT_INTERFACE" >>$NOVA_DIR/bin/nova.conf
|
||||
fi
|
||||
|
||||
if [ "$CMD" == "branch" ]; then
|
||||
sudo apt-get install -y bzr
|
||||
rm -rf $NOVA_DIR
|
||||
|
@ -61,9 +72,12 @@ if [ "$CMD" == "install" ]; then
|
|||
sudo apt-get install -y python-software-properties
|
||||
sudo add-apt-repository ppa:nova-core/ppa
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y dnsmasq open-iscsi kpartx kvm gawk iptables ebtables
|
||||
sudo apt-get install -y dnsmasq kpartx kvm gawk iptables ebtables
|
||||
sudo apt-get install -y user-mode-linux kvm libvirt-bin
|
||||
sudo apt-get install -y screen iscsitarget euca2ools vlan curl rabbitmq-server
|
||||
sudo apt-get install -y screen euca2ools vlan curl rabbitmq-server
|
||||
sudo apt-get install -y lvm2 iscsitarget open-iscsi
|
||||
echo "ISCSITARGET_ENABLE=true" | sudo tee /etc/default/iscsitarget
|
||||
sudo /etc/init.d/iscsitarget restart
|
||||
sudo modprobe kvm
|
||||
sudo /etc/init.d/libvirt-bin restart
|
||||
sudo apt-get install -y python-twisted python-sqlalchemy python-mox python-greenlet python-carrot
|
||||
|
@ -122,31 +136,32 @@ if [ "$CMD" == "run" ]; then
|
|||
$NOVA_DIR/bin/nova-manage project create admin admin
|
||||
# export environment variables for project 'admin' and user 'admin'
|
||||
$NOVA_DIR/bin/nova-manage project environment admin admin $NOVA_DIR/novarc
|
||||
# create 3 small networks
|
||||
$NOVA_DIR/bin/nova-manage network create 10.0.0.0/8 3 16
|
||||
# create a small network
|
||||
$NOVA_DIR/bin/nova-manage network create 10.0.0.0/8 1 32
|
||||
|
||||
# nova api crashes if we start it with a regular screen command,
|
||||
# so send the start command by forcing text into the window.
|
||||
screen_it api "$NOVA_DIR/bin/nova-api --flagfile=/etc/nova/nova-manage.conf"
|
||||
screen_it objectstore "$NOVA_DIR/bin/nova-objectstore --flagfile=/etc/nova/nova-manage.conf"
|
||||
screen_it compute "$NOVA_DIR/bin/nova-compute --flagfile=/etc/nova/nova-manage.conf"
|
||||
screen_it network "$NOVA_DIR/bin/nova-network --flagfile=/etc/nova/nova-manage.conf"
|
||||
screen_it scheduler "$NOVA_DIR/bin/nova-scheduler --flagfile=/etc/nova/nova-manage.conf"
|
||||
screen_it volume "$NOVA_DIR/bin/nova-volume --flagfile=/etc/nova/nova-manage.conf"
|
||||
screen_it api "$NOVA_DIR/bin/nova-api"
|
||||
screen_it objectstore "$NOVA_DIR/bin/nova-objectstore"
|
||||
screen_it compute "$NOVA_DIR/bin/nova-compute"
|
||||
screen_it network "$NOVA_DIR/bin/nova-network"
|
||||
screen_it scheduler "$NOVA_DIR/bin/nova-scheduler"
|
||||
screen_it volume "$NOVA_DIR/bin/nova-volume"
|
||||
screen_it test ". $NOVA_DIR/novarc"
|
||||
screen -x
|
||||
screen -S nova -x
|
||||
fi
|
||||
|
||||
if [ "$CMD" == "run" ] || [ "$CMD" == "terminate" ]; then
|
||||
# shutdown instances
|
||||
. $NOVA_DIR/novarc; euca-describe-instances | grep i- | cut -f2 | xargs euca-terminate-instances
|
||||
sleep 2
|
||||
# delete volumes
|
||||
. $NOVA_DIR/novarc; euca-describe-volumes | grep vol- | cut -f2 | xargs -n1 euca-delete-volume
|
||||
fi
|
||||
|
||||
if [ "$CMD" == "run" ] || [ "$CMD" == "clean" ]; then
|
||||
screen -S nova -X quit
|
||||
rm *.pid*
|
||||
$NOVA_DIR/tools/setup_iptables.sh clear
|
||||
fi
|
||||
|
||||
if [ "$CMD" == "scrub" ]; then
|
||||
|
|
|
@ -994,8 +994,11 @@ class CloudController(object):
|
|||
return True
|
||||
|
||||
def describe_images(self, context, image_id=None, **kwargs):
|
||||
imageSet = self.image_service.index(context, image_id)
|
||||
return {'imagesSet': imageSet}
|
||||
# Note: image_id is a list!
|
||||
images = self.image_service.index(context)
|
||||
if image_id:
|
||||
images = filter(lambda x: x['imageId'] in image_id, images)
|
||||
return {'imagesSet': images}
|
||||
|
||||
def deregister_image(self, context, image_id, **kwargs):
|
||||
self.image_service.deregister(context, image_id)
|
||||
|
|
|
@ -23,10 +23,7 @@ class Context(object):
|
|||
class BasicApiAuthManager(object):
|
||||
""" Implements a somewhat rudimentary version of OpenStack Auth"""
|
||||
|
||||
def __init__(self, host=None, db_driver=None):
|
||||
if not host:
|
||||
host = FLAGS.host
|
||||
self.host = host
|
||||
def __init__(self, db_driver=None):
|
||||
if not db_driver:
|
||||
db_driver = FLAGS.db_driver
|
||||
self.db = utils.import_object(db_driver)
|
||||
|
@ -47,7 +44,7 @@ class BasicApiAuthManager(object):
|
|||
except KeyError:
|
||||
return faults.Fault(webob.exc.HTTPUnauthorized())
|
||||
|
||||
token, user = self._authorize_user(username, key)
|
||||
token, user = self._authorize_user(username, key, req)
|
||||
if user and token:
|
||||
res = webob.Response()
|
||||
res.headers['X-Auth-Token'] = token.token_hash
|
||||
|
@ -82,8 +79,13 @@ class BasicApiAuthManager(object):
|
|||
return {'id': user.id}
|
||||
return None
|
||||
|
||||
def _authorize_user(self, username, key):
|
||||
""" Generates a new token and assigns it to a user """
|
||||
def _authorize_user(self, username, key, req):
|
||||
"""Generates a new token and assigns it to a user.
|
||||
|
||||
username - string
|
||||
key - string API key
|
||||
req - webob.Request object
|
||||
"""
|
||||
user = self.auth.get_user_from_access_key(key)
|
||||
if user and user.name == username:
|
||||
token_hash = hashlib.sha1('%s%s%f' % (username, key,
|
||||
|
@ -91,12 +93,10 @@ class BasicApiAuthManager(object):
|
|||
token_dict = {}
|
||||
token_dict['token_hash'] = token_hash
|
||||
token_dict['cdn_management_url'] = ''
|
||||
token_dict['server_management_url'] = self._get_server_mgmt_url()
|
||||
# Same as auth url, e.g. http://foo.org:8774/baz/v1.0
|
||||
token_dict['server_management_url'] = req.url
|
||||
token_dict['storage_url'] = ''
|
||||
token_dict['user_id'] = user.id
|
||||
token = self.db.auth_create_token(self.context, token_dict)
|
||||
return token, user
|
||||
return None, None
|
||||
|
||||
def _get_server_mgmt_url(self):
|
||||
return 'https://%s/v1.0/' % self.host
|
||||
|
|
|
@ -47,7 +47,7 @@ class Fault(webob.exc.HTTPException):
|
|||
"""Generate a WSGI response based on the exception passed to ctor."""
|
||||
# Replace the body with fault details.
|
||||
code = self.wrapped_exc.status_int
|
||||
fault_name = self._fault_names.get(code, "cloudServersFault")
|
||||
fault_name = self._fault_names.get(code, "computeFault")
|
||||
fault_data = {
|
||||
fault_name: {
|
||||
'code': code,
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
#
|
||||
# Person object for Nova
|
||||
# inetorgperson with extra attributes
|
||||
# Author: Vishvananda Ishaya <vishvananda@yahoo.com>
|
||||
#
|
||||
#
|
||||
|
||||
# using internet experimental oid arc as per BP64 3.1
|
||||
objectidentifier novaSchema 1.3.6.1.3.1.666.666
|
||||
objectidentifier novaAttrs novaSchema:3
|
||||
objectidentifier novaOCs novaSchema:4
|
||||
|
||||
attributetype (
|
||||
novaAttrs:1
|
||||
NAME 'accessKey'
|
||||
DESC 'Key for accessing data'
|
||||
EQUALITY caseIgnoreMatch
|
||||
SUBSTR caseIgnoreSubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
|
||||
SINGLE-VALUE
|
||||
)
|
||||
|
||||
attributetype (
|
||||
novaAttrs:2
|
||||
NAME 'secretKey'
|
||||
DESC 'Secret key'
|
||||
EQUALITY caseIgnoreMatch
|
||||
SUBSTR caseIgnoreSubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
|
||||
SINGLE-VALUE
|
||||
)
|
||||
|
||||
attributetype (
|
||||
novaAttrs:3
|
||||
NAME 'keyFingerprint'
|
||||
DESC 'Fingerprint of private key'
|
||||
EQUALITY caseIgnoreMatch
|
||||
SUBSTR caseIgnoreSubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
|
||||
SINGLE-VALUE
|
||||
)
|
||||
|
||||
attributetype (
|
||||
novaAttrs:4
|
||||
NAME 'isAdmin'
|
||||
DESC 'Is user an administrator?'
|
||||
EQUALITY booleanMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
|
||||
SINGLE-VALUE
|
||||
)
|
||||
|
||||
attributetype (
|
||||
novaAttrs:5
|
||||
NAME 'projectManager'
|
||||
DESC 'Project Managers of a project'
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
|
||||
)
|
||||
|
||||
objectClass (
|
||||
novaOCs:1
|
||||
NAME 'novaUser'
|
||||
DESC 'access and secret keys'
|
||||
AUXILIARY
|
||||
MUST ( uid )
|
||||
MAY ( accessKey $ secretKey $ isAdmin )
|
||||
)
|
||||
|
||||
objectClass (
|
||||
novaOCs:2
|
||||
NAME 'novaKeyPair'
|
||||
DESC 'Key pair for User'
|
||||
SUP top
|
||||
STRUCTURAL
|
||||
MUST ( cn $ sshPublicKey $ keyFingerprint )
|
||||
)
|
||||
|
||||
objectClass (
|
||||
novaOCs:3
|
||||
NAME 'novaProject'
|
||||
DESC 'Container for project'
|
||||
SUP groupOfNames
|
||||
STRUCTURAL
|
||||
MUST ( cn $ projectManager )
|
||||
)
|
|
@ -0,0 +1,16 @@
|
|||
#
|
||||
# Person object for Nova
|
||||
# inetorgperson with extra attributes
|
||||
# Author: Vishvananda Ishaya <vishvananda@yahoo.com>
|
||||
# Modified for strict RFC 4512 compatibility by: Ryan Lane <ryan@ryandlane.com>
|
||||
#
|
||||
# using internet experimental oid arc as per BP64 3.1
|
||||
dn: cn=schema
|
||||
attributeTypes: ( 1.3.6.1.3.1.666.666.3.1 NAME 'accessKey' DESC 'Key for accessing data' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )
|
||||
attributeTypes: ( 1.3.6.1.3.1.666.666.3.2 NAME 'secretKey' DESC 'Secret key' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )
|
||||
attributeTypes: ( 1.3.6.1.3.1.666.666.3.3 NAME 'keyFingerprint' DESC 'Fingerprint of private key' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE)
|
||||
attributeTypes: ( 1.3.6.1.3.1.666.666.3.4 NAME 'isAdmin' DESC 'Is user an administrator?' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
|
||||
attributeTypes: ( 1.3.6.1.3.1.666.666.3.5 NAME 'projectManager' DESC 'Project Managers of a project' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
|
||||
objectClasses: ( 1.3.6.1.3.1.666.666.4.1 NAME 'novaUser' DESC 'access and secret keys' SUP top AUXILIARY MUST ( uid ) MAY ( accessKey $ secretKey $ isAdmin ) )
|
||||
objectClasses: ( 1.3.6.1.3.1.666.666.4.2 NAME 'novaKeyPair' DESC 'Key pair for User' SUP top STRUCTURAL MUST ( cn $ sshPublicKey $ keyFingerprint ) )
|
||||
objectClasses: ( 1.3.6.1.3.1.666.666.4.3 NAME 'novaProject' DESC 'Container for project' SUP groupOfNames STRUCTURAL MUST ( cn $ projectManager ) )
|
|
@ -0,0 +1,19 @@
|
|||
#
|
||||
# LDAP Public Key Patch schema for use with openssh-ldappubkey
|
||||
# Author: Eric AUGE <eau@phear.org>
|
||||
#
|
||||
# Based on the proposal of : Mark Ruijter
|
||||
#
|
||||
|
||||
|
||||
# octetString SYNTAX
|
||||
attributetype ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey'
|
||||
DESC 'MANDATORY: OpenSSH Public key'
|
||||
EQUALITY octetStringMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
|
||||
|
||||
# printableString SYNTAX yes|no
|
||||
objectclass ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY
|
||||
DESC 'MANDATORY: OpenSSH LPK objectclass'
|
||||
MAY ( sshPublicKey $ uid )
|
||||
)
|
|
@ -0,0 +1,10 @@
|
|||
#
|
||||
# LDAP Public Key Patch schema for use with openssh-ldappubkey
|
||||
# Author: Eric AUGE <eau@phear.org>
|
||||
#
|
||||
# Schema for Sun Directory Server.
|
||||
# Based on the original schema, modified by Stefan Fischer.
|
||||
#
|
||||
dn: cn=schema
|
||||
attributeTypes: ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey' DESC 'MANDATORY: OpenSSH Public key' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
|
||||
objectClasses: ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY DESC 'MANDATORY: OpenSSH LPK objectclass' MAY ( sshPublicKey $ uid ) )
|
|
@ -20,115 +20,9 @@
|
|||
|
||||
apt-get install -y slapd ldap-utils python-ldap
|
||||
|
||||
cat >/etc/ldap/schema/openssh-lpk_openldap.schema <<LPK_SCHEMA_EOF
|
||||
#
|
||||
# LDAP Public Key Patch schema for use with openssh-ldappubkey
|
||||
# Author: Eric AUGE <eau@phear.org>
|
||||
#
|
||||
# Based on the proposal of : Mark Ruijter
|
||||
#
|
||||
|
||||
|
||||
# octetString SYNTAX
|
||||
attributetype ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey'
|
||||
DESC 'MANDATORY: OpenSSH Public key'
|
||||
EQUALITY octetStringMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
|
||||
|
||||
# printableString SYNTAX yes|no
|
||||
objectclass ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY
|
||||
DESC 'MANDATORY: OpenSSH LPK objectclass'
|
||||
MAY ( sshPublicKey $ uid )
|
||||
)
|
||||
LPK_SCHEMA_EOF
|
||||
|
||||
cat >/etc/ldap/schema/nova.schema <<NOVA_SCHEMA_EOF
|
||||
#
|
||||
# Person object for Nova
|
||||
# inetorgperson with extra attributes
|
||||
# Author: Vishvananda Ishaya <vishvananda@yahoo.com>
|
||||
#
|
||||
#
|
||||
|
||||
# using internet experimental oid arc as per BP64 3.1
|
||||
objectidentifier novaSchema 1.3.6.1.3.1.666.666
|
||||
objectidentifier novaAttrs novaSchema:3
|
||||
objectidentifier novaOCs novaSchema:4
|
||||
|
||||
attributetype (
|
||||
novaAttrs:1
|
||||
NAME 'accessKey'
|
||||
DESC 'Key for accessing data'
|
||||
EQUALITY caseIgnoreMatch
|
||||
SUBSTR caseIgnoreSubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
|
||||
SINGLE-VALUE
|
||||
)
|
||||
|
||||
attributetype (
|
||||
novaAttrs:2
|
||||
NAME 'secretKey'
|
||||
DESC 'Secret key'
|
||||
EQUALITY caseIgnoreMatch
|
||||
SUBSTR caseIgnoreSubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
|
||||
SINGLE-VALUE
|
||||
)
|
||||
|
||||
attributetype (
|
||||
novaAttrs:3
|
||||
NAME 'keyFingerprint'
|
||||
DESC 'Fingerprint of private key'
|
||||
EQUALITY caseIgnoreMatch
|
||||
SUBSTR caseIgnoreSubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
|
||||
SINGLE-VALUE
|
||||
)
|
||||
|
||||
attributetype (
|
||||
novaAttrs:4
|
||||
NAME 'isAdmin'
|
||||
DESC 'Is user an administrator?'
|
||||
EQUALITY booleanMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
|
||||
SINGLE-VALUE
|
||||
)
|
||||
|
||||
attributetype (
|
||||
novaAttrs:5
|
||||
NAME 'projectManager'
|
||||
DESC 'Project Managers of a project'
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
|
||||
)
|
||||
|
||||
objectClass (
|
||||
novaOCs:1
|
||||
NAME 'novaUser'
|
||||
DESC 'access and secret keys'
|
||||
AUXILIARY
|
||||
MUST ( uid )
|
||||
MAY ( accessKey $ secretKey $ isAdmin )
|
||||
)
|
||||
|
||||
objectClass (
|
||||
novaOCs:2
|
||||
NAME 'novaKeyPair'
|
||||
DESC 'Key pair for User'
|
||||
SUP top
|
||||
STRUCTURAL
|
||||
MUST ( cn $ sshPublicKey $ keyFingerprint )
|
||||
)
|
||||
|
||||
objectClass (
|
||||
novaOCs:3
|
||||
NAME 'novaProject'
|
||||
DESC 'Container for project'
|
||||
SUP groupOfNames
|
||||
STRUCTURAL
|
||||
MUST ( cn $ projectManager )
|
||||
)
|
||||
|
||||
NOVA_SCHEMA_EOF
|
||||
abspath=`dirname "$(cd "${0%/*}" 2>/dev/null; echo "$PWD"/"${0##*/}")"`
|
||||
cp $abspath/openssh-lpk_openldap.schema /etc/ldap/schema/openssh-lpk_openldap.schema
|
||||
cp $abspath/nova_openldap.schema /etc/ldap/schema/nova_openldap.schema
|
||||
|
||||
mv /etc/ldap/slapd.conf /etc/ldap/slapd.conf.orig
|
||||
cat >/etc/ldap/slapd.conf <<SLAPD_CONF_EOF
|
||||
|
|
|
@ -47,7 +47,7 @@ from nova.compute import power_state
|
|||
|
||||
|
||||
FLAGS = flags.FLAGS
|
||||
flags.DEFINE_string('instances_path', utils.abspath('../instances'),
|
||||
flags.DEFINE_string('instances_path', '$state_path/instances',
|
||||
'where instances are stored on disk')
|
||||
flags.DEFINE_string('compute_driver', 'nova.virt.connection.get_connection',
|
||||
'Driver to use for volume creation')
|
||||
|
|
|
@ -46,7 +46,7 @@ flags.DEFINE_integer('monitoring_instances_delay', 5,
|
|||
'Sleep time between updates')
|
||||
flags.DEFINE_integer('monitoring_instances_step', 300,
|
||||
'Interval of RRD updates')
|
||||
flags.DEFINE_string('monitoring_rrd_path', '/var/nova/monitor/instances',
|
||||
flags.DEFINE_string('monitoring_rrd_path', '$state_path/monitor/instances',
|
||||
'Location of RRD files')
|
||||
|
||||
|
||||
|
|
|
@ -40,9 +40,9 @@ from nova import flags
|
|||
|
||||
FLAGS = flags.FLAGS
|
||||
flags.DEFINE_string('ca_file', 'cacert.pem', 'Filename of root CA')
|
||||
flags.DEFINE_string('keys_path', utils.abspath('../keys'),
|
||||
flags.DEFINE_string('keys_path', '$state_path/keys',
|
||||
'Where we keep our keys')
|
||||
flags.DEFINE_string('ca_path', utils.abspath('../CA'),
|
||||
flags.DEFINE_string('ca_path', '$state_path/CA',
|
||||
'Where we keep our root CA')
|
||||
flags.DEFINE_boolean('use_intermediate_ca', False,
|
||||
'Should we use intermediate CAs for each project?')
|
||||
|
|
|
@ -24,6 +24,7 @@ where they're used.
|
|||
import getopt
|
||||
import os
|
||||
import socket
|
||||
import string
|
||||
import sys
|
||||
|
||||
import gflags
|
||||
|
@ -38,11 +39,12 @@ class FlagValues(gflags.FlagValues):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, extra_context=None):
|
||||
gflags.FlagValues.__init__(self)
|
||||
self.__dict__['__dirty'] = []
|
||||
self.__dict__['__was_already_parsed'] = False
|
||||
self.__dict__['__stored_argv'] = []
|
||||
self.__dict__['__extra_context'] = extra_context
|
||||
|
||||
def __call__(self, argv):
|
||||
# We're doing some hacky stuff here so that we don't have to copy
|
||||
|
@ -112,7 +114,7 @@ class FlagValues(gflags.FlagValues):
|
|||
def ParseNewFlags(self):
|
||||
if '__stored_argv' not in self.__dict__:
|
||||
return
|
||||
new_flags = FlagValues()
|
||||
new_flags = FlagValues(self)
|
||||
for k in self.__dict__['__dirty']:
|
||||
new_flags[k] = gflags.FlagValues.__getitem__(self, k)
|
||||
|
||||
|
@ -134,9 +136,29 @@ class FlagValues(gflags.FlagValues):
|
|||
def __getattr__(self, name):
|
||||
if self.IsDirty(name):
|
||||
self.ParseNewFlags()
|
||||
return gflags.FlagValues.__getattr__(self, name)
|
||||
val = gflags.FlagValues.__getattr__(self, name)
|
||||
if type(val) is str:
|
||||
tmpl = string.Template(val)
|
||||
context = [self, self.__dict__['__extra_context']]
|
||||
return tmpl.substitute(StrWrapper(context))
|
||||
return val
|
||||
|
||||
|
||||
class StrWrapper(object):
|
||||
"""Wrapper around FlagValues objects
|
||||
|
||||
Wraps FlagValues objects for string.Template so that we're
|
||||
sure to return strings."""
|
||||
def __init__(self, context_objs):
|
||||
self.context_objs = context_objs
|
||||
|
||||
def __getitem__(self, name):
|
||||
for context in self.context_objs:
|
||||
val = getattr(context, name, False)
|
||||
if val:
|
||||
return str(val)
|
||||
raise KeyError(name)
|
||||
|
||||
FLAGS = FlagValues()
|
||||
gflags.FLAGS = FLAGS
|
||||
gflags.DEFINE_flag(gflags.HelpFlag(), FLAGS)
|
||||
|
@ -222,8 +244,11 @@ DEFINE_string('vpn_key_suffix',
|
|||
|
||||
DEFINE_integer('auth_token_ttl', 3600, 'Seconds for auth tokens to linger')
|
||||
|
||||
DEFINE_string('state_path', os.path.join(os.path.dirname(__file__), '../'),
|
||||
"Top-level directory for maintaining nova's state")
|
||||
|
||||
DEFINE_string('sql_connection',
|
||||
'sqlite:///%s/nova.sqlite' % os.path.abspath("./"),
|
||||
'sqlite:///$state_path/nova.sqlite',
|
||||
'connection string for sql database')
|
||||
|
||||
DEFINE_string('compute_manager', 'nova.compute.manager.ComputeManager',
|
||||
|
|
|
@ -38,12 +38,12 @@ flags.DEFINE_string('dhcpbridge_flagfile',
|
|||
'/etc/nova/nova-dhcpbridge.conf',
|
||||
'location of flagfile for dhcpbridge')
|
||||
|
||||
flags.DEFINE_string('networks_path', utils.abspath('../networks'),
|
||||
flags.DEFINE_string('networks_path', '$state_path/networks',
|
||||
'Location to keep network config files')
|
||||
flags.DEFINE_string('public_interface', 'vlan1',
|
||||
'Interface for public IP addresses')
|
||||
flags.DEFINE_string('bridge_dev', 'eth0',
|
||||
'network device for bridges')
|
||||
flags.DEFINE_string('vlan_interface', 'eth0',
|
||||
'network device for vlans')
|
||||
flags.DEFINE_string('dhcpbridge', _bin_file('nova-dhcpbridge'),
|
||||
'location of nova-dhcpbridge')
|
||||
flags.DEFINE_string('routing_source_ip', '127.0.0.1',
|
||||
|
@ -54,14 +54,15 @@ flags.DEFINE_bool('use_nova_chains', False,
|
|||
DEFAULT_PORTS = [("tcp", 80), ("tcp", 22), ("udp", 1194), ("tcp", 443)]
|
||||
|
||||
|
||||
def init_host():
|
||||
"""Basic networking setup goes here"""
|
||||
# NOTE(devcamcar): Cloud public DNAT entries, CloudPipe port
|
||||
# forwarding entries and a default DNAT entry.
|
||||
def metadata_forward():
|
||||
"""Create forwarding rule for metadata"""
|
||||
_confirm_rule("PREROUTING", "-t nat -s 0.0.0.0/0 "
|
||||
"-d 169.254.169.254/32 -p tcp -m tcp --dport 80 -j DNAT "
|
||||
"--to-destination %s:%s" % (FLAGS.cc_host, FLAGS.cc_port))
|
||||
|
||||
|
||||
def init_host():
|
||||
"""Basic networking setup goes here"""
|
||||
# NOTE(devcamcar): Cloud public SNAT entries and the default
|
||||
# SNAT rule for outbound traffic.
|
||||
_confirm_rule("POSTROUTING", "-t nat -s %s "
|
||||
|
@ -134,7 +135,7 @@ def ensure_vlan(vlan_num):
|
|||
if not _device_exists(interface):
|
||||
logging.debug("Starting VLAN inteface %s", interface)
|
||||
_execute("sudo vconfig set_name_type VLAN_PLUS_VID_NO_PAD")
|
||||
_execute("sudo vconfig add %s %s" % (FLAGS.bridge_dev, vlan_num))
|
||||
_execute("sudo vconfig add %s %s" % (FLAGS.vlan_interface, vlan_num))
|
||||
_execute("sudo ifconfig %s up" % interface)
|
||||
return interface
|
||||
|
||||
|
@ -142,12 +143,13 @@ def ensure_vlan(vlan_num):
|
|||
def ensure_bridge(bridge, interface, net_attrs=None):
|
||||
"""Create a bridge unless it already exists"""
|
||||
if not _device_exists(bridge):
|
||||
logging.debug("Starting Bridge inteface for %s", interface)
|
||||
logging.debug("Starting Bridge interface for %s", interface)
|
||||
_execute("sudo brctl addbr %s" % bridge)
|
||||
_execute("sudo brctl setfd %s 0" % bridge)
|
||||
# _execute("sudo brctl setageing %s 10" % bridge)
|
||||
_execute("sudo brctl stp %s off" % bridge)
|
||||
_execute("sudo brctl addif %s %s" % (bridge, interface))
|
||||
if interface:
|
||||
_execute("sudo brctl addif %s %s" % (bridge, interface))
|
||||
if net_attrs:
|
||||
_execute("sudo ifconfig %s %s broadcast %s netmask %s up" % \
|
||||
(bridge,
|
||||
|
|
|
@ -27,6 +27,7 @@ topologies. All of the network commands are issued to a subclass of
|
|||
|
||||
:network_driver: Driver to use for network creation
|
||||
:flat_network_bridge: Bridge device for simple network instances
|
||||
:flat_interface: FlatDhcp will bridge into this interface if set
|
||||
:flat_network_dns: Dns for simple network
|
||||
:flat_network_dhcp_start: Dhcp start for FlatDhcp
|
||||
:vlan_start: First VLAN for private networks
|
||||
|
@ -63,7 +64,11 @@ flags.DEFINE_string('flat_network_bridge', 'br100',
|
|||
'Bridge for simple network instances')
|
||||
flags.DEFINE_string('flat_network_dns', '8.8.4.4',
|
||||
'Dns for simple network')
|
||||
flags.DEFINE_string('flat_network_dhcp_start', '192.168.0.2',
|
||||
flags.DEFINE_bool('flat_injected', True,
|
||||
'Whether to attempt to inject network setup into guest')
|
||||
flags.DEFINE_string('flat_interface', None,
|
||||
'FlatDhcp will bridge into this interface if set')
|
||||
flags.DEFINE_string('flat_network_dhcp_start', '10.0.0.2',
|
||||
'Dhcp start for FlatDhcp')
|
||||
flags.DEFINE_integer('vlan_start', 100, 'First VLAN for private networks')
|
||||
flags.DEFINE_integer('num_networks', 1000, 'Number of networks to support')
|
||||
|
@ -175,9 +180,11 @@ class NetworkManager(manager.Manager):
|
|||
if instance_ref['mac_address'] != mac:
|
||||
raise exception.Error("IP %s leased to bad mac %s vs %s" %
|
||||
(address, instance_ref['mac_address'], mac))
|
||||
now = datetime.datetime.utcnow()
|
||||
self.db.fixed_ip_update(context,
|
||||
fixed_ip_ref['address'],
|
||||
{'leased': True})
|
||||
{'leased': True,
|
||||
'updated_at': now})
|
||||
if not fixed_ip_ref['allocated']:
|
||||
logging.warn("IP %s leased that was already deallocated", address)
|
||||
|
||||
|
@ -246,7 +253,31 @@ class NetworkManager(manager.Manager):
|
|||
|
||||
|
||||
class FlatManager(NetworkManager):
|
||||
"""Basic network where no vlans are used."""
|
||||
"""Basic network where no vlans are used.
|
||||
|
||||
FlatManager does not do any bridge or vlan creation. The user is
|
||||
responsible for setting up whatever bridge is specified in
|
||||
flat_network_bridge (br100 by default). This bridge needs to be created
|
||||
on all compute hosts.
|
||||
|
||||
The idea is to create a single network for the host with a command like:
|
||||
nova-manage network create 192.168.0.0/24 1 256. Creating multiple
|
||||
networks for for one manager is currently not supported, but could be
|
||||
added by modifying allocate_fixed_ip and get_network to get the a network
|
||||
with new logic instead of network_get_by_bridge. Arbitrary lists of
|
||||
addresses in a single network can be accomplished with manual db editing.
|
||||
|
||||
If flat_injected is True, the compute host will attempt to inject network
|
||||
config into the guest. It attempts to modify /etc/network/interfaces and
|
||||
currently only works on debian based systems. To support a wider range of
|
||||
OSes, some other method may need to be devised to let the guest know which
|
||||
ip it should be using so that it can configure itself. Perhaps an attached
|
||||
disk or serial device with configuration info.
|
||||
|
||||
Metadata forwarding must be handled by the gateway, and since nova does
|
||||
not do any setup in this mode, it must be done manually. Requests to
|
||||
169.254.169.254 port 80 will need to be forwarded to the api server.
|
||||
"""
|
||||
|
||||
def allocate_fixed_ip(self, context, instance_id, *args, **kwargs):
|
||||
"""Gets a fixed ip from the pool."""
|
||||
|
@ -285,6 +316,7 @@ class FlatManager(NetworkManager):
|
|||
cidr = "%s/%s" % (fixed_net[start], significant_bits)
|
||||
project_net = IPy.IP(cidr)
|
||||
net = {}
|
||||
net['bridge'] = FLAGS.flat_network_bridge
|
||||
net['cidr'] = cidr
|
||||
net['netmask'] = str(project_net.netmask())
|
||||
net['gateway'] = str(project_net[1])
|
||||
|
@ -306,18 +338,36 @@ class FlatManager(NetworkManager):
|
|||
def _on_set_network_host(self, context, network_id):
|
||||
"""Called when this host becomes the host for a network."""
|
||||
net = {}
|
||||
net['injected'] = True
|
||||
net['bridge'] = FLAGS.flat_network_bridge
|
||||
net['injected'] = FLAGS.flat_injected
|
||||
net['dns'] = FLAGS.flat_network_dns
|
||||
self.db.network_update(context, network_id, net)
|
||||
|
||||
|
||||
class FlatDHCPManager(NetworkManager):
|
||||
"""Flat networking with dhcp."""
|
||||
class FlatDHCPManager(FlatManager):
|
||||
"""Flat networking with dhcp.
|
||||
|
||||
FlatDHCPManager will start up one dhcp server to give out addresses.
|
||||
It never injects network settings into the guest. Otherwise it behaves
|
||||
like FlatDHCPManager.
|
||||
"""
|
||||
|
||||
def init_host(self):
|
||||
"""Do any initialization that needs to be run if this is a
|
||||
standalone service.
|
||||
"""
|
||||
super(FlatDHCPManager, self).init_host()
|
||||
self.driver.metadata_forward()
|
||||
|
||||
def setup_compute_network(self, context, instance_id):
|
||||
"""Sets up matching network for compute hosts."""
|
||||
network_ref = db.network_get_by_instance(context, instance_id)
|
||||
self.driver.ensure_bridge(network_ref['bridge'],
|
||||
FLAGS.flat_interface,
|
||||
network_ref)
|
||||
|
||||
def setup_fixed_ip(self, context, address):
|
||||
"""Setup dhcp for this network."""
|
||||
network_ref = db.fixed_ip_get_by_address(context, address)
|
||||
network_ref = db.fixed_ip_get_network(context, address)
|
||||
self.driver.update_dhcp(context, network_ref['id'])
|
||||
|
||||
def deallocate_fixed_ip(self, context, address, *args, **kwargs):
|
||||
|
@ -326,18 +376,28 @@ class FlatDHCPManager(NetworkManager):
|
|||
|
||||
def _on_set_network_host(self, context, network_id):
|
||||
"""Called when this host becomes the host for a project."""
|
||||
super(FlatDHCPManager, self)._on_set_network_host(context, network_id)
|
||||
network_ref = self.db.network_get(context, network_id)
|
||||
self.db.network_update(context,
|
||||
network_id,
|
||||
{'dhcp_start': FLAGS.flat_network_dhcp_start})
|
||||
net = {}
|
||||
net['dhcp_start'] = FLAGS.flat_network_dhcp_start
|
||||
self.db.network_update(context, network_id, net)
|
||||
network_ref = db.network_get(context, network_id)
|
||||
self.driver.ensure_bridge(network_ref['bridge'],
|
||||
FLAGS.bridge_dev,
|
||||
FLAGS.flat_interface,
|
||||
network_ref)
|
||||
|
||||
|
||||
class VlanManager(NetworkManager):
|
||||
"""Vlan network with dhcp."""
|
||||
"""Vlan network with dhcp.
|
||||
|
||||
VlanManager is the most complicated. It will create a host-managed
|
||||
vlan for each project. Each project gets its own subnet. The networks
|
||||
and associated subnets are created with nova-manage using a command like:
|
||||
nova-manage network create 10.0.0.0/8 3 16. This will create 3 networks
|
||||
of 16 addresses from the beginning of the 10.0.0.0 range.
|
||||
|
||||
A dhcp server is run for each subnet, so each project will have its own.
|
||||
For this mode to be useful, each project will need a vpn to access the
|
||||
instances in its subnet.
|
||||
"""
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def periodic_tasks(self, context=None):
|
||||
|
@ -357,6 +417,7 @@ class VlanManager(NetworkManager):
|
|||
standalone service.
|
||||
"""
|
||||
super(VlanManager, self).init_host()
|
||||
self.driver.metadata_forward()
|
||||
self.driver.init_host()
|
||||
|
||||
def allocate_fixed_ip(self, context, instance_id, *args, **kwargs):
|
||||
|
|
|
@ -33,7 +33,7 @@ from nova.objectstore import stored
|
|||
|
||||
|
||||
FLAGS = flags.FLAGS
|
||||
flags.DEFINE_string('buckets_path', utils.abspath('../buckets'),
|
||||
flags.DEFINE_string('buckets_path', '$state_path/buckets',
|
||||
'path to s3 buckets')
|
||||
|
||||
|
||||
|
|
|
@ -39,8 +39,8 @@ from nova.objectstore import bucket
|
|||
|
||||
|
||||
FLAGS = flags.FLAGS
|
||||
flags.DEFINE_string('images_path', utils.abspath('../images'),
|
||||
'path to decrypted images')
|
||||
flags.DEFINE_string('images_path', '$state_path/images',
|
||||
'path to decrypted images')
|
||||
|
||||
|
||||
class Image(object):
|
||||
|
|
|
@ -54,7 +54,6 @@ def fake_auth_init(self):
|
|||
self.db = FakeAuthDatabase()
|
||||
self.context = Context()
|
||||
self.auth = FakeAuthManager()
|
||||
self.host = 'foo'
|
||||
|
||||
|
||||
@webob.dec.wsgify
|
||||
|
|
|
@ -50,12 +50,12 @@ class APITest(unittest.TestCase):
|
|||
|
||||
api.application = succeed
|
||||
resp = Request.blank('/').get_response(api)
|
||||
self.assertFalse('cloudServersFault' in resp.body, resp.body)
|
||||
self.assertFalse('computeFault' in resp.body, resp.body)
|
||||
self.assertEqual(resp.status_int, 200, resp.body)
|
||||
|
||||
api.application = raise_webob_exc
|
||||
resp = Request.blank('/').get_response(api)
|
||||
self.assertFalse('cloudServersFault' in resp.body, resp.body)
|
||||
self.assertFalse('computeFault' in resp.body, resp.body)
|
||||
self.assertEqual(resp.status_int, 404, resp.body)
|
||||
|
||||
api.application = raise_api_fault
|
||||
|
@ -65,10 +65,10 @@ class APITest(unittest.TestCase):
|
|||
|
||||
api.application = fail
|
||||
resp = Request.blank('/').get_response(api)
|
||||
self.assertTrue('{"cloudServersFault' in resp.body, resp.body)
|
||||
self.assertTrue('{"computeFault' in resp.body, resp.body)
|
||||
self.assertEqual(resp.status_int, 500, resp.body)
|
||||
|
||||
api.application = fail
|
||||
resp = Request.blank('/.xml').get_response(api)
|
||||
self.assertTrue('<cloudServersFault' in resp.body, resp.body)
|
||||
self.assertTrue('<computeFault' in resp.body, resp.body)
|
||||
self.assertEqual(resp.status_int, 500, resp.body)
|
||||
|
|
|
@ -62,14 +62,14 @@ class Test(unittest.TestCase):
|
|||
f = fakes.FakeAuthManager()
|
||||
f.add_user('derp', nova.auth.manager.User(1, 'herp', None, None, None))
|
||||
|
||||
req = webob.Request.blank('/v1.0/')
|
||||
req = webob.Request.blank('/v1.0/', {'HTTP_HOST': 'foo'})
|
||||
req.headers['X-Auth-User'] = 'herp'
|
||||
req.headers['X-Auth-Key'] = 'derp'
|
||||
result = req.get_response(nova.api.API('os'))
|
||||
self.assertEqual(result.status, '204 No Content')
|
||||
self.assertEqual(len(result.headers['X-Auth-Token']), 40)
|
||||
self.assertEqual(result.headers['X-Server-Management-Url'],
|
||||
"https://foo/v1.0/")
|
||||
"http://foo/v1.0/")
|
||||
self.assertEqual(result.headers['X-CDN-Management-Url'],
|
||||
"")
|
||||
self.assertEqual(result.headers['X-Storage-Url'], "")
|
||||
|
|
Loading…
Reference in New Issue