diff --git a/blazar_dashboard/content/leases/forms.py b/blazar_dashboard/content/leases/forms.py index d0fa2f2..40dfa2d 100644 --- a/blazar_dashboard/content/leases/forms.py +++ b/blazar_dashboard/content/leases/forms.py @@ -56,7 +56,7 @@ class CreateForm(forms.SelfHandlingForm): required=True, choices=( ('host', _('Physical Host')), - ('instance', _('Virtual Instance (Not yet supported in GUI)')) + ('instance', _('Virtual Instance')) ), widget=forms.ThemableSelectWidget(attrs={ 'class': 'switchable', @@ -108,6 +108,52 @@ class CreateForm(forms.SelfHandlingForm): 'placeholder': 'e.g. ["==", "$extra_key", "extra_value"]'}) ) + # Fields for instance reservation + amount = forms.IntegerField( + label=_('Instance Count'), + required=False, + help_text=_('Enter the number of instances to reserve.'), + min_value=1, + initial=1, + widget=forms.NumberInput(attrs={ + 'class': 'switched', + 'data-switch-on': 'source', + 'data-source-instance': _('Instance Count')}) + ) + vcpus = forms.IntegerField( + label=_('Number of VCPUs'), + required=False, + help_text=_('Enter the number of VCPUs per instance.'), + min_value=1, + initial=1, + widget=forms.NumberInput(attrs={ + 'class': 'switched', + 'data-switch-on': 'source', + 'data-source-instance': _('Number of VCPUs')}) + ) + memory_mb = forms.IntegerField( + label=_('RAM (MB)'), + required=False, + help_text=_('Enter the size of RAM (MB) per instance'), + min_value=1, + initial=1, + widget=forms.NumberInput(attrs={ + 'class': 'switched', + 'data-switch-on': 'source', + 'data-source-instance': _('RAM (MB)')}) + ) + disk_gb = forms.IntegerField( + label=_('Root Disk (GB)'), + required=False, + help_text=_('Enter the root disk size (GB) per instance'), + min_value=0, + initial=0, + widget=forms.NumberInput(attrs={ + 'class': 'switched', + 'data-switch-on': 'source', + 'data-source-instance': _('Root Disk (GB)')}) + ) + def handle(self, request, data): if data['resource_type'] == 'host': reservations = [ @@ -121,8 +167,16 @@ class CreateForm(forms.SelfHandlingForm): } ] elif data['resource_type'] == 'instance': - raise forms.ValidationError('Virtual instance is not yet ' - 'supported in GUI') + reservations = [ + { + 'resource_type': 'virtual:instance', + 'amount': data['amount'], + 'vcpus': data['vcpus'], + 'memory_mb': data['memory_mb'], + 'disk_gb': data['disk_gb'], + 'affinity': False + } + ] events = [] @@ -161,10 +215,6 @@ class CreateForm(forms.SelfHandlingForm): cleaned_data['end_date'] = (cleaned_data['start_date'] + datetime.timedelta(days=1)) - if cleaned_data['resource_type'] == 'instance': - raise forms.ValidationError('Resource type "virtual instance" is ' - 'not yet supported in GUI') - class UpdateForm(forms.SelfHandlingForm): diff --git a/blazar_dashboard/content/leases/tests.py b/blazar_dashboard/content/leases/tests.py index 9d612c2..d58663d 100644 --- a/blazar_dashboard/content/leases/tests.py +++ b/blazar_dashboard/content/leases/tests.py @@ -133,17 +133,40 @@ class LeasesTests(test.TestCase): def test_create_lease_instance_reservation(self): start_date = datetime(2030, 6, 27, 18, 0, tzinfo=pytz.utc) end_date = datetime(2030, 6, 30, 18, 0, tzinfo=pytz.utc) + dummy_lease = {} + api.client.lease_create( + IsA(http.HttpRequest), + 'lease-1', + start_date.strftime('%Y-%m-%d %H:%M'), + end_date.strftime('%Y-%m-%d %H:%M'), + [ + { + 'resource_type': 'virtual:instance', + 'amount': 3, + 'vcpus': 2, + 'memory_mb': 4096, + 'disk_gb': 128, + 'affinity': False + } + ], + [] + ).AndReturn(dummy_lease) + self.mox.ReplayAll() form_data = { 'name': 'lease-1', 'start_date': start_date.strftime('%Y-%m-%d %H:%M'), 'end_date': end_date.strftime('%Y-%m-%d %H:%M'), 'resource_type': 'instance', + 'amount': 3, + 'vcpus': 2, + 'memory_mb': 4096, + 'disk_gb': 128 } res = self.client.post(CREATE_URL, form_data) - self.assertTemplateUsed(res, CREATE_TEMPLATE) - self.assertFormErrors(res, 1) - self.assertContains(res, 'not yet supported') + self.assertNoFormErrors(res) + self.assertMessageCount(success=1) + self.assertRedirectsNoFollow(res, INDEX_URL) @test.create_stubs({api.client: ('lease_create', )}) def test_create_lease_client_error(self):