Skip to content

Unsuitable ResourceNotFoundError raised in LazyDiscoverer.__search, caused by cache expiration #1536

@narasux

Description

@narasux

What happened (please include outputs or screenshots):

  1. logic at discovery.py#L261, self.get_resources_for_api_version() called for fetch group's resource. However, the group name (samplecontroller.k8s.io) not exists in cluster but in cache. So this func will raise NotFoundError, caught by __search() and raise ResourceNotFoundError, break and stop search.
parts = ['v1alpha1', 'Namespace', {'preferred': True}]
resources = {'v1alpha1': <kubernetes.dynamic.discovery.ResourceGroup object at 0x7f90df241710>}
reqParams = ['apis', 'samplecontroller.k8s.io']

def __search(self,  parts, resources, reqParams):
    part = parts[0]
    if part != '*':

        resourcePart = resources.get(part)
        if not resourcePart:
            return []
        elif isinstance(resourcePart, ResourceGroup):
            if len(reqParams) != 2:
                raise ValueError("prefix and group params should be present, have %s" % reqParams)
            # Check if we've requested resources for this group
            if not resourcePart.resources:
                prefix, group, version = reqParams[0], reqParams[1], part
                try:
                    resourcePart.resources = self.get_resources_for_api_version(
                        prefix, group, part, resourcePart.preferred)
                except NotFoundError:
>                       raise ResourceNotFoundError
E                       kubernetes.dynamic.exceptions.ResourceNotFoundError

/.../kubernetes/dynamic/discovery.py:264: ResourceNotFoundError
  1. why this group name not exists in cluster but in cache is that I had create a CRD with this group name and delete it after used, so it was leave in cache.
// cache content
{
  "library_version": "17.17.0",
  "version": {
    "kubernetes": {...}
  },
  "resources": {
    "api": {
      "": {
        "v1": {
          "_type": "ResourceGroup",
          "preferred": true,
          "resources": {}
        }
      }
    },
    "apis": {
      "": {
        "v1": {
          "_type": "ResourceGroup",
          "preferred": true,
          "resources": {
            "List": [
              {
                "_type": "ResourceList",
                "group": "",
                "api_version": "v1",
                "kind": "List",
                "base_kind": ""
              }
            ]
          }
        }
      },
      ...
      "samplecontroller.k8s.io": {
        "v1alpha1": {
          "_type": "ResourceGroup",
          "preferred": true,
          "resources": {}
        }
      },
      "traefik.containo.us": {
        "v1alpha1": {
          "_type": "ResourceGroup",
          "preferred": true,
          "resources": {}
        }
      }
    }
  }
}

What you expected to happen:

In this case, I want to ignore the NotFoundError raise by self.get_resources_for_api_version()

So can raise ResourceNotFoundError here is Optional? Such as control by args?

Or more thoroughly, how can I remove expired group in cache in time?

How to reproduce it (as minimally and precisely as possible):

  1. create a CRD with new group name
  2. call resource‘s api defined by CRD immediately, so this group will in cache
  3. delete this CRD, search other resource with this cache

Anything else we need to know?:

None

Environment:

  • Kubernetes version (kubectl version): v1.21.2+k3s1
  • OS (e.g., MacOS 10.13.6): linux/amd64
  • Python version (python --version): 3.6.8
  • Python client version (pip list | grep kubernetes): 17.17.0

Metadata

Metadata

Assignees

Labels

kind/bugCategorizes issue or PR as related to a bug.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions