Files
terdut-operator/charts/terdut-operator/templates/crd/terdutalertsources.terdut.ryuvia.com.yaml
T
Niklas Ye b4ccdb09d5
Release / test (push) Successful in 2m48s
CI / chart (push) Successful in 1s
CI / security (push) Successful in 1m3s
CI / test (push) Successful in 2m5s
Release / chart (push) Successful in 4s
Release / image (push) Successful in 7m6s
Release / scan-image (push) Failing after 33s
Stage 5: installer chart + release infra, kind e2e pass through the chart
Chart (charts/terdut-operator) generated via kubebuilder's own helm/v2-alpha
plugin from config/'s kustomize output -- CRDs + manager Deployment/RBAC
come from the same markers every other stage already generates, one source
of truth. Hand-added on top: the optional terdutServer values block
(DESIGN.md §10's "helm install and get a server" path, off by default) and
the release-skill plumbing -- .release.conf, release-vars/helm-lint/push/
helm-package/helm-push/release Makefile targets, .gitea/workflows/release.yaml
(test -> image/chart -> scan-image) -- mirroring terdut-server's own shape
(registry/namespace convention, multi-arch buildx push, trivy/govulncheck/
gitleaks scans). ci.yaml gains security and chart jobs to match.

Two real issues caught while wiring this, fixed before either shipped:
- Dockerfile's builder stage didn't pin --platform=$BUILDPLATFORM, which
  would have made a multi-arch release build fail outright on this org's
  runners (no binfmt registration) -- same fix terdut-server's own
  Dockerfile already needed for the same reason.
- govulncheck found one real, reachable finding: google.golang.org/grpc
  v1.82.1 (transitive via controller-runtime's otel exporter), fixed by
  bumping to v1.83.1.

Full golden-path kind e2e pass, this time through `helm install` rather than
raw kustomize: TerdutServer (real terdut-server v0.33.0 image) -> TerdutTeam
-> one of each child kind, each confirmed Ready and then independently
confirmed against terdut-server's own API from inside the cluster (not just
the operator's own status). Deleted every CR in reverse order and confirmed
server-side cleanup the same independent way for all three child kinds, the
team, and the server. No new bugs found -- Stage 1's own kind pass already
caught what a real cluster catches that envtest can't.

Also dropped the kubebuilder helm plugin's default .github/workflows/
scaffold, same as Stage 0 already did for the main scaffold: this org runs
on Gitea, not GitHub.

Not done here, deliberately: an actual tagged release. release-preflight
found no terdut-operator/ entry under Ryuvia/charts yet to bump -- that
one-time wrapper bootstrap is a decision about deploying this operator for
real, not a side effect of finishing this stage.

make fmt lint test helm-lint build all clean.
2026-10-01 14:47:10 +02:00

199 lines
8.7 KiB
YAML

{{- if .Values.crd.enabled }}
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
{{- if .Values.crd.keep }}
"helm.sh/resource-policy": keep
{{- end }}
controller-gen.kubebuilder.io/version: v0.22.0
name: terdutalertsources.terdut.ryuvia.com
spec:
group: terdut.ryuvia.com
names:
kind: TerdutAlertSource
listKind: TerdutAlertSourceList
plural: terdutalertsources
singular: terdutalertsource
scope: Namespaced
versions:
- additionalPrinterColumns:
- jsonPath: .spec.teamRef.name
name: Team
type: string
- jsonPath: .status.integrationID
name: IntegrationID
type: integer
- jsonPath: .status.conditions[?(@.type=="Ready")].status
name: Ready
type: string
- jsonPath: .status.conditions[?(@.type=="Ready")].reason
name: Reason
type: string
name: v1alpha1
schema:
openAPIV3Schema:
description: TerdutAlertSource is the Schema for the terdutalertsources API
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: spec defines the desired state of TerdutAlertSource
properties:
kind:
default: alertmanager
description: |-
kind is the alert source type. Only "alertmanager" is supported
today, mirroring terdut-server's own CHECK constraint on
integrations.kind (internal/db/migrations/003_teams.sql) --
confirmed against source, not assumed. Changing it after the
integration already exists rotates the webhook key (DESIGN.md §5's
reconciliation table): the old one is deleted and a fresh one
created, which breaks whatever sends to the old URL until the new
Secret is picked up.
enum:
- alertmanager
type: string
name:
description: |-
name is this source's own display name server-side -- distinct from
this object's own metadata.name. POST
/api/teams/{teamID}/integrations {"name": ...} at creation, and what
PATCH renames thereafter; renaming never rotates the webhook key.
minLength: 1
type: string
teamRef:
description: |-
TerdutTeamRef names the TerdutTeam this resource belongs to. Always
same-namespace as the CR itself (DESIGN.md §1: only TerdutTeam.spec.serverRef
crosses namespaces in v1) -- no namespace field, unlike TerdutServerRef.
properties:
name:
minLength: 1
type: string
required:
- name
type: object
required:
- name
- teamRef
type: object
status:
description: status defines the observed state of TerdutAlertSource
properties:
conditions:
items:
description: Condition contains details for one aspect of the current
state of this API Resource.
properties:
lastTransitionTime:
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
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
x-kubernetes-list-map-keys:
- type
x-kubernetes-list-type: map
integrationID:
description: integrationID is the server-side id.
format: int64
type: integer
lastAppliedKind:
description: |-
lastAppliedKind is the kind the currently-live integration was
actually created with -- compared against spec.kind on every
reconcile to detect the one spec change that requires
delete-and-recreate (DESIGN.md §5), since terdut-server's own API has
no way to read a live integration's kind back for comparison.
type: string
observedGeneration:
format: int64
type: integer
webhookURLSecretRef:
description: |-
webhookURLSecretRef names the generated Secret holding "url" and
"key" -- the integration's webhook address and credential, shown by
terdut-server's API exactly once, at creation (DESIGN.md §4.5), and
never re-readable afterward, including from this status. Lives in
this CR's own namespace with a plain OwnerReference (§7) -- unlike
TerdutServer/TerdutTeam's credential Secrets, this one never crosses
namespaces, so no finalizer cleanup is needed for it specifically.
properties:
name:
description: name is the Secret's name.
minLength: 1
type: string
required:
- name
type: object
type: object
required:
- spec
type: object
served: true
storage: true
subresources:
status: {}
{{- end }}