merged trunk

This commit is contained in:
Ken Pepple
2011-04-06 15:55:55 -07:00
16 changed files with 73 additions and 214 deletions

View File

@@ -32,6 +32,7 @@ Jesse Andrews <anotherjesse@gmail.com>
Joe Heck <heckj@mac.com> Joe Heck <heckj@mac.com>
Joel Moore <joelbm24@gmail.com> Joel Moore <joelbm24@gmail.com>
John Dewey <john@dewey.ws> John Dewey <john@dewey.ws>
John Tran <jtran@attinteractive.com>
Jonathan Bryce <jbryce@jbryce.com> Jonathan Bryce <jbryce@jbryce.com>
Jordan Rinke <jordan@openstack.org> Jordan Rinke <jordan@openstack.org>
Josh Durgin <joshd@hq.newdream.net> Josh Durgin <joshd@hq.newdream.net>

11
CA/.gitignore vendored
View File

@@ -1,11 +0,0 @@
index.txt
index.txt.old
index.txt.attr
index.txt.attr.old
cacert.pem
serial
serial.old
openssl.cnf
private/*
newcerts/*

View File

@@ -1,39 +0,0 @@
#!/bin/bash
# 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.
# $1 is the id of the project and $2 is the subject of the cert
NAME=$1
SUBJ=$2
mkdir -p projects/$NAME
cd projects/$NAME
cp ../../openssl.cnf.tmpl openssl.cnf
sed -i -e s/%USERNAME%/$NAME/g openssl.cnf
mkdir certs crl newcerts private
openssl req -new -x509 -extensions v3_ca -keyout private/cakey.pem -out cacert.pem -days 365 -config ./openssl.cnf -batch -nodes
echo "10" > serial
touch index.txt
# NOTE(vish): Disabling intermediate ca's because we don't actually need them.
# It makes more sense to have each project have its own root ca.
# openssl genrsa -out private/cakey.pem 1024 -config ./openssl.cnf -batch -nodes
# openssl req -new -sha256 -key private/cakey.pem -out ../../reqs/inter$NAME.csr -batch -subj "$SUBJ"
openssl ca -gencrl -config ./openssl.cnf -out crl.pem
if [ "`id -u`" != "`grep nova /etc/passwd | cut -d':' -f3`" ]; then
sudo chown -R nova:nogroup .
fi
# cd ../../
# openssl ca -extensions v3_ca -days 365 -out INTER/$NAME/cacert.pem -in reqs/inter$NAME.csr -config openssl.cnf -batch

View File

@@ -1,29 +0,0 @@
#!/bin/bash
# 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.
if [ -f "cacert.pem" ];
then
echo "Not installing, it's already done."
else
cp openssl.cnf.tmpl openssl.cnf
sed -i -e s/%USERNAME%/ROOT/g openssl.cnf
openssl req -new -x509 -extensions v3_ca -keyout private/cakey.pem -out cacert.pem -days 365 -config ./openssl.cnf -batch -nodes
touch index.txt
echo "10" > serial
openssl ca -gencrl -config ./openssl.cnf -out crl.pem
fi

View File

@@ -1,36 +0,0 @@
#!/bin/bash
# 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.
# This gets zipped and run on the cloudpipe-managed OpenVPN server
NAME=$1
SUBJ=$2
mkdir -p projects/$NAME
cd projects/$NAME
# generate a server priv key
openssl genrsa -out server.key 2048
# generate a server CSR
openssl req -new -key server.key -out server.csr -batch -subj "$SUBJ"
novauid=`getent passwd nova | awk -F: '{print $3}'`
if [ ! -z "${novauid}" ] && [ "`id -u`" != "${novauid}" ]; then
sudo chown -R nova:nogroup .
fi

View File

@@ -1,90 +0,0 @@
# 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.
#
# OpenSSL configuration file.
#
# Establish working directory.
dir = .
[ ca ]
default_ca = CA_default
[ CA_default ]
serial = $dir/serial
database = $dir/index.txt
new_certs_dir = $dir/newcerts
certificate = $dir/cacert.pem
private_key = $dir/private/cakey.pem
unique_subject = no
default_crl_days = 365
default_days = 365
default_md = md5
preserve = no
email_in_dn = no
nameopt = default_ca
certopt = default_ca
policy = policy_match
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ]
default_bits = 1024 # Size of keys
default_keyfile = key.pem # name of generated keys
default_md = md5 # message digest algorithm
string_mask = nombstr # permitted characters
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
# Variable name Prompt string
#---------------------- ----------------------------------
0.organizationName = Organization Name (company)
organizationalUnitName = Organizational Unit Name (department, division)
emailAddress = Email Address
emailAddress_max = 40
localityName = Locality Name (city, district)
stateOrProvinceName = State or Province Name (full name)
countryName = Country Name (2 letter code)
countryName_min = 2
countryName_max = 2
commonName = Common Name (hostname, IP, or your name)
commonName_max = 64
# Default values for the above, for consistency and less typing.
# Variable name Value
#------------------------------ ------------------------------
0.organizationName_default = NOVA %USERNAME%
localityName_default = Mountain View
stateOrProvinceName_default = California
countryName_default = US
[ v3_ca ]
basicConstraints = CA:TRUE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer:always
[ v3_req ]
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash

View File

@@ -1 +0,0 @@
*

1
CA/reqs/.gitignore vendored
View File

@@ -1 +0,0 @@
*

View File

View File

@@ -1,7 +1,7 @@
include HACKING LICENSE run_tests.py run_tests.sh include HACKING LICENSE run_tests.py run_tests.sh
include README builddeb.sh exercise_rsapi.py include README builddeb.sh exercise_rsapi.py
include ChangeLog MANIFEST.in pylintrc Authors include ChangeLog MANIFEST.in pylintrc Authors
graft CA graft nova/CA
graft doc graft doc
graft smoketests graft smoketests
graft tools graft tools

View File

@@ -41,6 +41,7 @@ from nova.compute import power_state
from nova.api.ec2 import cloud from nova.api.ec2 import cloud
from nova.api.ec2 import ec2utils from nova.api.ec2 import ec2utils
from nova.image import local from nova.image import local
from nova.exception import NotFound
FLAGS = flags.FLAGS FLAGS = flags.FLAGS
@@ -71,7 +72,8 @@ class CloudTestCase(test.TestCase):
host = self.network.get_network_host(self.context.elevated()) host = self.network.get_network_host(self.context.elevated())
def fake_show(meh, context, id): def fake_show(meh, context, id):
return {'id': 1, 'properties': {'kernel_id': 1, 'ramdisk_id': 1}} return {'id': 1, 'properties': {'kernel_id': 1, 'ramdisk_id': 1,
'type': 'machine'}}
self.stubs.Set(local.LocalImageService, 'show', fake_show) self.stubs.Set(local.LocalImageService, 'show', fake_show)
self.stubs.Set(local.LocalImageService, 'show_by_name', fake_show) self.stubs.Set(local.LocalImageService, 'show_by_name', fake_show)
@@ -216,6 +218,35 @@ class CloudTestCase(test.TestCase):
db.service_destroy(self.context, comp1['id']) db.service_destroy(self.context, comp1['id'])
db.service_destroy(self.context, comp2['id']) db.service_destroy(self.context, comp2['id'])
def test_describe_images(self):
describe_images = self.cloud.describe_images
def fake_detail(meh, context):
return [{'id': 1, 'properties': {'kernel_id': 1, 'ramdisk_id': 1,
'type': 'machine'}}]
def fake_show_none(meh, context, id):
raise NotFound
self.stubs.Set(local.LocalImageService, 'detail', fake_detail)
# list all
result1 = describe_images(self.context)
result1 = result1['imagesSet'][0]
self.assertEqual(result1['imageId'], 'ami-00000001')
# provided a valid image_id
result2 = describe_images(self.context, ['ami-00000001'])
self.assertEqual(1, len(result2['imagesSet']))
# provide more than 1 valid image_id
result3 = describe_images(self.context, ['ami-00000001',
'ami-00000002'])
self.assertEqual(2, len(result3['imagesSet']))
# provide an non-existing image_id
self.stubs.UnsetAll()
self.stubs.Set(local.LocalImageService, 'show', fake_show_none)
self.stubs.Set(local.LocalImageService, 'show_by_name', fake_show_none)
self.assertRaises(NotFound, describe_images,
self.context, ['ami-fake'])
def test_console_output(self): def test_console_output(self):
instance_type = FLAGS.default_instance_type instance_type = FLAGS.default_instance_type
max_count = 1 max_count = 1

View File

@@ -355,24 +355,25 @@ class Controller(object):
if type(result) is dict: if type(result) is dict:
content_type = req.best_match_content_type() content_type = req.best_match_content_type()
body = self._serialize(result, content_type) default_xmlns = self.get_default_xmlns(req)
body = self._serialize(result, content_type, default_xmlns)
response = webob.Response() response = webob.Response()
response.headers["Content-Type"] = content_type response.headers["Content-Type"] = content_type
response.body = body response.body = body
return response return response
else: else:
return result return result
def _serialize(self, data, content_type): def _serialize(self, data, content_type, default_xmlns):
""" """
Serialize the given dict to the provided content_type. Serialize the given dict to the provided content_type.
Uses self._serialization_metadata if it exists, which is a dict mapping Uses self._serialization_metadata if it exists, which is a dict mapping
MIME types to information needed to serialize to that type. MIME types to information needed to serialize to that type.
""" """
_metadata = getattr(type(self), "_serialization_metadata", {}) _metadata = getattr(type(self), "_serialization_metadata", {})
serializer = Serializer(_metadata)
serializer = Serializer(_metadata, default_xmlns)
try: try:
return serializer.serialize(data, content_type) return serializer.serialize(data, content_type)
except exception.InvalidContentType: except exception.InvalidContentType:
@@ -388,19 +389,24 @@ class Controller(object):
serializer = Serializer(_metadata) serializer = Serializer(_metadata)
return serializer.deserialize(data, content_type) return serializer.deserialize(data, content_type)
def get_default_xmlns(self, req):
"""Provide the XML namespace to use if none is otherwise specified."""
return None
class Serializer(object): class Serializer(object):
""" """
Serializes and deserializes dictionaries to certain MIME types. Serializes and deserializes dictionaries to certain MIME types.
""" """
def __init__(self, metadata=None): def __init__(self, metadata=None, default_xmlns=None):
""" """
Create a serializer based on the given WSGI environment. Create a serializer based on the given WSGI environment.
'metadata' is an optional dict mapping MIME types to information 'metadata' is an optional dict mapping MIME types to information
needed to serialize a dictionary to that type. needed to serialize a dictionary to that type.
""" """
self.metadata = metadata or {} self.metadata = metadata or {}
self.default_xmlns = default_xmlns
def _get_serialize_handler(self, content_type): def _get_serialize_handler(self, content_type):
handlers = { handlers = {
@@ -478,11 +484,23 @@ class Serializer(object):
root_key = data.keys()[0] root_key = data.keys()[0]
doc = minidom.Document() doc = minidom.Document()
node = self._to_xml_node(doc, metadata, root_key, data[root_key]) node = self._to_xml_node(doc, metadata, root_key, data[root_key])
xmlns = node.getAttribute('xmlns')
if not xmlns and self.default_xmlns:
node.setAttribute('xmlns', self.default_xmlns)
return node.toprettyxml(indent=' ') return node.toprettyxml(indent=' ')
def _to_xml_node(self, doc, metadata, nodename, data): def _to_xml_node(self, doc, metadata, nodename, data):
"""Recursive method to convert data members to XML nodes.""" """Recursive method to convert data members to XML nodes."""
result = doc.createElement(nodename) result = doc.createElement(nodename)
# Set the xml namespace if one is specified
# TODO(justinsb): We could also use prefixes on the keys
xmlns = metadata.get('xmlns', None)
if xmlns:
result.setAttribute('xmlns', xmlns)
if type(data) is list: if type(data) is list:
singular = metadata.get('plurals', {}).get(nodename, None) singular = metadata.get('plurals', {}).get(nodename, None)
if singular is None: if singular is None:
@@ -532,6 +550,7 @@ def paste_config_file(basename):
""" """
configfiles = [basename, configfiles = [basename,
os.path.join(FLAGS.state_path, 'etc', 'nova', basename),
os.path.join(FLAGS.state_path, 'etc', basename), os.path.join(FLAGS.state_path, 'etc', basename),
os.path.join(FLAGS.state_path, basename), os.path.join(FLAGS.state_path, basename),
'/etc/nova/%s' % basename] '/etc/nova/%s' % basename]

View File

@@ -16,6 +16,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import glob
import os import os
import subprocess import subprocess
import sys import sys
@@ -86,6 +87,19 @@ try:
except: except:
pass pass
def find_data_files(destdir, srcdir):
package_data = []
files = []
for d in glob.glob('%s/*' % (srcdir, )):
if os.path.isdir(d):
package_data += find_data_files(
os.path.join(destdir, os.path.basename(d)), d)
else:
files += [d]
package_data += [(destdir, files)]
return package_data
DistUtilsExtra.auto.setup(name='nova', DistUtilsExtra.auto.setup(name='nova',
version=version.canonical_version_string(), version=version.canonical_version_string(),
description='cloud computing fabric controller', description='cloud computing fabric controller',
@@ -96,6 +110,7 @@ DistUtilsExtra.auto.setup(name='nova',
packages=find_packages(exclude=['bin', 'smoketests']), packages=find_packages(exclude=['bin', 'smoketests']),
include_package_data=True, include_package_data=True,
test_suite='nose.collector', test_suite='nose.collector',
data_files=find_data_files('share/nova', 'tools'),
scripts=['bin/nova-ajax-console-proxy', scripts=['bin/nova-ajax-console-proxy',
'bin/nova-api', 'bin/nova-api',
'bin/nova-compute', 'bin/nova-compute',