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:
@ -89,7 +89,7 @@ class KerberosSourceViewSet(UsedByMixin, ModelViewSet):
|
|||||||
url_path="sync/status",
|
url_path="sync/status",
|
||||||
filter_backends=[ObjectFilter],
|
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"""
|
"""Get provider's sync status"""
|
||||||
source: KerberosSource = self.get_object()
|
source: KerberosSource = self.get_object()
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ class LDAPSourceViewSet(UsedByMixin, ModelViewSet):
|
|||||||
url_path="sync/status",
|
url_path="sync/status",
|
||||||
filter_backends=[ObjectFilter],
|
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"""
|
"""Get provider's sync status"""
|
||||||
source: LDAPSource = self.get_object()
|
source: LDAPSource = self.get_object()
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ from dramatiq.errors import ActorNotFound
|
|||||||
from drf_spectacular.types import OpenApiTypes
|
from drf_spectacular.types import OpenApiTypes
|
||||||
from drf_spectacular.utils import OpenApiResponse, extend_schema
|
from drf_spectacular.utils import OpenApiResponse, extend_schema
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
from rest_framework.fields import ReadOnlyField
|
from rest_framework.fields import ChoiceField, ReadOnlyField
|
||||||
from rest_framework.mixins import (
|
from rest_framework.mixins import (
|
||||||
ListModelMixin,
|
ListModelMixin,
|
||||||
RetrieveModelMixin,
|
RetrieveModelMixin,
|
||||||
@ -20,6 +20,7 @@ from structlog.stdlib import get_logger
|
|||||||
|
|
||||||
from authentik.core.api.utils import ModelSerializer
|
from authentik.core.api.utils import ModelSerializer
|
||||||
from authentik.rbac.decorators import permission_required
|
from authentik.rbac.decorators import permission_required
|
||||||
|
from authentik.tasks.models import Task, TaskStatus
|
||||||
from authentik.tasks.schedules.models import Schedule
|
from authentik.tasks.schedules.models import Schedule
|
||||||
|
|
||||||
LOGGER = get_logger()
|
LOGGER = get_logger()
|
||||||
@ -30,6 +31,7 @@ class ScheduleSerializer(ModelSerializer):
|
|||||||
rel_obj_model = ReadOnlyField(source="rel_obj_content_type.model")
|
rel_obj_model = ReadOnlyField(source="rel_obj_content_type.model")
|
||||||
|
|
||||||
description = SerializerMethodField()
|
description = SerializerMethodField()
|
||||||
|
last_task_status = SerializerMethodField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Schedule
|
model = Schedule
|
||||||
@ -44,6 +46,7 @@ class ScheduleSerializer(ModelSerializer):
|
|||||||
"paused",
|
"paused",
|
||||||
"next_run",
|
"next_run",
|
||||||
"description",
|
"description",
|
||||||
|
"last_task_status",
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_description(self, instance: Schedule) -> str | None:
|
def get_description(self, instance: Schedule) -> str | None:
|
||||||
@ -61,6 +64,12 @@ class ScheduleSerializer(ModelSerializer):
|
|||||||
return None
|
return None
|
||||||
return actor.options["description"]
|
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):
|
class ScheduleFilter(FilterSet):
|
||||||
rel_obj_id__isnull = BooleanFilter("rel_obj_id", "isnull")
|
rel_obj_id__isnull = BooleanFilter("rel_obj_id", "isnull")
|
||||||
@ -83,7 +92,9 @@ class ScheduleViewSet(
|
|||||||
ListModelMixin,
|
ListModelMixin,
|
||||||
GenericViewSet,
|
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
|
serializer_class = ScheduleSerializer
|
||||||
search_fields = (
|
search_fields = (
|
||||||
"id",
|
"id",
|
||||||
|
16
schema.yml
16
schema.yml
@ -48395,6 +48395,16 @@ components:
|
|||||||
- name
|
- name
|
||||||
- server_uri
|
- server_uri
|
||||||
- slug
|
- slug
|
||||||
|
LastTaskStatusEnum:
|
||||||
|
enum:
|
||||||
|
- queued
|
||||||
|
- consumed
|
||||||
|
- rejected
|
||||||
|
- done
|
||||||
|
- info
|
||||||
|
- warning
|
||||||
|
- error
|
||||||
|
type: string
|
||||||
License:
|
License:
|
||||||
type: object
|
type: object
|
||||||
description: License Serializer
|
description: License Serializer
|
||||||
@ -59565,11 +59575,17 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
nullable: true
|
nullable: true
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
last_task_status:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/LastTaskStatusEnum'
|
||||||
|
nullable: true
|
||||||
|
readOnly: true
|
||||||
required:
|
required:
|
||||||
- actor_name
|
- actor_name
|
||||||
- crontab
|
- crontab
|
||||||
- description
|
- description
|
||||||
- id
|
- id
|
||||||
|
- last_task_status
|
||||||
- next_run
|
- next_run
|
||||||
- rel_obj_app_label
|
- rel_obj_app_label
|
||||||
- rel_obj_model
|
- rel_obj_model
|
||||||
|
@ -11,6 +11,7 @@ import "@goauthentik/elements/ak-mdx";
|
|||||||
import "@goauthentik/elements/buttons/ActionButton";
|
import "@goauthentik/elements/buttons/ActionButton";
|
||||||
import "@goauthentik/elements/buttons/SpinnerButton";
|
import "@goauthentik/elements/buttons/SpinnerButton";
|
||||||
import "@goauthentik/elements/forms/ModalForm";
|
import "@goauthentik/elements/forms/ModalForm";
|
||||||
|
import "@goauthentik/elements/sync/SyncStatusCard";
|
||||||
import MDSourceKerberosBrowser from "~docs/users-sources/sources/protocols/kerberos/browser.md";
|
import MDSourceKerberosBrowser from "~docs/users-sources/sources/protocols/kerberos/browser.md";
|
||||||
|
|
||||||
import { msg } from "@lit/localize";
|
import { msg } from "@lit/localize";
|
||||||
@ -93,7 +94,9 @@ export class KerberosSourceViewPage extends AKElement {
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="pf-l-grid pf-m-gutter">
|
<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">
|
<div class="pf-c-card__body">
|
||||||
<dl class="pf-c-description-list pf-m-2-col-on-lg">
|
<dl class="pf-c-description-list pf-m-2-col-on-lg">
|
||||||
<div class="pf-c-description-list__group">
|
<div class="pf-c-description-list__group">
|
||||||
@ -137,7 +140,20 @@ export class KerberosSourceViewPage extends AKElement {
|
|||||||
</ak-forms-modal>
|
</ak-forms-modal>
|
||||||
</div>
|
</div>
|
||||||
</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">
|
<div class="pf-c-card__title">
|
||||||
<p>${msg("Connectivity")}</p>
|
<p>${msg("Connectivity")}</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -10,6 +10,7 @@ import "@goauthentik/elements/Tabs";
|
|||||||
import "@goauthentik/elements/buttons/ActionButton";
|
import "@goauthentik/elements/buttons/ActionButton";
|
||||||
import "@goauthentik/elements/buttons/SpinnerButton";
|
import "@goauthentik/elements/buttons/SpinnerButton";
|
||||||
import "@goauthentik/elements/forms/ModalForm";
|
import "@goauthentik/elements/forms/ModalForm";
|
||||||
|
import "@goauthentik/elements/sync/SyncStatusCard";
|
||||||
import "@goauthentik/elements/tasks/ScheduleList";
|
import "@goauthentik/elements/tasks/ScheduleList";
|
||||||
|
|
||||||
import { msg } from "@lit/localize";
|
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"
|
class="pf-c-page__main-section pf-m-no-padding-mobile"
|
||||||
>
|
>
|
||||||
<div class="pf-l-grid pf-m-gutter">
|
<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">
|
<div class="pf-c-card__body">
|
||||||
<dl class="pf-c-description-list pf-m-2-col-on-lg">
|
<dl class="pf-c-description-list pf-m-2-col-on-lg">
|
||||||
<div class="pf-c-description-list__group">
|
<div class="pf-c-description-list__group">
|
||||||
@ -127,7 +130,20 @@ export class LDAPSourceViewPage extends AKElement {
|
|||||||
</ak-forms-modal>
|
</ak-forms-modal>
|
||||||
</div>
|
</div>
|
||||||
</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">
|
<div class="pf-c-card__title">
|
||||||
<p>${msg("Connectivity")}</p>
|
<p>${msg("Connectivity")}</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -9,6 +9,7 @@ import { PaginatedResponse, Table } from "@goauthentik/elements/table/Table";
|
|||||||
import { TableColumn } from "@goauthentik/elements/table/Table";
|
import { TableColumn } from "@goauthentik/elements/table/Table";
|
||||||
import "@goauthentik/elements/tasks/ScheduleForm";
|
import "@goauthentik/elements/tasks/ScheduleForm";
|
||||||
import "@goauthentik/elements/tasks/TaskList";
|
import "@goauthentik/elements/tasks/TaskList";
|
||||||
|
import "@goauthentik/elements/tasks/TaskStatus";
|
||||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||||
|
|
||||||
import { msg } from "@lit/localize";
|
import { msg } from "@lit/localize";
|
||||||
@ -72,6 +73,7 @@ export class ScheduleList extends Table<Schedule> {
|
|||||||
new TableColumn(msg("Schedule"), "actor_name"),
|
new TableColumn(msg("Schedule"), "actor_name"),
|
||||||
new TableColumn(msg("Crontab"), "crontab"),
|
new TableColumn(msg("Crontab"), "crontab"),
|
||||||
new TableColumn(msg("Next run"), "next_run"),
|
new TableColumn(msg("Next run"), "next_run"),
|
||||||
|
new TableColumn(msg("Last status")),
|
||||||
new TableColumn(msg("Actions")),
|
new TableColumn(msg("Actions")),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -118,6 +120,7 @@ export class ScheduleList extends Table<Schedule> {
|
|||||||
<small>${item.nextRun.toLocaleString()}</small>
|
<small>${item.nextRun.toLocaleString()}</small>
|
||||||
`}
|
`}
|
||||||
`,
|
`,
|
||||||
|
html`<ak-task-status .status=${item.lastTaskStatus}></ak-task-status>`,
|
||||||
html`<ak-action-button
|
html`<ak-action-button
|
||||||
class="pf-m-plain"
|
class="pf-m-plain"
|
||||||
.apiRequest=${() => {
|
.apiRequest=${() => {
|
||||||
|
@ -9,12 +9,16 @@ import { customElement, property } from "lit/decorators.js";
|
|||||||
import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
||||||
import PFBase from "@patternfly/patternfly/patternfly-base.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")
|
@customElement("ak-task-status")
|
||||||
export class TaskStatus extends AKElement {
|
export class TaskStatus extends AKElement {
|
||||||
@property()
|
@property()
|
||||||
status?: TaskAggregatedStatusEnum | TasksTasksListAggregatedStatusEnum;
|
status?: TaskAggregatedStatusEnum | TasksTasksListAggregatedStatusEnum | LastTaskStatusEnum;
|
||||||
|
|
||||||
static get styles(): CSSResult[] {
|
static get styles(): CSSResult[] {
|
||||||
return [PFBase, PFButton];
|
return [PFBase, PFButton];
|
||||||
@ -24,22 +28,29 @@ export class TaskStatus extends AKElement {
|
|||||||
switch (this.status) {
|
switch (this.status) {
|
||||||
case TasksTasksListAggregatedStatusEnum.Queued:
|
case TasksTasksListAggregatedStatusEnum.Queued:
|
||||||
case TaskAggregatedStatusEnum.Queued:
|
case TaskAggregatedStatusEnum.Queued:
|
||||||
|
case LastTaskStatusEnum.Queued:
|
||||||
return html`<ak-label color=${PFColor.Grey}>${msg("Waiting to run")}</ak-label>`;
|
return html`<ak-label color=${PFColor.Grey}>${msg("Waiting to run")}</ak-label>`;
|
||||||
case TasksTasksListAggregatedStatusEnum.Consumed:
|
case TasksTasksListAggregatedStatusEnum.Consumed:
|
||||||
case TaskAggregatedStatusEnum.Consumed:
|
case TaskAggregatedStatusEnum.Consumed:
|
||||||
|
case LastTaskStatusEnum.Consumed:
|
||||||
return html`<ak-label color=${PFColor.Blue}>${msg("Running")}</ak-label>`;
|
return html`<ak-label color=${PFColor.Blue}>${msg("Running")}</ak-label>`;
|
||||||
case TasksTasksListAggregatedStatusEnum.Done:
|
case TasksTasksListAggregatedStatusEnum.Done:
|
||||||
case TaskAggregatedStatusEnum.Done:
|
case TaskAggregatedStatusEnum.Done:
|
||||||
|
case LastTaskStatusEnum.Done:
|
||||||
case TasksTasksListAggregatedStatusEnum.Info:
|
case TasksTasksListAggregatedStatusEnum.Info:
|
||||||
case TaskAggregatedStatusEnum.Info:
|
case TaskAggregatedStatusEnum.Info:
|
||||||
|
case LastTaskStatusEnum.Info:
|
||||||
return html`<ak-label color=${PFColor.Green}>${msg("Successful")}</ak-label>`;
|
return html`<ak-label color=${PFColor.Green}>${msg("Successful")}</ak-label>`;
|
||||||
case TasksTasksListAggregatedStatusEnum.Warning:
|
case TasksTasksListAggregatedStatusEnum.Warning:
|
||||||
case TaskAggregatedStatusEnum.Warning:
|
case TaskAggregatedStatusEnum.Warning:
|
||||||
|
case LastTaskStatusEnum.Warning:
|
||||||
return html`<ak-label color=${PFColor.Orange}>${msg("Warning")}</ak-label>`;
|
return html`<ak-label color=${PFColor.Orange}>${msg("Warning")}</ak-label>`;
|
||||||
case TasksTasksListAggregatedStatusEnum.Rejected:
|
case TasksTasksListAggregatedStatusEnum.Rejected:
|
||||||
case TaskAggregatedStatusEnum.Rejected:
|
case TaskAggregatedStatusEnum.Rejected:
|
||||||
|
case LastTaskStatusEnum.Rejected:
|
||||||
case TasksTasksListAggregatedStatusEnum.Error:
|
case TasksTasksListAggregatedStatusEnum.Error:
|
||||||
case TaskAggregatedStatusEnum.Error:
|
case TaskAggregatedStatusEnum.Error:
|
||||||
|
case LastTaskStatusEnum.Error:
|
||||||
return html`<ak-label color=${PFColor.Red}>${msg("Error")}</ak-label>`;
|
return html`<ak-label color=${PFColor.Red}>${msg("Error")}</ak-label>`;
|
||||||
default:
|
default:
|
||||||
return html`<ak-label color=${PFColor.Grey}>${msg("Unknown")}</ak-label>`;
|
return html`<ak-label color=${PFColor.Grey}>${msg("Unknown")}</ak-label>`;
|
||||||
|
Reference in New Issue
Block a user