Repository navigation
build: update the Kubernetes client - #178
Conversation
Move io.kubernetes:client-java from 11.0.4 to 28.0.0 (Kubernetes 1.37), with SnakeYAML 2 instead of 1.33, and set the versions of the libraries that the client needs and Spring Boot 2.7 manages lower (OkHttp, Kotlin, Gson, Commons Lang, Commons Codec). Drop the pins of protobuf-java, commons-io, commons-compress and bcprov-ext-jdk15on: the client asks for the same versions, or nothing needs them any more. - Calls in KubernetesClientWrapper and KubernetesObjectsSupplier use the request-builder API; the models use java.time instead of Joda-Time. - KubernetesJson: a Gson that ignores unknown fields, as the client did up to version 19, since its models now refuse objects of newer Kubernetes versions (kubernetes-client/java#4941). - The merge-patch client keeps the "Bearer" prefix of a kubeconfig token, which it dropped, so patches failed outside a cluster. - ServiceInfoService builds its YAML constructor with LoaderOptions (SnakeYAML 2). - A task whose taskmaster job has no creation time gets none, rather than the current time. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The image has SnakeYAML 2 now, so CVE-2022-1471 no longer needs an entry in .trivyignore.yaml. Dependabot may propose major versions of the Kubernetes client again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Deployment: the client version, and the Kubernetes versions TESK API works with. Development: the library versions to update with the client, and KubernetesJson. Upgrade notes: what changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Kubernetes client brings bcprov/bcpkix-jdk18on 1.86, and spring-security-jwt the jdk15on jars 1.70, which have the same classes: the image had both. Exclude the jdk15on jars, whose pins go too; spring-security-jwt only uses ASN.1 classes that jdk18on has. Drop the unused apache.commons.lang3.version property. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
KubernetesClientWrapperHttpTest sends the wrapper's requests through a real client to WireMock: query parameters (labelSelector, continue, limit, dryRun, propagationPolicy), merge-patch bodies, pod logs, LimitRanges and errors. KubernetesClientConfig installs the lenient Gson in its constructor, which a test checks. Converter tests strip empty fields only in the executors' jobs, with a test of the helper. Docs: the creation time, the affected kubeconfigs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The models of client 28 start with empty lists and maps, so the
executors' jobs in the taskmaster's input had "limits": {} for a
task with ram_gb but no cpu_cores. The taskmaster sets the limits
to the requests only if there are none, so such executors ran
without a memory limit. Write the executors' jobs with a Gson that
leaves out empty lists and maps, as client 11 did, and restore the
strict assertions of the converter tests (and drop the helper that
stripped empty fields in them).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reviewer's GuideData structuresDefine the Kubernetes JSON serialization behavior needed by the upgraded models: tolerate unknown fields, preserve Kubernetes-specific adapters, and omit empty collections where taskmaster input requires their absence.
APIAdapt Kubernetes client configuration and calls to client 28’s request-builder API, install the lenient Gson, and preserve authentication when constructing the merge-patch client.
ImplementationApply the new Kubernetes serialization and java.time behavior when converting tasks, executor jobs, and Kubernetes timestamps.
Update the service-info YAML constructor for SnakeYAML 2’s required LoaderOptions.
ConfigurationUpgrade the Kubernetes client and align dependency overrides with the versions required by its parent POM.
DocumentationDocument the upgraded client’s Kubernetes compatibility, serialization behavior, dependency maintenance, and upgrade impact.
TestsVerify Kubernetes JSON compatibility, merge-patch authentication, and real HTTP request behavior against WireMock.
Update and extend tests for new client request builders, java.time values, missing creation times, and absent empty collections in executor input.
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## dev #178 +/- ##
==========================================
+ Coverage 76.82% 77.60% +0.77%
==========================================
Files 73 74 +1
Lines 3439 3487 +48
Branches 412 416 +4
==========================================
+ Hits 2642 2706 +64
+ Misses 640 621 -19
- Partials 157 160 +3 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Linked issuesChecked at commit e43f580 #164 build: update the Kubernetes client · 7 of 8 met · 1 to check by hand
|
…lient Resolves pom.xml: #175 removed spring-security-oauth2 and its autoconfigure, so the Bouncy Castle exclusion goes with them; the removed pins stay removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
spring-security-jwt left with #175, so there are no older Bouncy Castle jars left to keep out. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Covers the read side of the adapter that leaves out empty collections, the one line of the patch that no test ran. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings in #161, #174, #175, #176, #178, #181, #183 and #184. The conflict in docs/upgrading.md is resolved by merging both lists under "To 1.3.0": the upgrade order for filer labels and Java 21 come first, and the TES 1.1 fields item no longer says that ignore_error: true is refused. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Lists the changes merged into dev since the notes were written: Java 21 (#161), ignore_error (#174), the resource server (#175), output file logs (#176), the Kubernetes client (#178), Dependabot labels (#181), the executor job selector (#183) and full test coverage (#184). Adds a Breaking changes section, as in the 1.2.0 notes, and sets date-released to the planned tag date, 2026-11-16. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Summary
Updates
io.kubernetes:client-javafrom 11.0.4 to 28.0.0 (Kubernetes 1.37), still on Spring Boot 2.7 and Java 21, and moves to SnakeYAML 2.pom.xml): the client, plus the libraries it needs in newer versions than Spring Boot 2.7 manages, set to those of the client's parent POM: SnakeYAML 2.7, OkHttp 5.5.0, Kotlin 2.1.21, Gson 2.14.0, Commons Lang 3.21.0, Commons Codec 1.23.0. The pins of protobuf-java, commons-io and commons-compress are dropped: the client resolves to the same versions (4.36.2, 2.22.0, 1.28.0). With refactor: use Spring Security's resource server #175 merged, spring-security-jwt and its Bouncy Castle*-jdk15on1.70 jars are gone, so only the client's*-jdk18on1.86 jars are on the classpath (no exclusion needed).KubernetesClientWrapperandKubernetesObjectsSupplieruse the client's request-builder API. The models usejava.timeinstead of Joda-Time.ServiceInfoServicepassesLoaderOptions, which SnakeYAML 2 needs.KubernetesJson): since version 20, the client's models refuse JSON with fields they don't know, so any object that a newer Kubernetes version extends would fail to read (kubernetes-client/java#4941).KubernetesClientConfiginstalls a Gson that ignores unknown fields, as client 11 and client-go do. TESK API only reads objects and creates or patches its own, so it loses nothing.GSON_WITHOUT_EMPTY_COLLECTIONS), as before. This matters because the taskmaster copies the requests to the limits only whenlimitsis missing, so withlimits: {}a task withram_gbbut nocpu_coreswould have run without a memory limit (caught in review; regression testramOnlyExecutorHasNoLimits). Objects that TESK API sends to Kubernetes directly do list empty fields, which Kubernetes treats as unset.Bearerprefix of a kubeconfig token. Before, patches (cancelling tasks) failed when TESK API ran outside a cluster with a token in its kubeconfig (regression testKubernetesClientConfigTest, which fails on 11.0.4).creationTimestamp(Kubernetes always sets one) now gives a task withoutcreation_time. Joda printed the current time instead.KubernetesJson), upgrade notes.Spring Boot stays on 2.7 (#168/#169 are separate).
devwith #175 is merged in (no rebase): thepom.xmlconflict is resolved by keeping neither the removed pins nor the spring-security-oauth2 pin, and the Bouncy Castle exclusion and its note in the development docs went with spring-security-oauth2-autoconfigure.Closes #164
Verification
./mvnw verifyon Java 21, after mergingdev(refactor: use Spring Security's resource server #175): 18492 unit tests and 109 integration tests pass, and the JaCoCo coverage checks are met../mvnw spotless:check checkstyle:checkon Java 8 passes.New tests:
KubernetesClientWrapperHttpTestruns the wrapper through a real client against WireMock and checks the query parameters, merge-patch bodies, pod logs, LimitRanges and errors.KubernetesClientConfigTestcovers the patch client's content type and token prefix.KubernetesJsonTestcovers unknown fields, missing required fields, times, Base64 data, the leaving out of empty collections, and the install.TesKubernetesConverterMinimalTestaddsramOnlyExecutorHasNoLimitsandfromK8sToTask_noCreationTime.dev.docker buildsucceeds. The image starts and answersGET /service-info. The fat jar holdssnakeyaml-2.7.jarand no SnakeYAML 1.x, and only the*-jdk18onBouncy Castle jars.CI: all checks pass (
CI passed), includingTest,Lint,Docs,Smoke test, andScan imagewithout the Trivy entry for SnakeYAML. CodeQL also passes.End to end on kind (v0.33.0, Kubernetes node image of that release), after merging
dev: the PR image with the tesk-core 0.11.0 taskmaster and filer, in its own namespace, with theeditrole for the API's and the taskmaster's service accounts. All three checks pass:echo) reachesCOMPLETE, and its stdout is in theFULLview.ram_gb: 0.25, nocpu_cores): the executor pod haslimits.memory=requests.memory= 268435456, and the task completes. This is the case of the review finding fixed above.CANCELED, the taskmaster job is labelledCancelled, and the executor stops.The script is outside the repository (it has no end-to-end suite yet):
tesk-api-e2e-kind.shin the maintainer's work folder; it builds the image, creates a throwaway cluster with its own kubeconfig, and deletes the cluster at the end. The cluster is deleted.codecov/patchwas at 98.76%: the read side of the new Gson adapter had no test;withoutEmptyCollectionsReadscovers it now.Declined review findings
docs/deployment.md. Kept: the v28.0.0 release notes of the client state it, and the docs name version 28 next to it.Open questions
None.
🤖 Generated with Claude Code
Summary by Sourcery
Upgrade the Kubernetes client and its supporting dependencies while preserving TESK’s Kubernetes compatibility and correcting authentication and serialization edge cases.
Bug Fixes:
Enhancements:
Build:
Documentation:
Tests:
Chores: