Implement view logic
This commit is contained in:
parent
ef4f76b290
commit
2a63677539
1 changed files with 87 additions and 6 deletions
|
|
@ -14,6 +14,7 @@ from servala.core.models import (
|
||||||
ServiceOffering,
|
ServiceOffering,
|
||||||
)
|
)
|
||||||
from servala.frontend.forms.service import (
|
from servala.frontend.forms.service import (
|
||||||
|
ComputePlanSelectionForm,
|
||||||
ControlPlaneSelectForm,
|
ControlPlaneSelectForm,
|
||||||
ServiceFilterForm,
|
ServiceFilterForm,
|
||||||
ServiceInstanceDeleteForm,
|
ServiceInstanceDeleteForm,
|
||||||
|
|
@ -152,6 +153,13 @@ class ServiceOfferingDetailView(OrganizationViewMixin, HtmxViewMixin, DetailView
|
||||||
control_plane=self.selected_plane, service_offering=self.object
|
control_plane=self.selected_plane, service_offering=self.object
|
||||||
).first()
|
).first()
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def plan_form(self):
|
||||||
|
data = self.request.POST if self.request.method == "POST" else None
|
||||||
|
return ComputePlanSelectionForm(
|
||||||
|
data=data, control_plane_crd=self.context_object, prefix="plans"
|
||||||
|
)
|
||||||
|
|
||||||
def get_instance_form_kwargs(self, ignore_data=False):
|
def get_instance_form_kwargs(self, ignore_data=False):
|
||||||
return {
|
return {
|
||||||
"initial": {
|
"initial": {
|
||||||
|
|
@ -205,6 +213,7 @@ class ServiceOfferingDetailView(OrganizationViewMixin, HtmxViewMixin, DetailView
|
||||||
context["select_form"] = self.select_form
|
context["select_form"] = self.select_form
|
||||||
context["has_control_planes"] = self.planes.exists()
|
context["has_control_planes"] = self.planes.exists()
|
||||||
context["selected_plane"] = self.selected_plane
|
context["selected_plane"] = self.selected_plane
|
||||||
|
context["context_object"] = self.context_object
|
||||||
context["hide_expert_mode"] = self.hide_expert_mode
|
context["hide_expert_mode"] = self.hide_expert_mode
|
||||||
if self.request.method == "POST":
|
if self.request.method == "POST":
|
||||||
if self.is_custom_form:
|
if self.is_custom_form:
|
||||||
|
|
@ -222,6 +231,17 @@ class ServiceOfferingDetailView(OrganizationViewMixin, HtmxViewMixin, DetailView
|
||||||
if self.selected_plane and self.selected_plane.wildcard_dns:
|
if self.selected_plane and self.selected_plane.wildcard_dns:
|
||||||
context["wildcard_dns"] = self.selected_plane.wildcard_dns
|
context["wildcard_dns"] = self.selected_plane.wildcard_dns
|
||||||
context["organization_namespace"] = self.request.organization.namespace
|
context["organization_namespace"] = self.request.organization.namespace
|
||||||
|
|
||||||
|
if self.context_object:
|
||||||
|
context["plan_form"] = self.plan_form
|
||||||
|
context["has_available_plans"] = self.plan_form.fields[
|
||||||
|
"compute_plan_assignment"
|
||||||
|
].queryset.exists()
|
||||||
|
if self.context_object.control_plane.storage_plan_price_per_gib:
|
||||||
|
context["storage_plan"] = {
|
||||||
|
"price_per_gib": self.context_object.control_plane.storage_plan_price_per_gib,
|
||||||
|
}
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
|
|
@ -232,6 +252,9 @@ class ServiceOfferingDetailView(OrganizationViewMixin, HtmxViewMixin, DetailView
|
||||||
context["form_error"] = True
|
context["form_error"] = True
|
||||||
return self.render_to_response(context)
|
return self.render_to_response(context)
|
||||||
|
|
||||||
|
if not self.plan_form.is_valid():
|
||||||
|
return self.render_to_response(context)
|
||||||
|
|
||||||
if self.is_custom_form:
|
if self.is_custom_form:
|
||||||
form = self.get_custom_instance_form()
|
form = self.get_custom_instance_form()
|
||||||
else:
|
else:
|
||||||
|
|
@ -245,7 +268,11 @@ class ServiceOfferingDetailView(OrganizationViewMixin, HtmxViewMixin, DetailView
|
||||||
)
|
)
|
||||||
return self.render_to_response(context)
|
return self.render_to_response(context)
|
||||||
|
|
||||||
if form.is_valid():
|
if form.is_valid() and self.plan_form.is_valid():
|
||||||
|
compute_plan_assignment = self.plan_form.cleaned_data[
|
||||||
|
"compute_plan_assignment"
|
||||||
|
]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
service_instance = ServiceInstance.create_instance(
|
service_instance = ServiceInstance.create_instance(
|
||||||
organization=self.request.organization,
|
organization=self.request.organization,
|
||||||
|
|
@ -253,16 +280,22 @@ class ServiceOfferingDetailView(OrganizationViewMixin, HtmxViewMixin, DetailView
|
||||||
context=self.context_object,
|
context=self.context_object,
|
||||||
created_by=request.user,
|
created_by=request.user,
|
||||||
spec_data=form.get_nested_data().get("spec"),
|
spec_data=form.get_nested_data().get("spec"),
|
||||||
|
compute_plan_assignment=compute_plan_assignment,
|
||||||
)
|
)
|
||||||
return redirect(service_instance.urls.base)
|
return redirect(service_instance.urls.base)
|
||||||
except ValidationError as e:
|
except ValidationError as e:
|
||||||
form.add_error(None, e.message or str(e))
|
form.add_error(None, e.message or str(e))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error_message = self.organization.add_support_message(
|
error_message = self.organization.add_support_message(
|
||||||
_(f"Error creating instance: {str(e)}.")
|
_("Error creating instance: {error}.").format(error=str(e))
|
||||||
)
|
)
|
||||||
form.add_error(None, error_message)
|
form.add_error(None, error_message)
|
||||||
|
|
||||||
|
if self.is_custom_form:
|
||||||
|
context["custom_service_form"] = form
|
||||||
|
else:
|
||||||
|
context["service_form"] = form
|
||||||
|
|
||||||
return self.render_to_response(context)
|
return self.render_to_response(context)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -332,6 +365,18 @@ class ServiceInstanceDetailView(
|
||||||
context["has_delete_permission"] = self.request.user.has_perm(
|
context["has_delete_permission"] = self.request.user.has_perm(
|
||||||
ServiceInstance.get_perm("delete"), self.object
|
ServiceInstance.get_perm("delete"), self.object
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if self.object.compute_plan_assignment:
|
||||||
|
context["compute_plan_assignment"] = self.object.compute_plan_assignment
|
||||||
|
|
||||||
|
if (
|
||||||
|
self.object.context
|
||||||
|
and self.object.context.control_plane.storage_plan_price_per_gib
|
||||||
|
):
|
||||||
|
context["storage_plan"] = {
|
||||||
|
"price_per_gib": self.object.context.control_plane.storage_plan_price_per_gib,
|
||||||
|
}
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def get_nested_spec(self):
|
def get_nested_spec(self):
|
||||||
|
|
@ -475,6 +520,17 @@ class ServiceInstanceUpdateView(
|
||||||
kwargs.pop("data", None)
|
kwargs.pop("data", None)
|
||||||
return cls(**kwargs)
|
return cls(**kwargs)
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def plan_form(self):
|
||||||
|
data = self.request.POST if self.request.method == "POST" else None
|
||||||
|
initial = self.object.compute_plan_assignment if self.object else None
|
||||||
|
return ComputePlanSelectionForm(
|
||||||
|
data=data,
|
||||||
|
control_plane_crd=self.object.context if self.object else None,
|
||||||
|
prefix="plans",
|
||||||
|
initial={"compute_plan_assignment": initial} if initial else None,
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_custom_form(self):
|
def is_custom_form(self):
|
||||||
# Note: "custom form" = user-friendly, subset of fields
|
# Note: "custom form" = user-friendly, subset of fields
|
||||||
|
|
@ -489,7 +545,7 @@ class ServiceInstanceUpdateView(
|
||||||
else:
|
else:
|
||||||
form = self.get_form()
|
form = self.get_form()
|
||||||
|
|
||||||
if form.is_valid():
|
if form.is_valid() and self.plan_form.is_valid():
|
||||||
return self.form_valid(form)
|
return self.form_valid(form)
|
||||||
return self.form_invalid(form)
|
return self.form_invalid(form)
|
||||||
|
|
||||||
|
|
@ -506,14 +562,29 @@ class ServiceInstanceUpdateView(
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
context["hide_expert_mode"] = self.hide_expert_mode
|
context["hide_expert_mode"] = self.hide_expert_mode
|
||||||
|
|
||||||
|
# Check if a form was passed (e.g., from form_invalid)
|
||||||
|
form_from_kwargs = kwargs.get("form")
|
||||||
|
|
||||||
if self.request.method == "POST":
|
if self.request.method == "POST":
|
||||||
if self.is_custom_form:
|
if self.is_custom_form:
|
||||||
context["custom_form"] = self.get_custom_form()
|
# Use the form with errors if passed, otherwise create new
|
||||||
|
context["custom_form"] = form_from_kwargs or self.get_custom_form()
|
||||||
context["form"] = self.get_form(ignore_data=True)
|
context["form"] = self.get_form(ignore_data=True)
|
||||||
else:
|
else:
|
||||||
|
# Use the form with errors if passed, otherwise create new
|
||||||
|
context["form"] = form_from_kwargs or self.get_form()
|
||||||
context["custom_form"] = self.get_custom_form(ignore_data=True)
|
context["custom_form"] = self.get_custom_form(ignore_data=True)
|
||||||
else:
|
else:
|
||||||
context["custom_form"] = self.get_custom_form()
|
context["custom_form"] = self.get_custom_form()
|
||||||
|
|
||||||
|
if self.object and self.object.context:
|
||||||
|
context["plan_form"] = self.plan_form
|
||||||
|
if self.object.context.control_plane.storage_plan_price_per_gib:
|
||||||
|
context["storage_plan"] = {
|
||||||
|
"price_per_gib": self.object.context.control_plane.storage_plan_price_per_gib,
|
||||||
|
}
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def _deep_merge(self, base, update):
|
def _deep_merge(self, base, update):
|
||||||
|
|
@ -533,7 +604,17 @@ class ServiceInstanceUpdateView(
|
||||||
current_spec = dict(self.object.spec) if self.object.spec else {}
|
current_spec = dict(self.object.spec) if self.object.spec else {}
|
||||||
spec_data = self._deep_merge(current_spec, spec_data)
|
spec_data = self._deep_merge(current_spec, spec_data)
|
||||||
|
|
||||||
self.object.update_spec(spec_data=spec_data, updated_by=self.request.user)
|
compute_plan_assignment = None
|
||||||
|
if self.plan_form.is_valid():
|
||||||
|
compute_plan_assignment = self.plan_form.cleaned_data.get(
|
||||||
|
"compute_plan_assignment"
|
||||||
|
)
|
||||||
|
|
||||||
|
self.object.update_spec(
|
||||||
|
spec_data=spec_data,
|
||||||
|
updated_by=self.request.user,
|
||||||
|
compute_plan_assignment=compute_plan_assignment,
|
||||||
|
)
|
||||||
messages.success(
|
messages.success(
|
||||||
self.request,
|
self.request,
|
||||||
_("Service instance '{name}' updated successfully.").format(
|
_("Service instance '{name}' updated successfully.").format(
|
||||||
|
|
@ -546,7 +627,7 @@ class ServiceInstanceUpdateView(
|
||||||
return self.form_invalid(form)
|
return self.form_invalid(form)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error_message = self.organization.add_support_message(
|
error_message = self.organization.add_support_message(
|
||||||
_(f"Error updating instance: {str(e)}.")
|
_("Error updating instance: {error}.").format(error=str(e))
|
||||||
)
|
)
|
||||||
form.add_error(None, error_message)
|
form.add_error(None, error_message)
|
||||||
return self.form_invalid(form)
|
return self.form_invalid(form)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue