openshift/openshift-restclient-python

Creation of a Route object raise ResourceNotFoundError excpetion when serving.knative.dev/v1 Route api resource is present on the cluster

gmeghnag opened this issue · 5 comments

Issue

When Red Hat OpenShift Serverless is installed and serving.knative.dev/v1 Route api exists as resource in the cluster, the v1_routes.create( .. ) method raise the following exception : openshift.dynamic.exceptions.ResourceNotFoundError: No matches found for {'api_version': 'v1', 'kind': 'Route'}.

How to reproduce the issue:

  1. Install Red Hat OpenShift Serverless Operator

  2. Create a KnativeServing object (as the following for example:)

    # cat << EOF  | oc apply -n knative-serving -f -
    apiVersion: operator.knative.dev/v1alpha1
    kind: KnativeServing
    metadata:
      name: knative-serving
      namespace: knative-serving
    spec: {}
    EOF
  3. Check if the KnativeServing Route api exists in the cluster:

    # oc api-resources --verbs=list | grep routes          
    routes                                             route.openshift.io/v1                       true         Route
    routes                            rt               serving.knative.dev/v1                      true         Route
  4. Try to create an OpenShift Route executing the following script (adjusting the <variable> ):

    import yaml
    from kubernetes import client, config
    from openshift.dynamic import DynamicClient
    
    k8s_client = config.new_client_from_config()
    dyn_client = DynamicClient(k8s_client)
    
    v1_routes = dyn_client.resources.get(api_version='v1', kind='Route')
    route = """
    kind: Route
    metadata:
      name: test-route
    spec:
      host: test-route.<host>
      port:
        targetPort: 8080-tcp
      to:
        kind: Service
        name:  <service>
        weight: 100
      wildcardPolicy: None
      tls:
        termination: edge
    """
    
    route_data = yaml.load(route)
    resp = v1_routes.create(body=route_data, namespace='default')
    
    # resp is a ResourceInstance object
    print(resp.metadata)

    The execution of the script raise the following Exception:

    Traceback (most recent call last):
      File "createroute.py", line 11, in <module>
        v1_routes = dyn_client.resources.get(api_version='v1', kind='Route')
      File "/Users/gmeghnag/Library/Python/3.8/lib/python/site-packages/openshift/dynamic/discovery.py", line 246, in get
        raise ResourceNotFoundError('No matches found for {}'.format(kwargs))
    openshift.dynamic.exceptions.ResourceNotFoundError: No matches found for {'api_version': 'v1', 'kind': 'Route'}

Potential cause

From discovery.py #L165

def get(self, **kwargs):
        """ Same as search, but will throw an error if there are multiple or no
            results. If there are multiple results and only one is an exact match
            on api_version, that resource will be returned.
        """

Other Information

# oc get clusterversion
NAME      VERSION   AVAILABLE   PROGRESSING   SINCE   STATUS
version   4.6.15    True        False         134m    Cluster version is 4.6.15

# oc get sub -A
NAMESPACE              NAME                  PACKAGE               SOURCE             CHANNEL
openshift-serverless   serverless-operator   serverless-operator   redhat-operators   stable

Hi, you should specify the full API version, otherwise cannot distinguish between the two:

v1_routes = dyn_client.resources.get(api_version='route.openshift.io/v1', kind='Route')

Question is whether for the long run we can have a solution similar to "oc client" which succeeds with even though the full api version is not used in the resource definition

actually oc is failing too:

$ oc apply -f - <<EOF
> kind: Route
> metadata:
>   name: testroute
> spec:
>   port:
>     targetPort: 8080-tcp
>   to:
>     kind: Service
>     name: svc
>     weight: 100
>   wildcardPolicy: None
>   tls:
>     termination: edge
> EOF
W0909 14:30:41.836086  950719 shim_kubectl.go:55] Using non-groupfied API resources is deprecated and will be removed in a future release, update apiVersion to "route.openshift.io/" for your resource
Error from server (NotFound): error when creating "STDIN": the server could not find the requested resource (post routes.route.openshift.io)

Works with this one
apiVersion: v1
kind: Route
metadata:
name: test-route
spec:
host: test-route.
port:
targetPort: 8080-tcp
to:
kind: Service
name:
weight: 100
wildcardPolicy: None
using oc client tool we don't get any error and the resource is created as expected.