Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

All notable changes to this project will be documented in this file.

## 0.2.6 - 2026-06-03

### Added

- Add `spec.template.pod.hostAliases` support for `KafkaBackup` and `KafkaRestore` job pods. Fixes [#22](https://github.com/osodevops/strimzi-backup-operator/issues/22).

## 0.2.5 - 2026-05-17

### Changed
Expand Down
3 changes: 2 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "kafka-backup-operator"
version = "0.2.5"
version = "0.2.6"
edition = "2021"
rust-version = "1.88"
license = "Apache-2.0"
Expand All @@ -19,7 +19,7 @@ path = "src/bin/crdgen.rs"
# Kubernetes
kube = { version = "0.95", features = ["runtime", "derive", "client"] }
kube-runtime = "0.95"
k8s-openapi = { version = "0.23", features = ["v1_30"] }
k8s-openapi = { version = "0.23", features = ["v1_30", "schemars"] }

# Async runtime
tokio = { version = "1", features = ["full", "signal"] }
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ The **Kafka Backup Operator** solves these problems with a purpose-built Kuberne
- **Retention policies** — automatic pruning of old backups by count or age
- **Compression** — gzip, snappy, lz4, or zstd compression for storage efficiency
- **Prometheus metrics** — built-in observability with backup/restore counters, duration histograms, and storage gauges
- **Pod template customisation** — full control over backup/restore Job pods (affinity, tolerations, security context, environment variables)
- **Pod template customisation** — full control over backup/restore Job pods (affinity, tolerations, host aliases, security context, environment variables)
- **Azure Workload Identity** — native support for passwordless Azure authentication

## Architecture
Expand Down
7 changes: 7 additions & 0 deletions config/examples/kafka-backup-s3.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,10 @@ spec:
limits:
cpu: "2"
memory: "4Gi"

template:
pod:
hostAliases:
- ip: "10.10.0.5"
hostnames:
- "s3.internal"
7 changes: 7 additions & 0 deletions config/examples/kafka-restore-pitr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,10 @@ spec:
limits:
cpu: "4"
memory: "8Gi"

template:
pod:
hostAliases:
- ip: "10.10.0.5"
hostnames:
- "s3.internal"
22 changes: 17 additions & 5 deletions deploy/crds/kafkabackups.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -667,8 +667,6 @@ spec:
description: Container security context (pass-through to k8s SecurityContext)
type: object
x-kubernetes-preserve-unknown-fields: true
required:
- securityContext
type: object
pod:
description: Pod-level overrides
Expand All @@ -678,6 +676,23 @@ spec:
description: Pod affinity rules (pass-through to k8s Affinity)
type: object
x-kubernetes-preserve-unknown-fields: true
hostAliases:
description: Pod host aliases (pass-through to k8s HostAlias)
items:
description: HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the pod's hosts file.
properties:
hostnames:
description: Hostnames for the above IP address.
items:
type: string
type: array
ip:
description: IP address of the host file entry.
type: string
required:
- ip
type: object
type: array
imagePullSecrets:
description: Image pull secrets
items:
Expand Down Expand Up @@ -709,9 +724,6 @@ spec:
type: object
x-kubernetes-preserve-unknown-fields: true
type: array
required:
- affinity
- securityContext
type: object
type: object
topics:
Expand Down
22 changes: 17 additions & 5 deletions deploy/crds/kafkarestores.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -465,8 +465,6 @@ spec:
description: Container security context (pass-through to k8s SecurityContext)
type: object
x-kubernetes-preserve-unknown-fields: true
required:
- securityContext
type: object
pod:
description: Pod-level overrides
Expand All @@ -476,6 +474,23 @@ spec:
description: Pod affinity rules (pass-through to k8s Affinity)
type: object
x-kubernetes-preserve-unknown-fields: true
hostAliases:
description: Pod host aliases (pass-through to k8s HostAlias)
items:
description: HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the pod's hosts file.
properties:
hostnames:
description: Hostnames for the above IP address.
items:
type: string
type: array
ip:
description: IP address of the host file entry.
type: string
required:
- ip
type: object
type: array
imagePullSecrets:
description: Image pull secrets
items:
Expand Down Expand Up @@ -507,9 +522,6 @@ spec:
type: object
x-kubernetes-preserve-unknown-fields: true
type: array
required:
- affinity
- securityContext
type: object
type: object
topicMapping:
Expand Down
4 changes: 2 additions & 2 deletions deploy/helm/strimzi-backup-operator/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ apiVersion: v2
name: strimzi-backup-operator
description: Kubernetes operator for Kafka backup and restore, integrated with Strimzi
type: application
version: 0.2.5
appVersion: "0.2.5"
version: 0.2.6
appVersion: "0.2.6"
home: https://github.com/osodevops/strimzi-backup-operator
sources:
- https://github.com/osodevops/strimzi-backup-operator
Expand Down
22 changes: 17 additions & 5 deletions deploy/helm/strimzi-backup-operator/crds/kafkabackups.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -667,8 +667,6 @@ spec:
description: Container security context (pass-through to k8s SecurityContext)
type: object
x-kubernetes-preserve-unknown-fields: true
required:
- securityContext
type: object
pod:
description: Pod-level overrides
Expand All @@ -678,6 +676,23 @@ spec:
description: Pod affinity rules (pass-through to k8s Affinity)
type: object
x-kubernetes-preserve-unknown-fields: true
hostAliases:
description: Pod host aliases (pass-through to k8s HostAlias)
items:
description: HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the pod's hosts file.
properties:
hostnames:
description: Hostnames for the above IP address.
items:
type: string
type: array
ip:
description: IP address of the host file entry.
type: string
required:
- ip
type: object
type: array
imagePullSecrets:
description: Image pull secrets
items:
Expand Down Expand Up @@ -709,9 +724,6 @@ spec:
type: object
x-kubernetes-preserve-unknown-fields: true
type: array
required:
- affinity
- securityContext
type: object
type: object
topics:
Expand Down
22 changes: 17 additions & 5 deletions deploy/helm/strimzi-backup-operator/crds/kafkarestores.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -465,8 +465,6 @@ spec:
description: Container security context (pass-through to k8s SecurityContext)
type: object
x-kubernetes-preserve-unknown-fields: true
required:
- securityContext
type: object
pod:
description: Pod-level overrides
Expand All @@ -476,6 +474,23 @@ spec:
description: Pod affinity rules (pass-through to k8s Affinity)
type: object
x-kubernetes-preserve-unknown-fields: true
hostAliases:
description: Pod host aliases (pass-through to k8s HostAlias)
items:
description: HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the pod's hosts file.
properties:
hostnames:
description: Hostnames for the above IP address.
items:
type: string
type: array
ip:
description: IP address of the host file entry.
type: string
required:
- ip
type: object
type: array
imagePullSecrets:
description: Image pull secrets
items:
Expand Down Expand Up @@ -507,9 +522,6 @@ spec:
type: object
x-kubernetes-preserve-unknown-fields: true
type: array
required:
- affinity
- securityContext
type: object
type: object
topicMapping:
Expand Down
8 changes: 8 additions & 0 deletions docs/strimzi-backup-operator-prd.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,10 @@ spec:
prometheus.io/port: "9090"
affinity: {}
tolerations: []
hostAliases:
- ip: "10.10.0.5"
hostnames:
- "s3.internal"
securityContext:
runAsNonRoot: true
runAsUser: 1001
Expand Down Expand Up @@ -335,6 +339,10 @@ spec:
metadata:
labels:
custom-label: restore-pod
hostAliases:
- ip: "10.10.0.5"
hostnames:
- "s3.internal"

status:
conditions:
Expand Down
10 changes: 7 additions & 3 deletions src/crd/common.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use chrono::{DateTime, Utc};
use k8s_openapi::api::core::v1::HostAlias;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
Expand Down Expand Up @@ -389,20 +390,23 @@ pub struct PodOverrides {
pub metadata: Option<PodMetadata>,
/// Pod affinity rules (pass-through to k8s Affinity)
#[schemars(schema_with = "free_form_object")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub affinity: Option<serde_json::Value>,
/// Pod tolerations (pass-through to k8s Tolerations)
#[schemars(schema_with = "free_form_object_array")]
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub tolerations: Vec<serde_json::Value>,
/// Pod security context (pass-through to k8s PodSecurityContext)
#[schemars(schema_with = "free_form_object")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub security_context: Option<serde_json::Value>,
/// Image pull secrets
#[schemars(schema_with = "free_form_object_array")]
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub image_pull_secrets: Vec<serde_json::Value>,
/// Pod host aliases (pass-through to k8s HostAlias)
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub host_aliases: Vec<HostAlias>,
}

#[derive(Clone, Debug, Default, Deserialize, Serialize, JsonSchema)]
Expand All @@ -425,7 +429,7 @@ pub struct ContainerOverrides {
pub env: Vec<serde_json::Value>,
/// Container security context (pass-through to k8s SecurityContext)
#[schemars(schema_with = "free_form_object")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub security_context: Option<serde_json::Value>,
}

Expand Down
4 changes: 4 additions & 0 deletions src/jobs/templates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,10 @@ pub fn apply_pod_template(pod_spec: &mut PodSpec, template: Option<&CrdPodTempla
pod_spec.image_pull_secrets = Some(secrets);
}
}

if !pod_overrides.host_aliases.is_empty() {
pod_spec.host_aliases = Some(pod_overrides.host_aliases.clone());
}
}

if let Some(container_overrides) = &tmpl.container {
Expand Down
Loading
Loading