diff --git a/.forgejo/workflows/renovate.yaml b/.forgejo/workflows/renovate.yaml index a2577d9..23ef6d5 100644 --- a/.forgejo/workflows/renovate.yaml +++ b/.forgejo/workflows/renovate.yaml @@ -19,7 +19,7 @@ jobs: node-version: "24" - name: Renovate - uses: https://github.com/renovatebot/github-action@v44.0.5 + uses: https://github.com/renovatebot/github-action@v44.2.0 with: token: ${{ secrets.RENOVATE_TOKEN }} env: diff --git a/src/servala/core/models/service.py b/src/servala/core/models/service.py index 31527c5..c2fedad 100644 --- a/src/servala/core/models/service.py +++ b/src/servala/core/models/service.py @@ -1202,50 +1202,5 @@ class ServiceInstance(ServalaModelMixin, models.Model): except (AttributeError, KeyError, IndexError): return None - @cached_property - def kubernetes_events(self) -> dict: - """ - Returns a list of event dictionaries sorted by last timestamp (newest first). - """ - if not self.kubernetes_object: - return [] - - try: - v1 = kubernetes.client.CoreV1Api( - self.context.control_plane.get_kubernetes_client() - ) - events = v1.list_namespaced_event( - namespace=self.organization.namespace, - field_selector=f"involvedObject.name={self.name},involvedObject.kind={self.context.kind}", - ) - event_list = [] - for event in events.items: - event_dict = { - "type": event.type, # Normal or Warning - "reason": event.reason, - "message": event.message, - "count": event.count or 1, - "first_timestamp": ( - event.first_timestamp.isoformat() - if event.first_timestamp - else None - ), - "last_timestamp": ( - event.last_timestamp.isoformat() - if event.last_timestamp - else None - ), - "source": event.source.component if event.source else None, - } - event_list.append(event_dict) - - event_list.sort(key=lambda x: x.get("last_timestamp") or "", reverse=True) - - return event_list - except ApiException: - return [] - except Exception: - return [] - auditlog.register(ServiceInstance, exclude_fields=["updated_at"], serialize_data=True) diff --git a/src/servala/frontend/templates/frontend/base.html b/src/servala/frontend/templates/frontend/base.html index 8454e0d..620cb6d 100644 --- a/src/servala/frontend/templates/frontend/base.html +++ b/src/servala/frontend/templates/frontend/base.html @@ -35,8 +35,6 @@ {% block page_title_extra %} {% endblock page_title_extra %} - {% block page_subtitle %} - {% endblock page_subtitle %}
{% for message in messages %} diff --git a/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html b/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html index da08603..c0924ed 100644 --- a/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html +++ b/src/servala/frontend/templates/frontend/organizations/service_instance_detail.html @@ -29,197 +29,136 @@ {% endif %}
{% endblock page_title_extra %} -{% block page_subtitle %} -
- {% if instance.context.service_definition.service.logo %} - {{ instance.context.service_definition.service.name }} - {% endif %} - | - {% if instance.context.service_offering.provider.logo %} - {{ instance.context.service_offering.provider.name }} - {% endif %} -
-{% endblock page_subtitle %} {% block content %}
- -
+
- {% if compute_plan_assignment or storage_plan %} -
-
-

{% translate "Product" %}

-

+

+
+

{% translate "Details" %}

+
+
+
+
{% translate "Instance ID" %}
+
+ {{ instance.name }} +
+
{% translate "Service" %}
+
{{ instance.context.service_definition.service.name }} - {% translate "at" %} +
+
{% translate "Service Provider" %}
+
{{ instance.context.service_offering.provider.name }} - ({{ instance.context.control_plane.name }}) -

-
-
+ +
{% translate "Control Plane" %}
+
+ {{ instance.context.control_plane.name }} +
{% if compute_plan_assignment %} -
-
{% translate "Compute" %}
-
- {% translate "Plan:" %} {{ compute_plan_assignment.compute_plan.name }} -
-
+
{% translate "Compute Plan" %}
+
+ {{ compute_plan_assignment.compute_plan.name }} + + {{ compute_plan_assignment.get_sla_display }} + +
{{ compute_plan_assignment.compute_plan.cpu_limits }} vCPU {{ compute_plan_assignment.compute_plan.memory_limits }} RAM - SLA: {{ compute_plan_assignment.get_sla_display }} + CHF {{ compute_plan_assignment.price }}/{{ compute_plan_assignment.get_unit_display }}
-
- CHF {{ compute_plan_assignment.price }} / {{ compute_plan_assignment.get_unit_display }} - {% if pricing.compute_monthly %} - (~CHF {{ pricing.compute_monthly }} / {% translate "month" %}) - {% endif %} -
-
+ {% endif %} {% if storage_plan %} -
-
{% translate "Storage" %}
-
- CHF {{ storage_plan.price_per_gib }} / GiB / {% translate "hour" %} - {% if pricing.disk_size_gib %} - - {{ pricing.disk_size_gib }} GiB {% translate "configured" %} - {% endif %} -
- {% if pricing.storage_monthly %} -
- CHF {{ pricing.storage_hourly }} / {% translate "hour" %} - (~CHF {{ pricing.storage_monthly }} / {% translate "month" %}) -
- {% endif %} -
+
{% translate "Storage Plan" %}
+
+ CHF {{ storage_plan.price_per_gib }} per GiB +
{% translate "Billed separately based on disk usage" %}
+
{% endif %} - {% if pricing.total_monthly %} -
-
- {% translate "Estimated Total" %} -
-
~CHF {{ pricing.total_monthly }} / {% translate "month" %}
-
CHF {{ pricing.total_hourly }} / {% translate "hour" %}
-
-
- {% endif %} -
+
{% translate "Created By" %}
+
+ {{ instance.created_by|default:"-" }} +
+
{% translate "Created At" %}
+
+ {{ instance.created_at|date:"SHORT_DATETIME_FORMAT" }} +
+
{% translate "Updated At" %}
+
+ {{ instance.updated_at|date:"SHORT_DATETIME_FORMAT" }} +
+
- {% endif %} +
- {% if instance.connection_credentials %} -
-
-

{% translate "Connection Credentials" %}

- + {% if instance.status_conditions %} +
+
+

{% translate "Status" %}

-
- - - - - - - - - - - - - - - {% for key, value in instance.connection_credentials.items %} - {% if "_HOST" not in key and "_URL" not in key %} +
+
+
{% translate "Name" %}{% translate "Value" %}
+ + + + + + + + + + + {% for condition in instance.status_conditions %} - - + - + + + - {% endif %} - {% endfor %} - -
{% translate "Type" %}{% translate "Status" %}{% translate "Last Transition Time" %}{% translate "Reason" %}{% translate "Message" %}
{{ key }} - {% if key == "error" %} - {{ value }} + {{ condition.type }} + {% if condition.status == "True" %} + True + {% elif condition.status == "False" %} + False {% else %} - •••••••••••• - {% endif %} - - {% if key != "error" %} - + {{ condition.status }} {% endif %} {{ condition.lastTransitionTime|date:"SHORT_DATETIME_FORMAT" }}{{ condition.reason|default:"-" }}{{ condition.message|truncatewords:20|default:"-" }}
-
-
- - {% translate "Click the eye icon to reveal individual credentials, or use 'Show All' to reveal all at once." %} -
-
-
- {% endif %} -
-
- - {% if instance.spec and spec_fieldsets or instance.context.control_plane.user_info %} -
- - {% if instance.context.control_plane.user_info %} -
-
-
-

- -

-

{% translate "Technical details for connecting to this zone" %}

-
-
-
- {% include "includes/control_plane_user_info.html" with control_plane=instance.context.control_plane %} + {% endfor %} + +
{% endif %} - - {% if instance.spec and spec_fieldsets %} -
-
-
-

{% translate "Service Configuration" %}

-
-
- {% if spec_fieldsets|length > 1 %} - + {% if control_plane.user_info %} +
+
+

{% translate "Service Provider Zone Information" %}

+
+
+ {% include "includes/control_plane_user_info.html" with control_plane=instance.context.control_plane %} +
+
+ {% endif %} +
+ {% if instance.spec and spec_fieldsets %} +
+
+
+

{% translate "Specification" %}

+
+
+
+
+ +
{% for fieldset in spec_fieldsets %}
-
+ +
{% for field in fieldset.fields %} -
- {{ field.label }} - {% if field.help_text %} - +
{{ field.label }}
+
+ {% if field.value|default:""|stringformat:"s"|slice:":1" == "{" or field.value|default:""|stringformat:"s"|slice:":1" == "[" %} +
{{ field.value|pprint }}
+ {% else %} + {{ field.value|default:"-" }} {% endif %} - -
- {{ field.value|render_tree }}
{% endfor %}
+ {% for sub_key, sub_fieldset in fieldset.fieldsets.items %} -
{{ sub_fieldset.title }}
-
+
{{ sub_fieldset.title }}
+
{% for field in sub_fieldset.fields %} -
{{ field.label }}
-
- {{ field.value|render_tree }} +
{{ field.label }}
+
+ {% if field.value|default:""|stringformat:"s"|slice:":1" == "{" or field.value|default:""|stringformat:"s"|slice:":1" == "[" %} +
{{ field.value|pprint }}
+ {% else %} + {{ field.value|default:"-" }} + {% endif %}
{% endfor %}
{% endfor %}
+ {% empty %} +

{% translate "No specification details to display." %}

{% endfor %}
- {% else %} - - {% for fieldset in spec_fieldsets %} -
- {% for field in fieldset.fields %} -
- {{ field.label }} - {% if field.help_text %} - - {% endif %} -
-
- {{ field.value|render_tree }} -
- {% endfor %} -
- {% for sub_key, sub_fieldset in fieldset.fieldsets.items %} -
{{ sub_fieldset.title }}
-
- {% for field in sub_fieldset.fields %} -
{{ field.label }}
-
- {{ field.value|render_tree }} -
- {% endfor %} -
- {% endfor %} - {% endfor %} - {% endif %} -
-
-
- {% endif %} -
- {% endif %} - - {% if instance.status_conditions or instance.created_at %} -
-
-
-
-

- -

-
-
-
- -
- {% if instance.status_conditions %} -
{% translate "Status Conditions" %}
-
- - - - - - - - - - - - {% for condition in instance.status_conditions %} - - - - - - - - {% endfor %} - -
{% translate "Type" %}{% translate "Status" %}{% translate "Last Transition" %}{% translate "Reason" %}{% translate "Message" %}
{{ condition.type }} - {% if condition.status == "True" %} - True - {% elif condition.status == "False" %} - False - {% else %} - {{ condition.status }} - {% endif %} - {{ condition.lastTransitionTime|localtime_tag }}{{ condition.reason|default:"-" }}{{ condition.message|truncatewords:20|default:"-" }}
-
- {% endif %} -
- -
-
{% translate "Metadata" %}
-
-
{% translate "Created By" %}
-
{{ instance.created_by|default:"-" }}
-
{% translate "Created At" %}
-
{{ instance.created_at|localtime_tag }}
-
{% translate "Updated At" %}
-
{{ instance.updated_at|localtime_tag }}
-
-
-
-
- {% endif %} + {% endif %} + {% if instance.connection_credentials %} +
+
+
+

{% translate "Connection Credentials" %}

+
+
+
+ + + + + + + + + {% for key, value in instance.connection_credentials.items %} + + + + + {% endfor %} + +
{% translate "Name" %}{% translate "Value" %}
{{ key }} + {% if key == "error" %} + {{ value }} + {% else %} + {{ value }} + {% endif %} +
+
+
+
+
+ {% endif %} +