Compare commits

...

18 Commits

Author SHA1 Message Date
unkinben c17bbda89b schemas: add grafana.integreatly.org CRD schemas
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/kubeconform Pipeline was successful
Generated from the grafana-operator v5.24.0 CRDs (added in the previous
PR) so `make kubeconform` can validate the Grafana / GrafanaDashboard /
GrafanaDatasource / GrafanaFolder CRs introduced by the grafana instance
PR. Mirrors ci/generate-schemas.sh output for the grafana CRD group.
2026-07-05 22:19:40 +10:00
unkinben 0f6c9e5502 Merge pull request 'grafana-system: deploy grafana-operator' (#235) from benvin/grafana-operator into main 2026-07-05 22:18:57 +10:00
unkinben 5f8f2b1c70 observability: migrate VictoriaMetrics to operator CRDs + Consul SD (#234)
## Why
The k8s au-syd1 VictoriaMetrics stack ran as two helm charts and only scraped in-cluster targets. The victoria-metrics-operator already runs in vm-system, so this moves the stack onto operator-managed CRDs. That unlocks VMServiceScrape/VMPodScrape (auto-converted from Prometheus ServiceMonitors, used by a follow-up PR) and adds Consul service discovery so the cluster scrapes the **same puppet-prod targets** as the puppet vmagent. Also shrinks vmstorage 3 → 2 (Ceph-backed, replicationFactor 2).

## Changes
- Add **VMCluster `main`**: vmstorage 2 replicas (cephrbd-fast-delete 200Gi, 180d retention, replicationFactor 2), vminsert/vmselect 2 replicas + HPA (2–10, 60% cpu).
- Add **VMAgent `main`**: retains the kubernetes SD jobs (apiservers/nodes/cadvisor), `selectAllByDefault` for VMServiceScrape/VMPodScrape, and a **Consul SD job** against `consul.service.consul` (resolves to the puppet Consul from pods) replicating the puppet vmagent relabels — keep tag `metrics`, `__scheme__` from `metrics_scheme`, `job` from `metrics_job`. TLS is **verified against the reflected `vault-ca-cert`** (no insecure skip-verify).
- Expose vmselect/vminsert/vmagent via **Gateway API** (traefik-internal Gateway + HTTPRoute, http→https redirect), same hostnames.
- Remove the two helm charts, their values files, and vendored charts.

## Notes
- Data wipe on cutover is acceptable (confirmed) — old helm PVCs can be deleted.
- Verify at rollout: pods resolve `*.main.unkin.net` node FQDNs (needed for CA SAN match on scrape targets); `/targets` shows `job=consul`.

Reviewed-on: #234
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-07-05 22:17:32 +10:00
unkinben 3df8ac2779 grafana-system: deploy grafana-operator
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/kubeconform Pipeline was successful
Adds the grafana-operator (grafana.integreatly.org CRDs + controller) so
Grafana and its dashboards/datasources can be managed declaratively as
CRs in a follow-up PR. Sits in the platform project like the other
operators (vm-system, cnpg-system).

Changes:
- Add grafana-system namespace + grafana-operator helm chart v5.24.0
  (watches all namespaces).
- Render CRDs inline (crds.immutable: false) so ArgoCD installs/manages
  the 13 grafana.integreatly.org CRDs instead of the skipped helm crds/
  subchart.
- Register apps/overlays/*/grafana-system in the platform ApplicationSet.
2026-07-05 22:16:30 +10:00
benvin 53b55419a7 chore: add encapi to platform project (#233)
- ensure encapi is deployed to platform

---------

Co-authored-by: Ben Vincent <ben@unkin.net>
Reviewed-on: #233
2026-07-05 17:57:49 +10:00
benvin 56d60f969c bump artifactapi to 3.7.6 (#232)
Co-authored-by: Ben Vincent <ben@unkin.net>
Reviewed-on: #232
2026-07-05 17:51:59 +10:00
unkinben 333e638e24 deploy encapi to au-syd1 (#230)
## Why
encapi is the new Postgres-backed Puppet ENC that replaces Cobbler (Go API + encapi-cli + terraform provider). It needs to run somewhere reachable by the puppet masters (`encapi-cli classify`) and every node's `enc_direct_facts` fact. Deploy it in k8s alongside artifactapi, exposed at `encapi.k8s.syd1.au.unkin.net`.

## Changes
- add `apps/base/encapi/`: namespace, deployment (`git.unkin.net/unkin/encapi`, port 8000, `/healthz` probes), service, gateway + httproute (`encapi.k8s.syd1.au.unkin.net`, traefik-internal), configmap (DB coordinates), CNPG cluster + pooler (database `encapi`), and VaultAuth + VaultStaticSecrets (`postgres-credentials`, `environment`)
- add `apps/overlays/au-syd1/encapi` overlay referencing the base
- register `apps/overlays/*/encapi` in the platform ApplicationSet so ArgoCD picks it up

## Notes
- Mirrors the artifactapi pattern (VaultAuth role `default`, namespace-scoped VSO paths `kv/kubernetes/namespace/encapi/default/*`).
- Before first sync, seed the Vault KV secrets: `environment` must carry `DBPASS` (matching the CNPG owner password) and `ENCAPI_WRITE_TOKEN`; `postgres-credentials` carries the CNPG owner username/password.
- `kustomize build apps/overlays/au-syd1/encapi` validates clean (11 resources).

---------

Co-authored-by: unkinben <neotheo@gmail.com>
Reviewed-on: #230
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-07-05 17:41:21 +10:00
unkinben 6ed436b973 chore: bump artifactapi to v3.7.5 (#231)
## Why

Roll out artifactapi `v3.7.5`, which ships the local docker registry (artifactapi#103): local `docker` repos now serve the Docker Registry HTTP API V2 for push and pull.

## Changes

- `apps/base/artifactapi/api-deployment.yaml`: `artifactapi` image `v3.7.4` → `v3.7.5`
- `apps/base/artifactapi/ui-deployment.yaml`: `artifactapi-ui` image `v3.7.4` → `v3.7.5`

## Heads-up (follow-up needed)

The API HPA runs `minReplicas: 2`. Local-docker **chunked** blob uploads keep the upload session in-memory per replica, so a real `docker push` (POST → PATCH → PUT across replicas, no session affinity) can intermittently 404 with `BLOB_UPLOAD_UNKNOWN`. Monolithic pushes are unaffected. Recommend a follow-up to make upload sessions replica-independent (S3-backed) or add session affinity for `/v2/*/blobs/uploads/` before relying on pushes in anger.

Reviewed-on: #231
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-07-05 17:14:08 +10:00
unkinben e030f07986 Add primary (write) Services to authoritative + externaldns (#229)
**Stacked on #228** (needs operator v0.1.5). Merge #228 first; the diff collapses to just this after.

## Why
Writes (RFC2136/nsupdate) must go to pod-0 — the round-robin read Service would land them on a secondary (rejected). Adds a dedicated write endpoint per cluster (operator v0.1.5 `primaryService`).

## Changes
- `bind-authoritative`: LoadBalancer write endpoint on **198.18.200.9** (`bind-authoritative-primary`)
- `bind-externaldns`: ClusterIP write endpoint (`bind-externaldns-primary`, for in-cluster writers)
- regenerate the bindcluster kubeconform schema (primaryService + externalTrafficPolicy)

## Deferred
external-dns is **not** repointed at `bind-externaldns-primary` yet: it authenticates with the existing TSIG key, which the operator-generated key won't match until the planned Vault-sync + secret-reflection features exist. Until then external-dns keeps writing to the puppet externaldns.

## Validated
kustomize build + kubeconform (3 BindClusters valid against the v0.1.5 schema).

---------

Co-authored-by: BenVincent <benvin@main.unkin.net>
Reviewed-on: #229
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-07-05 16:37:49 +10:00
unkinben 15e70404ae Use externalTrafficPolicy: Local on the DNS services (#228)
- bump operator to v0.1.5 (CRD link + image)

Reviewed-on: #228
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-07-05 16:08:47 +10:00
unkinben 3ab8bcc34b Restrict authoritative queries to internal networks (#227)
Mirrors the puppet authoritative `master-zones` view (match-clients `acl-main.unkin.net`, recursion no) — restricting who can query bind-authoritative.

## Changes
- add `auth-acl-main` BindACL with the puppet authoritative acl-main.unkin.net networks (13-17,19,20,24-29)
- `allow-query { auth-acl-main; 10.42.0.0/16; }` on bind-authoritative via extraOptions

## Notes
- Implemented as a global `allow-query` rather than a BindView: dynamic *primary* zones inside a view would need per-view `allow-new-zones` (an operator gap). Functionally equivalent for the single master-zones view.
- `10.42.0.0/16` (pod network) is included so secondaries can SOA-refresh from the primary during catalog replication — without it, replication breaks.
- Works on the current operator (no HOLD).

## Caveat
The DNS Services use externalTrafficPolicy: Cluster, which SNATs external clients to node IPs (198.18.19.x, already in acl-main), so this ACL doesn't truly restrict *external* clients yet. True source-IP restriction needs externalTrafficPolicy: Local — happy to switch if wanted.

Reviewed-on: #227
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-07-04 22:15:43 +10:00
unkinben c8d61205ce Configure resolvers like puppet (openforwarder view + forward zones) (#226)
## Why
`dig google.com @198.18.200.7` was refused: the resolver never set allow-recursion, so BIND defaulted to localnets/localhost. This mirrors the puppet resolver (/etc/named/views.conf + acls.conf) exactly.

## Changes
- `openforwarder` BindView: `match-clients` = the 4 internal ACLs, recursion yes, allow-recursion/allow-query `any` (match-clients gates)
- 4 BindACLs from puppet acls.conf (acl-main.unkin.net/acl-dmz/acl-common/acl-nomad-jobs)
- 26 conditional forward zones in the view (unkin→198.18.19.15, consul→.14, k8s→.20, dmz/network/prod + 10.10.x reverse → 10.10.16.32/33)
- global forwarders 8.8.8.8/1.1.1.1
- operator image → v0.1.4

## Note
Forward-zone upstreams point at the **puppet anycast** servers (still authoritative during migration); flip to the in-cluster authoritative/externaldns LBs once zone data is migrated.

## Validated
kustomize build (59 docs), kubeconform clean.

Reviewed-on: #226
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-07-04 21:55:33 +10:00
unkinben ce8ebc71ce Consolidate BIND DNS into one bind-internal namespace (#225)
**HOLD until v0.1.3 is tagged/built** (operator #4 merged + tagged) — this PR bumps the operator to v0.1.3, whose CRD adds the `clusterRef` field these keys use.

## Why
Put all BIND DNS services in one `bind-internal` namespace and name the StatefulSets clearly.

## Changes
- 3 clusters consolidated into `bind-internal`, StatefulSets renamed **bind-authoritative** / **bind-resolvers** / **bind-externaldns**; LBs kept on 198.18.200.6/.7/.8; external-dns hostnames renamed to match
- `clusterRef` added to `transfer-key` (→ bind-authoritative) and `externaldns-key` (→ bind-externaldns) so keys are scoped per cluster
- removed the old `ns-auth`/`ns-resolver`/`ns-externaldns` apps; ApplicationSet + AppProject now list `bind-internal`
- bumped `bind-system` operator to **v0.1.3** (CRD link + image)
- operator stays in `bind-system`

## Deploy impact
ArgoCD prunes the old ns-* namespaces (StatefulSets/PVCs — data is only seed SOA+NS, no migrated records yet) and creates the renamed clusters in bind-internal.

## Validated
`kustomize build` → 28 docs (3 BindCluster, 20 BindZone, 2 catalog, 2 keys, ns); kubeconform clean.

Reviewed-on: #225
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-07-04 00:35:43 +10:00
unkinben 7c9a697452 Deploy binddns-externaldns (RFC2136 dynamic cluster) (#222)
Part of the bind rollout split. **Merge #219 (bind-operator) first** — stacked on it; diff reduces to the binddns-externaldns files once #219 merges.

## Why
The external-dns tier (replaces 3x Puppet external-dns servers): an authoritative cluster whose zones accept RFC2136 TSIG updates from external-dns.

## Changes
- `apps/base/binddns-externaldns`: authoritative `BindCluster` (3 replicas, LoadBalancer/PureLB), `BindTSIGKey` for RFC2136, namespace
- au-syd1 `binddns-externaldns` overlay

## Deploy impact
Creates the `binddns-externaldns` StatefulSet + LoadBalancer once merged.

Reviewed-on: #222
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-07-03 23:09:36 +10:00
unkinben 6affc5d8f4 Deploy binddns-resolver (recursive resolver cluster) (#221)
Part of the bind rollout split. **Merge #219 (bind-operator) first** — stacked on it; diff reduces to the binddns-resolver files once #219 merges.

## Why
The recursive-resolver tier (replaces 3x Puppet only-resolver servers): 3 identical recursive servers with upstream forwarders.

## Changes
- `apps/base/binddns-resolver`: resolver `BindCluster` (3 replicas, forwarders, LoadBalancer/PureLB), namespace
- au-syd1 `binddns-resolver` overlay

## Deploy impact
Creates the `binddns-resolver` StatefulSet + LoadBalancer once merged.

Reviewed-on: #221
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-07-03 23:08:06 +10:00
unkinben de123af1b1 Bump bind-operator image to v0.1.2 (#224)
**HOLD until v0.1.2 is tagged/built** (bind-operator #3 merged + tagged).

Picks up the zone-provisioning fix (seed glue A record + IP-based primaries + Pod watch) so the clusters stop failing to load their zones.

- `apps/base/bind-system/deployment.yaml`: image v0.1.1 -> v0.1.2

Reviewed-on: #224
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-07-03 23:03:37 +10:00
unkinben 649ed07ab0 Deploy binddns-auth (authoritative BIND cluster) (#220)
Part of the bind rollout split. **Merge #219 (bind-operator) first** — this PR is stacked on it, so its diff will reduce to just the binddns-auth files once #219 merges.

## Why
The authoritative masters tier (replaces 3x Puppet authoritative servers): pod-0 primary + 2 secondaries replicating via the catalog zone + AXFR/IXFR.

## Changes
- `apps/base/binddns-auth`: authoritative `BindCluster` (3 replicas, LoadBalancer/PureLB), `BindCatalogZone`, transfer `BindTSIGKey`, namespace
- au-syd1 `binddns-auth` overlay

## Deploy impact
Creates the `binddns-auth` StatefulSet + LoadBalancer once merged.

Reviewed-on: #220
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-07-03 21:23:25 +10:00
unkinben dbb5ad4f86 Rename bind DNS namespaces to ns-* (#223)
Renames the three BIND DNS app namespaces `binddns-{auth,resolver,externaldns}` -> `ns-{auth,resolver,externaldns}`.

## Why
Shorter, clearer namespace names for the DNS tiers.

## Changes
- `argocd/applicationsets/platform.yaml`: overlay path registrations renamed (the ApplicationSet derives each app's namespace from its overlay dir name)
- `argocd/projects/platform.yaml`: destination namespaces renamed

## Coupled with
The per-tier PRs (#220/#221/#222) rename the overlay dirs + namespaces + external-dns hostnames to match. No app deploys to a renamed namespace until both this and the tier PR are merged (harmless before then — the ApplicationSet only instantiates apps for existing dirs).

Reviewed-on: #223
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-07-03 21:16:24 +10:00
62 changed files with 14160 additions and 313 deletions
+1 -1
View File
@@ -35,7 +35,7 @@ spec:
mountPath: /combined-certs mountPath: /combined-certs
containers: containers:
- name: api - name: api
image: git.unkin.net/unkin/artifactapi:v3.7.4 image: git.unkin.net/unkin/artifactapi:v3.7.6
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
ports: ports:
- containerPort: 8000 - containerPort: 8000
+1 -1
View File
@@ -22,7 +22,7 @@ spec:
automountServiceAccountToken: true automountServiceAccountToken: true
containers: containers:
- name: ui - name: ui
image: git.unkin.net/unkin/artifactapi-ui:v3.7.4 image: git.unkin.net/unkin/artifactapi-ui:v3.7.6
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
ports: ports:
- containerPort: 80 - containerPort: 80
@@ -0,0 +1,26 @@
---
# Internal client networks allowed to query the authoritative servers,
# mirrored from the puppet authoritative /etc/named/acls.conf
# (acl-main.unkin.net). Named auth-acl-main because the resolver has its own,
# differently-scoped acl-main.unkin.net in the same namespace.
apiVersion: bind.unkin.net/v1alpha1
kind: BindACL
metadata:
name: auth-acl-main
namespace: bind-internal
spec:
clusterRef: bind-authoritative
entries:
- 198.18.13.0/24
- 198.18.14.0/24
- 198.18.15.0/24
- 198.18.16.0/24
- 198.18.17.0/24
- 198.18.19.0/24
- 198.18.20.0/24
- 198.18.24.0/24
- 198.18.25.0/24
- 198.18.26.0/24
- 198.18.27.0/24
- 198.18.28.0/24
- 198.18.29.0/24
@@ -0,0 +1,49 @@
---
# Authoritative masters (replaces the 3x Puppet authoritative servers).
# pod-0 is the primary; pods 1-2 replicate via the catalog zone + AXFR/IXFR.
apiVersion: bind.unkin.net/v1alpha1
kind: BindCluster
metadata:
name: bind-authoritative
namespace: bind-internal
spec:
mode: authoritative
replicas: 3
storageClassName: cephrbd-fast-delete
storageSize: 2Gi
# Restrict queries to internal networks (puppet acl-main.unkin.net).
# 10.42.0.0/16 (pod net) is required so secondaries can SOA-refresh
# from the primary during catalog replication.
extraOptions:
- "allow-query { auth-acl-main; 10.42.0.0/16; }"
service:
type: LoadBalancer
externalTrafficPolicy: Local
annotations:
purelb.io/service-group: common
purelb.io/addresses: 198.18.200.6
external-dns.alpha.kubernetes.io/hostname: bind-authoritative.k8s.syd1.au.unkin.net
primaryService:
type: LoadBalancer
annotations:
purelb.io/service-group: common
purelb.io/addresses: 198.18.200.9
external-dns.alpha.kubernetes.io/hostname: bind-authoritative-primary.k8s.syd1.au.unkin.net
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: "1"
memory: 512Mi
---
# Catalog zone so new BindZones auto-provision onto the secondaries.
apiVersion: bind.unkin.net/v1alpha1
kind: BindCatalogZone
metadata:
name: bind-authoritative-catalog
namespace: bind-internal
spec:
clusterRef: bind-authoritative
zoneName: catalog.internal
transferKeyRef: transfer-key
@@ -0,0 +1,9 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- cluster.yaml
- tsigkey.yaml
- zones.yaml
- acls.yaml
@@ -0,0 +1,11 @@
---
# Zone-transfer / catalog key. The operator generates the material into a
# Secret (transfer-key-tsig); nothing sensitive is committed to git.
apiVersion: bind.unkin.net/v1alpha1
kind: BindTSIGKey
metadata:
name: transfer-key
namespace: bind-internal
spec:
clusterRef: bind-authoritative
algorithm: hmac-sha256
@@ -0,0 +1,204 @@
# Authoritative zones migrated from puppet-prod
# (profiles::dns::master::zones in hieradata/roles/infra/dns/master.yaml).
# type primary, static (puppet dynamic:false); TTL 600 as in the puppet zone header.
# Record data is populated by PuppetDB exported resources upstream, so it is
# NOT in this repo — migrate it into these zones (AXFR from the current masters,
# or DNSRecord CRs) as a follow-up. The zones start with SOA+NS only.
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: unkin-net
namespace: bind-internal
spec:
clusterRef: bind-authoritative
zoneName: unkin.net
type: primary
defaultTTL: 600
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: main-unkin-net
namespace: bind-internal
spec:
clusterRef: bind-authoritative
zoneName: main.unkin.net
type: primary
defaultTTL: 600
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: 13-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-authoritative
zoneName: 13.18.198.in-addr.arpa
type: primary
defaultTTL: 600
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: 14-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-authoritative
zoneName: 14.18.198.in-addr.arpa
type: primary
defaultTTL: 600
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: 15-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-authoritative
zoneName: 15.18.198.in-addr.arpa
type: primary
defaultTTL: 600
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: 16-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-authoritative
zoneName: 16.18.198.in-addr.arpa
type: primary
defaultTTL: 600
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: 17-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-authoritative
zoneName: 17.18.198.in-addr.arpa
type: primary
defaultTTL: 600
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: 19-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-authoritative
zoneName: 19.18.198.in-addr.arpa
type: primary
defaultTTL: 600
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: 20-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-authoritative
zoneName: 20.18.198.in-addr.arpa
type: primary
defaultTTL: 600
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: 21-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-authoritative
zoneName: 21.18.198.in-addr.arpa
type: primary
defaultTTL: 600
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: 22-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-authoritative
zoneName: 22.18.198.in-addr.arpa
type: primary
defaultTTL: 600
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: 23-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-authoritative
zoneName: 23.18.198.in-addr.arpa
type: primary
defaultTTL: 600
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: 24-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-authoritative
zoneName: 24.18.198.in-addr.arpa
type: primary
defaultTTL: 600
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: 25-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-authoritative
zoneName: 25.18.198.in-addr.arpa
type: primary
defaultTTL: 600
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: 26-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-authoritative
zoneName: 26.18.198.in-addr.arpa
type: primary
defaultTTL: 600
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: 27-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-authoritative
zoneName: 27.18.198.in-addr.arpa
type: primary
defaultTTL: 600
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: 28-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-authoritative
zoneName: 28.18.198.in-addr.arpa
type: primary
defaultTTL: 600
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: 29-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-authoritative
zoneName: 29.18.198.in-addr.arpa
type: primary
defaultTTL: 600
@@ -0,0 +1,42 @@
---
# external-dns tier (replaces the 3x Puppet external-dns servers). An ordinary
# authoritative cluster; external-dns writes to its zones via RFC2136 because
# those BindZones set dynamicUpdate (allow-update { key externaldns-key; }).
apiVersion: bind.unkin.net/v1alpha1
kind: BindCluster
metadata:
name: bind-externaldns
namespace: bind-internal
spec:
mode: authoritative
replicas: 3
storageClassName: cephrbd-fast-delete
storageSize: 1Gi
service:
type: LoadBalancer
externalTrafficPolicy: Local
annotations:
purelb.io/service-group: common
purelb.io/addresses: 198.18.200.8
external-dns.alpha.kubernetes.io/hostname: bind-externaldns.k8s.syd1.au.unkin.net
primaryService:
type: ClusterIP
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: "1"
memory: 512Mi
---
# Catalog zone so the dynamic zones replicate onto the cluster's secondaries
# (external-dns writes to the primary; secondaries IXFR the result).
apiVersion: bind.unkin.net/v1alpha1
kind: BindCatalogZone
metadata:
name: bind-externaldns-catalog
namespace: bind-internal
spec:
clusterRef: bind-externaldns
zoneName: catalog.externaldns.internal
transferKeyRef: externaldns-key
@@ -0,0 +1,8 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- cluster.yaml
- tsigkey.yaml
- zones.yaml
@@ -0,0 +1,11 @@
---
# Key that external-dns (and DNSRecord objects) use to send RFC2136 dynamic
# updates to the primary. The operator generates the material into a Secret.
apiVersion: bind.unkin.net/v1alpha1
kind: BindTSIGKey
metadata:
name: externaldns-key
namespace: bind-internal
spec:
clusterRef: bind-externaldns
algorithm: hmac-sha256
@@ -0,0 +1,34 @@
# k8s external-dns zones migrated from puppet-prod
# (externaldns::k8s_zones in hieradata/roles/infra/dns/externaldns.yaml).
# Primary + dynamicUpdate: the Kubernetes external-dns controller writes
# records here via RFC2136 authenticated with externaldns-key.
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: k8s-syd1-au-unkin-net
namespace: bind-internal
spec:
clusterRef: bind-externaldns
zoneName: k8s.syd1.au.unkin.net
type: primary
defaultTTL: 600
dynamicUpdate: true
updateKeyRef: externaldns-key
allowTransfer:
- key externaldns-key
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: 200-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-externaldns
zoneName: 200.18.198.in-addr.arpa
type: primary
defaultTTL: 600
dynamicUpdate: true
updateKeyRef: externaldns-key
allowTransfer:
- key externaldns-key
@@ -0,0 +1,9 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- authoritative
- resolvers
- externaldns
+5
View File
@@ -0,0 +1,5 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: bind-internal
@@ -0,0 +1,65 @@
# Internal client ACLs, mirrored from puppet /etc/named/acls.conf.
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindACL
metadata:
name: acl-main.unkin.net
namespace: bind-internal
spec:
clusterRef: bind-resolvers
entries:
- 198.18.1.10/32
- 198.18.2.160/27
- 198.18.21.160/27
- 198.18.2.192/27
- 198.18.21.192/27
- 198.18.13.0/24
- 198.18.14.0/24
- 198.18.15.0/24
- 198.18.16.0/24
- 198.18.17.0/24
- 198.18.18.0/24
- 198.18.19.0/24
- 198.18.20.0/24
- 198.18.21.0/24
- 198.18.22.0/24
- 198.18.23.0/24
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindACL
metadata:
name: acl-dmz
namespace: bind-internal
spec:
clusterRef: bind-resolvers
entries:
- 198.18.24.0/24
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindACL
metadata:
name: acl-common
namespace: bind-internal
spec:
clusterRef: bind-resolvers
entries:
- 198.18.25.0/24
- 198.18.26.0/24
- 198.18.27.0/24
- 198.18.28.0/24
- 198.18.29.0/24
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindACL
metadata:
name: acl-nomad-jobs
namespace: bind-internal
spec:
clusterRef: bind-resolvers
entries:
- 198.18.64.0/24
- 198.18.65.0/24
- 198.18.66.0/24
- 198.18.67.0/24
- 198.18.68.0/24
- 198.18.69.0/24
@@ -0,0 +1,30 @@
---
# Recursive resolvers (replaces the 3x Puppet only-resolver servers).
# Three identical recursive servers; no zone replication.
apiVersion: bind.unkin.net/v1alpha1
kind: BindCluster
metadata:
name: bind-resolvers
namespace: bind-internal
spec:
mode: resolver
replicas: 3
storageClassName: cephrbd-fast-delete
storageSize: 1Gi
service:
type: LoadBalancer
externalTrafficPolicy: Local
annotations:
purelb.io/service-group: common
purelb.io/addresses: 198.18.200.7
external-dns.alpha.kubernetes.io/hostname: bind-resolvers.k8s.syd1.au.unkin.net
forwarders:
- 8.8.8.8
- 1.1.1.1
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: "1"
memory: 512Mi
@@ -0,0 +1,284 @@
# Conditional forward zones, from the puppet openforwarder view.
# Upstreams: unkin authoritative 198.18.200.6, consul 198.18.19.14, k8s 198.18.200.8.
# k8s -> in-cluster bind-externaldns 198.18.200.8.
# (Zones that forwarded to 10.10.16.x were dropped; consul left as-is.)
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: fwd-unkin-net
namespace: bind-internal
spec:
clusterRef: bind-resolvers
viewRef: openforwarder
zoneName: unkin.net
type: forward
catalog: false
forwarders:
- 198.18.200.6
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: fwd-main-unkin-net
namespace: bind-internal
spec:
clusterRef: bind-resolvers
viewRef: openforwarder
zoneName: main.unkin.net
type: forward
catalog: false
forwarders:
- 198.18.200.6
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: fwd-consul
namespace: bind-internal
spec:
clusterRef: bind-resolvers
viewRef: openforwarder
zoneName: consul
type: forward
catalog: false
forwarders:
- 198.18.19.14
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: fwd-k8s-syd1-au-unkin-net
namespace: bind-internal
spec:
clusterRef: bind-resolvers
viewRef: openforwarder
zoneName: k8s.syd1.au.unkin.net
type: forward
catalog: false
forwarders:
- 198.18.200.8
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: fwd-13-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-resolvers
viewRef: openforwarder
zoneName: 13.18.198.in-addr.arpa
type: forward
catalog: false
forwarders:
- 198.18.200.6
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: fwd-14-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-resolvers
viewRef: openforwarder
zoneName: 14.18.198.in-addr.arpa
type: forward
catalog: false
forwarders:
- 198.18.200.6
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: fwd-15-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-resolvers
viewRef: openforwarder
zoneName: 15.18.198.in-addr.arpa
type: forward
catalog: false
forwarders:
- 198.18.200.6
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: fwd-16-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-resolvers
viewRef: openforwarder
zoneName: 16.18.198.in-addr.arpa
type: forward
catalog: false
forwarders:
- 198.18.200.6
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: fwd-17-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-resolvers
viewRef: openforwarder
zoneName: 17.18.198.in-addr.arpa
type: forward
catalog: false
forwarders:
- 198.18.200.6
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: fwd-19-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-resolvers
viewRef: openforwarder
zoneName: 19.18.198.in-addr.arpa
type: forward
catalog: false
forwarders:
- 198.18.200.6
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: fwd-20-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-resolvers
viewRef: openforwarder
zoneName: 20.18.198.in-addr.arpa
type: forward
catalog: false
forwarders:
- 198.18.200.6
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: fwd-21-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-resolvers
viewRef: openforwarder
zoneName: 21.18.198.in-addr.arpa
type: forward
catalog: false
forwarders:
- 198.18.200.6
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: fwd-22-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-resolvers
viewRef: openforwarder
zoneName: 22.18.198.in-addr.arpa
type: forward
catalog: false
forwarders:
- 198.18.200.6
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: fwd-23-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-resolvers
viewRef: openforwarder
zoneName: 23.18.198.in-addr.arpa
type: forward
catalog: false
forwarders:
- 198.18.200.6
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: fwd-24-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-resolvers
viewRef: openforwarder
zoneName: 24.18.198.in-addr.arpa
type: forward
catalog: false
forwarders:
- 198.18.200.6
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: fwd-25-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-resolvers
viewRef: openforwarder
zoneName: 25.18.198.in-addr.arpa
type: forward
catalog: false
forwarders:
- 198.18.200.6
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: fwd-26-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-resolvers
viewRef: openforwarder
zoneName: 26.18.198.in-addr.arpa
type: forward
catalog: false
forwarders:
- 198.18.200.6
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: fwd-27-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-resolvers
viewRef: openforwarder
zoneName: 27.18.198.in-addr.arpa
type: forward
catalog: false
forwarders:
- 198.18.200.6
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: fwd-28-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-resolvers
viewRef: openforwarder
zoneName: 28.18.198.in-addr.arpa
type: forward
catalog: false
forwarders:
- 198.18.200.6
---
apiVersion: bind.unkin.net/v1alpha1
kind: BindZone
metadata:
name: fwd-29-18-198-in-addr-arpa
namespace: bind-internal
spec:
clusterRef: bind-resolvers
viewRef: openforwarder
zoneName: 29.18.198.in-addr.arpa
type: forward
catalog: false
forwarders:
- 198.18.200.6
@@ -0,0 +1,9 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- cluster.yaml
- acls.yaml
- view.yaml
- forward-zones.yaml
@@ -0,0 +1,23 @@
---
# openforwarder view, mirrored from puppet /etc/named/views.conf.
# match-clients gates access to internal networks; recursion/query are 'any'
# within the view since match-clients already restricts who reaches it.
apiVersion: bind.unkin.net/v1alpha1
kind: BindView
metadata:
name: openforwarder
namespace: bind-internal
spec:
clusterRef: bind-resolvers
order: 100
matchClients:
- acl-main.unkin.net
- acl-nomad-jobs
- acl-common
- acl-dmz
recursion: true
allowQuery:
- any
extraOptions:
- "allow-recursion { any; }"
- "allow-query-cache { any; }"
+1 -1
View File
@@ -21,7 +21,7 @@ spec:
runAsNonRoot: true runAsNonRoot: true
containers: containers:
- name: operator - name: operator
image: git.unkin.net/unkin/bind-operator:v0.1.1 image: git.unkin.net/unkin/bind-operator:v0.1.5
args: args:
- --metrics-bind-address=:8080 - --metrics-bind-address=:8080
- --health-probe-bind-address=:8081 - --health-probe-bind-address=:8081
+1 -1
View File
@@ -6,6 +6,6 @@ resources:
- namespace.yaml - namespace.yaml
# CRDs are pulled from the bind-operator repo at the matching tag rather than # CRDs are pulled from the bind-operator repo at the matching tag rather than
# vendored here, so they never drift from the operator. # vendored here, so they never drift from the operator.
- https://git.unkin.net/unkin/bind-operator/raw/tag/v0.1.1/config/crd/install.yaml - https://git.unkin.net/unkin/bind-operator/raw/tag/v0.1.5/config/crd/install.yaml
- rbac.yaml - rbac.yaml
- deployment.yaml - deployment.yaml
+91
View File
@@ -0,0 +1,91 @@
---
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: postgres
namespace: encapi
spec:
affinity:
podAntiAffinityType: preferred
bootstrap:
initdb:
database: encapi
encoding: UTF8
localeCType: C
localeCollate: C
owner: encapi
secret:
name: postgres-credentials
enablePDB: true
enableSuperuserAccess: false
failoverDelay: 0
imageName: ghcr.io/cloudnative-pg/postgresql:18.1-system-trixie
instances: 3
logLevel: info
maxSyncReplicas: 0
minSyncReplicas: 0
monitoring:
customQueriesConfigMap:
- key: queries
name: cnpg-default-monitoring
disableDefaultQueries: false
enablePodMonitor: false
postgresql:
parameters:
archive_mode: "on"
archive_timeout: 5min
dynamic_shared_memory_type: posix
effective_cache_size: 256MB
full_page_writes: "on"
log_destination: csvlog
log_directory: /controller/log
log_filename: postgres
log_rotation_age: "0"
log_rotation_size: "0"
log_truncate_on_rotation: "false"
logging_collector: "on"
max_connections: "200"
max_parallel_workers: "16"
max_replication_slots: "16"
max_worker_processes: "16"
shared_buffers: 128MB
shared_memory_type: mmap
ssl_max_protocol_version: TLSv1.3
ssl_min_protocol_version: TLSv1.3
wal_keep_size: 256MB
wal_level: logical
wal_log_hints: "on"
wal_receiver_timeout: 5s
wal_sender_timeout: 5s
syncReplicaElectionConstraint:
enabled: false
primaryUpdateMethod: restart
primaryUpdateStrategy: unsupervised
probes:
liveness:
isolationCheck:
connectionTimeout: 1000
enabled: true
requestTimeout: 1000
replicationSlots:
highAvailability:
enabled: true
slotPrefix: _cnpg_
synchronizeReplicas:
enabled: true
updateInterval: 30
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 250m
memory: 256Mi
smartShutdownTimeout: 180
startDelay: 3600
stopDelay: 1800
storage:
resizeInUseVolumes: true
size: 10Gi
storageClass: cephrbd-fast-delete
switchoverDelay: 3600
+33
View File
@@ -0,0 +1,33 @@
---
apiVersion: postgresql.cnpg.io/v1
kind: Pooler
metadata:
name: postgres-pooler
namespace: encapi
spec:
cluster:
name: postgres
instances: 2
pgbouncer:
parameters:
default_pool_size: "100"
max_client_conn: "400"
paused: false
poolMode: session
template:
metadata:
labels:
app: pooler
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- pooler
topologyKey: kubernetes.io/hostname
containers: []
type: rw
+13
View File
@@ -0,0 +1,13 @@
---
apiVersion: v1
kind: ConfigMap
metadata:
name: encapi-env
namespace: encapi
data:
LISTEN_ADDR: ":8000"
DBHOST: postgres-pooler
DBNAME: encapi
DBPORT: "5432"
DBUSER: encapi
DBSSL: require
+64
View File
@@ -0,0 +1,64 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: encapi
namespace: encapi
annotations:
reloader.stakater.com/auto: "true"
spec:
replicas: 2
selector:
matchLabels:
app: encapi
strategy:
rollingUpdate:
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
labels:
app: encapi
spec:
automountServiceAccountToken: true
containers:
- name: encapi
image: git.unkin.net/unkin/encapi:v0.1.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8000
name: http
protocol: TCP
envFrom:
# DBHOST/DBNAME/DBPORT/DBUSER/DBSSL/LISTEN_ADDR
- configMapRef:
name: encapi-env
optional: false
# DBPASS + ENCAPI_WRITE_TOKEN (seeded in Vault, see cutover notes)
- secretRef:
name: environment
optional: false
livenessProbe:
httpGet:
path: /healthz
port: http
initialDelaySeconds: 15
periodSeconds: 30
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /healthz
port: http
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 5
failureThreshold: 3
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 500m
memory: 256Mi
restartPolicy: Always
+37
View File
@@ -0,0 +1,37 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
labels:
traefik.io/instance: internal
annotations:
cert-manager.io/cluster-issuer: vault-issuer
cert-manager.io/common-name: encapi.k8s.syd1.au.unkin.net
cert-manager.io/private-key-size: "4096"
external-dns.alpha.kubernetes.io/hostname: encapi.k8s.syd1.au.unkin.net
external-dns.alpha.kubernetes.io/target: 198.18.200.4
name: encapi
namespace: encapi
spec:
gatewayClassName: traefik-internal
listeners:
- allowedRoutes:
namespaces:
from: Same
hostname: encapi.k8s.syd1.au.unkin.net
name: http
port: 80
protocol: HTTP
- allowedRoutes:
namespaces:
from: Same
hostname: encapi.k8s.syd1.au.unkin.net
name: https
port: 443
protocol: HTTPS
tls:
certificateRefs:
- group: ""
kind: Secret
name: encapi-tls
mode: Terminate
+49
View File
@@ -0,0 +1,49 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: encapi-http-redirect
namespace: encapi
spec:
hostnames:
- encapi.k8s.syd1.au.unkin.net
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: encapi
sectionName: http
rules:
- filters:
- type: RequestRedirect
requestRedirect:
scheme: https
statusCode: 301
matches:
- path:
type: PathPrefix
value: /
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: encapi
namespace: encapi
spec:
hostnames:
- encapi.k8s.syd1.au.unkin.net
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: encapi
sectionName: https
rules:
- backendRefs:
- group: ""
kind: Service
name: encapi
port: 80
weight: 1
matches:
- path:
type: PathPrefix
value: /
+15
View File
@@ -0,0 +1,15 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- configmap.yaml
- deployment.yaml
- service.yaml
- gateway.yaml
- httproute.yaml
- cnpg_cluster.yaml
- cnpg_pooler.yaml
- vaultauth.yaml
- vaultstaticsecret.yaml
+5
View File
@@ -0,0 +1,5 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: encapi
+17
View File
@@ -0,0 +1,17 @@
---
apiVersion: v1
kind: Service
metadata:
name: encapi
namespace: encapi
spec:
internalTrafficPolicy: Cluster
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
selector:
app: encapi
sessionAffinity: None
type: ClusterIP
+18
View File
@@ -0,0 +1,18 @@
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultAuth
metadata:
name: default
namespace: encapi
spec:
allowedNamespaces:
- encapi
kubernetes:
audiences:
- vault
role: default
serviceAccount: default
tokenExpirationSeconds: 600
method: kubernetes
mount: k8s/au/syd1
vaultConnectionRef: vso-system/default
+34
View File
@@ -0,0 +1,34 @@
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: postgres-credentials
namespace: encapi
spec:
destination:
create: true
name: postgres-credentials
overwrite: true
hmacSecretData: true
mount: kv
path: kubernetes/namespace/encapi/default/postgres-credentials
refreshAfter: 5m
type: kv-v2
vaultAuthRef: default
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: environment
namespace: encapi
spec:
destination:
create: true
name: environment
overwrite: true
hmacSecretData: true
mount: kv
path: kubernetes/namespace/encapi/default/environment
refreshAfter: 5m
type: kv-v2
vaultAuthRef: default
@@ -0,0 +1,6 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
+7
View File
@@ -0,0 +1,7 @@
---
apiVersion: v1
kind: Namespace
metadata:
labels:
app.kubernetes.io/name: grafana-system
name: grafana-system
+117
View File
@@ -0,0 +1,117 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: vmselect
namespace: observability
labels:
app.kubernetes.io/name: vmselect
app.kubernetes.io/instance: victoria-metrics
traefik.io/instance: internal
annotations:
cert-manager.io/cluster-issuer: vault-issuer
cert-manager.io/common-name: vmselect.k8s.syd1.au.unkin.net
cert-manager.io/private-key-size: "4096"
external-dns.alpha.kubernetes.io/hostname: vmselect.k8s.syd1.au.unkin.net
external-dns.alpha.kubernetes.io/target: 198.18.200.4
spec:
gatewayClassName: traefik-internal
listeners:
- name: http
port: 80
protocol: HTTP
hostname: vmselect.k8s.syd1.au.unkin.net
allowedRoutes:
namespaces:
from: Same
- name: https
port: 443
protocol: HTTPS
hostname: vmselect.k8s.syd1.au.unkin.net
allowedRoutes:
namespaces:
from: Same
tls:
mode: Terminate
certificateRefs:
- group: ""
kind: Secret
name: vmselect-tls
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: vminsert
namespace: observability
labels:
app.kubernetes.io/name: vminsert
app.kubernetes.io/instance: victoria-metrics
traefik.io/instance: internal
annotations:
cert-manager.io/cluster-issuer: vault-issuer
cert-manager.io/common-name: vminsert.k8s.syd1.au.unkin.net
cert-manager.io/private-key-size: "4096"
external-dns.alpha.kubernetes.io/hostname: vminsert.k8s.syd1.au.unkin.net
external-dns.alpha.kubernetes.io/target: 198.18.200.4
spec:
gatewayClassName: traefik-internal
listeners:
- name: http
port: 80
protocol: HTTP
hostname: vminsert.k8s.syd1.au.unkin.net
allowedRoutes:
namespaces:
from: Same
- name: https
port: 443
protocol: HTTPS
hostname: vminsert.k8s.syd1.au.unkin.net
allowedRoutes:
namespaces:
from: Same
tls:
mode: Terminate
certificateRefs:
- group: ""
kind: Secret
name: vminsert-tls
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: vmagent
namespace: observability
labels:
app.kubernetes.io/name: vmagent
app.kubernetes.io/instance: victoria-metrics
traefik.io/instance: internal
annotations:
cert-manager.io/cluster-issuer: vault-issuer
cert-manager.io/common-name: vmagent.k8s.syd1.au.unkin.net
cert-manager.io/private-key-size: "4096"
external-dns.alpha.kubernetes.io/hostname: vmagent.k8s.syd1.au.unkin.net
external-dns.alpha.kubernetes.io/target: 198.18.200.4
spec:
gatewayClassName: traefik-internal
listeners:
- name: http
port: 80
protocol: HTTP
hostname: vmagent.k8s.syd1.au.unkin.net
allowedRoutes:
namespaces:
from: Same
- name: https
port: 443
protocol: HTTPS
hostname: vmagent.k8s.syd1.au.unkin.net
allowedRoutes:
namespaces:
from: Same
tls:
mode: Terminate
certificateRefs:
- group: ""
kind: Secret
name: vmagent-tls
+165
View File
@@ -0,0 +1,165 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: vmselect-http-redirect
namespace: observability
labels:
app.kubernetes.io/name: vmselect
app.kubernetes.io/instance: victoria-metrics
spec:
hostnames:
- vmselect.k8s.syd1.au.unkin.net
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: vmselect
sectionName: http
rules:
- filters:
- type: RequestRedirect
requestRedirect:
scheme: https
statusCode: 301
matches:
- path:
type: PathPrefix
value: /
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: vmselect
namespace: observability
labels:
app.kubernetes.io/name: vmselect
app.kubernetes.io/instance: victoria-metrics
spec:
hostnames:
- vmselect.k8s.syd1.au.unkin.net
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: vmselect
sectionName: https
rules:
- backendRefs:
- group: ""
kind: Service
name: vmselect-main
port: 8481
weight: 1
matches:
- path:
type: PathPrefix
value: /
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: vminsert-http-redirect
namespace: observability
labels:
app.kubernetes.io/name: vminsert
app.kubernetes.io/instance: victoria-metrics
spec:
hostnames:
- vminsert.k8s.syd1.au.unkin.net
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: vminsert
sectionName: http
rules:
- filters:
- type: RequestRedirect
requestRedirect:
scheme: https
statusCode: 301
matches:
- path:
type: PathPrefix
value: /
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: vminsert
namespace: observability
labels:
app.kubernetes.io/name: vminsert
app.kubernetes.io/instance: victoria-metrics
spec:
hostnames:
- vminsert.k8s.syd1.au.unkin.net
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: vminsert
sectionName: https
rules:
- backendRefs:
- group: ""
kind: Service
name: vminsert-main
port: 8480
weight: 1
matches:
- path:
type: PathPrefix
value: /
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: vmagent-http-redirect
namespace: observability
labels:
app.kubernetes.io/name: vmagent
app.kubernetes.io/instance: victoria-metrics
spec:
hostnames:
- vmagent.k8s.syd1.au.unkin.net
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: vmagent
sectionName: http
rules:
- filters:
- type: RequestRedirect
requestRedirect:
scheme: https
statusCode: 301
matches:
- path:
type: PathPrefix
value: /
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: vmagent
namespace: observability
labels:
app.kubernetes.io/name: vmagent
app.kubernetes.io/instance: victoria-metrics
spec:
hostnames:
- vmagent.k8s.syd1.au.unkin.net
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: vmagent
sectionName: https
rules:
- backendRefs:
- group: ""
kind: Service
name: vmagent-main
port: 8429
weight: 1
matches:
- path:
type: PathPrefix
value: /
@@ -4,3 +4,7 @@ kind: Kustomization
resources: resources:
- namespace.yaml - namespace.yaml
- vmcluster.yaml
- vmagent.yaml
- gateway.yaml
- httproute.yaml
+122
View File
@@ -0,0 +1,122 @@
---
apiVersion: operator.victoriametrics.com/v1beta1
kind: VMAgent
metadata:
name: main
namespace: observability
spec:
replicaCount: 2
scrapeInterval: 15s
# Also consume VMServiceScrape / VMPodScrape / VMNodeScrape from every namespace
# (the operator auto-converts Prometheus ServiceMonitors -> VMServiceScrape).
selectAllByDefault: true
extraArgs:
loggerFormat: json
remoteWrite:
- url: http://vminsert-main.observability.svc.cluster.local:8480/insert/0/prometheus/
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: "1"
memory: 2Gi
# Reflected Vault intermediate CA (unkin.net) for verifying puppet Consul + metrics targets.
volumes:
- name: vault-ca
secret:
secretName: vault-ca-cert
volumeMounts:
- name: vault-ca
mountPath: /etc/vmagent-tls
readOnly: true
inlineScrapeConfig: |
- job_name: vmagent
static_configs:
- targets: ["localhost:8429"]
- job_name: "kubernetes-apiservers"
kubernetes_sd_configs:
- role: endpoints
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
insecure_skip_verify: true
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels:
- __meta_kubernetes_namespace
- __meta_kubernetes_service_name
- __meta_kubernetes_endpoint_port_name
action: keep
regex: default;kubernetes;https
- job_name: "kubernetes-nodes"
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
insecure_skip_verify: true
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
kubernetes_sd_configs:
- role: node
relabel_configs:
- action: labelmap
regex: __meta_kubernetes_node_label_(.+)
- job_name: "kubernetes-nodes-cadvisor"
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
insecure_skip_verify: true
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
kubernetes_sd_configs:
- role: node
metrics_path: /metrics/cadvisor
relabel_configs:
- action: labelmap
regex: __meta_kubernetes_node_label_(.+)
- source_labels: [__metrics_path__]
target_label: metrics_path
metric_relabel_configs:
- action: replace
source_labels: [pod]
regex: '(.+)'
target_label: pod_name
replacement: '${1}'
- action: replace
source_labels: [container]
regex: '(.+)'
target_label: container_name
replacement: '${1}'
- action: replace
target_label: name
replacement: k8s_stub
- action: replace
source_labels: [id]
regex: '^/system\.slice/(.+)\.service$'
target_label: systemd_service_name
replacement: '${1}'
# puppet-prod Consul service discovery (same targets as the puppet vmagent).
# consul.service.consul resolves to the puppet Consul from in-cluster pods.
- job_name: consul
consul_sd_configs:
- server: consul.service.consul:443
scheme: https
tls_config:
ca_file: /etc/vmagent-tls/ca.crt
relabel_configs:
- source_labels: [__meta_consul_tagpresent_metrics]
regex: "true"
action: keep
- source_labels: [__meta_consul_node, __meta_consul_service_port]
separator: ":"
target_label: __address__
replacement: "${1}:${2}"
action: replace
- source_labels: [__meta_consul_tag_metrics_scheme]
target_label: __scheme__
action: replace
- target_label: __metrics_path__
replacement: /metrics
- source_labels: [__meta_consul_tag_metrics_job]
target_label: job
action: replace
tls_config:
ca_file: /etc/vmagent-tls/ca.crt
+115
View File
@@ -0,0 +1,115 @@
---
apiVersion: operator.victoriametrics.com/v1beta1
kind: VMCluster
metadata:
name: main
namespace: observability
spec:
retentionPeriod: "180d"
replicationFactor: 2
vmstorage:
replicaCount: 2
extraArgs:
dedup.minScrapeInterval: 15s
loggerFormat: json
storage:
volumeClaimTemplate:
spec:
storageClassName: cephrbd-fast-delete
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 200Gi
resources:
requests:
cpu: "1"
memory: 2Gi
limits:
cpu: "2"
memory: 8Gi
vmselect:
replicaCount: 2
extraArgs:
dedup.minScrapeInterval: 15s
loggerFormat: json
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
cpu: 500m
memory: 1024Mi
hpa:
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
behavior:
scaleUp:
stabilizationWindowSeconds: 0
selectPolicy: Max
policies:
- type: Percent
value: 100
periodSeconds: 30
- type: Pods
value: 4
periodSeconds: 30
scaleDown:
stabilizationWindowSeconds: 300
selectPolicy: Min
policies:
- type: Percent
value: 10
periodSeconds: 60
- type: Pods
value: 2
periodSeconds: 60
vminsert:
replicaCount: 2
extraArgs:
loggerFormat: json
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
cpu: 500m
memory: 1024Mi
hpa:
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
behavior:
scaleUp:
stabilizationWindowSeconds: 0
selectPolicy: Max
policies:
- type: Percent
value: 100
periodSeconds: 30
- type: Pods
value: 4
periodSeconds: 30
scaleDown:
stabilizationWindowSeconds: 300
selectPolicy: Min
policies:
- type: Percent
value: 10
periodSeconds: 60
- type: Pods
value: 2
periodSeconds: 60
@@ -0,0 +1,6 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../../base/bind-internal
@@ -0,0 +1,6 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../../base/encapi
@@ -0,0 +1,16 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: grafana-system
resources:
- ../../../base/grafana-system
helmCharts:
- name: grafana-operator
repo: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/virtual/helm
version: "5.24.0"
releaseName: grafana-operator
namespace: grafana-system
valuesFile: values.yaml
@@ -0,0 +1,16 @@
# Watches all namespaces by default (namespaceScope: false) so it can manage the
# Grafana instance + dashboards/datasources in the `grafana` namespace.
#
# Render the CRDs as normal templated manifests (instead of the helm `crds/`
# subchart, which `helm template`/kustomize skip) so ArgoCD installs and manages
# them alongside the operator.
crds:
immutable: false
replicas: 1
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
@@ -6,17 +6,3 @@ namespace: observability
resources: resources:
- ../../../base/observability - ../../../base/observability
helmCharts:
- name: victoria-metrics-cluster
repo: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/virtual/helm
version: "0.33.0"
releaseName: victoria-metrics-cluster
namespace: observability
valuesFile: values-vmcluster.yaml
- name: victoria-metrics-agent
repo: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/virtual/helm
version: "0.30.0"
releaseName: victoria-metrics-agent
namespace: observability
valuesFile: values-vmagent.yaml
@@ -1,102 +0,0 @@
image:
repository: victoriametrics/vmagent
pullPolicy: IfNotPresent
global:
scrape_interval: 15s
podDisruptionBudget:
enabled: true
maxUnavailable: 1
podAnnotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8481"
replicaCount: 3
extraArgs:
envflag.enable: true
envflag.prefix: VM_
loggerFormat: json
httpListenAddr: :8429
service:
enabled: true
ingress:
enabled: true
annotations:
cert-manager.io/cluster-issuer: vault-issuer
cert-manager.io/common-name: vmagent.k8s.syd1.au.unkin.net
cert-manager.io/private-key-size: "4096"
external-dns.alpha.kubernetes.io/hostname: vmagent.k8s.syd1.au.unkin.net
external-dns.alpha.kubernetes.io/target: 198.18.200.0
hosts:
- name: vmagent.k8s.syd1.au.unkin.net
path:
- /
port: http
tls:
- hosts:
- vmagent.k8s.syd1.au.unkin.net
secretName: vmagent-tls
ingressClassName: nginx
remoteWrite:
- url: http://victoria-metrics-cluster-vminsert.observability.svc.cluster.local:8480/insert/0/prometheus/
scrape_configs:
- job_name: vmagent
static_configs:
- targets: ["localhost:8429"]
- job_name: "kubernetes-apiservers"
kubernetes_sd_configs:
- role: endpoints
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
insecure_skip_verify: true
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels:
- __meta_kubernetes_namespace
- __meta_kubernetes_service_name
- __meta_kubernetes_endpoint_port_name
action: keep
regex: default;kubernetes;https
- job_name: "kubernetes-nodes"
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
insecure_skip_verify: true
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
kubernetes_sd_configs:
- role: node
relabel_configs:
- action: labelmap
regex: __meta_kubernetes_node_label_(.+)
- job_name: "kubernetes-nodes-cadvisor"
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
insecure_skip_verify: true
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
kubernetes_sd_configs:
- role: node
metrics_path: /metrics/cadvisor
relabel_configs:
- action: labelmap
regex: __meta_kubernetes_node_label_(.+)
- source_labels: [__metrics_path__]
target_label: metrics_path
metric_relabel_configs:
- action: replace
source_labels: [pod]
regex: '(.+)'
target_label: pod_name
replacement: '${1}'
- action: replace
source_labels: [container]
regex: '(.+)'
target_label: container_name
replacement: '${1}'
- action: replace
target_label: name
replacement: k8s_stub
- action: replace
source_labels: [id]
regex: '^/system\.slice/(.+)\.service$'
target_label: systemd_service_name
replacement: '${1}'
@@ -1,185 +0,0 @@
vmselect:
enabled: true
image:
repository: victoriametrics/vmselect
pullPolicy: IfNotPresent
variant: cluster
extraArgs:
envflag.enable: true
envflag.prefix: VM_
loggerFormat: json
httpListenAddr: :8481
dedup.minScrapeInterval: 15s
replicationFactor: 2
resources:
limits:
cpu: 500m
memory: 1024Mi
requests:
cpu: 50m
memory: 128Mi
horizontalPodAutoscaler:
enabled: true
maxReplicas: 10
minReplicas: 2
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
behavior:
scaleUp:
stabilizationWindowSeconds: 0
selectPolicy: Max
policies:
- type: Percent
value: 100
periodSeconds: 30
- type: Pods
value: 4
periodSeconds: 30
scaleDown:
stabilizationWindowSeconds: 300
selectPolicy: Min
policies:
- type: Percent
value: 10
periodSeconds: 60
- type: Pods
value: 2
periodSeconds: 60
podAnnotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8481"
podDisruptionBudget:
enabled: true
maxUnavailable: 1
replicaCount: 2
ingress:
enabled: true
annotations:
cert-manager.io/cluster-issuer: vault-issuer
cert-manager.io/common-name: vmselect.k8s.syd1.au.unkin.net
cert-manager.io/private-key-size: "4096"
external-dns.alpha.kubernetes.io/hostname: vmselect.k8s.syd1.au.unkin.net
external-dns.alpha.kubernetes.io/target: 198.18.200.0
hosts:
- name: vmselect.k8s.syd1.au.unkin.net
path:
- /
port: http
tls:
- hosts:
- vmselect.k8s.syd1.au.unkin.net
secretName: vmselect-tls
ingressClassName: nginx
vminsert:
enabled: true
image:
repository: victoriametrics/vminsert
variant: cluster
pullPolicy: IfNotPresent
extraArgs:
envflag.enable: true
envflag.prefix: VM_
loggerFormat: json
httpListenAddr: :8480
replicationFactor: 2
resources:
limits:
cpu: 500m
memory: 1024Mi
requests:
cpu: 50m
memory: 128Mi
horizontalPodAutoscaler:
enabled: true
maxReplicas: 10
minReplicas: 2
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
behavior:
scaleUp:
stabilizationWindowSeconds: 0
selectPolicy: Max
policies:
- type: Percent
value: 100
periodSeconds: 30
- type: Pods
value: 4
periodSeconds: 30
scaleDown:
stabilizationWindowSeconds: 300
selectPolicy: Min
policies:
- type: Percent
value: 10
periodSeconds: 60
- type: Pods
value: 2
periodSeconds: 60
podAnnotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8480"
podDisruptionBudget:
enabled: true
maxUnavailable: 1
replicaCount: 2
ingress:
enabled: true
annotations:
cert-manager.io/cluster-issuer: vault-issuer
cert-manager.io/common-name: vminsert.k8s.syd1.au.unkin.net
cert-manager.io/private-key-size: "4096"
external-dns.alpha.kubernetes.io/hostname: vminsert.k8s.syd1.au.unkin.net
external-dns.alpha.kubernetes.io/target: 198.18.200.0
nginx.ingress.kubernetes.io/proxy-body-size: "100m"
hosts:
- name: vminsert.k8s.syd1.au.unkin.net
path:
- /
port: http
tls:
- hosts:
- vminsert.k8s.syd1.au.unkin.net
secretName: vminsert-tls
ingressClassName: nginx
vmstorage:
enabled: true
image:
repository: victoriametrics/vmstorage
variant: cluster
pullPolicy: IfNotPresent
retentionPeriod: 180d
extraArgs:
envflag.enable: true
envflag.prefix: VM_
loggerFormat: json
httpListenAddr: :8482
dedup.minScrapeInterval: 15s
podAnnotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8482"
podDisruptionBudget:
enabled: true
maxUnavailable: 1
persistentVolume:
enabled: true
name: vmstorage-volume
accessModes:
- ReadWriteOnce
storageClassName: cephrbd-fast-delete
mountPath: /storage
size: 200Gi
replicaCount: 3
podManagementPolicy: OrderedReady
+3 -3
View File
@@ -13,9 +13,7 @@ spec:
- path: apps/overlays/*/authentik - path: apps/overlays/*/authentik
- path: apps/overlays/*/artifactapi - path: apps/overlays/*/artifactapi
- path: apps/overlays/*/bind-system - path: apps/overlays/*/bind-system
- path: apps/overlays/*/binddns-auth - path: apps/overlays/*/bind-internal
- path: apps/overlays/*/binddns-resolver
- path: apps/overlays/*/binddns-externaldns
- path: apps/overlays/*/age-api - path: apps/overlays/*/age-api
- path: apps/overlays/*/cattle-system - path: apps/overlays/*/cattle-system
- path: apps/overlays/*/cert-manager - path: apps/overlays/*/cert-manager
@@ -23,7 +21,9 @@ spec:
- path: apps/overlays/*/cnpg-system - path: apps/overlays/*/cnpg-system
- path: apps/overlays/*/consul - path: apps/overlays/*/consul
- path: apps/overlays/*/elastic-system - path: apps/overlays/*/elastic-system
- path: apps/overlays/*/encapi
- path: apps/overlays/*/externaldns - path: apps/overlays/*/externaldns
- path: apps/overlays/*/grafana-system
- path: apps/overlays/*/inteldeviceplugins-system - path: apps/overlays/*/inteldeviceplugins-system
- path: apps/overlays/*/jfrog - path: apps/overlays/*/jfrog
- path: apps/overlays/*/kanidm - path: apps/overlays/*/kanidm
+3 -5
View File
@@ -21,11 +21,7 @@ spec:
server: https://kubernetes.default.svc server: https://kubernetes.default.svc
- namespace: 'authentik' - namespace: 'authentik'
server: https://kubernetes.default.svc server: https://kubernetes.default.svc
- namespace: 'binddns-auth' - namespace: 'bind-internal'
server: https://kubernetes.default.svc
- namespace: 'binddns-resolver'
server: https://kubernetes.default.svc
- namespace: 'binddns-externaldns'
server: https://kubernetes.default.svc server: https://kubernetes.default.svc
- namespace: 'cert-manager' - namespace: 'cert-manager'
server: https://kubernetes.default.svc server: https://kubernetes.default.svc
@@ -33,6 +29,8 @@ spec:
server: https://kubernetes.default.svc server: https://kubernetes.default.svc
- namespace: 'consul' - namespace: 'consul'
server: https://kubernetes.default.svc server: https://kubernetes.default.svc
- namespace: 'encapi'
server: https://kubernetes.default.svc
- namespace: 'externaldns' - namespace: 'externaldns'
server: https://kubernetes.default.svc server: https://kubernetes.default.svc
- namespace: 'jfrog' - namespace: 'jfrog'
@@ -692,6 +692,35 @@
}, },
"type": "object" "type": "object"
}, },
"primaryService": {
"properties": {
"annotations": {
"additionalProperties": {
"type": "string"
},
"type": "object"
},
"externalTrafficPolicy": {
"enum": [
"Cluster",
"Local"
],
"type": "string"
},
"loadBalancerIP": {
"type": "string"
},
"type": {
"enum": [
"ClusterIP",
"LoadBalancer",
"NodePort"
],
"type": "string"
}
},
"type": "object"
},
"recursion": { "recursion": {
"type": "boolean" "type": "boolean"
}, },
@@ -765,6 +794,13 @@
}, },
"type": "object" "type": "object"
}, },
"externalTrafficPolicy": {
"enum": [
"Cluster",
"Local"
],
"type": "string"
},
"loadBalancerIP": { "loadBalancerIP": {
"type": "string" "type": "string"
}, },
@@ -24,6 +24,9 @@
], ],
"type": "string" "type": "string"
}, },
"clusterRef": {
"type": "string"
},
"importExisting": { "importExisting": {
"type": "boolean" "type": "boolean"
}, },
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,371 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"apiVersion": {
"type": "string"
},
"kind": {
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"properties": {
"allowCrossNamespaceImport": {
"default": false,
"type": "boolean"
},
"editable": {
"type": "boolean",
"x-kubernetes-validations": [
{
"message": "Value is immutable",
"rule": "self == oldSelf"
}
]
},
"folderRef": {
"type": "string",
"x-kubernetes-validations": [
{
"message": "Value is immutable",
"rule": "self == oldSelf"
}
]
},
"folderUID": {
"type": "string",
"x-kubernetes-validations": [
{
"message": "Value is immutable",
"rule": "self == oldSelf"
}
]
},
"instanceSelector": {
"properties": {
"matchExpressions": {
"items": {
"properties": {
"key": {
"type": "string"
},
"operator": {
"type": "string"
},
"values": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"key",
"operator"
],
"type": "object"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"matchLabels": {
"additionalProperties": {
"type": "string"
},
"type": "object"
}
},
"type": "object",
"x-kubernetes-map-type": "atomic",
"x-kubernetes-validations": [
{
"message": "spec.instanceSelector is immutable",
"rule": "self == oldSelf"
}
]
},
"interval": {
"format": "duration",
"pattern": "^([0-9]+(\\.[0-9]+)?(ns|us|\u00b5s|ms|s|m|h))+$",
"type": "string"
},
"name": {
"type": "string"
},
"resyncPeriod": {
"pattern": "^([0-9]+(\\.[0-9]+)?(ns|us|\u00b5s|ms|s|m|h))+$",
"type": "string"
},
"rules": {
"items": {
"properties": {
"annotations": {
"additionalProperties": {
"type": "string"
},
"type": "object"
},
"condition": {
"type": "string"
},
"dashboardUid": {
"type": "string"
},
"data": {
"items": {
"properties": {
"datasourceUid": {
"type": "string"
},
"model": {
"x-kubernetes-preserve-unknown-fields": true
},
"queryType": {
"type": "string"
},
"refId": {
"type": "string"
},
"relativeTimeRange": {
"properties": {
"from": {
"format": "int64",
"type": "integer"
},
"to": {
"format": "int64",
"type": "integer"
}
},
"type": "object"
}
},
"type": "object"
},
"type": "array"
},
"execErrState": {
"enum": [
"OK",
"Alerting",
"Error",
"KeepLast"
],
"type": "string"
},
"for": {
"default": "0s",
"pattern": "^([0-9]+(\\.[0-9]+)?(s|m|h|d|w))+$",
"type": "string"
},
"isPaused": {
"type": "boolean"
},
"keepFiringFor": {
"format": "duration",
"pattern": "^([0-9]+(\\.[0-9]+)?(ns|us|\u00b5s|ms|s|m|h))+$",
"type": "string"
},
"labels": {
"additionalProperties": {
"type": "string"
},
"type": "object"
},
"missingSeriesEvalsToResolve": {
"format": "int64",
"type": "integer"
},
"noDataState": {
"enum": [
"Alerting",
"NoData",
"OK",
"KeepLast"
],
"type": "string"
},
"notificationSettings": {
"properties": {
"active_time_intervals": {
"items": {
"type": "string"
},
"type": "array"
},
"group_by": {
"items": {
"type": "string"
},
"type": "array"
},
"group_interval": {
"type": "string"
},
"group_wait": {
"type": "string"
},
"mute_time_intervals": {
"items": {
"type": "string"
},
"type": "array"
},
"receiver": {
"minLength": 1,
"type": "string"
},
"repeat_interval": {
"type": "string"
}
},
"required": [
"receiver"
],
"type": "object"
},
"panelId": {
"type": "integer"
},
"record": {
"properties": {
"from": {
"type": "string"
},
"metric": {
"type": "string"
},
"targetDatasourceUid": {
"type": "string"
}
},
"required": [
"from",
"metric"
],
"type": "object"
},
"title": {
"example": "Always firing",
"maxLength": 190,
"minLength": 1,
"type": "string"
},
"uid": {
"maxLength": 40,
"pattern": "^[a-zA-Z0-9-_]+$",
"type": "string"
}
},
"required": [
"condition",
"data",
"execErrState",
"for",
"noDataState",
"title",
"uid"
],
"type": "object"
},
"minItems": 1,
"type": "array"
},
"suspend": {
"type": "boolean"
}
},
"required": [
"instanceSelector",
"interval",
"rules"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "Only one of FolderUID or FolderRef can be set and one must be defined",
"rule": "(has(self.folderUID) && !(has(self.folderRef))) || (has(self.folderRef) && !(has(self.folderUID)))"
},
{
"message": "spec.editable is immutable",
"rule": "((!has(oldSelf.editable) && !has(self.editable)) || (has(oldSelf.editable) && has(self.editable)))"
},
{
"message": "spec.folderUID is immutable",
"rule": "((!has(oldSelf.folderUID) && !has(self.folderUID)) || (has(oldSelf.folderUID) && has(self.folderUID)))"
},
{
"message": "spec.folderRef is immutable",
"rule": "((!has(oldSelf.folderRef) && !has(self.folderRef)) || (has(oldSelf.folderRef) && has(self.folderRef)))"
},
{
"message": "disabling spec.allowCrossNamespaceImport requires a recreate to ensure desired state",
"rule": "!oldSelf.allowCrossNamespaceImport || (oldSelf.allowCrossNamespaceImport && self.allowCrossNamespaceImport)"
}
]
},
"status": {
"properties": {
"conditions": {
"items": {
"properties": {
"lastTransitionTime": {
"format": "date-time",
"type": "string"
},
"message": {
"maxLength": 32768,
"type": "string"
},
"observedGeneration": {
"format": "int64",
"minimum": 0,
"type": "integer"
},
"reason": {
"maxLength": 1024,
"minLength": 1,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
},
"status": {
"enum": [
"True",
"False",
"Unknown"
],
"type": "string"
},
"type": {
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
}
},
"required": [
"lastTransitionTime",
"message",
"reason",
"status",
"type"
],
"type": "object"
},
"type": "array"
},
"lastResync": {
"format": "date-time",
"type": "string"
}
},
"type": "object"
}
},
"required": [
"spec"
],
"type": "object"
}
@@ -0,0 +1,348 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"apiVersion": {
"type": "string"
},
"kind": {
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"properties": {
"allowCrossNamespaceImport": {
"default": false,
"type": "boolean"
},
"disableResolveMessage": {
"type": "boolean"
},
"editable": {
"type": "boolean",
"x-kubernetes-validations": [
{
"message": "spec.editable is immutable",
"rule": "self == oldSelf"
}
]
},
"instanceSelector": {
"properties": {
"matchExpressions": {
"items": {
"properties": {
"key": {
"type": "string"
},
"operator": {
"type": "string"
},
"values": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"key",
"operator"
],
"type": "object"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"matchLabels": {
"additionalProperties": {
"type": "string"
},
"type": "object"
}
},
"type": "object",
"x-kubernetes-map-type": "atomic",
"x-kubernetes-validations": [
{
"message": "spec.instanceSelector is immutable",
"rule": "self == oldSelf"
}
]
},
"name": {
"type": "string",
"x-kubernetes-validations": [
{
"message": "spec.name is immutable",
"rule": "self == oldSelf"
}
]
},
"receivers": {
"items": {
"properties": {
"disableResolveMessage": {
"type": "boolean"
},
"settings": {
"x-kubernetes-preserve-unknown-fields": true
},
"type": {
"minLength": 1,
"type": "string"
},
"uid": {
"maxLength": 40,
"pattern": "^[a-zA-Z0-9-_]+$",
"type": "string"
},
"valuesFrom": {
"items": {
"properties": {
"targetPath": {
"type": "string"
},
"valueFrom": {
"properties": {
"configMapKeyRef": {
"properties": {
"key": {
"type": "string"
},
"name": {
"default": "",
"type": "string"
},
"optional": {
"type": "boolean"
}
},
"required": [
"key"
],
"type": "object",
"x-kubernetes-map-type": "atomic"
},
"secretKeyRef": {
"properties": {
"key": {
"type": "string"
},
"name": {
"default": "",
"type": "string"
},
"optional": {
"type": "boolean"
}
},
"required": [
"key"
],
"type": "object",
"x-kubernetes-map-type": "atomic"
}
},
"type": "object",
"x-kubernetes-validations": [
{
"message": "Either configMapKeyRef or secretKeyRef must be set",
"rule": "(has(self.configMapKeyRef) && !has(self.secretKeyRef)) || (!has(self.configMapKeyRef) && has(self.secretKeyRef))"
}
]
}
},
"required": [
"targetPath",
"valueFrom"
],
"type": "object"
},
"maxItems": 99,
"type": "array"
}
},
"required": [
"settings",
"type"
],
"type": "object"
},
"maxItems": 99,
"type": "array"
},
"resyncPeriod": {
"pattern": "^([0-9]+(\\.[0-9]+)?(ns|us|\u00b5s|ms|s|m|h))+$",
"type": "string"
},
"settings": {
"x-kubernetes-preserve-unknown-fields": true
},
"suspend": {
"type": "boolean"
},
"type": {
"minLength": 1,
"type": "string"
},
"uid": {
"maxLength": 40,
"pattern": "^[a-zA-Z0-9-_]+$",
"type": "string",
"x-kubernetes-validations": [
{
"message": "spec.uid is immutable",
"rule": "self == oldSelf"
}
]
},
"valuesFrom": {
"items": {
"properties": {
"targetPath": {
"type": "string"
},
"valueFrom": {
"properties": {
"configMapKeyRef": {
"properties": {
"key": {
"type": "string"
},
"name": {
"default": "",
"type": "string"
},
"optional": {
"type": "boolean"
}
},
"required": [
"key"
],
"type": "object",
"x-kubernetes-map-type": "atomic"
},
"secretKeyRef": {
"properties": {
"key": {
"type": "string"
},
"name": {
"default": "",
"type": "string"
},
"optional": {
"type": "boolean"
}
},
"required": [
"key"
],
"type": "object",
"x-kubernetes-map-type": "atomic"
}
},
"type": "object",
"x-kubernetes-validations": [
{
"message": "Either configMapKeyRef or secretKeyRef must be set",
"rule": "(has(self.configMapKeyRef) && !has(self.secretKeyRef)) || (!has(self.configMapKeyRef) && has(self.secretKeyRef))"
}
]
}
},
"required": [
"targetPath",
"valueFrom"
],
"type": "object"
},
"maxItems": 99,
"type": "array"
}
},
"required": [
"instanceSelector"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "spec.name is immutable",
"rule": "((!has(oldSelf.name) && !has(self.name)) || (has(oldSelf.name) && has(self.name)))"
},
{
"message": "spec.editable is immutable",
"rule": "((!has(oldSelf.editable) && !has(self.editable)) || (has(oldSelf.editable) && has(self.editable)))"
},
{
"message": "disabling spec.allowCrossNamespaceImport requires a recreate to ensure desired state",
"rule": "!oldSelf.allowCrossNamespaceImport || (oldSelf.allowCrossNamespaceImport && self.allowCrossNamespaceImport)"
}
]
},
"status": {
"properties": {
"conditions": {
"items": {
"properties": {
"lastTransitionTime": {
"format": "date-time",
"type": "string"
},
"message": {
"maxLength": 32768,
"type": "string"
},
"observedGeneration": {
"format": "int64",
"minimum": 0,
"type": "integer"
},
"reason": {
"maxLength": 1024,
"minLength": 1,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
},
"status": {
"enum": [
"True",
"False",
"Unknown"
],
"type": "string"
},
"type": {
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
}
},
"required": [
"lastTransitionTime",
"message",
"reason",
"status",
"type"
],
"type": "object"
},
"type": "array"
},
"lastResync": {
"format": "date-time",
"type": "string"
}
},
"type": "object"
}
},
"required": [
"spec"
],
"type": "object"
}
@@ -0,0 +1,492 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"apiVersion": {
"type": "string"
},
"kind": {
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"properties": {
"allowCrossNamespaceImport": {
"default": false,
"type": "boolean"
},
"configMapRef": {
"properties": {
"key": {
"type": "string"
},
"name": {
"default": "",
"type": "string"
},
"optional": {
"type": "boolean"
}
},
"required": [
"key"
],
"type": "object",
"x-kubernetes-map-type": "atomic"
},
"contentCacheDuration": {
"type": "string"
},
"datasources": {
"items": {
"properties": {
"datasourceName": {
"type": "string"
},
"inputName": {
"type": "string"
}
},
"required": [
"datasourceName",
"inputName"
],
"type": "object"
},
"type": "array"
},
"envFrom": {
"items": {
"properties": {
"configMapKeyRef": {
"properties": {
"key": {
"type": "string"
},
"name": {
"default": "",
"type": "string"
},
"optional": {
"type": "boolean"
}
},
"required": [
"key"
],
"type": "object",
"x-kubernetes-map-type": "atomic"
},
"secretKeyRef": {
"properties": {
"key": {
"type": "string"
},
"name": {
"default": "",
"type": "string"
},
"optional": {
"type": "boolean"
}
},
"required": [
"key"
],
"type": "object",
"x-kubernetes-map-type": "atomic"
}
},
"type": "object"
},
"type": "array"
},
"envs": {
"items": {
"properties": {
"name": {
"type": "string"
},
"value": {
"type": "string"
},
"valueFrom": {
"properties": {
"configMapKeyRef": {
"properties": {
"key": {
"type": "string"
},
"name": {
"default": "",
"type": "string"
},
"optional": {
"type": "boolean"
}
},
"required": [
"key"
],
"type": "object",
"x-kubernetes-map-type": "atomic"
},
"secretKeyRef": {
"properties": {
"key": {
"type": "string"
},
"name": {
"default": "",
"type": "string"
},
"optional": {
"type": "boolean"
}
},
"required": [
"key"
],
"type": "object",
"x-kubernetes-map-type": "atomic"
}
},
"type": "object"
}
},
"required": [
"name"
],
"type": "object"
},
"type": "array"
},
"folder": {
"type": "string"
},
"folderRef": {
"type": "string"
},
"folderUID": {
"type": "string"
},
"grafanaCom": {
"properties": {
"id": {
"type": "integer"
},
"revision": {
"type": "integer"
}
},
"required": [
"id"
],
"type": "object"
},
"gzipJson": {
"format": "byte",
"type": "string"
},
"instanceSelector": {
"properties": {
"matchExpressions": {
"items": {
"properties": {
"key": {
"type": "string"
},
"operator": {
"type": "string"
},
"values": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"key",
"operator"
],
"type": "object"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"matchLabels": {
"additionalProperties": {
"type": "string"
},
"type": "object"
}
},
"type": "object",
"x-kubernetes-map-type": "atomic",
"x-kubernetes-validations": [
{
"message": "spec.instanceSelector is immutable",
"rule": "self == oldSelf"
}
]
},
"json": {
"type": "string"
},
"jsonnet": {
"type": "string"
},
"jsonnetLib": {
"properties": {
"fileName": {
"type": "string"
},
"gzipJsonnetProject": {
"format": "byte",
"type": "string"
},
"jPath": {
"items": {
"type": "string"
},
"type": "array"
}
},
"required": [
"fileName",
"gzipJsonnetProject"
],
"type": "object"
},
"oci": {
"properties": {
"insecurePlainHTTP": {
"type": "boolean"
},
"path": {
"maxLength": 512,
"minLength": 1,
"type": "string"
},
"pullSecretRef": {
"properties": {
"name": {
"default": "",
"type": "string"
}
},
"type": "object",
"x-kubernetes-map-type": "atomic"
},
"reference": {
"maxLength": 512,
"minLength": 3,
"pattern": "^[^:@]+(:[^:@/]+|@sha256:[a-fA-F0-9]{64})$",
"type": "string"
}
},
"required": [
"path",
"reference"
],
"type": "object"
},
"plugins": {
"items": {
"properties": {
"name": {
"minLength": 1,
"type": "string"
},
"version": {
"pattern": "^((0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?|latest)$",
"type": "string"
}
},
"required": [
"name",
"version"
],
"type": "object"
},
"type": "array"
},
"resyncPeriod": {
"pattern": "^([0-9]+(\\.[0-9]+)?(ns|us|\u00b5s|ms|s|m|h))+$",
"type": "string"
},
"suspend": {
"type": "boolean"
},
"uid": {
"maxLength": 40,
"pattern": "^[a-zA-Z0-9-_]+$",
"type": "string",
"x-kubernetes-validations": [
{
"message": "spec.uid is immutable",
"rule": "self == oldSelf"
}
]
},
"url": {
"pattern": "^https?://.+$",
"type": "string"
},
"urlAuthorization": {
"properties": {
"basicAuth": {
"properties": {
"password": {
"properties": {
"key": {
"type": "string"
},
"name": {
"default": "",
"type": "string"
},
"optional": {
"type": "boolean"
}
},
"required": [
"key"
],
"type": "object",
"x-kubernetes-map-type": "atomic"
},
"username": {
"properties": {
"key": {
"type": "string"
},
"name": {
"default": "",
"type": "string"
},
"optional": {
"type": "boolean"
}
},
"required": [
"key"
],
"type": "object",
"x-kubernetes-map-type": "atomic"
}
},
"type": "object"
}
},
"type": "object"
}
},
"required": [
"instanceSelector"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "Only one of folderUID or folderRef can be declared at the same time",
"rule": "(has(self.folderUID) && !(has(self.folderRef))) || (has(self.folderRef) && !(has(self.folderUID))) || !(has(self.folderRef) && (has(self.folderUID)))"
},
{
"message": "folder field cannot be set when folderUID or folderRef is already declared",
"rule": "(has(self.folder) && !(has(self.folderRef) || has(self.folderUID))) || !(has(self.folder))"
},
{
"message": "spec.uid is immutable",
"rule": "((!has(oldSelf.uid) && !has(self.uid)) || (has(oldSelf.uid) && has(self.uid)))"
},
{
"message": "disabling spec.allowCrossNamespaceImport requires a recreate to ensure desired state",
"rule": "!oldSelf.allowCrossNamespaceImport || (oldSelf.allowCrossNamespaceImport && self.allowCrossNamespaceImport)"
}
]
},
"status": {
"properties": {
"NoMatchingInstances": {
"type": "boolean"
},
"conditions": {
"items": {
"properties": {
"lastTransitionTime": {
"format": "date-time",
"type": "string"
},
"message": {
"maxLength": 32768,
"type": "string"
},
"observedGeneration": {
"format": "int64",
"minimum": 0,
"type": "integer"
},
"reason": {
"maxLength": 1024,
"minLength": 1,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
},
"status": {
"enum": [
"True",
"False",
"Unknown"
],
"type": "string"
},
"type": {
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
}
},
"required": [
"lastTransitionTime",
"message",
"reason",
"status",
"type"
],
"type": "object"
},
"type": "array"
},
"contentCache": {
"format": "byte",
"type": "string"
},
"contentTimestamp": {
"format": "date-time",
"type": "string"
},
"contentUrl": {
"type": "string"
},
"hash": {
"type": "string"
},
"lastResync": {
"format": "date-time",
"type": "string"
},
"uid": {
"type": "string"
}
},
"type": "object"
}
},
"required": [
"spec"
],
"type": "object"
}
@@ -0,0 +1,306 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"apiVersion": {
"type": "string"
},
"kind": {
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"properties": {
"allowCrossNamespaceImport": {
"default": false,
"type": "boolean"
},
"datasource": {
"properties": {
"access": {
"type": "string"
},
"basicAuth": {
"type": "boolean"
},
"basicAuthUser": {
"type": "string"
},
"database": {
"type": "string"
},
"editable": {
"type": "boolean"
},
"isDefault": {
"type": "boolean"
},
"jsonData": {
"type": "object",
"x-kubernetes-preserve-unknown-fields": true
},
"name": {
"type": "string"
},
"orgId": {
"format": "int64",
"type": "integer"
},
"secureJsonData": {
"type": "object",
"x-kubernetes-preserve-unknown-fields": true
},
"type": {
"type": "string"
},
"uid": {
"type": "string"
},
"url": {
"type": "string"
},
"user": {
"type": "string"
}
},
"type": "object"
},
"instanceSelector": {
"properties": {
"matchExpressions": {
"items": {
"properties": {
"key": {
"type": "string"
},
"operator": {
"type": "string"
},
"values": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"key",
"operator"
],
"type": "object"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"matchLabels": {
"additionalProperties": {
"type": "string"
},
"type": "object"
}
},
"type": "object",
"x-kubernetes-map-type": "atomic",
"x-kubernetes-validations": [
{
"message": "spec.instanceSelector is immutable",
"rule": "self == oldSelf"
}
]
},
"plugins": {
"items": {
"properties": {
"name": {
"minLength": 1,
"type": "string"
},
"version": {
"pattern": "^((0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?|latest)$",
"type": "string"
}
},
"required": [
"name",
"version"
],
"type": "object"
},
"type": "array"
},
"resyncPeriod": {
"pattern": "^([0-9]+(\\.[0-9]+)?(ns|us|\u00b5s|ms|s|m|h))+$",
"type": "string"
},
"suspend": {
"type": "boolean"
},
"uid": {
"maxLength": 40,
"pattern": "^[a-zA-Z0-9-_]+$",
"type": "string",
"x-kubernetes-validations": [
{
"message": "spec.uid is immutable",
"rule": "self == oldSelf"
}
]
},
"valuesFrom": {
"items": {
"properties": {
"targetPath": {
"type": "string"
},
"valueFrom": {
"properties": {
"configMapKeyRef": {
"properties": {
"key": {
"type": "string"
},
"name": {
"default": "",
"type": "string"
},
"optional": {
"type": "boolean"
}
},
"required": [
"key"
],
"type": "object",
"x-kubernetes-map-type": "atomic"
},
"secretKeyRef": {
"properties": {
"key": {
"type": "string"
},
"name": {
"default": "",
"type": "string"
},
"optional": {
"type": "boolean"
}
},
"required": [
"key"
],
"type": "object",
"x-kubernetes-map-type": "atomic"
}
},
"type": "object",
"x-kubernetes-validations": [
{
"message": "Either configMapKeyRef or secretKeyRef must be set",
"rule": "(has(self.configMapKeyRef) && !has(self.secretKeyRef)) || (!has(self.configMapKeyRef) && has(self.secretKeyRef))"
}
]
}
},
"required": [
"targetPath",
"valueFrom"
],
"type": "object"
},
"maxItems": 99,
"type": "array"
}
},
"required": [
"datasource",
"instanceSelector"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "spec.uid is immutable",
"rule": "((!has(oldSelf.uid) && !has(self.uid)) || (has(oldSelf.uid) && has(self.uid)))"
},
{
"message": "disabling spec.allowCrossNamespaceImport requires a recreate to ensure desired state",
"rule": "!oldSelf.allowCrossNamespaceImport || (oldSelf.allowCrossNamespaceImport && self.allowCrossNamespaceImport)"
}
]
},
"status": {
"properties": {
"NoMatchingInstances": {
"type": "boolean"
},
"conditions": {
"items": {
"properties": {
"lastTransitionTime": {
"format": "date-time",
"type": "string"
},
"message": {
"maxLength": 32768,
"type": "string"
},
"observedGeneration": {
"format": "int64",
"minimum": 0,
"type": "integer"
},
"reason": {
"maxLength": 1024,
"minLength": 1,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
},
"status": {
"enum": [
"True",
"False",
"Unknown"
],
"type": "string"
},
"type": {
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
}
},
"required": [
"lastTransitionTime",
"message",
"reason",
"status",
"type"
],
"type": "object"
},
"type": "array"
},
"hash": {
"type": "string"
},
"lastMessage": {
"type": "string"
},
"lastResync": {
"format": "date-time",
"type": "string"
},
"uid": {
"type": "string"
}
},
"type": "object"
}
},
"required": [
"spec"
],
"type": "object"
}
@@ -0,0 +1,180 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"apiVersion": {
"type": "string"
},
"kind": {
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"properties": {
"allowCrossNamespaceImport": {
"default": false,
"type": "boolean"
},
"instanceSelector": {
"properties": {
"matchExpressions": {
"items": {
"properties": {
"key": {
"type": "string"
},
"operator": {
"type": "string"
},
"values": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"key",
"operator"
],
"type": "object"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"matchLabels": {
"additionalProperties": {
"type": "string"
},
"type": "object"
}
},
"type": "object",
"x-kubernetes-map-type": "atomic",
"x-kubernetes-validations": [
{
"message": "spec.instanceSelector is immutable",
"rule": "self == oldSelf"
}
]
},
"parentFolderRef": {
"type": "string"
},
"parentFolderUID": {
"type": "string"
},
"permissions": {
"type": "string"
},
"resyncPeriod": {
"pattern": "^([0-9]+(\\.[0-9]+)?(ns|us|\u00b5s|ms|s|m|h))+$",
"type": "string"
},
"suspend": {
"type": "boolean"
},
"title": {
"type": "string"
},
"uid": {
"maxLength": 40,
"pattern": "^[a-zA-Z0-9-_]+$",
"type": "string",
"x-kubernetes-validations": [
{
"message": "spec.uid is immutable",
"rule": "self == oldSelf"
}
]
}
},
"required": [
"instanceSelector"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "Only one of parentFolderUID or parentFolderRef can be set",
"rule": "(has(self.parentFolderUID) && !(has(self.parentFolderRef))) || (has(self.parentFolderRef) && !(has(self.parentFolderUID))) || !(has(self.parentFolderRef) && (has(self.parentFolderUID)))"
},
{
"message": "spec.uid is immutable",
"rule": "((!has(oldSelf.uid) && !has(self.uid)) || (has(oldSelf.uid) && has(self.uid)))"
},
{
"message": "disabling spec.allowCrossNamespaceImport requires a recreate to ensure desired state",
"rule": "!oldSelf.allowCrossNamespaceImport || (oldSelf.allowCrossNamespaceImport && self.allowCrossNamespaceImport)"
}
]
},
"status": {
"properties": {
"NoMatchingInstances": {
"type": "boolean"
},
"conditions": {
"items": {
"properties": {
"lastTransitionTime": {
"format": "date-time",
"type": "string"
},
"message": {
"maxLength": 32768,
"type": "string"
},
"observedGeneration": {
"format": "int64",
"minimum": 0,
"type": "integer"
},
"reason": {
"maxLength": 1024,
"minLength": 1,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
},
"status": {
"enum": [
"True",
"False",
"Unknown"
],
"type": "string"
},
"type": {
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
}
},
"required": [
"lastTransitionTime",
"message",
"reason",
"status",
"type"
],
"type": "object"
},
"type": "array"
},
"hash": {
"type": "string"
},
"lastResync": {
"format": "date-time",
"type": "string"
}
},
"type": "object"
}
},
"required": [
"spec"
],
"type": "object"
}
@@ -0,0 +1,482 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"apiVersion": {
"type": "string"
},
"kind": {
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"properties": {
"allowCrossNamespaceImport": {
"default": false,
"type": "boolean"
},
"configMapRef": {
"properties": {
"key": {
"type": "string"
},
"name": {
"default": "",
"type": "string"
},
"optional": {
"type": "boolean"
}
},
"required": [
"key"
],
"type": "object",
"x-kubernetes-map-type": "atomic"
},
"contentCacheDuration": {
"type": "string"
},
"datasources": {
"items": {
"properties": {
"datasourceName": {
"type": "string"
},
"inputName": {
"type": "string"
}
},
"required": [
"datasourceName",
"inputName"
],
"type": "object"
},
"type": "array"
},
"envFrom": {
"items": {
"properties": {
"configMapKeyRef": {
"properties": {
"key": {
"type": "string"
},
"name": {
"default": "",
"type": "string"
},
"optional": {
"type": "boolean"
}
},
"required": [
"key"
],
"type": "object",
"x-kubernetes-map-type": "atomic"
},
"secretKeyRef": {
"properties": {
"key": {
"type": "string"
},
"name": {
"default": "",
"type": "string"
},
"optional": {
"type": "boolean"
}
},
"required": [
"key"
],
"type": "object",
"x-kubernetes-map-type": "atomic"
}
},
"type": "object"
},
"type": "array"
},
"envs": {
"items": {
"properties": {
"name": {
"type": "string"
},
"value": {
"type": "string"
},
"valueFrom": {
"properties": {
"configMapKeyRef": {
"properties": {
"key": {
"type": "string"
},
"name": {
"default": "",
"type": "string"
},
"optional": {
"type": "boolean"
}
},
"required": [
"key"
],
"type": "object",
"x-kubernetes-map-type": "atomic"
},
"secretKeyRef": {
"properties": {
"key": {
"type": "string"
},
"name": {
"default": "",
"type": "string"
},
"optional": {
"type": "boolean"
}
},
"required": [
"key"
],
"type": "object",
"x-kubernetes-map-type": "atomic"
}
},
"type": "object"
}
},
"required": [
"name"
],
"type": "object"
},
"type": "array"
},
"folderRef": {
"type": "string"
},
"folderUID": {
"type": "string"
},
"grafanaCom": {
"properties": {
"id": {
"type": "integer"
},
"revision": {
"type": "integer"
}
},
"required": [
"id"
],
"type": "object"
},
"gzipJson": {
"format": "byte",
"type": "string"
},
"instanceSelector": {
"properties": {
"matchExpressions": {
"items": {
"properties": {
"key": {
"type": "string"
},
"operator": {
"type": "string"
},
"values": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"key",
"operator"
],
"type": "object"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"matchLabels": {
"additionalProperties": {
"type": "string"
},
"type": "object"
}
},
"type": "object",
"x-kubernetes-map-type": "atomic",
"x-kubernetes-validations": [
{
"message": "spec.instanceSelector is immutable",
"rule": "self == oldSelf"
}
]
},
"json": {
"type": "string"
},
"jsonnet": {
"type": "string"
},
"jsonnetLib": {
"properties": {
"fileName": {
"type": "string"
},
"gzipJsonnetProject": {
"format": "byte",
"type": "string"
},
"jPath": {
"items": {
"type": "string"
},
"type": "array"
}
},
"required": [
"fileName",
"gzipJsonnetProject"
],
"type": "object"
},
"oci": {
"properties": {
"insecurePlainHTTP": {
"type": "boolean"
},
"path": {
"maxLength": 512,
"minLength": 1,
"type": "string"
},
"pullSecretRef": {
"properties": {
"name": {
"default": "",
"type": "string"
}
},
"type": "object",
"x-kubernetes-map-type": "atomic"
},
"reference": {
"maxLength": 512,
"minLength": 3,
"pattern": "^[^:@]+(:[^:@/]+|@sha256:[a-fA-F0-9]{64})$",
"type": "string"
}
},
"required": [
"path",
"reference"
],
"type": "object"
},
"plugins": {
"items": {
"properties": {
"name": {
"minLength": 1,
"type": "string"
},
"version": {
"pattern": "^((0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?|latest)$",
"type": "string"
}
},
"required": [
"name",
"version"
],
"type": "object"
},
"type": "array"
},
"resyncPeriod": {
"pattern": "^([0-9]+(\\.[0-9]+)?(ns|us|\u00b5s|ms|s|m|h))+$",
"type": "string"
},
"suspend": {
"type": "boolean"
},
"uid": {
"maxLength": 40,
"pattern": "^[a-zA-Z0-9-_]+$",
"type": "string",
"x-kubernetes-validations": [
{
"message": "spec.uid is immutable",
"rule": "self == oldSelf"
}
]
},
"url": {
"pattern": "^https?://.+$",
"type": "string"
},
"urlAuthorization": {
"properties": {
"basicAuth": {
"properties": {
"password": {
"properties": {
"key": {
"type": "string"
},
"name": {
"default": "",
"type": "string"
},
"optional": {
"type": "boolean"
}
},
"required": [
"key"
],
"type": "object",
"x-kubernetes-map-type": "atomic"
},
"username": {
"properties": {
"key": {
"type": "string"
},
"name": {
"default": "",
"type": "string"
},
"optional": {
"type": "boolean"
}
},
"required": [
"key"
],
"type": "object",
"x-kubernetes-map-type": "atomic"
}
},
"type": "object"
}
},
"type": "object"
}
},
"required": [
"instanceSelector"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "Only one of folderUID or folderRef can be declared at the same time",
"rule": "(has(self.folderUID) && !(has(self.folderRef))) || (has(self.folderRef) && !(has(self.folderUID))) || !(has(self.folderRef) && (has(self.folderUID)))"
},
{
"message": "spec.uid is immutable",
"rule": "((!has(oldSelf.uid) && !has(self.uid)) || (has(oldSelf.uid) && has(self.uid)))"
},
{
"message": "disabling spec.allowCrossNamespaceImport requires a recreate to ensure desired state",
"rule": "!oldSelf.allowCrossNamespaceImport || (oldSelf.allowCrossNamespaceImport && self.allowCrossNamespaceImport)"
}
]
},
"status": {
"properties": {
"conditions": {
"items": {
"properties": {
"lastTransitionTime": {
"format": "date-time",
"type": "string"
},
"message": {
"maxLength": 32768,
"type": "string"
},
"observedGeneration": {
"format": "int64",
"minimum": 0,
"type": "integer"
},
"reason": {
"maxLength": 1024,
"minLength": 1,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
},
"status": {
"enum": [
"True",
"False",
"Unknown"
],
"type": "string"
},
"type": {
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
}
},
"required": [
"lastTransitionTime",
"message",
"reason",
"status",
"type"
],
"type": "object"
},
"type": "array"
},
"contentCache": {
"format": "byte",
"type": "string"
},
"contentTimestamp": {
"format": "date-time",
"type": "string"
},
"contentUrl": {
"type": "string"
},
"hash": {
"type": "string"
},
"lastResync": {
"format": "date-time",
"type": "string"
},
"uid": {
"type": "string"
}
},
"type": "object"
}
},
"required": [
"spec"
],
"type": "object"
}
@@ -0,0 +1,300 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"apiVersion": {
"type": "string"
},
"kind": {
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"properties": {
"allowCrossNamespaceImport": {
"default": false,
"type": "boolean"
},
"instanceSelector": {
"properties": {
"matchExpressions": {
"items": {
"properties": {
"key": {
"type": "string"
},
"operator": {
"type": "string"
},
"values": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"key",
"operator"
],
"type": "object"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"matchLabels": {
"additionalProperties": {
"type": "string"
},
"type": "object"
}
},
"type": "object",
"x-kubernetes-map-type": "atomic",
"x-kubernetes-validations": [
{
"message": "spec.instanceSelector is immutable",
"rule": "self == oldSelf"
}
]
},
"patch": {
"properties": {
"env": {
"items": {
"properties": {
"name": {
"type": "string"
},
"valueFrom": {
"properties": {
"configMapKeyRef": {
"properties": {
"key": {
"type": "string"
},
"name": {
"default": "",
"type": "string"
},
"optional": {
"type": "boolean"
}
},
"required": [
"key"
],
"type": "object",
"x-kubernetes-map-type": "atomic"
},
"grafanaRef": {
"properties": {
"apiVersion": {
"type": "string"
},
"fieldPath": {
"type": "string"
}
},
"required": [
"fieldPath"
],
"type": "object",
"x-kubernetes-map-type": "atomic"
},
"secretKeyRef": {
"properties": {
"key": {
"type": "string"
},
"name": {
"default": "",
"type": "string"
},
"optional": {
"type": "boolean"
}
},
"required": [
"key"
],
"type": "object",
"x-kubernetes-map-type": "atomic"
}
},
"type": "object"
}
},
"required": [
"name",
"valueFrom"
],
"type": "object"
},
"type": "array"
},
"scripts": {
"items": {
"type": "string"
},
"type": "array"
}
},
"required": [
"scripts"
],
"type": "object"
},
"resyncPeriod": {
"pattern": "^([0-9]+(\\.[0-9]+)?(ns|us|\u00b5s|ms|s|m|h))+$",
"type": "string"
},
"suspend": {
"type": "boolean"
},
"template": {
"properties": {
"apiVersion": {
"type": "string"
},
"kind": {
"type": "string",
"x-kubernetes-validations": [
{
"message": "Value is immutable",
"rule": "self == oldSelf"
}
]
},
"metadata": {
"properties": {
"annotations": {
"additionalProperties": {
"type": "string"
},
"type": "object"
},
"labels": {
"additionalProperties": {
"type": "string"
},
"type": "object"
},
"name": {
"type": "string",
"x-kubernetes-validations": [
{
"message": "Value is immutable",
"rule": "self == oldSelf"
}
]
},
"namespace": {
"type": "string",
"x-kubernetes-validations": [
{
"message": "Value is immutable",
"rule": "self == oldSelf"
}
]
}
},
"required": [
"name"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "namespace is immutable",
"rule": "((!has(oldSelf.__namespace__) && !has(self.__namespace__)) || (has(oldSelf.__namespace__) && has(self.__namespace__)))"
}
]
},
"spec": {
"x-kubernetes-preserve-unknown-fields": true
}
},
"required": [
"apiVersion",
"kind",
"metadata"
],
"type": "object"
}
},
"required": [
"instanceSelector",
"template"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "disabling spec.allowCrossNamespaceImport requires a recreate to ensure desired state",
"rule": "!oldSelf.allowCrossNamespaceImport || (oldSelf.allowCrossNamespaceImport && self.allowCrossNamespaceImport)"
}
]
},
"status": {
"properties": {
"conditions": {
"items": {
"properties": {
"lastTransitionTime": {
"format": "date-time",
"type": "string"
},
"message": {
"maxLength": 32768,
"type": "string"
},
"observedGeneration": {
"format": "int64",
"minimum": 0,
"type": "integer"
},
"reason": {
"maxLength": 1024,
"minLength": 1,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
},
"status": {
"enum": [
"True",
"False",
"Unknown"
],
"type": "string"
},
"type": {
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
}
},
"required": [
"lastTransitionTime",
"message",
"reason",
"status",
"type"
],
"type": "object"
},
"type": "array"
},
"lastResync": {
"format": "date-time",
"type": "string"
}
},
"type": "object"
}
},
"required": [
"spec"
],
"type": "object"
}
@@ -0,0 +1,212 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"apiVersion": {
"type": "string"
},
"kind": {
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"properties": {
"allowCrossNamespaceImport": {
"default": false,
"type": "boolean"
},
"editable": {
"default": true,
"type": "boolean",
"x-kubernetes-validations": [
{
"message": "spec.editable is immutable",
"rule": "self == oldSelf"
}
]
},
"instanceSelector": {
"properties": {
"matchExpressions": {
"items": {
"properties": {
"key": {
"type": "string"
},
"operator": {
"type": "string"
},
"values": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"key",
"operator"
],
"type": "object"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"matchLabels": {
"additionalProperties": {
"type": "string"
},
"type": "object"
}
},
"type": "object",
"x-kubernetes-map-type": "atomic",
"x-kubernetes-validations": [
{
"message": "spec.instanceSelector is immutable",
"rule": "self == oldSelf"
}
]
},
"name": {
"type": "string"
},
"resyncPeriod": {
"pattern": "^([0-9]+(\\.[0-9]+)?(ns|us|\u00b5s|ms|s|m|h))+$",
"type": "string"
},
"suspend": {
"type": "boolean"
},
"time_intervals": {
"items": {
"properties": {
"days_of_month": {
"items": {
"type": "string"
},
"type": "array"
},
"location": {
"type": "string"
},
"months": {
"items": {
"type": "string"
},
"type": "array"
},
"times": {
"items": {
"properties": {
"end_time": {
"type": "string"
},
"start_time": {
"type": "string"
}
},
"required": [
"end_time",
"start_time"
],
"type": "object"
},
"type": "array"
},
"weekdays": {
"items": {
"type": "string"
},
"type": "array"
},
"years": {
"items": {
"type": "string"
},
"type": "array"
}
},
"type": "object"
},
"minItems": 1,
"type": "array"
}
},
"required": [
"instanceSelector",
"name",
"time_intervals"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "disabling spec.allowCrossNamespaceImport requires a recreate to ensure desired state",
"rule": "!oldSelf.allowCrossNamespaceImport || (oldSelf.allowCrossNamespaceImport && self.allowCrossNamespaceImport)"
}
]
},
"status": {
"properties": {
"conditions": {
"items": {
"properties": {
"lastTransitionTime": {
"format": "date-time",
"type": "string"
},
"message": {
"maxLength": 32768,
"type": "string"
},
"observedGeneration": {
"format": "int64",
"minimum": 0,
"type": "integer"
},
"reason": {
"maxLength": 1024,
"minLength": 1,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
},
"status": {
"enum": [
"True",
"False",
"Unknown"
],
"type": "string"
},
"type": {
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
}
},
"required": [
"lastTransitionTime",
"message",
"reason",
"status",
"type"
],
"type": "object"
},
"type": "array"
},
"lastResync": {
"format": "date-time",
"type": "string"
}
},
"type": "object"
}
},
"required": [
"spec"
],
"type": "object"
}
@@ -0,0 +1,314 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"apiVersion": {
"type": "string"
},
"kind": {
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"properties": {
"allowCrossNamespaceImport": {
"default": false,
"type": "boolean"
},
"editable": {
"type": "boolean",
"x-kubernetes-validations": [
{
"message": "Value is immutable",
"rule": "self == oldSelf"
}
]
},
"instanceSelector": {
"properties": {
"matchExpressions": {
"items": {
"properties": {
"key": {
"type": "string"
},
"operator": {
"type": "string"
},
"values": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"key",
"operator"
],
"type": "object"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"matchLabels": {
"additionalProperties": {
"type": "string"
},
"type": "object"
}
},
"type": "object",
"x-kubernetes-map-type": "atomic",
"x-kubernetes-validations": [
{
"message": "spec.instanceSelector is immutable",
"rule": "self == oldSelf"
}
]
},
"resyncPeriod": {
"pattern": "^([0-9]+(\\.[0-9]+)?(ns|us|\u00b5s|ms|s|m|h))+$",
"type": "string"
},
"route": {
"properties": {
"active_time_intervals": {
"items": {
"type": "string"
},
"type": "array"
},
"continue": {
"type": "boolean"
},
"group_by": {
"items": {
"type": "string"
},
"type": "array"
},
"group_interval": {
"type": "string"
},
"group_wait": {
"type": "string"
},
"match_re": {
"additionalProperties": {
"type": "string"
},
"type": "object"
},
"matchers": {
"items": {
"properties": {
"isEqual": {
"type": "boolean"
},
"isRegex": {
"type": "boolean"
},
"name": {
"type": "string"
},
"value": {
"type": "string"
}
},
"required": [
"isRegex",
"value"
],
"type": "object"
},
"type": "array"
},
"mute_time_intervals": {
"items": {
"type": "string"
},
"type": "array"
},
"object_matchers": {
"items": {
"items": {
"type": "string"
},
"type": "array"
},
"type": "array"
},
"provenance": {
"type": "string"
},
"receiver": {
"minLength": 1,
"type": "string"
},
"repeat_interval": {
"type": "string"
},
"routeSelector": {
"properties": {
"matchExpressions": {
"items": {
"properties": {
"key": {
"type": "string"
},
"operator": {
"type": "string"
},
"values": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"key",
"operator"
],
"type": "object"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"matchLabels": {
"additionalProperties": {
"type": "string"
},
"type": "object"
}
},
"type": "object",
"x-kubernetes-map-type": "atomic"
},
"routes": {
"x-kubernetes-preserve-unknown-fields": true
}
},
"required": [
"receiver"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "continue is invalid on the top level route node",
"rule": "!has(self.__continue__)"
},
{
"message": "match_re is invalid on the top level route node",
"rule": "!has(self.match_re)"
},
{
"message": "matchers is invalid on the top level route node",
"rule": "!has(self.matchers)"
},
{
"message": "object_matchers is invalid on the top level route node",
"rule": "!has(self.object_matchers)"
},
{
"message": "mute_time_intervals is invalid on the top level route node",
"rule": "!has(self.mute_time_intervals)"
},
{
"message": "active_time_intervals is invalid on the top level route node",
"rule": "!has(self.active_time_intervals)"
}
]
},
"suspend": {
"type": "boolean"
}
},
"required": [
"instanceSelector",
"route"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "spec.editable is immutable",
"rule": "((!has(oldSelf.editable) && !has(self.editable)) || (has(oldSelf.editable) && has(self.editable)))"
},
{
"message": "disabling spec.allowCrossNamespaceImport requires a recreate to ensure desired state",
"rule": "!oldSelf.allowCrossNamespaceImport || (oldSelf.allowCrossNamespaceImport && self.allowCrossNamespaceImport)"
}
]
},
"status": {
"properties": {
"conditions": {
"items": {
"properties": {
"lastTransitionTime": {
"format": "date-time",
"type": "string"
},
"message": {
"maxLength": 32768,
"type": "string"
},
"observedGeneration": {
"format": "int64",
"minimum": 0,
"type": "integer"
},
"reason": {
"maxLength": 1024,
"minLength": 1,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
},
"status": {
"enum": [
"True",
"False",
"Unknown"
],
"type": "string"
},
"type": {
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
}
},
"required": [
"lastTransitionTime",
"message",
"reason",
"status",
"type"
],
"type": "object"
},
"type": "array"
},
"discoveredRoutes": {
"items": {
"type": "string"
},
"type": "array"
},
"lastResync": {
"format": "date-time",
"type": "string"
}
},
"type": "object"
}
},
"required": [
"spec"
],
"type": "object"
}
@@ -0,0 +1,199 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"apiVersion": {
"type": "string"
},
"kind": {
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"properties": {
"active_time_intervals": {
"items": {
"type": "string"
},
"type": "array"
},
"continue": {
"type": "boolean"
},
"group_by": {
"items": {
"type": "string"
},
"type": "array"
},
"group_interval": {
"type": "string"
},
"group_wait": {
"type": "string"
},
"match_re": {
"additionalProperties": {
"type": "string"
},
"type": "object"
},
"matchers": {
"items": {
"properties": {
"isEqual": {
"type": "boolean"
},
"isRegex": {
"type": "boolean"
},
"name": {
"type": "string"
},
"value": {
"type": "string"
}
},
"required": [
"isRegex",
"value"
],
"type": "object"
},
"type": "array"
},
"mute_time_intervals": {
"items": {
"type": "string"
},
"type": "array"
},
"object_matchers": {
"items": {
"items": {
"type": "string"
},
"type": "array"
},
"type": "array"
},
"provenance": {
"type": "string"
},
"receiver": {
"minLength": 1,
"type": "string"
},
"repeat_interval": {
"type": "string"
},
"routeSelector": {
"properties": {
"matchExpressions": {
"items": {
"properties": {
"key": {
"type": "string"
},
"operator": {
"type": "string"
},
"values": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"key",
"operator"
],
"type": "object"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"matchLabels": {
"additionalProperties": {
"type": "string"
},
"type": "object"
}
},
"type": "object",
"x-kubernetes-map-type": "atomic"
},
"routes": {
"x-kubernetes-preserve-unknown-fields": true
}
},
"required": [
"receiver"
],
"type": "object"
},
"status": {
"properties": {
"conditions": {
"items": {
"properties": {
"lastTransitionTime": {
"format": "date-time",
"type": "string"
},
"message": {
"maxLength": 32768,
"type": "string"
},
"observedGeneration": {
"format": "int64",
"minimum": 0,
"type": "integer"
},
"reason": {
"maxLength": 1024,
"minLength": 1,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
},
"status": {
"enum": [
"True",
"False",
"Unknown"
],
"type": "string"
},
"type": {
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
}
},
"required": [
"lastTransitionTime",
"message",
"reason",
"status",
"type"
],
"type": "object"
},
"type": "array"
},
"lastResync": {
"format": "date-time",
"type": "string"
}
},
"type": "object"
}
},
"required": [
"spec"
],
"type": "object"
}
@@ -0,0 +1,163 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"apiVersion": {
"type": "string"
},
"kind": {
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"properties": {
"allowCrossNamespaceImport": {
"default": false,
"type": "boolean"
},
"editable": {
"type": "boolean",
"x-kubernetes-validations": [
{
"message": "spec.editable is immutable",
"rule": "self == oldSelf"
}
]
},
"instanceSelector": {
"properties": {
"matchExpressions": {
"items": {
"properties": {
"key": {
"type": "string"
},
"operator": {
"type": "string"
},
"values": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"key",
"operator"
],
"type": "object"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"matchLabels": {
"additionalProperties": {
"type": "string"
},
"type": "object"
}
},
"type": "object",
"x-kubernetes-map-type": "atomic",
"x-kubernetes-validations": [
{
"message": "spec.instanceSelector is immutable",
"rule": "self == oldSelf"
}
]
},
"name": {
"type": "string"
},
"resyncPeriod": {
"pattern": "^([0-9]+(\\.[0-9]+)?(ns|us|\u00b5s|ms|s|m|h))+$",
"type": "string"
},
"suspend": {
"type": "boolean"
},
"template": {
"type": "string"
}
},
"required": [
"instanceSelector",
"name"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "spec.editable is immutable",
"rule": "((!has(oldSelf.editable) && !has(self.editable)) || (has(oldSelf.editable) && has(self.editable)))"
},
{
"message": "disabling spec.allowCrossNamespaceImport requires a recreate to ensure desired state",
"rule": "!oldSelf.allowCrossNamespaceImport || (oldSelf.allowCrossNamespaceImport && self.allowCrossNamespaceImport)"
}
]
},
"status": {
"properties": {
"conditions": {
"items": {
"properties": {
"lastTransitionTime": {
"format": "date-time",
"type": "string"
},
"message": {
"maxLength": 32768,
"type": "string"
},
"observedGeneration": {
"format": "int64",
"minimum": 0,
"type": "integer"
},
"reason": {
"maxLength": 1024,
"minLength": 1,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
},
"status": {
"enum": [
"True",
"False",
"Unknown"
],
"type": "string"
},
"type": {
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
}
},
"required": [
"lastTransitionTime",
"message",
"reason",
"status",
"type"
],
"type": "object"
},
"type": "array"
},
"lastResync": {
"format": "date-time",
"type": "string"
}
},
"type": "object"
}
},
"required": [
"spec"
],
"type": "object"
}
@@ -0,0 +1,221 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"apiVersion": {
"type": "string"
},
"kind": {
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"properties": {
"instanceName": {
"minLength": 1,
"type": "string",
"x-kubernetes-validations": [
{
"message": "spec.instanceName is immutable",
"rule": "self == oldSelf"
}
]
},
"isDisabled": {
"default": false,
"type": "boolean"
},
"name": {
"minLength": 1,
"type": "string",
"x-kubernetes-validations": [
{
"message": "spec.name is immutable",
"rule": "self == oldSelf"
}
]
},
"resyncPeriod": {
"pattern": "^([0-9]+(\\.[0-9]+)?(ns|us|\u00b5s|ms|s|m|h))+$",
"type": "string",
"x-kubernetes-validations": [
{
"message": "spec.resyncPeriod must be greater than 0",
"rule": "duration(self) > duration('0s')"
}
]
},
"role": {
"enum": [
"Viewer",
"Editor",
"Admin"
],
"type": "string"
},
"suspend": {
"default": false,
"type": "boolean"
},
"tokens": {
"items": {
"properties": {
"expires": {
"format": "date-time",
"type": "string"
},
"name": {
"minLength": 1,
"type": "string"
},
"secretName": {
"minLength": 1,
"type": "string"
}
},
"required": [
"name"
],
"type": "object"
},
"type": "array",
"x-kubernetes-list-map-keys": [
"name"
],
"x-kubernetes-list-type": "map"
}
},
"required": [
"instanceName",
"role"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "spec.name is immutable",
"rule": "((!has(oldSelf.name) && !has(self.name)) || (has(oldSelf.name) && has(self.name)))"
}
]
},
"status": {
"properties": {
"account": {
"properties": {
"id": {
"format": "int64",
"type": "integer"
},
"isDisabled": {
"type": "boolean"
},
"login": {
"type": "string"
},
"name": {
"type": "string"
},
"role": {
"type": "string"
},
"tokens": {
"items": {
"properties": {
"expires": {
"format": "date-time",
"type": "string"
},
"id": {
"format": "int64",
"type": "integer"
},
"name": {
"type": "string"
},
"secret": {
"properties": {
"name": {
"type": "string"
},
"namespace": {
"type": "string"
}
},
"type": "object"
}
},
"required": [
"id",
"name"
],
"type": "object"
},
"type": "array"
}
},
"required": [
"id",
"isDisabled",
"login",
"name",
"role"
],
"type": "object"
},
"conditions": {
"items": {
"properties": {
"lastTransitionTime": {
"format": "date-time",
"type": "string"
},
"message": {
"maxLength": 32768,
"type": "string"
},
"observedGeneration": {
"format": "int64",
"minimum": 0,
"type": "integer"
},
"reason": {
"maxLength": 1024,
"minLength": 1,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
},
"status": {
"enum": [
"True",
"False",
"Unknown"
],
"type": "string"
},
"type": {
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
}
},
"required": [
"lastTransitionTime",
"message",
"reason",
"status",
"type"
],
"type": "object"
},
"type": "array"
},
"lastResync": {
"format": "date-time",
"type": "string"
}
},
"type": "object"
}
},
"type": "object"
}