From 517885785aeaf28e46531aee0f5c8a789edd123a Mon Sep 17 00:00:00 2001 From: Munish Chouhan Date: Mon, 25 Nov 2024 20:26:28 +0100 Subject: [PATCH] Bump k8s client to version 21.0.1 (#553) Signed-off-by: munishchouhan Signed-off-by: Paolo Di Tommaso Co-authored-by: Paolo Di Tommaso --- build.gradle | 4 +-- .../wave/service/k8s/K8sServiceImpl.groovy | 32 ++++++++++++------- .../service/k8s/K8sServiceImplTest.groovy | 27 ++++++++++++---- 3 files changed, 42 insertions(+), 21 deletions(-) diff --git a/build.gradle b/build.gradle index 2e07ead85..7e240d16c 100644 --- a/build.gradle +++ b/build.gradle @@ -56,8 +56,8 @@ dependencies { implementation 'io.micronaut.reactor:micronaut-reactor-http-client' implementation 'org.apache.commons:commons-compress:1.27.1' implementation 'org.apache.commons:commons-lang3:3.17.0' - implementation 'io.kubernetes:client-java:19.0.0' - implementation 'io.kubernetes:client-java-api-fluent:18.0.1' + implementation 'io.kubernetes:client-java:21.0.1' + implementation 'io.kubernetes:client-java-api-fluent:21.0.1' implementation 'com.google.code.gson:gson:2.10.1' implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310' implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml' diff --git a/src/main/groovy/io/seqera/wave/service/k8s/K8sServiceImpl.groovy b/src/main/groovy/io/seqera/wave/service/k8s/K8sServiceImpl.groovy index c954794c2..199c788ac 100644 --- a/src/main/groovy/io/seqera/wave/service/k8s/K8sServiceImpl.groovy +++ b/src/main/groovy/io/seqera/wave/service/k8s/K8sServiceImpl.groovy @@ -26,7 +26,6 @@ import groovy.transform.CompileStatic import groovy.util.logging.Slf4j import io.kubernetes.client.custom.Quantity import io.kubernetes.client.openapi.models.V1ContainerBuilder -import io.kubernetes.client.openapi.models.V1DeleteOptions import io.kubernetes.client.openapi.models.V1EnvVar import io.kubernetes.client.openapi.models.V1HostPathVolumeSource import io.kubernetes.client.openapi.models.V1Job @@ -144,7 +143,8 @@ class K8sServiceImpl implements K8sService { JobStatus getJobStatus(String name) { final job = k8sClient .batchV1Api() - .readNamespacedJob(name, namespace, null) + .readNamespacedJob(name, namespace) + .execute() if( !job ) { log.warn "K8s job=$name - unknown" return null @@ -178,7 +178,8 @@ class K8sServiceImpl implements K8sService { V1Pod getPod(String name) { return k8sClient .coreV1Api() - .readNamespacedPod(name, namespace, null) + .readNamespacedPod(name, namespace) + .execute() } /** @@ -293,7 +294,6 @@ class K8sServiceImpl implements K8sService { .withRestartPolicy("Never") .addAllToVolumes(volumes) - final requests = new V1ResourceRequirements() if( requestsCpu ) requests.putRequestsItem('cpu', new Quantity(requestsCpu)) @@ -356,7 +356,8 @@ class K8sServiceImpl implements K8sService { void deletePod(String name) { k8sClient .coreV1Api() - .deleteNamespacedPod(name, namespace, (String)null, (String)null, (Integer)null, (Boolean)null, (String)null, (V1DeleteOptions)null) + .deleteNamespacedPod(name, namespace) + .execute() } @Deprecated @@ -391,7 +392,6 @@ class K8sServiceImpl implements K8sService { .withRestartPolicy("Never") .addAllToVolumes(volumes) - final requests = new V1ResourceRequirements() if( scanConfig.requestsCpu ) requests.putRequestsItem('cpu', new Quantity(scanConfig.requestsCpu)) @@ -431,7 +431,8 @@ class K8sServiceImpl implements K8sService { return k8sClient .batchV1Api() - .createNamespacedJob(namespace, spec, null, null, null,null) + .createNamespacedJob(namespace, spec) + .execute() } V1Job createTransferJobSpec(String name, String containerImage, List args, BlobCacheConfig blobConfig) { @@ -494,7 +495,8 @@ class K8sServiceImpl implements K8sService { final spec = buildJobSpec(name, containerImage, args, workDir, creds, timeout, nodeSelector) return k8sClient .batchV1Api() - .createNamespacedJob(namespace, spec, null, null, null,null) + .createNamespacedJob(namespace, spec) + .execute() } V1Job buildJobSpec(String name, String containerImage, List args, Path workDir, Path credsFile, Duration timeout, Map nodeSelector) { @@ -583,7 +585,8 @@ class K8sServiceImpl implements K8sService { final spec = scanJobSpec(name, containerImage, args, workDir, creds, scanConfig) return k8sClient .batchV1Api() - .createNamespacedJob(namespace, spec, null, null, null,null) + .createNamespacedJob(namespace, spec) + .execute() } V1Job scanJobSpec(String name, String containerImage, List args, Path workDir, Path credsFile, ScanConfig scanConfig) { @@ -650,7 +653,8 @@ class K8sServiceImpl implements K8sService { final spec = mirrorJobSpec(name, containerImage, args, workDir, creds, config) return k8sClient .batchV1Api() - .createNamespacedJob(namespace, spec, null, null, null,null) + .createNamespacedJob(namespace, spec) + .execute() } V1Job mirrorJobSpec(String name, String containerImage, List args, Path workDir, Path credsFile, MirrorConfig config) { @@ -722,7 +726,9 @@ class K8sServiceImpl implements K8sService { void deleteJob(String name) { k8sClient .batchV1Api() - .deleteNamespacedJob(name, namespace, null, null, null, null,"Foreground", null) + .deleteNamespacedJob(name, namespace) + .propagationPolicy("Foreground") + .execute() } @Override @@ -730,7 +736,9 @@ class K8sServiceImpl implements K8sService { // list all pods for the given job final allPods = k8sClient .coreV1Api() - .listNamespacedPod(namespace, null, null, null, null, "job-name=${jobName}", null, null, null, null, null, null) + .listNamespacedPod(namespace) + .labelSelector("job-name=${jobName}") + .execute() if( !allPods || !allPods.items ) return null diff --git a/src/test/groovy/io/seqera/wave/service/k8s/K8sServiceImplTest.groovy b/src/test/groovy/io/seqera/wave/service/k8s/K8sServiceImplTest.groovy index f1b276c47..3a0f1ad77 100644 --- a/src/test/groovy/io/seqera/wave/service/k8s/K8sServiceImplTest.groovy +++ b/src/test/groovy/io/seqera/wave/service/k8s/K8sServiceImplTest.groovy @@ -513,11 +513,16 @@ class K8sServiceImplTest extends Specification { def "getLatestPodForJob should return the latest pod when multiple pods are present"() { given: def jobName = "test-job" + def namespace = "test-ns" def pod1 = new V1Pod().metadata(new V1ObjectMeta().creationTimestamp(OffsetDateTime.now().minusDays(1))) def pod2 = new V1Pod().metadata(new V1ObjectMeta().creationTimestamp(OffsetDateTime.now())) def allPods = new V1PodList().items(Arrays.asList(pod1, pod2)) def api = Mock(CoreV1Api) - api.listNamespacedPod(_, _, _, _, _, "job-name=${jobName}", _, _, _, _, _, _) >> allPods + def podRequest2 = Mock(CoreV1Api. APIlistNamespacedPodRequest) + podRequest2.execute() >> allPods + def podRequest1 = Mock(CoreV1Api. APIlistNamespacedPodRequest) + podRequest1.labelSelector("job-name=${jobName}") >> podRequest2 + api.listNamespacedPod(namespace) >> podRequest1 def k8sClient = new K8sClient() { @Override ApiClient apiClient() { @@ -528,7 +533,7 @@ class K8sServiceImplTest extends Specification { } } and: - def k8sService = new K8sServiceImpl(k8sClient: k8sClient) + def k8sService = new K8sServiceImpl(k8sClient: k8sClient, namespace: namespace) when: def latestPod = k8sService.getLatestPodForJob(jobName) @@ -540,8 +545,13 @@ class K8sServiceImplTest extends Specification { def "getLatestPodForJob should return null when no pod is present"() { given: def jobName = "test-job" + def namespace = "test-ns" def api = Mock(CoreV1Api) - api.listNamespacedPod(_, _, _, _, _, "job-name=${jobName}", _, _, _, _, _, _) >> null + def podRequest2 = Mock(CoreV1Api. APIlistNamespacedPodRequest) + podRequest2.execute() >> null + def podRequest1 = Mock(CoreV1Api. APIlistNamespacedPodRequest) + podRequest1.labelSelector("job-name=${jobName}") >> podRequest2 + api.listNamespacedPod(namespace) >> podRequest1 def k8sClient = new K8sClient() { @Override ApiClient apiClient() { @@ -552,7 +562,7 @@ class K8sServiceImplTest extends Specification { } } and: - def k8sService = new K8sServiceImpl(k8sClient: k8sClient) + def k8sService = new K8sServiceImpl(k8sClient: k8sClient, namespace: namespace) when: def latestPod = k8sService.getLatestPodForJob(jobName) @@ -826,7 +836,7 @@ class K8sServiceImplTest extends Specification { job.spec.backoffLimit == 3 job.spec.template.spec.containers[0].image == containerImage job.spec.template.spec.containers[0].args == args - job.spec.template.spec.containers[0].resources.requests == null + job.spec.template.spec.containers[0].resources.requests == [:] job.spec.template.spec.containers[0].env == [new V1EnvVar().name('REGISTRY_AUTH_FILE').value('/tmp/config.json')] and: job.spec.template.spec.containers[0].volumeMounts.size() == 2 @@ -886,7 +896,7 @@ class K8sServiceImplTest extends Specification { job.spec.backoffLimit == 3 job.spec.template.spec.containers[0].image == containerImage job.spec.template.spec.containers[0].args == args - job.spec.template.spec.containers[0].resources.requests == null + job.spec.template.spec.containers[0].resources.requests == [:] job.spec.template.spec.volumes.size() == 1 job.spec.template.spec.volumes[0].persistentVolumeClaim.claimName == 'bar' job.spec.template.spec.restartPolicy == 'Never' @@ -973,11 +983,14 @@ class K8sServiceImplTest extends Specification { def api = Mock(BatchV1Api) def client = Mock(K8sClient) { batchV1Api()>>api } def service = Spy(new K8sServiceImpl(namespace:NS, k8sClient: client)) + def jobRequest = Mock(BatchV1Api. APIreadNamespacedJobRequest) when: def status = service.getJobStatus(NAME) + then: - 1 * api.readNamespacedJob(NAME, NS, null) >> JOB + jobRequest.execute() >> JOB + 1 * api.readNamespacedJob(NAME, NS) >> jobRequest and: status == EXPECTED