Skip to content

Adding Owner ResourceAttribute to nodes that don’t have one #383

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions coldfront/core/resource/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ def __init__(self, *args, **kwargs):
self.fields['resource_attribute_type'].queryset = self.fields['resource_attribute_type'].queryset.order_by(Lower('name'))


class ResourceAttributeUpdateForm(forms.Form):
resource_attribute_type_name = forms.CharField(max_length=250, required=False, disabled=True)
value = forms.CharField(max_length=350, required=True)


class ResourceAllocationUpdateForm(forms.Form):
allocation_pk = forms.IntegerField(required=False)
project = forms.CharField(max_length=250, required=False, disabled=True)
Expand Down
8 changes: 8 additions & 0 deletions coldfront/core/resource/templates/resource_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ <h3><i class="fas fa-list" aria-hidden="true"></i> Resource Information</h3>
</div>

<div class="card-body">
{% if request.user.is_superuser and not owner_set%}
<div class="alert alert-info" role="alert">
<i class="fas fa-info-circle" aria-hidden="true"></i> No owner has been set for this resource! Change this by editing the Owner value in the Resource Attributes table.
</div>
{% endif %}
{% csrf_token %}
<div class="table-responsive">
<table class="table table-bordered table-sm">
Expand Down Expand Up @@ -100,6 +105,9 @@ <h3 class="d-inline"><i class="fas fa-info-circle" aria-hidden="true"></i> Resou
<a class="btn btn-success" href="{% url 'resource-attribute-add' resource.pk %}" role="button">
<i class="fas fa-plus" aria-hidden="true"></i> Add Resource Attribute
</a>
<a class="btn btn-danger" href="{% url 'resource-attributes-edit' resource.pk %}" role="button">
<i class="fas fa-edit" aria-hidden="true"></i> Edit Resource Attributes
</a>
<a class="btn btn-danger" href="{% url 'resource-attribute-delete' resource.pk %}" role="button">
<i class="fas fa-minus" aria-hidden="true"></i> Delete Resource Attributes
</a>
Expand Down
101 changes: 101 additions & 0 deletions coldfront/core/resource/templates/resource_resourceattribute_edit.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
{% extends "common/base.html" %}
{% load crispy_forms_tags %}
{% load static %}
{% load django_tables2 %}
{% load mathfilters %}
{% load common_tags %}
{% load fasrc_tags %}

{% block title %}Edit Resource Attributes for {% endblock %}

{% block content %}
<div id="allocation-list">
<div class="mb-3">
<h2>Edit Resource Attributes for {{resource.name}} {{resource.resource_type.name}}</h2>
<hr>
</div>
<!-- Start Attributes -->
<div class="mb-3">
<div class="row">
<div class="table-responsive">
<div class="container mb-3 mt-3">
<form id="edit_resouce_attributes" method="POST" action="{% url 'resource-attributes-edit' resource.pk %}">
{{ formset.management_form }}
{% csrf_token %}
<table id="edit_resouce_attributes_table" class="table table-striped table-bordered" filter="off">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Attribute</th>
<th scope="col">Value</th>
</tr>
</thead>
<tbody>
{% for form in formset.forms %}
<tr>
<th scope="col"> {{ forloop.counter }} </th>
<th scope="col"> {{form.resource_attribute_type_name.value}} </th>
<th scope="col"> {{form.value}} </th>
{% if form.errors %}
<div class="alert alert-danger">{{ form.errors }}</div>
{% endif %}
</tr>
{% endfor %}
</tbody>

<script type="text/javascript">
function findTotal(){
var arr = document.getElementsByName('usage');
var tot=0;
for(var i=0;i<arr.length;i++){
if(parseInt(arr[i].value))
tot += parseInt(arr[i].value);
}
document.getElementById('total').value = tot;
}
</script>

</table>
</form>
{% if request.user.is_superuser %}
<div class="text-left">
<a class="btn btn-primary" href="#" role="button" id="edit_resource_attributes_button">
<i class="fas fa-sync" aria-hidden="true"></i> Save Changes
</a>
<a class="btn btn-secondary" href="{% url 'resource-detail' resource.pk %}" role="button">
<i class="fas fa-long-arrow-left" aria-hidden="true"></i>
Back to Resource
</a>
</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>


<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/dt/jszip-2.5.0/dt-1.10.24/af-2.3.5/b-1.7.0/b-colvis-1.7.0/b-html5-1.7.0/b-print-1.7.0/cr-1.5.3/date-1.0.2/fc-3.3.2/kt-2.6.1/r-2.2.7/rg-1.1.2/rr-1.2.7/sl-1.3.2/datatables.min.css"/>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/pdfmake.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/vfs_fonts.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/v/dt/jszip-2.5.0/dt-1.10.24/af-2.3.5/b-1.7.0/b-colvis-1.7.0/b-html5-1.7.0/b-print-1.7.0/cr-1.5.3/date-1.0.2/fc-3.3.2/kt-2.6.1/r-2.2.7/rg-1.1.2/rr-1.2.7/sl-1.3.2/datatables.min.js"></script>
<script>
$(document).ready(
function () {
$('#edit_resouce_attributes_table').DataTable(
{
"lengthMenu": [[25, 50, -1], [25, 50, "All"]],
"pageLength": 25,
dom: 'B<"clear">lfrtip',
order: [[ 1, "asc" ]],
buttons: [],
paging: false
}
);
document.getElementById('edit_resource_attributes_button').addEventListener('click', (event)=> {
document.getElementById('edit_resouce_attributes').submit();
});
});
</script>
{% endblock %}

2 changes: 2 additions & 0 deletions coldfront/core/resource/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@
resource_views.ResourceAttributeDeleteView.as_view(), name='resource-attribute-delete'),
path('<int:pk>/resourceallocations/edit', resource_views.ResourceAllocationsEditView.as_view(),
name='resource-allocations-edit'),
path('<int:pk>/resourceattributes/edit', resource_views.ResourceAttributeEditView.as_view(),
name='resource-attributes-edit'),
]
87 changes: 86 additions & 1 deletion coldfront/core/resource/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
ResourceAttributeCreateForm,
ResourceSearchForm,
ResourceAttributeDeleteForm,
ResourceAttributeUpdateForm,
ResourceAllocationUpdateForm,
)
from coldfront.core.allocation.models import AllocationStatusChoice, AllocationAttributeType, AllocationAttribute
Expand Down Expand Up @@ -161,6 +162,12 @@ def get_context_data(self, **kwargs):
'effectvusage'
)
)
if 'Compute Node' in resource_obj.resource_type.name:
owner_attribute_list = list(filter(lambda attribute: attribute.resource_attribute_type.name.lower() in ['owner'], attributes))
owner_attribute_value = ''
if len(owner_attribute_list) == 1:
owner_attribute_value = owner_attribute_list[0].value
context['owner_set'] = bool(owner_attribute_value)
elif resource_obj.resource_type.name == 'Storage':
allocation_total = {'size': 0, 'usage':0}
for allocation in allocations:
Expand All @@ -169,7 +176,6 @@ def get_context_data(self, **kwargs):
if allocation.usage:
allocation_total['usage'] += allocation.usage
context['allocation_total'] = allocation_total

context['allocations'] = allocations
context['resource'] = resource_obj
context['attributes'] = attributes
Expand Down Expand Up @@ -217,6 +223,85 @@ def get_success_url(self):
return reverse('resource-detail', kwargs={'pk': self.kwargs.get('pk')})


class ResourceAttributeEditView(LoginRequiredMixin, UserPassesTestMixin, TemplateView):
template_name = 'resource_resourceattribute_edit.html'

def test_func(self):
"""UserPassesTestMixin Tests"""
if self.request.user.is_superuser:
return True
err = 'You do not have permission to edit resource attributes.'
messages.error(self.request, err)
return False

def get_formset_initial_data(self, resource_attributes):
edit_attributes_formset_initial_data = []
if resource_attributes:
for attribute in resource_attributes:
edit_attributes_formset_initial_data.append(
{
'resource_attribute_type_name': attribute.resource_attribute_type.name,
'value': attribute.value,
}
)
return edit_attributes_formset_initial_data

def get_context_data(self, resource_obj):
context = {}
resource_attributes = resource_obj.resourceattribute_set.all()
if resource_attributes:
ResourceAttributeUpdateFormSet = formset_factory(
ResourceAttributeUpdateForm,
max_num=len(resource_attributes),
extra=0
)
edit_attributes_formset_initial_data = self.get_formset_initial_data(resource_attributes)
formset = ResourceAttributeUpdateFormSet(
initial=edit_attributes_formset_initial_data,
prefix='attributesform'
)
context['formset'] = formset
context['resource'] = resource_obj
return context

def get(self, request, *args, **kwargs):
resource_obj = get_object_or_404(Resource, pk=self.kwargs.get('pk'))
context = self.get_context_data(resource_obj)
return render(request, self.template_name, context)

def post(self, request, *args, **kwargs):
pk = self.kwargs.get('pk')
resource_obj = get_object_or_404(Resource, pk=pk)
resource_attributes = resource_obj.resourceattribute_set.all()
edit_attributes_formset_initial_data = self.get_formset_initial_data(resource_attributes)
logger.warning(f'initial_data {edit_attributes_formset_initial_data}')

ResourceAttributeUpdateFormSet = formset_factory(
ResourceAttributeUpdateForm,
max_num=len(resource_attributes),
extra=0
)
formset = ResourceAttributeUpdateFormSet(
request.POST,
initial=edit_attributes_formset_initial_data,
prefix='attributesform'
)
if formset.is_valid():
for form in formset.forms:
attribute_name = form.cleaned_data.get('resource_attribute_type_name')
attribute_value = form.cleaned_data.get('value')
resource_attribute = [attribute for attribute in resource_attributes if attribute.resource_attribute_type.name == attribute_name][0]
resource_attribute.value = attribute_value
resource_attribute.save()
messages.success(request, 'Resource attributes update complete.')
return HttpResponseRedirect(reverse('resource-attributes-edit', kwargs={'pk': pk}))
else:
messages.error(request, 'Errors encountered, changes not saved. Check the form for details')
context = self.get_context_data(resource_obj)
context['formset'] = formset
return render(request, self.template_name, context)


class ResourceAttributeDeleteView(LoginRequiredMixin, UserPassesTestMixin, TemplateView):
template_name = 'resource_resourceattribute_delete.html'

Expand Down