summaryrefslogtreecommitdiff
path: root/openstack_dashboard/api/keystone.py
diff options
context:
space:
mode:
Diffstat (limited to 'openstack_dashboard/api/keystone.py')
-rw-r--r--openstack_dashboard/api/keystone.py545
1 files changed, 0 insertions, 545 deletions
diff --git a/openstack_dashboard/api/keystone.py b/openstack_dashboard/api/keystone.py
deleted file mode 100644
index 87d112a7..00000000
--- a/openstack_dashboard/api/keystone.py
+++ /dev/null
@@ -1,545 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Openstack, LLC
-# Copyright 2012 Nebula, Inc.
-#
-# 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
-import urlparse
-
-from django.conf import settings
-from django.contrib.auth import logout
-from django.utils.translation import ugettext_lazy as _
-
-from keystoneclient.exceptions import ClientException
-
-from openstack_auth.backend import KEYSTONE_CLIENT_ATTR
-
-from horizon import exceptions
-from horizon import messages
-
-from openstack_dashboard.api import base
-
-
-LOG = logging.getLogger(__name__)
-DEFAULT_ROLE = None
-
-
-# Set up our data structure for managing Identity API versions, and
-# add a couple utility methods to it.
-class IdentityAPIVersionManager(base.APIVersionManager):
- def upgrade_v2_user(self, user):
- if getattr(user, "project_id", None) is None:
- user.project_id = getattr(user, "tenantId", None)
- return user
-
- def get_project_manager(self, *args, **kwargs):
- if VERSIONS.active < 3:
- manager = keystoneclient(*args, **kwargs).tenants
- else:
- manager = keystoneclient(*args, **kwargs).projects
- return manager
-
-
-VERSIONS = IdentityAPIVersionManager("identity", preferred_version=3)
-
-
-# Import from oldest to newest so that "preferred" takes correct precedence.
-try:
- from keystoneclient.v2_0 import client as keystone_client_v2
- VERSIONS.load_supported_version(2.0, {"client": keystone_client_v2})
-except ImportError:
- pass
-
-try:
- from keystoneclient.v3 import client as keystone_client_v3
- VERSIONS.load_supported_version(3, {"client": keystone_client_v3})
-except ImportError:
- pass
-
-
-class Service(base.APIDictWrapper):
- """ Wrapper for a dict based on the service data from keystone. """
- _attrs = ['id', 'type', 'name']
-
- def __init__(self, service, region, *args, **kwargs):
- super(Service, self).__init__(service, *args, **kwargs)
- self.public_url = base.get_url_for_service(service, region,
- 'publicURL')
- self.url = base.get_url_for_service(service, region, 'internalURL')
- if self.url:
- self.host = urlparse.urlparse(self.url).hostname
- else:
- self.host = None
- self.disabled = None
- self.region = region
-
- def __unicode__(self):
- if(self.type == "identity"):
- return _("%(type)s (%(backend)s backend)") \
- % {"type": self.type, "backend": keystone_backend_name()}
- else:
- return self.type
-
- def __repr__(self):
- return "<Service: %s>" % unicode(self)
-
-
-def _get_endpoint_url(request, endpoint_type, catalog=None):
- if getattr(request.user, "service_catalog", None):
- url = base.url_for(request,
- service_type='identity',
- endpoint_type=endpoint_type)
- else:
- auth_url = getattr(settings, 'OPENSTACK_KEYSTONE_URL')
- url = request.session.get('region_endpoint', auth_url)
-
- # TODO(gabriel): When the Service Catalog no longer contains API versions
- # in the endpoints this can be removed.
- bits = urlparse.urlparse(url)
- root = "://".join((bits.scheme, bits.netloc))
- url = "%s/v%s" % (root, VERSIONS.active)
-
- return url
-
-
-def keystoneclient(request, admin=False):
- """Returns a client connected to the Keystone backend.
-
- Several forms of authentication are supported:
-
- * Username + password -> Unscoped authentication
- * Username + password + tenant id -> Scoped authentication
- * Unscoped token -> Unscoped authentication
- * Unscoped token + tenant id -> Scoped authentication
- * Scoped token -> Scoped authentication
-
- Available services and data from the backend will vary depending on
- whether the authentication was scoped or unscoped.
-
- Lazy authentication if an ``endpoint`` parameter is provided.
-
- Calls requiring the admin endpoint should have ``admin=True`` passed in
- as a keyword argument.
-
- The client is cached so that subsequent API calls during the same
- request/response cycle don't have to be re-authenticated.
- """
- user = request.user
- if admin:
- if not user.is_superuser:
- raise exceptions.NotAuthorized
- endpoint_type = 'adminURL'
- else:
- endpoint_type = getattr(settings,
- 'OPENSTACK_ENDPOINT_TYPE',
- 'internalURL')
-
- api_version = VERSIONS.get_active_version()
-
- # Take care of client connection caching/fetching a new client.
- # Admin vs. non-admin clients are cached separately for token matching.
- cache_attr = "_keystoneclient_admin" if admin else KEYSTONE_CLIENT_ATTR
- if hasattr(request, cache_attr) and (not user.token.id
- or getattr(request, cache_attr).auth_token == user.token.id):
- LOG.debug("Using cached client for token: %s" % user.token.id)
- conn = getattr(request, cache_attr)
- else:
- endpoint = _get_endpoint_url(request, endpoint_type)
- insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False)
- LOG.debug("Creating a new keystoneclient connection to %s." % endpoint)
- remote_addr = request.environ.get('REMOTE_ADDR', '')
- conn = api_version['client'].Client(token=user.token.id,
- endpoint=endpoint,
- original_ip=remote_addr,
- insecure=insecure,
- auth_url=endpoint,
- debug=settings.DEBUG)
- setattr(request, cache_attr, conn)
- return conn
-
-
-def domain_create(request, name, description=None, enabled=None):
- manager = keystoneclient(request, admin=True).domains
- return manager.create(name,
- description=description,
- enabled=enabled)
-
-
-def domain_get(request, domain_id):
- manager = keystoneclient(request, admin=True).domains
- return manager.get(domain_id)
-
-
-def domain_delete(request, domain_id):
- manager = keystoneclient(request, admin=True).domains
- return manager.delete(domain_id)
-
-
-def domain_list(request):
- manager = keystoneclient(request, admin=True).domains
- return manager.list()
-
-
-def domain_update(request, domain_id, name=None, description=None,
- enabled=None):
- manager = keystoneclient(request, admin=True).domains
- return manager.update(domain_id, name, description, enabled)
-
-
-def tenant_create(request, name, description=None, enabled=None, domain=None):
- manager = VERSIONS.get_project_manager(request, admin=True)
- if VERSIONS.active < 3:
- return manager.create(name, description, enabled)
- else:
- return manager.create(name, domain,
- description=description,
- enabled=enabled)
-
-
-# TODO(gabriel): Is there ever a valid case for admin to be false here?
-# A quick search through the codebase reveals that it's always called with
-# admin=true so I suspect we could eliminate it entirely as with the other
-# tenant commands.
-def tenant_get(request, project, admin=True):
- manager = VERSIONS.get_project_manager(request, admin=admin)
- return manager.get(project)
-
-
-def tenant_delete(request, project):
- manager = VERSIONS.get_project_manager(request, admin=True)
- return manager.delete(project)
-
-
-def tenant_list(request, paginate=False, marker=None, domain=None, user=None):
- manager = VERSIONS.get_project_manager(request, admin=True)
- page_size = getattr(settings, 'API_RESULT_PAGE_SIZE', 20)
- limit = None
- if paginate:
- limit = page_size + 1
-
- has_more_data = False
- if VERSIONS.active < 3:
- tenants = manager.list(limit, marker)
- if paginate and len(tenants) > page_size:
- tenants.pop(-1)
- has_more_data = True
- else:
- tenants = manager.list(domain=domain, user=user)
- return (tenants, has_more_data)
-
-
-def tenant_update(request, project, name=None, description=None,
- enabled=None, domain=None):
- manager = VERSIONS.get_project_manager(request, admin=True)
- if VERSIONS.active < 3:
- return manager.update(project, name, description, enabled)
- else:
- return manager.update(project, name=name, description=description,
- enabled=enabled, domain=domain)
-
-
-def user_list(request, project=None, domain=None, group=None):
- if VERSIONS.active < 3:
- kwargs = {"tenant_id": project}
- else:
- kwargs = {
- "project": project,
- "domain": domain,
- "group": group
- }
- users = keystoneclient(request, admin=True).users.list(**kwargs)
- return [VERSIONS.upgrade_v2_user(user) for user in users]
-
-
-def user_create(request, name=None, email=None, password=None, project=None,
- enabled=None, domain=None):
- manager = keystoneclient(request, admin=True).users
- if VERSIONS.active < 3:
- user = manager.create(name, password, email, project, enabled)
- return VERSIONS.upgrade_v2_user(user)
- else:
- return manager.create(name, password=password, email=email,
- project=project, enabled=enabled, domain=domain)
-
-
-def user_delete(request, user_id):
- return keystoneclient(request, admin=True).users.delete(user_id)
-
-
-def user_get(request, user_id, admin=True):
- user = keystoneclient(request, admin=admin).users.get(user_id)
- return VERSIONS.upgrade_v2_user(user)
-
-
-def user_update(request, user, **data):
- manager = keystoneclient(request, admin=True).users
- error = None
-
- if not keystone_can_edit_user():
- raise ClientException(405, _("Identity service does not allow "
- "editing user data."))
-
- # The v2 API updates user model, password and default project separately
- if VERSIONS.active < 3:
- password = data.pop('password')
- project = data.pop('project')
-
- # Update user details
- try:
- user = manager.update(user, **data)
- except:
- error = exceptions.handle(request, ignore=True)
-
- # Update default tenant
- try:
- user_update_tenant(request, user, project)
- user.tenantId = project
- except:
- error = exceptions.handle(request, ignore=True)
-
- # Check for existing roles
- # Show a warning if no role exists for the project
- user_roles = roles_for_user(request, user, project)
- if not user_roles:
- messages.warning(request,
- _('User %s has no role defined for '
- 'that project.')
- % data.get('name', None))
-
- # If present, update password
- # FIXME(gabriel): password change should be its own form + view
- if password:
- try:
- user_update_password(request, user, password)
- if user == request.user.id:
- logout(request)
- except:
- error = exceptions.handle(request, ignore=True)
-
- if error is not None:
- raise error
-
- # v3 API is so much simpler...
- else:
- if not data['password']:
- data.pop('password')
- user = manager.update(user, **data)
-
- return VERSIONS.upgrade_v2_user(user)
-
-
-def user_update_enabled(request, user, enabled):
- manager = keystoneclient(request, admin=True).users
- if VERSIONS.active < 3:
- return manager.update_enabled(user, enabled)
- else:
- return manager.update(user, enabled=enabled)
-
-
-def user_update_password(request, user, password, admin=True):
- manager = keystoneclient(request, admin=admin).users
- if VERSIONS.active < 3:
- return manager.update_password(user, password)
- else:
- return manager.update(user, password=password)
-
-
-def user_update_own_password(request, origpassword, password):
- client = keystoneclient(request, admin=False)
- if VERSIONS.active < 3:
- client.user_id = request.user.id
- return client.users.update_own_password(origpassword, password)
- else:
- return client.users.update(request.user.id, password=password)
-
-
-def user_update_tenant(request, user, project, admin=True):
- manager = keystoneclient(request, admin=admin).users
- if VERSIONS.active < 3:
- return manager.update_tenant(user, project)
- else:
- return manager.update(user, project=project)
-
-
-def group_create(request, domain_id, name, description=None):
- manager = keystoneclient(request, admin=True).groups
- return manager.create(domain=domain_id,
- name=name,
- description=description)
-
-
-def group_get(request, group_id, admin=True):
- manager = keystoneclient(request, admin=admin).groups
- return manager.get(group_id)
-
-
-def group_delete(request, group_id):
- manager = keystoneclient(request, admin=True).groups
- return manager.delete(group_id)
-
-
-def group_list(request):
- manager = keystoneclient(request, admin=True).groups
- return manager.list()
-
-
-def group_update(request, group_id, name=None, description=None):
- manager = keystoneclient(request, admin=True).groups
- return manager.update(group=group_id,
- name=name,
- description=description)
-
-
-def add_group_user(request, group_id, user_id):
- manager = keystoneclient(request, admin=True).users
- return manager.add_to_group(group=group_id, user=user_id)
-
-
-def remove_group_user(request, group_id, user_id):
- manager = keystoneclient(request, admin=True).users
- return manager.remove_from_group(group=group_id, user=user_id)
-
-
-def role_create(request, name):
- manager = keystoneclient(request, admin=True).roles
- return manager.create(name)
-
-
-def role_get(request, role_id):
- manager = keystoneclient(request, admin=True).roles
- return manager.get(role_id)
-
-
-def role_update(request, role_id, name=None):
- manager = keystoneclient(request, admin=True).roles
- return manager.update(role_id, name)
-
-
-def role_delete(request, role_id):
- manager = keystoneclient(request, admin=True).roles
- return manager.delete(role_id)
-
-
-def role_list(request):
- """ Returns a global list of available roles. """
- return keystoneclient(request, admin=True).roles.list()
-
-
-def roles_for_user(request, user, project):
- manager = keystoneclient(request, admin=True).roles
- if VERSIONS.active < 3:
- return manager.roles_for_user(user, project)
- else:
- return manager.list(user=user, project=project)
-
-
-def add_tenant_user_role(request, project=None, user=None, role=None,
- group=None, domain=None):
- """ Adds a role for a user on a tenant. """
- manager = keystoneclient(request, admin=True).roles
- if VERSIONS.active < 3:
- return manager.add_user_role(user, role, project)
- else:
- return manager.grant(role, user=user, project=project,
- group=group, domain=domain)
-
-
-def remove_tenant_user_role(request, project=None, user=None, role=None,
- group=None, domain=None):
- """ Removes a given single role for a user from a tenant. """
- manager = keystoneclient(request, admin=True).roles
- if VERSIONS.active < 3:
- return manager.remove_user_role(user, role, project)
- else:
- return manager.revoke(role, user=user, project=project,
- group=group, domain=domain)
-
-
-def remove_tenant_user(request, project=None, user=None, domain=None):
- """ Removes all roles from a user on a tenant, removing them from it. """
- client = keystoneclient(request, admin=True)
- roles = client.roles.roles_for_user(user, project)
- for role in roles:
- remove_tenant_user_role(request, user=user, role=role.id,
- project=project, domain=domain)
-
-
-def get_default_role(request):
- """
- Gets the default role object from Keystone and saves it as a global
- since this is configured in settings and should not change from request
- to request. Supports lookup by name or id.
- """
- global DEFAULT_ROLE
- default = getattr(settings, "OPENSTACK_KEYSTONE_DEFAULT_ROLE", None)
- if default and DEFAULT_ROLE is None:
- try:
- roles = keystoneclient(request, admin=True).roles.list()
- except:
- roles = []
- exceptions.handle(request)
- for role in roles:
- if role.id == default or role.name == default:
- DEFAULT_ROLE = role
- break
- return DEFAULT_ROLE
-
-
-def list_ec2_credentials(request, user_id):
- return keystoneclient(request).ec2.list(user_id)
-
-
-def create_ec2_credentials(request, user_id, tenant_id):
- return keystoneclient(request).ec2.create(user_id, tenant_id)
-
-
-def get_user_ec2_credentials(request, user_id, access_token):
- return keystoneclient(request).ec2.get(user_id, access_token)
-
-
-def keystone_can_edit_domain():
- backend_settings = getattr(settings, "OPENSTACK_KEYSTONE_BACKEND", {})
- return backend_settings.get('can_edit_domain', True)
-
-
-def keystone_can_edit_user():
- backend_settings = getattr(settings, "OPENSTACK_KEYSTONE_BACKEND", {})
- return backend_settings.get('can_edit_user', True)
-
-
-def keystone_can_edit_project():
- backend_settings = getattr(settings, "OPENSTACK_KEYSTONE_BACKEND", {})
- return backend_settings.get('can_edit_project', True)
-
-
-def keystone_can_edit_group():
- backend_settings = getattr(settings, "OPENSTACK_KEYSTONE_BACKEND", {})
- return backend_settings.get('can_edit_group', True)
-
-
-def keystone_can_edit_role():
- backend_settings = getattr(settings, "OPENSTACK_KEYSTONE_BACKEND", {})
- return backend_settings.get('can_edit_role', True)
-
-
-def keystone_backend_name():
- if hasattr(settings, "OPENSTACK_KEYSTONE_BACKEND"):
- return settings.OPENSTACK_KEYSTONE_BACKEND['name']
- else:
- return 'unknown'