bindy/
constants.rs

1// Copyright (c) 2025 Erick Bourgeois, firestoned
2// SPDX-License-Identifier: MIT
3
4//! Global constants for the Bindy operator.
5//!
6//! This module contains all numeric and string constants used throughout the codebase.
7//! Constants are organized by category for easy maintenance.
8
9// ============================================================================
10// API Constants
11// ============================================================================
12
13/// API group for all Bindy DNS CRDs
14pub const API_GROUP: &str = "bindy.firestoned.io";
15
16/// API version for all Bindy DNS CRDs
17pub const API_VERSION: &str = "v1beta1";
18
19/// Fully qualified API version (group/version)
20pub const API_GROUP_VERSION: &str = "bindy.firestoned.io/v1beta1";
21
22/// Kind name for `DNSZone` resource
23pub const KIND_DNS_ZONE: &str = "DNSZone";
24
25/// Kind name for `ARecord` resource
26pub const KIND_A_RECORD: &str = "ARecord";
27
28/// Kind name for `AAAARecord` resource
29pub const KIND_AAAA_RECORD: &str = "AAAARecord";
30
31/// Kind name for `TXTRecord` resource
32pub const KIND_TXT_RECORD: &str = "TXTRecord";
33
34/// Kind name for `CNAMERecord` resource
35pub const KIND_CNAME_RECORD: &str = "CNAMERecord";
36
37/// Kind name for `MXRecord` resource
38pub const KIND_MX_RECORD: &str = "MXRecord";
39
40/// Kind name for `NSRecord` resource
41pub const KIND_NS_RECORD: &str = "NSRecord";
42
43/// Kind name for `SRVRecord` resource
44pub const KIND_SRV_RECORD: &str = "SRVRecord";
45
46/// Kind name for `CAARecord` resource
47pub const KIND_CAA_RECORD: &str = "CAARecord";
48
49/// Kind name for `Bind9Cluster` resource
50pub const KIND_BIND9_CLUSTER: &str = "Bind9Cluster";
51
52/// Kind name for `ClusterBind9Provider` resource
53pub const KIND_CLUSTER_BIND9_PROVIDER: &str = "ClusterBind9Provider";
54
55/// Kind name for `Bind9Instance` resource
56pub const KIND_BIND9_INSTANCE: &str = "Bind9Instance";
57
58// ============================================================================
59// DNS Protocol Constants
60// ============================================================================
61
62/// Standard DNS service port exposed externally
63pub const DNS_PORT: u16 = 53;
64
65/// DNS container port (non-privileged port for non-root execution)
66pub const DNS_CONTAINER_PORT: u16 = 5353;
67
68/// Standard RNDC control port (non-privileged)
69pub const RNDC_PORT: u16 = 9530;
70
71/// Default bindcar HTTP API container port
72pub const BINDCAR_API_PORT: u16 = 8080;
73
74/// Default bindcar HTTP API service port (exposed via Kubernetes Service)
75pub const BINDCAR_SERVICE_PORT: u16 = 80;
76
77/// Default TTL for DNS records (5 minutes)
78pub const DEFAULT_DNS_RECORD_TTL_SECS: i32 = 300;
79
80/// Default TTL for zone files (1 hour)
81pub const DEFAULT_ZONE_TTL_SECS: u32 = 3600;
82
83/// Default SOA refresh interval (1 hour)
84pub const DEFAULT_SOA_REFRESH_SECS: u32 = 3600;
85
86/// Default SOA retry interval (10 minutes)
87pub const DEFAULT_SOA_RETRY_SECS: u32 = 600;
88
89/// Default SOA expire time (7 days)
90pub const DEFAULT_SOA_EXPIRE_SECS: u32 = 604_800;
91
92/// Default SOA negative TTL (1 day)
93pub const DEFAULT_SOA_NEGATIVE_TTL_SECS: u32 = 86400;
94
95/// TSIG fudge time in seconds (allows for clock skew)
96pub const TSIG_FUDGE_TIME_SECS: u64 = 300;
97
98// ============================================================================
99// Kubernetes Health Check Constants
100// ============================================================================
101
102/// Liveness probe initial delay (wait for BIND9 to start)
103pub const LIVENESS_INITIAL_DELAY_SECS: i32 = 30;
104
105/// Liveness probe period (how often to check)
106pub const LIVENESS_PERIOD_SECS: i32 = 10;
107
108/// Liveness probe timeout
109pub const LIVENESS_TIMEOUT_SECS: i32 = 5;
110
111/// Liveness probe failure threshold
112pub const LIVENESS_FAILURE_THRESHOLD: i32 = 3;
113
114/// Readiness probe initial delay
115pub const READINESS_INITIAL_DELAY_SECS: i32 = 10;
116
117/// Readiness probe period
118pub const READINESS_PERIOD_SECS: i32 = 5;
119
120/// Readiness probe timeout
121pub const READINESS_TIMEOUT_SECS: i32 = 3;
122
123/// Readiness probe failure threshold
124pub const READINESS_FAILURE_THRESHOLD: i32 = 3;
125
126// ============================================================================
127// Controller Error Handling Constants
128// ============================================================================
129
130/// Requeue duration for controller errors (30 seconds)
131pub const ERROR_REQUEUE_DURATION_SECS: u64 = 30;
132
133// ============================================================================
134// Leader Election Constants
135// ============================================================================
136
137/// Default leader election lease duration (15 seconds)
138pub const DEFAULT_LEASE_DURATION_SECS: u64 = 15;
139
140/// Default leader election renew deadline (10 seconds)
141pub const DEFAULT_LEASE_RENEW_DEADLINE_SECS: u64 = 10;
142
143/// Default leader election retry period (2 seconds)
144pub const DEFAULT_LEASE_RETRY_PERIOD_SECS: u64 = 2;
145
146// ============================================================================
147// BIND9 Version Constants
148// ============================================================================
149
150/// Default BIND9 version tag
151pub const DEFAULT_BIND9_VERSION: &str = "9.18";
152
153/// `ServiceAccount` name for BIND9 pods
154pub const BIND9_SERVICE_ACCOUNT: &str = "bind9";
155
156/// `MALLOC_CONF` environment variable value for BIND9 containers
157///
158/// Optimizes jemalloc memory decay for containerized environments:
159/// - `dirty_decay_ms:0` - Immediately return dirty pages to OS
160/// - `muzzy_decay_ms:0` - Immediately return muzzy pages to OS
161///
162/// This enables more aggressive memory reclamation in environments where
163/// memory pressure is monitored closely.
164pub const BIND9_MALLOC_CONF: &str = "dirty_decay_ms:0,muzzy_decay_ms:0";
165
166/// UID for running BIND9 and bindcar containers as non-root
167///
168/// This UID corresponds to the 'bind' or 'named' user in most BIND9 images.
169/// Running as non-root improves container security by following the principle
170/// of least privilege.
171pub const BIND9_NONROOT_UID: i64 = 101;
172
173// ============================================================================
174// Bindcar Container Constants
175// ============================================================================
176
177/// Default bindcar sidecar container image
178///
179/// This is the default image used for the bindcar HTTP API sidecar container
180/// when no image is specified in the `BindcarConfig` of a `Bind9Instance`,
181/// `Bind9Cluster`, or `ClusterBind9Provider`.
182pub const DEFAULT_BINDCAR_IMAGE: &str = "ghcr.io/firestoned/bindcar:v0.5.1";
183
184// ============================================================================
185// Container Name Constants
186// ============================================================================
187
188/// Name of the BIND9 container in the pod
189pub const CONTAINER_NAME_BIND9: &str = "bind9";
190
191/// Name of the bindcar API sidecar container in the pod
192pub const CONTAINER_NAME_BINDCAR: &str = "api";
193
194// ============================================================================
195// Runtime Constants
196// ============================================================================
197
198/// Number of worker threads for Tokio runtime
199pub const TOKIO_WORKER_THREADS: usize = 4;
200
201// ============================================================================
202// Replica Count Constants
203// ============================================================================
204
205/// Minimum number of replicas for testing
206pub const MIN_TEST_REPLICAS: i32 = 2;
207
208/// Maximum reasonable number of replicas for testing
209pub const MAX_TEST_REPLICAS: i32 = 10;
210
211// ============================================================================
212// Metrics Server Constants
213// ============================================================================
214
215/// Port for Prometheus metrics HTTP server
216pub const METRICS_SERVER_PORT: u16 = 8080;
217
218/// Path for Prometheus metrics endpoint
219pub const METRICS_SERVER_PATH: &str = "/metrics";
220
221/// Bind address for metrics HTTP server
222pub const METRICS_SERVER_BIND_ADDRESS: &str = "0.0.0.0";
223
224// ============================================================================
225// DNSZone Record Ownership Constants
226// ============================================================================
227
228/// Annotation key for marking which zone owns a DNS record
229///
230/// When a `DNSZone`'s label selector matches a DNS record, the `DNSZone` controller
231/// sets this annotation on the record with the value being the zone's FQDN.
232/// Record reconcilers read this annotation to determine which zone to update.
233pub const ANNOTATION_ZONE_OWNER: &str = "bindy.firestoned.io/zone";
234
235/// Annotation key for marking which zone previously owned a record
236///
237/// When a record stops matching a zone's selector, the `DNSZone` controller sets
238/// this annotation before removing the zone ownership. This helps track orphaned
239/// records and enables cleanup workflows.
240pub const ANNOTATION_ZONE_PREVIOUS_OWNER: &str = "bindy.firestoned.io/previous-zone";
241
242// ============================================================================
243// RNDC Key Rotation Constants
244// ============================================================================
245
246/// Annotation key for RNDC key creation timestamp (ISO 8601 format)
247///
248/// Tracks when the current RNDC key was created or last rotated.
249/// Used by the rotation reconciler to determine when rotation is due.
250///
251/// Example value: `"2025-01-26T10:00:00Z"`
252pub const ANNOTATION_RNDC_CREATED_AT: &str = "bindy.firestoned.io/rndc-created-at";
253
254/// Annotation key for RNDC key rotation timestamp (ISO 8601 format)
255///
256/// Tracks when the RNDC key should be rotated next.
257/// Calculated as: `created_at + rotate_after`
258///
259/// Only present when `auto_rotate` is enabled.
260///
261/// Example value: `"2025-02-25T10:00:00Z"` (30 days after creation)
262pub const ANNOTATION_RNDC_ROTATE_AT: &str = "bindy.firestoned.io/rndc-rotate-at";
263
264/// Annotation key for RNDC key rotation count
265///
266/// Tracks the number of times the RNDC key has been rotated.
267/// Starts at `0` for newly-created keys and increments on each rotation.
268///
269/// Example value: `"5"` (key has been rotated 5 times)
270pub const ANNOTATION_RNDC_ROTATION_COUNT: &str = "bindy.firestoned.io/rndc-rotation-count";
271
272/// Annotation key for tracking pod restarts after RNDC rotation
273///
274/// Added to Deployment pod template to trigger rolling restart when RNDC key is rotated.
275/// Value is the timestamp when rotation occurred (ISO 8601 format).
276///
277/// Example value: `"2025-01-26T10:30:00Z"`
278pub const ANNOTATION_RNDC_ROTATED_AT: &str = "bindy.firestoned.io/rndc-rotated-at";
279
280/// Minimum rotation interval in hours (1 hour)
281///
282/// RNDC keys cannot be rotated more frequently than once per hour.
283/// This prevents infinite reconciliation loops and rate-limits rotation operations.
284pub const MIN_ROTATION_INTERVAL_HOURS: u64 = 1;
285
286/// Maximum rotation interval in hours (8760 hours = 365 days = 1 year)
287///
288/// RNDC keys must be rotated at least once per year for security compliance.
289/// This is the upper bound for the `rotate_after` configuration.
290pub const MAX_ROTATION_INTERVAL_HOURS: u64 = 8760;
291
292/// Default rotation interval (720 hours = 30 days)
293///
294/// Default value for the `rotate_after` field when `auto_rotate` is enabled.
295/// Balances security (regular rotation) with operational stability (not too frequent).
296///
297/// This is specified as a Go duration string: `"720h"`
298pub const DEFAULT_ROTATION_INTERVAL: &str = "720h";
299
300/// Minimum time between rotations in hours (1 hour)
301///
302/// Even if rotation is due (based on `rotate_at` timestamp), the reconciler
303/// will not rotate a key if it was created or rotated within the last hour.
304///
305/// This prevents rapid successive rotations in edge cases (e.g., clock skew,
306/// manual timestamp manipulation, reconciliation loops).
307pub const MIN_TIME_BETWEEN_ROTATIONS_HOURS: i64 = 1;
308
309// ============================================================================
310// Kubernetes API Client Rate Limiting Constants
311// ============================================================================
312
313/// Kubernetes API client queries per second (sustained rate)
314///
315/// This matches kubectl default rate limits and has been tested at scale.
316/// Prevents overwhelming the API server with too many requests.
317/// Can be overridden via `BINDY_KUBE_QPS` environment variable.
318pub const KUBE_CLIENT_QPS: f32 = 20.0;
319
320/// Kubernetes API client burst size (max concurrent requests)
321///
322/// Allows temporary bursts above the QPS limit for reconciliation spikes.
323/// Matches kubectl defaults for optimal API server behavior.
324/// Can be overridden via `BINDY_KUBE_BURST` environment variable.
325pub const KUBE_CLIENT_BURST: u32 = 30;
326
327/// Page size for Kubernetes API list operations
328///
329/// Balances memory usage vs. number of API calls.
330/// Limits each list response to 100 items, reducing memory pressure
331/// when listing large resource sets (e.g., 1000+ `DNSZone`s).
332///
333/// With 100 items per page:
334/// - 1000 resources = 10 API calls
335/// - Memory usage remains constant (O(1) relative to total count)
336/// - Reduces API server load per request
337pub const KUBE_LIST_PAGE_SIZE: u32 = 100;