add missing for ldap kerberos, add last status for schedules

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
This commit is contained in:
Marc 'risson' Schmitt
2025-06-26 16:45:26 +02:00
parent 49a9911271
commit 0ebbaeea6f
8 changed files with 83 additions and 10 deletions

View File

@ -89,7 +89,7 @@ class KerberosSourceViewSet(UsedByMixin, ModelViewSet):
url_path="sync/status",
filter_backends=[ObjectFilter],
)
def sync_status(self, request: Request, pk: int) -> Response:
def sync_status(self, request: Request, slug: str) -> Response:
"""Get provider's sync status"""
source: KerberosSource = self.get_object()

View File

@ -164,7 +164,7 @@ class LDAPSourceViewSet(UsedByMixin, ModelViewSet):
url_path="sync/status",
filter_backends=[ObjectFilter],
)
def sync_status(self, request: Request, pk: int) -> Response:
def sync_status(self, request: Request, slug: str) -> Response:
"""Get provider's sync status"""
source: LDAPSource = self.get_object()

View File

@ -6,7 +6,7 @@ from dramatiq.errors import ActorNotFound
from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import OpenApiResponse, extend_schema
from rest_framework.decorators import action
from rest_framework.fields import ReadOnlyField
from rest_framework.fields import ChoiceField, ReadOnlyField
from rest_framework.mixins import (
ListModelMixin,
RetrieveModelMixin,
@ -20,6 +20,7 @@ from structlog.stdlib import get_logger
from authentik.core.api.utils import ModelSerializer
from authentik.rbac.decorators import permission_required
from authentik.tasks.models import Task, TaskStatus
from authentik.tasks.schedules.models import Schedule
LOGGER = get_logger()
@ -30,6 +31,7 @@ class ScheduleSerializer(ModelSerializer):
rel_obj_model = ReadOnlyField(source="rel_obj_content_type.model")
description = SerializerMethodField()
last_task_status = SerializerMethodField()
class Meta:
model = Schedule
@ -44,6 +46,7 @@ class ScheduleSerializer(ModelSerializer):
"paused",
"next_run",
"description",
"last_task_status",
)
def get_description(self, instance: Schedule) -> str | None:
@ -61,6 +64,12 @@ class ScheduleSerializer(ModelSerializer):
return None
return actor.options["description"]
def get_last_task_status(self, instance: Schedule) -> TaskStatus | None:
last_task: Task = instance.tasks.order_by("-mtime").first()
if last_task:
return last_task.aggregated_status
return None
class ScheduleFilter(FilterSet):
rel_obj_id__isnull = BooleanFilter("rel_obj_id", "isnull")
@ -83,7 +92,9 @@ class ScheduleViewSet(
ListModelMixin,
GenericViewSet,
):
queryset = Schedule.objects.select_related("rel_obj_content_type").all()
queryset = (
Schedule.objects.select_related("rel_obj_content_type").prefetch_related("tasks").all()
)
serializer_class = ScheduleSerializer
search_fields = (
"id",

View File

@ -48395,6 +48395,16 @@ components:
- name
- server_uri
- slug
LastTaskStatusEnum:
enum:
- queued
- consumed
- rejected
- done
- info
- warning
- error
type: string
License:
type: object
description: License Serializer
@ -59565,11 +59575,17 @@ components:
type: string
nullable: true
readOnly: true
last_task_status:
allOf:
- $ref: '#/components/schemas/LastTaskStatusEnum'
nullable: true
readOnly: true
required:
- actor_name
- crontab
- description
- id
- last_task_status
- next_run
- rel_obj_app_label
- rel_obj_model

View File

@ -11,6 +11,7 @@ import "@goauthentik/elements/ak-mdx";
import "@goauthentik/elements/buttons/ActionButton";
import "@goauthentik/elements/buttons/SpinnerButton";
import "@goauthentik/elements/forms/ModalForm";
import "@goauthentik/elements/sync/SyncStatusCard";
import MDSourceKerberosBrowser from "~docs/users-sources/sources/protocols/kerberos/browser.md";
import { msg } from "@lit/localize";
@ -93,7 +94,9 @@ export class KerberosSourceViewPage extends AKElement {
>
</div>
<div class="pf-l-grid pf-m-gutter">
<div class="pf-c-card pf-l-grid__item pf-m-4-col">
<div
class="pf-c-card pf-l-grid__item pf-m-12-col pf-m-6-col-on-xl pf-m-6-col-on-2xl"
>
<div class="pf-c-card__body">
<dl class="pf-c-description-list pf-m-2-col-on-lg">
<div class="pf-c-description-list__group">
@ -137,7 +140,20 @@ export class KerberosSourceViewPage extends AKElement {
</ak-forms-modal>
</div>
</div>
<div class="pf-c-card pf-l-grid__item pf-m-8-col">
<div
class="pf-c-card pf-l-grid__item pf-m-12-col pf-m-6-col-on-xl pf-m-6-col-on-2xl"
>
<ak-sync-status-card
.fetch=${() => {
return new SourcesApi(
DEFAULT_CONFIG,
).sourcesKerberosSyncStatusRetrieve({
slug: this.source?.slug,
});
}}
></ak-sync-status-card>
</div>
<div class="pf-c-card pf-l-grid__item pf-m-12-col">
<div class="pf-c-card__title">
<p>${msg("Connectivity")}</p>
</div>

View File

@ -10,6 +10,7 @@ import "@goauthentik/elements/Tabs";
import "@goauthentik/elements/buttons/ActionButton";
import "@goauthentik/elements/buttons/SpinnerButton";
import "@goauthentik/elements/forms/ModalForm";
import "@goauthentik/elements/sync/SyncStatusCard";
import "@goauthentik/elements/tasks/ScheduleList";
import { msg } from "@lit/localize";
@ -72,7 +73,9 @@ export class LDAPSourceViewPage extends AKElement {
class="pf-c-page__main-section pf-m-no-padding-mobile"
>
<div class="pf-l-grid pf-m-gutter">
<div class="pf-c-card pf-l-grid__item pf-m-4-col">
<div
class="pf-c-card pf-l-grid__item pf-m-12-col pf-m-6-col-on-xl pf-m-6-col-on-2xl"
>
<div class="pf-c-card__body">
<dl class="pf-c-description-list pf-m-2-col-on-lg">
<div class="pf-c-description-list__group">
@ -127,7 +130,20 @@ export class LDAPSourceViewPage extends AKElement {
</ak-forms-modal>
</div>
</div>
<div class="pf-c-card pf-l-grid__item pf-m-8-col">
<div
class="pf-c-card pf-l-grid__item pf-m-12-col pf-m-6-col-on-xl pf-m-6-col-on-2xl"
>
<ak-sync-status-card
.fetch=${() => {
return new SourcesApi(DEFAULT_CONFIG).sourcesLdapSyncStatusRetrieve(
{
slug: this.source?.slug,
},
);
}}
></ak-sync-status-card>
</div>
<div class="pf-c-card pf-l-grid__item pf-m-12-col">
<div class="pf-c-card__title">
<p>${msg("Connectivity")}</p>
</div>

View File

@ -9,6 +9,7 @@ import { PaginatedResponse, Table } from "@goauthentik/elements/table/Table";
import { TableColumn } from "@goauthentik/elements/table/Table";
import "@goauthentik/elements/tasks/ScheduleForm";
import "@goauthentik/elements/tasks/TaskList";
import "@goauthentik/elements/tasks/TaskStatus";
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
import { msg } from "@lit/localize";
@ -72,6 +73,7 @@ export class ScheduleList extends Table<Schedule> {
new TableColumn(msg("Schedule"), "actor_name"),
new TableColumn(msg("Crontab"), "crontab"),
new TableColumn(msg("Next run"), "next_run"),
new TableColumn(msg("Last status")),
new TableColumn(msg("Actions")),
];
}
@ -118,6 +120,7 @@ export class ScheduleList extends Table<Schedule> {
<small>${item.nextRun.toLocaleString()}</small>
`}
`,
html`<ak-task-status .status=${item.lastTaskStatus}></ak-task-status>`,
html`<ak-action-button
class="pf-m-plain"
.apiRequest=${() => {

View File

@ -9,12 +9,16 @@ import { customElement, property } from "lit/decorators.js";
import PFButton from "@patternfly/patternfly/components/Button/button.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css";
import { TaskAggregatedStatusEnum, TasksTasksListAggregatedStatusEnum } from "@goauthentik/api";
import {
LastTaskStatusEnum,
TaskAggregatedStatusEnum,
TasksTasksListAggregatedStatusEnum,
} from "@goauthentik/api";
@customElement("ak-task-status")
export class TaskStatus extends AKElement {
@property()
status?: TaskAggregatedStatusEnum | TasksTasksListAggregatedStatusEnum;
status?: TaskAggregatedStatusEnum | TasksTasksListAggregatedStatusEnum | LastTaskStatusEnum;
static get styles(): CSSResult[] {
return [PFBase, PFButton];
@ -24,22 +28,29 @@ export class TaskStatus extends AKElement {
switch (this.status) {
case TasksTasksListAggregatedStatusEnum.Queued:
case TaskAggregatedStatusEnum.Queued:
case LastTaskStatusEnum.Queued:
return html`<ak-label color=${PFColor.Grey}>${msg("Waiting to run")}</ak-label>`;
case TasksTasksListAggregatedStatusEnum.Consumed:
case TaskAggregatedStatusEnum.Consumed:
case LastTaskStatusEnum.Consumed:
return html`<ak-label color=${PFColor.Blue}>${msg("Running")}</ak-label>`;
case TasksTasksListAggregatedStatusEnum.Done:
case TaskAggregatedStatusEnum.Done:
case LastTaskStatusEnum.Done:
case TasksTasksListAggregatedStatusEnum.Info:
case TaskAggregatedStatusEnum.Info:
case LastTaskStatusEnum.Info:
return html`<ak-label color=${PFColor.Green}>${msg("Successful")}</ak-label>`;
case TasksTasksListAggregatedStatusEnum.Warning:
case TaskAggregatedStatusEnum.Warning:
case LastTaskStatusEnum.Warning:
return html`<ak-label color=${PFColor.Orange}>${msg("Warning")}</ak-label>`;
case TasksTasksListAggregatedStatusEnum.Rejected:
case TaskAggregatedStatusEnum.Rejected:
case LastTaskStatusEnum.Rejected:
case TasksTasksListAggregatedStatusEnum.Error:
case TaskAggregatedStatusEnum.Error:
case LastTaskStatusEnum.Error:
return html`<ak-label color=${PFColor.Red}>${msg("Error")}</ak-label>`;
default:
return html`<ak-label color=${PFColor.Grey}>${msg("Unknown")}</ak-label>`;