Commit bdcea810 authored by Kostas Papadimitriou's avatar Kostas Papadimitriou
Browse files

Helpdesk app fixes

- Do not use autocomplete feature (usernames are now stored in astakos
  db)
- Translate provided username to retrieve user uuid
- UI: Display network operstate in as badge. Hide deleted vms in nics
  lists.
parent 1c9a8228
{% extends "helpdesk/base.html" %}
{% block extraheader %}
<small>/ {{ account }}</small>
<small>/ {{ account_name }}</small>
{% endblock %}
{% block content %}
......@@ -35,12 +35,12 @@
</li>
</ul>
</li>
<li><h2>{{ account }}</h2></li>
<li><h2>{{ account_name }}</h2></li>
</ul>
</div>
<div class="row-fluid">
<div class="object-anchor" id="account"></div>
<h3 class="info">{{ account }} | {{ vms|length }} VMs | {{ networks|length }} Networks</h3>
<h3 class="info">{{ account_name }} | {{ account }} | {{ vms|length }} VMs | {{ networks|length }} Networks</h3>
</div>
<div class="object-anchor" id="vms"></div>
<div class="vms info-block well">
......
......@@ -5,6 +5,7 @@
{{ network|network_deleted_badge|safe }}
<span class="badge badge-info">ID: {{ network.pk }}</span>
{{ network|object_status_badge|safe }}
<div class="network-details-content object-details-content">
<ul class="nav nav-tabs">
......
......@@ -2,12 +2,12 @@
<div class="object-anchor" id="vm-{{vm.pk}}"></div>
<div class="vm-details object-details {{ rowcls }}">
<h4><em><img src="{{ UI_MEDIA_URL }}images/icons/os/{{ vm|get_os }}.png" />{{ vm|get_os }}</em><i class="icon-tasks"></i>{{ vm.name }}<span class="badge">&nbsp;</span></h4>
{{ vm|vm_status_badge|safe }}
<span class="badge badge-inverse">ID: {{ vm.pk }}</span>
<span class="badge badge-inverse">{{ vm|vm_public_ip }}</span>
{% if vm.suspended %}
<span class="badge badge-important">SUSPENDED</span>
{% endif %}
{{ vm|object_status_badge|safe }}
<span class="badge badge-inverse">ID: {{ vm.pk }}</span>
<span class="badge badge-inverse">{{ vm|vm_public_ip }}</span>
<span class="badge badge-inverse flavor">
<span class="cpu">{{ vm.flavor.cpu }}x</span>
<span class="ram">{{ vm.flavor.ram}}MB</span>
......
......@@ -16,26 +16,29 @@ def vm_public_ip(vm):
VM_STATE_CSS_MAP = {
'BUILD': 'warning',
'PENDING': 'warning',
'ERROR': 'important',
'STOPPED': 'notice',
'STARTED': 'success',
'ACTIVE': 'success',
'DESTROYED': 'inverse'
}
@register.filter(name="vm_status_badge")
def vm_status_badge(vm):
@register.filter(name="object_status_badge")
def object_status_badge(vm_or_net):
"""
Return a span badge styled based on the vm current status
"""
state_cls = VM_STATE_CSS_MAP[vm.operstate]
state = vm_or_net.operstate if hasattr(vm_or_net, 'operstate') else \
vm_or_net.state
state_cls = VM_STATE_CSS_MAP.get(state, 'notice')
badge_cls = "badge badge-%s" % state_cls
deleted_badge = ""
if vm.deleted:
if vm_or_net.deleted:
deleted_badge = '<span class="badge badge-important">Deleted</span>'
return '%s\n<span class="%s">%s</span>' % (deleted_badge, badge_cls,
vm.operstate)
return '%s\n<span class="%s">%s</span>' % (deleted_badge, badge_cls, state)
vm_status_badge.is_safe = True
object_status_badge.is_safe = True
@register.filter(name="network_deleted_badge")
def network_deleted_badge(network):
......@@ -59,19 +62,23 @@ def get_os(vm):
get_os.is_safe = True
@register.filter(name="network_vms")
def network_vms(network, account):
def network_vms(network, account, show_deleted=False):
vms = []
for nic in network.nics.filter(machine__userid=account):
nics = network.nics.filter(machine__userid=account)
if not show_deleted:
nics = nics.filter(machine__deleted=False).distinct()
for nic in nics:
vms.append(nic.machine)
return vms
network_vms.is_safe = True
@register.filter(name="network_nics")
def network_nics(network, account):
def network_nics(network, account, show_deleted=False):
vms = []
for nic in network.nics.filter(machine__userid=account):
vms.append(nic)
return vms
nics = network.nics.filter(machine__userid=account)
if not show_deleted:
nics = nics.filter(machine__deleted=False).distinct()
return nics
network_nics.is_safe = True
......@@ -7,8 +7,6 @@ urlpatterns = patterns('',
url(r'^suspend_release/(?P<vm_id>[0-9]+)$',
'synnefo.helpdesk.views.suspend_vm_release',
name='helpdesk-suspend-vm-release'),
url(r'^api/users', 'synnefo.helpdesk.views.user_list',
name='helpdesk-userslist'),
url(r'^(?P<account_or_ip>.*)$', 'synnefo.helpdesk.views.account',
name='helpdesk-details'),
)
......
......@@ -34,26 +34,26 @@
import re
import logging
from itertools import chain
from django.shortcuts import redirect, get_object_or_404
from django.shortcuts import redirect
from django.views.generic.simple import direct_to_template
from django.db.models import get_apps
from django.conf import settings
from django.core.exceptions import PermissionDenied
from django.db.models import Q
from django.http import Http404, HttpResponse, HttpResponseRedirect
from django.utils import simplejson as json
from django.http import Http404, HttpResponseRedirect
from django.core.urlresolvers import reverse
from urllib import unquote
from synnefo.lib.astakos import get_user
from synnefo.db.models import *
from synnefo.db.models import VirtualMachine, NetworkInterface, Network
from synnefo.lib import astakos
logger = logging.getLogger(__name__)
IP_SEARCH_REGEX = re.compile('([0-9]+)(?:\.[0-9]+){3}')
UUID_SEARCH_REGEX = re.compile('([0-9a-z]{8}-([0-9a-z]{4}-){3}[0-9a-z]{12})')
USER_CATALOG_URL = settings.CYCLADES_USER_CATALOG_URL
def get_token_from_cookie(request, cookiename):
"""
......@@ -71,10 +71,10 @@ def get_token_from_cookie(request, cookiename):
return None
AUTH_COOKIE_NAME = getattr(settings, 'HELPDESK_AUTH_COOKIE_NAME', getattr(settings,
'UI_AUTH_COOKIE_NAME', '_pithos2_a'))
PERMITTED_GROUPS = getattr(settings, 'HELPDESK_PERMITTED_GROUPS',
['helpdesk'])
AUTH_COOKIE_NAME = getattr(settings, 'HELPDESK_AUTH_COOKIE_NAME',
getattr(settings, 'UI_AUTH_COOKIE_NAME',
'_pithos2_a'))
PERMITTED_GROUPS = getattr(settings, 'HELPDESK_PERMITTED_GROUPS', ['helpdesk'])
SHOW_DELETED_VMS = getattr(settings, 'HELPDESK_SHOW_DELETED_VMS', False)
......@@ -138,7 +138,8 @@ def index(request):
# if form submitted redirect to details
account = request.GET.get('account', None)
if account:
return redirect('synnefo.helpdesk.views.account', account_or_ip=account)
return redirect('synnefo.helpdesk.views.account',
account_or_ip=account)
# show index template
return direct_to_template(request, "helpdesk/index.html")
......@@ -156,44 +157,60 @@ def account(request, account_or_ip):
vms = []
networks = []
is_ip = IP_SEARCH_REGEX.match(account_or_ip)
account = account_or_ip
is_uuid = UUID_SEARCH_REGEX.match(account_or_ip)
account_name = account_or_ip
auth_token = request.user.get('auth_token')
if is_ip:
try:
nic = NetworkInterface.objects.get(ipv4=account_or_ip)
account = nic.machine.userid
account_or_ip = nic.machine.userid
is_uuid = True
except NetworkInterface.DoesNotExist:
account_exists = False
if is_uuid:
account = account_or_ip
account_name = astakos.get_displayname(auth_token, account,
USER_CATALOG_URL)
else:
filter_extra = {}
if not show_deleted:
filter_extra['deleted'] = False
# all user vms
vms = VirtualMachine.objects.filter(userid=account,
**filter_extra).order_by('deleted')
# return all user private and public networks
public_networks = Network.objects.filter(public=True,
**filter_extra).order_by('state')
private_networks = Network.objects.filter(userid=account,
**filter_extra).order_by('state')
networks = list(public_networks) + list(private_networks)
if vms.count() == 0 and private_networks.count() == 0:
account_exists = False
account_name = account_or_ip
account = astakos.get_user_uuid(auth_token, account_name,
USER_CATALOG_URL)
filter_extra = {}
if not show_deleted:
filter_extra['deleted'] = False
# all user vms
vms = VirtualMachine.objects.filter(userid=account,
**filter_extra).order_by('deleted')
# return all user private and public networks
public_networks = Network.objects.filter(public=True,
nics__machine__userid=account,
**filter_extra
).order_by('state').distinct()
private_networks = Network.objects.filter(userid=account,
**filter_extra).order_by('state')
networks = list(public_networks) + list(private_networks)
if vms.count() == 0 and private_networks.count() == 0:
account_exists = False
user_context = {
'account_exists': account_exists,
'is_ip': is_ip,
'account': account,
'vms': vms,
'show_deleted': show_deleted,
'account_name': account_name,
'csrf_token': request.user['auth_token'],
'networks': networks,
'UI_MEDIA_URL': settings.UI_MEDIA_URL
}
return direct_to_template(request, "helpdesk/account.html",
extra_context=user_context)
extra_context=user_context)
@helpdesk_user_required
......@@ -214,25 +231,3 @@ def suspend_vm_release(request, vm_id):
vm.save()
account = vm.userid
return HttpResponseRedirect(reverse('helpdesk-details', args=(account,)))
@helpdesk_user_required
def user_list(request):
"""
Return a json list of users based on the prefix provided. Prefix
should end with "@".
"""
prefix = request.GET.get('prefix', None)
if not prefix or "@" not in prefix:
raise Http404
# keep only the user part (e.g. "user@")
prefix = prefix.split("@")[0] + "@"
q = Q(userid__startswith=prefix) & ~Q(userid=None)
vm_users = VirtualMachine.objects.filter(q).values_list("userid", flat=True)
net_users = Network.objects.filter(q).values_list("userid", flat=True)
users = list(set(list(vm_users) + list(net_users)))
return HttpResponse(json.dumps(users), content_type="application/json")
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment