Commit 67af8386 authored by Danielle Caled's avatar Danielle Caled
Browse files

Ajustes após o merge com a branch reservation-dev.

parent ca3a383e
import copy
import json
from base64 import b64encode
import time
from django.db import models
from tools.broker_rest_client import Urllib3RestClient
from tools.rest_client import communication_client
import portal.portal_constants as const
import logging
from django.contrib.auth.hashers import check_password
import portal.portal_constants as constants
from django.utils import timezone
class Reservation(object):
def __init__(self, slice, member_certificate):
self.slice = slice
self.member_certificate = member_certificate
def __init__(self, slice_credential):
self.slice_credential = slice_credential
self.vms = None
self.nodes = None
self.schedules = None
state, slice_credential = slice.retrieve_credential(certificate=member_certificate)
self.slice_credential = slice_credential
self.b64_slice_credential = b64encode(self.slice_credential.encode('utf-8')).decode('utf-8')
self.b64_slice_credential = b64encode(
self.slice_credential.encode('utf-8')).decode('utf-8')
@classmethod
def create_from_form(cls, form, slice, member_certificate):
reservation = Reservation(slice, member_certificate)
def create_from_form(cls, form, slice_credential):
reservation = Reservation(slice_credential)
reservation.vms = form.cleaned_data['vms']
reservation.nodes = form.cleaned_data['nodes']
reservation.schedules = form.cleaned_data['schedules']
......@@ -40,7 +32,7 @@ class Reservation(object):
leases = self.get_leases()
success = 0
for lease in leases:
leases_url = constants.BROKER_BASE_URL + '/resources/leases'
leases_url = const.BROKER_BASE_URL + '/resources/leases'
status, result = broker_client.post(leases_url, lease)
if status == 200:
success += 1
......@@ -85,23 +77,25 @@ class Reservation(object):
class Resource(object):
def __init__(self, member_urn, member_certificate):
self.member_certificate = member_certificate
self.member = Member(urn=member_urn)
state, self.member_credential = self.member.retrieve_credential(certificate=member_certificate)
def __init__(self, member_credential):
self.member_credential = member_credential
self.broker_client = Urllib3RestClient()
self.b64_member_credential = b64encode(self.member_credential.encode('utf-8')).decode('utf-8')
self.broker_client.add_header('CH-Credential', self.b64_member_credential)
self.b64_member_credential = b64encode(
self.member_credential.encode('utf-8')).decode('utf-8')
self.broker_client.add_header(
'CH-Credential', self.b64_member_credential)
def get_resources(self, resource_type, filter=None):
resources_url = constants.BROKER_BASE_URL + '/resources/' + resource_type
resources_url = const.BROKER_BASE_URL + '/resources/' + resource_type
status, resources = self.broker_client.get(resources_url)
if status != 200:
raise "Could not get resources, code " + str(status)
if filter is not None:
filtered_resources = copy.deepcopy(resources['resource_response']['resources'])
filtered_resources =\
copy.deepcopy(resources['resource_response']['resources'])
for key, value in filter.items():
splitted_key = key.split('.')
for resource in resources['resource_response']['resources']:
......@@ -124,14 +118,16 @@ class Resource(object):
nodes = self.get_resources('nodes')
hypervisors = []
for node in nodes['resource_response']['resources']:
resource_type = 'node' if (node['exclusive'] == True) else 'hypervisor'
resource_type =\
'node' if (node['exclusive']) else 'hypervisor'
if resource_type == 'hypervisor':
if node['urn'] in hypervisors:
continue
hypervisors.append(node['urn'])
# treat hypervisor
node['vcpu_count'] = sum([(int(x['cores']) * int(x['threads'])) for x in node['cpus']])
node['vcpu_count'] =\
sum([(int(x['cores']) * int(x['threads'])) for x in node['cpus']])
# Get topology
topology['nodes'].append({
......@@ -145,8 +141,10 @@ class Resource(object):
and (interface['link']['urn'] not in inserted_edges):
topology['edges'].append({
'urn': interface['link']['urn'],
'source': interface['link']['connects'][0]['urn'],
'target': interface['link']['connects'][1]['urn']
'source':
interface['link']['connects'][0]['urn'],
'target':
interface['link']['connects'][1]['urn']
})
inserted_edges.append(interface['link']['urn'])
......@@ -157,7 +155,9 @@ class Resource(object):
# Get leases
leases = self.get_resources('leases')
for lease in leases['resource_response']['resources']:
if len(lease['components']) > 0 and lease['valid_until']['s'] > time.time():
if len(lease['components']) > 0 and\
lease['valid_until']['s'] > time.time():
treated_resources['lease'].append({
'urn': lease['urn'],
'start': lease['valid_from']['s'],
......@@ -167,5 +167,3 @@ class Resource(object):
return treated_resources
......@@ -9,85 +9,78 @@
{% if project_expired %}
<p class="text-left">Project {{project_name}} is expired. You can only create slices in an enabled project. Reactivate or ask the project owner of this project to update its expiration. </p>
<p class="text-left">Project {{project_name}} is expired. You can only create slices in an enabled project. Reactivate or ask the project owner of this project to update its expiration. </p>
{% else %}
<p class="text-left">Slice name must have from 2 to 18 alphanumeric characters, hyphen or underscore. Ant it should not begin with hyphen or underscore.</p>
<p class="text-left">Slice name must have from 2 to 18 alphanumeric characters, hyphen or underscore. Ant it should not begin with hyphen or underscore.</p>
<p class="text-left text-muted">Slice names must be unique in a project context. There can only exist one slice with a given name in its project. Slice names are public and visible to all project members.</p>
<p class="text-left text-muted">Slice names must be unique in a project context. There can only exist one slice with a given name in its project. Slice names are public and visible to all project members.</p>
<p class="text-left text-muted">When the slice expiration is not set during the creation, a default expiration (1 week) is adopted.</p>
<p class="text-left text-muted">When the slice expiration is not set during the creation, a default expiration (1 week) is adopted.</p>
{% endif %}
</div>
{% if not project_expired %}
<div>
<form class="form-horizontal" role="form" action="" method="post">
{% csrf_token %}
<div>
<form class="form-horizontal" role="form" action="" method="post">
{% csrf_token %}
{% if slice_created == True %}
{% if slice_created == True %}
<div class="alert alert-success">
<p>Your slice was successfully created.</p>
</div>
<div class="alert alert-success">
<p>Your slice was successfully created.</p>
</div>
{% elif form.errors or slice_created == False %}
{% elif form.errors or slice_created == False %}
<div class="alert alert-danger">
<p><strong>Please, review the follwing item(s):</strong></p>
<div class="alert alert-danger">
<p><strong>Please, review the follwing item(s):</strong></p>
{{ form.non_field_errors }}
{{ form.non_field_errors }}
{% if message %}
<p>{{ message }}</p>
{% endif %}
{% if form.slice_name.errors %}
<p>{{ form.slice_name.label }} {{ form.slice_name.errors }}</p>
{% endif %}
{% if form.slice_description.errors %}
<p>{{ form.slice_description.label }} {{ form.slice_description.errors }}</p>
{% endif %}
{% if form.slice_expiration.errors %}
<p>{{ form.slice_expiration.label }} {{ form.slice_expiration.errors }}</p>
{% endif %}
{% if message %}
<p>{{ message }}</p>
{% endif %}
{% if form.slice_expiration_time.errors %}
<p>{{ form.slice_expiration_time.label }} {{ form.slice_expiration_time.errors }}</p>
{% endif %}
</div>
{% endif %}
{% if form.slice_name.errors %}
<p>{{ form.slice_name.label }} {{ form.slice_name.errors }}</p>
{% endif %}
{% for field in form %}
{% if form.slice_description.errors %}
<p>{{ form.slice_description.label }} {{ form.slice_description.errors }}</p>
{% endif %}
<div class="form-group" id={{field.id_for_label}}_div>
<div class="col-sm-4">
<label for="{{ field.id_for_label }}" class="control-label">{{ field.label }}{% if field.field.required %}<span class="special_class">*</span>{% endif %}</label>
</div>
{% if form.slice_expiration.errors %}
<p>{{ form.slice_expiration.label }} {{ form.slice_expiration.errors }}</p>
{% endif %}
<div class="form-group" id={{field.id_for_label}}_div>
<div class="col-sm-4">
<label for="{{ field.id_for_label }}" class="control-label">{{ field.label }}{% if field.field.required %}<span class="special_class">*</span>{% endif %}</label>
</div>
<div class="col-sm-8">
{{field}}
<p>{{field.help_text}}</p>
</div>
</div>
{% if form.slice_expiration_time.errors %}
<p>{{ form.slice_expiration_time.label }} {{ form.slice_expiration_time.errors }}</p>
{% endif %}
</div>
<button type="submit" class="btn btn-primary">Create Slice</button>
</div>
{% endif %}
{% for field in form %}
<div class="form-group" id={{field.id_for_label}}_div>
<div class="col-sm-4">
<label for="{{ field.id_for_label }}" class="control-label">{{ field.label }}{% if field.field.required %}<span class="special_class">*</span>{% endif %}</label>
</div>
<div class="col-sm-8">
{{field}}
<p>{{field.help_text}}</p>
</div>
</div>
{% endfor %}
<button type="submit" class="btn btn-primary">Create Slice</button>
</form>
</div>
{% endif %}
<script type="text/javascript">
<script type="text/javascript">
$("input[name='slice_expiration_time']").attr('disabled',true);
......
......@@ -14,23 +14,24 @@
});
});
</script>
{% if messages or get_resources_error %}
<div class="panel panel-primary">
<div class="panel-heading">Info</div>
<div class="panel-body">
<ul style="margin-bottom: 0;">
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message|capfirst }}</li>
{% endfor %}
</ul>
{% if get_resources_error %}
<ul style="margin-bottom: 0;">
<li>Could not get reservations of this slice, try later.</li>
</ul>
{% endif %}
</div>
</div>
{% endif %}
{% if messages or get_resources_error %}
<div class="panel panel-primary">
<div class="panel-heading">Info</div>
<div class="panel-body">
<ul style="margin-bottom: 0;">
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message|capfirst }}</li>
{% endfor %}
</ul>
{% if get_resources_error %}
<ul style="margin-bottom: 0;">
<li>Could not get reservations of this slice, try later.</li>
</ul>
{% endif %}
</div>
</div>
{% endif %}
{% if delete_member_status == True %}
......@@ -149,7 +150,7 @@
<button type="submit" name="delete_slice" class="btn btn-primary">Delete Slice</button>
<a class="btn btn-primary" href="{% url 'portal:create_reservation' project_name=project_name slice_name=slice_name%}">Create Reservation</a>
<a class="btn btn-primary" href="{% url 'portal:create_reservation' project_name=project_name slice_name=retrieved_slice.slice_name%}">Create Reservation</a>
<p><b>ATTENTION:</b> To enable an expired slice, you must update it with a future expiration date.</p>
{% endif %}
......
......@@ -5,6 +5,7 @@ from django.core.exceptions import PermissionDenied
from django.conf import settings
from django.http import Http404
from django.shortcuts import render, redirect
from django.contrib import messages
from portal.forms.forms_projects import CreateProjectForm, \
UpdateProjectForm
......@@ -19,8 +20,8 @@ import portal.views.views_requests as v_req
#Reservations
from portal.forms.forms_reservations import CreateReservationForm
from tools.broker_rest_client import Urllib3RestClient
import portal.models.reservation
from portal.models.reservation import Reservation, Resource
import json
fmt = getattr(settings, 'LOG_FORMAT', None)
......@@ -1027,59 +1028,97 @@ def list_project_members_and_membership(members_dict):
# Return project_members_dict
return project_members_dict
#Reservations
# Reservations
def create_reservation(request, project_name, slice_name):
member_certificate = request.session['member_certificate']
# Instantiates new project with a given project name.
slice = Slice(slice_name=slice_name)
# Retrieves slice urn
retrived_slice = slice.search_slice(
certificate=member_certificate,
filter_params=[
constants.CH_SLICE_NAME,
constants.CH_SLICE_EXPIRED])
# Checks if any slice was retrieved.
if retrived_slice:
# Initializes slice_urn as the URN of retrieved slice.
slice_urn = getattr(retrived_slice[0], constants.CH_SLICE_URN)
slice_expired = getattr(retrived_slice[0], constants.CH_SLICE_EXPIRED)
if slice_expired:
logging.debug(constants.VIEW_SLICE_EXPIRED)
form = CreateReservationForm((None if request.method == 'GET' else request.POST))
if form.is_valid():
reservation = Reservation.create_from_form(form, retrived_slice[0], member_certificate)
success, total = reservation.create_reservation()
if success == total:
messages.add_message(request, messages.INFO, "Your reservation was successfully created")
else:
messages.add_message(request, messages.INFO, "Your reservation was partially created, check the " +
"reservations list")
return redirect('portal:detail_slice', project_name=project_name, slice_name=slice_name)
context = {
'form': form,
'project_name': project_name,
'slice_name': slice_name,
'slice_expired': slice_expired
}
try:
resources = Resource(request.session['member_urn'], member_certificate).get_treated_resources_of_testbed()
context['resources'] = resources
context['topology'] = json.dumps(resources['topology'])
context['leases'] = json.dumps(resources['lease'])
context['hypervisors'] = json.dumps(resources['hypervisor'])
except Exception:
context['get_resources_error'] = True
context['topology'] = json.dumps([])
context['leases'] = json.dumps([])
context['hypervisors'] = json.dumps([])
# Renders template.
return render(request, 'slice/create_reservation.html', context)
# Set member_credential as the credential in the session.
member_credential = request.session['member_cred']
# Lookup projects in CH by name.
retrieved_projects = Project().retrieve_project(
credential=member_credential,
match={const.CH_PROJECT_NAME: project_name},
filter=[const.CH_PROJECT_URN])
# If search returns project.
if retrieved_projects:
# Set retrieved_project as retrieved_projects[0].
retrieved_project = retrieved_projects[0]
# Set project_urn.
project_urn = getattr(retrieved_project, const.CH_PROJECT_URN)
# Retrieve slice
retrieved_slices = Slice().retrieve_slice(
credential=member_credential,
project_urn=project_urn,
match={const.CH_SLICE_NAME: slice_name},
filter=[
const.CH_SLICE_URN,
const.CH_SLICE_EXPIRED])
# If search returns slice.
if retrieved_slices:
# Set slice_urn.
slice_urn = getattr(
retrieved_slices[0], const.CH_SLICE_URN)
# Set slice expired flag.
slice_expired = getattr(
retrieved_slices[0], const.CH_SLICE_EXPIRED)
# Retrieve slice credential
credential_status, slice_credential =\
Slice().retrieve_credential(
credential=member_credential,
slice_urn=slice_urn)
if slice_expired:
logging.debug(const.VIEW_SLICE_EXPIRED)
form = CreateReservationForm(
(None if request.method == 'GET' else request.POST))
if form.is_valid():
reservation = Reservation.create_from_form(
form, slice_credential)
success, total = reservation.create_reservation()
if success == total:
messages.add_message(
request,
messages.INFO,
"Your reservation was successfully created")
else:
messages.add_message(
request, messages.INFO,
"Your reservation was partially created, check the " +
"reservations list")
return redirect(
'portal:detail_slice',
project_name=project_name,
slice_name=slice_name)
context = {
'form': form,
'project_name': project_name,
'slice_name': slice_name,
'slice_expired': slice_expired
}
try:
resources = Resource(
member_credential).get_treated_resources_of_testbed()
context['resources'] = resources
context['topology'] = json.dumps(resources['topology'])
context['leases'] = json.dumps(resources['lease'])
context['hypervisors'] = json.dumps(resources['hypervisor'])
except Exception:
context['get_resources_error'] = True
context['topology'] = json.dumps([])
context['leases'] = json.dumps([])
context['hypervisors'] = json.dumps([])
# Renders template.
return render(request, 'slice/create_reservation.html', context)
raise Http404
......@@ -32,11 +32,9 @@ def create_slice(request, project_name):
member_credential = request.session['member_cred']
# Set member_urn as the member urn in the session.
member_urn = request.session['member_urn']
# Instantiate new project with a given project name.
project = Project(project_name=project_name)
# Retrieve project urn
retrieved_projects = project.retrieve_project(
retrieved_projects = Project().retrieve_project(
credential=Portal.get_portal_credential(),
match={const.CH_PROJECT_NAME: project_name},
filter=[
......
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