Implement plan logic in create/update
This commit is contained in:
parent
2bbd643cf9
commit
29661aa7cd
1 changed files with 96 additions and 3 deletions
|
|
@ -686,6 +686,60 @@ class ServiceInstance(ServalaModelMixin, models.Model):
|
||||||
spec_data = prune_empty_data(spec_data)
|
spec_data = prune_empty_data(spec_data)
|
||||||
return spec_data
|
return spec_data
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _apply_compute_plan_to_spec(spec_data, compute_plan_assignment):
|
||||||
|
"""
|
||||||
|
Apply compute plan resource allocations and SLA to spec.
|
||||||
|
"""
|
||||||
|
if not compute_plan_assignment:
|
||||||
|
return spec_data
|
||||||
|
|
||||||
|
compute_plan = compute_plan_assignment.compute_plan
|
||||||
|
|
||||||
|
if "parameters" not in spec_data:
|
||||||
|
spec_data["parameters"] = {}
|
||||||
|
if "size" not in spec_data["parameters"]:
|
||||||
|
spec_data["parameters"]["size"] = {}
|
||||||
|
if "requests" not in spec_data["parameters"]["size"]:
|
||||||
|
spec_data["parameters"]["size"]["requests"] = {}
|
||||||
|
if "service" not in spec_data["parameters"]:
|
||||||
|
spec_data["parameters"]["service"] = {}
|
||||||
|
|
||||||
|
spec_data["parameters"]["size"]["memory"] = compute_plan.memory_limits
|
||||||
|
spec_data["parameters"]["size"]["cpu"] = compute_plan.cpu_limits
|
||||||
|
spec_data["parameters"]["size"]["requests"][
|
||||||
|
"memory"
|
||||||
|
] = compute_plan.memory_requests
|
||||||
|
spec_data["parameters"]["size"]["requests"]["cpu"] = compute_plan.cpu_requests
|
||||||
|
spec_data["parameters"]["service"]["serviceLevel"] = compute_plan_assignment.sla
|
||||||
|
return spec_data
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _build_billing_annotations(compute_plan_assignment, control_plane):
|
||||||
|
"""
|
||||||
|
Build Kubernetes annotations for billing integration.
|
||||||
|
"""
|
||||||
|
annotations = {}
|
||||||
|
|
||||||
|
if compute_plan_assignment:
|
||||||
|
annotations["servala.com/erp_product_id_resource"] = str(
|
||||||
|
compute_plan_assignment.odoo_product_id
|
||||||
|
)
|
||||||
|
annotations["servala.com/erp_unit_id_resource"] = str(
|
||||||
|
compute_plan_assignment.odoo_unit_id
|
||||||
|
)
|
||||||
|
|
||||||
|
if control_plane.storage_plan_odoo_product_id:
|
||||||
|
annotations["servala.com/erp_product_id_storage"] = str(
|
||||||
|
control_plane.storage_plan_odoo_product_id
|
||||||
|
)
|
||||||
|
if control_plane.storage_plan_odoo_unit_id:
|
||||||
|
annotations["servala.com/erp_unit_id_storage"] = str(
|
||||||
|
control_plane.storage_plan_odoo_unit_id
|
||||||
|
)
|
||||||
|
|
||||||
|
return annotations
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _format_kubernetes_error(cls, error_message):
|
def _format_kubernetes_error(cls, error_message):
|
||||||
if not error_message:
|
if not error_message:
|
||||||
|
|
@ -740,7 +794,15 @@ class ServiceInstance(ServalaModelMixin, models.Model):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
def create_instance(cls, name, organization, context, created_by, spec_data):
|
def create_instance(
|
||||||
|
cls,
|
||||||
|
name,
|
||||||
|
organization,
|
||||||
|
context,
|
||||||
|
created_by,
|
||||||
|
spec_data,
|
||||||
|
compute_plan_assignment=None,
|
||||||
|
):
|
||||||
# Ensure the namespace exists
|
# Ensure the namespace exists
|
||||||
context.control_plane.get_or_create_namespace(organization)
|
context.control_plane.get_or_create_namespace(organization)
|
||||||
try:
|
try:
|
||||||
|
|
@ -749,6 +811,7 @@ class ServiceInstance(ServalaModelMixin, models.Model):
|
||||||
organization=organization,
|
organization=organization,
|
||||||
created_by=created_by,
|
created_by=created_by,
|
||||||
context=context,
|
context=context,
|
||||||
|
compute_plan_assignment=compute_plan_assignment,
|
||||||
)
|
)
|
||||||
except IntegrityError:
|
except IntegrityError:
|
||||||
message = _(
|
message = _(
|
||||||
|
|
@ -759,6 +822,11 @@ class ServiceInstance(ServalaModelMixin, models.Model):
|
||||||
try:
|
try:
|
||||||
spec_data = cls._prepare_spec_data(spec_data)
|
spec_data = cls._prepare_spec_data(spec_data)
|
||||||
|
|
||||||
|
if compute_plan_assignment:
|
||||||
|
spec_data = cls._apply_compute_plan_to_spec(
|
||||||
|
spec_data, compute_plan_assignment
|
||||||
|
)
|
||||||
|
|
||||||
if "writeConnectionSecretToRef" not in spec_data:
|
if "writeConnectionSecretToRef" not in spec_data:
|
||||||
spec_data["writeConnectionSecretToRef"] = {}
|
spec_data["writeConnectionSecretToRef"] = {}
|
||||||
|
|
||||||
|
|
@ -776,6 +844,13 @@ class ServiceInstance(ServalaModelMixin, models.Model):
|
||||||
},
|
},
|
||||||
"spec": spec_data,
|
"spec": spec_data,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
annotations = cls._build_billing_annotations(
|
||||||
|
compute_plan_assignment, context.control_plane
|
||||||
|
)
|
||||||
|
if annotations:
|
||||||
|
create_data["metadata"]["annotations"] = annotations
|
||||||
|
|
||||||
if label := context.control_plane.required_label:
|
if label := context.control_plane.required_label:
|
||||||
create_data["metadata"]["labels"] = {settings.DEFAULT_LABEL_KEY: label}
|
create_data["metadata"]["labels"] = {settings.DEFAULT_LABEL_KEY: label}
|
||||||
api_instance = context.control_plane.custom_objects_api
|
api_instance = context.control_plane.custom_objects_api
|
||||||
|
|
@ -813,12 +888,23 @@ class ServiceInstance(ServalaModelMixin, models.Model):
|
||||||
raise ValidationError(organization.add_support_message(message))
|
raise ValidationError(organization.add_support_message(message))
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
def update_spec(self, spec_data, updated_by):
|
def update_spec(self, spec_data, updated_by, compute_plan_assignment=None):
|
||||||
try:
|
try:
|
||||||
spec_data = self._prepare_spec_data(spec_data)
|
spec_data = self._prepare_spec_data(spec_data)
|
||||||
|
|
||||||
|
plan_to_use = compute_plan_assignment or self.compute_plan_assignment
|
||||||
|
if plan_to_use:
|
||||||
|
spec_data = self._apply_compute_plan_to_spec(spec_data, plan_to_use)
|
||||||
|
|
||||||
api_instance = self.context.control_plane.custom_objects_api
|
api_instance = self.context.control_plane.custom_objects_api
|
||||||
patch_body = {"spec": spec_data}
|
patch_body = {"spec": spec_data}
|
||||||
|
|
||||||
|
annotations = self._build_billing_annotations(
|
||||||
|
plan_to_use, self.context.control_plane
|
||||||
|
)
|
||||||
|
if annotations:
|
||||||
|
patch_body["metadata"] = {"annotations": annotations}
|
||||||
|
|
||||||
api_instance.patch_namespaced_custom_object(
|
api_instance.patch_namespaced_custom_object(
|
||||||
group=self.context.group,
|
group=self.context.group,
|
||||||
version=self.context.version,
|
version=self.context.version,
|
||||||
|
|
@ -828,7 +914,14 @@ class ServiceInstance(ServalaModelMixin, models.Model):
|
||||||
body=patch_body,
|
body=patch_body,
|
||||||
)
|
)
|
||||||
self._clear_kubernetes_caches()
|
self._clear_kubernetes_caches()
|
||||||
self.save() # Updates updated_at timestamp
|
|
||||||
|
if (
|
||||||
|
compute_plan_assignment
|
||||||
|
and compute_plan_assignment != self.compute_plan_assignment
|
||||||
|
):
|
||||||
|
self.compute_plan_assignment = compute_plan_assignment
|
||||||
|
# Saving to update updated_at timestamp even if nothing was visibly changed
|
||||||
|
self.save()
|
||||||
except ApiException as e:
|
except ApiException as e:
|
||||||
if e.status == 404:
|
if e.status == 404:
|
||||||
message = _(
|
message = _(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue