|
| 1 | +--- |
| 2 | +title: "Release v0.37.0" |
| 3 | +linkTitle: "Release v0.37.0" |
| 4 | +weight: 37 |
| 5 | +--- |
| 6 | + |
| 7 | +## 🚀 Introducing Jikkou 0.37.0 |
| 8 | + |
| 9 | +We're pleased to announce [Jikkou 0.37.0](https://github.com/streamthoughts/jikkou/releases/tag/v0.37.0). |
| 10 | + |
| 11 | +This release tackles real pain points reported by the community — from managing multiple Kafka environments in a single config, to fixing broken Schema Registry workflows. Here's the overview: |
| 12 | + |
| 13 | +- 🆕 **Multiple provider instances** — manage prod, staging, and dev from one configuration |
| 14 | +- 🔄 New **`replace`** command for full resource recreation |
| 15 | +- 🛡️ Schema Registry overhaul: **subject modes**, **failover**, **regex validation**, and more |
| 16 | +- ⚙️ **KIP-980**: create Kafka connectors in STOPPED or PAUSED state |
| 17 | +- 📦 **Directories** as input for `--values-files` |
| 18 | +- 📑 **Jinja template file locations** for reusable templates |
| 19 | +- 📐 All resource schemas promoted to **v1** API version |
| 20 | +- 🔧 Java 25 migration and REST client modernization |
| 21 | + |
| 22 | +To install, check out the [installation guide](https://www.jikkou.io/docs/install/). |
| 23 | +For the full changelog, see the [GitHub release page](https://github.com/streamthoughts/jikkou/releases/tag/v0.37.0). |
| 24 | + |
| 25 | +--- |
| 26 | + |
| 27 | +## 📐 All Resource Schemas Promoted to v1 |
| 28 | + |
| 29 | +All resource `apiVersion` values have been promoted from `v1beta1`/`v1beta2` to `v1`. This applies across every provider — Kafka, Schema Registry, Kafka Connect, Aiven, AWS, and core resources. |
| 30 | + |
| 31 | +```yaml |
| 32 | +# Before (still works, but deprecated) |
| 33 | +apiVersion: "kafka.jikkou.io/v1beta2" |
| 34 | + |
| 35 | +# After |
| 36 | +apiVersion: "kafka.jikkou.io/v1" |
| 37 | +``` |
| 38 | +
|
| 39 | +Existing YAML files using `v1beta1` or `v1beta2` will continue to work — Jikkou automatically resolves old versions to the latest registered resource class and normalises the `apiVersion` during deserialisation. But we recommend updating your files to `v1` going forward. |
| 40 | + |
| 41 | +--- |
| 42 | + |
| 43 | +## 🆕 Multiple Provider Instances |
| 44 | + |
| 45 | +Most teams don't run a single Kafka cluster. You have production, staging, maybe a dev cluster — and until now, you needed separate Jikkou configurations or manual overrides to target each one. There was no way to register multiple instances of the same provider type. |
| 46 | + |
| 47 | +Jikkou 0.37.0 introduces **named provider instances**. Register as many Kafka (or Schema Registry, or Kafka Connect) providers as you need, each with its own name and configuration. Then target the right one with `--provider` on the CLI or `"provider"` in API requests. |
| 48 | + |
| 49 | +```hocon |
| 50 | +jikkou { |
| 51 | + provider.kafka-prod { |
| 52 | + enabled = true |
| 53 | + type = io.streamthoughts.jikkou.kafka.KafkaExtensionProvider |
| 54 | + default = true |
| 55 | + config = { |
| 56 | + client { bootstrap.servers = "prod-kafka:9092" } |
| 57 | + } |
| 58 | + } |
| 59 | + provider.kafka-staging { |
| 60 | + enabled = true |
| 61 | + type = io.streamthoughts.jikkou.kafka.KafkaExtensionProvider |
| 62 | + config = { |
| 63 | + client { bootstrap.servers = "staging-kafka:9092" } |
| 64 | + } |
| 65 | + } |
| 66 | +} |
| 67 | +``` |
| 68 | + |
| 69 | +```bash |
| 70 | +# Preview changes against production |
| 71 | +jikkou diff --values-files topics.yaml --provider kafka-prod |
| 72 | +
|
| 73 | +# Apply to staging |
| 74 | +jikkou create --values-files topics.yaml --provider kafka-staging |
| 75 | +``` |
| 76 | + |
| 77 | +### How Provider Selection Works |
| 78 | + |
| 79 | +The `--provider` flag is **always optional**. Jikkou resolves the target provider with a simple fallback chain: |
| 80 | + |
| 81 | +- **Single provider of a given type**: It's used automatically — no `--provider` flag needed, no `default` flag needed. If you only have one Kafka provider configured, everything works exactly as before. |
| 82 | +- **Multiple providers, one marked `default = true`**: The default is used when `--provider` is omitted. You only need the flag when targeting a non-default provider. |
| 83 | +- **Multiple providers, no default**: You **must** specify `--provider` on every command. Omitting it will fail with an explicit error: *"No default configuration defined, and multiple configurations found for provider type"*. |
| 84 | + |
| 85 | +This means existing single-provider configurations continue to work without any changes. The `default` and `--provider` flags only matter once you add a second provider. |
| 86 | + |
| 87 | +Provider selection works across all commands — `create`, `update`, `delete`, `diff`, `validate`, `replace`, and `patch` — and extends to the REST API server with a `provider` field in reconciliation request bodies. |
| 88 | + |
| 89 | +--- |
| 90 | + |
| 91 | +## 🔄 New `replace` Command |
| 92 | + |
| 93 | +If you've used Terraform's `taint` or `--replace` flag, you know the pattern: sometimes you don't want to update a resource in place — you want to tear it down and recreate it from scratch. |
| 94 | + |
| 95 | +Jikkou now has its own version of this. The new `replace` command forces a full delete-then-create cycle on all targeted resources, regardless of whether an in-place update would be possible. |
| 96 | + |
| 97 | +```bash |
| 98 | +jikkou replace --values-files resources.yaml |
| 99 | +
|
| 100 | +# Preview first |
| 101 | +jikkou replace --values-files resources.yaml --dry-run |
| 102 | +``` |
| 103 | + |
| 104 | +A typical use case: development environments where you want to drop and recreate all your Kafka topics daily to start from a clean state. Rather than chaining `jikkou delete` and `jikkou create` in a script, `replace` handles it in one pass. |
| 105 | + |
| 106 | +--- |
| 107 | + |
| 108 | +## 🛡️ Schema Registry — Major Improvements |
| 109 | + |
| 110 | +This release brings five targeted fixes and features for the Schema Registry provider, most addressing specific community-reported issues. |
| 111 | + |
| 112 | +### Subject Modes |
| 113 | + |
| 114 | +Schema Registry subjects now support **mode management** directly from your resource definitions. This is essential for schema migration workflows — set a subject to `IMPORT` mode, register schemas with specific IDs, then switch back to `READWRITE`. |
| 115 | + |
| 116 | +```yaml |
| 117 | +apiVersion: "schemaregistry.jikkou.io/v1" |
| 118 | +kind: "SchemaRegistrySubject" |
| 119 | +metadata: |
| 120 | + name: "user-events" |
| 121 | +spec: |
| 122 | + mode: "IMPORT" |
| 123 | + compatibilityLevel: "BACKWARD" |
| 124 | + schemaType: "AVRO" |
| 125 | + schema: | |
| 126 | + { |
| 127 | + "type": "record", |
| 128 | + "name": "User", |
| 129 | + "fields": [{"name": "id", "type": "int"}] |
| 130 | + } |
| 131 | +``` |
| 132 | + |
| 133 | +Supported modes: `IMPORT`, `READONLY`, `READWRITE`, `FORWARD`. |
| 134 | + |
| 135 | +### Schema ID and Version on Create |
| 136 | + |
| 137 | +When migrating schemas between registries, you often need to preserve the original schema IDs and versions. Jikkou now lets you specify both via annotations: |
| 138 | + |
| 139 | +```yaml |
| 140 | +metadata: |
| 141 | + name: "events" |
| 142 | + annotations: |
| 143 | + schemaregistry.jikkou.io/schema-id: "100" |
| 144 | + schemaregistry.jikkou.io/schema-version: "1" |
| 145 | +``` |
| 146 | + |
| 147 | +Combined with `IMPORT` mode, this gives you full control over registry migrations. |
| 148 | + |
| 149 | +### Multiple URLs with Failover |
| 150 | + |
| 151 | +The documentation promised comma-separated Schema Registry URLs for failover, but the raw string was passed directly to the underlying HTTP client. Failover simply didn't work. |
| 152 | + |
| 153 | +Jikkou now properly parses comma-separated URLs. On connection failure, it automatically tries the next URL in the list. |
| 154 | + |
| 155 | +```hocon |
| 156 | +provider.schemaregistry { |
| 157 | + config = { |
| 158 | + url = "http://sr-primary:8081,http://sr-backup:8081,http://sr-dr:8081" |
| 159 | + } |
| 160 | +} |
| 161 | +``` |
| 162 | + |
| 163 | +### Subject Name Regex Validation |
| 164 | + |
| 165 | +Enforce naming conventions on your Schema Registry subjects with a regex pattern. Jikkou will reject any subject that doesn't match — before it ever reaches the registry. |
| 166 | + |
| 167 | +```yaml |
| 168 | +validations: |
| 169 | + - name: "subjectMustHaveValidName" |
| 170 | + type: "io.streamthoughts.jikkou.schema.registry.validation.SubjectNameRegexValidation" |
| 171 | + config: |
| 172 | + subjectNameRegex: "[a-zA-Z0-9\\._\\-]+" |
| 173 | +``` |
| 174 | + |
| 175 | +### Permanent Schema Deletion in One Step |
| 176 | + |
| 177 | +Permanently deleting a schema used to require two separate Jikkou runs — first a soft delete, then a hard delete. In a CI/CD pipeline, that's impractical. You declare "delete this permanently" and expect it to happen in one operation. |
| 178 | + |
| 179 | +When you set `jikkou.io/permanent-delete: true`, Jikkou now automatically performs the soft delete followed by the hard delete in a single reconciliation pass. |
| 180 | + |
| 181 | +--- |
| 182 | + |
| 183 | +## ⚙️ Kafka Connect: KIP-980 Support |
| 184 | + |
| 185 | +When creating Kafka connectors, the `state` field was silently ignored — every connector started in `RUNNING` state, even if you specified `STOPPED` or `PAUSED`. For production deployments, you often want to create a connector, verify its configuration, and only then start it manually. |
| 186 | + |
| 187 | +Jikkou now uses the [KIP-980](https://cwiki.apache.org/confluence/display/KAFKA/KIP-980%3A+Allow+creating+connectors+in+a+stopped+state) API to pass `initial_state` when creating connectors: |
| 188 | + |
| 189 | +```yaml |
| 190 | +apiVersion: "kafkaconnect.jikkou.io/v1" |
| 191 | +kind: "KafkaConnector" |
| 192 | +metadata: |
| 193 | + name: "jdbc-source" |
| 194 | + annotations: |
| 195 | + kafkaconnect.jikkou.io/initial_state: "STOPPED" |
| 196 | +spec: |
| 197 | + connectorClass: "io.confluent.connect.jdbc.JdbcSourceConnector" |
| 198 | + config: |
| 199 | + connection.url: "jdbc:mysql://db:3306/mydb" |
| 200 | +``` |
| 201 | + |
| 202 | +Options: `RUNNING`, `STOPPED`, `PAUSED`. |
| 203 | + |
| 204 | +--- |
| 205 | + |
| 206 | +## 📦 Directory Support for `--values-files` |
| 207 | + |
| 208 | +Teams organizing Kafka configurations by team or environment — e.g., `configurations/cluster1/resources/teamA/values.yml` — couldn't pass a directory to `--values-files`. You'd get `java.io.IOException: Is a directory`, and wildcard expansion didn't work either. |
| 209 | + |
| 210 | +`--values-files` now accepts directories. Jikkou recursively loads all matching files and deep-merges their values: |
| 211 | + |
| 212 | +```bash |
| 213 | +jikkou create --values-files config/environments/prod/ |
| 214 | +``` |
| 215 | + |
| 216 | +``` |
| 217 | +config/environments/prod/ |
| 218 | +├── teamA/ |
| 219 | +│ ├── topics.yml |
| 220 | +│ └── acls.yml |
| 221 | +├── teamB/ |
| 222 | +│ └── topics.yml |
| 223 | +└── shared.yaml |
| 224 | +``` |
| 225 | +
|
| 226 | +All files are loaded and their values are merged recursively. No more listing every file individually. |
| 227 | +
|
| 228 | +--- |
| 229 | +
|
| 230 | +## 📑 Jinja Template File Locations |
| 231 | +
|
| 232 | +Jinja's `{% include %}` directive only resolved templates from the Java classpath. If you wanted to split a large Jikkou YAML into reusable fragments, you had to mess with `CLASSPATH_PREFIX` or embed files into container images. For a tool that champions declarative configuration, this was a rough edge. |
| 233 | +
|
| 234 | +You can now configure filesystem directories where Jinja resolves template includes: |
| 235 | +
|
| 236 | +```hocon |
| 237 | +jikkou { |
| 238 | + jinja { |
| 239 | + resourceLocations = [ |
| 240 | + "/etc/jikkou/templates", |
| 241 | + "/opt/shared-templates" |
| 242 | + ] |
| 243 | + } |
| 244 | +} |
| 245 | +``` |
| 246 | + |
| 247 | +Your templates can reference local files naturally: |
| 248 | + |
| 249 | +```jinja |
| 250 | +{%- include "kafka/topic-defaults.jinja" -%} |
| 251 | +{%- import "macros/common.jinja" as m -%} |
| 252 | +{{ m.topic_config(name, partitions) }} |
| 253 | +``` |
| 254 | + |
| 255 | +No classpath gymnastics required. |
| 256 | + |
| 257 | +--- |
| 258 | + |
| 259 | +## 🔧 Under the Hood |
| 260 | + |
| 261 | +- **Java 25**: The project now targets Java 25 with GraalVM 25.0.2. Native image metadata has been migrated to the newer reachability-metadata format for better compilation support. |
| 262 | +- **REST client modernization**: Migrated from Jersey to RESTEasy proxy client, removing dependency on Jersey internals. OkHttp upgraded from 4.12.0 to 5.3.2. |
| 263 | +- **Security fixes**: Addressed CVE-2024-47561, CVE-2025-12183, CVE-2025-55163, and CVE-2026-25526 (Jinjava). |
| 264 | +- **Bug fixes**: Fixed repository double-loading on reconcile, GitHub repository file-pattern config, invalid supplier for Schema Registry basic auth, and comma-separated key-value pair parsing. |
| 265 | +- **Server**: API resources now use a blocking executor for improved stability. |
| 266 | + |
| 267 | +--- |
| 268 | + |
| 269 | +## ✅ Wrapping Up |
| 270 | + |
| 271 | +A lot of what's in this release came directly from issues and feedback you opened on GitHub — so thank you. Keep it coming. |
| 272 | + |
| 273 | +If you run into problems, open a [GitHub issue](https://github.com/streamthoughts/jikkou/issues). |
| 274 | +Give us a ⭐️ on [GitHub](https://github.com/streamthoughts/jikkou) and join the conversation on [Slack](https://join.slack.com/t/jikkou-io/shared_invite/zt-27c0pt61j-F10NN7d7ZEppQeMMyvy3VA). |
0 commit comments