@ -1,12 +1,13 @@
|
||||
"""authentik API AppConfig"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikAPIConfig(AppConfig):
|
||||
class AuthentikAPIConfig(ManagedAppConfig):
|
||||
"""authentik API Config"""
|
||||
|
||||
name = "authentik.api"
|
||||
label = "authentik_api"
|
||||
mountpoint = "api/"
|
||||
verbose_name = "authentik API"
|
||||
default = True
|
||||
mountpoint = "api/"
|
||||
|
@ -6,6 +6,7 @@ from inspect import ismethod
|
||||
|
||||
from django.apps import AppConfig
|
||||
from django.db import DatabaseError, InternalError, ProgrammingError
|
||||
from dramatiq.broker import get_broker
|
||||
from structlog.stdlib import BoundLogger, get_logger
|
||||
|
||||
from authentik.lib.utils.time import fqdn_rand
|
||||
@ -92,10 +93,6 @@ class ManagedAppConfig(AppConfig):
|
||||
"""Get a list of schedule specs that must exist in the default tenant"""
|
||||
return []
|
||||
|
||||
def _reconcile_schedules(self, schedules: list[ScheduleSpec]):
|
||||
for schedule in schedules:
|
||||
schedule.update_or_create()
|
||||
|
||||
def _reconcile_tenant(self) -> None:
|
||||
"""reconcile ourselves for tenanted methods"""
|
||||
from authentik.tenants.models import Tenant
|
||||
@ -108,7 +105,6 @@ class ManagedAppConfig(AppConfig):
|
||||
for tenant in tenants:
|
||||
with tenant:
|
||||
self._reconcile(self.RECONCILE_TENANT_CATEGORY)
|
||||
self._reconcile_schedules(self.tenant_schedule_specs)
|
||||
|
||||
def _reconcile_global(self) -> None:
|
||||
"""
|
||||
@ -119,7 +115,6 @@ class ManagedAppConfig(AppConfig):
|
||||
|
||||
with schema_context(get_public_schema_name()):
|
||||
self._reconcile(self.RECONCILE_GLOBAL_CATEGORY)
|
||||
self._reconcile_schedules(self.global_schedule_specs)
|
||||
|
||||
|
||||
class AuthentikBlueprintsConfig(ManagedAppConfig):
|
||||
@ -131,9 +126,15 @@ class AuthentikBlueprintsConfig(ManagedAppConfig):
|
||||
default = True
|
||||
|
||||
@ManagedAppConfig.reconcile_global
|
||||
def load_blueprints_v1_tasks(self):
|
||||
"""Load v1 tasks"""
|
||||
self.import_module("authentik.blueprints.v1.tasks")
|
||||
def tasks_middlewares(self):
|
||||
from authentik.blueprints.v1.tasks import BlueprintWatcherMiddleware
|
||||
|
||||
get_broker().add_middleware(BlueprintWatcherMiddleware())
|
||||
|
||||
# @ManagedAppConfig.reconcile_global
|
||||
# def load_blueprints_v1_tasks(self):
|
||||
# """Load v1 tasks"""
|
||||
# self.import_module("authentik.blueprints.v1.tasks")
|
||||
|
||||
@ManagedAppConfig.reconcile_tenant
|
||||
def blueprints_discovery(self):
|
||||
|
2
authentik/blueprints/tasks.py
Normal file
2
authentik/blueprints/tasks.py
Normal file
@ -0,0 +1,2 @@
|
||||
# Import all v1 tasks for auto task discovery
|
||||
from authentik.blueprints.v1.tasks import * # noqa: F403
|
@ -65,7 +65,7 @@ class BlueprintWatcherMiddleware(Middleware):
|
||||
)
|
||||
observer.start()
|
||||
|
||||
def before_worker_boot(self, broker, worker):
|
||||
def after_worker_boot(self, broker, worker):
|
||||
self.start_blueprint_watcher()
|
||||
|
||||
|
||||
|
@ -1,14 +1,15 @@
|
||||
"""authentik brands app"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikBrandsConfig(AppConfig):
|
||||
class AuthentikBrandsConfig(ManagedAppConfig):
|
||||
"""authentik Brand app"""
|
||||
|
||||
name = "authentik.brands"
|
||||
label = "authentik_brands"
|
||||
verbose_name = "authentik Brands"
|
||||
default = True
|
||||
mountpoints = {
|
||||
"authentik.brands.urls_root": "",
|
||||
}
|
||||
|
@ -317,7 +317,7 @@ class Outpost(ScheduledModel, SerializerModel, ManagedModel):
|
||||
ScheduleSpec(
|
||||
actor_name="authentik.outposts.tasks.outpost_controller",
|
||||
uid=self.pk,
|
||||
args=(self.pk, "up"),
|
||||
args=(self.pk,),
|
||||
kwargs={"action": "up", "from_cache": False},
|
||||
crontab=f"{fqdn_rand('outpost_controller')} */4 * * *",
|
||||
description=_(
|
||||
|
@ -134,8 +134,9 @@ def outpost_controller(outpost_pk: str, action: str = "up", from_cache: bool = F
|
||||
|
||||
@actor
|
||||
def outpost_token_ensurer():
|
||||
"""Periodically ensure that all Outposts have valid Service Accounts
|
||||
and Tokens"""
|
||||
"""
|
||||
Periodically ensure that all Outposts have valid Service Accounts and Tokens
|
||||
"""
|
||||
self: Task = CurrentTask.get_task()
|
||||
all_outposts = Outpost.objects.all()
|
||||
for outpost in all_outposts:
|
||||
|
@ -1,11 +1,12 @@
|
||||
"""Authentik policy dummy app config"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikPolicyDummyConfig(AppConfig):
|
||||
class AuthentikPolicyDummyConfig(ManagedAppConfig):
|
||||
"""Authentik policy_dummy app config"""
|
||||
|
||||
name = "authentik.policies.dummy"
|
||||
label = "authentik_policies_dummy"
|
||||
verbose_name = "authentik Policies.Dummy"
|
||||
default = True
|
||||
|
@ -1,11 +1,12 @@
|
||||
"""authentik Event Matcher policy app config"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikPoliciesEventMatcherConfig(AppConfig):
|
||||
class AuthentikPoliciesEventMatcherConfig(ManagedAppConfig):
|
||||
"""authentik Event Matcher policy app config"""
|
||||
|
||||
name = "authentik.policies.event_matcher"
|
||||
label = "authentik_policies_event_matcher"
|
||||
verbose_name = "authentik Policies.Event Matcher"
|
||||
default = True
|
||||
|
@ -1,11 +1,12 @@
|
||||
"""Authentik policy_expiry app config"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikPolicyExpiryConfig(AppConfig):
|
||||
class AuthentikPolicyExpiryConfig(ManagedAppConfig):
|
||||
"""Authentik policy_expiry app config"""
|
||||
|
||||
name = "authentik.policies.expiry"
|
||||
label = "authentik_policies_expiry"
|
||||
verbose_name = "authentik Policies.Expiry"
|
||||
default = True
|
||||
|
@ -1,11 +1,12 @@
|
||||
"""Authentik policy_expression app config"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikPolicyExpressionConfig(AppConfig):
|
||||
class AuthentikPolicyExpressionConfig(ManagedAppConfig):
|
||||
"""Authentik policy_expression app config"""
|
||||
|
||||
name = "authentik.policies.expression"
|
||||
label = "authentik_policies_expression"
|
||||
verbose_name = "authentik Policies.Expression"
|
||||
default = True
|
||||
|
@ -1,11 +1,12 @@
|
||||
"""Authentik policy geoip app config"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikPolicyGeoIPConfig(AppConfig):
|
||||
class AuthentikPolicyGeoIPConfig(ManagedAppConfig):
|
||||
"""Authentik policy_geoip app config"""
|
||||
|
||||
name = "authentik.policies.geoip"
|
||||
label = "authentik_policies_geoip"
|
||||
verbose_name = "authentik Policies.GeoIP"
|
||||
default = True
|
||||
|
@ -1,11 +1,12 @@
|
||||
"""authentik Password policy app config"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikPoliciesPasswordConfig(AppConfig):
|
||||
class AuthentikPoliciesPasswordConfig(ManagedAppConfig):
|
||||
"""authentik Password policy app config"""
|
||||
|
||||
name = "authentik.policies.password"
|
||||
label = "authentik_policies_password"
|
||||
verbose_name = "authentik Policies.Password"
|
||||
default = True
|
||||
|
@ -1,11 +1,12 @@
|
||||
"""authentik ldap provider app config"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikProviderLDAPConfig(AppConfig):
|
||||
class AuthentikProviderLDAPConfig(ManagedAppConfig):
|
||||
"""authentik ldap provider app config"""
|
||||
|
||||
name = "authentik.providers.ldap"
|
||||
label = "authentik_providers_ldap"
|
||||
verbose_name = "authentik Providers.LDAP"
|
||||
default = True
|
||||
|
@ -1,11 +1,12 @@
|
||||
"""authentik radius provider app config"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikProviderRadiusConfig(AppConfig):
|
||||
class AuthentikProviderRadiusConfig(ManagedAppConfig):
|
||||
"""authentik radius provider app config"""
|
||||
|
||||
name = "authentik.providers.radius"
|
||||
label = "authentik_providers_radius"
|
||||
verbose_name = "authentik Providers.Radius"
|
||||
default = True
|
||||
|
@ -1,12 +1,13 @@
|
||||
"""authentik SAML IdP app config"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikProviderSAMLConfig(AppConfig):
|
||||
class AuthentikProviderSAMLConfig(ManagedAppConfig):
|
||||
"""authentik SAML IdP app config"""
|
||||
|
||||
name = "authentik.providers.saml"
|
||||
label = "authentik_providers_saml"
|
||||
verbose_name = "authentik Providers.SAML"
|
||||
mountpoint = "application/saml/"
|
||||
default = True
|
||||
|
@ -1,12 +1,13 @@
|
||||
"""authentik Recovery app config"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikRecoveryConfig(AppConfig):
|
||||
class AuthentikRecoveryConfig(ManagedAppConfig):
|
||||
"""authentik Recovery app config"""
|
||||
|
||||
name = "authentik.recovery"
|
||||
label = "authentik_recovery"
|
||||
verbose_name = "authentik Recovery"
|
||||
mountpoint = "recovery/"
|
||||
default = True
|
||||
|
@ -1,11 +1,12 @@
|
||||
"""authentik plex config"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikSourcePlexConfig(AppConfig):
|
||||
class AuthentikSourcePlexConfig(ManagedAppConfig):
|
||||
"""authentik source plex config"""
|
||||
|
||||
name = "authentik.sources.plex"
|
||||
label = "authentik_sources_plex"
|
||||
verbose_name = "authentik Sources.Plex"
|
||||
default = True
|
||||
|
@ -1,11 +1,12 @@
|
||||
"""Authenticator"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikStageAuthenticatorConfig(AppConfig):
|
||||
class AuthentikStageAuthenticatorConfig(ManagedAppConfig):
|
||||
"""Authenticator App config"""
|
||||
|
||||
name = "authentik.stages.authenticator"
|
||||
label = "authentik_stages_authenticator"
|
||||
verbose_name = "authentik Stages.Authenticator"
|
||||
default = True
|
||||
|
@ -1,11 +1,12 @@
|
||||
"""SMS"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikStageAuthenticatorSMSConfig(AppConfig):
|
||||
class AuthentikStageAuthenticatorSMSConfig(ManagedAppConfig):
|
||||
"""SMS App config"""
|
||||
|
||||
name = "authentik.stages.authenticator_sms"
|
||||
label = "authentik_stages_authenticator_sms"
|
||||
verbose_name = "authentik Stages.Authenticator.SMS"
|
||||
default = True
|
||||
|
@ -1,11 +1,12 @@
|
||||
"""TOTP"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikStageAuthenticatorTOTPConfig(AppConfig):
|
||||
class AuthentikStageAuthenticatorTOTPConfig(ManagedAppConfig):
|
||||
"""TOTP App config"""
|
||||
|
||||
name = "authentik.stages.authenticator_totp"
|
||||
label = "authentik_stages_authenticator_totp"
|
||||
verbose_name = "authentik Stages.Authenticator.TOTP"
|
||||
default = True
|
||||
|
@ -1,11 +1,12 @@
|
||||
"""Authenticator Validation Stage"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikStageAuthenticatorValidateConfig(AppConfig):
|
||||
class AuthentikStageAuthenticatorValidateConfig(ManagedAppConfig):
|
||||
"""Authenticator Validation Stage"""
|
||||
|
||||
name = "authentik.stages.authenticator_validate"
|
||||
label = "authentik_stages_authenticator_validate"
|
||||
verbose_name = "authentik Stages.Authenticator.Validate"
|
||||
default = True
|
||||
|
@ -1,11 +1,12 @@
|
||||
"""authentik captcha app"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikStageCaptchaConfig(AppConfig):
|
||||
class AuthentikStageCaptchaConfig(ManagedAppConfig):
|
||||
"""authentik captcha app"""
|
||||
|
||||
name = "authentik.stages.captcha"
|
||||
label = "authentik_stages_captcha"
|
||||
verbose_name = "authentik Stages.Captcha"
|
||||
default = True
|
||||
|
@ -1,11 +1,12 @@
|
||||
"""authentik consent app"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikStageConsentConfig(AppConfig):
|
||||
class AuthentikStageConsentConfig(ManagedAppConfig):
|
||||
"""authentik consent app"""
|
||||
|
||||
name = "authentik.stages.consent"
|
||||
label = "authentik_stages_consent"
|
||||
verbose_name = "authentik Stages.Consent"
|
||||
default = True
|
||||
|
@ -1,11 +1,12 @@
|
||||
"""authentik deny stage app config"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikStageDenyConfig(AppConfig):
|
||||
class AuthentikStageDenyConfig(ManagedAppConfig):
|
||||
"""authentik deny stage config"""
|
||||
|
||||
name = "authentik.stages.deny"
|
||||
label = "authentik_stages_deny"
|
||||
verbose_name = "authentik Stages.Deny"
|
||||
default = True
|
||||
|
@ -1,11 +1,12 @@
|
||||
"""authentik dummy stage config"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikStageDummyConfig(AppConfig):
|
||||
class AuthentikStageDummyConfig(ManagedAppConfig):
|
||||
"""authentik dummy stage config"""
|
||||
|
||||
name = "authentik.stages.dummy"
|
||||
label = "authentik_stages_dummy"
|
||||
verbose_name = "authentik Stages.Dummy"
|
||||
default = True
|
||||
|
@ -1,11 +1,12 @@
|
||||
"""authentik identification stage app config"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikStageIdentificationConfig(AppConfig):
|
||||
class AuthentikStageIdentificationConfig(ManagedAppConfig):
|
||||
"""authentik identification stage config"""
|
||||
|
||||
name = "authentik.stages.identification"
|
||||
label = "authentik_stages_identification"
|
||||
verbose_name = "authentik Stages.Identification"
|
||||
default = True
|
||||
|
@ -1,11 +1,12 @@
|
||||
"""authentik invitation stage app config"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikStageInvitationConfig(AppConfig):
|
||||
class AuthentikStageInvitationConfig(ManagedAppConfig):
|
||||
"""authentik invitation stage config"""
|
||||
|
||||
name = "authentik.stages.invitation"
|
||||
label = "authentik_stages_invitation"
|
||||
verbose_name = "authentik Stages.Invitation"
|
||||
default = True
|
||||
|
@ -1,11 +1,12 @@
|
||||
"""authentik core app config"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikStagePasswordConfig(AppConfig):
|
||||
class AuthentikStagePasswordConfig(ManagedAppConfig):
|
||||
"""authentik password stage config"""
|
||||
|
||||
name = "authentik.stages.password"
|
||||
label = "authentik_stages_password"
|
||||
verbose_name = "authentik Stages.Password"
|
||||
default = True
|
||||
|
@ -1,11 +1,12 @@
|
||||
"""authentik prompt stage app config"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikStagePromptConfig(AppConfig):
|
||||
class AuthentikStagePromptConfig(ManagedAppConfig):
|
||||
"""authentik prompt stage config"""
|
||||
|
||||
name = "authentik.stages.prompt"
|
||||
label = "authentik_stages_prompt"
|
||||
verbose_name = "authentik Stages.Prompt"
|
||||
default = True
|
||||
|
@ -1,11 +1,12 @@
|
||||
"""authentik redirect app"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikStageRedirectConfig(AppConfig):
|
||||
class AuthentikStageRedirectConfig(ManagedAppConfig):
|
||||
"""authentik redirect app"""
|
||||
|
||||
name = "authentik.stages.redirect"
|
||||
label = "authentik_stages_redirect"
|
||||
verbose_name = "authentik Stages.Redirect"
|
||||
default = True
|
||||
|
@ -1,11 +1,12 @@
|
||||
"""authentik delete stage app config"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikStageUserDeleteConfig(AppConfig):
|
||||
class AuthentikStageUserDeleteConfig(ManagedAppConfig):
|
||||
"""authentik delete stage config"""
|
||||
|
||||
name = "authentik.stages.user_delete"
|
||||
label = "authentik_stages_user_delete"
|
||||
verbose_name = "authentik Stages.User Delete"
|
||||
default = True
|
||||
|
@ -1,11 +1,12 @@
|
||||
"""authentik login stage app config"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikStageUserLoginConfig(AppConfig):
|
||||
class AuthentikStageUserLoginConfig(ManagedAppConfig):
|
||||
"""authentik login stage config"""
|
||||
|
||||
name = "authentik.stages.user_login"
|
||||
label = "authentik_stages_user_login"
|
||||
verbose_name = "authentik Stages.User Login"
|
||||
default = True
|
||||
|
@ -1,11 +1,12 @@
|
||||
"""authentik logout stage app config"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikStageUserLogoutConfig(AppConfig):
|
||||
class AuthentikStageUserLogoutConfig(ManagedAppConfig):
|
||||
"""authentik logout stage config"""
|
||||
|
||||
name = "authentik.stages.user_logout"
|
||||
label = "authentik_stages_user_logout"
|
||||
verbose_name = "authentik Stages.User Logout"
|
||||
default = True
|
||||
|
@ -1,11 +1,12 @@
|
||||
"""authentik write stage app config"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikStageUserWriteConfig(AppConfig):
|
||||
class AuthentikStageUserWriteConfig(ManagedAppConfig):
|
||||
"""authentik write stage config"""
|
||||
|
||||
name = "authentik.stages.user_write"
|
||||
label = "authentik_stages_user_write"
|
||||
verbose_name = "authentik Stages.User Write"
|
||||
default = True
|
||||
|
@ -35,6 +35,7 @@ class AuthentikTasksConfig(ManagedAppConfig):
|
||||
broker.add_middleware(Pipelines())
|
||||
broker.add_middleware(Retries(max_retries=max_retries))
|
||||
broker.add_middleware(Results(backend=PostgresBackend(), store_results=True))
|
||||
|
||||
broker.add_middleware(FullyQualifiedActorName())
|
||||
broker.add_middleware(CurrentTask())
|
||||
|
||||
|
@ -319,20 +319,29 @@ class _PostgresConsumer(Consumer):
|
||||
|
||||
@raise_connection_error
|
||||
def requeue(self, messages: Iterable[Message]):
|
||||
for message in messages:
|
||||
self.unlock_queue.put_nowait(message)
|
||||
self.query_set.filter(
|
||||
message_id__in=[message.message_id for message in messages],
|
||||
).update(
|
||||
state=TaskState.QUEUED,
|
||||
)
|
||||
# We don't care about locks, requeue occurs on worker stop
|
||||
# TODO: this is not true, we need to handle them
|
||||
for message in messages:
|
||||
self.in_processing.remove(message.message_id)
|
||||
self._purge_locks()
|
||||
|
||||
def _fetch_pending_notifies(self) -> list[Notify]:
|
||||
self.logger.debug(f"Polling for lost messages in {self.queue_name}")
|
||||
notifies = self.query_set.filter(
|
||||
state__in=(TaskState.QUEUED, TaskState.CONSUMED),
|
||||
queue_name=self.queue_name,
|
||||
).values_list("message_id", flat=True)
|
||||
notifies = (
|
||||
self.query_set.filter(
|
||||
state__in=(TaskState.QUEUED, TaskState.CONSUMED),
|
||||
queue_name=self.queue_name,
|
||||
)
|
||||
.exclude(
|
||||
message_id__in=self.in_processing,
|
||||
)
|
||||
.values_list("message_id", flat=True)
|
||||
)
|
||||
channel = channel_name(self.queue_name, ChannelIdentifier.ENQUEUE)
|
||||
return [Notify(pid=0, channel=channel, payload=item) for item in notifies]
|
||||
|
||||
@ -383,7 +392,7 @@ class _PostgresConsumer(Consumer):
|
||||
|
||||
processing = len(self.in_processing)
|
||||
if processing >= self.prefetch:
|
||||
# Wait and don't consume the message, other worker will be fast
|
||||
# Wait and don't consume the message, other worker will be faster
|
||||
self.misses, backoff_ms = compute_backoff(self.misses, max_backoff=1000)
|
||||
self.logger.debug(
|
||||
f"Too many messages in processing: {processing}. Sleeping {backoff_ms} ms"
|
||||
|
@ -1,6 +1,7 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.utils.module_loading import module_has_submodule
|
||||
|
||||
@ -48,7 +49,7 @@ class Command(BaseCommand):
|
||||
):
|
||||
executable_name = "dramatiq-gevent" if use_gevent else "dramatiq"
|
||||
executable_path = self._resolve_executable(executable_name)
|
||||
watch_args = ["--watch", "."] if use_watcher else []
|
||||
watch_args = ["--watch", "."] if use_watcher or settings.DEBUG else []
|
||||
if watch_args and use_polling_watcher:
|
||||
watch_args.append("--watch-use-polling")
|
||||
|
||||
|
@ -35,8 +35,8 @@ class ScheduleSerializer(ModelSerializer):
|
||||
try:
|
||||
actor: Actor = get_broker().get_actor(instance.actor_name)
|
||||
except ActorNotFound:
|
||||
return None
|
||||
return actor.fn.__doc__
|
||||
return "FIXME this shouldn't happen"
|
||||
return actor.fn.__doc__.strip()
|
||||
|
||||
|
||||
class ScheduleViewSet(
|
||||
|
@ -1,4 +1,5 @@
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
from authentik.lib.utils.reflection import get_apps
|
||||
from authentik.tasks.schedules.lib import ScheduleSpec
|
||||
|
||||
|
||||
@ -21,3 +22,26 @@ class AuthentikTasksSchedulesConfig(ManagedAppConfig):
|
||||
spec.rel_obj = obj
|
||||
schedules.append(spec)
|
||||
return schedules
|
||||
|
||||
def _reconcile_schedules(self, specs: list[ScheduleSpec]):
|
||||
from django.db import transaction
|
||||
|
||||
from authentik.tasks.schedules.models import Schedule
|
||||
|
||||
with transaction.atomic():
|
||||
pks_to_keep = []
|
||||
for spec in specs:
|
||||
schedule = spec.update_or_create()
|
||||
pks_to_keep.append(schedule.pk)
|
||||
Schedule.objects.exclude(pk__in=pks_to_keep).delete()
|
||||
|
||||
@ManagedAppConfig.reconcile_tenant
|
||||
def reconcile_tenant_schedules(self):
|
||||
from authentik.tenants.utils import get_current_tenant, get_public_schema_name
|
||||
|
||||
schedule_specs = []
|
||||
for app in get_apps():
|
||||
schedule_specs.extend(app.tenant_schedule_specs)
|
||||
if get_current_tenant().schema_name == get_public_schema_name():
|
||||
schedule_specs.extend(app.global_schedule_specs)
|
||||
self._reconcile_schedules(schedule_specs)
|
||||
|
@ -1,14 +1,10 @@
|
||||
import os
|
||||
import sys
|
||||
import warnings
|
||||
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
from defusedxml import defuse_stdlib
|
||||
from django.utils.autoreload import DJANGO_AUTORELOAD_ENV
|
||||
|
||||
from authentik.lib.config import CONFIG
|
||||
from lifecycle.migrate import run_migrations
|
||||
from lifecycle.wait_for_db import wait_for_db
|
||||
|
||||
warnings.filterwarnings("ignore", "SelectableGroups dict interface")
|
||||
warnings.filterwarnings(
|
||||
@ -25,21 +21,15 @@ defuse_stdlib()
|
||||
if CONFIG.get_bool("compliance.fips.enabled", False):
|
||||
backend._enable_fips()
|
||||
|
||||
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "authentik.root.settings")
|
||||
wait_for_db()
|
||||
print(sys.argv)
|
||||
if (
|
||||
len(sys.argv) > 1
|
||||
# Explicitly only run migrate for server and worker
|
||||
# `bootstrap_tasks` is a special case as that command might be triggered by the `ak`
|
||||
# script to pre-run certain tasks for an automated install
|
||||
and sys.argv[1] in ["dev_server", "worker", "bootstrap_tasks"]
|
||||
# and don't run if this is the child process of a dev_server
|
||||
and os.environ.get(DJANGO_AUTORELOAD_ENV, None) is None
|
||||
):
|
||||
run_migrations()
|
||||
|
||||
import django # noqa: E402
|
||||
|
||||
django.setup()
|
||||
|
||||
from authentik.root.signals import post_startup, pre_startup, startup # noqa: E402
|
||||
|
||||
_startup_sender = type("WorkerStartup", (object,), {})
|
||||
pre_startup.send(sender=_startup_sender)
|
||||
startup.send(sender=_startup_sender)
|
||||
post_startup.send(sender=_startup_sender)
|
||||
|
@ -108,6 +108,7 @@ func NewWebServer() *WebServer {
|
||||
func (ws *WebServer) Start() {
|
||||
go ws.runMetricsServer()
|
||||
go ws.attemptStartBackend()
|
||||
go ws.attemptStartWorker()
|
||||
go ws.listenPlain()
|
||||
go ws.listenTLS()
|
||||
}
|
||||
@ -137,6 +138,12 @@ func (ws *WebServer) attemptStartBackend() {
|
||||
}
|
||||
}
|
||||
|
||||
func (ws *WebServer) attemptStartWorker() {
|
||||
if ws.worker == nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (ws *WebServer) Core() *gounicorn.GoUnicorn {
|
||||
return ws.g
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ type Worker struct {
|
||||
}
|
||||
|
||||
func New(healthcheck func() bool) *Worker {
|
||||
logger := log.WithField("logger", "authentik.router.unicorn")
|
||||
logger := log.WithField("logger", "authentik.router.worker")
|
||||
w := &Worker{
|
||||
Healthcheck: healthcheck,
|
||||
log: logger,
|
||||
|
Reference in New Issue
Block a user