Compare commits
49 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 411ee92106 | |||
| 7cfcd0f46b | |||
| 2f249a9e18 | |||
| cea4658b91 | |||
| c5a8f9f58c | |||
| 8e64a9e2ac | |||
| 348baf96bb | |||
| cb9909172b | |||
| 38cddd6dfc | |||
| cd0ed86571 | |||
| cb4c0649f5 | |||
| 1a1a109aa3 | |||
| b616e11bdf | |||
| 618d1acd68 | |||
| 459fc99f31 | |||
| e470826a78 | |||
| c5947359c5 | |||
| 5555c7524b | |||
| 8c46feb1c6 | |||
| 28878773dd | |||
| c71651d4a2 | |||
| 636d68ced5 | |||
| b62bf046f6 | |||
| 181b9f9501 | |||
| d465c26832 | |||
| 49af1e73a6 | |||
| d9a13d8c29 | |||
| 04102c75a4 | |||
| 3860b44dc5 | |||
| 94631c18d0 | |||
| c394c0c563 | |||
| 886d8e73d3 | |||
| 43f5d5ef60 | |||
| a0620ea391 | |||
| 8902feada7 | |||
| 13ce96e07e | |||
| fe9d867a87 | |||
| 9ad73f3741 | |||
| e72a845c31 | |||
| b371c39c13 | |||
| 33c6007899 | |||
| 9a1639ff4f | |||
| 4ab65ca4dd | |||
| 7311df25bc | |||
| 53466186b8 | |||
| 8d5ae5ee31 | |||
| 82c9f70a01 | |||
| 68a1524dca | |||
| bf19fb1cf5 |
@@ -0,0 +1,21 @@
|
||||
# Smoke test: confirms Gitea Act Runner is online and accepting jobs.
|
||||
# Run manually via workflow_dispatch after runner is registered (#77).
|
||||
# Closes leeworks-agents/api-company#96
|
||||
|
||||
name: Runner Smoke Test
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
smoke:
|
||||
name: Smoke Test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Confirm runner is online
|
||||
run: |
|
||||
echo "Runner is online!"
|
||||
echo "Job ID: $GITHUB_JOB"
|
||||
echo "Runner OS: $(uname -a)"
|
||||
echo "Date: $(date -u)"
|
||||
echo "Smoke test PASSED"
|
||||
@@ -0,0 +1,21 @@
|
||||
name: Validate Flux manifests
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [main]
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
kustomize-build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install kustomize
|
||||
run: |
|
||||
curl -sL "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
|
||||
sudo mv kustomize /usr/local/bin/
|
||||
|
||||
- name: kustomize build flux/
|
||||
run: kustomize build flux/ > /dev/null
|
||||
@@ -1,6 +1,6 @@
|
||||
# Company Status
|
||||
|
||||
_Last updated: 2026-05-26 (agent cycle — afternoon)_
|
||||
_Last updated: 2026-05-28 (agent cycle — cycle-2 triage)_
|
||||
|
||||
## APIs
|
||||
| API | Spec | Code | Deployed | Listed on RapidAPI | Paying Users | MRR |
|
||||
@@ -18,9 +18,68 @@ Legend: [x]=done, [~]=in-progress, [ ]=not started
|
||||
- **Container registry:** Gitea built-in registry selected; docs/registry.md committed — PENDING Gitea packages enabled (issue #4)
|
||||
- **Prometheus + Grafana:** Flux HelmRelease at `flux/monitoring/` — PENDING Flux wiring + Grafana secret (issue #7)
|
||||
- **Gatus status page:** Flux HelmRelease at `flux/monitoring/gatus-helmrelease.yaml` — PENDING Flux wiring (issue #8)
|
||||
- **API service manifests (NEW):** `flux/zip-enrichment/`, `flux/holidays/`, `flux/air-quality/` scaffolded (PR #48, closes #46)
|
||||
- **API service manifests:** `flux/zip-enrichment/`, `flux/holidays/`, `flux/air-quality/` scaffolded (PR #48, closes #46)
|
||||
- **Image automation:** `flux/image-automation/` — ImageRepository + ImagePolicy + ImageUpdateAutomation for all three APIs
|
||||
|
||||
## Completed This Cycle (2026-05-26 PM)
|
||||
## Completed This Cycle (2026-05-28 — Cycle-2 Triage)
|
||||
- **#83** — Triaged: `GITEA_TOKEN` Actions secrets needed in `zip-enrichment`, `holidays`, `air-quality` repos. Manual operator task; reuse token from #74 if it has `write:package` scope. Step-by-step instructions posted.
|
||||
- **No open PRs** — queue empty.
|
||||
- **`kustomize build flux/` = PASS** — no regressions.
|
||||
- **Upstream `0xWheatyz/api-company`** — still does not exist; fork sync skipped (blocker #47).
|
||||
|
||||
## Completed Previous Cycle (2026-05-28 — Late-Night Triage)
|
||||
- **#79** — Triaged: `gitea-registry` imagePullSecret needed in 4 namespaces. Manual operator task; kubectl docker-registry secret instructions posted.
|
||||
- **#80** — Triaged: `gitea-image-automation-token` secret needed in `flux-system`. Manual operator task; write-scoped PAT required, kubectl instructions posted.
|
||||
- **#81** — Triaged: `rapidapi-proxy-secret` needed in `zip-enrichment`, `holidays`, `air-quality`. Manual operator task; placeholder + real-secret commands posted.
|
||||
- **No open PRs** — queue empty.
|
||||
- **`kustomize build flux/` = PASS** — no regressions.
|
||||
|
||||
## Completed Previous Cycle (2026-05-28 — Night Triage)
|
||||
- **#76** — Triaged: `gitea-leeworks-agents-token` secret required in `flux-system` to unblock Flux GitRepository auth. Manual operator task; kubectl instructions + reconcile steps posted in issue comment.
|
||||
- **#77** — Triaged: `gitea-runner-token` secret required in `gitea-runner` namespace to register Act Runner. Manual operator task; full step-by-step instructions posted in issue comment.
|
||||
- **No open PRs** — queue empty.
|
||||
- **`kustomize build flux/` = PASS** — no regressions.
|
||||
|
||||
## Completed Previous Cycle (2026-05-28 — Evening Triage)
|
||||
- **#74** — Triaged: `GITEA_TOKEN` Actions secret required in leeworks-agents/api-company for docs-site CI. Manual operator task; instructions posted.
|
||||
- **#73** — Triaged: `gatus-slack-webhook` secret required in `monitoring` namespace. Manual operator task; kubectl instructions posted.
|
||||
- **#67** — Confirmed already resolved: `docs/operator-runbook.md` and `docs/dns.md` both list all 7 subdomains incl. `grafana.leeworks.dev` (PR #63). No code change needed.
|
||||
- **No open PRs** — queue empty.
|
||||
- **`kustomize build flux/` = PASS** — no regressions.
|
||||
|
||||
## Completed Previous Cycle (2026-05-28 — Morning Triage)
|
||||
- **#69 → PR #71 MERGED** — Added `.gitea/workflows/validate-flux.yaml` CI workflow: runs `kustomize build flux/` on every PR and push to `main`. CI gate enforced once Act Runner (#3) is online.
|
||||
- **#70** — Triaged: `grafana-admin` secret needed in `monitoring` namespace. Manual operator task; kubectl instructions posted in issue comment.
|
||||
- **#67** — Confirmed `docs/operator-runbook.md` Phase 4 DNS table already lists all 7 subdomains including grafana.leeworks.dev. No code change needed.
|
||||
- **#66** — Blocked on Phase 0 operator actions (#47, #2, #3, #4). Status comment posted.
|
||||
- **#47, #2, #3, #4, #7, #8, #16, #17, #18, #19, #27, #30, #33, #44** — Status comments posted confirming blocked/awaiting-operator state.
|
||||
- **No open PRs to review** — queue empty after PR #71 merged.
|
||||
- **`kustomize build flux/` = PASS** — no regressions.
|
||||
|
||||
## Completed Previous Cycle (2026-05-27 — Evening Triage)
|
||||
- **Triage pass** — all 15 open agent-ready issues reviewed; status comments posted on each.
|
||||
- **No open PRs** — nothing to merge or review.
|
||||
- **No new feature work** — all issues remain blocked on operator actions or cross-repo prerequisites.
|
||||
- **`kustomize build flux/` = PASS** — no regressions.
|
||||
|
||||
## Completed Previous Cycle (2026-05-27 — Ship/Afternoon)
|
||||
- **PRs reviewed** — 0 open PRs on fork; nothing to merge.
|
||||
- **Upstream sync** — `0xWheatyz/api-company` does not yet exist (blocker #41/#47); `git fetch upstream` failed as expected. Fork `origin/main` is current (SHA `9a1639f`).
|
||||
- **`kustomize build flux/` = PASS** — all sub-trees validate cleanly; no regressions.
|
||||
- **Deployment PR** — skipped; upstream repo must be created by operator first (#41, #47).
|
||||
- **No new feature work** — all 15 open agent-ready issues remain blocked on operator actions.
|
||||
|
||||
## Completed Previous Cycle (2026-05-27 — Morning)
|
||||
- **Triage pass** — all 15 open agent-ready issues reviewed; status comments posted/confirmed on each.
|
||||
- **#19** — First triage comment posted: RapidAPI/PayPal operator task fully documented; all agent-side prerequisites (OpenAPI specs, listing copy, proxy-secret placeholders) confirmed ready.
|
||||
- **No PRs to review** — fork had no open PRs.
|
||||
- **No new feature work** — all open issues blocked on operator actions.
|
||||
|
||||
## Completed Previous Cycle (2026-05-26 Evening)
|
||||
- **#50** — `docs/operator-runbook.md` added: ordered phase-by-phase manual for operator. PR #52 merged.
|
||||
- **#51** — Flux image automation: `ImageRepository` + `ImagePolicy` + `ImageUpdateAutomation` for all three API services; setter markers added to HelmReleases. PR #52 merged. `kustomize build flux/ = PASS`.
|
||||
|
||||
## Completed Previous Cycle (2026-05-26 PM)
|
||||
- **#46** — Scaffolded Flux deployment manifests for all three API services (zip-enrichment, holidays, air-quality). PR #48 merged.
|
||||
|
||||
## Completed Previous Cycle (2026-05-26 AM)
|
||||
@@ -33,19 +92,22 @@ Legend: [x]=done, [~]=in-progress, [ ]=not started
|
||||
- **#34** — Cluster audit PR merged
|
||||
|
||||
## Flux Manifests (kustomize build flux/ = PASS)
|
||||
All flux manifests validate successfully. Deployed components pending Flux activation:
|
||||
All flux manifests validate successfully. Committed components pending Flux activation:
|
||||
- `gitea-runner` namespace + HelmRelease (gitea-act-runner chart)
|
||||
- `monitoring` namespace + kube-prometheus-stack HelmRelease
|
||||
- `monitoring` Gatus HelmRelease (status.leeworks.dev, 90-day retention)
|
||||
- `docs-site` HelmRelease (docs.leeworks.dev)
|
||||
- `zip-enrichment` namespace + HelmRelease (zip.leeworks.dev) + rapidapi-proxy-secret placeholder ← NEW
|
||||
- `holidays` namespace + HelmRelease (holidays.leeworks.dev) + rapidapi-proxy-secret placeholder ← NEW
|
||||
- `air-quality` namespace + HelmRelease (aqi.leeworks.dev) + rapidapi-proxy-secret placeholder ← NEW
|
||||
- `zip-enrichment` namespace + HelmRelease (zip.leeworks.dev) + rapidapi-proxy-secret placeholder
|
||||
- `holidays` namespace + HelmRelease (holidays.leeworks.dev) + rapidapi-proxy-secret placeholder
|
||||
- `air-quality` namespace + HelmRelease (aqi.leeworks.dev) + rapidapi-proxy-secret placeholder
|
||||
- `image-automation` ImageRepository + ImagePolicy + ImageUpdateAutomation for all three APIs
|
||||
|
||||
## Blockers (human operator action required)
|
||||
1. **Create `0xWheatyz/api-company` repo on Gitea** — every ship cycle fails until this exists (#41, #47)
|
||||
1. **Create `0xWheatyz/api-company` repo on Gitea** — every ship cycle fails until this exists (#41, #47) **<-- DO THIS FIRST**
|
||||
2. **Add api-company GitRepository+Kustomization to 0xWheatyz/Talos** at `testing1/first-cluster/cluster/flux/` — reference manifests ready in `flux/api-company-source/` (#2)
|
||||
3. **Create `gitea-leeworks-agents-token` secret** in `flux-system` namespace (HTTPS token for Gitea)
|
||||
4. **Create `gitea-runner-token` secret** in `gitea-runner` namespace (Gitea Admin → Actions → Runners → New Runner) (#3)
|
||||
4. **Create `gitea-runner-token` secret** in `gitea-runner` namespace (Gitea Admin -> Actions -> Runners -> New Runner) (#3)
|
||||
5. **Enable Gitea packages** (for container registry at `registry.leeworks.dev`) (#4)
|
||||
6. **RapidAPI + PayPal setup** — manual, gated on operator turning 18 (#19, #44)
|
||||
|
||||
> Full ordered runbook with copy-paste commands: `docs/operator-runbook.md`
|
||||
|
||||
@@ -31,6 +31,7 @@ const { title, description = "leeworks.dev API documentation" } = Astro.props;
|
||||
<a href="/zip-enrichment">ZIP Enrichment</a>
|
||||
<a href="/holidays">Holidays</a>
|
||||
<a href="/air-quality">Air Quality</a>
|
||||
<a href="/pricing">Pricing</a>
|
||||
<a href="/blog">Blog</a>
|
||||
<a href="https://rapidapi.com/leeworks" target="_blank" rel="noopener">RapidAPI</a>
|
||||
</nav>
|
||||
|
||||
@@ -53,4 +53,14 @@ import Base from '../layouts/Base.astro';
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer style="text-align: center; padding: 2rem; border-top: 1px solid #2d3748; margin-top: 3rem; color: #718096; font-size: 0.875rem;">
|
||||
<p style="margin-bottom: 0.5rem;">© 2026 leeworks.dev — All rights reserved.</p>
|
||||
<nav style="display: flex; gap: 1.5rem; justify-content: center; flex-wrap: wrap;">
|
||||
<a href="/legal/terms-of-service" style="color: #a0aec0; text-decoration: none;">Terms of Service</a>
|
||||
<a href="/legal/privacy-policy" style="color: #a0aec0; text-decoration: none;">Privacy Policy</a>
|
||||
<a href="/legal/acceptable-use-policy" style="color: #a0aec0; text-decoration: none;">Acceptable Use Policy</a>
|
||||
<a href="mailto:legal@leeworks.dev" style="color: #a0aec0; text-decoration: none;">Contact</a>
|
||||
</nav>
|
||||
</footer>
|
||||
</Base>
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
---
|
||||
layout: ../../layouts/Base.astro
|
||||
title: Acceptable Use Policy
|
||||
description: leeworks.dev API Acceptable Use Policy
|
||||
---
|
||||
|
||||
# Acceptable Use Policy
|
||||
|
||||
**Effective Date:** 2026-05-24
|
||||
**Contact:** legal@leeworks.dev
|
||||
|
||||
---
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This Acceptable Use Policy ("AUP") defines the rules for using leeworks.dev APIs. It applies to all users regardless of plan. Violations may result in immediate account suspension.
|
||||
|
||||
## 2. Rate Limits and Abuse
|
||||
|
||||
### 2.1 Respect Your Plan Limits
|
||||
|
||||
Each subscription plan includes defined rate limits:
|
||||
|
||||
| Plan | Requests/min | Requests/month |
|
||||
|------|-------------|---------------|
|
||||
| Free | 10 | 500 |
|
||||
| Basic | 60 | 10,000 |
|
||||
| Pro | 300 | 100,000 |
|
||||
| Ultra | 1,000 | 1,000,000 |
|
||||
|
||||
### 2.2 Prohibited Rate Limit Circumvention
|
||||
|
||||
The following are explicitly prohibited:
|
||||
- Using multiple API keys or accounts to aggregate quota
|
||||
- Caching responses for redistribution beyond your own application
|
||||
- Rotating IP addresses or using proxies to bypass rate limits
|
||||
|
||||
## 3. Prohibited Uses
|
||||
|
||||
You may **not**:
|
||||
- Download or cache the entire dataset backing any API
|
||||
- Resell, sublicense, or redistribute API access to third parties
|
||||
- Build a competing API product that serves our data to others
|
||||
- Use the APIs for any illegal purpose
|
||||
- Attempt to compromise the security or integrity of our systems
|
||||
- Perform denial-of-service attacks against our infrastructure
|
||||
- Probe our systems for vulnerabilities without prior written authorization
|
||||
|
||||
## 4. Acceptable Uses
|
||||
|
||||
The following are examples of acceptable use:
|
||||
- Integrating ZIP code, holiday, or air quality data into your own product
|
||||
- Building dashboards, mobile apps, or internal tools
|
||||
- Academic research (within Free plan limits)
|
||||
- Automated data fetching within your plan's rate limits
|
||||
|
||||
## 5. Enforcement
|
||||
|
||||
We continuously monitor API usage for abuse. Flagged accounts may be throttled, suspended, or permanently terminated for serious violations.
|
||||
|
||||
## 6. Reporting Abuse
|
||||
|
||||
Report misuse to **legal@leeworks.dev** immediately.
|
||||
|
||||
## 7. Contact
|
||||
|
||||
Questions about this policy: **legal@leeworks.dev**
|
||||
@@ -0,0 +1,72 @@
|
||||
---
|
||||
layout: ../../layouts/Base.astro
|
||||
title: Privacy Policy
|
||||
description: leeworks.dev API Privacy Policy
|
||||
---
|
||||
|
||||
# Privacy Policy
|
||||
|
||||
**Effective Date:** 2026-05-24
|
||||
**Contact:** legal@leeworks.dev
|
||||
|
||||
---
|
||||
|
||||
## 1. Overview
|
||||
|
||||
leeworks.dev ("we", "us") operates the ZIP Enrichment, Holidays, and Air Quality APIs. This Privacy Policy describes what data we collect when you use our Services, how we use it, and your rights regarding that data.
|
||||
|
||||
## 2. What Data We Collect
|
||||
|
||||
### 2.1 Request Logs
|
||||
|
||||
When you make API calls, we log:
|
||||
- API key identifier (hashed/truncated — not the full key)
|
||||
- IP address of the requesting client
|
||||
- HTTP method and endpoint path
|
||||
- Response status code
|
||||
- Request timestamp
|
||||
- Response time (latency)
|
||||
|
||||
We do not log the full content of request or response bodies unless required for debugging.
|
||||
|
||||
### 2.2 Account Data (via RapidAPI)
|
||||
|
||||
If you subscribe through RapidAPI, your account data (name, email, billing information) is managed by RapidAPI, not by us. Please review RapidAPI's Privacy Policy at rapidapi.com/privacy.
|
||||
|
||||
### 2.3 Cookies and Tracking
|
||||
|
||||
The API endpoints themselves do not use cookies. Our documentation site (`docs.leeworks.dev`) may use minimal session cookies for navigation only — no analytics or tracking cookies.
|
||||
|
||||
## 3. How We Use Your Data
|
||||
|
||||
We use collected data to monitor API health, detect and prevent abuse, debug issues, generate aggregate usage statistics (anonymized), and respond to support requests.
|
||||
|
||||
**We do not sell your personal data to third parties. Ever.**
|
||||
|
||||
## 4. Data Retention
|
||||
|
||||
| Data Type | Retention Period |
|
||||
|-----------|-----------------|
|
||||
| Request logs (IP + endpoint) | 90 days |
|
||||
| Aggregated usage metrics | 12 months |
|
||||
| Billing records (via RapidAPI) | Per RapidAPI policy |
|
||||
|
||||
## 5. Data Sharing
|
||||
|
||||
We share data only with RapidAPI for billing and subscription management, when required by law, and with hosting infrastructure providers under data processing agreements.
|
||||
|
||||
## 6. Security
|
||||
|
||||
We take reasonable technical and organizational measures to protect your data including HTTPS-only API keys, restricted log access, and Kubernetes RBAC and network policies.
|
||||
|
||||
## 7. Your Rights
|
||||
|
||||
Depending on your jurisdiction, you may have rights to access, delete, or restrict processing of your personal data. Contact legal@leeworks.dev — we will respond within 30 days.
|
||||
|
||||
## 8. Changes to This Policy
|
||||
|
||||
We may update this Privacy Policy periodically. Continued use of the Services after changes constitutes acceptance.
|
||||
|
||||
## 9. Contact
|
||||
|
||||
For privacy inquiries: **legal@leeworks.dev**
|
||||
@@ -0,0 +1,86 @@
|
||||
---
|
||||
layout: ../../layouts/Base.astro
|
||||
title: Terms of Service
|
||||
description: leeworks.dev API Terms of Service
|
||||
---
|
||||
|
||||
# Terms of Service
|
||||
|
||||
**Effective Date:** 2026-05-24
|
||||
**Contact:** legal@leeworks.dev
|
||||
|
||||
---
|
||||
|
||||
## 1. Acceptance of Terms
|
||||
|
||||
By accessing or using any API offered by leeworks.dev ("Services"), you agree to be bound by these Terms of Service. If you do not agree, do not use the Services.
|
||||
|
||||
## 2. Description of Services
|
||||
|
||||
leeworks.dev provides data API services including:
|
||||
- ZIP Enrichment API (`zip.leeworks.dev`)
|
||||
- Holidays API (`holidays.leeworks.dev`)
|
||||
- Air Quality API (`aqi.leeworks.dev`)
|
||||
|
||||
These APIs are offered via RapidAPI and directly. Access requires a valid API key.
|
||||
|
||||
## 3. API Usage Limits
|
||||
|
||||
- Each plan has defined rate limits (requests per minute and per month). Exceeding your plan's limits will result in HTTP 429 responses.
|
||||
- You must not circumvent rate limiting through multiple accounts, shared keys, or other technical means.
|
||||
- Free and Basic plan users are limited to non-commercial use unless explicitly stated otherwise.
|
||||
|
||||
## 4. Prohibited Use
|
||||
|
||||
You may not use the Services to:
|
||||
- Resell or redistribute the API data or API access without written permission
|
||||
- Scrape, download, or replicate the underlying dataset in bulk
|
||||
- Build a competing API product using our data
|
||||
- Violate any applicable laws, including data privacy regulations
|
||||
- Harass, harm, or interfere with other users or our infrastructure
|
||||
|
||||
See also the [Acceptable Use Policy](/legal/acceptable-use-policy).
|
||||
|
||||
## 5. Account Registration and Security
|
||||
|
||||
- You are responsible for keeping your API key confidential.
|
||||
- You are responsible for all activity under your API key.
|
||||
- Notify us immediately at legal@leeworks.dev if you suspect unauthorized use.
|
||||
|
||||
## 6. Payment and Billing
|
||||
|
||||
- Paid plans are billed through RapidAPI according to their billing terms.
|
||||
- Refunds are handled at our discretion on a case-by-case basis. Contact legal@leeworks.dev within 7 days of a charge.
|
||||
- We reserve the right to change pricing with 30 days' notice.
|
||||
|
||||
## 7. Data Accuracy Disclaimer
|
||||
|
||||
The data provided by leeworks.dev APIs is sourced from public datasets. We make no warranty as to the accuracy, completeness, or fitness for any particular purpose. You use the data at your own risk.
|
||||
|
||||
## 8. Service Availability
|
||||
|
||||
- We target 99.9% uptime but make no formal SLA guarantee on free or Basic plans.
|
||||
- We reserve the right to take the service down for maintenance with or without notice.
|
||||
- See status.leeworks.dev for real-time uptime information.
|
||||
|
||||
## 9. Intellectual Property
|
||||
|
||||
- The APIs, documentation, and underlying software are the intellectual property of leeworks.dev.
|
||||
- Response data may be used in your own products subject to these Terms.
|
||||
- You may not claim ownership of the data or present it as proprietary to you.
|
||||
|
||||
## 10. Termination
|
||||
|
||||
We may suspend or terminate your access to the Services immediately, without prior notice, for violation of these Terms, suspected abuse or fraud, or non-payment of applicable fees.
|
||||
|
||||
## 11. Limitation of Liability
|
||||
|
||||
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, LEEWORKS.DEV SHALL NOT BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, OR PUNITIVE DAMAGES, INCLUDING LOSS OF PROFITS, DATA, OR BUSINESS.
|
||||
|
||||
## 12. Changes to Terms
|
||||
|
||||
We may modify these Terms at any time. Continued use of the Services after changes constitutes acceptance.
|
||||
|
||||
## 13. Contact
|
||||
|
||||
Questions about these Terms? Contact us at: **legal@leeworks.dev**
|
||||
@@ -0,0 +1,84 @@
|
||||
---
|
||||
import Base from '../layouts/Base.astro';
|
||||
---
|
||||
<Base title="API Pricing" description="API Pricing — leeworks.dev — compare plans for ZIP Enrichment, Holidays, and Air Quality APIs">
|
||||
<style>
|
||||
.pricing-hero { padding: 4rem 2rem 2rem; text-align: center; }
|
||||
.pricing-hero h1 { font-size: 2.5rem; font-weight: 800; background: linear-gradient(135deg, #90cdf4, #667eea); -webkit-background-clip: text; -webkit-text-fill-color: transparent; margin-bottom: 1rem; }
|
||||
.pricing-hero p { font-size: 1.15rem; color: #a0aec0; max-width: 600px; margin: 0 auto 2rem; }
|
||||
.pricing-wrap { padding: 1rem 2rem 3rem; max-width: 1100px; margin: 0 auto; overflow-x: auto; }
|
||||
table { width: 100%; border-collapse: collapse; background: #1a1d27; border-radius: 12px; overflow: hidden; min-width: 640px; }
|
||||
caption { caption-side: top; text-align: left; font-size: 0.875rem; color: #718096; padding: 0.75rem 1rem; font-style: italic; }
|
||||
thead tr { background: #2d3748; }
|
||||
th, td { padding: 0.9rem 1.25rem; text-align: left; border-bottom: 1px solid #2d3748; }
|
||||
th { font-weight: 700; color: #90cdf4; font-size: 0.9rem; text-transform: uppercase; letter-spacing: 0.04em; }
|
||||
td { color: #e2e8f0; font-size: 0.95rem; }
|
||||
tbody tr:last-child td { border-bottom: none; }
|
||||
tbody tr:hover { background: #232738; }
|
||||
.tier-name { font-weight: 600; color: #fff; }
|
||||
.tier-price { color: #9ae6b4; font-weight: 600; }
|
||||
.free-price { color: #68d391; }
|
||||
.cta-row { display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap; margin: 2.5rem 0 1rem; }
|
||||
.cta-btn { display: inline-block; background: #667eea; color: #fff; padding: 0.65rem 1.5rem; border-radius: 8px; text-decoration: none; font-weight: 600; font-size: 0.95rem; }
|
||||
.cta-btn:hover { background: #5a67d8; }
|
||||
.disclaimer { text-align: center; color: #718096; font-size: 0.85rem; margin-top: 2rem; padding: 0 2rem; }
|
||||
</style>
|
||||
|
||||
<div class="pricing-hero">
|
||||
<h1>API Pricing</h1>
|
||||
<p>Simple, transparent pricing for all three APIs. Start free — upgrade when you need more.</p>
|
||||
</div>
|
||||
|
||||
<div class="pricing-wrap">
|
||||
<table>
|
||||
<caption>All plans are monthly. Requests reset at the start of each billing cycle.</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Tier</th>
|
||||
<th scope="col">Price / mo</th>
|
||||
<th scope="col">ZIP Enrichment</th>
|
||||
<th scope="col">Holidays</th>
|
||||
<th scope="col">Air Quality</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="tier-name">Free</td>
|
||||
<td class="tier-price free-price">$0</td>
|
||||
<td>100 req/mo · 5 req/min</td>
|
||||
<td>100 req/mo · 5 req/min</td>
|
||||
<td>100 req/mo · 5 req/min</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tier-name">Basic</td>
|
||||
<td class="tier-price">$9</td>
|
||||
<td>5,000 req/mo · 60 req/min</td>
|
||||
<td>5,000 req/mo · 60 req/min</td>
|
||||
<td>5,000 req/mo · 60 req/min</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tier-name">Pro</td>
|
||||
<td class="tier-price">$19</td>
|
||||
<td>25,000 req/mo · 200 req/min</td>
|
||||
<td>20,000 req/mo · 200 req/min</td>
|
||||
<td>20,000 req/mo · 200 req/min</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tier-name">Ultra</td>
|
||||
<td class="tier-price">$49</td>
|
||||
<td>100,000 req/mo · 500 req/min</td>
|
||||
<td>100,000 req/mo · 500 req/min</td>
|
||||
<td>100,000 req/mo · 500 req/min</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="cta-row">
|
||||
<a href="#" class="cta-btn">ZIP Enrichment on RapidAPI</a>
|
||||
<a href="#" class="cta-btn">Holidays on RapidAPI</a>
|
||||
<a href="#" class="cta-btn">Air Quality on RapidAPI</a>
|
||||
</div>
|
||||
|
||||
<p class="disclaimer">Subscriptions managed via RapidAPI marketplace. Prices shown in USD. Rate limits apply per API key.</p>
|
||||
</div>
|
||||
</Base>
|
||||
+4
-2
@@ -102,6 +102,7 @@ dig aqi.leeworks.dev +short
|
||||
dig docs.leeworks.dev +short
|
||||
dig status.leeworks.dev +short
|
||||
dig registry.leeworks.dev +short
|
||||
dig grafana.leeworks.dev +short
|
||||
|
||||
# Check TLS certificates (once services are deployed)
|
||||
curl -v https://zip.leeworks.dev/health 2>&1 | grep -E "SSL|certificate|issuer"
|
||||
@@ -125,7 +126,7 @@ The following actions require human operator access to the DNS provider:
|
||||
|
||||
1. Log into the DNS provider managing `leeworks.dev`
|
||||
2. Find the cluster ingress IP: `kubectl get svc -n ingress-nginx ingress-nginx-controller`
|
||||
3. Create/update the 6 A records listed in the table above
|
||||
3. Create/update the 7 A records listed in the table above
|
||||
4. Verify propagation: `dig +trace zip.leeworks.dev`
|
||||
|
||||
DNS propagation typically takes 5–60 minutes.
|
||||
@@ -141,4 +142,5 @@ DNS propagation typically takes 5–60 minutes.
|
||||
- [ ] `docs.leeworks.dev` → DNS record created
|
||||
- [ ] `status.leeworks.dev` → DNS record created
|
||||
- [ ] `registry.leeworks.dev` → DNS record created
|
||||
- [ ] TLS certificates issued and valid for all 6 subdomains
|
||||
- [ ] `grafana.leeworks.dev` → DNS record created
|
||||
- [ ] TLS certificates issued and valid for all 7 subdomains
|
||||
|
||||
@@ -0,0 +1,309 @@
|
||||
# Operator Runbook
|
||||
|
||||
**Audience:** Human operator (0xWheatyz)
|
||||
**Purpose:** Ordered, copy-paste-ready guide to bring the full `api-company` stack live.
|
||||
**Last updated:** 2026-05-26
|
||||
**Closes:** leeworks-agents/api-company#50
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
The agent has committed all Flux manifests and documentation. The only remaining
|
||||
work is a set of manual steps that require Gitea admin access, `kubectl` access to
|
||||
the `testing1` cluster, and external service accounts (RapidAPI, Slack, PayPal).
|
||||
|
||||
Work through these phases **in order** — each phase unblocks the next.
|
||||
|
||||
---
|
||||
|
||||
## Phase 0 — Create upstream repo (unblocks all ship cycles)
|
||||
|
||||
> **Why first?** Every agent deployment cycle fails to open a PR to upstream
|
||||
> because `0xWheatyz/api-company` does not yet exist. This one step unblocks
|
||||
> all automated deployments. See issues #41, #47.
|
||||
|
||||
### Step 0-A — Create `0xWheatyz/api-company` on Gitea
|
||||
|
||||
1. Log into Gitea as `0xWheatyz`.
|
||||
2. **+** → **New Repository**.
|
||||
3. Owner: `0xWheatyz`, Name: `api-company`.
|
||||
4. Visibility: Public (or Private — your choice).
|
||||
5. **Do not** initialise with a README.
|
||||
6. Click **Create Repository**.
|
||||
|
||||
Once created, the agent's next ship cycle will open a deployment PR automatically.
|
||||
|
||||
---
|
||||
|
||||
## Phase 1 — Wire Flux to this repo (unblocks all GitOps reconciliation)
|
||||
|
||||
> **Why second?** Until Flux watches `leeworks-agents/api-company`, none of the
|
||||
> manifests in `flux/` are applied to the cluster. See issue #2.
|
||||
|
||||
### Step 1-A — Create `gitea-leeworks-agents-token` secret in `flux-system`
|
||||
|
||||
```bash
|
||||
# In Gitea: User Settings → Applications → Generate Token
|
||||
# Scopes: read:repository (read-only is sufficient for Flux)
|
||||
# Copy the token, then:
|
||||
|
||||
kubectl create secret generic gitea-leeworks-agents-token \
|
||||
-n flux-system \
|
||||
--from-literal=username=leeworks-agents \
|
||||
--from-literal=password=<GITEA_TOKEN>
|
||||
```
|
||||
|
||||
### Step 1-B — Copy Flux source + kustomization into 0xWheatyz/Talos
|
||||
|
||||
Reference manifests are at `flux/api-company-source/` in this repo.
|
||||
Copy them verbatim to:
|
||||
|
||||
```
|
||||
0xWheatyz/Talos:testing1/first-cluster/cluster/flux/api-company-source/
|
||||
├── gitrepository.yaml
|
||||
└── kustomization.yaml
|
||||
```
|
||||
|
||||
You can do this via the Gitea web editor or locally:
|
||||
|
||||
```bash
|
||||
cd /path/to/Talos-checkout
|
||||
mkdir -p testing1/first-cluster/cluster/flux/api-company-source
|
||||
# copy the two files from api-company/flux/api-company-source/
|
||||
git add .
|
||||
git commit -m "feat: wire Flux GitRepository + Kustomization for api-company"
|
||||
git push origin main
|
||||
```
|
||||
|
||||
**Verify reconciliation (after ~5 minutes):**
|
||||
```bash
|
||||
flux get sources git -n flux-system
|
||||
flux get kustomizations -n flux-system
|
||||
```
|
||||
|
||||
Both `api-company` entries should show `Ready = True`.
|
||||
|
||||
---
|
||||
|
||||
## Phase 2 — Secrets for already-staged services
|
||||
|
||||
Once Flux is watching the repo, it will attempt to reconcile all `flux/`
|
||||
sub-directories. The HelmReleases will stall on missing secrets. Create them:
|
||||
|
||||
### Step 2-A — `gitea-runner-token` (unblocks Gitea Actions runner, issue #3)
|
||||
|
||||
```bash
|
||||
# In Gitea: Admin Panel → Site Administration → Actions → Runners
|
||||
# → Create new Runner → copy registration token
|
||||
|
||||
kubectl create secret generic gitea-runner-token \
|
||||
-n gitea-runner \
|
||||
--from-literal=token=<RUNNER_REGISTRATION_TOKEN>
|
||||
```
|
||||
|
||||
**Verify:**
|
||||
```bash
|
||||
kubectl get pods -n gitea-runner
|
||||
# Then check Gitea Admin → Actions → Runners — runner should appear Online
|
||||
```
|
||||
|
||||
### Step 2-B — `grafana-admin` (unblocks Grafana, issue #7)
|
||||
|
||||
```bash
|
||||
kubectl create secret generic grafana-admin \
|
||||
-n monitoring \
|
||||
--from-literal=admin-password=<CHOOSE_STRONG_PASSWORD>
|
||||
```
|
||||
|
||||
Grafana URL: `https://grafana.leeworks.dev` (login: `admin` / `<PASSWORD>`)
|
||||
|
||||
### Step 2-C — `gatus-slack-webhook` (unblocks Gatus alerts, issue #8)
|
||||
|
||||
```bash
|
||||
# Create an incoming webhook at: https://api.slack.com/messaging/webhooks
|
||||
|
||||
kubectl create secret generic gatus-slack-webhook \
|
||||
-n monitoring \
|
||||
--from-literal=url=https://hooks.slack.com/services/YOUR/WEBHOOK/URL
|
||||
```
|
||||
|
||||
Gatus URL: `https://status.leeworks.dev`
|
||||
|
||||
### Step 2-D — Enable Gitea packages + registry DNS (issue #4)
|
||||
|
||||
**4a — Enable packages in Gitea `app.ini`:**
|
||||
```ini
|
||||
[packages]
|
||||
ENABLED = true
|
||||
```
|
||||
Restart Gitea after editing `app.ini`.
|
||||
|
||||
**4b — Add DNS A record:**
|
||||
```
|
||||
registry.leeworks.dev → <cluster ingress IP>
|
||||
```
|
||||
|
||||
Find the ingress IP:
|
||||
```bash
|
||||
kubectl get svc -n ingress-nginx
|
||||
```
|
||||
|
||||
See `docs/registry.md` for additional context.
|
||||
|
||||
---
|
||||
|
||||
## Phase 3 — Enable CI image push (unblocks API service deployments)
|
||||
|
||||
Once the runner is online and the registry is reachable, CI pipelines can build
|
||||
and push container images.
|
||||
|
||||
### Step 3-A — Add `GITEA_TOKEN` Actions Secret to each repo
|
||||
|
||||
Repos to configure:
|
||||
- `leeworks-agents/api-company`
|
||||
- `leeworks-agents/zip-enrichment`
|
||||
- `leeworks-agents/holidays`
|
||||
- `leeworks-agents/air-quality`
|
||||
|
||||
**For each repo:** Repo → Settings → Actions → Secrets → Add Secret
|
||||
- **Name:** `GITEA_TOKEN`
|
||||
- **Value:** Gitea personal access token with `write:packages` scope
|
||||
|
||||
### Step 3-B — Create image-automation token secret (issue #51)
|
||||
|
||||
The agent has added `ImageRepository` + `ImagePolicy` + `ImageUpdateAutomation`
|
||||
manifests to `flux/image-automation/`. Flux will automatically update image tags
|
||||
in HelmReleases when CI pushes new images — but it needs write access to commit
|
||||
back:
|
||||
|
||||
```bash
|
||||
kubectl create secret generic gitea-image-automation-token \
|
||||
-n flux-system \
|
||||
--from-literal=username=leeworks-agents \
|
||||
--from-literal=password=<GITEA_TOKEN_WITH_WRITE_REPO>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 4 — DNS for API services (issue #33)
|
||||
|
||||
Add DNS A records for all seven leeworks.dev subdomains (all point to the same
|
||||
cluster ingress IP):
|
||||
|
||||
| Hostname | Target |
|
||||
|-------------------------|------------------------|
|
||||
| `zip.leeworks.dev` | `<cluster ingress IP>` |
|
||||
| `holidays.leeworks.dev` | `<cluster ingress IP>` |
|
||||
| `aqi.leeworks.dev` | `<cluster ingress IP>` |
|
||||
| `docs.leeworks.dev` | `<cluster ingress IP>` |
|
||||
| `grafana.leeworks.dev` | `<cluster ingress IP>` |
|
||||
| `status.leeworks.dev` | `<cluster ingress IP>` |
|
||||
| `registry.leeworks.dev` | `<cluster ingress IP>` |
|
||||
|
||||
Verify DNS propagation:
|
||||
|
||||
```bash
|
||||
for host in zip holidays aqi docs grafana status registry; do
|
||||
echo -n "${host}.leeworks.dev: "
|
||||
dig ${host}.leeworks.dev +short
|
||||
done
|
||||
```
|
||||
|
||||
cert-manager will obtain Let's Encrypt certificates automatically once DNS
|
||||
propagates (typically minutes, up to 48 h).
|
||||
|
||||
---
|
||||
|
||||
## Phase 5 — RapidAPI + PayPal (issue #44, #19)
|
||||
|
||||
> **Blocked on operator being 18+ for PayPal.** Complete when eligible.
|
||||
|
||||
1. Create accounts on [rapidapi.com](https://rapidapi.com) and [paypal.com](https://www.paypal.com).
|
||||
2. Link PayPal to RapidAPI as the payout method.
|
||||
3. Submit each API to the RapidAPI marketplace using `docs/rapidapi-listings.md`.
|
||||
4. Configure paid tiers per `ROADMAP.md`.
|
||||
|
||||
After submission, RapidAPI generates a `X-RapidAPI-Proxy-Secret` per API. Create:
|
||||
|
||||
```bash
|
||||
# zip-enrichment
|
||||
kubectl create secret generic rapidapi-proxy-secret \
|
||||
-n zip-enrichment \
|
||||
--from-literal=X-RapidAPI-Proxy-Secret=<VALUE>
|
||||
|
||||
# holidays
|
||||
kubectl create secret generic rapidapi-proxy-secret \
|
||||
-n holidays \
|
||||
--from-literal=X-RapidAPI-Proxy-Secret=<VALUE>
|
||||
|
||||
# air-quality
|
||||
kubectl create secret generic rapidapi-proxy-secret \
|
||||
-n air-quality \
|
||||
--from-literal=X-RapidAPI-Proxy-Secret=<VALUE>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Verification Checklist
|
||||
|
||||
```bash
|
||||
# Flux overall health
|
||||
flux get all -A
|
||||
|
||||
# API service pods
|
||||
kubectl get pods -n zip-enrichment
|
||||
kubectl get pods -n holidays
|
||||
kubectl get pods -n air-quality
|
||||
|
||||
# Ingress + TLS
|
||||
kubectl get ingress -A
|
||||
kubectl get certificates -A
|
||||
|
||||
# Gitea runner
|
||||
kubectl get pods -n gitea-runner
|
||||
|
||||
# Monitoring stack
|
||||
kubectl get pods -n monitoring
|
||||
|
||||
# Image automation
|
||||
flux get imagepolicies -A
|
||||
flux get imagerepositories -A
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dependency Summary
|
||||
|
||||
```
|
||||
Phase 0: Create 0xWheatyz/api-company repo
|
||||
└─► unblocks agent deployment PRs to upstream
|
||||
|
||||
Phase 1: Wire Flux (gitea-token secret + Talos manifests)
|
||||
└─► all flux/ manifests reconcile
|
||||
|
||||
Phase 2: Service secrets (runner-token, grafana-admin, gatus-webhook, registry)
|
||||
└─► runner online, monitoring live, registry reachable
|
||||
|
||||
Phase 3: CI secrets + image-automation token
|
||||
└─► images build, push, and auto-update → API services deploy
|
||||
|
||||
Phase 4: DNS records
|
||||
└─► HTTPS certs issued → public URLs go live
|
||||
|
||||
Phase 5: RapidAPI + PayPal
|
||||
└─► revenue enabled
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Related Documents
|
||||
|
||||
| Document | Purpose |
|
||||
|----------|---------|
|
||||
| `docs/secrets-checklist.md` | Full checklist of all required secrets |
|
||||
| `docs/registry.md` | Container registry architecture decision |
|
||||
| `docs/cluster-audit.md` | Node/namespace/ingress inventory |
|
||||
| `docs/rapidapi-listings.md` | RapidAPI marketplace submission details |
|
||||
| `ROADMAP.md` | Full project roadmap and milestones |
|
||||
| `STATUS.md` | Current cycle status and blockers |
|
||||
+102
-1
@@ -16,6 +16,9 @@ Follow this list top-to-bottom; each step unblocks the next.
|
||||
- [ ] 5. `GITEA_TOKEN` in each API repo's Actions Secrets — unblocks CI image push
|
||||
- [ ] 6. Gitea packages enabled + DNS record for `registry.leeworks.dev` — unblocks image push to registry
|
||||
- [ ] 7. Add api-company Flux source + kustomization to 0xWheatyz/Talos — unblocks all GitOps reconciliation
|
||||
- [ ] 8. `gitea-registry` (zip-enrichment, holidays, air-quality, docs-site) — imagePullSecret for pods pulling from `registry.leeworks.dev`
|
||||
- [ ] 9. `gitea-image-automation-token` (flux-system) — write-scoped token for Flux ImageUpdateAutomation to push image-tag commits
|
||||
- [ ] 10. `rapidapi-proxy-secret` (zip-enrichment, holidays, air-quality) — RapidAPI Proxy Secret for server-side request validation
|
||||
|
||||
---
|
||||
|
||||
@@ -153,6 +156,44 @@ Unblocks: Issue #2 (Flux reconciliation of all `flux/` manifests in this repo).
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
### 10. `rapidapi-proxy-secret` — RapidAPI Proxy Secret (per API namespace)
|
||||
|
||||
| Field | Value |
|
||||
|-----------|-------|
|
||||
| Name | `rapidapi-proxy-secret` |
|
||||
| Namespaces | `zip-enrichment`, `holidays`, `air-quality` |
|
||||
| Purpose | Every API service validates the `X-RapidAPI-Proxy-Secret` header on every route. Requests without a valid secret return HTTP 403. |
|
||||
| Source | RapidAPI dashboard → API Settings → Security → **Proxy Secret** (generated after each API listing is created) |
|
||||
| Unblocks | Phase 3 server middleware; API services will start but reject all traffic without this secret |
|
||||
|
||||
```bash
|
||||
for NS in zip-enrichment holidays air-quality; do
|
||||
kubectl create secret generic rapidapi-proxy-secret \
|
||||
--namespace=$NS \
|
||||
--from-literal=X-RapidAPI-Proxy-Secret=<value-from-rapidapi-dashboard>
|
||||
done
|
||||
```
|
||||
|
||||
**Source:** RapidAPI dashboard → select your API → Settings → Security → Proxy Secret
|
||||
|
||||
> **Note:** Placeholder `ExternalSecret` manifests are committed at
|
||||
> `flux/zip-enrichment/externalsecret.yaml`, `flux/holidays/externalsecret.yaml`,
|
||||
> and `flux/air-quality/externalsecret.yaml`. These will auto-sync this secret
|
||||
> from the configured backend once the External Secrets Operator (ESO) is
|
||||
> deployed (see issue #61). Until then, create manually using the commands above.
|
||||
|
||||
Verify:
|
||||
```bash
|
||||
for NS in zip-enrichment holidays air-quality; do
|
||||
echo -n "$NS: "
|
||||
kubectl get secret rapidapi-proxy-secret -n $NS -o jsonpath='{.data.X-RapidAPI-Proxy-Secret}' | base64 -d | wc -c
|
||||
echo " chars"
|
||||
done
|
||||
```
|
||||
|
||||
|
||||
## Dependency Order
|
||||
|
||||
```
|
||||
@@ -162,6 +203,66 @@ Unblocks: Issue #2 (Flux reconciliation of all `flux/` manifests in this repo).
|
||||
3 (grafana-admin) → Grafana login works
|
||||
4 (gatus-slack-webhook) → Gatus alerting works
|
||||
5 + 6 (GITEA_TOKEN + registry packages) → CI pushes images → API services deploy
|
||||
8 (gitea-registry) → pods can pull images from registry.leeworks.dev → services start
|
||||
9 (gitea-image-automation-token) → Flux ImageUpdateAutomation pushes tag-update commits
|
||||
10 (rapidapi-proxy-secret × 3) → API server middleware validates RapidAPI requests → revenue enabled
|
||||
```
|
||||
|
||||
Once all seven items are complete, the full stack (runner, registry, Prometheus, Grafana, Gatus, docs-site, three API services) reconciles automatically via FluxCD with no further manual steps.
|
||||
Once all nine items are complete, the full stack (runner, registry, Prometheus, Grafana, Gatus, docs-site, three API services) reconciles automatically via FluxCD with no further manual steps.
|
||||
|
||||
---
|
||||
|
||||
### 8. `gitea-registry` — imagePullSecret for API service namespaces
|
||||
|
||||
| Field | Value |
|
||||
|-----------|-------|
|
||||
| Name | `gitea-registry` |
|
||||
| Namespaces | `zip-enrichment`, `holidays`, `air-quality`, `docs-site` |
|
||||
| Type | `kubernetes.io/dockerconfigjson` |
|
||||
| Purpose | Allows pods to pull images from `registry.leeworks.dev` without ImagePullBackOff |
|
||||
| Source | Gitea token with `read:packages` scope (can reuse the same token as step 1 if it has that scope) |
|
||||
| Unblocks | Issues #58 (Phase 0 hard deploy blocker) and transitively Phase 3 service deploys |
|
||||
|
||||
```bash
|
||||
for NS in zip-enrichment holidays air-quality docs-site; do
|
||||
kubectl create secret docker-registry gitea-registry \
|
||||
--namespace=$NS \
|
||||
--docker-server=registry.leeworks.dev \
|
||||
--docker-username=leeworks-agents \
|
||||
--docker-password=<GITEA_TOKEN_WITH_READ_PACKAGES> \
|
||||
--docker-email=agent@leeworks.dev
|
||||
done
|
||||
```
|
||||
|
||||
Verify:
|
||||
```bash
|
||||
kubectl get secret gitea-registry -n zip-enrichment -o jsonpath='{.type}'
|
||||
# expected: kubernetes.io/dockerconfigjson
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 9. `gitea-image-automation-token` — Flux ImageUpdateAutomation write token
|
||||
|
||||
| Field | Value |
|
||||
|-----------|-------|
|
||||
| Name | `gitea-image-automation-token` |
|
||||
| Namespace | `flux-system` |
|
||||
| Purpose | Allows Flux `ImageUpdateAutomation` to push image-tag update commits back to `leeworks-agents/api-company` |
|
||||
| Source | Gitea token with **`write:repository`** scope (the existing `gitea-leeworks-agents-token` only has `read:repository` — create a separate token or verify scope) |
|
||||
| Unblocks | Issue #57 (Flux ImageUpdateAutomation for api-company) |
|
||||
|
||||
```bash
|
||||
kubectl create secret generic gitea-image-automation-token \
|
||||
-n flux-system \
|
||||
--from-literal=username=leeworks-agents \
|
||||
--from-literal=password=<TOKEN_WITH_WRITE_REPO_SCOPE>
|
||||
```
|
||||
|
||||
Verify after creation:
|
||||
```bash
|
||||
flux get imageupdateautomations -n flux-system
|
||||
# Expected: api-company shows READY=True
|
||||
```
|
||||
|
||||
> **Note:** If you create a new token with `write:repository` scope, keep the existing `gitea-leeworks-agents-token` for read-only Flux GitRepository pulls and use this new secret exclusively for `ImageUpdateAutomation`.
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
# Tooling Versions
|
||||
|
||||
> Phase 0 checklist item — documents the local agent container tooling and confirms git remote config.
|
||||
> Live cluster verification (kubectl/flux against the running cluster) requires operator confirmation.
|
||||
|
||||
## Agent Container Tooling
|
||||
|
||||
| Tool | Version | Source |
|
||||
|------|---------|--------|
|
||||
| Node.js | v22.22.2 | `node --version` |
|
||||
| Python 3 | 3.11.2 | `python3 --version` |
|
||||
| Helm | v3.21.0 | `helm version --short` |
|
||||
| Flux CLI | v2.4.0 | `flux version --client` |
|
||||
| kustomize | v5.6.0 | `kustomize version` |
|
||||
| kubectl | available | `kubectl` (cluster context not set in agent container — live commands require kubeconfig from operator) |
|
||||
|
||||
## Git Remote Config
|
||||
|
||||
```
|
||||
origin ssh://git@gitea.leeworks.dev/leeworks-agents/api-company (fetch)
|
||||
origin ssh://git@gitea.leeworks.dev/leeworks-agents/api-company (push)
|
||||
upstream ssh://git@gitea.leeworks.dev/0xWheatyz/api-company (fetch)
|
||||
upstream ssh://git@gitea.leeworks.dev/0xWheatyz/api-company (push)
|
||||
```
|
||||
|
||||
Remote `origin` confirmed pointing to `gitea.leeworks.dev/leeworks-agents/api-company`.
|
||||
|
||||
> Note: `0xWheatyz/api-company` upstream repo does not yet exist on Gitea — tracked by issue #47.
|
||||
|
||||
## Stack Summary
|
||||
|
||||
### Runtime choices
|
||||
|
||||
| API Service | Runtime | Rationale |
|
||||
|-------------|---------|-----------|
|
||||
| zip-enrichment | Node.js (Fastify) | Lightweight, fast JSON serialisation; large ZIP dataset fits SQLite well |
|
||||
| holidays | Node.js (Fastify) | Simple lookup API; Fastify handles high req/s with low memory |
|
||||
| air-quality | Python (FastAPI) | AQI ingestion benefits from Python data-science ecosystem |
|
||||
| docs-site | Astro (static) | Zero-runtime static site; built by CI, served from container |
|
||||
|
||||
### Helm chart registry
|
||||
|
||||
All HelmReleases use charts sourced from public Helm chart repositories declared in `flux/` as `HelmRepository` resources:
|
||||
|
||||
- `flux/gitea-runner/helmrepository.yaml` — Gitea Act Runner chart
|
||||
- `flux/monitoring/` — `kube-prometheus-stack` and Gatus charts
|
||||
- `flux/zip-enrichment/`, `flux/holidays/`, `flux/air-quality/` — per-API service charts
|
||||
|
||||
The in-cluster container registry is `registry.leeworks.dev` (Gitea built-in packages/container registry, documented in `docs/registry.md`).
|
||||
|
||||
### Flux version and bootstrap
|
||||
|
||||
- **Flux CLI**: v2.4.0 (available in agent container for manifest authoring)
|
||||
- **Flux controllers**: bootstrapped into `0xWheatyz/Talos` cluster (FluxCD v2.x)
|
||||
- `flux-system` namespace managed by Talos GitOps repo
|
||||
- Flux watches `0xWheatyz/Talos` → `testing1/first-cluster/cluster/`
|
||||
- `api-company-source` GitRepository + Kustomization adds this repo to Flux (issues #2, #90)
|
||||
- **Bootstrap reference**: `0xWheatyz/Talos` repo — see Talos cluster documentation
|
||||
|
||||
## Live Verification (Operator)
|
||||
|
||||
The following commands require a valid `kubeconfig` (not available in agent container):
|
||||
|
||||
```bash
|
||||
kubectl config current-context # confirm cluster context
|
||||
kubectl version --client # kubectl client version
|
||||
flux check # Flux controller health
|
||||
flux get sources git api-company # GitRepository READY status
|
||||
flux get kustomizations api-company # Kustomization READY status
|
||||
helm version # Helm client version
|
||||
kustomize version # kustomize version
|
||||
```
|
||||
|
||||
_Reference: MASTER_BUILD_PROMPT.md §Phase 0 step 2 — Closes leeworks-agents/api-company#94_
|
||||
@@ -1,29 +1,18 @@
|
||||
# Placeholder: inject the RapidAPI Proxy Secret here once ESO is deployed.
|
||||
# Replace with a real ExternalSecret once leeworks-agents/api-company#2 and
|
||||
# the external-secrets operator are running in the cluster.
|
||||
#
|
||||
# Example (uncomment and fill in secretStore name):
|
||||
#
|
||||
# apiVersion: external-secrets.io/v1beta1
|
||||
# kind: ExternalSecret
|
||||
# metadata:
|
||||
# name: rapidapi-proxy-secret
|
||||
# namespace: air-quality
|
||||
# spec:
|
||||
# refreshInterval: 1h
|
||||
# secretStoreRef:
|
||||
# name: <your-secret-store>
|
||||
# kind: ClusterSecretStore
|
||||
# target:
|
||||
# name: rapidapi-proxy-secret
|
||||
# creationPolicy: Owner
|
||||
# data:
|
||||
# - secretKey: X-RapidAPI-Proxy-Secret
|
||||
# remoteRef:
|
||||
# key: rapidapi/air-quality
|
||||
# property: proxy-secret
|
||||
#
|
||||
# Until then, create manually:
|
||||
# kubectl create secret generic rapidapi-proxy-secret \
|
||||
# --from-literal=X-RapidAPI-Proxy-Secret=<value> \
|
||||
# -n air-quality
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: rapidapi-proxy-secret
|
||||
namespace: air-quality
|
||||
spec:
|
||||
refreshInterval: 1h
|
||||
secretStoreRef:
|
||||
name: kubernetes-provider
|
||||
kind: ClusterSecretStore
|
||||
target:
|
||||
name: rapidapi-proxy-secret
|
||||
creationPolicy: Owner
|
||||
data:
|
||||
- secretKey: X-RapidAPI-Proxy-Secret
|
||||
remoteRef:
|
||||
key: rapidapi-air-quality-source
|
||||
property: X-RapidAPI-Proxy-Secret
|
||||
|
||||
@@ -35,7 +35,7 @@ spec:
|
||||
- name: gitea-registry
|
||||
containers:
|
||||
- name: air-quality
|
||||
image: registry.leeworks.dev/air-quality/server:latest
|
||||
image: registry.leeworks.dev/air-quality/server:latest # {"$imagepolicy": "flux-system:air-quality"}
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
env:
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# This manifest is FOR REFERENCE — the live version must be committed to
|
||||
# 0xWheatyz/Talos at testing1/first-cluster/cluster/flux/api-company/
|
||||
# 0xWheatyz/Talos at testing1/first-cluster/cluster/flux/api-company-source/
|
||||
#
|
||||
# See leeworks-agents/api-company#2
|
||||
# See leeworks-agents/api-company#97
|
||||
|
||||
apiVersion: kustomize.toolkit.fluxcd.io/v1
|
||||
kind: Kustomization
|
||||
@@ -17,3 +18,8 @@ spec:
|
||||
prune: true
|
||||
wait: true
|
||||
timeout: 5m
|
||||
postBuild:
|
||||
substituteFrom:
|
||||
- kind: Secret
|
||||
name: grafana-admin
|
||||
optional: false
|
||||
|
||||
@@ -35,7 +35,7 @@ spec:
|
||||
- name: gitea-registry
|
||||
containers:
|
||||
- name: docs-site
|
||||
image: registry.leeworks.dev/leeworks-agents/docs-site:latest
|
||||
image: registry.leeworks.dev/leeworks-agents/docs-site:latest # {"$imagepolicy": "flux-system:docs-site"}
|
||||
ports:
|
||||
- containerPort: 80
|
||||
resources:
|
||||
|
||||
@@ -2,5 +2,4 @@ apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- namespace.yaml
|
||||
- helmrepository.yaml
|
||||
- helmrelease.yaml
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
# ClusterSecretStore using the Kubernetes provider.
|
||||
# Reads secrets from the cluster itself — no external vault required.
|
||||
# The service account below must have get/list access to secrets in
|
||||
# the namespaces where ExternalSecrets are created.
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: eso-kubernetes-provider
|
||||
namespace: external-secrets
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: eso-kubernetes-provider-reader
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["secrets"]
|
||||
verbs: ["get", "list", "watch"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: eso-kubernetes-provider-reader
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: eso-kubernetes-provider-reader
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: eso-kubernetes-provider
|
||||
namespace: external-secrets
|
||||
---
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ClusterSecretStore
|
||||
metadata:
|
||||
name: kubernetes-provider
|
||||
spec:
|
||||
provider:
|
||||
kubernetes:
|
||||
remoteNamespace: external-secrets
|
||||
server:
|
||||
caProvider:
|
||||
type: ConfigMap
|
||||
name: kube-root-ca.crt
|
||||
namespace: external-secrets
|
||||
key: ca.crt
|
||||
auth:
|
||||
serviceAccount:
|
||||
name: eso-kubernetes-provider
|
||||
namespace: external-secrets
|
||||
@@ -0,0 +1,30 @@
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: external-secrets
|
||||
namespace: external-secrets
|
||||
spec:
|
||||
interval: 15m
|
||||
chart:
|
||||
spec:
|
||||
chart: external-secrets
|
||||
version: ">=0.9.0 <1.0.0"
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: external-secrets
|
||||
namespace: flux-system
|
||||
interval: 60m
|
||||
install:
|
||||
crds: CreateReplace
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
crds: CreateReplace
|
||||
remediation:
|
||||
retries: 3
|
||||
values:
|
||||
installCRDs: true
|
||||
webhook:
|
||||
port: 9443
|
||||
certController:
|
||||
requeueInterval: 5m
|
||||
@@ -0,0 +1,8 @@
|
||||
apiVersion: source.toolkit.fluxcd.io/v1
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: external-secrets
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 60m
|
||||
url: https://charts.external-secrets.io
|
||||
@@ -0,0 +1,7 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- namespace.yaml
|
||||
- helmrepository.yaml
|
||||
- helmrelease.yaml
|
||||
- clustersecretstore.yaml
|
||||
@@ -0,0 +1,4 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: external-secrets
|
||||
@@ -1,29 +1,18 @@
|
||||
# Placeholder: inject the RapidAPI Proxy Secret here once ESO is deployed.
|
||||
# Replace with a real ExternalSecret once leeworks-agents/api-company#2 and
|
||||
# the external-secrets operator are running in the cluster.
|
||||
#
|
||||
# Example (uncomment and fill in secretStore name):
|
||||
#
|
||||
# apiVersion: external-secrets.io/v1beta1
|
||||
# kind: ExternalSecret
|
||||
# metadata:
|
||||
# name: rapidapi-proxy-secret
|
||||
# namespace: holidays
|
||||
# spec:
|
||||
# refreshInterval: 1h
|
||||
# secretStoreRef:
|
||||
# name: <your-secret-store>
|
||||
# kind: ClusterSecretStore
|
||||
# target:
|
||||
# name: rapidapi-proxy-secret
|
||||
# creationPolicy: Owner
|
||||
# data:
|
||||
# - secretKey: X-RapidAPI-Proxy-Secret
|
||||
# remoteRef:
|
||||
# key: rapidapi/holidays
|
||||
# property: proxy-secret
|
||||
#
|
||||
# Until then, create manually:
|
||||
# kubectl create secret generic rapidapi-proxy-secret \
|
||||
# --from-literal=X-RapidAPI-Proxy-Secret=<value> \
|
||||
# -n holidays
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: rapidapi-proxy-secret
|
||||
namespace: holidays
|
||||
spec:
|
||||
refreshInterval: 1h
|
||||
secretStoreRef:
|
||||
name: kubernetes-provider
|
||||
kind: ClusterSecretStore
|
||||
target:
|
||||
name: rapidapi-proxy-secret
|
||||
creationPolicy: Owner
|
||||
data:
|
||||
- secretKey: X-RapidAPI-Proxy-Secret
|
||||
remoteRef:
|
||||
key: rapidapi-holidays-source
|
||||
property: X-RapidAPI-Proxy-Secret
|
||||
|
||||
@@ -35,7 +35,7 @@ spec:
|
||||
- name: gitea-registry
|
||||
containers:
|
||||
- name: holidays
|
||||
image: registry.leeworks.dev/holidays/server:latest
|
||||
image: registry.leeworks.dev/holidays/server:latest # {"$imagepolicy": "flux-system:holidays"}
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
env:
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
# ImagePolicy: select the latest semver tag from each ImageRepository.
|
||||
# Tags pushed by CI should follow semver (e.g. v1.2.3) or use "latest" —
|
||||
# the semver policy picks up any vX.Y.Z tag. The "latest" alias keeps
|
||||
# things working before formal releases are tagged.
|
||||
apiVersion: image.toolkit.fluxcd.io/v1beta2
|
||||
kind: ImagePolicy
|
||||
metadata:
|
||||
name: zip-enrichment
|
||||
namespace: flux-system
|
||||
spec:
|
||||
imageRepositoryRef:
|
||||
name: zip-enrichment
|
||||
policy:
|
||||
semver:
|
||||
range: ">=0.1.0"
|
||||
---
|
||||
apiVersion: image.toolkit.fluxcd.io/v1beta2
|
||||
kind: ImagePolicy
|
||||
metadata:
|
||||
name: holidays
|
||||
namespace: flux-system
|
||||
spec:
|
||||
imageRepositoryRef:
|
||||
name: holidays
|
||||
policy:
|
||||
semver:
|
||||
range: ">=0.1.0"
|
||||
---
|
||||
apiVersion: image.toolkit.fluxcd.io/v1beta2
|
||||
kind: ImagePolicy
|
||||
metadata:
|
||||
name: air-quality
|
||||
namespace: flux-system
|
||||
spec:
|
||||
imageRepositoryRef:
|
||||
name: air-quality
|
||||
policy:
|
||||
semver:
|
||||
range: ">=0.1.0"
|
||||
---
|
||||
apiVersion: image.toolkit.fluxcd.io/v1beta2
|
||||
kind: ImagePolicy
|
||||
metadata:
|
||||
name: docs-site
|
||||
namespace: flux-system
|
||||
spec:
|
||||
imageRepositoryRef:
|
||||
name: docs-site
|
||||
policy:
|
||||
alphabetical:
|
||||
order: asc
|
||||
@@ -0,0 +1,45 @@
|
||||
# Flux image-reflector-controller watches these registries for new image tags.
|
||||
# Requires: flux-system/gitea-image-automation-token secret (see docs/operator-runbook.md)
|
||||
apiVersion: image.toolkit.fluxcd.io/v1beta2
|
||||
kind: ImageRepository
|
||||
metadata:
|
||||
name: zip-enrichment
|
||||
namespace: flux-system
|
||||
spec:
|
||||
image: registry.leeworks.dev/zip-enrichment/server
|
||||
interval: 5m
|
||||
secretRef:
|
||||
name: gitea-leeworks-agents-token
|
||||
---
|
||||
apiVersion: image.toolkit.fluxcd.io/v1beta2
|
||||
kind: ImageRepository
|
||||
metadata:
|
||||
name: holidays
|
||||
namespace: flux-system
|
||||
spec:
|
||||
image: registry.leeworks.dev/holidays/server
|
||||
interval: 5m
|
||||
secretRef:
|
||||
name: gitea-leeworks-agents-token
|
||||
---
|
||||
apiVersion: image.toolkit.fluxcd.io/v1beta2
|
||||
kind: ImageRepository
|
||||
metadata:
|
||||
name: air-quality
|
||||
namespace: flux-system
|
||||
spec:
|
||||
image: registry.leeworks.dev/air-quality/server
|
||||
interval: 5m
|
||||
secretRef:
|
||||
name: gitea-leeworks-agents-token
|
||||
---
|
||||
apiVersion: image.toolkit.fluxcd.io/v1beta2
|
||||
kind: ImageRepository
|
||||
metadata:
|
||||
name: docs-site
|
||||
namespace: flux-system
|
||||
spec:
|
||||
image: registry.leeworks.dev/leeworks-agents/docs-site
|
||||
interval: 5m
|
||||
secretRef:
|
||||
name: gitea-leeworks-agents-token
|
||||
@@ -0,0 +1,39 @@
|
||||
# ImageUpdateAutomation: when an ImagePolicy selects a new tag, this object
|
||||
# instructs Flux to open a commit on the api-company repo updating the
|
||||
# image reference in the relevant HelmRelease values.
|
||||
#
|
||||
# The GitRepository used here is the api-company source (flux-system/api-company).
|
||||
# Flux needs write access; create the token secret first:
|
||||
# kubectl create secret generic gitea-image-automation-token \
|
||||
# -n flux-system \
|
||||
# --from-literal=username=leeworks-agents \
|
||||
# --from-literal=password=<TOKEN_WITH_WRITE_REPO>
|
||||
# Then patch the api-company GitRepository to reference it (or reuse
|
||||
# gitea-leeworks-agents-token if that token also has write:repository scope).
|
||||
apiVersion: image.toolkit.fluxcd.io/v1beta2
|
||||
kind: ImageUpdateAutomation
|
||||
metadata:
|
||||
name: api-company
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 10m
|
||||
sourceRef:
|
||||
kind: GitRepository
|
||||
name: api-company
|
||||
git:
|
||||
checkout:
|
||||
ref:
|
||||
branch: main
|
||||
commit:
|
||||
author:
|
||||
email: agent@leeworks.dev
|
||||
name: Flux Image Automation
|
||||
messageTemplate: |
|
||||
chore(image): update {{range .Updated.Images}}{{.Repository}}:{{.NewTag}} {{end}}
|
||||
push:
|
||||
branch: main
|
||||
secretRef:
|
||||
name: gitea-image-automation-token # must pre-exist in flux-system ns — see docs/secrets-checklist.md item 9
|
||||
update:
|
||||
path: ./flux
|
||||
strategy: Setters
|
||||
@@ -0,0 +1,6 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- imagerepositories.yaml
|
||||
- imagepolicies.yaml
|
||||
- imageupdateautomation.yaml
|
||||
@@ -1,9 +1,12 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- bedag-helmrepository.yaml
|
||||
- external-secrets
|
||||
- gitea-runner
|
||||
- monitoring
|
||||
- docs-site
|
||||
- zip-enrichment
|
||||
- holidays
|
||||
- air-quality
|
||||
- image-automation
|
||||
|
||||
@@ -71,7 +71,7 @@ spec:
|
||||
- alert: APIDataStale
|
||||
expr: |
|
||||
api_data_freshness_seconds{job=~"zip|holidays|air-quality"} > 2592000
|
||||
for: 5m
|
||||
for: 30m
|
||||
labels:
|
||||
severity: warning
|
||||
team: api-company
|
||||
@@ -79,6 +79,20 @@ spec:
|
||||
summary: "Stale dataset on {{ $labels.job }} ({{ $labels.dataset }})"
|
||||
description: "{{ $labels.job }} dataset '{{ $labels.dataset }}' has not been re-seeded in {{ $value | humanizeDuration }} (threshold: 30 days). Re-seed required."
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# APIDataCriticallyStale — data freshness > 60 days
|
||||
# -------------------------------------------------------------------
|
||||
- alert: APIDataCriticallyStale
|
||||
expr: |
|
||||
api_data_freshness_seconds{job=~"zip|holidays|air-quality"} > 5184000
|
||||
for: 1h
|
||||
labels:
|
||||
severity: critical
|
||||
team: api-company
|
||||
annotations:
|
||||
summary: "API data is critically stale on {{ $labels.job }}"
|
||||
description: "{{ $labels.job }} data has not been re-seeded in more than 60 days ({{ $value | humanizeDuration }})"
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# APIDown — any API job absent for 2 min
|
||||
# -------------------------------------------------------------------
|
||||
|
||||
@@ -1,29 +1,18 @@
|
||||
# Placeholder: inject the RapidAPI Proxy Secret here once ESO is deployed.
|
||||
# Replace with a real ExternalSecret once leeworks-agents/api-company#2 and
|
||||
# the external-secrets operator are running in the cluster.
|
||||
#
|
||||
# Example (uncomment and fill in secretStore name):
|
||||
#
|
||||
# apiVersion: external-secrets.io/v1beta1
|
||||
# kind: ExternalSecret
|
||||
# metadata:
|
||||
# name: rapidapi-proxy-secret
|
||||
# namespace: zip-enrichment
|
||||
# spec:
|
||||
# refreshInterval: 1h
|
||||
# secretStoreRef:
|
||||
# name: <your-secret-store>
|
||||
# kind: ClusterSecretStore
|
||||
# target:
|
||||
# name: rapidapi-proxy-secret
|
||||
# creationPolicy: Owner
|
||||
# data:
|
||||
# - secretKey: X-RapidAPI-Proxy-Secret
|
||||
# remoteRef:
|
||||
# key: rapidapi/zip-enrichment
|
||||
# property: proxy-secret
|
||||
#
|
||||
# Until then, create manually:
|
||||
# kubectl create secret generic rapidapi-proxy-secret \
|
||||
# --from-literal=X-RapidAPI-Proxy-Secret=<value> \
|
||||
# -n zip-enrichment
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: rapidapi-proxy-secret
|
||||
namespace: zip-enrichment
|
||||
spec:
|
||||
refreshInterval: 1h
|
||||
secretStoreRef:
|
||||
name: kubernetes-provider
|
||||
kind: ClusterSecretStore
|
||||
target:
|
||||
name: rapidapi-proxy-secret
|
||||
creationPolicy: Owner
|
||||
data:
|
||||
- secretKey: X-RapidAPI-Proxy-Secret
|
||||
remoteRef:
|
||||
key: rapidapi-zip-enrichment-source
|
||||
property: X-RapidAPI-Proxy-Secret
|
||||
|
||||
@@ -35,7 +35,7 @@ spec:
|
||||
- name: gitea-registry
|
||||
containers:
|
||||
- name: zip-enrichment
|
||||
image: registry.leeworks.dev/zip-enrichment/server:latest
|
||||
image: registry.leeworks.dev/zip-enrichment/server:latest # {"$imagepolicy": "flux-system:zip-enrichment"}
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
env:
|
||||
|
||||
Reference in New Issue
Block a user