You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Update dependency io.fabric8:kubernetes-httpclient-okhttp to v7.9.0 - #477
Fix #8024: (httpclient-vertx-5) WebSocket operations (exec/attach/portForward/WebSocket-backed watches) on a derived client - one produced by calling newBuilder()/build() on an already-built HttpClient - no longer fall back to Vert.x's bare WebSocketClient defaults. Vertx5HttpClientBuilder.build()'s short-circuit path for derived clients reused the original client's plain HTTP connection (with its configuration intact) but always created a brand-new WebSocketClient with no options at all, discarding both the trust/key material (so TLS verified against the JVM default trust store instead of the configured cluster CA) and the configured limits (maxFrameSize/maxMessageSize fell back to 64 KiB/256 KiB instead of unlimited, and maxConnections to 50 instead of 8192, so oversized exec/attach messages were silently dropped even on plain HTTP). This affects kubernetes-httpclient-vertx-5 only, which is opt-in - the bundled default kubernetes-httpclient-vertx (Vert.x 4) serves WebSockets from the same client it reuses when deriving and was never affected - and it is present in 7.6.0 through 7.8.0. Derivation happens more often than it looks: OpenShiftClientImpl derives on every adapt(OpenShiftClient.class) to install its OAuth token-refresh interceptor, OpenShiftOAuthInterceptor derives on every token refresh, and BaseClient#newClient derives whenever a differing RequestConfig is set. Derived clients now reuse the original's WebSocketClient outright, the same way they already reused its HTTP client, so they can no longer drift from it and no second transport is allocated per derivation. Note that sharing the transport also means closing any client in a derived family closes it for the whole family: close() on a client obtained from adapt(OpenShiftClient.class) now ends WebSocket operations on the client it was derived from as well, which is already what happened to that client's HTTP requests and what the other four implementations do. Nothing usable is lost, since the original's HTTP client was closed regardless; what changes is that the per-derivation WebSocketClient is no longer left behind unclosed
Fix #8029: (httpclient-vertx-5, httpclient-jetty) WebSocket connections now honor the configured proxy, so exec/attach/portForward and WebSocket-backed watches no longer connect straight to the API server and bypass a mandated egress proxy. Both implementations serve WebSockets from a transport separate from the HTTP client (a Vert.x 5 WebSocketClient, and a second Jetty HttpClient behind the WebSocketClient) and neither was given the proxy configuration; Jetty's WebSocket transport now also receives the proxy BasicAuthentication entry. The OkHttp, JDK and Vert.x 4 modules were unaffected because a single client serves both. On httpclient-vertx-5 the configured connect timeout was not applied to the WebSocket client either, so a WebSocket connect could hang well past it. One consequence worth calling out: when the proxy credentials cannot be decoded - HttpClientUtils.decodeBasicCredentials returns null for anything that is not Basic, or whose decoded value does not split into exactly two :-separated parts, so a proxy password containing a colon is enough - the client falls back to stamping Proxy-Authorization on the request instead of configuring it on the transport. Such WebSocket connections now reach the proxy and are rejected with a 407 rather than silently completing straight to the API server, so a setup that appeared to work only because it was bypassing the proxy will now fail
Fix #7807: (kube-api-test) The KUBE_API_TEST_STARTUP_TIMEOUT environment variable is now parsed instead of throwing ClassCastException on every use — the value (always a String) was passed to Class.cast() for an Integer/Boolean target, which only widens reference types and never parses, so the timeout could not be configured via environment at all. A new startupTimeout attribute on @EnableKubeAPIServer (e.g. @EnableKubeAPIServer(startupTimeout = 180000)) allows overriding it declaratively, and all three configuration paths (annotation, builder, env var) now reject non-positive values
Fix #7983: (mockwebserver) WebSocket upgrades are now performed synchronously from the Vert.x request handler instead of from the asynchronous HttpServerRequest#body() callback. Deferring the upgrade let the request end event be processed first, so HttpServerRequest#toWebSocket() intermittently threw IllegalStateException: Request has already been read and the upgrade was lost (surfacing as flaky exec/attach mock-server tests). Upgrade requests carry no body, so they are detected via the Upgrade header and upgraded before the request is read; the asynchronous path is unchanged for regular HTTP requests
Fix #7955: (java-generator) Malicious CRD schema values can no longer inject executable code into the generated Java sources. Schema-controlled values (enum values, CRD group/version/names, property names, descriptions and defaults) are emitted as fully escaped Java string literals, so a value carrying a Unicode-escaped quote cannot break out of its literal once javac decodes it. As a defense in depth, each generated class is also re-parsed and structurally validated before it is written (with Java Unicode escape preprocessing enabled to match javac), aborting generation on any residual structural mismatch
Fix #8028: (openshift-model, kube-api-test) No package is shipped by two artifacts anymore, so each pair can be placed on the JPMS module path together. openshift-model no longer bundles the io.fabric8.openshift.api.model.config.* classes that openshift-model-config owns (its Export-Package wildcard inlined them from that dependency); they still reach consumers through it. Fabric8ClientInjectionHandler moved to io.fabric8.kubeapitest.junit.inject
Fix #7752: Support for Kubernetes v1.37.0 (Garhwal)
Fix #8033: gateway-api model gains v1.TCPRoute and v1.UDPRoute (both graduated from v1alpha2 upstream in gateway-api v1.6.0). The v1alpha2 types remain available, but upstream has deprecated them and will remove them in a future release, so new code should use the v1 types
Note: Breaking changes
Fix #7752: Kubernetes model API removals (removed upstream in Kubernetes v1.37.0). The following API versions have been completely removed from Kubernetes and are no longer available in the client:
certificates.k8s.io/v1alpha1/ClusterTrustBundle → use certificates.k8s.io/v1 or v1beta1
networking.k8s.io/v1beta1/IPAddress → use networking.k8s.io/v1
networking.k8s.io/v1beta1/ServiceCIDR → use networking.k8s.io/v1
storage.k8s.io/v1beta1/VolumeAttributesClass → use storage.k8s.io/v1
scheduling.k8s.io/v1alpha2 (entire API version, 28 types) → use v1alpha3 or v1beta1
Fix #7752: VolumeMount constructor signature changed (Kubernetes v1.37.0 added bindMountOptions field). The canonical constructor now takes bindMountOptions (List) as its first parameter. Builder usage (new VolumeMountBuilder().with...()) is unaffected
Fix #8033: gateway-api model v1.SessionPersistence no longer exposes idleTimeout (removed upstream in gateway-api v1.6.0). Besides the field, this removes getIdleTimeout()/setIdleTimeout(), collapses the canonical constructor from five arguments to four, and drops SessionPersistenceFluent.withIdleTimeout()/getIdleTimeout()/hasIdleTimeout(), so the builder form (withNewSessionPersistence().withIdleTimeout(...)) no longer compiles. There is no runtime data loss: the class keeps its @JsonAnyGetter/@JsonAnySetter, and both the fluent and the builder carry additionalProperties through, so JSON or YAML still containing idleTimeout continues to deserialize and re-serialize intact
Fix #8028: (kube-api-test) Fabric8ClientInjectionHandler moved to io.fabric8.kubeapitest.junit.inject. It is resolved through ServiceLoader, so only code naming the class directly is affected
Fix #8028: (openshift-model) The bundle no longer exports or contains io.fabric8.openshift.api.model.config.*. Maven consumers are unaffected (openshift-model-config is a compile dependency), but OSGi deployments importing those packages must install the openshift-model-config bundle, which the openshift-client Karaf feature already does
Fix #7953: (httpclient-jdk) bodyless requests now preserve the requested HTTP method instead of silently defaulting to GET. JdkHttpClientImpl.requestBuilder only called HttpRequest.Builder.method(...) inside the body != null branch, so a bodyless DELETE/POST/PUT/PATCH (such as client.raw(uri, "DELETE", null)) was sent as GET on the JDK backend; the method is now set with BodyPublishers.noBody() when there is no body, matching the OkHttp, Jetty and Vert.x backends
Fix #7435: (kubernetes-client) A SharedIndexInformer's periodic resync no longer stops permanently and silently when a single resync cycle throws. DefaultSharedIndexInformer.scheduleResync runs the resync through Utils.scheduleAtFixedRate, whose self-rescheduling chain re-arms the next cycle only when the previous one completes normally; an uncaught exception completed the (unobserved) resyncFuture exceptionally and the resync was never scheduled again, with no log, while the independent watch kept isWatching() reporting true (a restart was required to recover). The resync command now catches and WARN-logs the failure so the schedule fires again at the next interval
Fix #7933: (kubernetes-client-api) Deterministic TLS trust failures (untrusted cert, expired cert, hostname mismatch) are now classified as terminal and fail fast instead of being retried by the shared StandardHttpClient.shouldRetry backoff loop (~19 s drain). The classifier walks both getCause() and getSuppressed() trees for CertificateException, CertPathValidatorException, CertPathBuilderException, and SSLPeerUnverifiedException. Affects all five HTTP client modules (jdk, jetty, okhttp, vertx-4, vertx-5) on both the HTTP request and WebSocket connect paths
Fix #7867: (kubernetes-server-mock) WatchEventsListener now buffers outgoing watch events that are scheduled before Vert.x fires onOpen and replays them once the WebSocket is available, closing the open-side race where a CRUD operation landing between handleWatch registering the listener and onOpen populating webSocketRef scheduled a send that dereferenced a null webSocketRef; the resulting NullPointerException was silently swallowed by the executor and the event was dropped. Buffered events are replayed after the initial-sync ADDEDs so ordering is preserved
Fix #7896: (kubernetes-client) AbstractWatchManager.watchEnded() now emits a WatcherException when a watch closes cleanly with no messages within 2 seconds, compensating for a GKE-specific behaviour on v1/events where the GKFE proxy rejects a stale resourceVersion with a bare WebSocket close (code 1000, no body) instead of {"type":"ERROR","code":410}, causing an indefinite reconnect loop with the same stale resourceVersion
Fix #7907: (httpclient-vertx-5) WebSocket-over-TLS operations (exec/attach/portForward/WebSocket-backed watches, and the CRD-establishment waits that depend on them) now trust the cluster certificate again. Vert.x 5.1 rewrote the WebSocket client to resolve TLS through a per-connection ClientSSLOptions that ignored the custom SslContextFactory the client used as its sole carrier of trust material, so WebSocket handshakes silently fell back to the default JVM trust store, failed PKIX validation, and hung to the client-side timeout (regular HTTPS request/response was unaffected). Both the HTTP and WebSocket clients are now configured uniformly with Vert.x TrustOptions/KeyCertOptions derived from the supplied trust/key managers
Fix #7873: (kube-api-test) Utils.findFreePort now records every port it hands out for the JVM's lifetime and skips any port already returned, eliminating the back-to-back duplicate-port window that surfaced as a JUnitExtensionOnMethodTest.simpleTest2 flake — the probe ServerSocket was closed before the caller bound it, so EtcdProcess.startEtcd() and KubeAPIServerProcess.startApiServer() could draw the same port from Random.nextInt, etcd would win the bind, and apiserver would exit 1 with bind: address already in use, surfacing in ProcessReadinessChecker as Connection reset by peer
Fix #7857: (kubernetes-server-mock) WatchEventsListener.onClosing now queues the server-side WebSocket.close(...) on the listener's send executor instead of invoking it directly on the Vert.x event loop. This preserves FIFO ordering with any data frames already queued on that executor, so events scheduled before a client-initiated watch close (e.g. an ADDED/DELETED pair on a final create/delete before watch.close()) are delivered before the close frame instead of being silently dropped by writes against an already-closing socket
Fix #7832: (sonar) Re-interrupt thread in 8 production-code catch blocks that swallowed InterruptedException without preserving the interrupt status (S2142)
Fix #7841: (mockwebserver) split Dispatcher shutdown into two phases so MockDispatcher only tears down per-session WebSocketSession executors after the HTTP server has drained, removing the window where an in-flight upgrade's onOpen could land on a shut-down executor. shutdown() still runs before httpServer.close() to unblock blocked dispatches (e.g. QueueDispatcher.take()); the new releaseResources() runs after. WebSocketSession.send() additionally catches RejectedExecutionException defensively so any residual shutdown race stays silent instead of bubbling as a Vert.x Unhandled exception. KubernetesMixedDispatcher now delegates both lifecycle hooks to its inner MockDispatcher, fixing a pre-existing leak where CRUD-mode WebSocket session executors were never shut down
Fix #7779: (kubernetes-client) ExecWebSocketListener now notifies the user-supplied ExecListener on transport-level errors that race with terminateOnError / channel-3 exit-status completion — listener.onFailure (or onClose) fires exactly once, gated by a dedicated flag, instead of being silently swallowed when the deferred onError task observes exitCode.isDone()
Fix #7765: (kubernetes-client) BaseOperation.informOnCondition now stops the informer inline when the inner predicate completes the future, closing a CompletableFuture postComplete race where a waiter helping drain dependents could fire informer.stop after cf.complete had already triggered a spurious ?watch=true HTTP request
Fix #7847: (kubernetes-client) BaseClient.addToCloseable now synchronizes on the internal closeable set rather than the caller-supplied parameter, so callers cannot break mutual exclusion by passing different references (sonar S2445)
Fix #7847: (kubernetes-client-api) KUBERNETES_SUBDOMAIN_REGEX uses possessive quantifiers on the outer groups to block ReDoS-style backtracking on adversarial subdomain input; semantics still match the canonical RFC 1123 subdomain pattern (sonar S5998)
Fix #7847: (kubernetes-client-api) Serialization.yamlMapper builds the mapper into a local before assigning to the volatile field, so concurrent readers can no longer observe a partially-initialized instance with modules not yet registered (sonar S3064)
Fix #7847: (mockwebserver) self-signed cert/key temp file cleanup goes through Files.deleteIfExists with logging instead of swallowing the File.delete() return value (sonar S899)
Fix #7847: (httpclient-okhttp) OkHttpClientBuilderImpl now picks the first X509TrustManager from a multi-entry TrustManager[] rather than passing null to OkHttp's sslSocketFactory and NPE'ing; user-supplied sslContext is preserved for multi-CA setups (sonar S2637)
Fix #7847: (httpclient-okhttp) OkHttpClientImpl.doClose removes dead null checks on dispatcher and connectionPool that are guaranteed non-null by the OkHttp API (sonar S2583)
Improvements
Fix #7675: (mockwebserver) MockWebServer.dispatcher field marked volatile so a setDispatcher(...) call is reliably visible to the Vert.x request handler thread without further synchronization. MockWebServer.reset() Javadoc tightened to make its non-destructive contract explicit (no change to the running server, dispatcher, listeners, SSL/TLS state, port, or protocols)
Fix #7809: (kubernetes-client) Support for shard selectors for list and watch - including informers
Fix #7837: (kubernetes-client) Follow-ups on shard selector
Fix #7899: (kubernetes-client) Callback before re-list for Informers
Dependency Upgrade
Fix #7849: bump istio.io/client-go from 1.29.2 to 1.30.0
Fix #7894: bump k8s.io/autoscaler/vertical-pod-autoscaler from 1.6.0 to 1.7.0
Fix #7894: bump k8s.io/gengo/v2 from 2.0.0-20251215205346-5ee0d033ba5b to 2.0.0-20260408192533-25e2208e0dc3
Fix #7894: bump k8s.io/kube-openapi from 0.0.0-20260319004828-5883c5ee87b9 to 0.0.0-20260414162039-ec9c827d403f
Fix #7875: bump vertx5.version from 5.0.12 to 5.1.1, adapting httpclient-vertx-5 to Vert.x 5.1 behaviour changes (SSL engine options no longer accept an empty protocol array; request-body stream errors are reset with HTTP/2 CANCEL so they are not retried as transient IOExceptions)
New Features
Fix #7926: (httpclient-vertx-5, httpclient-vertx) opt-in TLS warm-up on the Vert.x HTTP client factory. Vertx5HttpClientFactory/VertxHttpClientFactory now expose setTlsWarmup(TlsWarmup) with modes OFF, CONTEXT (default, unchanged) and FULL. FULL runs a synchronous, once-per-JVM, throwaway loopback TLS handshake off the event loop when the client is built, so the first real connection no longer blocks the event loop on the one-time JDK/Netty TLS class loading — for users on cold or hard-CPU-throttled JVMs hitting the first-connection block/timeout described in #7921. Default behavior is unchanged; see the FAQ for CDS and pod CPU-sizing guidance for hard-throttled pods
Fix #5084: Jbang scripts to generate graalVM metadata
Fix #7375: (crd-generator) Support @JsonClassDescription for adding descriptions to classes in the generated CRD schema.
Fix #7747: (mockwebserver) avoid RejectedExecutionException in MockWebServer#shutdown() — linearize close sequence to remove the httpClose-listener vs await race, and make shutdown() idempotent against repeated calls (e.g. JUnit @Nested afterAll cascades)
Fix #7734: (mockwebserver) avoid sending Content-Length together with Transfer-Encoding for chunked responses
Fix #7716: (informer) SerialExecutor.execute() now returns immediately after shutdown — no wrapper is offered, scheduleNext() is not called, and the underlying executor is not touched, fixing a post-stop NPE race exposed by SharedProcessor.distribute(...) after stop()
Fix #7702: ExecWebSocketListener.onError now wraps WebSocketHandshakeException via the chaining KubernetesClientException constructor instead of post-hoc initCause — handshake failures with a non-null upgrade response no longer throw IllegalStateException synchronously, so onFailure/exitCode receive the parsed Status and the original handshake exception as the cause
Fix #7686: (httpclient-vertx-5) StackBasedRecursionGuard.enter() no longer increments depth when refusing entry, fixing an infinite runOnContext loop that stalled InputStreamReadStream uploads under CPU contention
Fix #7700: ExecWebSocketListener.onError now defers failure handling through the SerialExecutor so a pending channel-3 exit-status task runs first and the parsed exit code is preserved instead of being overwritten by a peer-close exception
Fix #7698: (httpclient-vertx-5) InputStreamReadStream now fires endHandler when registered after the end signal has already been delivered, fixing a race for empty/fast streams
Fix #7696: (httpclient-vertx) clear response exception handler before reset in cancel() to prevent StreamResetException from racing with future cancellation
Fix #7695: ExecWebSocketListener now defers exitCode completion through the SerialExecutor so pending stdout/stderr async writes are flushed before exit signals
Fix #7632: java-generator now HTML-escapes <, >, and & in CRD descriptions to produce valid Javadoc
Fix #7543: fix processInlineDuplicateFields to recursively resolve nested inline embeds
Fix #7450: StandardHttpClient.shouldRetry() does not retry on Vert.x HttpClosedException
Fix #7350: Improper callback timing in leaderelection leads to the dual-leader
Fix #7265: fix ephemeral removal of index entries from informer caches
Improvements
Fix #7426: add HasMetadata#isSameResource to test whether two HasMetadata instances point to the same logical cluster resource, with an optional strict mode that also requires matching kind and resourceVersion
Fix #7662: (mockwebserver) new MockWebServer#setHttp2ClearTextEnabled(boolean) setter to opt out of HTTP/2 cleartext (h2c) upgrade
Fix #7522: improve dependency management for kubernetes-httpclient-okhttp
Fix #7550: add a ResourceEventHandler onList method and deprecated onNothing
Fix #6922: add addOwnerReference variant to set controller and blockOwnerDeletion fields
Fix #3396: (mockwebserver) Enhance self-signed certificate generation to include Subject Alternative Names (SANs) for proper TLS verification by modern clients
Fix #6923: Make the crd-generator-maven-plugin be toolchain aware
Dependency Upgrade
Fix #7754: bump baremetal-operator/apis from 0.12.4 to 0.13.0
Fix #7754: bump cluster-api-provider-metal3 from 1.12.4 to 1.13.0
Fix #7651: bump k8s.io/apimachinery from 0.35.4 to 0.36.0
Fix #7579: bump istio.io/client-go from 1.28.0 to 1.29.1
Fix #7551: bump jackson-bom from 2.20.0 to 2.21.1
Fix #7718: bump kin-openapi from 0.135.0 to 0.137.0
Fix #7758: bump kin-openapi from 0.137.0 to 0.138.0
Fix #7723: bump knative.dev/eventing from 0.48.2 to 0.49.0
Fix #7723: bump knative.dev/eventing-github from 0.48.0 to 0.49.0
Fix #7723: bump knative.dev/eventing-gitlab from 0.48.0 to 0.49.0
Fix #7723: bump knative.dev/eventing-kafka-broker from 0.48.3 to 0.49.0
Fix #7723: bump knative.dev/networking from 0.0.0-20260120131110-a7cdca238a0d to 0.0.0-20260422140718-e9578ef11562
Fix #7723: bump knative.dev/serving from 0.48.2 to 0.49.0
Fix #7580: bump kustomize/api from 0.20.1 to 0.21.1
Fix #7726: bump tektoncd/pipeline from 1.11.1 to 1.12.0
Fix #7552: bump tektoncd/triggers from 0.33.0 to 0.35.0
Fix #7556: bump eventing-kafka-broker from 0.46.2 to 0.48.1
Fix #7553: bump cert-manager from 1.19.4 to 1.20.0
Fix #7557: bump baremetal-operator/apis from 0.9.2 to 0.12.2
Fix #7544: bump cluster-api-provider-metal3 from 1.9.3 to 1.12.2
Fix #7543: bump prometheus-operator from 0.85.0 to 0.89.0
Fix #7542: bump open-cluster-management.io/api from 0.16.2 to 1.2.0
Fix #7753: bump open-cluster-management.io/api from 1.2.0 to 1.3.0
Fix #7544: cluster-api model classes moved from package io.fabric8.kubernetes.api.model.clusterapi.v1beta1 to io.fabric8.kubernetes.api.model.clusterapi.core.v1beta1 (following upstream cluster-api v1.11+ API reorganization)
Fix #7538: cert-manager model ObjectReference renamed to IssuerReference (following upstream rename in cert-manager v1.19.0)
Fix #7541: gateway-api model v1beta1.ReferenceGrantFrom, v1beta1.ReferenceGrantSpec, and v1beta1.ReferenceGrantTo removed (ReferenceGrant graduated to v1 upstream)
Fix #7723: knative model internal.autoscaling.v1alpha1.PodScalableSpec.template field removed (upstream removed the field in autoscaling.internal.knative.dev v1alpha1)
Fix #7580: kustomize model Patch.options field type changed from Map<String, Boolean> to PatchArgs (following upstream kustomize v0.21.0 PatchArgs API type addition)
Fix #7543: monitoring model v1.AuthorizationValidationError, v1.OAuth2ValidationError, v1.ProbeTargetsValidationError, and v1.PrometheusTracingConfig removed
Fix #7736: monitoring model v1.ThanosSpec.grpcServerTlsConfig and v1.ThanosRulerSpec.grpcServerTlsConfig field type changed from TLSConfig to the new GRPCServerTLSConfig (following upstream prometheus-operator v0.91.0)
Fix #7542: open-cluster-management model operator.v1.WebhookConfiguration removed (replaced by DefaultWebhookConfiguration and HostedWebhookConfiguration upstream)
Fix #7252: call additionalConfig when building Vert.x HTTP clients with VertxHttpClientFactory
Dependency Upgrade
Fix #7374: bump snakeyaml-engine from 2.10 to 3.0.1
New Features
Fix #7385: Support for Kubernetes v1.35 (Timbernetes)
Fix #7174: Added Vert.x 5 HTTP client implementation with improved async handling and WebSocket separation
Fix #7402: Added Byte code level semver API compatibility report generation using Revapi
Note: Breaking changes
Fix #5756: Resources edited with visitors must now implement io.fabric8.kubernetes.api.builder.Editable. All model classes provided by the client already implement this interface. User-provided custom resources that use visitor-based editing will need to implement Editable (trivial when a builder already exists).
Fix #7422: bump okhttp from 4.12.0 to 5.3.2. The versions are binary compatible, but the major version upgrade might cause side effects.
The kubernetes-httpclient-vertx (Vert.x 4.x) and kubernetes-httpclient-vertx-5 (Vert.x 5.x) modules are mutually exclusive.
They must not be included together in your project dependencies.
Both modules provide an implementation of HttpClient.Factory and use the same io.vertx artifact coordinates but with incompatible major versions.
Problem: If both modules are present on the classpath, Maven's dependency resolution may pick Vert.x 4.x JARs while the Vertx5HttpClientFactory is selected at runtime.
This causes NoClassDefFoundError for Vert.x 5-specific classes like io.vertx.core.impl.SysProps.
Solution: Ensure your project includes only ONE of these modules:
kubernetes-httpclient-vertx (default, uses Vert.x 4.x) - included transitively via kubernetes-client
kubernetes-httpclient-vertx-5 (optional, uses Vert.x 5.x) - requires explicit dependency and exclusion of vertx-4
When using Vert.x 5, exclude the default Vert.x 4 client and set the vertx.version property:
This is an automated Renovate dependency bump that only touches two lines (one per pom.xml), bumping io.fabric8:kubernetes-httpclient-okhttp from 7.5.2 to 7.9.0 inside the openshift build profile of insurance-service and person-service. I verified the change by building both the pre- and post-PR state locally. Summary of findings below.
1. The openshift profile does not compile — pre-existing, but this PR silently widens the version gap (and CI never catches it)
Both modules pin kubernetes-httpclient-okhttp directly inside the openshift profile's <dependencies>, while the rest of the fabric8 Kubernetes/OpenShift client stack is pulled in transitively from io.dekorate:openshift-spring-starter:4.1.11, which manages io.fabric8:kubernetes-client-bom at 6.13.0:
Because kubernetes-httpclient-okhttp is declared as a direct (depth-1) dependency, Maven's "nearest wins" mediation makes its transitive kubernetes-client-api/kubernetes-model-*7.9.0 win over the 6.13.0 versions that kubernetes-client:6.13.0 (and Dekorate's OpenShift manifest-generation code) was actually compiled against. fabric8 kubernetes-client has had real breaking changes between 6.x and 7.x (e.g. this very PR's release notes call out a VolumeMount constructor signature change, removed API versions, moved classes, etc.), so mixing major versions on the classpath is not safe.
I confirmed this also fails identically with the old7.5.2 version, so it's a pre-existing problem, not introduced by this bump — but the bump moves the gap from 6.13.0→7.5.2 to 6.13.0→7.9.0, in the wrong direction, with zero validation. .circleci/config.yml's test job only runs mvn test (default profile), so the openshift profile is never exercised by CI, and Renovate's automerge happily merged this without anyone noticing the profile is broken.
Suggestion: Either align the whole fabric8 family to one version (e.g. import io.fabric8:kubernetes-client-bom at a single version instead of overriding a single leaf artifact), or bump dekorate.version so its managed kubernetes-client version is compatible, and add CI coverage that builds with -Popenshift so future Renovate bumps of fabric8 artifacts can't silently merge into a broken build again.
2. Design smell: pinning a single fabric8 artifact instead of the whole BOM
Only kubernetes-httpclient-okhttp is explicitly pinned; nothing manages kubernetes-client, kubernetes-client-api, openshift-client, etc. to match. This is exactly the kind of override Renovate will keep bumping in isolation (it only sees kubernetes-httpclient-okhttp in the pom), continuing to widen the gap with the 6.13.0 line that Dekorate actually uses. If this dependency needs overriding at all (e.g. to pick up a CVE fix), it should be done via dependencyManagement importing the matching kubernetes-client-bom, not as a lone direct dependency.
3. Minor: no <scope> on the overridden dependency
kubernetes-httpclient-okhttp is declared with the default compile scope inside the openshift profile, even though it appears to only be needed by Dekorate's build-time annotation processor for manifest generation, not by application code at runtime. If that's correct, scoping it (e.g. provided) would avoid bundling an unused/incompatible fabric8 client runtime inside the final Spring Boot fat jar.
Note: items 2 and 3 are pre-existing conditions not introduced by this specific diff, but they're the root cause of why this Renovate bump (item 1) is risky and went unnoticed — flagging them here since they're directly tied to the two lines this PR changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
7.5.2→7.9.0Warning
Some dependencies could not be looked up. Check the Dependency Dashboard for more information.
Release Notes
fabric8io/kubernetes-client (io.fabric8:kubernetes-httpclient-okhttp)
v7.9.0Compare Source
Bugs
exec/attach/portForward/WebSocket-backed watches) on a derived client - one produced by callingnewBuilder()/build()on an already-builtHttpClient- no longer fall back to Vert.x's bareWebSocketClientdefaults.Vertx5HttpClientBuilder.build()'s short-circuit path for derived clients reused the original client's plain HTTP connection (with its configuration intact) but always created a brand-newWebSocketClientwith no options at all, discarding both the trust/key material (so TLS verified against the JVM default trust store instead of the configured cluster CA) and the configured limits (maxFrameSize/maxMessageSizefell back to 64 KiB/256 KiB instead of unlimited, andmaxConnectionsto 50 instead of 8192, so oversizedexec/attachmessages were silently dropped even on plain HTTP). This affectskubernetes-httpclient-vertx-5only, which is opt-in - the bundled defaultkubernetes-httpclient-vertx(Vert.x 4) serves WebSockets from the same client it reuses when deriving and was never affected - and it is present in 7.6.0 through 7.8.0. Derivation happens more often than it looks:OpenShiftClientImplderives on everyadapt(OpenShiftClient.class)to install its OAuth token-refresh interceptor,OpenShiftOAuthInterceptorderives on every token refresh, andBaseClient#newClientderives whenever a differingRequestConfigis set. Derived clients now reuse the original'sWebSocketClientoutright, the same way they already reused its HTTP client, so they can no longer drift from it and no second transport is allocated per derivation. Note that sharing the transport also means closing any client in a derived family closes it for the whole family:close()on a client obtained fromadapt(OpenShiftClient.class)now ends WebSocket operations on the client it was derived from as well, which is already what happened to that client's HTTP requests and what the other four implementations do. Nothing usable is lost, since the original's HTTP client was closed regardless; what changes is that the per-derivationWebSocketClientis no longer left behind unclosedexec/attach/portForwardand WebSocket-backed watches no longer connect straight to the API server and bypass a mandated egress proxy. Both implementations serve WebSockets from a transport separate from the HTTP client (a Vert.x 5WebSocketClient, and a second JettyHttpClientbehind theWebSocketClient) and neither was given the proxy configuration; Jetty's WebSocket transport now also receives the proxyBasicAuthenticationentry. The OkHttp, JDK and Vert.x 4 modules were unaffected because a single client serves both. Onhttpclient-vertx-5the configured connect timeout was not applied to the WebSocket client either, so a WebSocket connect could hang well past it. One consequence worth calling out: when the proxy credentials cannot be decoded -HttpClientUtils.decodeBasicCredentialsreturnsnullfor anything that is notBasic, or whose decoded value does not split into exactly two:-separated parts, so a proxy password containing a colon is enough - the client falls back to stampingProxy-Authorizationon the request instead of configuring it on the transport. Such WebSocket connections now reach the proxy and are rejected with a 407 rather than silently completing straight to the API server, so a setup that appeared to work only because it was bypassing the proxy will now failKUBE_API_TEST_STARTUP_TIMEOUTenvironment variable is now parsed instead of throwingClassCastExceptionon every use — the value (always aString) was passed toClass.cast()for anInteger/Booleantarget, which only widens reference types and never parses, so the timeout could not be configured via environment at all. A newstartupTimeoutattribute on@EnableKubeAPIServer(e.g.@EnableKubeAPIServer(startupTimeout = 180000)) allows overriding it declaratively, and all three configuration paths (annotation, builder, env var) now reject non-positive valuesHttpServerRequest#body()callback. Deferring the upgrade let the request end event be processed first, soHttpServerRequest#toWebSocket()intermittently threwIllegalStateException: Request has already been readand the upgrade was lost (surfacing as flakyexec/attachmock-server tests). Upgrade requests carry no body, so they are detected via theUpgradeheader and upgraded before the request is read; the asynchronous path is unchanged for regular HTTP requestsjavacdecodes it. As a defense in depth, each generated class is also re-parsed and structurally validated before it is written (with Java Unicode escape preprocessing enabled to matchjavac), aborting generation on any residual structural mismatchopenshift-modelno longer bundles theio.fabric8.openshift.api.model.config.*classes thatopenshift-model-configowns (itsExport-Packagewildcard inlined them from that dependency); they still reach consumers through it.Fabric8ClientInjectionHandlermoved toio.fabric8.kubeapitest.junit.injectImprovements
Dependency Upgrade
New Features
v1.TCPRouteandv1.UDPRoute(both graduated fromv1alpha2upstream in gateway-api v1.6.0). Thev1alpha2types remain available, but upstream has deprecated them and will remove them in a future release, so new code should use thev1typesNote: Breaking changes
certificates.k8s.io/v1alpha1/ClusterTrustBundle→ usecertificates.k8s.io/v1orv1beta1networking.k8s.io/v1beta1/IPAddress→ usenetworking.k8s.io/v1networking.k8s.io/v1beta1/ServiceCIDR→ usenetworking.k8s.io/v1storage.k8s.io/v1beta1/VolumeAttributesClass→ usestorage.k8s.io/v1scheduling.k8s.io/v1alpha2(entire API version, 28 types) → usev1alpha3orv1beta1VolumeMountconstructor signature changed (Kubernetes v1.37.0 addedbindMountOptionsfield). The canonical constructor now takesbindMountOptions(List) as its first parameter. Builder usage (new VolumeMountBuilder().with...()) is unaffectedv1.SessionPersistenceno longer exposesidleTimeout(removed upstream in gateway-api v1.6.0). Besides the field, this removesgetIdleTimeout()/setIdleTimeout(), collapses the canonical constructor from five arguments to four, and dropsSessionPersistenceFluent.withIdleTimeout()/getIdleTimeout()/hasIdleTimeout(), so the builder form (withNewSessionPersistence().withIdleTimeout(...)) no longer compiles. There is no runtime data loss: the class keeps its@JsonAnyGetter/@JsonAnySetter, and both the fluent and the builder carryadditionalPropertiesthrough, so JSON or YAML still containingidleTimeoutcontinues to deserialize and re-serialize intactFabric8ClientInjectionHandlermoved toio.fabric8.kubeapitest.junit.inject. It is resolved throughServiceLoader, so only code naming the class directly is affectedio.fabric8.openshift.api.model.config.*. Maven consumers are unaffected (openshift-model-configis a compile dependency), but OSGi deployments importing those packages must install theopenshift-model-configbundle, which theopenshift-clientKaraf feature already doesv7.8.0Compare Source
Bugs
GET.JdkHttpClientImpl.requestBuilderonly calledHttpRequest.Builder.method(...)inside thebody != nullbranch, so a bodylessDELETE/POST/PUT/PATCH(such asclient.raw(uri, "DELETE", null)) was sent asGETon the JDK backend; the method is now set withBodyPublishers.noBody()when there is no body, matching the OkHttp, Jetty and Vert.x backendsSharedIndexInformer's periodic resync no longer stops permanently and silently when a single resync cycle throws.DefaultSharedIndexInformer.scheduleResyncruns the resync throughUtils.scheduleAtFixedRate, whose self-rescheduling chain re-arms the next cycle only when the previous one completes normally; an uncaught exception completed the (unobserved)resyncFutureexceptionally and the resync was never scheduled again, with no log, while the independent watch keptisWatching()reportingtrue(a restart was required to recover). The resync command now catches andWARN-logs the failure so the schedule fires again at the next intervalStandardHttpClient.shouldRetrybackoff loop (~19 s drain). The classifier walks bothgetCause()andgetSuppressed()trees forCertificateException,CertPathValidatorException,CertPathBuilderException, andSSLPeerUnverifiedException. Affects all five HTTP client modules (jdk, jetty, okhttp, vertx-4, vertx-5) on both the HTTP request and WebSocket connect pathsWatchEventsListenernow buffers outgoing watch events that are scheduled before Vert.x firesonOpenand replays them once the WebSocket is available, closing the open-side race where a CRUD operation landing betweenhandleWatchregistering the listener andonOpenpopulatingwebSocketRefscheduled a send that dereferenced a nullwebSocketRef; the resultingNullPointerExceptionwas silently swallowed by the executor and the event was dropped. Buffered events are replayed after the initial-syncADDEDs so ordering is preservedAbstractWatchManager.watchEnded()now emits aWatcherExceptionwhen a watch closes cleanly with no messages within 2 seconds, compensating for a GKE-specific behaviour onv1/eventswhere the GKFE proxy rejects a staleresourceVersionwith a bare WebSocket close (code 1000, no body) instead of{"type":"ERROR","code":410}, causing an indefinite reconnect loop with the same stale resourceVersionexec/attach/portForward/WebSocket-backed watches, and the CRD-establishment waits that depend on them) now trust the cluster certificate again. Vert.x 5.1 rewrote the WebSocket client to resolve TLS through a per-connectionClientSSLOptionsthat ignored the customSslContextFactorythe client used as its sole carrier of trust material, so WebSocket handshakes silently fell back to the default JVM trust store, failed PKIX validation, and hung to the client-side timeout (regular HTTPS request/response was unaffected). Both the HTTP and WebSocket clients are now configured uniformly with Vert.xTrustOptions/KeyCertOptionsderived from the supplied trust/key managersUtils.findFreePortnow records every port it hands out for the JVM's lifetime and skips any port already returned, eliminating the back-to-back duplicate-port window that surfaced as aJUnitExtensionOnMethodTest.simpleTest2flake — the probeServerSocketwas closed before the caller bound it, soEtcdProcess.startEtcd()andKubeAPIServerProcess.startApiServer()could draw the same port fromRandom.nextInt, etcd would win the bind, and apiserver would exit 1 withbind: address already in use, surfacing inProcessReadinessCheckerasConnection reset by peerWatchEventsListener.onClosingnow queues the server-sideWebSocket.close(...)on the listener's send executor instead of invoking it directly on the Vert.x event loop. This preserves FIFO ordering with any data frames already queued on that executor, so events scheduled before a client-initiated watch close (e.g. anADDED/DELETEDpair on a finalcreate/deletebeforewatch.close()) are delivered before the close frame instead of being silently dropped by writes against an already-closing socketInterruptedExceptionwithout preserving the interrupt status (S2142)Dispatchershutdown into two phases soMockDispatcheronly tears down per-sessionWebSocketSessionexecutors after the HTTP server has drained, removing the window where an in-flight upgrade'sonOpencould land on a shut-down executor.shutdown()still runs beforehttpServer.close()to unblock blocked dispatches (e.g.QueueDispatcher.take()); the newreleaseResources()runs after.WebSocketSession.send()additionally catchesRejectedExecutionExceptiondefensively so any residual shutdown race stays silent instead of bubbling as a Vert.xUnhandled exception.KubernetesMixedDispatchernow delegates both lifecycle hooks to its innerMockDispatcher, fixing a pre-existing leak where CRUD-mode WebSocket session executors were never shut downterminateOnError/ channel-3 exit-status completion —listener.onFailure(oronClose) fires exactly once, gated by a dedicated flag, instead of being silently swallowed when the deferred onError task observesexitCode.isDone()BaseOperation.informOnConditionnow stops the informer inline when the inner predicate completes the future, closing a CompletableFuturepostCompleterace where a waiter helping drain dependents could fireinformer.stopaftercf.completehad already triggered a spurious?watch=trueHTTP requestBaseClient.addToCloseablenow synchronizes on the internal closeable set rather than the caller-supplied parameter, so callers cannot break mutual exclusion by passing different references (sonar S2445)KUBERNETES_SUBDOMAIN_REGEXuses possessive quantifiers on the outer groups to block ReDoS-style backtracking on adversarial subdomain input; semantics still match the canonical RFC 1123 subdomain pattern (sonar S5998)Serialization.yamlMapperbuilds the mapper into a local before assigning to thevolatilefield, so concurrent readers can no longer observe a partially-initialized instance with modules not yet registered (sonar S3064)Files.deleteIfExistswith logging instead of swallowing theFile.delete()return value (sonar S899)OkHttpClientBuilderImplnow picks the firstX509TrustManagerfrom a multi-entryTrustManager[]rather than passingnullto OkHttp'ssslSocketFactoryand NPE'ing; user-suppliedsslContextis preserved for multi-CA setups (sonar S2637)OkHttpClientImpl.doCloseremoves dead null checks ondispatcherandconnectionPoolthat are guaranteed non-null by the OkHttp API (sonar S2583)Improvements
MockWebServer.dispatcherfield markedvolatileso asetDispatcher(...)call is reliably visible to the Vert.x request handler thread without further synchronization.MockWebServer.reset()Javadoc tightened to make its non-destructive contract explicit (no change to the running server, dispatcher, listeners, SSL/TLS state, port, or protocols)Dependency Upgrade
New Features
Vertx5HttpClientFactory/VertxHttpClientFactorynow exposesetTlsWarmup(TlsWarmup)with modesOFF,CONTEXT(default, unchanged) andFULL.FULLruns a synchronous, once-per-JVM, throwaway loopback TLS handshake off the event loop when the client is built, so the first real connection no longer blocks the event loop on the one-time JDK/Netty TLS class loading — for users on cold or hard-CPU-throttled JVMs hitting the first-connection block/timeout described in #7921. Default behavior is unchanged; see the FAQ for CDS and pod CPU-sizing guidance for hard-throttled podsNote: Breaking changes
v7.7.0Compare Source
Bugs
<,>, and&in CRD descriptions to produce valid JavadocImprovements
HasMetadata#isSameResourceto test whether two HasMetadata instances point to the same logical cluster resource, with an optional strict mode that also requires matching kind and resourceVersionMockWebServer#setHttp2ClearTextEnabled(boolean)setter to opt out of HTTP/2 cleartext (h2c) upgradeDependency Upgrade
New Features
subresource()methodNote: Breaking changes
scheduling.k8s.io/v1alpha1model classes removed (Workload,WorkloadList,WorkloadSpec,PodGroup,PodGroupPolicy,BasicSchedulingPolicy,GangSchedulingPolicy,TypedLocalObjectReference) — upstream rearchitected workload scheduling via KEP-5832io.fabric8.kubernetes.api.model.clusterapi.v1beta1toio.fabric8.kubernetes.api.model.clusterapi.core.v1beta1(following upstream cluster-api v1.11+ API reorganization)ObjectReferencerenamed toIssuerReference(following upstream rename in cert-manager v1.19.0)v1beta1.ReferenceGrantFrom,v1beta1.ReferenceGrantSpec, andv1beta1.ReferenceGrantToremoved (ReferenceGrant graduated to v1 upstream)internal.autoscaling.v1alpha1.PodScalableSpec.templatefield removed (upstream removed the field in autoscaling.internal.knative.dev v1alpha1)Patch.optionsfield type changed fromMap<String, Boolean>toPatchArgs(following upstream kustomize v0.21.0 PatchArgs API type addition)v1.AuthorizationValidationError,v1.OAuth2ValidationError,v1.ProbeTargetsValidationError, andv1.PrometheusTracingConfigremovedv1.ThanosSpec.grpcServerTlsConfigandv1.ThanosRulerSpec.grpcServerTlsConfigfield type changed fromTLSConfigto the newGRPCServerTLSConfig(following upstream prometheus-operator v0.91.0)operator.v1.WebhookConfigurationremoved (replaced byDefaultWebhookConfigurationandHostedWebhookConfigurationupstream)v7.6.1Compare Source
Bugs
v7.6.0Compare Source
Bugs
Improvements
Dependency Upgrade
New Features
Note: Breaking changes
io.fabric8.kubernetes.api.builder.Editable. All model classes provided by the client already implement this interface. User-provided custom resources that use visitor-based editing will need to implementEditable(trivial when a builder already exists).Note: Vert.x HTTP Client Compatibility (Issue #7174)
The
kubernetes-httpclient-vertx(Vert.x 4.x) andkubernetes-httpclient-vertx-5(Vert.x 5.x) modules are mutually exclusive.They must not be included together in your project dependencies.
Both modules provide an implementation of
HttpClient.Factoryand use the sameio.vertxartifact coordinates but with incompatible major versions.Problem: If both modules are present on the classpath, Maven's dependency resolution may pick Vert.x 4.x JARs while the
Vertx5HttpClientFactoryis selected at runtime.This causes
NoClassDefFoundErrorfor Vert.x 5-specific classes likeio.vertx.core.impl.SysProps.Solution: Ensure your project includes only ONE of these modules:
kubernetes-httpclient-vertx(default, uses Vert.x 4.x) - included transitively viakubernetes-clientkubernetes-httpclient-vertx-5(optional, uses Vert.x 5.x) - requires explicit dependency and exclusion of vertx-4When using Vert.x 5, exclude the default Vert.x 4 client and set the
vertx.versionproperty:Configuration
📅 Schedule: (UTC)
🚦 Automerge: Enabled.
♻ Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.