re-introduce sync status api
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
This commit is contained in:
@ -7,6 +7,7 @@ from authentik.core.api.used_by import UsedByMixin
|
||||
from authentik.enterprise.api import EnterpriseRequiredMixin
|
||||
from authentik.enterprise.providers.google_workspace.models import GoogleWorkspaceProvider
|
||||
from authentik.enterprise.providers.google_workspace.tasks import (
|
||||
google_workspace_sync,
|
||||
google_workspace_sync_objects,
|
||||
)
|
||||
from authentik.lib.sync.outgoing.api import OutgoingSyncProviderStatusMixin
|
||||
@ -54,4 +55,5 @@ class GoogleWorkspaceProviderViewSet(OutgoingSyncProviderStatusMixin, UsedByMixi
|
||||
]
|
||||
search_fields = ["name"]
|
||||
ordering = ["name"]
|
||||
sync_task = google_workspace_sync
|
||||
sync_objects_task = google_workspace_sync_objects
|
||||
|
@ -7,6 +7,7 @@ from authentik.core.api.used_by import UsedByMixin
|
||||
from authentik.enterprise.api import EnterpriseRequiredMixin
|
||||
from authentik.enterprise.providers.microsoft_entra.models import MicrosoftEntraProvider
|
||||
from authentik.enterprise.providers.microsoft_entra.tasks import (
|
||||
microsoft_entra_sync,
|
||||
microsoft_entra_sync_objects,
|
||||
)
|
||||
from authentik.lib.sync.outgoing.api import OutgoingSyncProviderStatusMixin
|
||||
@ -52,4 +53,5 @@ class MicrosoftEntraProviderViewSet(OutgoingSyncProviderStatusMixin, UsedByMixin
|
||||
]
|
||||
search_fields = ["name"]
|
||||
ordering = ["name"]
|
||||
sync_task = microsoft_entra_sync
|
||||
sync_objects_task = microsoft_entra_sync_objects
|
||||
|
17
authentik/lib/sync/api.py
Normal file
17
authentik/lib/sync/api.py
Normal file
@ -0,0 +1,17 @@
|
||||
from rest_framework.fields import BooleanField, ChoiceField, DateTimeField
|
||||
|
||||
from authentik.core.api.utils import PassiveSerializer
|
||||
from authentik.tasks.models import TaskStatus
|
||||
|
||||
|
||||
class SyncStatusSerializer(PassiveSerializer):
|
||||
"""Provider/source sync status"""
|
||||
|
||||
is_running = BooleanField(read_only=True, default=False)
|
||||
last_successful_sync = DateTimeField(read_only=True, required=False, default=None)
|
||||
last_sync_status = ChoiceField(
|
||||
read_only=True,
|
||||
required=False,
|
||||
default=None,
|
||||
choices=TaskStatus.choices,
|
||||
)
|
@ -1,5 +1,5 @@
|
||||
from dramatiq.actor import Actor
|
||||
from drf_spectacular.utils import extend_schema
|
||||
from drf_spectacular.utils import OpenApiResponse, extend_schema
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.fields import BooleanField, CharField, ChoiceField
|
||||
from rest_framework.request import Request
|
||||
@ -8,10 +8,11 @@ from rest_framework.response import Response
|
||||
from authentik.core.api.utils import ModelSerializer, PassiveSerializer
|
||||
from authentik.core.models import Group, User
|
||||
from authentik.events.logs import LogEventSerializer
|
||||
from authentik.lib.sync.api import SyncStatusSerializer
|
||||
from authentik.lib.sync.outgoing.models import OutgoingSyncProvider
|
||||
from authentik.lib.utils.reflection import class_to_path
|
||||
from authentik.rbac.filters import ObjectFilter
|
||||
from authentik.tasks.models import Task
|
||||
from authentik.tasks.models import Task, TaskStatus
|
||||
|
||||
|
||||
class SyncObjectSerializer(PassiveSerializer):
|
||||
@ -36,8 +37,55 @@ class SyncObjectResultSerializer(PassiveSerializer):
|
||||
class OutgoingSyncProviderStatusMixin:
|
||||
"""Common API Endpoints for Outgoing sync providers"""
|
||||
|
||||
sync_task: Actor
|
||||
sync_objects_task: Actor
|
||||
|
||||
@extend_schema(responses={200: SyncStatusSerializer()})
|
||||
@action(
|
||||
methods=["GET"],
|
||||
detail=True,
|
||||
pagination_class=None,
|
||||
url_path="sync/status",
|
||||
filter_backends=[ObjectFilter],
|
||||
)
|
||||
def sync_status(self, request: Request, pk: int) -> Response:
|
||||
"""Get provider's sync status"""
|
||||
provider: OutgoingSyncProvider = self.get_object()
|
||||
|
||||
sync_schedule = None
|
||||
for schedule in provider.schedules.all():
|
||||
if schedule.actor_name == self.sync_task.actor_name:
|
||||
sync_schedule = schedule
|
||||
|
||||
if not sync_schedule:
|
||||
return Response(SyncStatusSerializer({}).data)
|
||||
|
||||
status = {}
|
||||
|
||||
last_task: Task = (
|
||||
sync_schedule.tasks.exclude(
|
||||
aggregated_status__in=(TaskStatus.CONSUMED, TaskStatus.QUEUED)
|
||||
)
|
||||
.order_by("-mtime")
|
||||
.first()
|
||||
)
|
||||
last_successful_task: Task = (
|
||||
sync_schedule.tasks.filter(aggregated_status__in=(TaskStatus.DONE, TaskStatus.INFO))
|
||||
.order_by("-mtime")
|
||||
.first()
|
||||
)
|
||||
|
||||
if last_task:
|
||||
status["last_sync_status"] = last_task.aggregated_status
|
||||
if last_successful_task:
|
||||
status["last_successful_sync"] = last_successful_task.mtime
|
||||
|
||||
with provider.sync_lock as lock_acquired:
|
||||
# If we could not acquire the lock, it means a task is using it, and thus is running
|
||||
status["is_running"] = not lock_acquired
|
||||
|
||||
return Response(SyncStatusSerializer(status).data)
|
||||
|
||||
@extend_schema(
|
||||
request=SyncObjectSerializer,
|
||||
responses={200: SyncObjectResultSerializer()},
|
||||
|
@ -6,7 +6,7 @@ from authentik.core.api.providers import ProviderSerializer
|
||||
from authentik.core.api.used_by import UsedByMixin
|
||||
from authentik.lib.sync.outgoing.api import OutgoingSyncProviderStatusMixin
|
||||
from authentik.providers.scim.models import SCIMProvider
|
||||
from authentik.providers.scim.tasks import scim_sync_objects
|
||||
from authentik.providers.scim.tasks import scim_sync, scim_sync_objects
|
||||
|
||||
|
||||
class SCIMProviderSerializer(ProviderSerializer):
|
||||
@ -44,4 +44,5 @@ class SCIMProviderViewSet(OutgoingSyncProviderStatusMixin, UsedByMixin, ModelVie
|
||||
filterset_fields = ["name", "exclude_users_service_account", "url", "filter_group"]
|
||||
search_fields = ["name", "url"]
|
||||
ordering = ["name", "url"]
|
||||
sync_task = scim_sync
|
||||
sync_objects_task = scim_sync_objects
|
||||
|
@ -170,6 +170,7 @@ SPECTACULAR_SETTINGS = {
|
||||
"UserVerificationEnum": "authentik.stages.authenticator_webauthn.models.UserVerification",
|
||||
"UserTypeEnum": "authentik.core.models.UserTypes",
|
||||
"OutgoingSyncDeleteAction": "authentik.lib.sync.outgoing.models.OutgoingSyncDeleteAction",
|
||||
"TaskAggregatedStatusEnum": "authentik.tasks.models.TaskStatus",
|
||||
},
|
||||
"ENUM_ADD_EXPLICIT_BLANK_NULL_CHOICE": False,
|
||||
"ENUM_GENERATE_CHOICE_DESCRIPTION": False,
|
||||
|
@ -1,13 +1,20 @@
|
||||
"""Source API Views"""
|
||||
|
||||
from django.core.cache import cache
|
||||
from drf_spectacular.utils import OpenApiResponse, extend_schema
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.fields import SerializerMethodField
|
||||
from rest_framework.request import Request
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
|
||||
from authentik.core.api.sources import SourceSerializer
|
||||
from authentik.core.api.used_by import UsedByMixin
|
||||
from authentik.lib.sync.api import SyncStatusSerializer
|
||||
from authentik.rbac.filters import ObjectFilter
|
||||
from authentik.sources.kerberos.models import KerberosSource
|
||||
from authentik.sources.kerberos.tasks import CACHE_KEY_STATUS
|
||||
from authentik.sources.kerberos.tasks import CACHE_KEY_STATUS, kerberos_sync
|
||||
from authentik.tasks.models import Task, TaskStatus
|
||||
|
||||
|
||||
class KerberosSourceSerializer(SourceSerializer):
|
||||
@ -73,3 +80,49 @@ class KerberosSourceViewSet(UsedByMixin, ModelViewSet):
|
||||
"spnego_server_name",
|
||||
]
|
||||
ordering = ["name"]
|
||||
|
||||
@extend_schema(responses={200: SyncStatusSerializer()})
|
||||
@action(
|
||||
methods=["GET"],
|
||||
detail=True,
|
||||
pagination_class=None,
|
||||
url_path="sync/status",
|
||||
filter_backends=[ObjectFilter],
|
||||
)
|
||||
def sync_status(self, request: Request, pk: int) -> Response:
|
||||
"""Get provider's sync status"""
|
||||
source: KerberosSource = self.get_object()
|
||||
|
||||
sync_schedule = None
|
||||
for schedule in source.schedules.all():
|
||||
if schedule.actor_name == kerberos_sync.actor_name:
|
||||
sync_schedule = schedule
|
||||
|
||||
if not sync_schedule:
|
||||
return Response(SyncStatusSerializer({}).data)
|
||||
|
||||
status = {}
|
||||
|
||||
last_task: Task = (
|
||||
sync_schedule.tasks.exclude(
|
||||
aggregated_status__in=(TaskStatus.CONSUMED, TaskStatus.QUEUED)
|
||||
)
|
||||
.order_by("-mtime")
|
||||
.first()
|
||||
)
|
||||
last_successful_task: Task = (
|
||||
sync_schedule.tasks.filter(aggregated_status__in=(TaskStatus.DONE, TaskStatus.INFO))
|
||||
.order_by("-mtime")
|
||||
.first()
|
||||
)
|
||||
|
||||
if last_task:
|
||||
status["last_sync_status"] = last_task.aggregated_status
|
||||
if last_successful_task:
|
||||
status["last_successful_sync"] = last_successful_task.mtime
|
||||
|
||||
with source.sync_lock as lock_acquired:
|
||||
# If we could not acquire the lock, it means a task is using it, and thus is running
|
||||
status["is_running"] = not lock_acquired
|
||||
|
||||
return Response(SyncStatusSerializer(status).data)
|
||||
|
@ -4,7 +4,7 @@ from typing import Any
|
||||
|
||||
from django.core.cache import cache
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from drf_spectacular.utils import extend_schema, inline_serializer
|
||||
from drf_spectacular.utils import OpenApiResponse, extend_schema, inline_serializer
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.exceptions import ValidationError
|
||||
from rest_framework.fields import DictField, ListField, SerializerMethodField
|
||||
@ -23,13 +23,16 @@ from authentik.core.api.sources import (
|
||||
)
|
||||
from authentik.core.api.used_by import UsedByMixin
|
||||
from authentik.crypto.models import CertificateKeyPair
|
||||
from authentik.lib.sync.api import SyncStatusSerializer
|
||||
from authentik.rbac.filters import ObjectFilter
|
||||
from authentik.sources.ldap.models import (
|
||||
GroupLDAPSourceConnection,
|
||||
LDAPSource,
|
||||
LDAPSourcePropertyMapping,
|
||||
UserLDAPSourceConnection,
|
||||
)
|
||||
from authentik.sources.ldap.tasks import CACHE_KEY_STATUS, SYNC_CLASSES
|
||||
from authentik.sources.ldap.tasks import CACHE_KEY_STATUS, SYNC_CLASSES, ldap_sync
|
||||
from authentik.tasks.models import Task, TaskStatus
|
||||
|
||||
|
||||
class LDAPSourceSerializer(SourceSerializer):
|
||||
@ -153,6 +156,52 @@ class LDAPSourceViewSet(UsedByMixin, ModelViewSet):
|
||||
search_fields = ["name", "slug"]
|
||||
ordering = ["name"]
|
||||
|
||||
@extend_schema(responses={200: SyncStatusSerializer()})
|
||||
@action(
|
||||
methods=["GET"],
|
||||
detail=True,
|
||||
pagination_class=None,
|
||||
url_path="sync/status",
|
||||
filter_backends=[ObjectFilter],
|
||||
)
|
||||
def sync_status(self, request: Request, pk: int) -> Response:
|
||||
"""Get provider's sync status"""
|
||||
source: LDAPSource = self.get_object()
|
||||
|
||||
sync_schedule = None
|
||||
for schedule in source.schedules.all():
|
||||
if schedule.actor_name == ldap_sync.actor_name:
|
||||
sync_schedule = schedule
|
||||
|
||||
if not sync_schedule:
|
||||
return Response(SyncStatusSerializer({}).data)
|
||||
|
||||
status = {}
|
||||
|
||||
last_task: Task = (
|
||||
sync_schedule.tasks.exclude(
|
||||
aggregated_status__in=(TaskStatus.CONSUMED, TaskStatus.QUEUED)
|
||||
)
|
||||
.order_by("-mtime")
|
||||
.first()
|
||||
)
|
||||
last_successful_task: Task = (
|
||||
sync_schedule.tasks.filter(aggregated_status__in=(TaskStatus.DONE, TaskStatus.INFO))
|
||||
.order_by("-mtime")
|
||||
.first()
|
||||
)
|
||||
|
||||
if last_task:
|
||||
status["last_sync_status"] = last_task.aggregated_status
|
||||
if last_successful_task:
|
||||
status["last_successful_sync"] = last_successful_task.mtime
|
||||
|
||||
with source.sync_lock as lock_acquired:
|
||||
# If we could not acquire the lock, it means a task is using it, and thus is running
|
||||
status["is_running"] = not lock_acquired
|
||||
|
||||
return Response(SyncStatusSerializer(status).data)
|
||||
|
||||
@extend_schema(
|
||||
responses={
|
||||
200: inline_serializer(
|
||||
|
212
schema.yml
212
schema.yml
@ -19451,6 +19451,40 @@ paths:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
/providers/google_workspace/{id}/sync/status/:
|
||||
get:
|
||||
operationId: providers_google_workspace_sync_status_retrieve
|
||||
description: Get provider's sync status
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
schema:
|
||||
type: integer
|
||||
description: A unique integer value identifying this Google Workspace Provider.
|
||||
required: true
|
||||
tags:
|
||||
- providers
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SyncStatus'
|
||||
description: ''
|
||||
'400':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ValidationError'
|
||||
description: ''
|
||||
'403':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
/providers/google_workspace/{id}/used_by/:
|
||||
get:
|
||||
operationId: providers_google_workspace_used_by_list
|
||||
@ -20458,6 +20492,40 @@ paths:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
/providers/microsoft_entra/{id}/sync/status/:
|
||||
get:
|
||||
operationId: providers_microsoft_entra_sync_status_retrieve
|
||||
description: Get provider's sync status
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
schema:
|
||||
type: integer
|
||||
description: A unique integer value identifying this Microsoft Entra Provider.
|
||||
required: true
|
||||
tags:
|
||||
- providers
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SyncStatus'
|
||||
description: ''
|
||||
'400':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ValidationError'
|
||||
description: ''
|
||||
'403':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
/providers/microsoft_entra/{id}/used_by/:
|
||||
get:
|
||||
operationId: providers_microsoft_entra_used_by_list
|
||||
@ -22957,6 +23025,40 @@ paths:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
/providers/scim/{id}/sync/status/:
|
||||
get:
|
||||
operationId: providers_scim_sync_status_retrieve
|
||||
description: Get provider's sync status
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
schema:
|
||||
type: integer
|
||||
description: A unique integer value identifying this SCIM Provider.
|
||||
required: true
|
||||
tags:
|
||||
- providers
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SyncStatus'
|
||||
description: ''
|
||||
'400':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ValidationError'
|
||||
description: ''
|
||||
'403':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
/providers/scim/{id}/used_by/:
|
||||
get:
|
||||
operationId: providers_scim_used_by_list
|
||||
@ -28045,6 +28147,40 @@ paths:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
/sources/kerberos/{slug}/sync/status/:
|
||||
get:
|
||||
operationId: sources_kerberos_sync_status_retrieve
|
||||
description: Get provider's sync status
|
||||
parameters:
|
||||
- in: path
|
||||
name: slug
|
||||
schema:
|
||||
type: string
|
||||
description: Internal source name, used in URLs.
|
||||
required: true
|
||||
tags:
|
||||
- sources
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SyncStatus'
|
||||
description: ''
|
||||
'400':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ValidationError'
|
||||
description: ''
|
||||
'403':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
/sources/kerberos/{slug}/used_by/:
|
||||
get:
|
||||
operationId: sources_kerberos_used_by_list
|
||||
@ -28461,6 +28597,40 @@ paths:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
/sources/ldap/{slug}/sync/status/:
|
||||
get:
|
||||
operationId: sources_ldap_sync_status_retrieve
|
||||
description: Get provider's sync status
|
||||
parameters:
|
||||
- in: path
|
||||
name: slug
|
||||
schema:
|
||||
type: string
|
||||
description: Internal source name, used in URLs.
|
||||
required: true
|
||||
tags:
|
||||
- sources
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SyncStatus'
|
||||
description: ''
|
||||
'400':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ValidationError'
|
||||
description: ''
|
||||
'403':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
/sources/ldap/{slug}/used_by/:
|
||||
get:
|
||||
operationId: sources_ldap_used_by_list
|
||||
@ -41211,16 +41381,6 @@ components:
|
||||
required:
|
||||
- pending_user
|
||||
- pending_user_avatar
|
||||
AggregatedStatusEnum:
|
||||
enum:
|
||||
- queued
|
||||
- consumed
|
||||
- rejected
|
||||
- done
|
||||
- info
|
||||
- warning
|
||||
- error
|
||||
type: string
|
||||
AlgEnum:
|
||||
enum:
|
||||
- rsa
|
||||
@ -60224,6 +60384,26 @@ components:
|
||||
readOnly: true
|
||||
required:
|
||||
- messages
|
||||
SyncStatus:
|
||||
type: object
|
||||
description: Provider/source sync status
|
||||
properties:
|
||||
is_running:
|
||||
type: boolean
|
||||
readOnly: true
|
||||
default: false
|
||||
last_successful_sync:
|
||||
type: string
|
||||
format: date-time
|
||||
readOnly: true
|
||||
last_sync_status:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/TaskAggregatedStatusEnum'
|
||||
readOnly: true
|
||||
required:
|
||||
- is_running
|
||||
- last_successful_sync
|
||||
- last_sync_status
|
||||
SystemInfo:
|
||||
type: object
|
||||
description: Get system information.
|
||||
@ -60372,7 +60552,7 @@ components:
|
||||
items:
|
||||
$ref: '#/components/schemas/LogEvent'
|
||||
aggregated_status:
|
||||
$ref: '#/components/schemas/AggregatedStatusEnum'
|
||||
$ref: '#/components/schemas/TaskAggregatedStatusEnum'
|
||||
required:
|
||||
- actor_name
|
||||
- aggregated_status
|
||||
@ -60381,6 +60561,16 @@ components:
|
||||
- rel_obj_app_label
|
||||
- rel_obj_model
|
||||
- uid
|
||||
TaskAggregatedStatusEnum:
|
||||
enum:
|
||||
- queued
|
||||
- consumed
|
||||
- rejected
|
||||
- done
|
||||
- info
|
||||
- warning
|
||||
- error
|
||||
type: string
|
||||
Tenant:
|
||||
type: object
|
||||
description: Tenant Serializer
|
||||
|
@ -152,110 +152,108 @@ export class SCIMProviderViewPage extends AKElement {
|
||||
</div>`
|
||||
: html``}
|
||||
<div class="pf-c-page__main-section pf-m-no-padding-mobile pf-l-grid pf-m-gutter">
|
||||
<div class="pf-l-grid__item pf-m-7-col pf-l-stack pf-m-gutter">
|
||||
<div class="pf-c-card pf-m-12-col pf-l-stack__item">
|
||||
<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">
|
||||
<div class="pf-c-description-list__group">
|
||||
<dt class="pf-c-description-list__term">
|
||||
<span class="pf-c-description-list__text">${msg("Name")}</span>
|
||||
</dt>
|
||||
<dd class="pf-c-description-list__description">
|
||||
<div class="pf-c-description-list__text">
|
||||
${this.provider.name}
|
||||
</div>
|
||||
</dd>
|
||||
</div>
|
||||
<div class="pf-c-description-list__group">
|
||||
<dt class="pf-c-description-list__term">
|
||||
<span class="pf-c-description-list__text"
|
||||
>${msg("Assigned to application")}</span
|
||||
>
|
||||
</dt>
|
||||
<dd class="pf-c-description-list__description">
|
||||
<div class="pf-c-description-list__text">
|
||||
<ak-provider-related-application
|
||||
mode="backchannel"
|
||||
.provider=${this.provider}
|
||||
></ak-provider-related-application>
|
||||
</div>
|
||||
</dd>
|
||||
</div>
|
||||
<div class="pf-c-description-list__group">
|
||||
<dt class="pf-c-description-list__term">
|
||||
<span class="pf-c-description-list__text"
|
||||
>${msg("Dry-run")}</span
|
||||
>
|
||||
</dt>
|
||||
<dd class="pf-c-description-list__description">
|
||||
<div class="pf-c-description-list__text">
|
||||
<ak-status-label
|
||||
?good=${!this.provider.dryRun}
|
||||
type="info"
|
||||
good-label=${msg("No")}
|
||||
bad-label=${msg("Yes")}
|
||||
></ak-status-label>
|
||||
</div>
|
||||
</dd>
|
||||
</div>
|
||||
<div class="pf-c-description-list__group">
|
||||
<dt class="pf-c-description-list__term">
|
||||
<span class="pf-c-description-list__text">${msg("URL")}</span>
|
||||
</dt>
|
||||
<dd class="pf-c-description-list__description">
|
||||
<div class="pf-c-description-list__text">
|
||||
${this.provider.url}
|
||||
</div>
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="pf-c-card__footer">
|
||||
<ak-forms-modal>
|
||||
<span slot="submit"> ${msg("Update")} </span>
|
||||
<span slot="header"> ${msg("Update SCIM Provider")} </span>
|
||||
<ak-provider-scim-form slot="form" .instancePk=${this.provider.pk}>
|
||||
</ak-provider-scim-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">
|
||||
${msg("Edit")}
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pf-l-grid__item pf-m-12-col pf-l-stack__item">
|
||||
<div class="pf-c-card">
|
||||
<div class="pf-c-card__header">
|
||||
<div class="pf-c-card__title">${msg("Schedules")}</div>
|
||||
</div>
|
||||
<div class="pf-c-card__body">
|
||||
<dl class="pf-c-description-list pf-m-4-col-on-lg">
|
||||
<div class="pf-c-description-list__group">
|
||||
<dt class="pf-c-description-list__term">
|
||||
<span class="pf-c-description-list__text"
|
||||
>${msg("Name")}</span
|
||||
>
|
||||
</dt>
|
||||
<dd class="pf-c-description-list__description">
|
||||
<div class="pf-c-description-list__text">
|
||||
${this.provider.name}
|
||||
</div>
|
||||
</dd>
|
||||
</div>
|
||||
<div class="pf-c-description-list__group">
|
||||
<dt class="pf-c-description-list__term">
|
||||
<span class="pf-c-description-list__text"
|
||||
>${msg("Assigned to application")}</span
|
||||
>
|
||||
</dt>
|
||||
<dd class="pf-c-description-list__description">
|
||||
<div class="pf-c-description-list__text">
|
||||
<ak-provider-related-application
|
||||
mode="backchannel"
|
||||
.provider=${this.provider}
|
||||
></ak-provider-related-application>
|
||||
</div>
|
||||
</dd>
|
||||
</div>
|
||||
<div class="pf-c-description-list__group">
|
||||
<dt class="pf-c-description-list__term">
|
||||
<span class="pf-c-description-list__text"
|
||||
>${msg("Dry-run")}</span
|
||||
>
|
||||
</dt>
|
||||
<dd class="pf-c-description-list__description">
|
||||
<div class="pf-c-description-list__text">
|
||||
<ak-status-label
|
||||
?good=${!this.provider.dryRun}
|
||||
type="info"
|
||||
good-label=${msg("No")}
|
||||
bad-label=${msg("Yes")}
|
||||
></ak-status-label>
|
||||
</div>
|
||||
</dd>
|
||||
</div>
|
||||
<div class="pf-c-description-list__group">
|
||||
<dt class="pf-c-description-list__term">
|
||||
<span class="pf-c-description-list__text"
|
||||
>${msg("URL")}</span
|
||||
>
|
||||
</dt>
|
||||
<dd class="pf-c-description-list__description">
|
||||
<div class="pf-c-description-list__text">
|
||||
${this.provider.url}
|
||||
</div>
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="pf-c-card__footer">
|
||||
<ak-forms-modal>
|
||||
<span slot="submit"> ${msg("Update")} </span>
|
||||
<span slot="header"> ${msg("Update SCIM Provider")} </span>
|
||||
<ak-provider-scim-form slot="form" .instancePk=${this.provider.pk}>
|
||||
</ak-provider-scim-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">
|
||||
${msg("Edit")}
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pf-l-grid__item pf-m-12-col pf-l-stack__item">
|
||||
<div class="pf-c-card">
|
||||
<div class="pf-c-card__header">
|
||||
<div class="pf-c-card__title">${msg("Schedules")}</div>
|
||||
</div>
|
||||
<div class="pf-c-card__body">
|
||||
<ak-schedule-list
|
||||
.relObjAppLabel=${appLabel}
|
||||
.relObjModel=${modelName}
|
||||
.relObjId="${this.provider.pk}"
|
||||
></ak-schedule-list>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pf-l-grid__item pf-m-12-col pf-l-stack__item">
|
||||
<div class="pf-c-card">
|
||||
<div class="pf-c-card__header">
|
||||
<div class="pf-c-card__title">${msg("Tasks")}</div>
|
||||
</div>
|
||||
<div class="pf-c-card__body">
|
||||
<ak-task-list
|
||||
.relObjAppLabel=${appLabel}
|
||||
.relObjModel=${modelName}
|
||||
.relObjId="${this.provider.pk}"
|
||||
></ak-task-list>
|
||||
</div>
|
||||
<ak-schedule-list
|
||||
.relObjAppLabel=${appLabel}
|
||||
.relObjModel=${modelName}
|
||||
.relObjId="${this.provider.pk}"
|
||||
></ak-schedule-list>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pf-c-card pf-l-grid__item pf-m-5-col">
|
||||
<div class="pf-l-grid__item pf-m-12-col pf-l-stack__item">
|
||||
<div class="pf-c-card">
|
||||
<div class="pf-c-card__header">
|
||||
<div class="pf-c-card__title">${msg("Tasks")}</div>
|
||||
</div>
|
||||
<div class="pf-c-card__body">
|
||||
<ak-task-list
|
||||
.relObjAppLabel=${appLabel}
|
||||
.relObjModel=${modelName}
|
||||
.relObjId="${this.provider.pk}"
|
||||
></ak-task-list>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="pf-c-card pf-l-grid__item pf-m-12-col pf-m-12-col-on-xl pf-m-12-col-on-2xl"
|
||||
>
|
||||
<div class="pf-c-card__body">
|
||||
<ak-mdx .url=${MDSCIMProvider}></ak-mdx>
|
||||
</div>
|
||||
|
Reference in New Issue
Block a user