Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Create connectors in their requested initial state (KIP-980)#12974

Open
KasparMetsa wants to merge 3 commits into
strimzi:mainstrimzi/strimzi-kafka-operator:mainfrom
KasparMetsa:connector-create-in-initial-stateKasparMetsa/strimzi-kafka-operator:connector-create-in-initial-stateCopy head branch name to clipboard
Open

Create connectors in their requested initial state (KIP-980)#12974
KasparMetsa wants to merge 3 commits into
strimzi:mainstrimzi/strimzi-kafka-operator:mainfrom
KasparMetsa:connector-create-in-initial-stateKasparMetsa/strimzi-kafka-operator:connector-create-in-initial-stateCopy head branch name to clipboard

Conversation

@KasparMetsa

Copy link
Copy Markdown

Create stopped/paused connectors directly via POST /connectors with initial_state instead of creating them running and stopping them after.

Fixes #11754

Type of change

  • Enhancement / new feature

Description

A KafkaConnector (or MirrorMaker2 connector) with spec.state: stopped or paused was first created running and then stopped or paused with a second call. This briefly started a connector that should never have run (for example, a MirrorHeartbeat connector created a heartbeats topic before being stopped).

This change uses the Kafka Connect POST /connectors endpoint with the initial_state field (KIP-980, Kafka 3.7+) to create the connector directly in the requested state, in a single step.

Main changes:

  • Add KafkaConnectApi.createConnector(...), which sends POST /connectors with initial_state, plus its implementation.
  • AbstractConnectOperator: the create path (the 404 "connector does not exist" branch) now calls createConnector with spec.state. The old createOrUpdateConnector is renamed to updateConnector and is now only used to update an existing connector (still PUT /connectors/{name}/config).
  • Reconfiguring an existing connector is unchanged.

All Kafka versions currently supported by Strimzi are well past 3.7, so no version guard is needed for initial_state.

No documentation change is needed: the spec.state field, its values, and its contract are unchanged. A stopped connector still ends up stopped; this only removes the unwanted transient start.

AI assistance (Claude Code) was used throughout this change to analyze the issue, write the code and tests, and run the local Kubernetes verification. I reviewed all changes before submitting.

Checklist

  • Update documentation
  • Update CHANGELOG.md (if present)
  • Reference relevant issue(s) and close them after merging
  • Write tests
  • Make sure all tests pass
  • Try your changes inside a Kubernetes cluster, not just from unit tests
  • AI assistance was used to create this PR (see the Strimzi AI policy)

Create stopped/paused connectors directly via POST /connectors with
initial_state instead of creating them running and stopping them after.

Fixes strimzi#11754

Signed-off-by: Kaspar Metsa <kasparme@gmail.com>
@snyk-io

snyk-io Bot commented Jul 21, 2026

Copy link
Copy Markdown

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@scholzj
scholzj requested a review from katheris July 21, 2026 15:10
@scholzj scholzj added this to the 1.2.0 milestone Jul 21, 2026
@codecov

codecov Bot commented Jul 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 80.06%. Comparing base (80492f5) to head (bb8c87d).
⚠️ Report is 6 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff              @@
##               main   #12974      +/-   ##
============================================
+ Coverage     79.98%   80.06%   +0.08%     
- Complexity     6410     6448      +38     
============================================
  Files           337      341       +4     
  Lines         22489    22588      +99     
  Branches       3069     3082      +13     
============================================
+ Hits          17987    18086      +99     
  Misses         3282     3282              
  Partials       1220     1220              
Files with missing lines Coverage Δ
...ter/operator/assembly/AbstractConnectOperator.java 89.11% <100.00%> (+1.61%) ⬆️
...tor/cluster/operator/assembly/KafkaConnectApi.java 54.54% <ø> (ø)
...cluster/operator/assembly/KafkaConnectApiImpl.java 63.40% <100.00%> (+3.71%) ⬆️

... and 18 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Signed-off-by: Kaspar Metsa <kasparme@gmail.com>
@KasparMetsa
KasparMetsa force-pushed the connector-create-in-initial-state branch from c1b159c to 675d92c Compare July 21, 2026 22:26

@katheris katheris left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR @KasparMetsa, I'm generally happy with the changes. I've added a few comments about some code comments that I don't think are needed and some questions on some of the test changes.

I also want to see what others think on the handling of the 409 response code

Comment on lines +127 to +129
// 409 means the Connect cluster is rebalancing, or a connector with this name already exists.
// Retrying rides out a rebalance. An "already exists" 409 will not clear on retry, so it uses up
// the back off and fails this reconcile; the connector is then reconciled on the next one.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again I think this comment is overkill. However, I wonder whether we should be parsing the error and checking it isn't a failure because the connector already exists. Would be interested to see what other maintainers think

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the unnecessary comment.

I used this 409 handling because the existing PUT method (createOrUpdatePutRequest) already
handles 409 the same way, so I followed that pattern.

I think it makes sense here, because a 409 can happen in two cases:

  1. If the Connect cluster is rebalancing. This is temporary. If we wait and retry, it will try again many times and the create will succeed eventually, so retrying makes sense.
  2. A connector with that name already exists - retrying won't help, because the name stays taken, so every retry gets 409 again. After ~10 tries this reconcile fails.

So the question is really about case 2: should we detect "already exists" and stop retrying instead
of failing?

I don't think it's worth the extra code, because case 2 already fixes itself on the next reconcile:

  • Every reconcile starts by asking Connect whether the connector exists (a GET on its config). (AbstractConnectOperator:412)
  • If it now exists, the operator takes the update path (PUT) (AbstractConnectOperator:427) instead of the create path (POST) (AbstractConnectOperator:436), so no 409 happens.
  • So the create path (and its 409) only runs while the connector is missing; once it exists, the
    next reconcile just reconciles it normally.

It's also a rare case: the operator has a lock per connector, so it can't create a race condition itself - the name would
have to be taken by something outside the operator (for example a connector created directly via the
REST API, or a second operator on the same cluster).

Happy to add explicit "already exists" handling if you'd prefer, but I'd suggest keeping the simple retry.

Signed-off-by: Kaspar Metsa <kasparme@gmail.com>
@scholzj

scholzj commented Jul 23, 2026

Copy link
Copy Markdown
Member

/gha run pipeline=regression

@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown

⏳ System test verification started: link

The following 6 job(s) will be executed:

  • regression-brokers-and-security-amd64 (cncf-ubuntu-8-32-x86)
  • regression-operators-amd64 (cncf-ubuntu-8-32-x86)
  • regression-operands-amd64 (cncf-ubuntu-8-32-x86)
  • regression-brokers-and-security-arm64 (cncf-ubuntu-8-32-arm)
  • regression-operators-arm64 (cncf-ubuntu-8-32-arm)
  • regression-operands-arm64 (cncf-ubuntu-8-32-arm)

Tests will start after successful build completion.

@github-actions

Copy link
Copy Markdown

🎉 System test verification passed: link

@scholzj scholzj left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR. LGTM.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Enhancement]: Allow creating connectors in a stopped state

3 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.