nginxinc / kubernetes-ingress

NGINX and NGINX Plus Ingress Controllers for Kubernetes
https://docs.nginx.com/nginx-ingress-controller
Apache License 2.0
4.66k stars 1.97k forks source link

[Bug]: If a VirtualServer is configured with an an incompatible listener (eg TCP, UDP), the VS ends up valid, and without a listen directive #6409

Open j1m-ryan opened 1 month ago

j1m-ryan commented 1 month ago

Version

edge

What Kubernetes platforms are you running on?

Minikube

What happened?

I added a UDP listener to a VirtualServer. This is not a valid configuration, I did this to test the error behaviour. The VirtualServer ended up valid, and generated config did not have a listen directive.

Steps to reproduce

listeners:
     - name: http-listener
       port: 81 
       protocol: UDP 
     - name: https-listener
       port: 8443
       protocol: HTTP
       ssl: true

I made a GlobalConfiguration with the above config, the used these in the VirtualServer.

apiVersion: k8s.nginx.org/v1
kind: VirtualServer
metadata:
  name: cafe
spec:
  listener:
    http: http-listener 
    https: https-listener 
  host: cafe.example.com
  tls:
    secret: cafe-secret
  upstreams:
  - name: tea
    service: tea-svc
    port: 80
  - name: coffee
    service: coffee-svc
    port: 80
  routes:
  - path: /tea
    action:
      pass: tea
  - path: /coffee
    action:
      pass: coffee

The VS is valid

[] ➜  virtualserver git:(main) ✗ k get vs
NAME   STATE   HOST               IP    PORTS   AGE
cafe   Valid   cafe.example.com                 16s

This is the output in the nginx config

[] ➜  virtualserver git:(main) ✗ dev-sh
/ $ cat /etc/nginx/conf.d/vs_default_cafe.conf

upstream vs_default_cafe_coffee {zone vs_default_cafe_coffee 256k;
    random two least_conn;
    server 10.244.0.6:8080 max_fails=1 fail_timeout=10s max_conns=0;
    server 10.244.0.7:8080 max_fails=1 fail_timeout=10s max_conns=0;
}

upstream vs_default_cafe_tea {zone vs_default_cafe_tea 256k;
    random two least_conn;
    server 10.244.0.5:8080 max_fails=1 fail_timeout=10s max_conns=0;
}

server {

    server_name cafe.example.com;

    set $resource_type "virtualserver";
    set $resource_name "cafe";
    set $resource_namespace "default";
    listen 8443 ssl;
    listen [::]:8443 ssl;

    ssl_certificate $secret_dir_path/default-cafe-secret;
    ssl_certificate_key $secret_dir_path/default-cafe-secret;

    server_tokens "on";

    location /tea {
        set $service "tea-svc";

        set $default_connection_header close;
        proxy_connect_timeout 60s;
        proxy_read_timeout 60s;
        proxy_send_timeout 60s;
        client_max_body_size 1m;

        proxy_buffering on;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $vs_connection_header;
        proxy_pass_request_headers on;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Port $server_port;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host "$host";
        proxy_pass http://vs_default_cafe_tea;
        proxy_next_upstream error timeout;
        proxy_next_upstream_timeout 0s;
        proxy_next_upstream_tries 0;
    }
    location /coffee {
        set $service "coffee-svc";

        set $default_connection_header close;
        proxy_connect_timeout 60s;
        proxy_read_timeout 60s;
        proxy_send_timeout 60s;
        client_max_body_size 1m;

        proxy_buffering on;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $vs_connection_header;
        proxy_pass_request_headers on;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Port $server_port;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host "$host";
        proxy_pass http://vs_default_cafe_coffee;
        proxy_next_upstream error timeout;
        proxy_next_upstream_timeout 0s;
        proxy_next_upstream_tries 0;
    }

}
/ $

Expected behaviour

The VirtualServer is not valid

Kubectl Describe output

No response

Log output

No response

Contributing Guidelines

pdabelf5 commented 2 weeks ago

Desired outcome: Fail VirtualServer deployment if no matching HTTP listener is found. Fail with Invalid VirtualServer state & remove VirtualServer from the NGINX config.