From 6f3c42c02f0fe1a1d48297fffb691d190e98cb8e Mon Sep 17 00:00:00 2001 From: Yogeshwar Srikrishnan Date: Tue, 28 Jun 2011 16:29:08 -0500 Subject: Initial changes to support multiple backends. --- .gitignore | 1 + bin/keystone | 1 - bin/keystone-manage | 10 +- etc/keystone.conf | 34 +- keystone/backends/__init__.py | 30 ++ keystone/backends/alterdb/__init__.py | 94 +++++ keystone/backends/alterdb/api/__init__.py | 1 + keystone/backends/alterdb/api/token.py | 61 +++ keystone/backends/alterdb/models.py | 85 ++++ keystone/backends/api.py | 47 +++ keystone/backends/models.py | 28 ++ keystone/backends/sqlalchemy/__init__.py | 95 +++++ keystone/backends/sqlalchemy/api/__init__.py | 1 + .../backends/sqlalchemy/api/endpoint_template.py | 185 +++++++++ keystone/backends/sqlalchemy/api/group.py | 170 ++++++++ keystone/backends/sqlalchemy/api/role.py | 174 +++++++++ keystone/backends/sqlalchemy/api/tenant.py | 203 ++++++++++ keystone/backends/sqlalchemy/api/tenant_group.py | 118 ++++++ keystone/backends/sqlalchemy/api/token.py | 61 +++ keystone/backends/sqlalchemy/api/user.py | 429 +++++++++++++++++++++ keystone/backends/sqlalchemy/models.py | 171 ++++++++ keystone/common/config.py | 28 +- keystone/db/__init__.py | 0 keystone/db/sqlalchemy/__init__.py | 78 ---- keystone/db/sqlalchemy/api/__init__.py | 1 - keystone/db/sqlalchemy/api/endpoint_template.py | 185 --------- keystone/db/sqlalchemy/api/group.py | 170 -------- keystone/db/sqlalchemy/api/role.py | 174 --------- keystone/db/sqlalchemy/api/tenant.py | 203 ---------- keystone/db/sqlalchemy/api/tenant_group.py | 118 ------ keystone/db/sqlalchemy/api/token.py | 61 --- keystone/db/sqlalchemy/api/user.py | 429 --------------------- keystone/db/sqlalchemy/models.py | 173 --------- keystone/logic/service.py | 5 +- keystone/server.py | 12 +- keystone/test/unit/base.py | 4 +- keystone/utils.py | 18 +- setup.py | 0 38 files changed, 2035 insertions(+), 1623 deletions(-) create mode 100644 keystone/backends/__init__.py create mode 100755 keystone/backends/alterdb/__init__.py create mode 100644 keystone/backends/alterdb/api/__init__.py create mode 100755 keystone/backends/alterdb/api/token.py create mode 100755 keystone/backends/alterdb/models.py create mode 100755 keystone/backends/api.py create mode 100644 keystone/backends/models.py create mode 100755 keystone/backends/sqlalchemy/__init__.py create mode 100755 keystone/backends/sqlalchemy/api/__init__.py create mode 100755 keystone/backends/sqlalchemy/api/endpoint_template.py create mode 100644 keystone/backends/sqlalchemy/api/group.py create mode 100644 keystone/backends/sqlalchemy/api/role.py create mode 100755 keystone/backends/sqlalchemy/api/tenant.py create mode 100755 keystone/backends/sqlalchemy/api/tenant_group.py create mode 100755 keystone/backends/sqlalchemy/api/token.py create mode 100755 keystone/backends/sqlalchemy/api/user.py create mode 100755 keystone/backends/sqlalchemy/models.py delete mode 100644 keystone/db/__init__.py delete mode 100644 keystone/db/sqlalchemy/__init__.py delete mode 100644 keystone/db/sqlalchemy/api/__init__.py delete mode 100755 keystone/db/sqlalchemy/api/endpoint_template.py delete mode 100644 keystone/db/sqlalchemy/api/group.py delete mode 100644 keystone/db/sqlalchemy/api/role.py delete mode 100755 keystone/db/sqlalchemy/api/tenant.py delete mode 100644 keystone/db/sqlalchemy/api/tenant_group.py delete mode 100644 keystone/db/sqlalchemy/api/token.py delete mode 100755 keystone/db/sqlalchemy/api/user.py delete mode 100644 keystone/db/sqlalchemy/models.py mode change 100644 => 100755 keystone/utils.py mode change 100644 => 100755 setup.py diff --git a/.gitignore b/.gitignore index 94c324b9..c4dff7bb 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ .pydevproject/ .settings/ keystone.db +keystone.token.db .*.swp *.log *.pid diff --git a/bin/keystone b/bin/keystone index 3349f634..4664f80d 100755 --- a/bin/keystone +++ b/bin/keystone @@ -38,7 +38,6 @@ import tools.tracer #@UnusedImport # module runs on import import keystone from keystone.common import config, wsgi - if __name__ == '__main__': # Initialize a parser for our configuration paramaters parser = optparse.OptionParser(version='%%prog %s' % keystone.version) diff --git a/bin/keystone-manage b/bin/keystone-manage index e3208f40..0475b99b 100755 --- a/bin/keystone-manage +++ b/bin/keystone-manage @@ -38,9 +38,9 @@ if os.path.exists(os.path.join(possible_topdir, 'keystone', '__init__.py')): import tools.tracer #@UnusedImport # module runs on import import keystone from keystone.common import config -import keystone.db.sqlalchemy as db -import keystone.db.sqlalchemy.api as db_api -import keystone.db.sqlalchemy.models as db_models +import keystone.backends as db +import keystone.backends.api as db_api +import keystone.backends.sqlalchemy.models as db_models def Main(): @@ -72,7 +72,6 @@ def Main(): # Parse command-line and load config (options, args) = config.parse_options(parser) config_file, conf = config.load_paste_config('admin', options, args) - # Check arguments if len(args) == 0: parser.error('No object type specified for first argument') @@ -105,11 +104,10 @@ def Main(): verbose = verbose in [True, "True", "1"] if debug or verbose: config_file = config.find_config_file(options, args) - print "Using config file:", config_file config.setup_logging(options, conf) - db.configure_db(conf) + db.configure_backends(conf.global_conf) if object_type == "user": if command == "add": diff --git a/etc/keystone.conf b/etc/keystone.conf index c2f30556..4d81f48d 100755 --- a/etc/keystone.conf +++ b/etc/keystone.conf @@ -3,7 +3,7 @@ verbose = False # Show debugging output in logs (sets DEBUG log level output) -debug = False +debug = True # Which backend store should Keystone use by default. # Default: 'sqlite' @@ -14,15 +14,8 @@ default_store = sqlite # file for both the API and registry servers! #log_file = /var/log/keystone.log log_file = keystone.log - -# SQLAlchemy connection string for the reference implementation -# registry server. Any valid SQLAlchemy connection string is fine. -# See: http://www.sqlalchemy.org/docs/05/reference/sqlalchemy/connections.html#sqlalchemy.create_engine -sql_connection = sqlite:///keystone.db - -# Period in seconds after which SQLAlchemy should reestablish its connection -# to the database. -sql_idle_timeout = 30 +#List of backends to be configured +backends = keystone.backends.sqlalchemy,keystone.backends.alterdb #Dictionary Maps every service to a header.Missing services would get header X_(SERVICE_NAME) Key => Service Name, Value => Header Name service-header-mappings = {'nova' : 'X-Server-Management-Url' , 'swift' : 'X-Storage-Url', 'cdn' : 'X-CDN-Management-Url'} @@ -33,6 +26,27 @@ server_bind_host = 0.0.0.0 # Port the bind the API server to server_bind_port = 5000 + +[keystone.backends.sqlalchemy] +# SQLAlchemy connection string for the reference implementation +# registry server. Any valid SQLAlchemy connection string is fine. +# See: http://www.sqlalchemy.org/docs/05/reference/sqlalchemy/connections.html#sqlalchemy.create_engine +sql_connection = sqlite:///keystone.db +backend_entities = ['UserGroupAssociation', 'UserRoleAssociation', 'Endpoints', 'Role', 'Tenant', 'User', 'Credentials', 'Group', 'EndpointTemplates'] +# Period in seconds after which SQLAlchemy should reestablish its connection +# to the database. +sql_idle_timeout = 30 + +[keystone.backends.alterdb] +# SQLAlchemy connection string for the reference implementation +# registry server. Any valid SQLAlchemy connection string is fine. +# See: http://www.sqlalchemy.org/docs/05/reference/sqlalchemy/connections.html#sqlalchemy.create_engine +sql_connection = sqlite:///keystone.token.db +backend_entities = ['Token'] +# Period in seconds after which SQLAlchemy should reestablish its connection +# to the database. +sql_idle_timeout = 30 + [app:admin] paste.app_factory = keystone.server:admin_app_factory diff --git a/keystone/backends/__init__.py b/keystone/backends/__init__.py new file mode 100644 index 00000000..89b3afb1 --- /dev/null +++ b/keystone/backends/__init__.py @@ -0,0 +1,30 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 OpenStack LLC. +# 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 ast +import logging +import keystone.utils as utils +from keystone.backends import models as models +from keystone.backends import api as api + +DEFAULT_BACKENDS = 'keystone.backends.sqlalchemy' + +def configure_backends(options): + '''Load backends given in the 'backends' option.''' + backend_names = options.get('backends', DEFAULT_BACKENDS) + for backend in backend_names.split(','): + backend_module = utils.import_module(backend) + backend_module.configure_backend(options[backend]) diff --git a/keystone/backends/alterdb/__init__.py b/keystone/backends/alterdb/__init__.py new file mode 100755 index 00000000..fc7275cc --- /dev/null +++ b/keystone/backends/alterdb/__init__.py @@ -0,0 +1,94 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 OpenStack LLC. +# 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 ast +import logging + +from sqlalchemy import create_engine +from sqlalchemy.orm import joinedload, aliased, sessionmaker + +from keystone.common import config +from keystone.backends.alterdb import models +import keystone.utils as utils +import keystone.backends.api as top_api + +_ENGINE = None +_MAKER = None +BASE = models.Base +MODEL_PREFIX = 'keystone.backends.alterdb.models.' +API_PREFIX = 'keystone.backends.alterdb.api.' + +def configure_backend(options): + """ + Establish the database, create an engine if needed, and + register the models. + + :param options: Mapping of configuration options + """ + global _ENGINE + if not _ENGINE: + debug = config.get_option( + options, 'debug', type='bool', default=False) + verbose = config.get_option( + options, 'verbose', type='bool', default=False) + timeout = config.get_option( + options, 'sql_idle_timeout', type='int', default=3600) + _ENGINE = create_engine(options['sql_connection'], + pool_recycle=timeout) + logger = logging.getLogger('sqlalchemy.engine') + if debug: + logger.setLevel(logging.DEBUG) + elif verbose: + logger.setLevel(logging.INFO) + register_models(options) + + +def get_session(autocommit=True, expire_on_commit=False): + """Helper method to grab session""" + global _MAKER, _ENGINE + if not _MAKER: + assert _ENGINE + _MAKER = sessionmaker(bind=_ENGINE, + autocommit=autocommit, + expire_on_commit=expire_on_commit) + return _MAKER() + + +def register_models(options): + """Register Models and create properties""" + global _ENGINE + assert _ENGINE + supported_alchemy_models = ast.literal_eval( + options["backend_entities"]) + supported_alchemy_tables = [] + for supported_alchemy_model in supported_alchemy_models: + model = utils.import_module(MODEL_PREFIX + supported_alchemy_model) + supported_alchemy_tables.append(model.__table__) + if model.__api__ != None: + model_api = utils.import_module(API_PREFIX + model.__api__) + top_api.set_value(model.__api__, model_api) + creation_tables = [] + for table in reversed(BASE.metadata.sorted_tables): + if table in supported_alchemy_tables: + creation_tables.append(table) + BASE.metadata.create_all(_ENGINE, tables=creation_tables, checkfirst=True) + +def unregister_models(): + """Unregister Models, useful clearing out data before testing""" + global _ENGINE + assert _ENGINE + BASE.metadata.drop_all(_ENGINE) diff --git a/keystone/backends/alterdb/api/__init__.py b/keystone/backends/alterdb/api/__init__.py new file mode 100644 index 00000000..5e662f40 --- /dev/null +++ b/keystone/backends/alterdb/api/__init__.py @@ -0,0 +1 @@ +import token diff --git a/keystone/backends/alterdb/api/token.py b/keystone/backends/alterdb/api/token.py new file mode 100755 index 00000000..d7496ec9 --- /dev/null +++ b/keystone/backends/alterdb/api/token.py @@ -0,0 +1,61 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 OpenStack LLC. +# 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. + +from keystone.backends.alterdb import get_session, models + +def create(values): + token_ref = models.Token() + token_ref.update(values) + token_ref.save() + return token_ref + + +def get(id, session=None): + if not session: + session = get_session() + result = session.query(models.Token).filter_by(id=id).first() + return result + + +def delete(id, session=None): + if not session: + session = get_session() + with session.begin(): + token_ref = get(id, session) + session.delete(token_ref) + + +def get_for_user(user_id, session=None): + if not session: + session = get_session() + result = session.query(models.Token).filter_by( + user_id=user_id, tenant_id=None).order_by("expires desc").first() + return result + + +def get_for_user_by_tenant(user_id, tenant_id, session=None): + if not session: + session = get_session() + result = session.query(models.Token).filter_by( + user_id=user_id, tenant_id=tenant_id).order_by("expires desc").first() + return result + + +def get_all(session=None): + if not session: + session = get_session() + return session.query(models.Token).all() diff --git a/keystone/backends/alterdb/models.py b/keystone/backends/alterdb/models.py new file mode 100755 index 00000000..7aa30c18 --- /dev/null +++ b/keystone/backends/alterdb/models.py @@ -0,0 +1,85 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# Copyright (c) 2010-2011 OpenStack, LLC. +# +# 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. +# Not Yet PEP8 standardized +from sqlalchemy import Column, String, Integer, ForeignKey, \ + UniqueConstraint, Boolean, DateTime +from sqlalchemy.exc import IntegrityError +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import relationship, object_mapper +Base = declarative_base() + + +class KeystoneBase(object): + """Base class for Keystone Models.""" + __api__ = None + def save(self, session=None): + """Save this object.""" + + if not session: + from keystone.backends.alterdb import get_session + session = get_session() + session.add(self) + try: + session.flush() + except IntegrityError: + raise + + def delete(self, session=None): + """Delete this object.""" + self.save(session=session) + + def __setitem__(self, key, value): + setattr(self, key, value) + + def __getitem__(self, key): + return getattr(self, key) + + def get(self, key, default=None): + return getattr(self, key, default) + + def __iter__(self): + self._i = iter(object_mapper(self).columns) + return self + + def next(self): + n = self._i.next().name + return n, getattr(self, n) + + def update(self, values): + """Make the model object behave like a dict""" + for k, v in values.iteritems(): + setattr(self, k, v) + + def iteritems(self): + """Make the model object behave like a dict. + + Includes attributes from joins.""" + local = dict(self) + joined = dict([(k, v) for k, v in self.__dict__.iteritems() + if not k[0] == '_']) + local.update(joined) + return local.iteritems() + + + +class Token(Base, KeystoneBase): + __tablename__ = 'token' + __api__ ='token' + id = Column(String(255), primary_key=True, unique=True) + user_id = Column(String(255)) + tenant_id = Column(String(255)) + expires = Column(DateTime) + diff --git a/keystone/backends/api.py b/keystone/backends/api.py new file mode 100755 index 00000000..782d3071 --- /dev/null +++ b/keystone/backends/api.py @@ -0,0 +1,47 @@ +# +# 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. +# Not Yet PEP8 standardized +#API + +endpoint_template = None +group = None +role = None +tenant_group = None +tenant = None +token = None +user = None + +# Function to dynamically set module references. +def set_value(variable_name, value): + if variable_name == 'endpoint_template': + global endpoint_template + endpoint_template = value + elif variable_name == 'group': + global group + group = value + elif variable_name == 'role': + global role + role = value + elif variable_name == 'tenant_group': + global tenant_group + tenant_group = value + elif variable_name == 'tenant': + global tenant + tenant = value + elif variable_name == 'token': + global token + token = value + elif variable_name == 'user': + global user + user = value diff --git a/keystone/backends/models.py b/keystone/backends/models.py new file mode 100644 index 00000000..dc35361f --- /dev/null +++ b/keystone/backends/models.py @@ -0,0 +1,28 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# Copyright (c) 2010-2011 OpenStack, LLC. +# +# 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. +# Not Yet PEP8 standardized +#Models +UserGroupAssociation = None +UserRoleAssociation = None +Endpoints = None +Role = None +Tenant = None +User = None +Credentials = None +Group = None +Token = None +EndpointTemplates = None + diff --git a/keystone/backends/sqlalchemy/__init__.py b/keystone/backends/sqlalchemy/__init__.py new file mode 100755 index 00000000..6b3e52d1 --- /dev/null +++ b/keystone/backends/sqlalchemy/__init__.py @@ -0,0 +1,95 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 OpenStack LLC. +# 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 ast +import logging + +from sqlalchemy import create_engine +from sqlalchemy.orm import joinedload, aliased, sessionmaker + +from keystone.common import config +from keystone.backends.sqlalchemy import models +import keystone.utils as utils +import keystone.backends.api as top_api +_ENGINE = None +_MAKER = None +BASE = models.Base + +MODEL_PREFIX = 'keystone.backends.sqlalchemy.models.' +API_PREFIX = 'keystone.backends.sqlalchemy.api.' + +def configure_backend(options): + """ + Establish the database, create an engine if needed, and + register the models. + + :param options: Mapping of configuration options + """ + global _ENGINE + if not _ENGINE: + debug = config.get_option( + options, 'debug', type='bool', default=False) + verbose = config.get_option( + options, 'verbose', type='bool', default=False) + timeout = config.get_option( + options, 'sql_idle_timeout', type='int', default=3600) + _ENGINE = create_engine(options['sql_connection'], + pool_recycle=timeout) + logger = logging.getLogger('sqlalchemy.engine') + if debug: + logger.setLevel(logging.DEBUG) + elif verbose: + logger.setLevel(logging.INFO) + register_models(options) + + +def get_session(autocommit=True, expire_on_commit=False): + """Helper method to grab session""" + global _MAKER, _ENGINE + if not _MAKER: + assert _ENGINE + _MAKER = sessionmaker(bind=_ENGINE, + autocommit=autocommit, + expire_on_commit=expire_on_commit) + return _MAKER() + + +def register_models(options): + """Register Models and create properties""" + global _ENGINE + assert _ENGINE + supported_alchemy_models = ast.literal_eval( + options["backend_entities"]) + supported_alchemy_tables = [] + for supported_alchemy_model in supported_alchemy_models: + model = utils.import_module(MODEL_PREFIX + supported_alchemy_model) + supported_alchemy_tables.append(model.__table__) + if model.__api__ != None: + model_api = utils.import_module(API_PREFIX + model.__api__) + top_api.set_value(model.__api__, model_api) + creation_tables = [] + for table in reversed(BASE.metadata.sorted_tables): + if table in supported_alchemy_tables: + creation_tables.append(table) + BASE.metadata.create_all(_ENGINE, tables=creation_tables, checkfirst=True) + + +def unregister_models(): + """Unregister Models, useful clearing out data before testing""" + global _ENGINE + assert _ENGINE + BASE.metadata.drop_all(_ENGINE) diff --git a/keystone/backends/sqlalchemy/api/__init__.py b/keystone/backends/sqlalchemy/api/__init__.py new file mode 100755 index 00000000..657621a6 --- /dev/null +++ b/keystone/backends/sqlalchemy/api/__init__.py @@ -0,0 +1 @@ +import endpoint_template, group, role, tenant_group, tenant, token, user diff --git a/keystone/backends/sqlalchemy/api/endpoint_template.py b/keystone/backends/sqlalchemy/api/endpoint_template.py new file mode 100755 index 00000000..135cf0a6 --- /dev/null +++ b/keystone/backends/sqlalchemy/api/endpoint_template.py @@ -0,0 +1,185 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 OpenStack LLC. +# 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. + +from keystone.backends.sqlalchemy import get_session, models, aliased + +def create(values): + endpoint_template = models.EndpointTemplates() + endpoint_template.update(values) + endpoint_template.save() + return endpoint_template + + +def get(id, session=None): + if not session: + session = get_session() + result = session.query(models.EndpointTemplates).filter_by(id=id).first() + return result + + +def get_all(session=None): + if not session: + session = get_session() + return session.query(models.EndpointTemplates).all() + + +def get_page(marker, limit, session=None): + if not session: + session = get_session() + + if marker: + return session.query(models.EndpointTemplates).filter("id>:marker").params(\ + marker='%s' % marker).order_by(\ + models.EndpointTemplates.id.desc()).limit(limit).all() + else: + return session.query(models.EndpointTemplates).order_by(\ + models.EndpointTemplates.id.desc()).limit(limit).all() + + +def get_page_markers(marker, limit, session=None): + if not session: + session = get_session() + first = session.query(models.EndpointTemplates).order_by(\ + models.EndpointTemplates.id).first() + last = session.query(models.EndpointTemplates).order_by(\ + models.EndpointTemplates.id.desc()).first() + if first is None: + return (None, None) + if marker is None: + marker = first.id + next = session.query(models.EndpointTemplates).filter("id > :marker").params(\ + marker='%s' % marker).order_by(\ + models.EndpointTemplates.id).limit(limit).all() + prev = session.query(models.EndpointTemplates).filter("id < :marker").params(\ + marker='%s' % marker).order_by(\ + models.EndpointTemplates.id.desc()).limit(int(limit)).all() + if len(next) == 0: + next = last + else: + for t in next: + next = t + if len(prev) == 0: + prev = first + else: + for t in prev: + prev = t + if prev.id == marker: + prev = None + else: + prev = prev.id + if next.id == last.id: + next = None + else: + next = next.id + return (prev, next) + + +def endpoint_get_by_tenant_get_page(tenant_id, marker, limit, + session=None): + if not session: + session = get_session() + if marker: + return session.query(models.Endpoints).\ + filter(models.Endpoints.tenant_id == tenant_id).\ + filter("id >= :marker").params( + marker='%s' % marker).order_by( + models.Endpoints.id).limit(limit).all() + else: + return session.query(models.Endpoints).\ + filter(models.Endpoints.tenant_id == tenant_id).\ + order_by(models.Endpoints.id).limit(limit).all() + + +def endpoint_get_by_tenant_get_page_markers(tenant_id, marker, limit, + session=None): + if not session: + session = get_session() + tba = aliased(models.Endpoints) + first = session.query(tba).\ + filter(tba.tenant_id == tenant_id).\ + order_by(tba.id).first() + last = session.query(tba).\ + filter(tba.tenant_id == tenant_id).\ + order_by(tba.id.desc()).first() + if first is None: + return (None, None) + if marker is None: + marker = first.id + next = session.query(tba).\ + filter(tba.tenant_id == tenant_id).\ + filter("id>=:marker").params( + marker='%s' % marker).order_by( + tba.id).limit(int(limit)).all() + + prev = session.query(tba).\ + filter(tba.tenant_id == tenant_id).\ + filter("id < :marker").params( + marker='%s' % marker).order_by( + tba.id).limit(int(limit) + 1).all() + next_len = len(next) + prev_len = len(prev) + + if next_len == 0: + next = last + else: + for t in next: + next = t + if prev_len == 0: + prev = first + else: + for t in prev: + prev = t + if first.id == marker: + prev = None + else: + prev = prev.id + if marker == last.id: + next = None + else: + next = next.id + return (prev, next) + + +def endpoint_add(values): + endpoints = models.Endpoints() + endpoints.update(values) + endpoints.save() + return endpoints + + +def endpoint_get(id, session=None): + if not session: + session = get_session() + result = session.query(models.Endpoints).\ + filter_by(id=id).first() + return result + + +def endpoint_get_by_tenant(tenant_id, session=None): + if not session: + session = get_session() + result = session.query(models.Endpoints).\ + filter_by(tenant_id=tenant_id).first() + return result + + +def endpoint_delete(id, session=None): + if not session: + session = get_session() + with session.begin(): + endpoints = endpoint_get(id, session) + session.delete(endpoints) diff --git a/keystone/backends/sqlalchemy/api/group.py b/keystone/backends/sqlalchemy/api/group.py new file mode 100644 index 00000000..54b6ff09 --- /dev/null +++ b/keystone/backends/sqlalchemy/api/group.py @@ -0,0 +1,170 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 OpenStack LLC. +# 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. + +from keystone.backends.sqlalchemy import get_session, models, aliased + +def get(id, session=None): + if not session: + session = get_session() + result = session.query(models.Group).filter_by(id=id).first() + return result + + +def get_users(id, session=None): + if not session: + session = get_session() + result = session.query(models.User).filter_by(\ + group_id=id) + return result + + +def get_all(session=None): + if not session: + session = get_session() + result = session.query(models.Group) + return result + + +def get_page(marker, limit, session=None): + if not session: + session = get_session() + + if marker: + return session.query(models.Group).filter("id>:marker").params(\ + marker='%s' % marker).order_by(\ + models.Group.id.desc()).limit(limit).all() + else: + return session.query(models.Group).order_by(\ + models.Group.id.desc()).limit(limit).all() + + +def get_page_markers(marker, limit, session=None): + if not session: + session = get_session() + first = session.query(models.Group).order_by(\ + models.Group.id).first() + last = session.query(models.Group).order_by(\ + models.Group.id.desc()).first() + if first is None: + return (None, None) + if marker is None: + marker = first.id + next = session.query(models.Group).filter("id > :marker").params(\ + marker='%s' % marker).order_by(\ + models.Group.id).limit(limit).all() + prev = session.query(models.Group).filter("id < :marker").params(\ + marker='%s' % marker).order_by(\ + models.Group.id.desc()).limit(int(limit)).all() + if len(next) == 0: + next = last + else: + for t in next: + next = t + if len(prev) == 0: + prev = first + else: + for t in prev: + prev = t + if prev.id == marker: + prev = None + else: + prev = prev.id + if next.id == last.id: + next = None + else: + next = next.id + return (prev, next) + + +def delete(id, session=None): + if not session: + session = get_session() + with session.begin(): + group_ref = get(id, session) + session.delete(group_ref) + +def get_by_user_get_page(user_id, marker, limit, session=None): + if not session: + session = get_session() + uga = aliased(models.UserGroupAssociation) + group = aliased(models.Group) + if marker: + return session.query(group, uga).join(\ + (uga, uga.group_id == group.id)).\ + filter(uga.user_id == user_id).\ + filter("id>=:marker").params( + marker='%s' % marker).order_by( + group.id).limit(limit).all() + else: + return session.query(group, uga).\ + join((uga, uga.group_id == group.id)).\ + filter(uga.user_id == user_id).order_by( + group.id).limit(limit).all() + + +def get_by_user_get_page_markers(user_id, marker, limit, session=None): + if not session: + session = get_session() + uga = aliased(models.UserGroupAssociation) + group = aliased(models.Group) + first, _firstassoc = session.query(group, uga).\ + join((uga, uga.group_id == group.id)).\ + filter(uga.user_id == user_id).\ + order_by(group.id).first() + last, _lastassoc = session.query(group, uga).\ + join((uga, uga.group_id == group.id)).\ + filter(uga.user_id == user_id).\ + order_by(group.id.desc()).first() + if first is None: + return (None, None) + if marker is None: + marker = first.id + next = session.query(group, uga).join( + (uga, uga.group_id == group.id)).\ + filter(uga.user_id == user_id).\ + filter("id>=:marker").params( + marker='%s' % marker).order_by( + group.id).limit(int(limit)).all() + + prev = session.query(group, uga).join( + (uga, uga.group_id == group.id)).\ + filter(uga.user_id == user_id).\ + filter("id < :marker").params( + marker='%s' % marker).order_by( + group.id).limit(int(limit) + 1).all() + next_len = len(next) + prev_len = len(prev) + + if next_len == 0: + next = last + else: + for t, _a in next: + next = t + if prev_len == 0: + prev = first + else: + for t, _a in prev: + prev = t + if first.id == marker: + prev = None + else: + prev = prev.id + if marker == last.id: + next = None + else: + next = next.id + return (prev, next) diff --git a/keystone/backends/sqlalchemy/api/role.py b/keystone/backends/sqlalchemy/api/role.py new file mode 100644 index 00000000..d7dff110 --- /dev/null +++ b/keystone/backends/sqlalchemy/api/role.py @@ -0,0 +1,174 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 OpenStack LLC. +# 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. + +from keystone.backends.sqlalchemy import get_session, models + +def create(values): + role_ref = models.Role() + role_ref.update(values) + role_ref.save() + return role_ref + + +def get(id, session=None): + if not session: + session = get_session() + result = session.query(models.Role).filter_by(id=id).first() + return result + + +def get_all(session=None): + if not session: + session = get_session() + return session.query(models.Role).all() + + +def get_page(marker, limit, session=None): + if not session: + session = get_session() + + if marker: + return session.query(models.Role).filter("id>:marker").params(\ + marker='%s' % marker).order_by(\ + models.Role.id.desc()).limit(limit).all() + else: + return session.query(models.Role).order_by(\ + models.Role.id.desc()).limit(limit).all() + + +def ref_get_page(marker, limit, user_id, session=None): + if not session: + session = get_session() + + if marker: + return session.query(models.UserRoleAssociation).\ + filter("id>:marker").params(\ + marker='%s' % marker).filter_by(user_id=user_id).order_by(\ + models.UserRoleAssociation.id.desc()).limit(limit).all() + else: + return session.query(models.UserRoleAssociation).\ + filter_by(user_id=user_id).order_by(\ + models.UserRoleAssociation.id.desc()).limit(limit).all() + + +def ref_get_all_global_roles(user_id, session=None): + if not session: + session = get_session() + return session.query(models.UserRoleAssociation).\ + filter_by(user_id=user_id).filter("tenant_id is null").all() + + +def ref_get_all_tenant_roles(user_id, tenant_id, session=None): + if not session: + session = get_session() + return session.query(models.UserRoleAssociation).\ + filter_by(user_id=user_id).filter_by(tenant_id=tenant_id).all() + + +def ref_get(id, session=None): + if not session: + session = get_session() + result = session.query(models.UserRoleAssociation).filter_by(id=id).first() + return result + + +def ref_delete(id, session=None): + if not session: + session = get_session() + with session.begin(): + role_ref = ref_get(id, session) + session.delete(role_ref) + +def get_page_markers(marker, limit, session=None): + if not session: + session = get_session() + first = session.query(models.Role).order_by(\ + models.Role.id).first() + last = session.query(models.Role).order_by(\ + models.Role.id.desc()).first() + if first is None: + return (None, None) + if marker is None: + marker = first.id + next = session.query(models.Role).filter("id > :marker").params(\ + marker='%s' % marker).order_by(\ + models.Role.id).limit(limit).all() + prev = session.query(models.Role).filter("id < :marker").params(\ + marker='%s' % marker).order_by(\ + models.Role.id.desc()).limit(int(limit)).all() + if len(next) == 0: + next = last + else: + for t in next: + next = t + if len(prev) == 0: + prev = first + else: + for t in prev: + prev = t + if prev.id == marker: + prev = None + else: + prev = prev.id + if next.id == last.id: + next = None + else: + next = next.id + return (prev, next) + + +def ref_get_page_markers(user_id, marker, limit, session=None): + if not session: + session = get_session() + first = session.query(models.UserRoleAssociation).filter_by(\ + user_id=user_id).order_by(\ + models.UserRoleAssociation.id).first() + last = session.query(models.UserRoleAssociation).filter_by(\ + user_id=user_id).order_by(\ + models.UserRoleAssociation.id.desc()).first() + if first is None: + return (None, None) + if marker is None: + marker = first.id + next = session.query(models.UserRoleAssociation).filter_by(\ + user_id=user_id).filter("id > :marker").params(\ + marker='%s' % marker).order_by(\ + models.UserRoleAssociation.id).limit(limit).all() + prev = session.query(models.UserRoleAssociation).filter_by(\ + user_id=user_id).filter("id < :marker").params(\ + marker='%s' % marker).order_by(\ + models.UserRoleAssociation.id.desc()).limit(int(limit)).\ + all() + if len(next) == 0: + next = last + else: + for t in next: + next = t + if len(prev) == 0: + prev = first + else: + for t in prev: + prev = t + if prev.id == marker: + prev = None + else: + prev = prev.id + if next.id == last.id: + next = None + else: + next = next.id + return (prev, next) diff --git a/keystone/backends/sqlalchemy/api/tenant.py b/keystone/backends/sqlalchemy/api/tenant.py new file mode 100755 index 00000000..fe8b41cd --- /dev/null +++ b/keystone/backends/sqlalchemy/api/tenant.py @@ -0,0 +1,203 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 OpenStack LLC. +# 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. + +from keystone.backends.sqlalchemy import get_session, models, aliased + + +def create(values): + tenant_ref = models.Tenant() + tenant_ref.update(values) + tenant_ref.save() + return tenant_ref + + +def get(id, session=None): + if not session: + session = get_session() + result = session.query(models.Tenant).filter_by(id=id).first() + return result + + +def get_all(session=None): + if not session: + session = get_session() + return session.query(models.Tenant).all() + + +def tenants_for_user_get_page(user, marker, limit, session=None): + if not session: + session = get_session() + ura = aliased(models.UserRoleAssociation) + tenant = aliased(models.Tenant) + q1 = session.query(tenant).join((ura, ura.tenant_id == tenant.id)).\ + filter(ura.user_id == user.id) + q2 = session.query(tenant).filter(tenant.id == user.tenant_id) + q3 = q1.union(q2) + if marker: + return q3.filter("tenant.id>:marker").params(\ + marker='%s' % marker).order_by(\ + tenant.id.desc()).limit(limit).all() + else: + return q3.order_by(tenant.id.desc()).limit(limit).all() + + +def tenants_for_user_get_page_markers(user, marker, limit, session=None): + if not session: + session = get_session() + ura = aliased(models.UserRoleAssociation) + tenant = aliased(models.Tenant) + q1 = session.query(tenant).join((ura, ura.tenant_id == tenant.id)).\ + filter(ura.user_id == user.id) + q2 = session.query(tenant).filter(tenant.id == user.tenant_id) + q3 = q1.union(q2) + + first = q3.order_by(\ + tenant.id).first() + last = q3.order_by(\ + tenant.id.desc()).first() + if first is None: + return (None, None) + if marker is None: + marker = first.id + next = q3.filter(tenant.id > marker).order_by(\ + tenant.id).limit(limit).all() + prev = q3.filter(tenant.id > marker).order_by(\ + tenant.id.desc()).limit(int(limit)).all() + if len(next) == 0: + next = last + else: + for t in next: + next = t + if len(prev) == 0: + prev = first + else: + for t in prev: + prev = t + if prev.id == marker: + prev = None + else: + prev = prev.id + if next.id == last.id: + next = None + else: + next = next.id + return (prev, next) + + +def get_page(marker, limit, session=None): + if not session: + session = get_session() + + if marker: + return session.query(models.Tenant).filter("id>:marker").params(\ + marker='%s' % marker).order_by(\ + models.Tenant.id.desc()).limit(limit).all() + else: + return session.query(models.Tenant).order_by(\ + models.Tenant.id.desc()).limit(limit).all() + + +def get_page_markers(marker, limit, session=None): + if not session: + session = get_session() + first = session.query(models.Tenant).order_by(\ + models.Tenant.id).first() + last = session.query(models.Tenant).order_by(\ + models.Tenant.id.desc()).first() + if first is None: + return (None, None) + if marker is None: + marker = first.id + next = session.query(models.Tenant).filter("id > :marker").params(\ + marker='%s' % marker).order_by(\ + models.Tenant.id).limit(limit).all() + prev = session.query(models.Tenant).filter("id < :marker").params(\ + marker='%s' % marker).order_by(\ + models.Tenant.id.desc()).limit(int(limit)).all() + if len(next) == 0: + next = last + else: + for t in next: + next = t + if len(prev) == 0: + prev = first + else: + for t in prev: + prev = t + if prev.id == marker: + prev = None + else: + prev = prev.id + if next.id == last.id: + next = None + else: + next = next.id + return (prev, next) + + +def is_empty(id, session=None): + if not session: + session = get_session() + a_user = session.query(models.UserRoleAssociation).filter_by(\ + tenant_id=id).first() + if a_user != None: + return False + a_group = session.query(models.Group).filter_by(tenant_id=id).first() + if a_group != None: + return False + a_user = session.query(models.User).filter_by(tenant_id=id).first() + if a_user != None: + return False + return True + + +def update(id, values, session=None): + if not session: + session = get_session() + with session.begin(): + tenant_ref = get(id, session) + tenant_ref.update(values) + tenant_ref.save(session=session) + + +def delete(id, session=None): + if not session: + session = get_session() + with session.begin(): + tenant_ref = get(id, session) + session.delete(tenant_ref) + + +def get_all_endpoints(tenant_id, session=None): + if not session: + session = get_session() + ep = aliased(models.Endpoints) + endpointTemplates = aliased(models.EndpointTemplates) + q1 = session.query(endpointTemplates).join((ep, + ep.endpoint_template_id == endpointTemplates.id)).\ + filter(ep.tenant_id == tenant_id) + q2 = session.query(endpointTemplates).\ + filter(endpointTemplates.is_global == 1) + q3 = q1.union(q2) + return q3.all() + + +def get_role_assignments(tenant_id, session=None): + if not session: + session = get_session() + return session.query(models.UserRoleAssociation).\ + filter_by(tenant_id=tenant_id) diff --git a/keystone/backends/sqlalchemy/api/tenant_group.py b/keystone/backends/sqlalchemy/api/tenant_group.py new file mode 100755 index 00000000..21f466de --- /dev/null +++ b/keystone/backends/sqlalchemy/api/tenant_group.py @@ -0,0 +1,118 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 OpenStack LLC. +# 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. + +from keystone.backends.sqlalchemy import get_session, models + +def create(values): + group_ref = models.Group() + group_ref.update(values) + group_ref.save() + return group_ref + + +def is_empty(id, session=None): + if not session: + session = get_session() + a_user = session.query(models.UserGroupAssociation).filter_by( + group_id=id).first() + if a_user != None: + return False + return True + + +def get(id, tenant, session=None): + if not session: + session = get_session() + result = session.query(models.Group).filter_by(id=id, \ + tenant_id=tenant).first() + + return result + + +def get_page(tenantId, marker, limit, session=None): + if not session: + session = get_session() + + if marker: + return session.query(models.Group).filter("id>:marker").params(\ + marker='%s' % marker).filter_by(\ + tenant_id=tenantId).order_by(\ + models.Group.id.desc()).limit(limit).all() + else: + return session.query(models.Group).filter_by(tenant_id=tenantId)\ + .order_by(models.Group.id.desc()).limit(limit).all() + #return session.query(models.Tenant).all() + + +def get_page_markers(tenantId, marker, limit, session=None): + if not session: + session = get_session() + first = session.query(models.Group).filter_by(\ + tenant_id=tenantId).order_by(\ + models.Group.id).first() + last = session.query(models.Group).filter_by(\ + tenant_id=tenantId).order_by(\ + models.Group.id.desc()).first() + + if first is None: + return (None, None) + if marker is None: + marker = first.id + next = session.query(models.Group).filter("id > :marker").params(\ + marker='%s' % marker).filter_by(\ + tenant_id=tenantId).order_by(\ + models.Group.id).limit(limit).all() + prev = session.query(models.Group).filter("id < :marker").params(\ + marker='%s' % marker).filter_by(\ + tenant_id=tenantId).order_by(\ + models.Group.id.desc()).limit(int(limit)).all() + if len(next) == 0: + next = last + else: + for t in next: + next = t + if len(prev) == 0: + prev = first + else: + for t in prev: + prev = t + if prev.id == marker: + prev = None + else: + prev = prev.id + if next.id == last.id: + next = None + else: + next = next.id + return (prev, next) + + +def update(id, tenant_id, values, session=None): + if not session: + session = get_session() + with session.begin(): + tenant_ref = get(id, tenant_id, session) + tenant_ref.update(values) + tenant_ref.save(session=session) + + +def delete(id, tenant_id, session=None): + if not session: + session = get_session() + with session.begin(): + tenantgroup_ref = get(id, tenant_id, session) + session.delete(tenantgroup_ref) diff --git a/keystone/backends/sqlalchemy/api/token.py b/keystone/backends/sqlalchemy/api/token.py new file mode 100755 index 00000000..19c4b8b3 --- /dev/null +++ b/keystone/backends/sqlalchemy/api/token.py @@ -0,0 +1,61 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 OpenStack LLC. +# 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. + +from keystone.backends.sqlalchemy import get_session, models + +def create(values): + token_ref = models.Token() + token_ref.update(values) + token_ref.save() + return token_ref + + +def get(id, session=None): + if not session: + session = get_session() + result = session.query(models.Token).filter_by(id=id).first() + return result + + +def delete(id, session=None): + if not session: + session = get_session() + with session.begin(): + token_ref = get(id, session) + session.delete(token_ref) + + +def get_for_user(user_id, session=None): + if not session: + session = get_session() + result = session.query(models.Token).filter_by( + user_id=user_id, tenant_id=None).order_by("expires desc").first() + return result + + +def get_for_user_by_tenant(user_id, tenant_id, session=None): + if not session: + session = get_session() + result = session.query(models.Token).filter_by( + user_id=user_id, tenant_id=tenant_id).order_by("expires desc").first() + return result + + +def get_all(session=None): + if not session: + session = get_session() + return session.query(models.Token).all() diff --git a/keystone/backends/sqlalchemy/api/user.py b/keystone/backends/sqlalchemy/api/user.py new file mode 100755 index 00000000..5550a106 --- /dev/null +++ b/keystone/backends/sqlalchemy/api/user.py @@ -0,0 +1,429 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 OpenStack LLC. +# 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 keystone.utils as utils +from keystone.backends.sqlalchemy import get_session, models, aliased, joinedload + +def get_all(session=None): + if not session: + session = get_session() + result = session.query(models.User) + return result + + +def get_by_group(user_id, group_id, session=None): + if not session: + session = get_session() + result = session.query(models.UserGroupAssociation).filter_by(\ + group_id=group_id, user_id=user_id).first() + return result + + +def tenant_group(values): + user_ref = models.UserGroupAssociation() + user_ref.update(values) + user_ref.save() + return user_ref + + +def tenant_group_delete(id, group_id, session=None): + if not session: + session = get_session() + with session.begin(): + usertenantgroup_ref = get_by_group(id, group_id, session) + session.delete(usertenantgroup_ref) + + +def create(values): + user_ref = models.User() + check_and_use_hashed_password(values) + user_ref.update(values) + user_ref.save() + return user_ref + +def check_and_use_hashed_password(values): + if type(values) is dict and 'password' in values.keys(): + values['password'] = utils.get_hashed_password(values['password']) + elif type(values) is models.User: + values.password = utils.get_hashed_password(values.password) + +def get(id, session=None): + if not session: + session = get_session() + #TODO(Ziad): finish cleaning up model + # result = session.query(models.User).options(joinedload('groups')).\ + # options(joinedload('tenants')).filter_by(id=id).first() + result = session.query(models.User).filter_by(id=id).first() + return result + + +def get_page(marker, limit, session=None): + if not session: + session = get_session() + + if marker: + return session.query(models.User).filter("id>:marker").params(\ + marker='%s' % marker).order_by(\ + models.User.id.desc()).limit(limit).all() + else: + return session.query(models.User).order_by(\ + models.User.id.desc()).limit(limit).all() + + +def get_page_markers(marker, limit, session=None): + if not session: + session = get_session() + first = session.query(models.User).order_by(\ + models.User.id).first() + last = session.query(models.User).order_by(\ + models.User.id.desc()).first() + if first is None: + return (None, None) + if marker is None: + marker = first.id + next = session.query(models.User).filter("id > :marker").params(\ + marker='%s' % marker).order_by(\ + models.User.id).limit(limit).all() + prev = session.query(models.User).filter("id < :marker").params(\ + marker='%s' % marker).order_by(\ + models.User.id.desc()).limit(int(limit)).all() + if len(next) == 0: + next = last + else: + for t in next: + next = t + if len(prev) == 0: + prev = first + else: + for t in prev: + prev = t + if prev.id == marker: + prev = None + else: + prev = prev.id + if next.id == last.id: + next = None + else: + next = next.id + return (prev, next) + + +def get_by_email(email, session=None): + if not session: + session = get_session() + result = session.query(models.User).filter_by(email=email).first() + return result + + +def get_groups(id, session=None): + if not session: + session = get_session() + result = session.query(models.Group).filter_by(\ + user_id=id) + return result + + +def user_roles_by_tenant(user_id, tenant_id, session=None): + if not session: + session = get_session() + result = session.query(models.UserRoleAssociation).filter_by(\ + user_id=user_id, tenant_id=tenant_id).options(joinedload('roles')) + return result + + +def update(id, values, session=None): + if not session: + session = get_session() + with session.begin(): + user_ref = get(id, session) + check_and_use_hashed_password(values) + user_ref.update(values) + user_ref.save(session=session) + + +def users_tenant_group_get_page(group_id, marker, limit, session=None): + if not session: + session = get_session() + uga = aliased(models.UserGroupAssociation) + user = aliased(models.User) + if marker: + return session.query(user, uga).join(\ + (uga, uga.user_id == user.id)).\ + filter(uga.group_id == group_id).\ + filter("id>=:marker").params(\ + marker='%s' % marker).order_by(\ + user.id).limit(limit).all() + else: + return session.query(user, uga).\ + join((uga, uga.user_id == user.id)).\ + filter(uga.group_id == group_id).order_by(\ + user.id).limit(limit).all() + + +def users_tenant_group_get_page_markers(group_id, marker, limit, session=None): + if not session: + session = get_session() + uga = aliased(models.UserGroupAssociation) + user = aliased(models.User) + first = session.query(models.User).order_by(\ + models.User.id).first() + last = session.query(models.User).order_by(\ + models.User.id.desc()).first() + if first is None: + return (None, None) + if marker is None: + marker = first.id + next = session.query(user).join( + (uga, uga.user_id == user.id)).\ + filter(uga.group_id == group_id).\ + filter("id > :marker").params(\ + marker='%s' % marker).order_by(\ + user.id).limit(limit).all() + prev = session.query(user).join(\ + (uga, uga.user_id == user.id)).\ + filter(uga.group_id == group_id).\ + filter("id < :marker").params(\ + marker='%s' % marker).order_by(\ + user.id.desc()).limit(int(limit)).all() + if len(next) == 0: + next = last + else: + for t in next: + next = t + if len(prev) == 0: + prev = first + else: + for t in prev: + prev = t + if prev.id == marker: + prev = None + else: + prev = prev.id + if next.id == last.id: + next = None + else: + next = next.id + return (prev, next) + + +def delete(id, session=None): + if not session: + session = get_session() + with session.begin(): + user_ref = get(id, session) + session.delete(user_ref) + + +def get_by_tenant(id, tenant_id, session=None): + if not session: + session = get_session() + # Most common use case: user lives in tenant + user = session.query(models.User).\ + filter_by(id=id, tenant_id=tenant_id).first() + if user: + return user + + # Find user through grants to this tenant + user_tenant = session.query(models.UserRoleAssociation).filter_by(\ + tenant_id=tenant_id, user_id=id).first() + if user_tenant: + return get(id, session) + else: + return None + + +def get_group_by_tenant(id, session=None): + if not session: + session = get_session() + user_group = session.query(models.Group).filter_by(tenant_id=id).all() + return user_group + + +def delete_tenant_user(id, tenant_id, session=None): + if not session: + session = get_session() + with session.begin(): + users_tenant_ref = users_get_by_tenant(id, tenant_id, session) + if users_tenant_ref is not None: + for user_tenant_ref in users_tenant_ref: + session.delete(user_tenant_ref) + + user_group_ref = get_group_by_tenant(tenant_id, session) + + if user_group_ref is not None: + for user_group in user_group_ref: + get_users = session.query(models.UserGroupAssociation)\ + .filter_by(user_id=id, + group_id=user_group.id).all() + for group_user in get_users: + session.delete(group_user) + + +def users_get_by_tenant(user_id, tenant_id, session=None): + if not session: + session = get_session() + result = session.query(models.User).filter_by(id=user_id, + tenant_id=tenant_id) + return result + +def user_role_add(values): + user_role_ref = models.UserRoleAssociation() + user_role_ref.update(values) + user_role_ref.save() + return user_role_ref + + +def user_get_update(id, session=None): + if not session: + session = get_session() + result = session.query(models.User).filter_by(id=id).first() + return result + + +def users_get_page(marker, limit, session=None): + if not session: + session = get_session() + user = aliased(models.User) + if marker: + return session.query(user).\ + filter("id>=:marker").params( + marker='%s' % marker).order_by( + "id").limit(limit).all() + else: + return session.query(user).\ + order_by("id").limit(limit).all() + +def users_get_page_markers(marker, limit, \ + session=None): + if not session: + session = get_session() + user = aliased(models.User) + first = session.query(user).\ + order_by(user.id).first() + last = session.query(user).\ + order_by(user.id.desc()).first() + if first is None: + return (None, None) + if marker is None: + marker = first.id + next = session.query(user).\ + filter("id > :marker").params(\ + marker='%s' % marker).order_by(user.id).\ + limit(int(limit)).all() + prev = session.query(user).\ + filter("id < :marker").params( + marker='%s' % marker).order_by( + user.id.desc()).limit(int(limit)).all() + next_len = len(next) + prev_len = len(prev) + + if next_len == 0: + next = last + else: + for t in next: + next = t + if prev_len == 0: + prev = first + else: + for t in prev: + prev = t + if first.id == marker: + prev = None + else: + prev = prev.id + if marker == last.id: + next = None + else: + next = next.id + return (prev, next) + + +def users_get_by_tenant_get_page(tenant_id, marker, limit, session=None): + if not session: + session = get_session() + user = aliased(models.User) + if marker: + return session.query(user).\ + filter("tenant_id = :tenant_id").\ + params(tenant_id='%s' % tenant_id).\ + filter("id>=:marker").params( + marker='%s' % marker).order_by( + "id").limit(limit).all() + else: + return session.query(user).\ + filter("tenant_id = :tenant_id").\ + params(tenant_id='%s' % tenant_id).order_by( + "id").limit(limit).all() + + +def users_get_by_tenant_get_page_markers(tenant_id, marker, limit, \ + session=None): + if not session: + session = get_session() + user = aliased(models.User) + first = session.query(user).\ + filter(user.tenant_id == tenant_id).\ + order_by(user.id).first() + last = session.query(user).\ + filter(user.tenant_id == tenant_id).\ + order_by(user.id.desc()).first() + if first is None: + return (None, None) + if marker is None: + marker = first.id + next = session.query(user).\ + filter(user.tenant_id == tenant_id).\ + filter("id > :marker").params(\ + marker='%s' % marker).order_by(user.id).\ + limit(int(limit)).all() + prev = session.query(user).\ + filter(user.tenant_id == tenant_id).\ + filter("id < :marker").params( + marker='%s' % marker).order_by( + user.id.desc()).limit(int(limit)).all() + next_len = len(next) + prev_len = len(prev) + + if next_len == 0: + next = last + else: + for t in next: + next = t + if prev_len == 0: + prev = first + else: + for t in prev: + prev = t + if first.id == marker: + prev = None + else: + prev = prev.id + if marker == last.id: + next = None + else: + next = next.id + return (prev, next) + +def user_groups_get_all(user_id, session=None): + if not session: + session = get_session() + uga = aliased(models.UserGroupAssociation) + group = aliased(models.Group) + return session.query(group, uga).\ + join((uga, uga.group_id == group.id)).\ + filter(uga.user_id == user_id).order_by( + group.id).all() diff --git a/keystone/backends/sqlalchemy/models.py b/keystone/backends/sqlalchemy/models.py new file mode 100755 index 00000000..16bc7a75 --- /dev/null +++ b/keystone/backends/sqlalchemy/models.py @@ -0,0 +1,171 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# Copyright (c) 2010-2011 OpenStack, LLC. +# +# 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. +# Not Yet PEP8 standardized + +from sqlalchemy import Column, String, Integer, ForeignKey, \ + UniqueConstraint, Boolean, DateTime +from sqlalchemy.exc import IntegrityError +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import relationship, object_mapper +Base = declarative_base() + + +class KeystoneBase(object): + """Base class for Keystone Models.""" + __api__ = None + + def save(self, session=None): + """Save this object.""" + + if not session: + from keystone.backends.sqlalchemy import get_session + session = get_session() + session.add(self) + try: + session.flush() + except IntegrityError: + raise + + def delete(self, session=None): + """Delete this object.""" + self.save(session=session) + + def __setitem__(self, key, value): + setattr(self, key, value) + + def __getitem__(self, key): + return getattr(self, key) + + def get(self, key, default=None): + return getattr(self, key, default) + + def __iter__(self): + self._i = iter(object_mapper(self).columns) + return self + + def next(self): + n = self._i.next().name + return n, getattr(self, n) + + def update(self, values): + """Make the model object behave like a dict""" + for k, v in values.iteritems(): + setattr(self, k, v) + + def iteritems(self): + """Make the model object behave like a dict. + + Includes attributes from joins.""" + local = dict(self) + joined = dict([(k, v) for k, v in self.__dict__.iteritems() + if not k[0] == '_']) + local.update(joined) + return local.iteritems() + + +# Define associations first +class UserGroupAssociation(Base, KeystoneBase): + __tablename__ = 'user_group_association' + __api__ ='tenant_group' + user_id = Column(String(255), ForeignKey('users.id'), primary_key=True) + group_id = Column(String(255), ForeignKey('groups.id'), primary_key=True) + + +class UserRoleAssociation(Base, KeystoneBase): + __tablename__ = 'user_roles' + id = Column(Integer, primary_key=True) + user_id = Column(String(255), ForeignKey('users.id')) + role_id = Column(String(255), ForeignKey('roles.id')) + tenant_id = Column(String(255), ForeignKey('tenants.id')) + __table_args__ = (UniqueConstraint("user_id", "role_id", "tenant_id"), {}) + + +class Endpoints(Base, KeystoneBase): + __tablename__ = 'endpoints' + id = Column(Integer, primary_key=True) + tenant_id = Column(String(255), ForeignKey('tenants.id')) + endpoint_template_id = Column(Integer, ForeignKey('endpoint_templates.id')) + __table_args__ = (UniqueConstraint("endpoint_template_id",\ + "tenant_id"), {}) + + +# Define objects +class Role(Base, KeystoneBase): + __tablename__ = 'roles' + __api__ ='role' + id = Column(String(255), primary_key=True, unique=True) + desc = Column(String(255)) + + +class Tenant(Base, KeystoneBase): + __tablename__ = 'tenants' + __api__ ='tenant' + id = Column(String(255), primary_key=True, unique=True) + desc = Column(String(255)) + enabled = Column(Integer) + groups = relationship('Group', backref='tenants') + endpoints = relationship('Endpoints', backref='tenant', + cascade="all") + + +class User(Base, KeystoneBase): + __tablename__ = 'users' + __api__ ='user' + id = Column(String(255), primary_key=True, unique=True) + password = Column(String(255)) + email = Column(String(255)) + enabled = Column(Integer) + tenant_id = Column(String(255), ForeignKey('tenants.id')) + + groups = relationship(UserGroupAssociation, backref='users') + roles = relationship(UserRoleAssociation, cascade="all") + + +class Credentials(Base, KeystoneBase): + __tablename__ = 'credentials' + + user_id = Column(String(255), ForeignKey('users.id'), primary_key=True) + type = Column(String(20)) # ('Password','APIKey','EC2') + key = Column(String(255)) + secret = Column(String(255)) + + +class Group(Base, KeystoneBase): + __tablename__ = 'groups' + __api__ ='group' + id = Column(String(255), primary_key=True, unique=True) + desc = Column(String(255)) + tenant_id = Column(String(255), ForeignKey('tenants.id')) + +class Token(Base, KeystoneBase): + __tablename__ = 'token' + __api__ ='token' + id = Column(String(255), primary_key=True, unique=True) + user_id = Column(String(255)) + tenant_id = Column(String(255)) + expires = Column(DateTime) + +class EndpointTemplates(Base, KeystoneBase): + __tablename__ = 'endpoint_templates' + __api__ ='endpoint_template' + id = Column(Integer, primary_key=True) + region = Column(String(255)) + service = Column(String(255)) + public_url = Column(String(2000)) + admin_url = Column(String(2000)) + internal_url = Column(String(2000)) + enabled = Column(Boolean) + is_global = Column(Boolean) diff --git a/keystone/common/config.py b/keystone/common/config.py index 592e6cdd..e38c60a9 100755 --- a/keystone/common/config.py +++ b/keystone/common/config.py @@ -25,6 +25,7 @@ import optparse import os from paste import deploy import sys +import ConfigParser DEFAULT_LOG_FORMAT = "%(asctime)s %(levelname)8s [%(name)s] %(message)s" DEFAULT_LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S" @@ -294,11 +295,36 @@ def load_paste_config(app_name, options, args): "Cannot load application %s" % app_name) try: conf = deploy.appconfig("config:%s" % conf_file, name=app_name) + conf.global_conf.update(get_non_paste_configs(conf_file)) return conf_file, conf except Exception, e: raise RuntimeError("Error trying to load config %s: %s" % (conf_file, e)) +def get_non_paste_configs(conf_file): + load_config_files(conf_file) + complete_conf = load_config_files(conf_file) + #Add Non Paste global sections.Need to find a better way. + global_conf = {} + if complete_conf != None: + for section in complete_conf.sections(): + if not (section.startswith('filter:') or section.startswith('app:') or section.startswith('pipeline:')): + section_items = complete_conf.items(section) + section_items_dict = {} + for section_item in section_items: + section_items_dict[section_item[0]] = section_item[1] + global_conf[section] = section_items_dict + return global_conf + + +def load_config_files(config_files): + '''Load the config files.''' + config = ConfigParser.ConfigParser() + if config_files is not None: + config.read(config_files) + return config + + def load_paste_app(app_name, options, args): """ @@ -348,7 +374,7 @@ def load_paste_app(app_name, options, args): for key, value in sorted(items.items()): logger.info("%(key)-20s %(value)s" % locals()) logger.info("*" * 50) - app = deploy.loadapp("config:%s" % conf_file, name=app_name) + app = deploy.loadapp("config:%s" % conf_file, name=app_name, global_conf= conf.global_conf) except (LookupError, ImportError), e: raise RuntimeError("Unable to load %(app_name)s from " "configuration file %(conf_file)s." diff --git a/keystone/db/__init__.py b/keystone/db/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/keystone/db/sqlalchemy/__init__.py b/keystone/db/sqlalchemy/__init__.py deleted file mode 100644 index bdb9a5ba..00000000 --- a/keystone/db/sqlalchemy/__init__.py +++ /dev/null @@ -1,78 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2010 OpenStack LLC. -# 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 logging - -from sqlalchemy import create_engine -from sqlalchemy.orm import joinedload, aliased, sessionmaker - -from keystone.common import config -from keystone.db.sqlalchemy import models - -_ENGINE = None -_MAKER = None -BASE = models.Base - - -def configure_db(options): - """ - Establish the database, create an engine if needed, and - register the models. - - :param options: Mapping of configuration options - """ - global _ENGINE - if not _ENGINE: - debug = config.get_option( - options, 'debug', type='bool', default=False) - verbose = config.get_option( - options, 'verbose', type='bool', default=False) - timeout = config.get_option( - options, 'sql_idle_timeout', type='int', default=3600) - _ENGINE = create_engine(options['sql_connection'], - pool_recycle=timeout) - logger = logging.getLogger('sqlalchemy.engine') - if debug: - logger.setLevel(logging.DEBUG) - elif verbose: - logger.setLevel(logging.INFO) - register_models() - - -def get_session(autocommit=True, expire_on_commit=False): - """Helper method to grab session""" - global _MAKER, _ENGINE - if not _MAKER: - assert _ENGINE - _MAKER = sessionmaker(bind=_ENGINE, - autocommit=autocommit, - expire_on_commit=expire_on_commit) - return _MAKER() - - -def register_models(): - """Register Models and create properties""" - global _ENGINE - assert _ENGINE - BASE.metadata.create_all(_ENGINE) - - -def unregister_models(): - """Unregister Models, useful clearing out data before testing""" - global _ENGINE - assert _ENGINE - BASE.metadata.drop_all(_ENGINE) diff --git a/keystone/db/sqlalchemy/api/__init__.py b/keystone/db/sqlalchemy/api/__init__.py deleted file mode 100644 index 657621a6..00000000 --- a/keystone/db/sqlalchemy/api/__init__.py +++ /dev/null @@ -1 +0,0 @@ -import endpoint_template, group, role, tenant_group, tenant, token, user diff --git a/keystone/db/sqlalchemy/api/endpoint_template.py b/keystone/db/sqlalchemy/api/endpoint_template.py deleted file mode 100755 index f09479e5..00000000 --- a/keystone/db/sqlalchemy/api/endpoint_template.py +++ /dev/null @@ -1,185 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2010 OpenStack LLC. -# 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. - -from keystone.db.sqlalchemy import get_session, models, aliased - -def create(values): - endpoint_template = models.EndpointTemplates() - endpoint_template.update(values) - endpoint_template.save() - return endpoint_template - - -def get(id, session=None): - if not session: - session = get_session() - result = session.query(models.EndpointTemplates).filter_by(id=id).first() - return result - - -def get_all(session=None): - if not session: - session = get_session() - return session.query(models.EndpointTemplates).all() - - -def get_page(marker, limit, session=None): - if not session: - session = get_session() - - if marker: - return session.query(models.EndpointTemplates).filter("id>:marker").params(\ - marker='%s' % marker).order_by(\ - models.EndpointTemplates.id.desc()).limit(limit).all() - else: - return session.query(models.EndpointTemplates).order_by(\ - models.EndpointTemplates.id.desc()).limit(limit).all() - - -def get_page_markers(marker, limit, session=None): - if not session: - session = get_session() - first = session.query(models.EndpointTemplates).order_by(\ - models.EndpointTemplates.id).first() - last = session.query(models.EndpointTemplates).order_by(\ - models.EndpointTemplates.id.desc()).first() - if first is None: - return (None, None) - if marker is None: - marker = first.id - next = session.query(models.EndpointTemplates).filter("id > :marker").params(\ - marker='%s' % marker).order_by(\ - models.EndpointTemplates.id).limit(limit).all() - prev = session.query(models.EndpointTemplates).filter("id < :marker").params(\ - marker='%s' % marker).order_by(\ - models.EndpointTemplates.id.desc()).limit(int(limit)).all() - if len(next) == 0: - next = last - else: - for t in next: - next = t - if len(prev) == 0: - prev = first - else: - for t in prev: - prev = t - if prev.id == marker: - prev = None - else: - prev = prev.id - if next.id == last.id: - next = None - else: - next = next.id - return (prev, next) - - -def endpoint_get_by_tenant_get_page(tenant_id, marker, limit, - session=None): - if not session: - session = get_session() - if marker: - return session.query(models.Endpoints).\ - filter(models.Endpoints.tenant_id == tenant_id).\ - filter("id >= :marker").params( - marker='%s' % marker).order_by( - models.Endpoints.id).limit(limit).all() - else: - return session.query(models.Endpoints).\ - filter(models.Endpoints.tenant_id == tenant_id).\ - order_by(models.Endpoints.id).limit(limit).all() - - -def endpoint_get_by_tenant_get_page_markers(tenant_id, marker, limit, - session=None): - if not session: - session = get_session() - tba = aliased(models.Endpoints) - first = session.query(tba).\ - filter(tba.tenant_id == tenant_id).\ - order_by(tba.id).first() - last = session.query(tba).\ - filter(tba.tenant_id == tenant_id).\ - order_by(tba.id.desc()).first() - if first is None: - return (None, None) - if marker is None: - marker = first.id - next = session.query(tba).\ - filter(tba.tenant_id == tenant_id).\ - filter("id>=:marker").params( - marker='%s' % marker).order_by( - tba.id).limit(int(limit)).all() - - prev = session.query(tba).\ - filter(tba.tenant_id == tenant_id).\ - filter("id < :marker").params( - marker='%s' % marker).order_by( - tba.id).limit(int(limit) + 1).all() - next_len = len(next) - prev_len = len(prev) - - if next_len == 0: - next = last - else: - for t in next: - next = t - if prev_len == 0: - prev = first - else: - for t in prev: - prev = t - if first.id == marker: - prev = None - else: - prev = prev.id - if marker == last.id: - next = None - else: - next = next.id - return (prev, next) - - -def endpoint_add(values): - endpoints = models.Endpoints() - endpoints.update(values) - endpoints.save() - return endpoints - - -def endpoint_get(id, session=None): - if not session: - session = get_session() - result = session.query(models.Endpoints).\ - filter_by(id=id).first() - return result - - -def endpoint_get_by_tenant(tenant_id, session=None): - if not session: - session = get_session() - result = session.query(models.Endpoints).\ - filter_by(tenant_id=tenant_id).first() - return result - - -def endpoint_delete(id, session=None): - if not session: - session = get_session() - with session.begin(): - endpoints = endpoint_get(id, session) - session.delete(endpoints) diff --git a/keystone/db/sqlalchemy/api/group.py b/keystone/db/sqlalchemy/api/group.py deleted file mode 100644 index dbc75752..00000000 --- a/keystone/db/sqlalchemy/api/group.py +++ /dev/null @@ -1,170 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2010 OpenStack LLC. -# 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. - -from keystone.db.sqlalchemy import get_session, models, aliased - -def get(id, session=None): - if not session: - session = get_session() - result = session.query(models.Group).filter_by(id=id).first() - return result - - -def get_users(id, session=None): - if not session: - session = get_session() - result = session.query(models.User).filter_by(\ - group_id=id) - return result - - -def get_all(session=None): - if not session: - session = get_session() - result = session.query(models.Group) - return result - - -def get_page(marker, limit, session=None): - if not session: - session = get_session() - - if marker: - return session.query(models.Group).filter("id>:marker").params(\ - marker='%s' % marker).order_by(\ - models.Group.id.desc()).limit(limit).all() - else: - return session.query(models.Group).order_by(\ - models.Group.id.desc()).limit(limit).all() - - -def get_page_markers(marker, limit, session=None): - if not session: - session = get_session() - first = session.query(models.Group).order_by(\ - models.Group.id).first() - last = session.query(models.Group).order_by(\ - models.Group.id.desc()).first() - if first is None: - return (None, None) - if marker is None: - marker = first.id - next = session.query(models.Group).filter("id > :marker").params(\ - marker='%s' % marker).order_by(\ - models.Group.id).limit(limit).all() - prev = session.query(models.Group).filter("id < :marker").params(\ - marker='%s' % marker).order_by(\ - models.Group.id.desc()).limit(int(limit)).all() - if len(next) == 0: - next = last - else: - for t in next: - next = t - if len(prev) == 0: - prev = first - else: - for t in prev: - prev = t - if prev.id == marker: - prev = None - else: - prev = prev.id - if next.id == last.id: - next = None - else: - next = next.id - return (prev, next) - - -def delete(id, session=None): - if not session: - session = get_session() - with session.begin(): - group_ref = get(id, session) - session.delete(group_ref) - -def get_by_user_get_page(user_id, marker, limit, session=None): - if not session: - session = get_session() - uga = aliased(models.UserGroupAssociation) - group = aliased(models.Group) - if marker: - return session.query(group, uga).join(\ - (uga, uga.group_id == group.id)).\ - filter(uga.user_id == user_id).\ - filter("id>=:marker").params( - marker='%s' % marker).order_by( - group.id).limit(limit).all() - else: - return session.query(group, uga).\ - join((uga, uga.group_id == group.id)).\ - filter(uga.user_id == user_id).order_by( - group.id).limit(limit).all() - - -def get_by_user_get_page_markers(user_id, marker, limit, session=None): - if not session: - session = get_session() - uga = aliased(models.UserGroupAssociation) - group = aliased(models.Group) - first, _firstassoc = session.query(group, uga).\ - join((uga, uga.group_id == group.id)).\ - filter(uga.user_id == user_id).\ - order_by(group.id).first() - last, _lastassoc = session.query(group, uga).\ - join((uga, uga.group_id == group.id)).\ - filter(uga.user_id == user_id).\ - order_by(group.id.desc()).first() - if first is None: - return (None, None) - if marker is None: - marker = first.id - next = session.query(group, uga).join( - (uga, uga.group_id == group.id)).\ - filter(uga.user_id == user_id).\ - filter("id>=:marker").params( - marker='%s' % marker).order_by( - group.id).limit(int(limit)).all() - - prev = session.query(group, uga).join( - (uga, uga.group_id == group.id)).\ - filter(uga.user_id == user_id).\ - filter("id < :marker").params( - marker='%s' % marker).order_by( - group.id).limit(int(limit) + 1).all() - next_len = len(next) - prev_len = len(prev) - - if next_len == 0: - next = last - else: - for t, _a in next: - next = t - if prev_len == 0: - prev = first - else: - for t, _a in prev: - prev = t - if first.id == marker: - prev = None - else: - prev = prev.id - if marker == last.id: - next = None - else: - next = next.id - return (prev, next) diff --git a/keystone/db/sqlalchemy/api/role.py b/keystone/db/sqlalchemy/api/role.py deleted file mode 100644 index 1d39be0a..00000000 --- a/keystone/db/sqlalchemy/api/role.py +++ /dev/null @@ -1,174 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2010 OpenStack LLC. -# 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. - -from keystone.db.sqlalchemy import get_session, models - -def create(values): - role_ref = models.Role() - role_ref.update(values) - role_ref.save() - return role_ref - - -def get(id, session=None): - if not session: - session = get_session() - result = session.query(models.Role).filter_by(id=id).first() - return result - - -def get_all(session=None): - if not session: - session = get_session() - return session.query(models.Role).all() - - -def get_page(marker, limit, session=None): - if not session: - session = get_session() - - if marker: - return session.query(models.Role).filter("id>:marker").params(\ - marker='%s' % marker).order_by(\ - models.Role.id.desc()).limit(limit).all() - else: - return session.query(models.Role).order_by(\ - models.Role.id.desc()).limit(limit).all() - - -def ref_get_page(marker, limit, user_id, session=None): - if not session: - session = get_session() - - if marker: - return session.query(models.UserRoleAssociation).\ - filter("id>:marker").params(\ - marker='%s' % marker).filter_by(user_id=user_id).order_by(\ - models.UserRoleAssociation.id.desc()).limit(limit).all() - else: - return session.query(models.UserRoleAssociation).\ - filter_by(user_id=user_id).order_by(\ - models.UserRoleAssociation.id.desc()).limit(limit).all() - - -def ref_get_all_global_roles(user_id, session=None): - if not session: - session = get_session() - return session.query(models.UserRoleAssociation).\ - filter_by(user_id=user_id).filter("tenant_id is null").all() - - -def ref_get_all_tenant_roles(user_id, tenant_id, session=None): - if not session: - session = get_session() - return session.query(models.UserRoleAssociation).\ - filter_by(user_id=user_id).filter_by(tenant_id=tenant_id).all() - - -def ref_get(id, session=None): - if not session: - session = get_session() - result = session.query(models.UserRoleAssociation).filter_by(id=id).first() - return result - - -def ref_delete(id, session=None): - if not session: - session = get_session() - with session.begin(): - role_ref = ref_get(id, session) - session.delete(role_ref) - -def get_page_markers(marker, limit, session=None): - if not session: - session = get_session() - first = session.query(models.Role).order_by(\ - models.Role.id).first() - last = session.query(models.Role).order_by(\ - models.Role.id.desc()).first() - if first is None: - return (None, None) - if marker is None: - marker = first.id - next = session.query(models.Role).filter("id > :marker").params(\ - marker='%s' % marker).order_by(\ - models.Role.id).limit(limit).all() - prev = session.query(models.Role).filter("id < :marker").params(\ - marker='%s' % marker).order_by(\ - models.Role.id.desc()).limit(int(limit)).all() - if len(next) == 0: - next = last - else: - for t in next: - next = t - if len(prev) == 0: - prev = first - else: - for t in prev: - prev = t - if prev.id == marker: - prev = None - else: - prev = prev.id - if next.id == last.id: - next = None - else: - next = next.id - return (prev, next) - - -def ref_get_page_markers(user_id, marker, limit, session=None): - if not session: - session = get_session() - first = session.query(models.UserRoleAssociation).filter_by(\ - user_id=user_id).order_by(\ - models.UserRoleAssociation.id).first() - last = session.query(models.UserRoleAssociation).filter_by(\ - user_id=user_id).order_by(\ - models.UserRoleAssociation.id.desc()).first() - if first is None: - return (None, None) - if marker is None: - marker = first.id - next = session.query(models.UserRoleAssociation).filter_by(\ - user_id=user_id).filter("id > :marker").params(\ - marker='%s' % marker).order_by(\ - models.UserRoleAssociation.id).limit(limit).all() - prev = session.query(models.UserRoleAssociation).filter_by(\ - user_id=user_id).filter("id < :marker").params(\ - marker='%s' % marker).order_by(\ - models.UserRoleAssociation.id.desc()).limit(int(limit)).\ - all() - if len(next) == 0: - next = last - else: - for t in next: - next = t - if len(prev) == 0: - prev = first - else: - for t in prev: - prev = t - if prev.id == marker: - prev = None - else: - prev = prev.id - if next.id == last.id: - next = None - else: - next = next.id - return (prev, next) diff --git a/keystone/db/sqlalchemy/api/tenant.py b/keystone/db/sqlalchemy/api/tenant.py deleted file mode 100755 index 6617cb68..00000000 --- a/keystone/db/sqlalchemy/api/tenant.py +++ /dev/null @@ -1,203 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2010 OpenStack LLC. -# 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. - -from keystone.db.sqlalchemy import get_session, models, aliased - - -def create(values): - tenant_ref = models.Tenant() - tenant_ref.update(values) - tenant_ref.save() - return tenant_ref - - -def get(id, session=None): - if not session: - session = get_session() - result = session.query(models.Tenant).filter_by(id=id).first() - return result - - -def get_all(session=None): - if not session: - session = get_session() - return session.query(models.Tenant).all() - - -def tenants_for_user_get_page(user, marker, limit, session=None): - if not session: - session = get_session() - ura = aliased(models.UserRoleAssociation) - tenant = aliased(models.Tenant) - q1 = session.query(tenant).join((ura, ura.tenant_id == tenant.id)).\ - filter(ura.user_id == user.id) - q2 = session.query(tenant).filter(tenant.id == user.tenant_id) - q3 = q1.union(q2) - if marker: - return q3.filter("tenant.id>:marker").params(\ - marker='%s' % marker).order_by(\ - tenant.id.desc()).limit(limit).all() - else: - return q3.order_by(tenant.id.desc()).limit(limit).all() - - -def tenants_for_user_get_page_markers(user, marker, limit, session=None): - if not session: - session = get_session() - ura = aliased(models.UserRoleAssociation) - tenant = aliased(models.Tenant) - q1 = session.query(tenant).join((ura, ura.tenant_id == tenant.id)).\ - filter(ura.user_id == user.id) - q2 = session.query(tenant).filter(tenant.id == user.tenant_id) - q3 = q1.union(q2) - - first = q3.order_by(\ - tenant.id).first() - last = q3.order_by(\ - tenant.id.desc()).first() - if first is None: - return (None, None) - if marker is None: - marker = first.id - next = q3.filter(tenant.id > marker).order_by(\ - tenant.id).limit(limit).all() - prev = q3.filter(tenant.id > marker).order_by(\ - tenant.id.desc()).limit(int(limit)).all() - if len(next) == 0: - next = last - else: - for t in next: - next = t - if len(prev) == 0: - prev = first - else: - for t in prev: - prev = t - if prev.id == marker: - prev = None - else: - prev = prev.id - if next.id == last.id: - next = None - else: - next = next.id - return (prev, next) - - -def get_page(marker, limit, session=None): - if not session: - session = get_session() - - if marker: - return session.query(models.Tenant).filter("id>:marker").params(\ - marker='%s' % marker).order_by(\ - models.Tenant.id.desc()).limit(limit).all() - else: - return session.query(models.Tenant).order_by(\ - models.Tenant.id.desc()).limit(limit).all() - - -def get_page_markers(marker, limit, session=None): - if not session: - session = get_session() - first = session.query(models.Tenant).order_by(\ - models.Tenant.id).first() - last = session.query(models.Tenant).order_by(\ - models.Tenant.id.desc()).first() - if first is None: - return (None, None) - if marker is None: - marker = first.id - next = session.query(models.Tenant).filter("id > :marker").params(\ - marker='%s' % marker).order_by(\ - models.Tenant.id).limit(limit).all() - prev = session.query(models.Tenant).filter("id < :marker").params(\ - marker='%s' % marker).order_by(\ - models.Tenant.id.desc()).limit(int(limit)).all() - if len(next) == 0: - next = last - else: - for t in next: - next = t - if len(prev) == 0: - prev = first - else: - for t in prev: - prev = t - if prev.id == marker: - prev = None - else: - prev = prev.id - if next.id == last.id: - next = None - else: - next = next.id - return (prev, next) - - -def is_empty(id, session=None): - if not session: - session = get_session() - a_user = session.query(models.UserRoleAssociation).filter_by(\ - tenant_id=id).first() - if a_user != None: - return False - a_group = session.query(models.Group).filter_by(tenant_id=id).first() - if a_group != None: - return False - a_user = session.query(models.User).filter_by(tenant_id=id).first() - if a_user != None: - return False - return True - - -def update(id, values, session=None): - if not session: - session = get_session() - with session.begin(): - tenant_ref = get(id, session) - tenant_ref.update(values) - tenant_ref.save(session=session) - - -def delete(id, session=None): - if not session: - session = get_session() - with session.begin(): - tenant_ref = get(id, session) - session.delete(tenant_ref) - - -def get_all_endpoints(tenant_id, session=None): - if not session: - session = get_session() - ep = aliased(models.Endpoints) - endpointTemplates = aliased(models.EndpointTemplates) - q1 = session.query(endpointTemplates).join((ep, - ep.endpoint_template_id == endpointTemplates.id)).\ - filter(ep.tenant_id == tenant_id) - q2 = session.query(endpointTemplates).\ - filter(endpointTemplates.is_global == 1) - q3 = q1.union(q2) - return q3.all() - - -def get_role_assignments(tenant_id, session=None): - if not session: - session = get_session() - return session.query(models.UserRoleAssociation).\ - filter_by(tenant_id=tenant_id) diff --git a/keystone/db/sqlalchemy/api/tenant_group.py b/keystone/db/sqlalchemy/api/tenant_group.py deleted file mode 100644 index 4efce544..00000000 --- a/keystone/db/sqlalchemy/api/tenant_group.py +++ /dev/null @@ -1,118 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2010 OpenStack LLC. -# 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. - -from keystone.db.sqlalchemy import get_session, models - -def create(values): - group_ref = models.Group() - group_ref.update(values) - group_ref.save() - return group_ref - - -def is_empty(id, session=None): - if not session: - session = get_session() - a_user = session.query(models.UserGroupAssociation).filter_by( - group_id=id).first() - if a_user != None: - return False - return True - - -def get(id, tenant, session=None): - if not session: - session = get_session() - result = session.query(models.Group).filter_by(id=id, \ - tenant_id=tenant).first() - - return result - - -def get_page(tenantId, marker, limit, session=None): - if not session: - session = get_session() - - if marker: - return session.query(models.Group).filter("id>:marker").params(\ - marker='%s' % marker).filter_by(\ - tenant_id=tenantId).order_by(\ - models.Group.id.desc()).limit(limit).all() - else: - return session.query(models.Group).filter_by(tenant_id=tenantId)\ - .order_by(models.Group.id.desc()).limit(limit).all() - #return session.query(models.Tenant).all() - - -def get_page_markers(tenantId, marker, limit, session=None): - if not session: - session = get_session() - first = session.query(models.Group).filter_by(\ - tenant_id=tenantId).order_by(\ - models.Group.id).first() - last = session.query(models.Group).filter_by(\ - tenant_id=tenantId).order_by(\ - models.Group.id.desc()).first() - - if first is None: - return (None, None) - if marker is None: - marker = first.id - next = session.query(models.Group).filter("id > :marker").params(\ - marker='%s' % marker).filter_by(\ - tenant_id=tenantId).order_by(\ - models.Group.id).limit(limit).all() - prev = session.query(models.Group).filter("id < :marker").params(\ - marker='%s' % marker).filter_by(\ - tenant_id=tenantId).order_by(\ - models.Group.id.desc()).limit(int(limit)).all() - if len(next) == 0: - next = last - else: - for t in next: - next = t - if len(prev) == 0: - prev = first - else: - for t in prev: - prev = t - if prev.id == marker: - prev = None - else: - prev = prev.id - if next.id == last.id: - next = None - else: - next = next.id - return (prev, next) - - -def update(id, tenant_id, values, session=None): - if not session: - session = get_session() - with session.begin(): - tenant_ref = get(id, tenant_id, session) - tenant_ref.update(values) - tenant_ref.save(session=session) - - -def delete(id, tenant_id, session=None): - if not session: - session = get_session() - with session.begin(): - tenantgroup_ref = get(id, tenant_id, session) - session.delete(tenantgroup_ref) diff --git a/keystone/db/sqlalchemy/api/token.py b/keystone/db/sqlalchemy/api/token.py deleted file mode 100644 index 0c43af67..00000000 --- a/keystone/db/sqlalchemy/api/token.py +++ /dev/null @@ -1,61 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2010 OpenStack LLC. -# 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. - -from keystone.db.sqlalchemy import get_session, models - -def create(values): - token_ref = models.Token() - token_ref.update(values) - token_ref.save() - return token_ref - - -def get(id, session=None): - if not session: - session = get_session() - result = session.query(models.Token).filter_by(id=id).first() - return result - - -def delete(id, session=None): - if not session: - session = get_session() - with session.begin(): - token_ref = get(id, session) - session.delete(token_ref) - - -def get_for_user(user_id, session=None): - if not session: - session = get_session() - result = session.query(models.Token).filter_by( - user_id=user_id, tenant_id=None).order_by("expires desc").first() - return result - - -def get_for_user_by_tenant(user_id, tenant_id, session=None): - if not session: - session = get_session() - result = session.query(models.Token).filter_by( - user_id=user_id, tenant_id=tenant_id).order_by("expires desc").first() - return result - - -def get_all(session=None): - if not session: - session = get_session() - return session.query(models.Token).all() diff --git a/keystone/db/sqlalchemy/api/user.py b/keystone/db/sqlalchemy/api/user.py deleted file mode 100755 index d3d31387..00000000 --- a/keystone/db/sqlalchemy/api/user.py +++ /dev/null @@ -1,429 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2010 OpenStack LLC. -# 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 keystone.utils as utils -from keystone.db.sqlalchemy import get_session, models, aliased, joinedload - -def get_all(session=None): - if not session: - session = get_session() - result = session.query(models.User) - return result - - -def get_by_group(user_id, group_id, session=None): - if not session: - session = get_session() - result = session.query(models.UserGroupAssociation).filter_by(\ - group_id=group_id, user_id=user_id).first() - return result - - -def tenant_group(values): - user_ref = models.UserGroupAssociation() - user_ref.update(values) - user_ref.save() - return user_ref - - -def tenant_group_delete(id, group_id, session=None): - if not session: - session = get_session() - with session.begin(): - usertenantgroup_ref = get_by_group(id, group_id, session) - session.delete(usertenantgroup_ref) - - -def create(values): - user_ref = models.User() - check_and_use_hashed_password(values) - user_ref.update(values) - user_ref.save() - return user_ref - -def check_and_use_hashed_password(values): - if type(values) is dict and 'password' in values.keys(): - values['password'] = utils.get_hashed_password(values['password']) - elif type(values) is models.User: - values.password = utils.get_hashed_password(values.password) - -def get(id, session=None): - if not session: - session = get_session() - #TODO(Ziad): finish cleaning up model - # result = session.query(models.User).options(joinedload('groups')).\ - # options(joinedload('tenants')).filter_by(id=id).first() - result = session.query(models.User).filter_by(id=id).first() - return result - - -def get_page(marker, limit, session=None): - if not session: - session = get_session() - - if marker: - return session.query(models.User).filter("id>:marker").params(\ - marker='%s' % marker).order_by(\ - models.User.id.desc()).limit(limit).all() - else: - return session.query(models.User).order_by(\ - models.User.id.desc()).limit(limit).all() - - -def get_page_markers(marker, limit, session=None): - if not session: - session = get_session() - first = session.query(models.User).order_by(\ - models.User.id).first() - last = session.query(models.User).order_by(\ - models.User.id.desc()).first() - if first is None: - return (None, None) - if marker is None: - marker = first.id - next = session.query(models.User).filter("id > :marker").params(\ - marker='%s' % marker).order_by(\ - models.User.id).limit(limit).all() - prev = session.query(models.User).filter("id < :marker").params(\ - marker='%s' % marker).order_by(\ - models.User.id.desc()).limit(int(limit)).all() - if len(next) == 0: - next = last - else: - for t in next: - next = t - if len(prev) == 0: - prev = first - else: - for t in prev: - prev = t - if prev.id == marker: - prev = None - else: - prev = prev.id - if next.id == last.id: - next = None - else: - next = next.id - return (prev, next) - - -def get_by_email(email, session=None): - if not session: - session = get_session() - result = session.query(models.User).filter_by(email=email).first() - return result - - -def get_groups(id, session=None): - if not session: - session = get_session() - result = session.query(models.Group).filter_by(\ - user_id=id) - return result - - -def user_roles_by_tenant(user_id, tenant_id, session=None): - if not session: - session = get_session() - result = session.query(models.UserRoleAssociation).filter_by(\ - user_id=user_id, tenant_id=tenant_id).options(joinedload('roles')) - return result - - -def update(id, values, session=None): - if not session: - session = get_session() - with session.begin(): - user_ref = get(id, session) - check_and_use_hashed_password(values) - user_ref.update(values) - user_ref.save(session=session) - - -def users_tenant_group_get_page(group_id, marker, limit, session=None): - if not session: - session = get_session() - uga = aliased(models.UserGroupAssociation) - user = aliased(models.User) - if marker: - return session.query(user, uga).join(\ - (uga, uga.user_id == user.id)).\ - filter(uga.group_id == group_id).\ - filter("id>=:marker").params(\ - marker='%s' % marker).order_by(\ - user.id).limit(limit).all() - else: - return session.query(user, uga).\ - join((uga, uga.user_id == user.id)).\ - filter(uga.group_id == group_id).order_by(\ - user.id).limit(limit).all() - - -def users_tenant_group_get_page_markers(group_id, marker, limit, session=None): - if not session: - session = get_session() - uga = aliased(models.UserGroupAssociation) - user = aliased(models.User) - first = session.query(models.User).order_by(\ - models.User.id).first() - last = session.query(models.User).order_by(\ - models.User.id.desc()).first() - if first is None: - return (None, None) - if marker is None: - marker = first.id - next = session.query(user).join( - (uga, uga.user_id == user.id)).\ - filter(uga.group_id == group_id).\ - filter("id > :marker").params(\ - marker='%s' % marker).order_by(\ - user.id).limit(limit).all() - prev = session.query(user).join(\ - (uga, uga.user_id == user.id)).\ - filter(uga.group_id == group_id).\ - filter("id < :marker").params(\ - marker='%s' % marker).order_by(\ - user.id.desc()).limit(int(limit)).all() - if len(next) == 0: - next = last - else: - for t in next: - next = t - if len(prev) == 0: - prev = first - else: - for t in prev: - prev = t - if prev.id == marker: - prev = None - else: - prev = prev.id - if next.id == last.id: - next = None - else: - next = next.id - return (prev, next) - - -def delete(id, session=None): - if not session: - session = get_session() - with session.begin(): - user_ref = get(id, session) - session.delete(user_ref) - - -def get_by_tenant(id, tenant_id, session=None): - if not session: - session = get_session() - # Most common use case: user lives in tenant - user = session.query(models.User).\ - filter_by(id=id, tenant_id=tenant_id).first() - if user: - return user - - # Find user through grants to this tenant - user_tenant = session.query(models.UserRoleAssociation).filter_by(\ - tenant_id=tenant_id, user_id=id).first() - if user_tenant: - return get(id, session) - else: - return None - - -def get_group_by_tenant(id, session=None): - if not session: - session = get_session() - user_group = session.query(models.Group).filter_by(tenant_id=id).all() - return user_group - - -def delete_tenant_user(id, tenant_id, session=None): - if not session: - session = get_session() - with session.begin(): - users_tenant_ref = users_get_by_tenant(id, tenant_id, session) - if users_tenant_ref is not None: - for user_tenant_ref in users_tenant_ref: - session.delete(user_tenant_ref) - - user_group_ref = get_group_by_tenant(tenant_id, session) - - if user_group_ref is not None: - for user_group in user_group_ref: - get_users = session.query(models.UserGroupAssociation)\ - .filter_by(user_id=id, - group_id=user_group.id).all() - for group_user in get_users: - session.delete(group_user) - - -def users_get_by_tenant(user_id, tenant_id, session=None): - if not session: - session = get_session() - result = session.query(models.User).filter_by(id=user_id, - tenant_id=tenant_id) - return result - -def user_role_add(values): - user_role_ref = models.UserRoleAssociation() - user_role_ref.update(values) - user_role_ref.save() - return user_role_ref - - -def user_get_update(id, session=None): - if not session: - session = get_session() - result = session.query(models.User).filter_by(id=id).first() - return result - - -def users_get_page(marker, limit, session=None): - if not session: - session = get_session() - user = aliased(models.User) - if marker: - return session.query(user).\ - filter("id>=:marker").params( - marker='%s' % marker).order_by( - "id").limit(limit).all() - else: - return session.query(user).\ - order_by("id").limit(limit).all() - -def users_get_page_markers(marker, limit, \ - session=None): - if not session: - session = get_session() - user = aliased(models.User) - first = session.query(user).\ - order_by(user.id).first() - last = session.query(user).\ - order_by(user.id.desc()).first() - if first is None: - return (None, None) - if marker is None: - marker = first.id - next = session.query(user).\ - filter("id > :marker").params(\ - marker='%s' % marker).order_by(user.id).\ - limit(int(limit)).all() - prev = session.query(user).\ - filter("id < :marker").params( - marker='%s' % marker).order_by( - user.id.desc()).limit(int(limit)).all() - next_len = len(next) - prev_len = len(prev) - - if next_len == 0: - next = last - else: - for t in next: - next = t - if prev_len == 0: - prev = first - else: - for t in prev: - prev = t - if first.id == marker: - prev = None - else: - prev = prev.id - if marker == last.id: - next = None - else: - next = next.id - return (prev, next) - - -def users_get_by_tenant_get_page(tenant_id, marker, limit, session=None): - if not session: - session = get_session() - user = aliased(models.User) - if marker: - return session.query(user).\ - filter("tenant_id = :tenant_id").\ - params(tenant_id='%s' % tenant_id).\ - filter("id>=:marker").params( - marker='%s' % marker).order_by( - "id").limit(limit).all() - else: - return session.query(user).\ - filter("tenant_id = :tenant_id").\ - params(tenant_id='%s' % tenant_id).order_by( - "id").limit(limit).all() - - -def users_get_by_tenant_get_page_markers(tenant_id, marker, limit, \ - session=None): - if not session: - session = get_session() - user = aliased(models.User) - first = session.query(user).\ - filter(user.tenant_id == tenant_id).\ - order_by(user.id).first() - last = session.query(user).\ - filter(user.tenant_id == tenant_id).\ - order_by(user.id.desc()).first() - if first is None: - return (None, None) - if marker is None: - marker = first.id - next = session.query(user).\ - filter(user.tenant_id == tenant_id).\ - filter("id > :marker").params(\ - marker='%s' % marker).order_by(user.id).\ - limit(int(limit)).all() - prev = session.query(user).\ - filter(user.tenant_id == tenant_id).\ - filter("id < :marker").params( - marker='%s' % marker).order_by( - user.id.desc()).limit(int(limit)).all() - next_len = len(next) - prev_len = len(prev) - - if next_len == 0: - next = last - else: - for t in next: - next = t - if prev_len == 0: - prev = first - else: - for t in prev: - prev = t - if first.id == marker: - prev = None - else: - prev = prev.id - if marker == last.id: - next = None - else: - next = next.id - return (prev, next) - -def user_groups_get_all(user_id, session=None): - if not session: - session = get_session() - uga = aliased(models.UserGroupAssociation) - group = aliased(models.Group) - return session.query(group, uga).\ - join((uga, uga.group_id == group.id)).\ - filter(uga.user_id == user_id).order_by( - group.id).all() diff --git a/keystone/db/sqlalchemy/models.py b/keystone/db/sqlalchemy/models.py deleted file mode 100644 index 427e2507..00000000 --- a/keystone/db/sqlalchemy/models.py +++ /dev/null @@ -1,173 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# Copyright (c) 2010-2011 OpenStack, LLC. -# -# 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. -# Not Yet PEP8 standardized - -from sqlalchemy import Column, String, Integer, ForeignKey, \ - UniqueConstraint, Boolean, DateTime -from sqlalchemy.exc import IntegrityError -from sqlalchemy.ext.declarative import declarative_base -from sqlalchemy.orm import relationship, object_mapper - -Base = declarative_base() - - -class KeystoneBase(object): - """Base class for Keystone Models.""" - - def save(self, session=None): - """Save this object.""" - - if not session: - from keystone.db.sqlalchemy import get_session - session = get_session() - session.add(self) - try: - session.flush() - except IntegrityError: - raise - - def delete(self, session=None): - """Delete this object.""" - self.save(session=session) - - def __setitem__(self, key, value): - setattr(self, key, value) - - def __getitem__(self, key): - return getattr(self, key) - - def get(self, key, default=None): - return getattr(self, key, default) - - def __iter__(self): - self._i = iter(object_mapper(self).columns) - return self - - def next(self): - n = self._i.next().name - return n, getattr(self, n) - - def update(self, values): - """Make the model object behave like a dict""" - for k, v in values.iteritems(): - setattr(self, k, v) - - def iteritems(self): - """Make the model object behave like a dict. - - Includes attributes from joins.""" - local = dict(self) - joined = dict([(k, v) for k, v in self.__dict__.iteritems() - if not k[0] == '_']) - local.update(joined) - return local.iteritems() - - -# Define associations first -class UserGroupAssociation(Base, KeystoneBase): - __tablename__ = 'user_group_association' - - user_id = Column(String(255), ForeignKey('users.id'), primary_key=True) - group_id = Column(String(255), ForeignKey('groups.id'), primary_key=True) - - -class UserRoleAssociation(Base, KeystoneBase): - __tablename__ = 'user_roles' - id = Column(Integer, primary_key=True) - user_id = Column(String(255), ForeignKey('users.id')) - role_id = Column(String(255), ForeignKey('roles.id')) - tenant_id = Column(String(255), ForeignKey('tenants.id')) - __table_args__ = (UniqueConstraint("user_id", "role_id", "tenant_id"), {}) - - -class Endpoints(Base, KeystoneBase): - __tablename__ = 'endpoints' - id = Column(Integer, primary_key=True) - tenant_id = Column(String(255), ForeignKey('tenants.id')) - endpoint_template_id = Column(Integer, ForeignKey('endpoint_templates.id')) - __table_args__ = (UniqueConstraint("endpoint_template_id",\ - "tenant_id"), {}) - - -# Define objects -class Role(Base, KeystoneBase): - __tablename__ = 'roles' - - id = Column(String(255), primary_key=True, unique=True) - desc = Column(String(255)) - - -class Tenant(Base, KeystoneBase): - __tablename__ = 'tenants' - - id = Column(String(255), primary_key=True, unique=True) - desc = Column(String(255)) - enabled = Column(Integer) - groups = relationship('Group', backref='tenants') - endpoints = relationship('Endpoints', backref='tenant', - cascade="all") - - -class User(Base, KeystoneBase): - __tablename__ = 'users' - - id = Column(String(255), primary_key=True, unique=True) - password = Column(String(255)) - email = Column(String(255)) - enabled = Column(Integer) - tenant_id = Column(String(255), ForeignKey('tenants.id')) - - groups = relationship(UserGroupAssociation, backref='users') - roles = relationship(UserRoleAssociation, cascade="all") - - -class Credentials(Base, KeystoneBase): - __tablename__ = 'credentials' - - user_id = Column(String(255), ForeignKey('users.id'), primary_key=True) - type = Column(String(20)) # ('Password','APIKey','EC2') - key = Column(String(255)) - secret = Column(String(255)) - - -class Group(Base, KeystoneBase): - __tablename__ = 'groups' - - id = Column(String(255), primary_key=True, unique=True) - desc = Column(String(255)) - tenant_id = Column(String(255), ForeignKey('tenants.id')) - - -class Token(Base, KeystoneBase): - __tablename__ = 'token' - - id = Column(String(255), primary_key=True, unique=True) - user_id = Column(String(255)) - tenant_id = Column(String(255)) - expires = Column(DateTime) - - -class EndpointTemplates(Base, KeystoneBase): - __tablename__ = 'endpoint_templates' - - id = Column(Integer, primary_key=True) - region = Column(String(255)) - service = Column(String(255)) - public_url = Column(String(2000)) - admin_url = Column(String(2000)) - internal_url = Column(String(2000)) - enabled = Column(Boolean) - is_global = Column(Boolean) diff --git a/keystone/logic/service.py b/keystone/logic/service.py index be99a13a..172ff2c2 100755 --- a/keystone/logic/service.py +++ b/keystone/logic/service.py @@ -19,8 +19,8 @@ import uuid import keystone.logic.types.auth as auth import keystone.logic.types.atom as atom -import keystone.db.sqlalchemy.api as db_api -import keystone.db.sqlalchemy.models as db_models +import keystone.backends.api as db_api +import keystone.backends.sqlalchemy.models as db_models import keystone.logic.types.fault as fault import keystone.logic.types.tenant as tenants import keystone.logic.types.role as roles @@ -35,7 +35,6 @@ class IdentityService(object): # # Token Operations # - def authenticate(self, credentials): # Check credentials if not isinstance(credentials, auth.PasswordCredentials): diff --git a/keystone/server.py b/keystone/server.py index 114e6721..4f4fa483 100755 --- a/keystone/server.py +++ b/keystone/server.py @@ -49,7 +49,8 @@ if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'keystone', '__init__.py')): from keystone.common import wsgi -import keystone.db.sqlalchemy as db +import keystone.backends as db +import keystone.backends.alterdb import keystone.logic.service as serv import keystone.logic.types.tenant as tenants import keystone.logic.types.role as roles @@ -64,6 +65,7 @@ logger = logging.getLogger('keystone.server') VERSION_STATUS = "ALPHA" VERSION_DATE = "2011-04-23T00:00:00Z" + service = serv.IdentityService() @@ -530,14 +532,12 @@ def get_url(req): class KeystoneAPI(wsgi.Router): - """WSGI entry point for public Keystone API requests.""" + """WSGI entry point for public Keystone API requests.""" def __init__(self, options): self.options = options mapper = routes.Mapper() - - db.configure_db(options) - + db.configure_backends(options) # Token Operations auth_controller = AuthController(options) mapper.connect("/v2.0/tokens", controller=auth_controller, @@ -587,7 +587,7 @@ class KeystoneAdminAPI(wsgi.Router): self.options = options mapper = routes.Mapper() - db.configure_db(options) + db.configure_backends(options) # Token Operations auth_controller = AuthController(options) mapper.connect("/v2.0/tokens", controller=auth_controller, diff --git a/keystone/test/unit/base.py b/keystone/test/unit/base.py index 631e6cd3..c2dff063 100644 --- a/keystone/test/unit/base.py +++ b/keystone/test/unit/base.py @@ -27,8 +27,8 @@ from lxml import etree, objectify import webob from keystone import server -import keystone.db.sqlalchemy as db -import keystone.db.sqlalchemy.api as db_api +import keystone.backends.sqlalchemy as db +import keystone.backends.sqlalchemy.api as db_api logger = logging.getLogger('test.unit.base') diff --git a/keystone/utils.py b/keystone/utils.py old mode 100644 new mode 100755 index eb90b326..ddd63760 --- a/keystone/utils.py +++ b/keystone/utils.py @@ -165,6 +165,20 @@ def send_legacy_result(code, headers): #Currently using sha1 to hash.Need to figure if there is an openstack standard.Not using salt val as of now. def get_hashed_password(password): if password != None and len(password) > 0: - return hashlib.sha1(password).hexdigest() + return password + #return hashlib.sha1(password).hexdigest() else: - return None \ No newline at end of file + return None + +def import_module(module_name, class_name=None): + '''Import a class given a full module.class name or seperate + module and options. If no class_name is given, it is assumed to + be the last part of the module_name string.''' + if class_name is None: + module_name, _separator, class_name = module_name.rpartition('.') + try: + __import__(module_name) + return getattr(sys.modules[module_name], class_name) + except (ImportError, ValueError, AttributeError), exception: + raise ImportError(_('Class %s.%s cannot be found (%s)') % + (module_name, class_name, exception)) \ No newline at end of file diff --git a/setup.py b/setup.py old mode 100644 new mode 100755 -- cgit From e3f07c770720532ff48210797073fa34420e69ab Mon Sep 17 00:00:00 2001 From: Yogeshwar Srikrishnan Date: Tue, 28 Jun 2011 16:54:56 -0500 Subject: Adding list of todos. --- keystone/backends/api.py | 2 +- keystone/logic/service.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/keystone/backends/api.py b/keystone/backends/api.py index 782d3071..9bb23ae8 100755 --- a/keystone/backends/api.py +++ b/keystone/backends/api.py @@ -13,7 +13,7 @@ # limitations under the License. # Not Yet PEP8 standardized #API - +#TODO(Yogi) Refactor all API to separate classes specific to models. endpoint_template = None group = None role = None diff --git a/keystone/logic/service.py b/keystone/logic/service.py index 172ff2c2..59fc30d0 100755 --- a/keystone/logic/service.py +++ b/keystone/logic/service.py @@ -27,6 +27,7 @@ import keystone.logic.types.role as roles import keystone.logic.types.user as get_users import keystone.logic.types.endpoint as endpoints import keystone.utils as utils +#TODO(Yogi) Remove references to specific backend model and move them to generic models. class IdentityService(object): -- cgit