summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/source/apache-httpd.rst12
-rw-r--r--keystone/catalog/backends/sql.py6
-rw-r--r--keystone/common/openssl.py36
-rw-r--r--keystone/common/sql/core.py1
-rw-r--r--keystone/common/sql/migrate_repo/versions/031_drop_credential_indexes.py40
-rw-r--r--keystone/token/backends/sql.py9
-rw-r--r--keystone/trust/backends/sql.py8
-rw-r--r--tests/test_sql_upgrade.py18
8 files changed, 107 insertions, 23 deletions
diff --git a/doc/source/apache-httpd.rst b/doc/source/apache-httpd.rst
index 41437780..5bc0dbe8 100644
--- a/doc/source/apache-httpd.rst
+++ b/doc/source/apache-httpd.rst
@@ -87,7 +87,17 @@ Putting it somewhere else requires you set up your SELinux policy accordingly.
Keystone Configuration
----------------------
-Make sure you use the ``SQL`` driver for ``tokens``, otherwise the tokens will not be shared between the processes of the Apache HTTPD server. To do that, in ``/etc/keystone/keystone.conf`` make sure you have set::
+Make sure you use either the ``SQL`` or the ``memcached`` driver for ``tokens``, otherwise the tokens will not be shared between the processes of the Apache HTTPD server.
+
+For ``SQL,`` in ``/etc/keystone/keystone.conf`` make sure you have set::
[token]
driver = keystone.token.backends.sql.Token
+
+For ``memcache,`` in ``/etc/keystone/keystone.conf`` make sure you have set::
+
+ [token]
+ driver = keystone.token.backends.memcache.Token
+
+In both cases, all servers that are storing tokens need a shared backend. This means either that both point
+to the same database server, or both point to a common memcached instance.
diff --git a/keystone/catalog/backends/sql.py b/keystone/catalog/backends/sql.py
index 718d7c53..d7b2123a 100644
--- a/keystone/catalog/backends/sql.py
+++ b/keystone/catalog/backends/sql.py
@@ -41,12 +41,12 @@ class Endpoint(sql.ModelBase, sql.DictBase):
'legacy_endpoint_id']
id = sql.Column(sql.String(64), primary_key=True)
legacy_endpoint_id = sql.Column(sql.String(64))
- interface = sql.Column(sql.String(8), primary_key=True)
- region = sql.Column('region', sql.String(255))
+ interface = sql.Column(sql.String(8), nullable=False)
+ region = sql.Column(sql.String(255))
service_id = sql.Column(sql.String(64),
sql.ForeignKey('service.id'),
nullable=False)
- url = sql.Column(sql.Text())
+ url = sql.Column(sql.Text(), nullable=False)
extra = sql.Column(sql.JsonBlob())
diff --git a/keystone/common/openssl.py b/keystone/common/openssl.py
index fa09e37c..90484505 100644
--- a/keystone/common/openssl.py
+++ b/keystone/common/openssl.py
@@ -51,6 +51,7 @@ class BaseCertificateConfigure(object):
self.request_file_name = os.path.join(self.conf_dir, "req.pem")
self.ssl_dictionary = {'conf_dir': self.conf_dir,
'ca_cert': conf_obj.ca_certs,
+ 'default_md': 'default',
'ssl_config': self.ssl_config_file_name,
'ca_private_key': conf_obj.ca_key,
'request_file': self.request_file_name,
@@ -60,6 +61,17 @@ class BaseCertificateConfigure(object):
'valid_days': int(conf_obj.valid_days),
'cert_subject': conf_obj.cert_subject,
'ca_password': conf_obj.ca_password}
+
+ try:
+ # OpenSSL 1.0 and newer support default_md = default, olders do not
+ openssl_ver = environment.subprocess.Popen(
+ ['openssl', 'version'],
+ stdout=environment.subprocess.PIPE).stdout.read()
+ if "OpenSSL 0." in openssl_ver:
+ self.ssl_dictionary['default_md'] = 'sha1'
+ except OSError:
+ LOG.warn('Failed to invoke ``openssl version``, '
+ 'assuming is v1.0 or newer')
self.ssl_dictionary.update(kwargs)
def _make_dirs(self, file_name):
@@ -198,7 +210,7 @@ new_certs_dir = $dir
serial = $dir/serial
database = $dir/index.txt
default_days = 365
-default_md = default # use public key default MD
+default_md = %(default_md)s
preserve = no
email_in_dn = no
nameopt = default_ca
@@ -218,35 +230,35 @@ emailAddress = optional
[ req ]
default_bits = 2048 # Size of keys
default_keyfile = key.pem # name of generated keys
-default_md = default # message digest algorithm
-string_mask = nombstr # permitted characters
+string_mask = utf8only # permitted characters
distinguished_name = req_distinguished_name
req_extensions = v3_req
+x509_extensions = v3_ca
[ req_distinguished_name ]
-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
+stateOrProvinceName = State or Province Name (full name)
+localityName = Locality Name (city, district)
+0.organizationName = Organization Name (company)
+organizationalUnitName = Organizational Unit Name (department, division)
commonName = Common Name (hostname, IP, or your name)
commonName_max = 64
+emailAddress = Email Address
+emailAddress_max = 64
[ v3_ca ]
basicConstraints = CA:TRUE
subjectKeyIdentifier = hash
-authorityKeyIdentifier = keyid:always,issuer:always
+authorityKeyIdentifier = keyid:always,issuer
[ v3_req ]
basicConstraints = CA:FALSE
-subjectKeyIdentifier = hash
+keyUsage = nonRepudiation, digitalSignature, keyEncipherment
[ usr_cert ]
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
-authorityKeyIdentifier = keyid:always,issuer:always
+authorityKeyIdentifier = keyid:always
"""
diff --git a/keystone/common/sql/core.py b/keystone/common/sql/core.py
index a2deb58b..67863588 100644
--- a/keystone/common/sql/core.py
+++ b/keystone/common/sql/core.py
@@ -45,6 +45,7 @@ ModelBase = declarative.declarative_base()
# For exporting to other modules
Column = sql.Column
+Index = sql.Index
String = sql.String
ForeignKey = sql.ForeignKey
DateTime = sql.DateTime
diff --git a/keystone/common/sql/migrate_repo/versions/031_drop_credential_indexes.py b/keystone/common/sql/migrate_repo/versions/031_drop_credential_indexes.py
new file mode 100644
index 00000000..89ca04f0
--- /dev/null
+++ b/keystone/common/sql/migrate_repo/versions/031_drop_credential_indexes.py
@@ -0,0 +1,40 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 OpenStack Foundation
+#
+# 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 sqlalchemy
+
+
+def upgrade(migrate_engine):
+ #This migration is relevant only for mysql because for all other
+ #migrate engines these indexes were successfully dropped.
+ if migrate_engine.name != 'mysql':
+ return
+ meta = sqlalchemy.MetaData(bind=migrate_engine)
+ table = sqlalchemy.Table('credential', meta, autoload=True)
+ for index in table.indexes:
+ index.drop()
+
+
+def downgrade(migrate_engine):
+ if migrate_engine.name != 'mysql':
+ return
+ meta = sqlalchemy.MetaData(bind=migrate_engine)
+ table = sqlalchemy.Table('credential', meta, autoload=True)
+ index = sqlalchemy.Index('user_id', table.c['user_id'])
+ index.create()
+ index = sqlalchemy.Index('credential_project_id_fkey',
+ table.c['project_id'])
+ index.create()
diff --git a/keystone/token/backends/sql.py b/keystone/token/backends/sql.py
index 0e8a916d..82eab651 100644
--- a/keystone/token/backends/sql.py
+++ b/keystone/token/backends/sql.py
@@ -17,7 +17,6 @@
import copy
import datetime
-
from keystone.common import sql
from keystone import exception
from keystone.openstack.common import timeutils
@@ -30,9 +29,13 @@ class TokenModel(sql.ModelBase, sql.DictBase):
id = sql.Column(sql.String(64), primary_key=True)
expires = sql.Column(sql.DateTime(), default=None)
extra = sql.Column(sql.JsonBlob())
- valid = sql.Column(sql.Boolean(), default=True)
+ valid = sql.Column(sql.Boolean(), default=True, nullable=False)
user_id = sql.Column(sql.String(64))
- trust_id = sql.Column(sql.String(64), nullable=True)
+ trust_id = sql.Column(sql.String(64))
+ __table_args__ = (
+ sql.Index('ix_token_expires', 'expires'),
+ sql.Index('ix_token_valid', 'valid')
+ )
class Token(sql.Base, token.Driver):
diff --git a/keystone/trust/backends/sql.py b/keystone/trust/backends/sql.py
index daa8e3f7..9e92ad71 100644
--- a/keystone/trust/backends/sql.py
+++ b/keystone/trust/backends/sql.py
@@ -26,11 +26,11 @@ class TrustModel(sql.ModelBase, sql.DictBase):
'project_id', 'impersonation', 'expires_at']
id = sql.Column(sql.String(64), primary_key=True)
#user id Of owner
- trustor_user_id = sql.Column(sql.String(64), unique=False, nullable=False,)
+ trustor_user_id = sql.Column(sql.String(64), nullable=False,)
#user_id of user allowed to consume this preauth
- trustee_user_id = sql.Column(sql.String(64), unique=False, nullable=False)
- project_id = sql.Column(sql.String(64), unique=False, nullable=True)
- impersonation = sql.Column(sql.Boolean)
+ trustee_user_id = sql.Column(sql.String(64), nullable=False)
+ project_id = sql.Column(sql.String(64))
+ impersonation = sql.Column(sql.Boolean, nullable=False)
deleted_at = sql.Column(sql.DateTime)
expires_at = sql.Column(sql.DateTime)
extra = sql.Column(sql.JsonBlob())
diff --git a/tests/test_sql_upgrade.py b/tests/test_sql_upgrade.py
index 5975fb9d..9540c4cd 100644
--- a/tests/test_sql_upgrade.py
+++ b/tests/test_sql_upgrade.py
@@ -1238,6 +1238,24 @@ class SqlUpgradeTests(SqlMigrateBase):
self.assertEqual(cred.user_id,
ec2_credential['user_id'])
+ def test_drop_credential_indexes(self):
+ self.upgrade(31)
+ table = sqlalchemy.Table('credential', self.metadata, autoload=True)
+ self.assertEqual(len(table.indexes), 0)
+
+ def test_downgrade_30(self):
+ self.upgrade(31)
+ self.downgrade(30)
+ table = sqlalchemy.Table('credential', self.metadata, autoload=True)
+ index_data = [(idx.name, idx.columns.keys())
+ for idx in table.indexes]
+ if self.engine.name == 'mysql':
+ self.assertIn(('user_id', ['user_id']), index_data)
+ self.assertIn(('credential_project_id_fkey', ['project_id']),
+ index_data)
+ else:
+ self.assertEqual(len(index_data), 0)
+
def populate_user_table(self, with_pass_enab=False,
with_pass_enab_domain=False):
# Populate the appropriate fields in the user