java icon indicating copy to clipboard operation
java copied to clipboard

Issue with deploying/loading a custom resource making use of a CRD

Open Smith334 opened this issue 1 year ago • 6 comments

Describe the bug I am having an issue deploying a "Nginx VirtualServer" resource that makes use of a Custom Resource Definition (CRD). The CRD itself has no problems applying to the cluster, but deploying the custom VirtualServer resource just after throws an exception:

java.io.IOException: Unknown apiVersionKind k8s.nginx.org/v1/VirtualServer is it registered?
                at io.kubernetes.client.util.Yaml.modelMapper(Yaml.java:555)
                at io.kubernetes.client.util.Yaml.loadAll(Yaml.java:179)
                at io.kubernetes.client.util.Yaml.loadAll(Yaml.java:145)

The exception is coming from SnakeYaml itself not being able to map to an existing model. I believe that there is a way to generate the Java CRD model beforehand, but is this actually necessary even for custom resources if I have deployed the CRD literally just before? Should the client not be aware of the definition at the point of trying to make use of the CRD? Unless it is and I am just messing something up.

This is the VirtualServer CRD (v0.13.0): https://github.com/nginxinc/kubernetes-ingress/blob/main/deployments/common/crds/k8s.nginx.org_virtualservers.yaml

Every YAML resource, including the CRD, is deployed with this Java code:

  public void apply(String yaml) throws IOException, KubectlException {
    List<Object> all = Yaml.loadAll(yaml);
    apply(all);
  }

  public void apply(List<Object> all) throws KubectlException {
    for (Object object : all) {
      KubernetesObject source = (KubernetesObject) object;
      KubectlApply<KubernetesObject> apply = Kubectl.apply((Class<KubernetesObject>) source.getClass());
      apply.apiClient(ioClient());
      apply.resource(source);
      apply.name(source.getMetadata().getName());
      apply.execute();
    }
  }

This is the VirtualServer resource i am trying to deploy after deploying the VirtualServer CRD to the cluster:

# Ingress resources are bound to specific ingress controllers using an identifier
# Ingress Controller Identifier: nginx-firstone
kind: VirtualServer
apiVersion: k8s.nginx.org/v1
metadata: 
  name: nginx-firstone-dmz-vs
  namespace: dmz
spec: 
  host: some-host-name
  ingressClassName: nginx-firstone
  tls: 
    secret: firstone-secret
    redirect: 
      enable: true
      code: 301
  upstreams: 
  - name: psp-dmz-webinterfaceclient-service-80-us
    service: psp-dmz-webinterfaceclient-service
    port: 80
    connect-timeout: "60"
    send-timeout: "60"
    read-timeout: "60"
    keepalive: 75
  - name: psp-dmz-webinterfaceclient-service-85-us
    service: psp-dmz-webinterfaceclient-service
    port: 85
    connect-timeout: "60"
    send-timeout: "60"
    read-timeout: "60"
    keepalive: 75
  routes: 
  - path: /merchantportal
    action: 
      proxy: 
        upstream: psp-dmz-webinterfaceclient-service-80-us
        requestHeaders: 
            pass: true
        rewritePath: /merchantportal
    errorPages: 
      - codes: [404]
        return: 
          code: 200
          body: This was returned as a 200
  - path: /merchantenrolment
    action: 
      proxy: 
        upstream: psp-dmz-webinterfaceclient-service-85-us
        requestHeaders: 
            pass: true
        rewritePath: /merchantenrolment
    errorPages: 
      - codes: [404]
        return: 
          code: 200
          body: This was returned as a 200
---

A few months back, I was able to deploy the CRD and the VirtualServer resource with no problem, and no need for any model generations.

Client Version 1.19

Kubernetes Version 1.27

Java Version Java 11

To Reproduce Simply deploy the CRD first and then deploy a VirtualServer resource that makes use of it. An exception will throw.

Expected behavior The following exception will be thrown when attempting to deploy the VirtualServer resource:

java.io.IOException: Unknown apiVersionKind k8s.nginx.org/v1/VirtualServer is it registered?
                at io.kubernetes.client.util.Yaml.modelMapper(Yaml.java:555)
                at io.kubernetes.client.util.Yaml.loadAll(Yaml.java:179)
                at io.kubernetes.client.util.Yaml.loadAll(Yaml.java:145)

Server (please complete the following information):

  • OS: Windows
  • Environment: Windows VM
  • Cloud: AWS

Additional context A few months back, I was able to deploy the CRD and the VirtualServer resource with no problem, and no need for any model generations.

All resources are YAML. My VirtualServer Yaml is dynamically created using an XML model being fed into the system and then transformed. Therefore based on the XML model being fed in, the output Nginx VirtualServer YAML can look completely different. It will still follow the requirements of the CRD.

Smith334 avatar Oct 10 '23 07:10 Smith334