Webhook icon
Schedule icon
WorkingDirectory icon
Commands icon
Docker icon
Script icon
If icon
SlackIncomingWebhook icon
Fail icon
Log icon

Gate Artifactory Quotas and Retention Before Artifacts Vanish

Score an Artifactory storage report for repositories over quota and artifacts past retention with live references, alert Slack, and gate the run.

Categories
Infrastructure

How it works

  1. post_storage_report (io.kestra.plugin.core.trigger.Webhook, keyed with the ARTIFACTORY_REPORT_WEBHOOK_KEY secret) receives the storage report JSON from your Artifactory export job right after each quota snapshot. daily_quota_sweep (io.kestra.plugin.core.trigger.Schedule, cron 0 6 * * *) is the safety net and ships disabled: true until an operator turns it on.
  2. quota_workspace (io.kestra.plugin.core.flow.WorkingDirectory) opens one shared directory so the staged report and the scorer see the same file, because default tasks are stateless and a temp dir is purged when a task completes.
  3. stage_storage_report (io.kestra.plugin.scripts.shell.Commands on the io.kestra.plugin.scripts.runner.docker.Docker runner, image alpine:3.20) stores the posted body when one arrived and otherwise writes storage_report.json with a quoted heredoc. The bundled report holds four repositories, two over the quota threshold, one old artifact past retention without references and two past retention that services still call.
  4. evaluate_quotas (io.kestra.plugin.scripts.python.Script on python:3.12-slim) flags a repository as over quota when its usage percentage meets quota_threshold_pct (deriving the percentage from used and quota gigabytes when the field is missing), and flags an artifact as at risk only when its age passes retention_days and its downstream_references count is still above zero, so a retention sweep that only reclaims orphaned bytes never pages anyone. The verdict, the offenders and the worst usage are printed as a single ::{"outputs": ...}:: line.
  5. violation_gate (io.kestra.plugin.core.flow.If) branches on a parseable report that carries violations. Violations reach alert_violations (io.kestra.plugin.slack.notifications.SlackIncomingWebhook) with the offender lists, then enforce_quota_gate (io.kestra.plugin.core.flow.If) applies the fail_on_violations policy with fail_execution (io.kestra.plugin.core.execution.Fail) or the report only log_gate_softened. A clean report lands on log_within_policy, and an unreadable report routes through check_report_health and alert_unreadable_report instead of reading as compliance.
  6. The flow level errors handler (io.kestra.plugin.slack.notifications.SlackIncomingWebhook) reports any failure with the execution id, because a gate that dies silently is indistinguishable from a quiet instance.

What you get

  • One gateable verdict, quota and retention violations found or not, that any export pipeline can branch on.
  • Offender lists that name the exact repositories over quota and the exact artifact paths past retention with live references, not just counts.
  • A retention rule that distinguishes dangerous deletions from harmless cleanup by checking downstream references.
  • violations_found, over_quota_repos, at_risk_artifacts and worst_usage_pct as typed outputs for ticket automation and capacity reports.
  • A disabled daily sweep as a second net once the webhook path is trusted.

Who it's for

  • Platform teams running shared Artifactory instances who need quotas enforced before the disk fills.
  • Release engineers who have seen retention rules delete artifacts that a still deployed service resolves at startup.
  • FinOps reviewers who want storage consumption evidence attached to executions instead of buried in an export job log.

Why orchestrate this with Kestra

Artifactory reports usage but never gates anything on it, so quota overflow and risky retention wait for someone to open the storage page. Kestra gives the export job a webhook to land on, a shared workspace where the fixture and the scorer read one file, threshold policy as version controlled inputs, a branch that separates escalation from the all clear, and outputs a ticket or capacity report can consume. A cron job on the export host gives you none of that, it only prints a summary nobody triages.

Prerequisites

  • A worker with Docker access, the fixture runs in alpine:3.20 and the scorer in python:3.12-slim.
  • An export step that POSTs a storage report shaped as a repos array whose entries carry key, usage_pct or used and quota gigabytes, and an oldest_artifacts array with path, age_days and downstream_references, for example assembled from the Artifactory storage stats API.
  • A Slack incoming webhook for the violation alert, the unreadable report alert and failure alerts.

Secrets

  • ARTIFACTORY_REPORT_WEBHOOK_KEY: key segment guarding the storage report webhook URL, anyone holding it can trigger a grading run.
  • SLACK_WEBHOOK_URL: Slack incoming webhook for the violation alert, the unreadable report alert and failure alerts.

Quick start

  1. Add the two secrets to your Kestra namespace.
  2. Run the flow once with the default inputs and confirm violations_found reads true, over_quota_count lands at 2 with docker-prod-local and npm-virtual, at_risk_count lands at 2, worst_usage_pct reads 97.4, and the Slack alert arrived.
  3. Set fail_on_violations to false and re-run to watch log_gate_softened keep the execution green while the alert still fires.
  4. Point your export job at /api/v1/{tenant}/executions/webhook/{namespace}/jfrog-artifactory-quota-and-retention-gate/{ARTIFACTORY_REPORT_WEBHOOK_KEY}, and enable daily_quota_sweep once the path is trusted.

How to extend

  • Replace the staged fixture with an io.kestra.plugin.core.http.Request that pulls the live storage report from the Artifactory storage stats API with an ARTIFACTORY_TOKEN secret before scoring, keeping the heredoc as the offline fallback.
  • Add a per repository grace period by extending the scorer with a first_over_quota_seen field so a repo gets warned at 90 percent and failed only after two consecutive sweeps.
  • Archive every graded report to object storage with io.kestra.plugin.aws.s3.Upload to build a capacity evidence trail for FinOps reviews.
  • Fan out across Artifactory instances with io.kestra.plugin.core.flow.ForEachItem over an instance list, each subflow grading one instance of its own.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.