Kubernetes client delete returns true, if delete fails

3/8/2018

We are testing our code using the kubernetes client.

We experienced some interesting behaviour, in case of deletion e.g. a config map:

  • GET return 200, DELETE returns 200: delete() returns true
  • GET return 200, DELETE returns 404: delete() returns true
  • GET return 404, DELETE is not called at all: delete() returns false
  • GET return 200, DELETE returns 400: delete() throws KubernetesClientException
  • GET return 400: delete() throws KubernetesClientException

So we wonder, if it is really consistent, that 200/404 returns true and 404/nc returns false. Both should return true or both should return false.

So we wonder, is it perhaps a bug?

According io.fabric8.kubernetes.client.dsl.base.BaseOperation.delete() it is meant to return false in case of 404

  try {
    deleteList();
    return true;
  } catch (KubernetesClientException e) {
    if (e.getCode() != 404) {
      throw e;
    }
    return false;
  }

Here is the test example:

// GET return 200
// DELETE return 200
// kubernetesClient.delete() return TRUE
server.expect().get().withPath(format("/api/v1/namespaces/{}/configmaps?labelSelector={}%3D{}", namespace, name, value)).andReturn(200, configMapList).once();
server.expect().delete().withPath(format("/api/v1/namespaces/{}/configmaps/{}", namespace, configMapName)).andReturn(200, StringUtils.EMPTY).once();
actual = kubernetesClient.configMaps().inNamespace(namespace).withLabelSelector(labelSelector).delete();
assertTrue(actual)

// GET return 200
// DELETE return 404
// kubernetesClient.delete() return TRUE
server.expect().get().withPath(format("/api/v1/namespaces/{}/configmaps?labelSelector={}%3D{}", namespace, name, value)).andReturn(200, configMapList).once();
server.expect().delete().withPath(format("/api/v1/namespaces/{}/configmaps/{}", namespace, configMapName)).andReturn(404, StringUtils.EMPTY).once();
actual = kubernetesClient.configMaps().inNamespace(namespace).withLabelSelector(labelSelector).delete();
assertTrue(actual)

// GET return 404
// kubernetesClient.delete() return FALSE
server.expect().get().withPath(format("/api/v1/namespaces/{}/configmaps?labelSelector={}%3D{}", namespace, name, value)).andReturn(404, StringUtils.EMPTY).once();
actual = kubernetesClient.configMaps().inNamespace(namespace).withLabelSelector(labelSelector).delete();
assertFalse(actual)

// GET return 200
// DELETE return 400
// kubernetesClient.delete() throws KubernetesClientException
server.expect().get().withPath(format("/api/v1/namespaces/{}/configmaps?labelSelector={}%3D{}", namespace, name, value)).andReturn(200, configMapList).once();
server.expect().delete().withPath(format("/api/v1/namespaces/{}/configmaps/{}", namespace, configMapName)).andReturn(400, StringUtils.EMPTY).once();
try {
    kubernetesClient.configMaps().inNamespace(namespace).withLabelSelector(labelSelector).delete();
    fail();
} catch (io.fabric8.kubernetes.client.KubernetesClientException e) {
    assertTrue(true);
}

// GET return 400
// kubernetesClient.delete() throws KubernetesClientException
server.expect().get().withPath(format("/api/v1/namespaces/{}/configmaps?labelSelector={}%3D{}", namespace, name, value)).andReturn(400, StringUtils.EMPTY).once();
try {
    kubernetesClient.configMaps().inNamespace(namespace).withLabelSelector(labelSelector).delete();
    fail();
} catch (io.fabric8.kubernetes.client.KubernetesClientException e) {
    assertTrue(true);
}
-- Michael D.
fabric8
java
kubernetes
spring

0 Answers