Reconciliation Logic
Detailed reconciliation logic for each resource type.
Status Update Optimization
All reconcilers implement status change detection to prevent tight reconciliation loops. Before updating the status subresource, each reconciler checks if the status has actually changed. This prevents unnecessary API calls and reconciliation cycles.
Status is only updated when:
- Condition type changes
- Status value changes
- Message changes
- Status doesn’t exist yet
This optimization is implemented in:
Bind9Clusterreconciler (src/reconcilers/bind9cluster.rs:394-430)Bind9Instancereconciler (src/reconcilers/bind9instance.rs:736-758)DNSZonereconciler (src/reconcilers/dnszone.rs:535-565)- All record reconcilers (src/reconcilers/records.rs:1032-1072)
Bind9Instance Reconciliation
#![allow(unused)]
fn main() {
async fn reconcile_bind9instance(instance: Bind9Instance) -> Result<()> {
// 1. Build desired resources
let configmap = build_configmap(&instance);
let deployment = build_deployment(&instance);
let service = build_service(&instance);
// 2. Apply or update ConfigMap
apply_configmap(configmap).await?;
// 3. Apply or update Deployment
apply_deployment(deployment).await?;
// 4. Apply or update Service
apply_service(service).await?;
// 5. Update status
update_status(&instance, "Ready").await?;
Ok(())
}
}
DNSZone Reconciliation
DNSZone reconciliation uses granular status updates to provide real-time progress visibility and better error reporting. The reconciliation follows a multi-phase approach with status updates at each phase.
Reconciliation Flow
#![allow(unused)]
fn main() {
async fn reconcile_dnszone(zone: DNSZone) -> Result<()> {
// Phase 1: Set Progressing status before primary reconciliation
update_condition(&zone, "Progressing", "True", "PrimaryReconciling",
"Configuring zone on primary instances").await?;
// Phase 2: Configure zone on primary instances
let primary_count = add_dnszone(client, &zone, zone_manager).await
.map_err(|e| {
// On failure: Set Degraded status (primary failure is fatal)
update_condition(&zone, "Degraded", "True", "PrimaryFailed",
&format!("Failed to configure zone on primaries: {}", e)).await?;
e
})?;
// Phase 3: Set Progressing status after primary success
update_condition(&zone, "Progressing", "True", "PrimaryReconciled",
&format!("Configured on {} primary server(s)", primary_count)).await?;
// Phase 4: Set Progressing status before secondary reconciliation
let secondary_msg = format!("Configured on {} primary server(s), now configuring secondaries", primary_count);
update_condition(&zone, "Progressing", "True", "SecondaryReconciling", &secondary_msg).await?;
// Phase 5: Configure zone on secondary instances (non-fatal if fails)
match add_dnszone_to_secondaries(client, &zone, zone_manager).await {
Ok(secondary_count) => {
// Phase 6: Success - Set Ready status
let msg = format!("Configured on {} primary server(s) and {} secondary server(s)",
primary_count, secondary_count);
update_status_with_secondaries(&zone, "Ready", "True", "ReconcileSucceeded",
&msg, secondary_ips).await?;
}
Err(e) => {
// Phase 6: Partial success - Set Degraded status (primaries work, secondaries failed)
let msg = format!("Configured on {} primary server(s), but secondary configuration failed: {}",
primary_count, e);
update_status_with_secondaries(&zone, "Degraded", "True", "SecondaryFailed",
&msg, secondary_ips).await?;
}
}
Ok(())
}
}
Status Conditions
DNSZone reconciliation uses three condition types:
-
Progressing- During reconciliation phases- Reason:
PrimaryReconciling- Before primary configuration - Reason:
PrimaryReconciled- After primary configuration succeeds - Reason:
SecondaryReconciling- Before secondary configuration - Reason:
SecondaryReconciled- After secondary configuration succeeds
- Reason:
-
Ready- Successful reconciliation- Reason:
ReconcileSucceeded- All phases completed successfully
- Reason:
-
Degraded- Partial or complete failure- Reason:
PrimaryFailed- Primary configuration failed (fatal, reconciliation aborts) - Reason:
SecondaryFailed- Secondary configuration failed (non-fatal, primaries still work)
- Reason:
Benefits
- Real-time progress visibility - Users can see which phase is running
- Better error reporting - Know exactly which phase failed (primary vs secondary)
- Graceful degradation - Secondary failures don’t break the zone (primaries still work)
- Accurate status - Endpoint counts reflect actual configured servers
Record Reconciliation
All record types (A, AAAA, CNAME, MX, TXT, NS, SRV, CAA) follow a consistent pattern with granular status updates for better observability.
Reconciliation Flow
#![allow(unused)]
fn main() {
async fn reconcile_record(record: Record) -> Result<()> {
// Phase 1: Set Progressing status before configuration
update_record_status(&record, "Progressing", "True", "RecordReconciling",
"Configuring A record on zone endpoints").await?;
// Phase 2: Get zone and configure record on all endpoints
let zone = get_zone(&record.spec.zone).await?;
match add_record_to_all_endpoints(&zone, &record).await {
Ok(endpoint_count) => {
// Phase 3: Success - Set Ready status with endpoint count
let msg = format!("Record configured on {} endpoint(s)", endpoint_count);
update_record_status(&record, "Ready", "True", "ReconcileSucceeded", &msg).await?;
}
Err(e) => {
// Phase 3: Failure - Set Degraded status with error details
let msg = format!("Failed to configure record: {}", e);
update_record_status(&record, "Degraded", "True", "RecordFailed", &msg).await?;
return Err(e);
}
}
Ok(())
}
}
Status Conditions
All DNS record types use three condition types:
-
Progressing- During record configuration- Reason:
RecordReconciling- Before adding record to zone endpoints
- Reason:
-
Ready- Successful configuration- Reason:
ReconcileSucceeded- Record configured on all endpoints - Message includes count of configured endpoints (e.g., “Record configured on 3 endpoint(s)”)
- Reason:
-
Degraded- Configuration failure- Reason:
RecordFailed- Failed to configure record (includes error details)
- Reason:
Benefits
- Real-time progress - See when records are being configured
- Better debugging - Know immediately if/why a record failed
- Accurate reporting - Status shows exact number of endpoints configured
- Consistent with zones - Same status pattern as DNSZone reconciliation
Supported Record Types
All 8 record types use this granular status approach:
- A - IPv4 address records
- AAAA - IPv6 address records
- CNAME - Canonical name (alias) records
- MX - Mail exchange records
- TXT - Text records (SPF, DKIM, DMARC, etc.)
- NS - Nameserver delegation records
- SRV - Service location records
- CAA - Certificate authority authorization records