Compare commits

..

1 Commits

Author SHA1 Message Date
agent-company 43f5d5ef60 feat: deploy External Secrets Operator (ESO) via Flux + real ExternalSecrets
Add flux/external-secrets/ directory containing:
- namespace.yaml: external-secrets namespace
- helmrepository.yaml: charts.external-secrets.io HelmRepository
- helmrelease.yaml: ESO HelmRelease (external-secrets/external-secrets >=0.9.0 <1.0.0)
- clustersecretstore.yaml: ClusterSecretStore using Kubernetes provider
  (ServiceAccount + ClusterRole + ClusterRoleBinding + ClusterSecretStore)
- kustomization.yaml: wires all above resources

Uncomment and complete ExternalSecret manifests in each API namespace:
- flux/zip-enrichment/externalsecret.yaml
- flux/holidays/externalsecret.yaml
- flux/air-quality/externalsecret.yaml

All three ExternalSecrets reference the kubernetes-provider ClusterSecretStore
and will auto-sync rapidapi-proxy-secret once ESO is running.

Add external-secrets to flux/kustomization.yaml.

kustomize build flux/ = PASS

Closes leeworks-agents/api-company#61
2026-05-27 15:05:54 +00:00
10 changed files with 156 additions and 95 deletions
+2 -8
View File
@@ -1,6 +1,6 @@
# Company Status
_Last updated: 2026-05-27 (agent cycle — night triage)_
_Last updated: 2026-05-27 (agent cycle — evening triage)_
## APIs
| API | Spec | Code | Deployed | Listed on RapidAPI | Paying Users | MRR |
@@ -21,13 +21,7 @@ Legend: [x]=done, [~]=in-progress, [ ]=not started
- **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-27 — Night Triage)
- **#67** — New issue triaged: grafana.leeworks.dev missing from DNS checklist. Confirmed `docs/operator-runbook.md` Phase 4 DNS table already lists 7 subdomains including grafana (added by #62). No code change needed; gated on operator DNS setup. Comment posted.
- **#66** — New issue triaged: Flux reconciliation validation checklist. Blocked on operator completing Phase 0 (#47, #2, #3, #4). `kustomize build flux/` = PASS confirmed. Comment posted.
- **No open PRs** — nothing to merge or review.
- **`kustomize build flux/` = PASS** — no regressions.
## Completed Previous Cycle (2026-05-27 — Evening Triage)
## Completed This 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.
+18 -29
View File
@@ -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
@@ -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
+30
View File
@@ -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
+7
View File
@@ -0,0 +1,7 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- helmrepository.yaml
- helmrelease.yaml
- clustersecretstore.yaml
+4
View File
@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: external-secrets
+18 -29
View File
@@ -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
+1
View File
@@ -1,6 +1,7 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- external-secrets
- gitea-runner
- monitoring
- docs-site
+18 -29
View File
@@ -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