fixed more conflicts
This commit is contained in:
		
							
								
								
									
										1
									
								
								Authors
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								Authors
									
									
									
									
									
								
							@@ -27,6 +27,7 @@ Rick Clark <rick@openstack.org>
 | 
			
		||||
Ryan Lucio <rlucio@internap.com>
 | 
			
		||||
Sandy Walsh <sandy.walsh@rackspace.com>
 | 
			
		||||
Soren Hansen <soren.hansen@rackspace.com>
 | 
			
		||||
Thierry Carrez <thierry@openstack.org>
 | 
			
		||||
Todd Willey <todd@ansolabs.com>
 | 
			
		||||
Trey Morris <trey.morris@rackspace.com>
 | 
			
		||||
Vishvananda Ishaya <vishvananda@gmail.com>
 | 
			
		||||
 
 | 
			
		||||
@@ -16,16 +16,24 @@
 | 
			
		||||
#    License for the specific language governing permissions and limitations
 | 
			
		||||
#    under the License.
 | 
			
		||||
 | 
			
		||||
# ARG is the id of the user
 | 
			
		||||
export SUBJ="/C=US/ST=California/L=MountainView/O=AnsoLabs/OU=NovaDev/CN=customer-intCA-$1"
 | 
			
		||||
mkdir INTER/$1
 | 
			
		||||
cd INTER/$1
 | 
			
		||||
# $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%/$1/g 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
 | 
			
		||||
openssl genrsa -out private/cakey.pem 1024 -config ./openssl.cnf -batch -nodes
 | 
			
		||||
openssl req -new -sha2 -key private/cakey.pem -out ../../reqs/inter$1.csr -batch -subj "$SUBJ"
 | 
			
		||||
cd ../../
 | 
			
		||||
openssl ca -extensions v3_ca -days 365 -out INTER/$1/cacert.pem -in reqs/inter$1.csr -config openssl.cnf -batch
 | 
			
		||||
# 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
 | 
			
		||||
 
 | 
			
		||||
@@ -25,4 +25,5 @@ else
 | 
			
		||||
    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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										36
									
								
								CA/genvpn.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										36
									
								
								CA/genvpn.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
#!/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
 | 
			
		||||
@@ -24,7 +24,6 @@ dir			= .
 | 
			
		||||
 | 
			
		||||
[ ca ]
 | 
			
		||||
default_ca		= CA_default
 | 
			
		||||
unique_subject		= no
 | 
			
		||||
 | 
			
		||||
[ CA_default ]
 | 
			
		||||
serial			= $dir/serial
 | 
			
		||||
@@ -32,6 +31,8 @@ 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
 | 
			
		||||
 
 | 
			
		||||
@@ -72,6 +72,7 @@ if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
 | 
			
		||||
gettext.install('nova', unicode=1)
 | 
			
		||||
 | 
			
		||||
from nova import context
 | 
			
		||||
from nova import crypto
 | 
			
		||||
from nova import db
 | 
			
		||||
from nova import exception
 | 
			
		||||
from nova import flags
 | 
			
		||||
@@ -96,47 +97,43 @@ class VpnCommands(object):
 | 
			
		||||
        self.manager = manager.AuthManager()
 | 
			
		||||
        self.pipe = pipelib.CloudPipe()
 | 
			
		||||
 | 
			
		||||
    def list(self):
 | 
			
		||||
        """Print a listing of the VPNs for all projects."""
 | 
			
		||||
    def list(self, project=None):
 | 
			
		||||
        """Print a listing of the VPN data for one or all projects.
 | 
			
		||||
 | 
			
		||||
        args: [project=all]"""
 | 
			
		||||
        print "%-12s\t" % 'project',
 | 
			
		||||
        print "%-20s\t" % 'ip:port',
 | 
			
		||||
        print "%-20s\t" % 'private_ip',
 | 
			
		||||
        print "%s" % 'state'
 | 
			
		||||
        for project in self.manager.get_projects():
 | 
			
		||||
        if project:
 | 
			
		||||
            projects = [self.manager.get_project(project)]
 | 
			
		||||
        else:
 | 
			
		||||
            projects = self.manager.get_projects()
 | 
			
		||||
            # NOTE(vish): This hits the database a lot.  We could optimize
 | 
			
		||||
            #             by getting all networks in one query and all vpns
 | 
			
		||||
            #             in aother query, then doing lookups by project
 | 
			
		||||
        for project in projects:
 | 
			
		||||
            print "%-12s\t" % project.name,
 | 
			
		||||
 | 
			
		||||
            try:
 | 
			
		||||
                s = "%s:%s" % (project.vpn_ip, project.vpn_port)
 | 
			
		||||
            except exception.NotFound:
 | 
			
		||||
                s = "None"
 | 
			
		||||
            print "%-20s\t" % s,
 | 
			
		||||
 | 
			
		||||
            vpn = self._vpn_for(project.id)
 | 
			
		||||
            ipport = "%s:%s" % (project.vpn_ip, project.vpn_port)
 | 
			
		||||
            print "%-20s\t" % ipport,
 | 
			
		||||
            ctxt = context.get_admin_context()
 | 
			
		||||
            vpn = db.instance_get_project_vpn(ctxt, project.id)
 | 
			
		||||
            if vpn:
 | 
			
		||||
                command = "ping -c1 -w1 %s > /dev/null; echo $?"
 | 
			
		||||
                out, _err = utils.execute(command % vpn['private_dns_name'],
 | 
			
		||||
                                          check_exit_code=False)
 | 
			
		||||
                if out.strip() == '0':
 | 
			
		||||
                    net = 'up'
 | 
			
		||||
                else:
 | 
			
		||||
                    net = 'down'
 | 
			
		||||
                print vpn['private_dns_name'],
 | 
			
		||||
                print vpn['node_name'],
 | 
			
		||||
                print vpn['instance_id'],
 | 
			
		||||
                address = None
 | 
			
		||||
                state = 'down'
 | 
			
		||||
                if vpn.get('fixed_ip', None):
 | 
			
		||||
                    address = vpn['fixed_ip']['address']
 | 
			
		||||
                if project.vpn_ip and utils.vpn_ping(project.vpn_ip,
 | 
			
		||||
                                                     project.vpn_port):
 | 
			
		||||
                    state = 'up'
 | 
			
		||||
                print address,
 | 
			
		||||
                print vpn['host'],
 | 
			
		||||
                print vpn['ec2_id'],
 | 
			
		||||
                print vpn['state_description'],
 | 
			
		||||
                print net
 | 
			
		||||
 | 
			
		||||
                print state
 | 
			
		||||
            else:
 | 
			
		||||
                print None
 | 
			
		||||
 | 
			
		||||
    def _vpn_for(self, project_id):
 | 
			
		||||
        """Get the VPN instance for a project ID."""
 | 
			
		||||
        for instance in db.instance_get_all(context.get_admin_context()):
 | 
			
		||||
            if (instance['image_id'] == FLAGS.vpn_image_id
 | 
			
		||||
                and not instance['state_description'] in
 | 
			
		||||
                    ['shutting_down', 'shutdown']
 | 
			
		||||
                and instance['project_id'] == project_id):
 | 
			
		||||
                return instance
 | 
			
		||||
 | 
			
		||||
    def spawn(self):
 | 
			
		||||
        """Run all VPNs."""
 | 
			
		||||
        for p in reversed(self.manager.get_projects()):
 | 
			
		||||
@@ -149,6 +146,21 @@ class VpnCommands(object):
 | 
			
		||||
        """Start the VPN for a given project."""
 | 
			
		||||
        self.pipe.launch_vpn_instance(project_id)
 | 
			
		||||
 | 
			
		||||
    def change(self, project_id, ip, port):
 | 
			
		||||
        """Change the ip and port for a vpn.
 | 
			
		||||
 | 
			
		||||
        args: project, ip, port"""
 | 
			
		||||
        project = self.manager.get_project(project_id)
 | 
			
		||||
        if not project:
 | 
			
		||||
            print 'No project %s' % (project_id)
 | 
			
		||||
            return
 | 
			
		||||
        admin = context.get_admin_context()
 | 
			
		||||
        network_ref = db.project_get_network(admin, project_id)
 | 
			
		||||
        db.network_update(admin,
 | 
			
		||||
                          network_ref['id'],
 | 
			
		||||
                          {'vpn_public_address': ip,
 | 
			
		||||
                           'vpn_public_port': int(port)})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ShellCommands(object):
 | 
			
		||||
    def bpython(self):
 | 
			
		||||
@@ -295,6 +307,14 @@ class UserCommands(object):
 | 
			
		||||
            is_admin = False
 | 
			
		||||
        self.manager.modify_user(name, access_key, secret_key, is_admin)
 | 
			
		||||
 | 
			
		||||
    def revoke(self, user_id, project_id=None):
 | 
			
		||||
        """revoke certs for a user
 | 
			
		||||
        arguments: user_id [project_id]"""
 | 
			
		||||
        if project_id:
 | 
			
		||||
            crypto.revoke_certs_by_user_and_project(user_id, project_id)
 | 
			
		||||
        else:
 | 
			
		||||
            crypto.revoke_certs_by_user(user_id)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ProjectCommands(object):
 | 
			
		||||
    """Class for managing projects."""
 | 
			
		||||
 
 | 
			
		||||
@@ -64,12 +64,9 @@ flags.DEFINE_string('credential_key_file', 'pk.pem',
 | 
			
		||||
                    'Filename of private key in credentials zip')
 | 
			
		||||
flags.DEFINE_string('credential_cert_file', 'cert.pem',
 | 
			
		||||
                    'Filename of certificate in credentials zip')
 | 
			
		||||
flags.DEFINE_string('credential_rc_file', 'novarc',
 | 
			
		||||
                    'Filename of rc in credentials zip')
 | 
			
		||||
flags.DEFINE_string('credential_cert_subject',
 | 
			
		||||
                    '/C=US/ST=California/L=MountainView/O=AnsoLabs/'
 | 
			
		||||
                    'OU=NovaDev/CN=%s-%s',
 | 
			
		||||
                    'Subject for certificate for users')
 | 
			
		||||
flags.DEFINE_string('credential_rc_file', '%src',
 | 
			
		||||
                    'Filename of rc in credentials zip, %s will be '
 | 
			
		||||
                    'replaced by name of the region (nova by default)')
 | 
			
		||||
flags.DEFINE_string('auth_driver', 'nova.auth.dbdriver.DbDriver',
 | 
			
		||||
                    'Driver that auth manager uses')
 | 
			
		||||
 | 
			
		||||
@@ -543,11 +540,10 @@ class AuthManager(object):
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        network_ref = db.project_get_network(context.get_admin_context(),
 | 
			
		||||
                                             Project.safe_id(project))
 | 
			
		||||
                                             Project.safe_id(project), False)
 | 
			
		||||
 | 
			
		||||
        if not network_ref['vpn_public_port']:
 | 
			
		||||
            raise exception.NotFound(_('project network data has not '
 | 
			
		||||
                                       'been set'))
 | 
			
		||||
        if not network_ref:
 | 
			
		||||
            return (None, None)
 | 
			
		||||
        return (network_ref['vpn_public_address'],
 | 
			
		||||
                network_ref['vpn_public_port'])
 | 
			
		||||
 | 
			
		||||
@@ -629,27 +625,37 @@ class AuthManager(object):
 | 
			
		||||
    def get_key_pairs(context):
 | 
			
		||||
        return db.key_pair_get_all_by_user(context.elevated(), context.user_id)
 | 
			
		||||
 | 
			
		||||
    def get_credentials(self, user, project=None):
 | 
			
		||||
    def get_credentials(self, user, project=None, use_dmz=True):
 | 
			
		||||
        """Get credential zip for user in project"""
 | 
			
		||||
        if not isinstance(user, User):
 | 
			
		||||
            user = self.get_user(user)
 | 
			
		||||
        if project is None:
 | 
			
		||||
            project = user.id
 | 
			
		||||
        pid = Project.safe_id(project)
 | 
			
		||||
        rc = self.__generate_rc(user.access, user.secret, pid)
 | 
			
		||||
        private_key, signed_cert = self._generate_x509_cert(user.id, pid)
 | 
			
		||||
        private_key, signed_cert = crypto.generate_x509_cert(user.id, pid)
 | 
			
		||||
 | 
			
		||||
        tmpdir = tempfile.mkdtemp()
 | 
			
		||||
        zf = os.path.join(tmpdir, "temp.zip")
 | 
			
		||||
        zippy = zipfile.ZipFile(zf, 'w')
 | 
			
		||||
        zippy.writestr(FLAGS.credential_rc_file, rc)
 | 
			
		||||
        if use_dmz and FLAGS.region_list:
 | 
			
		||||
            regions = {}
 | 
			
		||||
            for item in FLAGS.region_list:
 | 
			
		||||
                region, _sep, region_host = item.partition("=")
 | 
			
		||||
                regions[region] = region_host
 | 
			
		||||
        else:
 | 
			
		||||
            regions = {'nova': FLAGS.cc_host}
 | 
			
		||||
        for region, host in regions.iteritems():
 | 
			
		||||
            rc = self.__generate_rc(user.access,
 | 
			
		||||
                                    user.secret,
 | 
			
		||||
                                    pid,
 | 
			
		||||
                                    use_dmz,
 | 
			
		||||
                                    host)
 | 
			
		||||
            zippy.writestr(FLAGS.credential_rc_file % region, rc)
 | 
			
		||||
 | 
			
		||||
        zippy.writestr(FLAGS.credential_key_file, private_key)
 | 
			
		||||
        zippy.writestr(FLAGS.credential_cert_file, signed_cert)
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
            (vpn_ip, vpn_port) = self.get_project_vpn_data(project)
 | 
			
		||||
        except exception.NotFound:
 | 
			
		||||
            vpn_ip = None
 | 
			
		||||
        (vpn_ip, vpn_port) = self.get_project_vpn_data(project)
 | 
			
		||||
        if vpn_ip:
 | 
			
		||||
            configfile = open(FLAGS.vpn_client_template, "r")
 | 
			
		||||
            s = string.Template(configfile.read())
 | 
			
		||||
@@ -662,7 +668,7 @@ class AuthManager(object):
 | 
			
		||||
        else:
 | 
			
		||||
            logging.warn(_("No vpn data for project %s"), pid)
 | 
			
		||||
 | 
			
		||||
        zippy.writestr(FLAGS.ca_file, crypto.fetch_ca(user.id))
 | 
			
		||||
        zippy.writestr(FLAGS.ca_file, crypto.fetch_ca(pid))
 | 
			
		||||
        zippy.close()
 | 
			
		||||
        with open(zf, 'rb') as f:
 | 
			
		||||
            read_buffer = f.read()
 | 
			
		||||
@@ -670,38 +676,38 @@ class AuthManager(object):
 | 
			
		||||
        shutil.rmtree(tmpdir)
 | 
			
		||||
        return read_buffer
 | 
			
		||||
 | 
			
		||||
    def get_environment_rc(self, user, project=None):
 | 
			
		||||
    def get_environment_rc(self, user, project=None, use_dmz=True):
 | 
			
		||||
        """Get credential zip for user in project"""
 | 
			
		||||
        if not isinstance(user, User):
 | 
			
		||||
            user = self.get_user(user)
 | 
			
		||||
        if project is None:
 | 
			
		||||
            project = user.id
 | 
			
		||||
        pid = Project.safe_id(project)
 | 
			
		||||
        return self.__generate_rc(user.access, user.secret, pid)
 | 
			
		||||
        return self.__generate_rc(user.access, user.secret, pid, use_dmz)
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def __generate_rc(access, secret, pid):
 | 
			
		||||
    def __generate_rc(access, secret, pid, use_dmz=True, host=None):
 | 
			
		||||
        """Generate rc file for user"""
 | 
			
		||||
        if use_dmz:
 | 
			
		||||
            cc_host = FLAGS.cc_dmz
 | 
			
		||||
        else:
 | 
			
		||||
            cc_host = FLAGS.cc_host
 | 
			
		||||
        # NOTE(vish): Always use the dmz since it is used from inside the
 | 
			
		||||
        #             instance
 | 
			
		||||
        s3_host = FLAGS.s3_dmz
 | 
			
		||||
        if host:
 | 
			
		||||
            s3_host = host
 | 
			
		||||
            cc_host = host
 | 
			
		||||
        rc = open(FLAGS.credentials_template).read()
 | 
			
		||||
        rc = rc % {'access': access,
 | 
			
		||||
                   'project': pid,
 | 
			
		||||
                   'secret': secret,
 | 
			
		||||
                   'ec2': FLAGS.ec2_url,
 | 
			
		||||
                   's3': 'http://%s:%s' % (FLAGS.s3_host, FLAGS.s3_port),
 | 
			
		||||
                   'ec2': '%s://%s:%s%s' % (FLAGS.ec2_prefix,
 | 
			
		||||
                                            cc_host,
 | 
			
		||||
                                            FLAGS.cc_port,
 | 
			
		||||
                                            FLAGS.ec2_suffix),
 | 
			
		||||
                   's3': 'http://%s:%s' % (s3_host, FLAGS.s3_port),
 | 
			
		||||
                   'nova': FLAGS.ca_file,
 | 
			
		||||
                   'cert': FLAGS.credential_cert_file,
 | 
			
		||||
                   'key': FLAGS.credential_key_file}
 | 
			
		||||
        return rc
 | 
			
		||||
 | 
			
		||||
    def _generate_x509_cert(self, uid, pid):
 | 
			
		||||
        """Generate x509 cert for user"""
 | 
			
		||||
        (private_key, csr) = crypto.generate_x509_cert(
 | 
			
		||||
                self.__cert_subject(uid))
 | 
			
		||||
        # TODO(joshua): This should be async call back to the cloud controller
 | 
			
		||||
        signed_cert = crypto.sign_csr(csr, pid)
 | 
			
		||||
        return (private_key, signed_cert)
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def __cert_subject(uid):
 | 
			
		||||
        """Helper to generate cert subject"""
 | 
			
		||||
        return FLAGS.credential_cert_subject % (uid, utils.isotime())
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										59
									
								
								nova/fakememcache.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								nova/fakememcache.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
			
		||||
# 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.
 | 
			
		||||
 | 
			
		||||
"""Super simple fake memcache client."""
 | 
			
		||||
 | 
			
		||||
import utils
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Client(object):
 | 
			
		||||
    """Replicates a tiny subset of memcached client interface."""
 | 
			
		||||
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
        """Ignores the passed in args"""
 | 
			
		||||
        self.cache = {}
 | 
			
		||||
 | 
			
		||||
    def get(self, key):
 | 
			
		||||
        """Retrieves the value for a key or None."""
 | 
			
		||||
        (timeout, value) = self.cache.get(key, (0, None))
 | 
			
		||||
        if timeout == 0 or utils.utcnow_ts() < timeout:
 | 
			
		||||
            return value
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
    def set(self, key, value, time=0, min_compress_len=0):
 | 
			
		||||
        """Sets the value for a key."""
 | 
			
		||||
        timeout = 0
 | 
			
		||||
        if time != 0:
 | 
			
		||||
            timeout = utils.utcnow_ts() + time
 | 
			
		||||
        self.cache[key] = (timeout, value)
 | 
			
		||||
        return True
 | 
			
		||||
 | 
			
		||||
    def add(self, key, value, time=0, min_compress_len=0):
 | 
			
		||||
        """Sets the value for a key if it doesn't exist."""
 | 
			
		||||
        if not self.get(key) is None:
 | 
			
		||||
            return False
 | 
			
		||||
        return self.set(key, value, time, min_compress_len)
 | 
			
		||||
 | 
			
		||||
    def incr(self, key, delta=1):
 | 
			
		||||
        """Increments the value for a key."""
 | 
			
		||||
        value = self.get(key)
 | 
			
		||||
        if value is None:
 | 
			
		||||
            return None
 | 
			
		||||
        new_value = int(value) + delta
 | 
			
		||||
        self.cache[key] = (self.cache[key][0], str(new_value))
 | 
			
		||||
        return new_value
 | 
			
		||||
@@ -29,6 +29,8 @@ import sys
 | 
			
		||||
 | 
			
		||||
import gflags
 | 
			
		||||
 | 
			
		||||
from nova import utils
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class FlagValues(gflags.FlagValues):
 | 
			
		||||
    """Extension of gflags.FlagValues that allows undefined and runtime flags.
 | 
			
		||||
@@ -211,7 +213,8 @@ DEFINE_string('connection_type', 'libvirt', 'libvirt, xenapi or fake')
 | 
			
		||||
DEFINE_string('aws_access_key_id', 'admin', 'AWS Access ID')
 | 
			
		||||
DEFINE_string('aws_secret_access_key', 'admin', 'AWS Access Key')
 | 
			
		||||
DEFINE_integer('s3_port', 3333, 's3 port')
 | 
			
		||||
DEFINE_string('s3_host', '127.0.0.1', 's3 host')
 | 
			
		||||
DEFINE_string('s3_host', utils.get_my_ip(), 's3 host (for infrastructure)')
 | 
			
		||||
DEFINE_string('s3_dmz', utils.get_my_ip(), 's3 dmz ip (for instances)')
 | 
			
		||||
DEFINE_string('compute_topic', 'compute', 'the topic compute nodes listen on')
 | 
			
		||||
DEFINE_string('scheduler_topic', 'scheduler',
 | 
			
		||||
              'the topic scheduler nodes listen on')
 | 
			
		||||
@@ -230,8 +233,11 @@ DEFINE_string('rabbit_virtual_host', '/', 'rabbit virtual host')
 | 
			
		||||
DEFINE_integer('rabbit_retry_interval', 10, 'rabbit connection retry interval')
 | 
			
		||||
DEFINE_integer('rabbit_max_retries', 12, 'rabbit connection attempts')
 | 
			
		||||
DEFINE_string('control_exchange', 'nova', 'the main exchange to connect to')
 | 
			
		||||
DEFINE_string('ec2_url', 'http://127.0.0.1:8773/services/Cloud',
 | 
			
		||||
              'Url to ec2 api server')
 | 
			
		||||
DEFINE_string('ec2_prefix', 'http', 'prefix for ec2')
 | 
			
		||||
DEFINE_string('cc_host', utils.get_my_ip(), 'ip of api server')
 | 
			
		||||
DEFINE_string('cc_dmz', utils.get_my_ip(), 'internal ip of api server')
 | 
			
		||||
DEFINE_integer('cc_port', 8773, 'cloud controller port')
 | 
			
		||||
DEFINE_string('ec2_suffix', '/services/Cloud', 'suffix for ec2')
 | 
			
		||||
 | 
			
		||||
DEFINE_string('default_image', 'ami-11111',
 | 
			
		||||
              'default image to use, testing only')
 | 
			
		||||
@@ -241,10 +247,10 @@ DEFINE_string('null_kernel', 'nokernel',
 | 
			
		||||
              'kernel image that indicates not to use a kernel,'
 | 
			
		||||
              ' but to use a raw disk image instead')
 | 
			
		||||
 | 
			
		||||
DEFINE_string('vpn_image_id', 'ami-CLOUDPIPE', 'AMI for cloudpipe vpn server')
 | 
			
		||||
DEFINE_string('vpn_image_id', 'ami-cloudpipe', 'AMI for cloudpipe vpn server')
 | 
			
		||||
DEFINE_string('vpn_key_suffix',
 | 
			
		||||
              '-key',
 | 
			
		||||
              'Suffix to add to project name for vpn key')
 | 
			
		||||
              '-vpn',
 | 
			
		||||
              'Suffix to add to project name for vpn key and secgroups')
 | 
			
		||||
 | 
			
		||||
DEFINE_integer('auth_token_ttl', 3600, 'Seconds for auth tokens to linger')
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -208,17 +208,13 @@ class AuthManagerTestCase(object):
 | 
			
		||||
        #             so it probably belongs in crypto_unittest
 | 
			
		||||
        #             but I'm leaving it where I found it.
 | 
			
		||||
        with user_and_project_generator(self.manager) as (user, project):
 | 
			
		||||
            # NOTE(todd): Should mention why we must setup controller first
 | 
			
		||||
            #             (somebody please clue me in)
 | 
			
		||||
            cloud_controller = cloud.CloudController()
 | 
			
		||||
            cloud_controller.setup()
 | 
			
		||||
            _key, cert_str = self.manager._generate_x509_cert('test1',
 | 
			
		||||
                                                              'testproj')
 | 
			
		||||
            # NOTE(vish): Setup runs genroot.sh if it hasn't been run
 | 
			
		||||
            cloud.CloudController().setup()
 | 
			
		||||
            _key, cert_str = crypto.generate_x509_cert(user.id, project.id)
 | 
			
		||||
            logging.debug(cert_str)
 | 
			
		||||
 | 
			
		||||
            # Need to verify that it's signed by the right intermediate CA
 | 
			
		||||
            full_chain = crypto.fetch_ca(project_id='testproj', chain=True)
 | 
			
		||||
            int_cert = crypto.fetch_ca(project_id='testproj', chain=False)
 | 
			
		||||
            full_chain = crypto.fetch_ca(project_id=project.id, chain=True)
 | 
			
		||||
            int_cert = crypto.fetch_ca(project_id=project.id, chain=False)
 | 
			
		||||
            cloud_cert = crypto.fetch_ca()
 | 
			
		||||
            logging.debug("CA chain:\n\n =====\n%s\n\n=====" % full_chain)
 | 
			
		||||
            signed_cert = X509.load_cert_string(cert_str)
 | 
			
		||||
@@ -227,7 +223,8 @@ class AuthManagerTestCase(object):
 | 
			
		||||
            cloud_cert = X509.load_cert_string(cloud_cert)
 | 
			
		||||
            self.assertTrue(signed_cert.verify(chain_cert.get_pubkey()))
 | 
			
		||||
            self.assertTrue(signed_cert.verify(int_cert.get_pubkey()))
 | 
			
		||||
            if not FLAGS.use_intermediate_ca:
 | 
			
		||||
 | 
			
		||||
            if not FLAGS.use_project_ca:
 | 
			
		||||
                self.assertTrue(signed_cert.verify(cloud_cert.get_pubkey()))
 | 
			
		||||
            else:
 | 
			
		||||
                self.assertFalse(signed_cert.verify(cloud_cert.get_pubkey()))
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										86
									
								
								nova/tests/middleware_unittest.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								nova/tests/middleware_unittest.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,86 @@
 | 
			
		||||
# 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.
 | 
			
		||||
 | 
			
		||||
import datetime
 | 
			
		||||
import webob
 | 
			
		||||
import webob.dec
 | 
			
		||||
import webob.exc
 | 
			
		||||
 | 
			
		||||
from nova.api import ec2
 | 
			
		||||
from nova import flags
 | 
			
		||||
from nova import test
 | 
			
		||||
from nova import utils
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
FLAGS = flags.FLAGS
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@webob.dec.wsgify
 | 
			
		||||
def conditional_forbid(req):
 | 
			
		||||
    """Helper wsgi app returns 403 if param 'die' is 1."""
 | 
			
		||||
    if 'die' in req.params and req.params['die'] == '1':
 | 
			
		||||
        raise webob.exc.HTTPForbidden()
 | 
			
		||||
    return 'OK'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class LockoutTestCase(test.TrialTestCase):
 | 
			
		||||
    """Test case for the Lockout middleware."""
 | 
			
		||||
    def setUp(self):  # pylint: disable-msg=C0103
 | 
			
		||||
        super(LockoutTestCase, self).setUp()
 | 
			
		||||
        utils.set_time_override()
 | 
			
		||||
        self.lockout = ec2.Lockout(conditional_forbid)
 | 
			
		||||
 | 
			
		||||
    def tearDown(self):  # pylint: disable-msg=C0103
 | 
			
		||||
        utils.clear_time_override()
 | 
			
		||||
        super(LockoutTestCase, self).tearDown()
 | 
			
		||||
 | 
			
		||||
    def _send_bad_attempts(self, access_key, num_attempts=1):
 | 
			
		||||
        """Fail x."""
 | 
			
		||||
        for i in xrange(num_attempts):
 | 
			
		||||
            req = webob.Request.blank('/?AWSAccessKeyId=%s&die=1' % access_key)
 | 
			
		||||
            self.assertEqual(req.get_response(self.lockout).status_int, 403)
 | 
			
		||||
 | 
			
		||||
    def _is_locked_out(self, access_key):
 | 
			
		||||
        """Sends a test request to see if key is locked out."""
 | 
			
		||||
        req = webob.Request.blank('/?AWSAccessKeyId=%s' % access_key)
 | 
			
		||||
        return (req.get_response(self.lockout).status_int == 403)
 | 
			
		||||
 | 
			
		||||
    def test_lockout(self):
 | 
			
		||||
        self._send_bad_attempts('test', FLAGS.lockout_attempts)
 | 
			
		||||
        self.assertTrue(self._is_locked_out('test'))
 | 
			
		||||
 | 
			
		||||
    def test_timeout(self):
 | 
			
		||||
        self._send_bad_attempts('test', FLAGS.lockout_attempts)
 | 
			
		||||
        self.assertTrue(self._is_locked_out('test'))
 | 
			
		||||
        utils.advance_time_seconds(FLAGS.lockout_minutes * 60)
 | 
			
		||||
        self.assertFalse(self._is_locked_out('test'))
 | 
			
		||||
 | 
			
		||||
    def test_multiple_keys(self):
 | 
			
		||||
        self._send_bad_attempts('test1', FLAGS.lockout_attempts)
 | 
			
		||||
        self.assertTrue(self._is_locked_out('test1'))
 | 
			
		||||
        self.assertFalse(self._is_locked_out('test2'))
 | 
			
		||||
        utils.advance_time_seconds(FLAGS.lockout_minutes * 60)
 | 
			
		||||
        self.assertFalse(self._is_locked_out('test1'))
 | 
			
		||||
        self.assertFalse(self._is_locked_out('test2'))
 | 
			
		||||
 | 
			
		||||
    def test_window_timeout(self):
 | 
			
		||||
        self._send_bad_attempts('test', FLAGS.lockout_attempts - 1)
 | 
			
		||||
        self.assertFalse(self._is_locked_out('test'))
 | 
			
		||||
        utils.advance_time_seconds(FLAGS.lockout_window * 60)
 | 
			
		||||
        self._send_bad_attempts('test', FLAGS.lockout_attempts - 1)
 | 
			
		||||
        self.assertFalse(self._is_locked_out('test'))
 | 
			
		||||
@@ -60,6 +60,7 @@ from nova.tests.auth_unittest import *
 | 
			
		||||
from nova.tests.cloud_unittest import *
 | 
			
		||||
from nova.tests.compute_unittest import *
 | 
			
		||||
from nova.tests.flags_unittest import *
 | 
			
		||||
from nova.tests.middleware_unittest import *
 | 
			
		||||
from nova.tests.misc_unittest import *
 | 
			
		||||
from nova.tests.network_unittest import *
 | 
			
		||||
#from nova.tests.objectstore_unittest import *
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user