job-hunter: weekly above-target Slack alert CronJob
Add job-hunter-alert CronJob (Sundays 05:00 UTC, an hour after the refresh): `python -m job_hunter alert --threshold 500000 --location london --slack` posts to Slack the companies whose London p50 total comp >= £500k, flagging any that newly crossed since last week's snapshot. SLACK_WEBHOOK_URL wired via the job-hunter-secrets ExternalSecret from Vault secret/job-hunter slack_webhook_url (seeded from the shared workspace webhook; repointable to a dedicated channel). Runbook gains an "above-target Slack alert" section. [ci skip] — applied locally (stack-scoped). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
5dc5cd53c0
commit
74313149dd
3 changed files with 112 additions and 0 deletions
|
|
@ -164,6 +164,31 @@ Grafana datasource password is mirrored via a second ExternalSecret in the
|
||||||
|
|
||||||
## ANALYST
|
## ANALYST
|
||||||
|
|
||||||
|
### Weekly above-target Slack alert
|
||||||
|
|
||||||
|
The `job-hunter-alert` CronJob (Sundays 05:00 UTC, an hour after the refresh)
|
||||||
|
posts to Slack the companies whose London p50 total comp **≥ £500k**, flagging
|
||||||
|
any that **newly crossed** since last week's snapshot. Threshold is the
|
||||||
|
`--threshold` arg in `cronjob.tf` (default 500000 — well above the ~£267k move
|
||||||
|
floor, so only clearly-exceptional comp pings). Slack webhook comes from Vault
|
||||||
|
`secret/job-hunter` → `slack_webhook_url` (seeded from the shared workspace
|
||||||
|
webhook → currently posts to the same channel as Keel; repoint to a dedicated
|
||||||
|
channel by `vault kv patch secret/job-hunter slack_webhook_url=<url>`).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Preview the message without posting
|
||||||
|
kubectl -n job-hunter exec deploy/job-hunter -- python -m job_hunter alert --stdout
|
||||||
|
# Different bar / location
|
||||||
|
kubectl -n job-hunter exec deploy/job-hunter -- \
|
||||||
|
python -m job_hunter alert --threshold 350000 --location london --stdout
|
||||||
|
# Fire it now (posts to Slack)
|
||||||
|
kubectl -n job-hunter create job --from=cronjob/job-hunter-alert jh-alert-manual
|
||||||
|
```
|
||||||
|
|
||||||
|
`newly_crossed` needs ≥2 snapshot dates — it's empty until the second weekly
|
||||||
|
run accumulates. To change the standing threshold, edit `--threshold` in
|
||||||
|
`infra/stacks/job-hunter/cronjob.tf` and apply.
|
||||||
|
|
||||||
### The periodic "market leaders in comp" report
|
### The periodic "market leaders in comp" report
|
||||||
|
|
||||||
This is the headline command — current leaders by p50 total comp, week-over-week
|
This is the headline command — current leaders by p50 total comp, week-over-week
|
||||||
|
|
|
||||||
|
|
@ -111,3 +111,83 @@ resource "kubernetes_cron_job_v1" "job_hunter_refresh" {
|
||||||
kubernetes_manifest.db_external_secret,
|
kubernetes_manifest.db_external_secret,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Weekly above-target comp alert. Runs an hour after the refresh (so it reads
|
||||||
|
# fresh data + the just-written snapshot) and posts to Slack the companies whose
|
||||||
|
# London p50 total comp >= £500k, flagging any that newly crossed since last
|
||||||
|
# week's snapshot. Read-only query + a Slack POST — no init/migrate needed.
|
||||||
|
resource "kubernetes_cron_job_v1" "job_hunter_alert" {
|
||||||
|
metadata {
|
||||||
|
name = "job-hunter-alert"
|
||||||
|
namespace = kubernetes_namespace.job_hunter.metadata[0].name
|
||||||
|
labels = local.labels
|
||||||
|
}
|
||||||
|
spec {
|
||||||
|
schedule = "0 5 * * 0"
|
||||||
|
concurrency_policy = "Forbid"
|
||||||
|
successful_jobs_history_limit = 3
|
||||||
|
failed_jobs_history_limit = 3
|
||||||
|
starting_deadline_seconds = 600
|
||||||
|
|
||||||
|
job_template {
|
||||||
|
metadata {
|
||||||
|
labels = local.labels
|
||||||
|
}
|
||||||
|
spec {
|
||||||
|
backoff_limit = 2
|
||||||
|
active_deadline_seconds = 300
|
||||||
|
ttl_seconds_after_finished = 86400
|
||||||
|
|
||||||
|
template {
|
||||||
|
metadata {
|
||||||
|
labels = local.labels
|
||||||
|
}
|
||||||
|
spec {
|
||||||
|
restart_policy = "OnFailure"
|
||||||
|
image_pull_secrets {
|
||||||
|
name = "registry-credentials"
|
||||||
|
}
|
||||||
|
container {
|
||||||
|
name = "alert"
|
||||||
|
image = local.image
|
||||||
|
image_pull_policy = "Always"
|
||||||
|
command = ["python", "-m", "job_hunter", "alert",
|
||||||
|
"--threshold", "500000", "--location", "london", "--slack"]
|
||||||
|
|
||||||
|
env_from {
|
||||||
|
secret_ref {
|
||||||
|
name = "job-hunter-secrets"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
env_from {
|
||||||
|
secret_ref {
|
||||||
|
name = "job-hunter-db-creds"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resources {
|
||||||
|
requests = {
|
||||||
|
cpu = "50m"
|
||||||
|
memory = "256Mi"
|
||||||
|
}
|
||||||
|
limits = {
|
||||||
|
memory = "512Mi"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lifecycle {
|
||||||
|
# KYVERNO_LIFECYCLE_V1
|
||||||
|
ignore_changes = [spec[0].job_template[0].spec[0].template[0].spec[0].dns_config]
|
||||||
|
}
|
||||||
|
|
||||||
|
depends_on = [
|
||||||
|
kubernetes_manifest.external_secret,
|
||||||
|
kubernetes_manifest.db_external_secret,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,13 @@ resource "kubernetes_manifest" "external_secret" {
|
||||||
secretKey = "DIGEST_FROM_ADDRESS"
|
secretKey = "DIGEST_FROM_ADDRESS"
|
||||||
remoteRef = { key = "job-hunter", property = "digest_from_address" }
|
remoteRef = { key = "job-hunter", property = "digest_from_address" }
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
# Weekly above-target comp alert (job-hunter-alert CronJob). Seeded
|
||||||
|
# from the shared workspace webhook; repoint to a dedicated channel
|
||||||
|
# by updating secret/job-hunter slack_webhook_url.
|
||||||
|
secretKey = "SLACK_WEBHOOK_URL"
|
||||||
|
remoteRef = { key = "job-hunter", property = "slack_webhook_url" }
|
||||||
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue