Merge remote branch 'origin/master'
This commit is contained in:
		@@ -191,6 +191,8 @@ def tenant_update(request, tenant_id, description, enabled):
 | 
				
			|||||||
def token_create(request, tenant, username, password):
 | 
					def token_create(request, tenant, username, password):
 | 
				
			||||||
    return auth_api().tokens.create(tenant, username, password)
 | 
					    return auth_api().tokens.create(tenant, username, password)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def tenant_quota_get(request, tenant):
 | 
				
			||||||
 | 
					    return admin_api(request).quota_sets.get(tenant)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def token_info(request, token):
 | 
					def token_info(request, token):
 | 
				
			||||||
    hdrs = {"Content-type": "application/json",
 | 
					    hdrs = {"Content-type": "application/json",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,6 +10,7 @@ KEYPAIRS = r'^(?P<tenant_id>[^/]+)/keypairs/%s$'
 | 
				
			|||||||
urlpatterns = patterns('django_openstack.dash.views.instances',
 | 
					urlpatterns = patterns('django_openstack.dash.views.instances',
 | 
				
			||||||
    url(r'^(?P<tenant_id>[^/]+)/$', 'usage', name='dash_usage'),
 | 
					    url(r'^(?P<tenant_id>[^/]+)/$', 'usage', name='dash_usage'),
 | 
				
			||||||
    url(r'^(?P<tenant_id>[^/]+)/instances/$', 'index', name='dash_instances'),
 | 
					    url(r'^(?P<tenant_id>[^/]+)/instances/$', 'index', name='dash_instances'),
 | 
				
			||||||
 | 
					    url(r'^(?P<tenant_id>[^/]+)/instances/refresh$', 'refresh', name='dash_instances_refresh'),
 | 
				
			||||||
    url(INSTANCES % 'console', 'console', name='dash_instances_console'),
 | 
					    url(INSTANCES % 'console', 'console', name='dash_instances_console'),
 | 
				
			||||||
    url(INSTANCES % 'vnc', 'vnc', name='dash_instances_vnc'),
 | 
					    url(INSTANCES % 'vnc', 'vnc', name='dash_instances_vnc'),
 | 
				
			||||||
    url(INSTANCES % 'update', 'update', name='dash_instances_update'),
 | 
					    url(INSTANCES % 'update', 'update', name='dash_instances_update'),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -175,6 +175,10 @@ def launch(request, tenant_id, image_id):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    try:
 | 
					    try:
 | 
				
			||||||
        image = api.image_get(request, image_id)
 | 
					        image = api.image_get(request, image_id)
 | 
				
			||||||
 | 
					        tenant = api.token_get_tenant(request, request.user.tenant)
 | 
				
			||||||
 | 
					        quotas = api.tenant_quota_get(request, request.user.tenant)
 | 
				
			||||||
 | 
					        quotas.ram = int(quotas.ram)/100
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
    except Exception, e:
 | 
					    except Exception, e:
 | 
				
			||||||
        messages.error(request, 'Unable to retrieve image %s: %s' %
 | 
					        messages.error(request, 'Unable to retrieve image %s: %s' %
 | 
				
			||||||
                                 (image_id, e.message))
 | 
					                                 (image_id, e.message))
 | 
				
			||||||
@@ -199,4 +203,5 @@ def launch(request, tenant_id, image_id):
 | 
				
			|||||||
        'tenant': tenant,
 | 
					        'tenant': tenant,
 | 
				
			||||||
        'image': image,
 | 
					        'image': image,
 | 
				
			||||||
        'form': form,
 | 
					        'form': form,
 | 
				
			||||||
 | 
					        'quotas': quotas,
 | 
				
			||||||
    }, context_instance=template.RequestContext(request))
 | 
					    }, context_instance=template.RequestContext(request))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -109,7 +109,34 @@ def index(request, tenant_id):
 | 
				
			|||||||
        'reboot_form': reboot_form,
 | 
					        'reboot_form': reboot_form,
 | 
				
			||||||
    }, context_instance=template.RequestContext(request))
 | 
					    }, context_instance=template.RequestContext(request))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@login_required
 | 
				
			||||||
 | 
					def refresh(request, tenant_id):
 | 
				
			||||||
 | 
					    for f in (TerminateInstance, RebootInstance):
 | 
				
			||||||
 | 
					        _, handled = f.maybe_handle(request)
 | 
				
			||||||
 | 
					        if handled:
 | 
				
			||||||
 | 
					            return handled
 | 
				
			||||||
 | 
					    instances = []
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        image_dict = api.image_all_metadata(request)
 | 
				
			||||||
 | 
					        instances = api.server_list(request)
 | 
				
			||||||
 | 
					        for instance in instances:
 | 
				
			||||||
 | 
					            # FIXME - ported this over, but it is hacky
 | 
				
			||||||
 | 
					            instance.attrs['image_name'] =\
 | 
				
			||||||
 | 
					               image_dict.get(int(instance.attrs['image_ref']),{}).get('name')
 | 
				
			||||||
 | 
					    except Exception as e:
 | 
				
			||||||
 | 
					        messages.error(request, 'Unable to get instance list: %s' % e.message)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # We don't have any way of showing errors for these, so don't bother
 | 
				
			||||||
 | 
					    # trying to reuse the forms from above
 | 
				
			||||||
 | 
					    terminate_form = TerminateInstance()
 | 
				
			||||||
 | 
					    reboot_form = RebootInstance()
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return render_to_response('_instance_list.html', {
 | 
				
			||||||
 | 
					        'instances': instances,
 | 
				
			||||||
 | 
					        'terminate_form': terminate_form,
 | 
				
			||||||
 | 
					        'reboot_form': reboot_form,
 | 
				
			||||||
 | 
					    }, context_instance=template.RequestContext(request))
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
@login_required
 | 
					@login_required
 | 
				
			||||||
def usage(request, tenant_id=None):
 | 
					def usage(request, tenant_id=None):
 | 
				
			||||||
    today = datetime.date.today()
 | 
					    today = datetime.date.today()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,6 +12,7 @@ urlpatterns = patterns('django_openstack.syspanel.views.instances',
 | 
				
			|||||||
    url(r'^usage/(?P<tenant_id>[^/]+)$', 'tenant_usage',
 | 
					    url(r'^usage/(?P<tenant_id>[^/]+)$', 'tenant_usage',
 | 
				
			||||||
        name='syspanel_tenant_usage'),
 | 
					        name='syspanel_tenant_usage'),
 | 
				
			||||||
    url(r'^instances/$', 'index', name='syspanel_instances'),
 | 
					    url(r'^instances/$', 'index', name='syspanel_instances'),
 | 
				
			||||||
 | 
					    url(r'^instances/refresh$', 'refresh', name='syspanel_instances_refresh'),
 | 
				
			||||||
    # NOTE(termie): currently just using the 'dash' versions
 | 
					    # NOTE(termie): currently just using the 'dash' versions
 | 
				
			||||||
    #url(INSTANCES % 'console', 'console', name='syspanel_instances_console'),
 | 
					    #url(INSTANCES % 'console', 'console', name='syspanel_instances_console'),
 | 
				
			||||||
    #url(INSTANCES % 'vnc', 'vnc', name='syspanel_instances_vnc'),
 | 
					    #url(INSTANCES % 'vnc', 'vnc', name='syspanel_instances_vnc'),
 | 
				
			||||||
@@ -25,6 +26,10 @@ urlpatterns += patterns('django_openstack.syspanel.views.images',
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					urlpatterns += patterns('django_openstack.syspanel.views.quotas',
 | 
				
			||||||
 | 
					    url(r'^quotas/$', 'index', name='syspanel_quotas'),
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
urlpatterns += patterns('django_openstack.syspanel.views.flavors',
 | 
					urlpatterns += patterns('django_openstack.syspanel.views.flavors',
 | 
				
			||||||
    url(r'^flavors/$', 'index', name='syspanel_flavors'),
 | 
					    url(r'^flavors/$', 'index', name='syspanel_flavors'),
 | 
				
			||||||
    url(r'^flavors/create/$', 'create', name='syspanel_flavors_create'),
 | 
					    url(r'^flavors/create/$', 'create', name='syspanel_flavors_create'),
 | 
				
			||||||
@@ -45,7 +50,8 @@ urlpatterns += patterns('django_openstack.syspanel.views.services',
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
urlpatterns += patterns('django_openstack.syspanel.views.tenants',
 | 
					urlpatterns += patterns('django_openstack.syspanel.views.tenants',
 | 
				
			||||||
    url(r'^tenants/$', 'index', name='syspanel_tenants'),
 | 
					    url(r'^tenants/$', 'index', name='syspanel_tenants'),
 | 
				
			||||||
 | 
					    url(r'^tenants/create$', 'create', name='syspanel_tenants_create'),
 | 
				
			||||||
    url(TENANTS % 'update', 'update', name='syspanel_tenant_update'),
 | 
					    url(TENANTS % 'update', 'update', name='syspanel_tenant_update'),
 | 
				
			||||||
    url(TENANTS % 'users', 'users', name='syspanel_tenant_users'),
 | 
					    url(TENANTS % 'users', 'users', name='syspanel_tenant_users'),
 | 
				
			||||||
    url(r'^tenants/create$', 'create', name='syspanel_tenants_create'),
 | 
					    url(TENANTS % 'quotas', 'quotas', name='syspanel_tenant_quotas'),
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -196,3 +196,32 @@ def index(request):
 | 
				
			|||||||
        'terminate_form': terminate_form,
 | 
					        'terminate_form': terminate_form,
 | 
				
			||||||
        'reboot_form': reboot_form,
 | 
					        'reboot_form': reboot_form,
 | 
				
			||||||
    }, context_instance=template.RequestContext(request))
 | 
					    }, context_instance=template.RequestContext(request))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@login_required
 | 
				
			||||||
 | 
					def refresh(request):
 | 
				
			||||||
 | 
					    for f in (TerminateInstance, RebootInstance):
 | 
				
			||||||
 | 
					        _, handled = f.maybe_handle(request)
 | 
				
			||||||
 | 
					        if handled:
 | 
				
			||||||
 | 
					            return handled
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    instances = []
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        image_dict = api.image_all_metadata(request)
 | 
				
			||||||
 | 
					        instances = api.server_list(request)
 | 
				
			||||||
 | 
					        for instance in instances:
 | 
				
			||||||
 | 
					            # FIXME - ported this over, but it is hacky
 | 
				
			||||||
 | 
					            instance._info['attrs']['image_name'] =\
 | 
				
			||||||
 | 
					               image_dict.get(int(instance.attrs['image_ref']),{}).get('name')
 | 
				
			||||||
 | 
					    except Exception as e:
 | 
				
			||||||
 | 
					        messages.error(request, 'Unable to get instance list: %s' % e.message)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # We don't have any way of showing errors for these, so don't bother
 | 
				
			||||||
 | 
					    # trying to reuse the forms from above
 | 
				
			||||||
 | 
					    terminate_form = TerminateInstance()
 | 
				
			||||||
 | 
					    reboot_form = RebootInstance()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return render_to_response('_syspanel_instance_list.html', {
 | 
				
			||||||
 | 
					        'instances': instances,
 | 
				
			||||||
 | 
					        'terminate_form': terminate_form,
 | 
				
			||||||
 | 
					        'reboot_form': reboot_form,
 | 
				
			||||||
 | 
					    }, context_instance=template.RequestContext(request))
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										28
									
								
								django-openstack/django_openstack/syspanel/views/quotas.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								django-openstack/django_openstack/syspanel/views/quotas.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
				
			|||||||
 | 
					# vim: tabstop=4 shiftwidth=4 softtabstop=4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from operator import itemgetter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django import template
 | 
				
			||||||
 | 
					from django import http
 | 
				
			||||||
 | 
					from django.conf import settings
 | 
				
			||||||
 | 
					from django.contrib import messages
 | 
				
			||||||
 | 
					from django.contrib.auth.decorators import login_required
 | 
				
			||||||
 | 
					from django.shortcuts import redirect
 | 
				
			||||||
 | 
					from django.shortcuts import render_to_response
 | 
				
			||||||
 | 
					from openstackx.api import exceptions as api_exceptions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django_openstack import api
 | 
				
			||||||
 | 
					from django_openstack import forms
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@login_required
 | 
				
			||||||
 | 
					def index(request):
 | 
				
			||||||
 | 
					    quotas = api.admin_api(request).quota_sets.get(True)._info
 | 
				
			||||||
 | 
					    quotas['ram'] = int(quotas['ram']) / 100
 | 
				
			||||||
 | 
					    quotas.pop('id')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return render_to_response('syspanel_quotas.html',{
 | 
				
			||||||
 | 
					        'quotas': quotas,
 | 
				
			||||||
 | 
					    }, context_instance = template.RequestContext(request))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -92,6 +92,38 @@ class UpdateTenant(forms.SelfHandlingForm):
 | 
				
			|||||||
            messages.error(request, 'Unable to update tenant: %s' % e.message)
 | 
					            messages.error(request, 'Unable to update tenant: %s' % e.message)
 | 
				
			||||||
        return redirect('syspanel_tenants')
 | 
					        return redirect('syspanel_tenants')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class UpdateQuotas(forms.SelfHandlingForm):
 | 
				
			||||||
 | 
					    tenant_id = forms.CharField(label="ID (name)", widget=forms.TextInput(attrs={'readonly':'readonly'}))
 | 
				
			||||||
 | 
					    metadata_items = forms.CharField(label="Metadata Items")
 | 
				
			||||||
 | 
					    injected_files = forms.CharField(label="Injected Files")
 | 
				
			||||||
 | 
					    injected_file_content_bytes = forms.CharField(label="Injected File Content Bytes")
 | 
				
			||||||
 | 
					    cores = forms.CharField(label="VCPUs")
 | 
				
			||||||
 | 
					    instances = forms.CharField(label="Instances")
 | 
				
			||||||
 | 
					    volumes = forms.CharField(label="Volumes")
 | 
				
			||||||
 | 
					    gigabytes = forms.CharField(label="Gigabytes")
 | 
				
			||||||
 | 
					    ram = forms.CharField(label="RAM (in MB)")
 | 
				
			||||||
 | 
					    floating_ips = forms.CharField(label="Floating IPs")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def handle(self, request, data):
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            api.admin_api(request).quota_sets.update(data['tenant_id'],
 | 
				
			||||||
 | 
					                          metadata_items=data['metadata_items'],
 | 
				
			||||||
 | 
					                          injected_file_content_bytes=
 | 
				
			||||||
 | 
					                          data['injected_file_content_bytes'],
 | 
				
			||||||
 | 
					                          volumes=data['volumes'],
 | 
				
			||||||
 | 
					                          gigabytes=data['gigabytes'],
 | 
				
			||||||
 | 
					                          ram=int(data['ram']) * 100,
 | 
				
			||||||
 | 
					                          floating_ips=data['floating_ips'],
 | 
				
			||||||
 | 
					                          instances=data['instances'],
 | 
				
			||||||
 | 
					                          injected_files=data['injected_files'],
 | 
				
			||||||
 | 
					                          cores=data['cores'],
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            messages.success(request,
 | 
				
			||||||
 | 
					                             'Quotas for %s were successfully updated.'
 | 
				
			||||||
 | 
					                             % data['tenant_id'])
 | 
				
			||||||
 | 
					        except api_exceptions.ApiException, e:
 | 
				
			||||||
 | 
					            messages.error(request, 'Unable to update quotas: %s' % e.message)
 | 
				
			||||||
 | 
					        return redirect('syspanel_tenants')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@login_required
 | 
					@login_required
 | 
				
			||||||
def index(request):
 | 
					def index(request):
 | 
				
			||||||
@@ -171,3 +203,32 @@ def users(request, tenant_id):
 | 
				
			|||||||
        'users': users,
 | 
					        'users': users,
 | 
				
			||||||
        'new_users': new_user_ids,
 | 
					        'new_users': new_user_ids,
 | 
				
			||||||
    }, context_instance = template.RequestContext(request))
 | 
					    }, context_instance = template.RequestContext(request))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@login_required
 | 
				
			||||||
 | 
					def quotas(request, tenant_id):
 | 
				
			||||||
 | 
					    for f in (UpdateQuotas,):
 | 
				
			||||||
 | 
					        _, handled = f.maybe_handle(request)
 | 
				
			||||||
 | 
					        if handled:
 | 
				
			||||||
 | 
					            return handled
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    quotas = api.admin_api(request).quota_sets.get(tenant_id)
 | 
				
			||||||
 | 
					    quota_set = {
 | 
				
			||||||
 | 
					        'tenant_id': quotas.id,
 | 
				
			||||||
 | 
					        'metadata_items': quotas.metadata_items,
 | 
				
			||||||
 | 
					        'injected_file_content_bytes': quotas.injected_file_content_bytes,
 | 
				
			||||||
 | 
					        'volumes': quotas.volumes,
 | 
				
			||||||
 | 
					        'gigabytes': quotas.gigabytes,
 | 
				
			||||||
 | 
					        'ram': int(quotas.ram) / 100,
 | 
				
			||||||
 | 
					        'floating_ips': quotas.floating_ips,
 | 
				
			||||||
 | 
					        'instances': quotas.instances,
 | 
				
			||||||
 | 
					        'injected_files': quotas.injected_files,
 | 
				
			||||||
 | 
					        'cores': quotas.cores,
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    form = UpdateQuotas(initial=quota_set)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return render_to_response(
 | 
				
			||||||
 | 
					    'syspanel_tenant_quotas.html',{
 | 
				
			||||||
 | 
					        'form': form,
 | 
				
			||||||
 | 
					        'tenant_id': tenant_id,
 | 
				
			||||||
 | 
					        'quotas': quotas,
 | 
				
			||||||
 | 
					    }, context_instance = template.RequestContext(request))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					{% extends "_quotas_form.html" %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% block submit %}
 | 
				
			||||||
 | 
					  <input type="submit" value="Update Quotas" class="large-rounded" />
 | 
				
			||||||
 | 
					{% endblock %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										12
									
								
								openstack-dashboard/dashboard/templates/_quotas_form.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								openstack-dashboard/dashboard/templates/_quotas_form.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					<form id="quotas_form" action="" method="post">
 | 
				
			||||||
 | 
					  {% csrf_token %}
 | 
				
			||||||
 | 
					  {% for hidden in form.hidden_fields %}{{ hidden }}{% endfor %}
 | 
				
			||||||
 | 
					    {% for field in form.visible_fields %}
 | 
				
			||||||
 | 
					    {{ field.label_tag }}
 | 
				
			||||||
 | 
					    {{ field.errors }}
 | 
				
			||||||
 | 
					    {{ field }}
 | 
				
			||||||
 | 
					  {% endfor %}
 | 
				
			||||||
 | 
					  {% block submit %}
 | 
				
			||||||
 | 
					  {% endblock %}
 | 
				
			||||||
 | 
					</form>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
{% load parse_date %}
 | 
					{% load parse_date %}
 | 
				
			||||||
<table class="wide">
 | 
					<table id="instances" class="wide">
 | 
				
			||||||
  <tr>
 | 
					  <tr>
 | 
				
			||||||
    <th>Id</th>
 | 
					    <th>Id</th>
 | 
				
			||||||
    <th>User</th>
 | 
					    <th>User</th>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,5 +8,6 @@
 | 
				
			|||||||
    <li><a {% if current_sidebar == "images" %} class="active" {% endif %} href="{% url syspanel_images %}">Images</a></li>
 | 
					    <li><a {% if current_sidebar == "images" %} class="active" {% endif %} href="{% url syspanel_images %}">Images</a></li>
 | 
				
			||||||
    <li><a {% if current_sidebar == "tenants" %} class="active" {% endif %} href="{% url syspanel_tenants %}">Tenants</a></li>
 | 
					    <li><a {% if current_sidebar == "tenants" %} class="active" {% endif %} href="{% url syspanel_tenants %}">Tenants</a></li>
 | 
				
			||||||
    <li><a {% if current_sidebar == "users" %} class="active" {% endif %} href="{% url syspanel_users %}">Users</a></li>
 | 
					    <li><a {% if current_sidebar == "users" %} class="active" {% endif %} href="{% url syspanel_users %}">Users</a></li>
 | 
				
			||||||
 | 
					    <li><a {% if current_sidebar == "quotas" %} class="active" {% endif %} href="{% url syspanel_quotas %}">Quotas</a></li>
 | 
				
			||||||
  </ul>
 | 
					  </ul>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,6 +15,7 @@
 | 
				
			|||||||
          <li>{% include "_tenant_delete.html" with form=tenant_delete_form %}</li>
 | 
					          <li>{% include "_tenant_delete.html" with form=tenant_delete_form %}</li>
 | 
				
			||||||
          <li><a href="{% url syspanel_tenant_update tenant.id %}">Edit</a></li>
 | 
					          <li><a href="{% url syspanel_tenant_update tenant.id %}">Edit</a></li>
 | 
				
			||||||
          <li><a href="{% url syspanel_tenant_users tenant.id %}">View Members</a></li>
 | 
					          <li><a href="{% url syspanel_tenant_users tenant.id %}">View Members</a></li>
 | 
				
			||||||
 | 
					          <li><a href="{% url syspanel_tenant_quotas tenant.id %}">Modify Quotas</a></li>
 | 
				
			||||||
        </ul>
 | 
					        </ul>
 | 
				
			||||||
      </td>
 | 
					      </td>
 | 
				
			||||||
    </tr>
 | 
					    </tr>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,6 +12,7 @@
 | 
				
			|||||||
  <div id='page_header'>
 | 
					  <div id='page_header'>
 | 
				
			||||||
    <h2><span>Compute:</span> Instances</h2>
 | 
					    <h2><span>Compute:</span> Instances</h2>
 | 
				
			||||||
    <p class='desc'><span>—</span> Instances are virtual servers launched from images.</p>
 | 
					    <p class='desc'><span>—</span> Instances are virtual servers launched from images.</p>
 | 
				
			||||||
 | 
					    <div id="spinner" class="dash">Loading...</div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  {% include "_messages.html" %}
 | 
					  {% include "_messages.html" %}
 | 
				
			||||||
@@ -41,3 +42,26 @@
 | 
				
			|||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% endblock %}
 | 
					{% endblock %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% block footer_js %}
 | 
				
			||||||
 | 
					  <script type="text/javascript" charset="utf-8">
 | 
				
			||||||
 | 
					    $(function(){
 | 
				
			||||||
 | 
					      $("#spinner").hide()
 | 
				
			||||||
 | 
					      function loadInstances(){
 | 
				
			||||||
 | 
					        $('#spinner').show();
 | 
				
			||||||
 | 
					        $('#instances').load('{% url dash_instances_refresh request.user.tenant %}', function(){
 | 
				
			||||||
 | 
					          $("#spinner").hide()
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      setInterval(function(){
 | 
				
			||||||
 | 
					        loadInstances();
 | 
				
			||||||
 | 
					      }, 15000);
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      $("a.refresh").click(function(e){
 | 
				
			||||||
 | 
					        e.preventDefault()
 | 
				
			||||||
 | 
					        loadInstances();
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					  </script>
 | 
				
			||||||
 | 
					{% endblock footer_js %}
 | 
				
			||||||
@@ -24,11 +24,36 @@
 | 
				
			|||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    {% include '_launch.html' %}
 | 
					    {% include '_launch.html' %}
 | 
				
			||||||
 | 
					 | 
				
			||||||
    <div class="right">
 | 
					    <div class="right">
 | 
				
			||||||
      <h3>Description:</h3>
 | 
					      <h3>Description:</h3>
 | 
				
			||||||
      <p>Specify the details for launching an instance.</p>
 | 
					      <p>Specify the details for launching an instance. Also please make note of the table below; all tenants have quotas which define the limit of resources you are allowed to provision.</p>
 | 
				
			||||||
    </div>
 | 
					      <table border="0">
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					          <th>Quota Name</th>
 | 
				
			||||||
 | 
					          <th>Limit</th>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					          <td>RAM (MB)</td>
 | 
				
			||||||
 | 
					          <td>{{quotas.ram}}MB</td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					          <td>Floating IPs</td>
 | 
				
			||||||
 | 
					          <td>{{quotas.floating_ips}}</td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					          <td>Instances</td>
 | 
				
			||||||
 | 
					          <td>{{quotas.instances}}</td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					          <td>Volumes</td>
 | 
				
			||||||
 | 
					          <td>{{quotas.volumes}}</td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					          <td>Gigabytes</td>
 | 
				
			||||||
 | 
					          <td>{{quotas.gigabytes}}GB</td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					      </table>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
{% endblock %}
 | 
					{% endblock %}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,6 +12,7 @@
 | 
				
			|||||||
  <div id='page_header'>
 | 
					  <div id='page_header'>
 | 
				
			||||||
    <h2><span>System Panel:</span> Instances</h2>
 | 
					    <h2><span>System Panel:</span> Instances</h2>
 | 
				
			||||||
    <p class='desc'><span>—</span> View all running instances other than VPNs.</p>
 | 
					    <p class='desc'><span>—</span> View all running instances other than VPNs.</p>
 | 
				
			||||||
 | 
					    <div id="spinner" class="syspanel">Loading...</div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  {% include "_messages.html" %}
 | 
					  {% include "_messages.html" %}
 | 
				
			||||||
@@ -43,3 +44,25 @@
 | 
				
			|||||||
    {% endif %}
 | 
					    {% endif %}
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
{% endblock %}
 | 
					{% endblock %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% block footer_js %}
 | 
				
			||||||
 | 
					  <script type="text/javascript" charset="utf-8">
 | 
				
			||||||
 | 
					    $(function(){
 | 
				
			||||||
 | 
					      $("#spinner").hide()
 | 
				
			||||||
 | 
					      function loadInstances(){
 | 
				
			||||||
 | 
					        $('#spinner').show();
 | 
				
			||||||
 | 
					        $('#instances').load('{% url syspanel_instances_refresh %}', function(){
 | 
				
			||||||
 | 
					          $("#spinner").hide()
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      setInterval(function(){
 | 
				
			||||||
 | 
					        loadInstances();
 | 
				
			||||||
 | 
					      }, 15000);
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      $("a.refresh").click(function(e){
 | 
				
			||||||
 | 
					        e.preventDefault()
 | 
				
			||||||
 | 
					        loadInstances();
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					  </script>
 | 
				
			||||||
 | 
					{% endblock footer_js %}
 | 
				
			||||||
							
								
								
									
										48
									
								
								openstack-dashboard/dashboard/templates/syspanel_quotas.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								openstack-dashboard/dashboard/templates/syspanel_quotas.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
				
			|||||||
 | 
					{% extends 'syspanel_base.html' %}
 | 
				
			||||||
 | 
					{# list of tenants #}
 | 
				
			||||||
 | 
					{# standard nav, sidebar, list of instances in main #}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% block sidebar %}
 | 
				
			||||||
 | 
					  {% with current_sidebar="quotas" %}
 | 
				
			||||||
 | 
					    {{block.super}}
 | 
				
			||||||
 | 
					  {% endwith %}
 | 
				
			||||||
 | 
					{% endblock %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% block main %}
 | 
				
			||||||
 | 
					    <div id='page_header'>
 | 
				
			||||||
 | 
					      <h2><span>System Panel:</span> Quotas</h2>
 | 
				
			||||||
 | 
					      <p class='desc'><span>—</span>Default Quotas</p>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    {% include "_messages.html" %}
 | 
				
			||||||
 | 
					    <div class="main_content">
 | 
				
			||||||
 | 
					      <div class='table_title wide'>
 | 
				
			||||||
 | 
					        <h3>Default Quotas</h3>
 | 
				
			||||||
 | 
					        <a class="refresh" title="Refresh" href="{% url syspanel_quotas %}">Refresh List</a>
 | 
				
			||||||
 | 
					        <div class='search'>
 | 
				
			||||||
 | 
					          <form action='' method='post'>
 | 
				
			||||||
 | 
					            <fieldset>
 | 
				
			||||||
 | 
					              <label for='table_search'>Search</label>
 | 
				
			||||||
 | 
					              <input id='table_search' name='search' type='text' value='' />
 | 
				
			||||||
 | 
					            </fieldset>
 | 
				
			||||||
 | 
					          </form>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <table class="wide">
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					          <th>Quota Name</th>
 | 
				
			||||||
 | 
					          <th>Limit</th>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        {% for name,value in quotas.items %}
 | 
				
			||||||
 | 
					          <tr>
 | 
				
			||||||
 | 
					            <td>{{name}}</td>
 | 
				
			||||||
 | 
					            <td>{{value}}</td>
 | 
				
			||||||
 | 
					          </tr>
 | 
				
			||||||
 | 
					        {% endfor %}
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					      </table>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <a id="tenant_create_link" class="action_link large-rounded" href="{% url syspanel_tenants_create %}">Create New Tenant </a>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					{% endblock %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -0,0 +1,33 @@
 | 
				
			|||||||
 | 
					{% extends 'syspanel_base.html' %}
 | 
				
			||||||
 | 
					{# list of tenants #}
 | 
				
			||||||
 | 
					{# standard nav, sidebar, list of instances in main #}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% block sidebar %}
 | 
				
			||||||
 | 
					  {% with current_sidebar="tenants" %}
 | 
				
			||||||
 | 
					    {{block.super}}
 | 
				
			||||||
 | 
					  {% endwith %}
 | 
				
			||||||
 | 
					{% endblock %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% block main %}
 | 
				
			||||||
 | 
					    <div id='page_header'>
 | 
				
			||||||
 | 
					      <h2><span>System Panel:</span> Tenants</h2>
 | 
				
			||||||
 | 
					      <p class='desc'><span>—</span>Manage Tenants Quotas</p>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    {% include "_messages.html" %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <div class="main_content">
 | 
				
			||||||
 | 
					      <div class="dash_block wide form">
 | 
				
			||||||
 | 
					        <div class='title_block'>
 | 
				
			||||||
 | 
					        <h3>Update Tenant Quotas</h3>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        {% include 'django_openstack/syspanel/_update_quotas_form.html' with form=form %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <div class="right">
 | 
				
			||||||
 | 
					          <h3>Description:</h3>
 | 
				
			||||||
 | 
					          <p>From here you can edit quotas (max limits) for the tenant {{tenant_id}}.</p>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					{% endblock %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1692,3 +1692,26 @@ li.title h4{
 | 
				
			|||||||
	margin-left: 25px;
 | 
						margin-left: 25px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#spinner {
 | 
				
			||||||
 | 
						background: url(../images/spinner.gif) top left no-repeat;
 | 
				
			||||||
 | 
						float: right;
 | 
				
			||||||
 | 
						width: 24px;
 | 
				
			||||||
 | 
						height: 24px;
 | 
				
			||||||
 | 
						text-indent: -9999px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#spinner.dash {
 | 
				
			||||||
 | 
						position: relative;
 | 
				
			||||||
 | 
						right: 10px;
 | 
				
			||||||
 | 
						bottom: 0;
 | 
				
			||||||
 | 
						margin-bottom: -24px;
 | 
				
			||||||
 | 
						top: -10px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#spinner.syspanel {
 | 
				
			||||||
 | 
						position: relative;
 | 
				
			||||||
 | 
						right: 20px;
 | 
				
			||||||
 | 
						top: -24px;
 | 
				
			||||||
 | 
						bottom: 0;
 | 
				
			||||||
 | 
						margin-bottom: -24px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user