def delete(): """Delete user. Removes user from Keystone database. TODO(apugachev): pass user_id in path, make form empty just for CSRF sake. This provides better tracking via HTTPD logs. """ form = forms.DeleteUserForm() if form.validate_on_submit(): keystone_user = clients.admin_clients().keystone.users.get( form.user_id.data) if keystone_user.email: odb_user = utils.neo4j_api_call('/users', {"email": keystone_user.email}, 'GET')[0] else: odb_user_list = utils.neo4j_api_call('/users', method='GET') odb_user = filter(lambda x: x.username == keystone_user.name, odb_user_list) utils.neo4j_api_call('/users/%s' % odb_user['id'], method='DELETE') roles = keystone_user.list_roles() for role in roles: clients.admin_clients().keystone.tenants.remove_user( role.tenant['id'], keystone_user, role.role['id']) keystone_user.delete() flask.flash('User was deleted.', 'success') else: flask.flash('User was not deleted', 'error') return flask.redirect(flask.url_for('.index'))
def password_recovery_finish(recovery_hash): """ This will be called after user clicked link in email. """ try: id, email, hash_code, complete = \ row_mysql_queries.get_recovery_request_by_hash(recovery_hash) except TypeError: # db returns None flask.abort(404) if complete == 1: flask.flash('Password recovery token is expired', 'error') return flask.redirect(flask.url_for('dashboard')) odb_user = utils.neo4j_api_call('/users', {"email": email}, 'GET')[0] new_hash = str(uuid.uuid4()) # set trash password in keystone keystone_user = utils.get_keystone_user_by_username(odb_user['username']) clients.admin_clients().keystone.users.update_password(keystone_user, new_hash) # set trash password in odb utils.neo4j_api_call('/users', { 'id': odb_user['id'], 'login': odb_user['login'], 'username': odb_user['username'], 'email': odb_user['email'], 'passwordHash': utils.create_hashed_password(new_hash)}, 'PUT') # send trash password back to user msg = mail.Message('Password recovery', recipients=[odb_user['email']]) msg.body = flask.render_template('RecoveryPasswordFinishEmail/body.txt', new_pass=new_hash) utils.send_msg(msg) flask.flash('New password was sent to you', 'success') return flask.redirect(flask.url_for('dashboard'))
def delete(): """Delete user. Removes user from Keystone database. TODO(apugachev): pass user_id in path, make form empty just for CSRF sake. This provides better tracking via HTTPD logs. """ form = forms.DeleteUserForm() if form.validate_on_submit(): keystone_user = clients.admin_clients().keystone.users.get( form.user_id.data) if keystone_user.email: odb_user = utils.neo4j_api_call('/users', { "email": keystone_user.email }, 'GET')[0] else: odb_user_list = utils.neo4j_api_call('/users', method='GET') odb_user = filter( lambda x: x.username == keystone_user.name, odb_user_list) utils.neo4j_api_call('/users/%s' % odb_user['id'], method='DELETE') roles = keystone_user.list_roles() for role in roles: clients.admin_clients().keystone.tenants.remove_user( role.tenant['id'], keystone_user, role.role['id']) keystone_user.delete() flask.flash('User was deleted.', 'success') else: flask.flash('User was not deleted', 'error') return flask.redirect(flask.url_for('.index'))
def revoke_admin(user_id): """Revoke admin permission. Remove admin role in admin tenant (aka systenant). TODO(apugachev): convert to POST TODO(apugachev): add form to plug in the CSRF protection """ clients.admin_clients().keystone.roles.remove_user_role( user_id, clients.get_role_id("admin"), clients.get_systenant_id()) flask.flash('Admin role removed', 'success') return flask.redirect(flask.url_for('.index'))
def show(image_id): """Present details page for single image object. Tries using both Glance and Nova services because they provide different info set about an image. """ glance_image = clients.admin_clients().glance.images.get(image_id) nova_image = clients.admin_clients().nova.images.get(image_id) return { 'glance_image': glance_image, 'nova_image': nova_image, 'title': bp.name.replace('global_', '').replace('_', ' ').capitalize(), 'subtitle': 'Image details', }
def delete(object_id): """Delete network and associated fixed IPs.""" form = forms.DeleteForm() if form.validate_on_submit(): try: clients.admin_clients().compute.networks.delete(object_id) except HttpException as ex: if ex.code == 500: flask.flash('Network is in use. Delete all VMs for the network and try again.', 'error') else: flask.flash(ex.message, 'error') else: flask.flash('Network deleted.', 'success') return flask.redirect(flask.url_for('.index'))
def on_identity_loaded(sender, identity): """Add admin and project participation roles. If user is authenticated and user has admin role in systenant, he has role admin permission. If user is authenticated and user participates in a tenant, he has project member permission. Exclude endpoints which do not require authentication/authorization. """ is_anon = identity.name == 'anon' loose_endpoints = flask.current_app.config['ANONYMOUS_ALLOWED'] is_loose = flask.request.endpoint in loose_endpoints if is_loose or is_anon: return roles = (clients.admin_clients().identity_admin.roles. roles_for_user(identity.name)) is_admin = False for role_tenant in roles: if clients.role_tenant_is_admin(role_tenant): is_admin = True if clients.role_is_member(role_tenant.role["name"]): identity.provides.add( ('role', 'member', role_tenant.tenant["id"])) if is_admin: identity.provides.add(('role', 'admin'))
def index(): """List users. TODO(apugachev): find way to count users without fetching all users. This would allow to use marker and limit to fetch one page only. """ identity_admin = clients.admin_clients().identity_admin users = sorted( identity_admin.users.list(limit=1000000), key=lambda x: x.name) p = pagination.Pagination(users) data = p.slice(users) potential_admins = set([ user.id for user in (identity_admin.users.list(clients.get_systenant_id()))]) for user in data: # TODO(apugachev) modify to work with form.DeleteUser form = forms.DeleteUserForm() form.user_id.data = user.id user.delete_form = form if user.id in potential_admins: for role in (identity_admin.roles. roles_for_user(user.id)): if clients.role_tenant_is_admin(role): user.is_global_admin = True break return { 'pagination': p, 'data': data, 'title': bp.name.replace('global_', '').replace('_', ' ').capitalize(), 'subtitle': 'List of users' }
def delete(object_id): """Delete network and associated fixed IPs.""" form = forms.DeleteForm() if form.validate_on_submit(): try: clients.admin_clients().compute.networks.delete(object_id) except HttpException as ex: if ex.code == 500: flask.flash( 'Network is in use. Delete all VMs for the network and try again.', 'error') else: flask.flash(ex.message, 'error') else: flask.flash('Network deleted.', 'success') return flask.redirect(flask.url_for('.index'))
def get_images_list(): """Return list of images visible for given condigions. If g.tenant_id is not set it is admin blueprint. We have to show only images owned by systenant, which are also public (can be protected as well (we set it so, but other tools can change this attribute or set it to a wrong value from the beginning). If g.tenant_id is set it is project blueprint. We have to show the same images as for admin blueprint _and_ images owned by current project (attribute "owner" must be equal to g.tenant_id) no matter if image is public/protected. NOTE(apugachev): Currently for some reason Glance does not return list of images owned by tenant with id '1' even if they are public - if they are requested through token issued for some other project then '1'. That's why we combine image lists here in case if list is for project. """ admin_id = clients.get_systenant_id() is_global = lambda x: x.owner == admin_id and x.is_public result = filter( is_global, clients.admin_clients().glance.images.list()) if getattr(flask.g, 'tenant_id', None): result.extend(filter( lambda x: x.owner == flask.g.tenant_id and x not in result, clients.user_clients(flask.g.tenant_id).glance.images.list())) result = sorted(result, key=lambda x: x.name) return result
def on_identity_loaded(sender, identity): """Add admin and project participation roles. If user is authenticated and user has admin role in systenant, he has role admin permission. If user is authenticated and user participates in a tenant, he has project member permission. Exclude endpoints which do not require authentication/authorization. """ is_anon = identity.name == 'anon' loose_endpoints = flask.current_app.config['ANONYMOUS_ALLOWED'] is_loose = flask.request.endpoint in loose_endpoints if is_loose or is_anon: return roles = (clients.admin_clients().identity_admin.roles.roles_for_user( identity.name)) is_admin = False for role_tenant in roles: if clients.role_tenant_is_admin(role_tenant): is_admin = True if clients.role_is_member(role_tenant.role["name"]): identity.provides.add(('role', 'member', role_tenant.tenant["id"])) if is_admin: identity.provides.add(('role', 'admin'))
def get_images_list(): """Return list of images visible for given condigions. If g.tenant_id is not set it is admin blueprint. We have to show only images owned by systenant, which are also public (can be protected as well (we set it so, but other tools can change this attribute or set it to a wrong value from the beginning). If g.tenant_id is set it is project blueprint. We have to show the same images as for admin blueprint _and_ images owned by current project (attribute "owner" must be equal to g.tenant_id) no matter if image is public/protected. NOTE(apugachev): Currently for some reason Glance does not return list of images owned by tenant with id '1' even if they are public - if they are requested through token issued for some other project then '1'. That's why we combine image lists here in case if list is for project. """ admin_id = clients.get_systenant_id() is_global = lambda x: x.owner == admin_id and x.is_public result = filter(is_global, clients.admin_clients().glance.images.list()) if getattr(flask.g, 'tenant_id', None): result.extend( filter( lambda x: x.owner == flask.g.tenant_id and x not in result, clients.user_clients(flask.g.tenant_id).glance.images.list())) result = sorted(result, key=lambda x: x.name) return result
def index(): """List users. TODO(apugachev): find way to count users without fetching all users. This would allow to use marker and limit to fetch one page only. """ identity_admin = clients.admin_clients().identity_admin users = sorted(identity_admin.users.list(limit=1000000), key=lambda x: x.name) p = pagination.Pagination(users) data = p.slice(users) potential_admins = set([ user.id for user in (identity_admin.users.list(clients.get_systenant_id())) ]) for user in data: # TODO(apugachev) modify to work with form.DeleteUser form = forms.DeleteUserForm() form.user_id.data = user.id user.delete_form = form if user.id in potential_admins: for role in (identity_admin.roles.roles_for_user(user.id)): if clients.role_tenant_is_admin(role): user.is_global_admin = True break return { 'pagination': p, 'data': data, 'title': bp.name.replace('global_', '').replace('_', ' ').capitalize(), 'subtitle': 'List of users' }
def show_tenant(): """ List VMs for the project """ c = clients.user_clients(flask.g.tenant_id) servers = c.compute.servers.list(detailed=True) vms_data = [s._info for s in servers] vms_data = sorted(vms_data, key=lambda x: x['name']) p = pagination.Pagination(vms_data) data = p.slice(vms_data) user_id2name = {} uuid_regex = re.compile( r'[a-f0-9]{8}-?[a-f0-9]{4}-?[a-f0-9]{4}-?[a-f0-9]{4}-?[a-f0-9]{12}') for x in data: user_id = x['user_id'] try: x['user_id'] = user_id2name[user_id] pass except KeyError: if user_id.isdigit() or uuid_regex.match(user_id): try: user = clients.admin_clients().keystone.users.get(user_id) user_id2name[user_id] = user.name x['user_id'] = user.name except: pass return { 'vms': data, 'pagination': p, 'title': 'Virtual Machines', 'subtitle': 'List of virtual machines' }
def new(): """Create network. Insert record in db for network and create records for fixed IPs based on network CIDR. Creating fixed IPs like nova/network/manager.py:_create_fixed_ips() """ form = forms.CreateNetwork() if form.validate_on_submit(): label = 'net%s' % form.vlan.data try: networks = (clients.admin_clients().compute.networks. create(label=label, vlan_start=form.vlan.data, cidr=form.cidr.data)) except HttpException as ex: flask.flash(ex.message, 'error') else: flask.flash('Network %s created.' % label, 'success') return flask.redirect(flask.url_for('.index')) return { 'form': form, 'title': bp.name.replace('global_', '').replace('_', ' ').capitalize(), 'subtitle': 'Add new network' }
def show_vm(vm_id): server = clients.admin_clients().nova.servers.get(vm_id) try: flavor = clients.admin_clients().nova.flavors.get(server.flavor['id']) except NotFound: flavor = None try: image = clients.admin_clients().nova.images.get(server.image['id']) except NotFound: image = None return { 'server': server, 'flavor': flavor, 'image': image, 'title': 'Virtual Machines', 'subtitle': 'Virtual machine details' }
def show(object_id): net = clients.admin_clients().compute.networks.get(object_id) return { 'object': dict(((k, '-' if v is None else v) for k, v in net._info.iteritems())), 'title': bp.name.replace('global_', '').replace('_', ' ').capitalize(), 'subtitle': 'Network details' }
def setup_tenant(): if flask.request.endpoint not in BARE_ENDPOINTS: visible_ids = [x.id for x in utils.get_visible_tenants()] if flask.g.tenant_id not in visible_ids: flask.abort(404) principal.Permission(('role', 'member', flask.g.tenant_id)).test() flask.g.tenant = clients.admin_clients().keystone.tenants.get( flask.g.tenant_id)
def get_visible_tenants(): """Return visible tenants. Exclude systenants and tenants which are not enabled. """ systenant_id = clients.get_systenant_id() return filter(lambda x: x.enabled and x.id != systenant_id, clients.admin_clients().keystone.tenants.list())
def add_user_to_project(): """ Giving a 'Member' role in given tenant """ form = forms.AddUserToProject() tenant = clients.admin_clients().keystone.tenants.get(form.add_project.data) tenant.add_user(form.user.data, clients.get_role_id("member")) flask.flash('User was added to project', 'success') return flask.redirect(flask.url_for('.show', user_id=form.user.data))
def remove_user_from_project(): """ Removes all user's roles for given tenant """ form = forms.RemoveUserFromProject() project = clients.admin_clients().keystone.tenants.get(form.remove_project.data) user = clients.admin_clients().keystone.users.get(form.user.data) user_roles_in_project = [] all_tenants = clients.admin_clients().keystone.tenants.list(limit=1000000) for tenant in all_tenants: if tenant.id == project.id: roles = user.list_roles(tenant) if len(roles): [user_roles_in_project.append(r) for r in roles] for role in user_roles_in_project: project.remove_user(form.user.data, role.id) flask.flash('User was removed from project', 'success') return flask.redirect(flask.url_for('.show', user_id=form.user.data))
def billing(): ''' Define tenant to show and redirect there. Not every billing account points to an existing tenants. ''' def out(tenant_id): return flask.redirect( flask.url_for( '.billing_details', tenant_id=tenant_id)) billing_accounts = clients.admin_clients().billing.account.list() tenants = clients.admin_clients().keystone.tenants.list() for n in billing_accounts: for k in tenants: if n['name'] == k.id: return out(k.id) return out(clients.get_systenant_id())
def get_visible_tenants(): """Return visible tenants. Exclude systenants and tenants which are not enabled. """ systenant_id = clients.get_systenant_id() return filter( lambda x: x.enabled and x.id != systenant_id, clients.admin_clients().keystone.tenants.list())
def get_tariff_list(): tariffs = { "glance/image": 1.0, "memory_mb": 1.0, "vcpus": 1.0, "nova/volume": 1.0, "local_gb": 1.0, } tariffs.update(clients.admin_clients().billing.tariff.list()) return tariffs
def index(): try: networks = clients.admin_clients().compute.networks.list() except HttpException as ex: networks = [] tenants = clients.admin_clients().identity_admin.tenants.list() tenants = dict(((t.id, t.name) for t in tenants)) p = pagination.Pagination(len(networks)) offset = p.limit_offset() networks = [net._info for net in networks[offset[0]:offset[1]]] for net in networks: net["label"] = tenants.get(net["project_id"], net["label"]) return { 'objects': networks, 'pagination': p, 'delete_form': forms.DeleteForm(), 'title': bp.name.replace('global_', '').replace('_', ' ').capitalize(), 'subtitle': 'List of networks' }
def add_user_to_project(): """ Giving a 'Member' role in given tenant """ form = forms.AddUserToProject() tenant = clients.admin_clients().keystone.tenants.get( form.add_project.data) tenant.add_user(form.user.data, clients.get_role_id("member")) flask.flash('User was added to project', 'success') return flask.redirect(flask.url_for('.show', user_id=form.user.data))
def remove_user_from_project(): """ Removes all user's roles for given tenant """ form = forms.RemoveUserFromProject() project = clients.admin_clients().keystone.tenants.get( form.remove_project.data) user = clients.admin_clients().keystone.users.get(form.user.data) user_roles_in_project = [] all_tenants = clients.admin_clients().keystone.tenants.list(limit=1000000) for tenant in all_tenants: if tenant.id == project.id: roles = user.list_roles(tenant) if len(roles): [user_roles_in_project.append(r) for r in roles] for role in user_roles_in_project: project.remove_user(form.user.data, role.id) flask.flash('User was removed from project', 'success') return flask.redirect(flask.url_for('.show', user_id=form.user.data))
def dashboard(): """Present brief info and useful links. Global admins see numbers summary and links to administrative section. Members of projects see links to their respective projects. """ context = {} if principal.Permission(('role', 'admin')).can(): projects = utils.get_visible_tenants() project_ids = [x.id for x in projects] users = clients.admin_clients().keystone.users.list() servers = filter( lambda x: x.tenant_id in project_ids, clients.admin_clients().nova.servers.list( search_opts={'all_tenants': 1})) context.update( dict(title='Altai private cloud', subtitle='%s users in %s projects use %s VMs' % (len(users), len(projects), len(servers)))) return context
def account_bill_show(user_id, tenant_id, **kw): # list with tenant_id as ['name'] try: bill = clients.admin_clients().billing.report.list( account_name=tenant_id, **kw)["accounts"][0] except (NotFound, IndexError): return {'resources': []} if hasattr(flask.g, 'tenant_id'): bill['resources'] = _concentrate_resources(bill['resources'], tenant_id) bill['resources'] = _compact_bill(bill['resources']) return bill
def get_keystone_user_by_username(username): """ Not implemented in Keystone API feature returns a user with specific username Important: Hardcore iteration through all existing users in keystone db """ users = clients.admin_clients().keystone.users.list() for user in users: if user.name == username: return user
def account_bill_show(user_id, tenant_id, **kw): # list with tenant_id as ['name'] try: bill = clients.admin_clients().billing.report.list( account_name=tenant_id, **kw)["accounts"][0] except (NotFound, IndexError): return {'resources': []} if hasattr(flask.g, 'tenant_id'): bill['resources'] = _concentrate_resources( bill['resources'], tenant_id) bill['resources'] = _compact_bill(bill['resources']) return bill
def user_tenants_with_roles_list(keystone_user): """ Not implemented in Keystone API feature Returns a list with user's roles in it """ user_roles = [] all_tenants = clients.admin_clients().keystone.tenants.list(limit=1000000) for tenant in all_tenants: roles = keystone_user.list_roles(tenant) if len(roles): user_roles.append((tenant, roles)) return user_roles
def dashboard(): """Present brief info and useful links. Global admins see numbers summary and links to administrative section. Members of projects see links to their respective projects. """ context = {} if principal.Permission(("role", "admin")).can(): projects = utils.get_visible_tenants() project_ids = [x.id for x in projects] users = clients.admin_clients().keystone.users.list() servers = filter( lambda x: x.tenant_id in project_ids, clients.admin_clients().nova.servers.list(search_opts={"all_tenants": 1}), ) context.update( dict( title="Altai private cloud", subtitle="%s users in %s projects use %s VMs" % (len(users), len(projects), len(servers)), ) ) return context
def register_in_keystone(): """ """ try: new_keystone_user = clients.admin_clients().keystone.users.create( username, password, email) if role != 'user': all_roles = clients.admin_clients().keystone.roles.list() for r in all_roles: if r.name.lower() == role.lower(): clients.admin_clients().keystone.roles.add_user_role( new_keystone_user, r, tenant=clients.get_systenant_id() ) break else: flask.current_app.logger( 'Matching Keystone role for %s nto found.' % role.lower(), 'error') return new_keystone_user except Exception, e: raise Exception("Registration fail", e.message)
def delete(image_id): image = clients.admin_clients().glance.images.get(image_id) owner = getattr(image, 'owner') if owner == clients.get_systenant_id(): principal.Permission(('role', 'admin')).test() else: principal.Permission(('role', 'member', owner)).test() form = forms.DeleteForm() if form.validate_on_submit(): image.delete() flask.flash('Image successfully deleted', 'success') else: flask.flash('Invalid form', 'error') return flask.redirect(flask.url_for('.index'))
def register_in_keystone(): """ """ try: new_keystone_user = clients.admin_clients().keystone.users.create( username, password, email) if role != 'user': all_roles = clients.admin_clients().keystone.roles.list() for r in all_roles: if r.name.lower() == role.lower(): clients.admin_clients().keystone.roles.add_user_role( new_keystone_user, r, tenant=clients.get_systenant_id()) break else: flask.current_app.logger( 'Matching Keystone role for %s nto found.' % role.lower(), 'error') return new_keystone_user except Exception, e: raise Exception("Registration fail", e.message)
def show(user_id): '''Show user details. Name, username, email, roles in tenants. ''' def is_non_admin(tenant): return tenant.id != \ clients.get_systenant_id() user = clients.admin_clients().keystone.users.get(user_id) user_roles = filter(lambda x: is_non_admin(x[0]), utils.user_tenants_with_roles_list(user)) add_user_to_project = forms.AddUserToProject() add_user_to_project.user.data = user_id remove_user_from_project = forms.RemoveUserFromProject() remove_user_from_project.user.data = user_id user_projects = [] users_projects_choices = [] not_user_projects_choices = [] for tenant, role in user_roles: if is_non_admin(tenant): users_projects_choices.append((tenant.id, tenant.name)) user_projects.append(tenant.id) remove_user_from_project.remove_project.choices = users_projects_choices all_tenants = clients.admin_clients().keystone.tenants.list() for tenant in all_tenants: if not tenant.id in user_projects and is_non_admin(tenant): not_user_projects_choices.append((tenant.id, tenant.name)) add_user_to_project.add_project.choices = not_user_projects_choices return { 'user': user, 'user_roles': user_roles, 'add_user_to_project_form': add_user_to_project, 'remove_user_from_project_form': remove_user_from_project, 'title': bp.name.replace('global_', '').replace('_', ' ').capitalize(), 'subtitle': 'User details' }
def show(user_id): '''Show user details. Name, username, email, roles in tenants. ''' def is_non_admin(tenant): return tenant.id != \ clients.get_systenant_id() user = clients.admin_clients().keystone.users.get(user_id) user_roles = filter( lambda x: is_non_admin(x[0]), utils.user_tenants_with_roles_list(user)) add_user_to_project = forms.AddUserToProject() add_user_to_project.user.data = user_id remove_user_from_project = forms.RemoveUserFromProject() remove_user_from_project.user.data = user_id user_projects = [] users_projects_choices = [] not_user_projects_choices = [] for tenant, role in user_roles: if is_non_admin(tenant): users_projects_choices.append((tenant.id, tenant.name)) user_projects.append(tenant.id) remove_user_from_project.remove_project.choices = users_projects_choices all_tenants = clients.admin_clients().keystone.tenants.list() for tenant in all_tenants: if not tenant.id in user_projects and is_non_admin(tenant): not_user_projects_choices.append((tenant.id, tenant.name)) add_user_to_project.add_project.choices = not_user_projects_choices return { 'user': user, 'user_roles': user_roles, 'add_user_to_project_form': add_user_to_project, 'remove_user_from_project_form': remove_user_from_project, 'title': bp.name.replace('global_', '').replace('_', ' ').capitalize(), 'subtitle': 'User details' }
def password_recovery_finish(recovery_hash): """ This will be called after user clicked link in email. """ try: id, email, hash_code, complete = \ row_mysql_queries.get_recovery_request_by_hash(recovery_hash) except TypeError: # db returns None flask.abort(404) if complete == 1: flask.flash('Password recovery token is expired', 'error') return flask.redirect(flask.url_for('dashboard')) odb_user = utils.neo4j_api_call('/users', {"email": email}, 'GET')[0] new_hash = str(uuid.uuid4()) # set trash password in keystone keystone_user = utils.get_keystone_user_by_username(odb_user['username']) clients.admin_clients().keystone.users.update_password( keystone_user, new_hash) # set trash password in odb utils.neo4j_api_call( '/users', { 'id': odb_user['id'], 'login': odb_user['login'], 'username': odb_user['username'], 'email': odb_user['email'], 'passwordHash': utils.create_hashed_password(new_hash) }, 'PUT') # send trash password back to user msg = mail.Message('Password recovery', recipients=[odb_user['email']]) msg.body = flask.render_template('RecoveryPasswordFinishEmail/body.txt', new_pass=new_hash) utils.send_msg(msg) flask.flash('New password was sent to you', 'success') return flask.redirect(flask.url_for('dashboard'))
def delete(object_id): """Deletes project. TODO(apugachev) remove images """ try: tenant = clients.admin_clients().keystone.tenants.get(object_id) except Exception: flask.abort(404) form = forms.DeleteForm() if form.validate_on_submit(): try: # refuse to delete project if it contains VMs vms = filter( lambda x: x.tenant_id == object_id, clients.admin_clients().nova.servers.list( search_opts={'all_tenants': 1})) if vms: flask.flash('Project contains VM(s). Please delete VM(s) manually before deleting the project', 'error') return flask.redirect(flask.url_for('.index')) # detach network networks_client = clients.admin_clients().compute.networks networks = networks_client.list() for net in networks: if net.project_id == object_id: networks_client.disassociate(net) break # delete tenant tenant.delete() flask.flash('Project removed successfully.', 'success') except HttpException as ex: flask.flash('Cannot remote the project. %s' % ex.message, 'error') else: flask.flash('Form is not valid.', 'error') return flask.redirect(flask.url_for('.index'))
def user_tenants_list(keystone_user): """ Returns a list of tenants in which keystone_user has admin or member role. Important: Should return dicts instead of Keystone client internal objects because this value will be stored in session and cannot be normally serialized. """ roles = (clients.admin_clients().identity_admin.roles. roles_for_user(keystone_user)) user_tenants = {} for role_tenant in roles: if (clients.role_is_admin(role_tenant.role["name"]) or clients.role_is_member(role_tenant.role["name"])): user_tenants[role_tenant.tenant["id"]] = role_tenant.tenant return user_tenants.values()
def user_tenants_list(keystone_user): """ Returns a list of tenants in which keystone_user has admin or member role. Important: Should return dicts instead of Keystone client internal objects because this value will be stored in session and cannot be normally serialized. """ roles = (clients.admin_clients().identity_admin.roles.roles_for_user( keystone_user)) user_tenants = {} for role_tenant in roles: if (clients.role_is_admin(role_tenant.role["name"]) or clients.role_is_member(role_tenant.role["name"])): user_tenants[role_tenant.tenant["id"]] = role_tenant.tenant return user_tenants.values()
def new(): """Creates project. Bind network to the project at the same time. """ form = forms.NewProject() admin_clients = clients.admin_clients() try: networks = admin_clients.compute.networks.list() except HttpException: networks = [] else: networks = [ (net.id, '%s (%s, %s)' % (net.label, net.cidr, net.vlan)) for net in networks if net.project_id is None ] if not networks: flask.flash('No free networks available.', 'error') return flask.redirect(flask.url_for('.index')) form.network.choices = networks if form.validate_on_submit(): if form.description.data: args = (form.name.data, form.description.data) else: args = (form.name.data, ) tenant = admin_clients.keystone.tenants.create(*args) try: admin_clients.compute.networks.associate( form.network.data, tenant.id) except HttpException: tenant.delete() raise flask.flash('Project created.', 'success') return flask.redirect(flask.url_for('.index')) return { 'form': form, 'title': bp.name.replace('global_', '').replace('_', ' ').capitalize(), 'subtitle': 'Add new project' }
def navigation_bar_tenant_data(): if not getattr(flask.g, 'is_authenticated', False): return {} try: user_id = flask.session['keystone_unscoped']['access']['user']['id'] roles = (clients.admin_clients().identity_admin.roles.roles_for_user( user_id)) roles_by_tenant = {} tenants = {} for r_t in roles: roles_by_tenant.setdefault(r_t.tenant["id"], []).append(r_t.role) tenants[r_t.tenant["id"]] = r_t.tenant tenants_with_roles = [ (tenant, roles_by_tenant[tenant["id"]]) for tenant in tenants.values() if tenant["name"] != clients.get_systenant_name() ] return {'tenants_with_roles': tenants_with_roles} except Exception: exc_type, exc_value, tb = sys.exc_info() focus.app.log_exception((exc_type, exc_value, tb)) return {}
def edit(name): """Edit tariff""" tariffs = generic_billing.get_tariff_list() # TODO(apugachev) - handle nonexisting tariff, KeyError in next line form = forms.TariffEditForm(price=tariffs.get(name, 1.0)) if form.validate_on_submit(): try: response = clients.admin_clients().billing.tariff.update( name, form.price.data, form.migrate.data) except Exception, e: flask.flash( 'Failed to update tariff. Error: %s' % e.args[0], 'error') exc_type, exc_value, tb = sys.exc_info() flask.current_app.log_exception((exc_type, exc_value, tb)) else: flask.flash( 'Successfully changed tarif %s to %s.' % response.items()[0], 'success') return flask.redirect(flask.url_for('.index'))