Skip to content

Commit 4fb5d2c

Browse files
committed
docs: review and update all documentation for v0.1.0 release
- Add CHANGELOG.md with v0.1.0 entry covering all 4 API groups and 20 CRDs - Document new certSecretRef field for external TLS verification in README and Helm chart README; clarify MissingExternalTLSCert condition - Correct credential documentation: list all three options (SecretRef, username/password, inline) and note external components require explicit creds - Fix external-searchdb-example.yaml: add TLS Secret and certSecretRef to satisfy the new MissingExternalTLSCert validation gate - Fix example files: storageConfig (was storage), heapSize (was jvmHeapSize), remove invalid replicas field on Server/TimeSeries/Search components - Fix connectionRef in examples to reference AxonOpsConnection CR not a Secret; add AxonOpsConnection CR definitions to all three example files - Fix MetricAlertFilters field: dc (was dataCenter) - Fix CRD count in Helm chart README: 20 (was 19)
1 parent 219cdb8 commit 4fb5d2c

9 files changed

Lines changed: 256 additions & 96 deletions

File tree

CHANGELOG.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6+
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
---
9+
10+
## [0.1.0] — 2026-04-09
11+
12+
Initial public release of the AxonOps Kubernetes Operator.
13+
14+
### Added
15+
16+
#### Infrastructure (`core.axonops.com`)
17+
- `AxonOpsPlatform` CRD — deploys and manages the full AxonOps server stack (axon-server, axon-dash, axondb-timeseries, axondb-search) from a single declarative resource
18+
- `AxonOpsConnection` CRD — stores reusable AxonOps API credentials referenced by alert and backup CRDs
19+
- Internal database components: operator-managed StatefulSets with automatic credential generation and TLS certificate provisioning via cert-manager
20+
- External database support: connect axon-server to user-managed Cassandra and Elasticsearch/OpenSearch clusters
21+
- TLS for external connections: `spec.*.external.tls.certSecretRef` — required when `tls.enabled=true` and `tls.insecureSkipVerify=false`; omitting it sets `Ready=False` with reason `MissingExternalTLSCert`
22+
- `spec.imageRegistry` — global registry override for all default component images (on-premises support)
23+
- `spec.initImage` — configurable init container image (default: `docker.io/library/busybox:1.37.0`)
24+
- `spec.pause` — halts reconciliation without deleting owned resources
25+
- Startup ordering: Server waits for databases to be ready; Dashboard waits for Server
26+
- Config rolling updates via checksum annotations on pod templates
27+
- Ingress and Gateway API support for Server (agent and API endpoints) and Dashboard
28+
- `spec.server.license.secretRef` / `spec.server.license.key` for license configuration
29+
- `spec.server.config` for additional axon-server configuration (merged into generated config)
30+
31+
#### Alerting and operations (`alerts.axonops.com`)
32+
- `AxonOpsMetricAlert` — metric threshold alert rules
33+
- `AxonOpsLogAlert` — log pattern alert rules
34+
- `AxonOpsAlertRoute` — alert routing to notification channels
35+
- `AxonOpsAlertEndpoint` — integration endpoint definitions (PagerDuty, Slack, email, OpsGenie, etc.)
36+
- `AxonOpsHealthcheckHTTP` — HTTP endpoint healthchecks
37+
- `AxonOpsHealthcheckTCP` — TCP port healthchecks
38+
- `AxonOpsHealthcheckShell` — shell script healthchecks
39+
- `AxonOpsDashboardTemplate` — declarative dashboard management
40+
- `AxonOpsAdaptiveRepair` — adaptive Cassandra repair configuration
41+
- `AxonOpsScheduledRepair` — cron-based Cassandra scheduled repairs
42+
- `AxonOpsCommitlogArchive` — commitlog archive settings
43+
- `AxonOpsSilenceWindow` — alert silence windows
44+
- `AxonOpsLogCollector` — log collector configuration
45+
46+
#### Backups (`backups.axonops.com`)
47+
- `AxonOpsBackup` — Cassandra scheduled snapshot backups with S3, SFTP, and Azure Blob storage support; inline and SecretRef credential patterns
48+
49+
#### Kafka (`kafka.axonops.com`)
50+
- `AxonOpsKafkaTopic` — Kafka topic lifecycle and configuration management
51+
- `AxonOpsKafkaACL` — Kafka ACL entry management
52+
- `AxonOpsKafkaConnector` — Kafka Connect connector management
53+
54+
#### Operator infrastructure
55+
- OpenTelemetry tracing support (OTLP exporter, configurable via environment variables)
56+
- Prometheus metrics endpoint with RBAC protection (port 8443, HTTPS)
57+
- Periodic drift detection on all controllers
58+
- Leader election support for multi-replica deployments
59+
- Namespace-scoped watch (`--watch-namespaces` flag)
60+
- Helm chart published to `oci://ghcr.io/axonops/charts/axonops-operator`
61+
- Kustomize-based installation (`make deploy`)
62+
- Convenience RBAC helper roles (`rbacHelpers.enable=true` in Helm values)
63+
64+
### Security
65+
- All AxonOps API URL path segments escaped with `url.PathEscape()` to prevent path injection
66+
- `errors.As` used throughout for safe API error type discrimination
67+
- Controller metrics served over HTTPS with RBAC-protected scraping endpoint
68+
69+
### Known limitations
70+
- Defaulting webhooks are not yet implemented; all components require explicit configuration (`enabled: true` must be set)
71+
- No conversion webhooks; only `v1alpha1` is available
72+
- External database credentials are not auto-generated; `authentication.secretRef` or inline credentials are required
73+
- `BuildHostURL` hardcodes `https://`, ignoring the `protocol` field in `AxonOpsConnection`
74+
- A new AxonOps API client is created on every reconciliation (no connection reuse)
75+
- Ingress and Gateway resources are not cleaned up automatically when disabled after initial creation
76+
77+
[0.1.0]: https://github.com/axonops/axonops-operator/releases/tag/v0.1.0

DEVELOPMENT.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -461,9 +461,10 @@ Add RBAC markers in the controller file alongside the `Reconcile` method. `make
461461
The `AxonAuthentication` struct defines credential priority for database components:
462462

463463
1. `SecretRef` — reference to an existing Kubernetes Secret (highest priority)
464-
2. Auto-generated random credentials via `generateRandomPassword` (default fallback)
464+
2. `Username` / `Password` — inline credentials specified directly in the CR
465+
3. Auto-generated random credentials via `generateRandomPassword` (default fallback for internal components only)
465466

466-
> **Note:** Inline `username` / `password` fields are not yet supported. Use `secretRef` or rely on auto-generation.
467+
> **Note:** Auto-generation applies only to internal (operator-managed) components. External components (`spec.*.external.hosts` set) require explicit credentials via `secretRef` or inline `username`/`password`.
467468
468469
The generated password meets complexity requirements: at least one uppercase letter, one digit, and one special character.
469470

README.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,17 @@ spec:
148148
external:
149149
hosts:
150150
- https://elasticsearch.example.com:9200
151+
tls:
152+
enabled: true
153+
insecureSkipVerify: true # Set to false and add certSecretRef for full TLS verification
154+
# certSecretRef: elasticsearch-tls # Secret with ca.crt, tls.crt, tls.key
151155
authentication:
152156
secretRef: elasticsearch-credentials # Secret with AXONOPS_SEARCH_USER / AXONOPS_SEARCH_PASSWORD
153157
dashboard: {}
154158
```
155159
160+
> **TLS verification:** When `tls.enabled=true` and `tls.insecureSkipVerify=false`, you must also set `tls.certSecretRef` to the name of a Secret containing `ca.crt`, `tls.crt`, and `tls.key`. Without it, the operator sets `Ready=False` with reason `MissingExternalTLSCert`.
161+
156162
### Alert management
157163

158164
Create an `AxonOpsConnection` once per namespace, then reference it from alert resources.
@@ -214,12 +220,13 @@ Each component can operate in **internal** (operator-managed) or **external** (u
214220

215221
### Authentication
216222

217-
For each database component, the operator uses credentials in this priority order:
223+
For internal (operator-managed) database components, credentials are resolved in this priority order:
218224

219-
1. `authentication.secretRef` — reference an existing Secret
220-
2. Auto-generated — operator creates and manages a Secret with random credentials
225+
1. `authentication.secretRef` — reference an existing Secret containing `AXONOPS_DB_USER` / `AXONOPS_DB_PASSWORD` (or `AXONOPS_SEARCH_USER` / `AXONOPS_SEARCH_PASSWORD` for Search)
226+
2. `authentication.username` / `authentication.password` — inline credentials in the CR
227+
3. Auto-generated — operator creates and manages a Secret with random credentials
221228

222-
> **Note:** Inline `authentication.username` / `authentication.password` fields are not yet supported. Use `secretRef` or rely on auto-generation.
229+
> **Note:** External components (those with `spec.*.external.hosts` set) require explicit credentials. Auto-generation does not apply to external database connections. Set `authentication.secretRef` or `authentication.username`/`authentication.password` when using external hosts.
223230

224231
### Ingress and Gateway API
225232

charts/axonops-operator/README.md

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ kubectl get crd | grep axonops.com
3737

3838
## Custom Resource Definitions
3939

40-
The operator introduces 19 CRDs across four API groups.
40+
The operator introduces 20 CRDs across four API groups.
4141

4242
### `core.axonops.com/v1alpha1`
4343

@@ -103,7 +103,7 @@ spec:
103103
104104
### Deploy the AxonOps stack with external databases
105105
106-
Use this form when Cassandra and Elasticsearch are managed outside the operator.
106+
Use this form when Cassandra and Elasticsearch are managed outside the operator. External components require explicit credentials — auto-generation does not apply.
107107
108108
```yaml
109109
apiVersion: core.axonops.com/v1alpha1
@@ -119,17 +119,25 @@ spec:
119119
hosts:
120120
- cassandra-node1.example.com:9042
121121
- cassandra-node2.example.com:9042
122+
tls:
123+
enabled: false
122124
authentication:
123-
secretRef: cassandra-credentials
125+
secretRef: cassandra-credentials # Secret with AXONOPS_DB_USER / AXONOPS_DB_PASSWORD
124126
search:
125127
external:
126128
hosts:
127129
- https://elasticsearch.example.com:9200
130+
tls:
131+
enabled: true
132+
insecureSkipVerify: true # Set to false and add certSecretRef for full TLS verification
133+
# certSecretRef: elasticsearch-tls # Secret with ca.crt, tls.crt, tls.key
128134
authentication:
129-
secretRef: elasticsearch-credentials
135+
secretRef: elasticsearch-credentials # Secret with AXONOPS_SEARCH_USER / AXONOPS_SEARCH_PASSWORD
130136
dashboard: {}
131137
```
132138
139+
> **TLS verification:** When `tls.enabled=true` and `tls.insecureSkipVerify=false`, you must set `tls.certSecretRef` to the name of a Secret containing `ca.crt`, `tls.crt`, and `tls.key`. Without it, the operator sets `Ready=False` with reason `MissingExternalTLSCert`.
140+
133141
### Configure an API connection and alert rule
134142

135143
`AxonOpsConnection` provides credentials for all other CRDs in the same namespace. `tokenType` is auto-detected from the host: cloud hosts (`dash.axonops.cloud`, `dash.axonopsdev.com`) default to `Bearer`; self-hosted instances default to `AxonApi`. Set it explicitly to override.

config/samples/external-searchdb-example.yaml

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,21 @@ stringData:
88
AXONOPS_SEARCH_USER: admin
99
AXONOPS_SEARCH_PASSWORD: "your-secure-password-here"
1010
---
11+
# TLS certificate secret for verifying the external Search endpoint.
12+
# Required when tls.enabled=true and tls.insecureSkipVerify=false.
13+
# The Secret must contain ca.crt, tls.crt, and tls.key.
14+
apiVersion: v1
15+
kind: Secret
16+
metadata:
17+
name: external-search-tls
18+
namespace: default
19+
type: kubernetes.io/tls
20+
data:
21+
# Base64-encoded PEM values:
22+
ca.crt: <base64-encoded-ca-cert>
23+
tls.crt: <base64-encoded-client-cert>
24+
tls.key: <base64-encoded-client-key>
25+
---
1126
apiVersion: core.axonops.com/v1alpha1
1227
kind: AxonOpsPlatform
1328
metadata:
@@ -23,8 +38,12 @@ spec:
2338
tls:
2439
enabled: true
2540
insecureSkipVerify: false
41+
# certSecretRef is required when insecureSkipVerify is false.
42+
# Omitting it will set Ready=False with reason MissingExternalTLSCert.
43+
certSecretRef: external-search-tls
2644
authentication:
27-
# Use an existing secret with credentials
45+
# Use an existing secret with credentials.
46+
# External Search requires explicit credentials — they are not auto-generated.
2847
secretRef: external-search-credentials
2948

3049
# Server configuration

examples/axonops/README.md

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,8 @@ kubectl port-forward -n axonops svc/server-dashboard 3000:3000
3838
**Use Case**: Production deployments with high availability
3939

4040
**Features**:
41-
- Multi-replica setup (HA):
42-
- Server: 3 replicas
43-
- TimeSeries: 3 replicas
44-
- Search: 2 replicas
45-
- Dashboard: 2 replicas
41+
- Larger resource allocations for TimeSeries, Search, and Dashboard components
42+
- Dashboard replicas set to 2 (the only component that supports the `replicas` field)
4643
- TLS certificates via cert-manager and Let's Encrypt
4744
- Proper resource requests/limits
4845
- 100Gi Server, 500Gi TimeSeries, 250Gi Search storage
@@ -79,12 +76,12 @@ kubectl apply -f examples/axonops/medium.yaml
7976
**Use Case**: Enterprise deployments with advanced features
8077

8178
**Features**:
82-
- Ultra-HA setup (5x Server, 5x TimeSeries, 3x Search, 3x Dashboard)
79+
- Full-scale setup (TimeSeries, Search, Dashboard StatefulSets/Deployments with large resource allocations)
8380
- Gateway API (Istio) instead of Ingress
8481
- Advanced TLS with Vault issuer
8582
- Large storage: 500Gi Server, 1Ti TimeSeries, 500Gi Search
86-
- JVM tuning (16GB heap for TimeSeries)
87-
- Multi-cluster support (Cassandra US-East, Kafka)
83+
- JVM tuning (16GB heap for TimeSeries via `heapSize`)
84+
- Multi-cluster monitoring support (Cassandra US-East, Kafka)
8885
- Sophisticated alert routing:
8986
- PagerDuty, Slack, OpsGenie integration
9087
- Different routing for Critical/Warning/Info
@@ -144,7 +141,6 @@ vault write pki/roles/kubernetes \
144141
spec:
145142
server:
146143
orgName: "Organization Name" # Required
147-
replicas: 3 # Number of server instances
148144
repository:
149145
image: "..." # Docker image
150146
tag: "..." # Image tag
@@ -156,8 +152,10 @@ spec:
156152
limits:
157153
cpu: "4"
158154
memory: "8Gi"
159-
storage:
160-
size: "100Gi"
155+
storageConfig: # PersistentVolumeClaimSpec
156+
resources:
157+
requests:
158+
storage: "100Gi"
161159
storageClassName: "fast-ssd"
162160
apiIngress: # Optional
163161
enabled: true
@@ -180,7 +178,7 @@ spec:
180178
```yaml
181179
spec:
182180
dashboard:
183-
replicas: 2
181+
replicas: 2 # Only dashboard supports replicas
184182
repository:
185183
image: "..."
186184
tag: "..."
@@ -198,15 +196,17 @@ spec:
198196
```yaml
199197
spec:
200198
timeSeries:
201-
replicas: 3
202-
storage:
203-
size: "500Gi"
199+
heapSize: "16384M" # JVM heap size (e.g., "1024M", "4G")
200+
storageConfig: # PersistentVolumeClaimSpec
201+
resources:
202+
requests:
203+
storage: "500Gi"
204204
storageClassName: "premium-ssd"
205-
jvmHeapSize: "16g" # JVM heap tuning
206205
search:
207-
replicas: 2
208-
storage:
209-
size: "250Gi"
206+
storageConfig:
207+
resources:
208+
requests:
209+
storage: "250Gi"
210210
storageClassName: "premium-ssd"
211211
```
212212
@@ -273,8 +273,10 @@ kubectl describe certificate axonops-api-tls -n axonops-prod
273273
```yaml
274274
spec:
275275
timeSeries:
276-
storage:
277-
size: "1Ti" # Increase to 1TB
276+
storageConfig:
277+
resources:
278+
requests:
279+
storage: "1Ti" # Increase to 1TB
278280
```
279281

280282
### Adjust resource limits
@@ -294,15 +296,15 @@ spec:
294296
```yaml
295297
spec:
296298
timeSeries:
297-
storage:
299+
storageConfig:
298300
storageClassName: "fast-nvme"
299301
```
300302

301303
### Configure custom JVM heap
302304
```yaml
303305
spec:
304306
timeSeries:
305-
jvmHeapSize: "32g" # For large deployments
307+
heapSize: "32768M" # For large deployments (e.g., 32GB)
306308
```
307309

308310
---

0 commit comments

Comments
 (0)