|
| 1 | +diff --git a/coldfront/core/allocation/forms.py b/coldfront/core/allocation/forms.py |
| 2 | +index 9700244..e893e8f 100644 |
| 3 | +--- a/coldfront/core/allocation/forms.py |
| 4 | ++++ b/coldfront/core/allocation/forms.py |
| 5 | +@@ -1,5 +1,6 @@ |
| 6 | + from django import forms |
| 7 | + from django.db.models.functions import Lower |
| 8 | ++from django.core.exceptions import ValidationError |
| 9 | + from django.shortcuts import get_object_or_404 |
| 10 | + |
| 11 | + from coldfront.core.allocation.models import (Allocation, AllocationAccount, |
| 12 | +@@ -11,6 +12,8 @@ from coldfront.core.project.models import Project |
| 13 | + from coldfront.core.resource.models import Resource, ResourceType |
| 14 | + from coldfront.core.utils.common import import_from_settings |
| 15 | + |
| 16 | ++from coldfront_plugin_cloud import tasks, utils |
| 17 | ++ |
| 18 | + ALLOCATION_ACCOUNT_ENABLED = import_from_settings( |
| 19 | + 'ALLOCATION_ACCOUNT_ENABLED', False) |
| 20 | + ALLOCATION_CHANGE_REQUEST_EXTENSION_DAYS = import_from_settings( |
| 21 | +@@ -201,6 +204,33 @@ class AllocationAttributeChangeForm(forms.Form): |
| 22 | + allocation_attribute.clean() |
| 23 | + |
| 24 | + |
| 25 | ++class AllocationAttributeChangeFormSet(forms.BaseFormSet): |
| 26 | ++ def __init__(self, *args, **kwargs): |
| 27 | ++ super().__init__(*args, **kwargs) |
| 28 | ++ |
| 29 | ++ def _validate_openshift_quotas(self): |
| 30 | ++ """ |
| 31 | ++ Performs validation on the OpenShift quotas. |
| 32 | ++ For now, only check that current usage is lower than requested quota. |
| 33 | ++ """ |
| 34 | ++ allocation_attribute = AllocationAttribute.objects.get(pk=self.cleaned_data[0].get('pk')) |
| 35 | ++ allocation = allocation_attribute.allocation |
| 36 | ++ if allocator := tasks.find_allocator(allocation): |
| 37 | ++ # Only support Openshift allocations for now |
| 38 | ++ if allocator.resource_type == 'openshift': |
| 39 | ++ requested_quota = utils.get_new_cloud_quota(self.cleaned_data) |
| 40 | ++ cloud_quota_usage = tasks.get_allocation_cloud_usage(allocation.pk) |
| 41 | ++ usage_errors = utils.check_cloud_usage_is_lower(requested_quota, cloud_quota_usage) |
| 42 | ++ |
| 43 | ++ if usage_errors: |
| 44 | ++ raise ValidationError(usage_errors) |
| 45 | ++ |
| 46 | ++ def clean(self): |
| 47 | ++ if any(self.errors): |
| 48 | ++ return |
| 49 | ++ self._validate_openshift_quotas() |
| 50 | ++ |
| 51 | ++ |
| 52 | + class AllocationAttributeUpdateForm(forms.Form): |
| 53 | + change_pk = forms.IntegerField(required=False, disabled=True) |
| 54 | + attribute_pk = forms.IntegerField(required=False, disabled=True) |
| 55 | +diff --git a/coldfront/core/allocation/views.py b/coldfront/core/allocation/views.py |
| 56 | +index 90f04b8..f5296fe 100644 |
| 57 | +--- a/coldfront/core/allocation/views.py |
| 58 | ++++ b/coldfront/core/allocation/views.py |
| 59 | +@@ -28,6 +28,7 @@ from coldfront.core.allocation.forms import (AllocationAccountForm, |
| 60 | + AllocationChangeForm, |
| 61 | + AllocationChangeNoteForm, |
| 62 | + AllocationAttributeChangeForm, |
| 63 | ++ AllocationAttributeChangeFormSet, |
| 64 | + AllocationAttributeUpdateForm, |
| 65 | + AllocationForm, |
| 66 | + AllocationInvoiceNoteDeleteForm, |
| 67 | +@@ -1786,7 +1787,7 @@ class AllocationChangeView(LoginRequiredMixin, UserPassesTestMixin, FormView): |
| 68 | + |
| 69 | + if allocation_attributes_to_change: |
| 70 | + formset = formset_factory(self.formset_class, max_num=len( |
| 71 | +- allocation_attributes_to_change)) |
| 72 | ++ allocation_attributes_to_change), formset=AllocationAttributeChangeFormSet) |
| 73 | + formset = formset( |
| 74 | + request.POST, initial=allocation_attributes_to_change, prefix='attributeform') |
| 75 | + |
| 76 | +@@ -1796,6 +1797,8 @@ class AllocationChangeView(LoginRequiredMixin, UserPassesTestMixin, FormView): |
| 77 | + messages.error(request, error) |
| 78 | + for error in formset.errors: |
| 79 | + if error: attribute_errors += error.get('__all__') |
| 80 | ++ for error in formset.non_form_errors(): |
| 81 | ++ messages.error(request, error) |
| 82 | + messages.error(request, attribute_errors) |
| 83 | + return HttpResponseRedirect(reverse('allocation-change', kwargs={'pk': pk})) |
| 84 | + form_data = form.cleaned_data |
0 commit comments