diff --git a/test/e2e/testdata/sds.yaml b/test/e2e/testdata/sds.yaml new file mode 100644 index 0000000000..ded91e0e7e --- /dev/null +++ b/test/e2e/testdata/sds.yaml @@ -0,0 +1,241 @@ +--- +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: Gateway +metadata: + name: sds-gateway + namespace: gateway-conformance-infra +spec: + gatewayClassName: "{GATEWAY_CLASS_NAME}" + infrastructure: + annotations: + kubectl.kubernetes.io/default-container: envoy + kubectl.kubernetes.io/default-logs-container: envoy + parametersRef: + group: gateway.envoyproxy.io + kind: EnvoyProxy + name: sds-gateway-settings + listeners: + - name: tcp + protocol: TCP + port: 8090 + allowedRoutes: + kinds: + - kind: TCPRoute +--- +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: EnvoyProxy +metadata: + name: sds-gateway-settings + namespace: gateway-conformance-infra +spec: + ipFamily: IPv4 + provider: + type: Kubernetes + kubernetes: + envoyDeployment: + pod: + volumes: + - name: tls-certs + secret: + secretName: tls-termination-certificate + - name: sds-socket + hostPath: + path: /var/run/sds + type: DirectoryOrCreate + patch: + type: StrategicMerge + value: + spec: + template: + spec: + containers: + - name: sds-test-server + image: envoyproxy/gateway-sds-test-server:latest + imagePullPolicy: IfNotPresent + args: + - --socket-path=/var/run/sds/sds.sock + - --secret-name=server_cert + - --cert-path=/var/tls-certs/tls.crt + - --key-path=/var/tls-certs/tls.key + volumeMounts: + - name: tls-certs + mountPath: /var/tls-certs/ + readOnly: true + - name: sds-socket + mountPath: /var/run/sds + - name: envoy + volumeMounts: + # mount the SDS socket to the envoy container so that it can talk to the SDS server + - name: sds-socket + mountPath: "/var/run/sds" + backendTLS: + clientCertificateRef: + kind: Secret + name: "sds-client-tls-certificate" +--- +apiVersion: v1 +kind: Secret +metadata: + name: sds-client-tls-certificate + namespace: gateway-conformance-infra +type: gateway.envoyproxy.io/sds +data: + # base64(unix:///var/run/sds/sds.sock) + url: dW5peDovLy92YXIvcnVuL3Nkcy9zZHMuc29jaw== + # base64 for "server_cert" + secretName: c2VydmVyX2NlcnQ= +--- +apiVersion: gateway.networking.k8s.io/v1alpha2 +kind: TCPRoute +metadata: + name: sds-route + namespace: gateway-conformance-infra +spec: + parentRefs: + - name: sds-gateway + rules: + - backendRefs: + - name: sds-mtls-backend + port: 443 +--- +apiVersion: v1 +data: + ca.crt: | + -----BEGIN CERTIFICATE----- + MIIDQzCCAiugAwIBAgIBATANBgkqhkiG9w0BAQsFADBCMRMwEQYDVQQKEwpFbnZv + eVByb3h5MRAwDgYDVQQLEwdHYXRld2F5MRkwFwYDVQQDExBFbnZveSBHYXRld2F5 + IENBMCAXDTI0MDMxMDE1MzIxN1oYDzIxMjQwMzEwMTYzMjE3WjBCMRMwEQYDVQQK + EwpFbnZveVByb3h5MRAwDgYDVQQLEwdHYXRld2F5MRkwFwYDVQQDExBFbnZveSBH + YXRld2F5IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7ZFmGB4e + m1KdGEohAZBfqydAEGLDHJ1YyfHWdd+vBAevdW64bZx3pggJOtgCnePuFd02rDQS + dlsJlX/6mFtoQilo6wvxDSJRfaTDbtfTjw+7k8yfd/Jsmh0RWG+UeyI7Na9sXAz7 + b57mpxsCoNowzeK5ETiOGGNWPcjENJkSnBarz5muN00xIZWBU+yN5PLJNxZvxpZJ + Ol/SSI8sno0e0PxAmp3fe7QaXiZj/TAGJPGuTJkUxrHqyZGJtYUxsS8A0dT1zBjj + izA5Dp+b5yzYo23Hh7BgpbZ7X4gsDThFuwCD6fHyepuv2zHPqvSsdqg2hAhDp91R + zrn7a9GxG2VSIwIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw + AwEB/zAdBgNVHQ4EFgQUUpP1aZ1M2KIuPPWrNPDV2c5CngowDQYJKoZIhvcNAQEL + BQADggEBAGSEkAVz+Z0qS4FmA0q4SCpIIq64bsdEjiUzev7pK1LEK0/Y28QBPixV + cUXfax18VPR9pls1JgXto9qY+C0hnRZic6611QTJlWK1p6dinQ/eDdYCBC+nv5xx + ssASwmplIxMvj3S1qF6dr7sMI2ZVD5HElTWdO19UBLyhiKKZW2KxDsYj+5NRwGFe + G+JuDgq7njUM8mdyYk0NehefdBUEUUCQtnwUtW95/429XwqQROuRDteGT9kjD+Y5 + ea5mW4mfqLeuGJXZs9bdWjKKdLQPrn9IshPysWqz2Hz8dQ1f7N9/g8UWVSjd4cyx + S5EAolzVv0yB7wHCWCgfG/ckdOTUNnE= + -----END CERTIFICATE----- +kind: ConfigMap +metadata: + name: backend-tls-ca + namespace: gateway-conformance-infra +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: BackendTLSPolicy +metadata: + name: tls-backend-policy + namespace: gateway-conformance-infra +spec: + targetRefs: + - group: "" + kind: Service + name: sds-mtls-backend + sectionName: https + validation: + caCertificateRefs: + - name: backend-tls-ca + group: "" + kind: ConfigMap + hostname: example.com +--- +# mTLS backend that validates client certificates +apiVersion: v1 +kind: Service +metadata: + name: sds-mtls-backend + namespace: gateway-conformance-infra +spec: + selector: + app: sds-mtls-backend + ports: + - name: https + protocol: TCP + port: 443 + targetPort: 8443 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: sds-mtls-backend + namespace: gateway-conformance-infra + labels: + app: sds-mtls-backend +spec: + replicas: 1 + selector: + matchLabels: + app: sds-mtls-backend + template: + metadata: + labels: + app: sds-mtls-backend + spec: + containers: + - name: mtls-backend + image: registry.k8s.io/gateway-api/echo-basic:v1.5.1 + volumeMounts: + - name: server-cert-volume + mountPath: /etc/server-cert + - name: client-ca-volume + mountPath: /etc/client-ca + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: SERVICE_NAME + value: sds-mtls-backend + - name: TLS_SERVER_CERT + value: /etc/server-cert/tls.crt + - name: TLS_SERVER_PRIVKEY + value: /etc/server-cert/tls.key + - name: TLS_CLIENT_CACERTS + value: /etc/client-ca/ca.crt + resources: + requests: + cpu: 10m + volumes: + - name: server-cert-volume + secret: + secretName: backend-tls-checks-certificate + - name: client-ca-volume + secret: + secretName: tls-termination-certificate + items: + - key: ca.crt + path: ca.crt +--- +# Certificate for TLS termination - Wildcard cert for *.example.com +# openssl req -x509 -sha256 -nodes -days 3650 -newkey rsa:2048 -subj '/O=example Inc./CN=*.example.com' -keyout tls.key -out tls.crt +apiVersion: v1 +data: + tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2Z0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktnd2dnU2tBZ0VBQW9JQkFRRG5zbHN5Q21VQmxmMTgKT0htNkNKRkdYeGNMWkF2TGhyWkdZK0NGTFpwTW5IaVhDTTRYLzB4V0ViS2d3TGJTd3c4RURISXZlVElSajNvQQpta2l0d2t2UUZiUkZSUnlDSlNjOXNMb1MzY2hPcEp5TlUxdEYrenYraHAvQlR6L0VGMHBqMUZJdDBYc0g3UlZIClRaaDBnUzdlYm53T3RhNU51WEFuYmFCakhxdVJmQVZPUWcrZDNCSU9kZXhzZkJvNFN5TEc4VHRsYis4bXVOY24KTll6UFVtQW01NkE4SmNsblVxc2U3aTVDWXdZeWlRZnJCNk5NS043c1YwR2p6enE0RHB5WHMxZWoxZmpGQmpKUwpxVlAzTm5FcEoyaWFsbC9yYzlUNXQ0Q0lqTjNPTEVUSHNRdUFLekdVQTkxQkQ2KzhuUUd0eGhUREhzRlhWdnRJCmN0UmVtZFdMQWdNQkFBRUNnZ0VBRG9Pd1RkS3o0Q1VPdzV6Z0YwVFpJUER0QnlRbHp3S3A0WC81UFM2TnAzWDMKNGZKRnd1QVYzcUJ1TWI3UTFTUXVDU0ZrZDgvZVVKWk4zTUxOZ2NFVnNidmlWcUtOTmlQd3NOOGswUEMrenhwbAp5ajZxRFppKytlTmlGNkNJekpadTdSRU1jdDFZR1RlRGFUdVZyTnE0M210S2J6dDNaMXdTQ0E1SWlWME8vMmFJCmhMVTE4TXg4Y3d6c0dmMEdKRkJndkMzcVdkdG1uL1BZVlFVV2x0Wi83LzF6NG5CNGhjZ0oxU0N0Uk9PejNWbzcKMDRKMWpiRitQTWFkNWFQQVVGa1ozR0RNY3I2ZVlLbVc2a1pqa3hEWDRSTGJwTHl5Vm1MOTNndGNMc0ZWL0tIbQpSQS9GWXZQUXNjUTk3ZmVzSmZ3REl1eXpraUw0VTZSVkxqZ1FtUjk1T1FLQmdRRDF3WGw5SEN4NXQ3cWlpYXZjCmdoMTlGbXZZUHluUDc0Y1BSVmFYNkpvTEVrbXVtTFBHMk1rUjV1bkU4MjAxSWJHRitud2dIY2pvVThFYU1kREQKc1NFeWxBekNwZW9ZbE1Wa0FmSVRuWVdZU0pGZk5nc1JESEhXRnBabEFZR1poMU0zV3pZYkFzTk5UNnk3UXJUSAp5c20zZHF0ayt0SEFQNTRMMkFtRjlOZjdxUUtCZ1FEeFd0cU5kSWlUaVA5KzlMdVg0enFWT1dHMzE2REpyRlMyCmxrMFp3Z1N6Vk5HVS9DK2lrMzJ1ZUwzVTNnbFJhNy8xRUV3WDA2MFI3QTdzK0p3cUl2NGN3ZHNZbHhmY0hpd1IKWXc5K1haZlltaFFiRUllL3lxRFVnN1lmYXVPdjUzT0RWeGNNb1I5MDdTUHRRbERzQk9WbGgrVlBqQWdpa2cyLwo2OHdlcXhub0V3S0JnSHNqZElKUnlaODdobExHOU14S2pnZ05ZZ0E2dGZLd3JGWGtnbDBmZVlBdXE2akdidDRsCjVhb0lyLzIxazNUWjZ4K2N3UEUrdTFwZURSWFkvQ2Z4NnhaeXhHb0x4RjZJdk5jOWVsU0Z5MWpnazZiSFo0Z2wKV2l6UnFJMzMwVDVpWmpvSWcvWEl6cDlBV3VhQnFCK3I1cUw4M1NoOTNQZWRhTTI2ZEJzZzhjL3hBb0dCQUpVYwpKVlFwUDh1dVl2TGpiaFpiZXpFQUgzLytCc2N4NGJCZ1VVZnRsd3ZZQmhkK2FrdU54YU1KMDNYMHExc1RMNmZPCnBzUTlzWG9XRmU2UGRhT090T0c5WG9mbHFRY0QyUVB3Nkh5UWhDUjhwSmxIOENZc29JcEt5VFRGeTk4OEppQnAKcU1MVHRHUi9zYWQrUmhKYXdBS25INk95aHNBYzdjTzVnUVVkZmtiakFvR0JBS1BlSFU3MDFmYjR4QkM2aUdsVgo4NVBLZzRVeGpDbEljQkw0amM5MWdMY1pBWEtIVWxzT0U1a00xYVJodlQyQUpzRmpKRnp5MHZmNkMrRE9BZUJ3ClRhN3hDMHVBbjc1R3lBVy9jZitYSnNHVEt4R0JoVVZCSXkzZkVOVTQ1UTNyZkRFSE1jTzVvRGQrS1p6Mk1SWWgKbW9qYnp5eVJ0VklHVy9kZUpEQ1FiRFlrCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K + tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURXakNDQWtLZ0F3SUJBZ0lVSk9taGNTTHR6LzVRU2tvcitaOFpvOWVocnlNd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0x6RVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkpibU11TVJZd0ZBWURWUVFEREEwcUxtVjRZVzF3YkdVdQpZMjl0TUI0WERUSTFNVEl3TlRBNE1EWXdNMW9YRFRNMU1USXdNekE0TURZd00xb3dMekVWTUJNR0ExVUVDZ3dNClpYaGhiWEJzWlNCSmJtTXVNUll3RkFZRFZRUUREQTBxTG1WNFlXMXdiR1V1WTI5dE1JSUJJakFOQmdrcWhraUcKOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQTU3SmJNZ3BsQVpYOWZEaDV1Z2lSUmw4WEMyUUx5NGEyUm1QZwpoUzJhVEp4NGx3ak9GLzlNVmhHeW9NQzIwc01QQkF4eUwza3lFWTk2QUpwSXJjSkwwQlcwUlVVY2dpVW5QYkM2CkV0M0lUcVNjalZOYlJmczcvb2Fmd1U4L3hCZEtZOVJTTGRGN0IrMFZSMDJZZElFdTNtNThEcld1VGJsd0oyMmcKWXg2cmtYd0ZUa0lQbmR3U0RuWHNiSHdhT0VzaXh2RTdaVy92SnJqWEp6V016MUpnSnVlZ1BDWEpaMUtySHU0dQpRbU1HTW9rSDZ3ZWpUQ2plN0ZkQm84ODZ1QTZjbDdOWG85WDR4UVl5VXFsVDl6WnhLU2RvbXBaZjYzUFUrYmVBCmlJemR6aXhFeDdFTGdDc3hsQVBkUVErdnZKMEJyY1lVd3g3QlYxYjdTSExVWHBuVml3SURBUUFCbzI0d2JEQkwKQmdOVkhSRUVSREJDZ2cwcUxtVjRZVzF3YkdVdVkyOXRnZzltYjI4dVpYaGhiWEJzWlM1amIyMkNEMkpoY2k1bAplR0Z0Y0d4bExtTnZiWUlQWW1GNkxtVjRZVzF3YkdVdVkyOXRNQjBHQTFVZERnUVdCQlFLbWNMbHFOVjlJei9DCnZZYWFhLzVaTkxESFJUQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFEZExaRHFQdllYc0d6YjFyektjY1pQV1IKNFMxYS9rNEl4Nk1yaExaRFc4YmdiL3hNalpqeHVMRVJGNk9YYlViazhuOFdaeWhpalY5SXZ2alZ2K1pGRVc4VQpnNjJnaWlyREFnVXp6SUc2RkdLejRvU2l5dmpGMnhUdURNY1J1Y0U5OFE4dnNUV0c1TU51L0lsdTlnbzg4Q3dwCkdNMlc0clRoVG05U3dBWi9XNE9NNlRpNHdBUldzUHJ5am5QZlIralQzUUVBcXJHMWNoZ3BKU29qSmhlK3p0RW4KaURkNmdMSFhKUUN5WnNJRklsRFdWVzdmVUEvNHNpUFB1dGxmc3JjY3gweW43WlVkU0k1ZkVzWm9jUkJBSFN3WgpIUFVwTlBoMno1ajZEOUNDVG5jQTVNbXRHNCtjdjNtMyt3eHFseUozWFhrSGd3SUtwWkNjbFNyVXRkL2t2dz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURXakNDQWtLZ0F3SUJBZ0lVSk9taGNTTHR6LzVRU2tvcitaOFpvOWVocnlNd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0x6RVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkpibU11TVJZd0ZBWURWUVFEREEwcUxtVjRZVzF3YkdVdQpZMjl0TUI0WERUSTFNVEl3TlRBNE1EWXdNMW9YRFRNMU1USXdNekE0TURZd00xb3dMekVWTUJNR0ExVUVDZ3dNClpYaGhiWEJzWlNCSmJtTXVNUll3RkFZRFZRUUREQTBxTG1WNFlXMXdiR1V1WTI5dE1JSUJJakFOQmdrcWhraUcKOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQTU3SmJNZ3BsQVpYOWZEaDV1Z2lSUmw4WEMyUUx5NGEyUm1QZwpoUzJhVEp4NGx3ak9GLzlNVmhHeW9NQzIwc01QQkF4eUwza3lFWTk2QUpwSXJjSkwwQlcwUlVVY2dpVW5QYkM2CkV0M0lUcVNjalZOYlJmczcvb2Fmd1U4L3hCZEtZOVJTTGRGN0IrMFZSMDJZZElFdTNtNThEcld1VGJsd0oyMmcKWXg2cmtYd0ZUa0lQbmR3U0RuWHNiSHdhT0VzaXh2RTdaVy92SnJqWEp6V016MUpnSnVlZ1BDWEpaMUtySHU0dQpRbU1HTW9rSDZ3ZWpUQ2plN0ZkQm84ODZ1QTZjbDdOWG85WDR4UVl5VXFsVDl6WnhLU2RvbXBaZjYzUFUrYmVBCmlJemR6aXhFeDdFTGdDc3hsQVBkUVErdnZKMEJyY1lVd3g3QlYxYjdTSExVWHBuVml3SURBUUFCbzI0d2JEQkwKQmdOVkhSRUVSREJDZ2cwcUxtVjRZVzF3YkdVdVkyOXRnZzltYjI4dVpYaGhiWEJzWlM1amIyMkNEMkpoY2k1bAplR0Z0Y0d4bExtTnZiWUlQWW1GNkxtVjRZVzF3YkdVdVkyOXRNQjBHQTFVZERnUVdCQlFLbWNMbHFOVjlJei9DCnZZYWFhLzVaTkxESFJUQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFEZExaRHFQdllYc0d6YjFyektjY1pQV1IKNFMxYS9rNEl4Nk1yaExaRFc4YmdiL3hNalpqeHVMRVJGNk9YYlViazhuOFdaeWhpalY5SXZ2alZ2K1pGRVc4VQpnNjJnaWlyREFnVXp6SUc2RkdLejRvU2l5dmpGMnhUdURNY1J1Y0U5OFE4dnNUV0c1TU51L0lsdTlnbzg4Q3dwCkdNMlc0clRoVG05U3dBWi9XNE9NNlRpNHdBUldzUHJ5am5QZlIralQzUUVBcXJHMWNoZ3BKU29qSmhlK3p0RW4KaURkNmdMSFhKUUN5WnNJRklsRFdWVzdmVUEvNHNpUFB1dGxmc3JjY3gweW43WlVkU0k1ZkVzWm9jUkJBSFN3WgpIUFVwTlBoMno1ajZEOUNDVG5jQTVNbXRHNCtjdjNtMyt3eHFseUozWFhrSGd3SUtwWkNjbFNyVXRkL2t2dz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K +kind: Secret +metadata: + name: tls-termination-certificate + namespace: gateway-conformance-infra +type: kubernetes.io/tls +--- +# Copy of the TLS termination certificate but with the key in a different namespace for non gateway namespace mode. +apiVersion: v1 +data: + tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2Z0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktnd2dnU2tBZ0VBQW9JQkFRRG5zbHN5Q21VQmxmMTgKT0htNkNKRkdYeGNMWkF2TGhyWkdZK0NGTFpwTW5IaVhDTTRYLzB4V0ViS2d3TGJTd3c4RURISXZlVElSajNvQQpta2l0d2t2UUZiUkZSUnlDSlNjOXNMb1MzY2hPcEp5TlUxdEYrenYraHAvQlR6L0VGMHBqMUZJdDBYc0g3UlZIClRaaDBnUzdlYm53T3RhNU51WEFuYmFCakhxdVJmQVZPUWcrZDNCSU9kZXhzZkJvNFN5TEc4VHRsYis4bXVOY24KTll6UFVtQW01NkE4SmNsblVxc2U3aTVDWXdZeWlRZnJCNk5NS043c1YwR2p6enE0RHB5WHMxZWoxZmpGQmpKUwpxVlAzTm5FcEoyaWFsbC9yYzlUNXQ0Q0lqTjNPTEVUSHNRdUFLekdVQTkxQkQ2KzhuUUd0eGhUREhzRlhWdnRJCmN0UmVtZFdMQWdNQkFBRUNnZ0VBRG9Pd1RkS3o0Q1VPdzV6Z0YwVFpJUER0QnlRbHp3S3A0WC81UFM2TnAzWDMKNGZKRnd1QVYzcUJ1TWI3UTFTUXVDU0ZrZDgvZVVKWk4zTUxOZ2NFVnNidmlWcUtOTmlQd3NOOGswUEMrenhwbAp5ajZxRFppKytlTmlGNkNJekpadTdSRU1jdDFZR1RlRGFUdVZyTnE0M210S2J6dDNaMXdTQ0E1SWlWME8vMmFJCmhMVTE4TXg4Y3d6c0dmMEdKRkJndkMzcVdkdG1uL1BZVlFVV2x0Wi83LzF6NG5CNGhjZ0oxU0N0Uk9PejNWbzcKMDRKMWpiRitQTWFkNWFQQVVGa1ozR0RNY3I2ZVlLbVc2a1pqa3hEWDRSTGJwTHl5Vm1MOTNndGNMc0ZWL0tIbQpSQS9GWXZQUXNjUTk3ZmVzSmZ3REl1eXpraUw0VTZSVkxqZ1FtUjk1T1FLQmdRRDF3WGw5SEN4NXQ3cWlpYXZjCmdoMTlGbXZZUHluUDc0Y1BSVmFYNkpvTEVrbXVtTFBHMk1rUjV1bkU4MjAxSWJHRitud2dIY2pvVThFYU1kREQKc1NFeWxBekNwZW9ZbE1Wa0FmSVRuWVdZU0pGZk5nc1JESEhXRnBabEFZR1poMU0zV3pZYkFzTk5UNnk3UXJUSAp5c20zZHF0ayt0SEFQNTRMMkFtRjlOZjdxUUtCZ1FEeFd0cU5kSWlUaVA5KzlMdVg0enFWT1dHMzE2REpyRlMyCmxrMFp3Z1N6Vk5HVS9DK2lrMzJ1ZUwzVTNnbFJhNy8xRUV3WDA2MFI3QTdzK0p3cUl2NGN3ZHNZbHhmY0hpd1IKWXc5K1haZlltaFFiRUllL3lxRFVnN1lmYXVPdjUzT0RWeGNNb1I5MDdTUHRRbERzQk9WbGgrVlBqQWdpa2cyLwo2OHdlcXhub0V3S0JnSHNqZElKUnlaODdobExHOU14S2pnZ05ZZ0E2dGZLd3JGWGtnbDBmZVlBdXE2akdidDRsCjVhb0lyLzIxazNUWjZ4K2N3UEUrdTFwZURSWFkvQ2Z4NnhaeXhHb0x4RjZJdk5jOWVsU0Z5MWpnazZiSFo0Z2wKV2l6UnFJMzMwVDVpWmpvSWcvWEl6cDlBV3VhQnFCK3I1cUw4M1NoOTNQZWRhTTI2ZEJzZzhjL3hBb0dCQUpVYwpKVlFwUDh1dVl2TGpiaFpiZXpFQUgzLytCc2N4NGJCZ1VVZnRsd3ZZQmhkK2FrdU54YU1KMDNYMHExc1RMNmZPCnBzUTlzWG9XRmU2UGRhT090T0c5WG9mbHFRY0QyUVB3Nkh5UWhDUjhwSmxIOENZc29JcEt5VFRGeTk4OEppQnAKcU1MVHRHUi9zYWQrUmhKYXdBS25INk95aHNBYzdjTzVnUVVkZmtiakFvR0JBS1BlSFU3MDFmYjR4QkM2aUdsVgo4NVBLZzRVeGpDbEljQkw0amM5MWdMY1pBWEtIVWxzT0U1a00xYVJodlQyQUpzRmpKRnp5MHZmNkMrRE9BZUJ3ClRhN3hDMHVBbjc1R3lBVy9jZitYSnNHVEt4R0JoVVZCSXkzZkVOVTQ1UTNyZkRFSE1jTzVvRGQrS1p6Mk1SWWgKbW9qYnp5eVJ0VklHVy9kZUpEQ1FiRFlrCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K + tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURXakNDQWtLZ0F3SUJBZ0lVSk9taGNTTHR6LzVRU2tvcitaOFpvOWVocnlNd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0x6RVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkpibU11TVJZd0ZBWURWUVFEREEwcUxtVjRZVzF3YkdVdQpZMjl0TUI0WERUSTFNVEl3TlRBNE1EWXdNMW9YRFRNMU1USXdNekE0TURZd00xb3dMekVWTUJNR0ExVUVDZ3dNClpYaGhiWEJzWlNCSmJtTXVNUll3RkFZRFZRUUREQTBxTG1WNFlXMXdiR1V1WTI5dE1JSUJJakFOQmdrcWhraUcKOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQTU3SmJNZ3BsQVpYOWZEaDV1Z2lSUmw4WEMyUUx5NGEyUm1QZwpoUzJhVEp4NGx3ak9GLzlNVmhHeW9NQzIwc01QQkF4eUwza3lFWTk2QUpwSXJjSkwwQlcwUlVVY2dpVW5QYkM2CkV0M0lUcVNjalZOYlJmczcvb2Fmd1U4L3hCZEtZOVJTTGRGN0IrMFZSMDJZZElFdTNtNThEcld1VGJsd0oyMmcKWXg2cmtYd0ZUa0lQbmR3U0RuWHNiSHdhT0VzaXh2RTdaVy92SnJqWEp6V016MUpnSnVlZ1BDWEpaMUtySHU0dQpRbU1HTW9rSDZ3ZWpUQ2plN0ZkQm84ODZ1QTZjbDdOWG85WDR4UVl5VXFsVDl6WnhLU2RvbXBaZjYzUFUrYmVBCmlJemR6aXhFeDdFTGdDc3hsQVBkUVErdnZKMEJyY1lVd3g3QlYxYjdTSExVWHBuVml3SURBUUFCbzI0d2JEQkwKQmdOVkhSRUVSREJDZ2cwcUxtVjRZVzF3YkdVdVkyOXRnZzltYjI4dVpYaGhiWEJzWlM1amIyMkNEMkpoY2k1bAplR0Z0Y0d4bExtTnZiWUlQWW1GNkxtVjRZVzF3YkdVdVkyOXRNQjBHQTFVZERnUVdCQlFLbWNMbHFOVjlJei9DCnZZYWFhLzVaTkxESFJUQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFEZExaRHFQdllYc0d6YjFyektjY1pQV1IKNFMxYS9rNEl4Nk1yaExaRFc4YmdiL3hNalpqeHVMRVJGNk9YYlViazhuOFdaeWhpalY5SXZ2alZ2K1pGRVc4VQpnNjJnaWlyREFnVXp6SUc2RkdLejRvU2l5dmpGMnhUdURNY1J1Y0U5OFE4dnNUV0c1TU51L0lsdTlnbzg4Q3dwCkdNMlc0clRoVG05U3dBWi9XNE9NNlRpNHdBUldzUHJ5am5QZlIralQzUUVBcXJHMWNoZ3BKU29qSmhlK3p0RW4KaURkNmdMSFhKUUN5WnNJRklsRFdWVzdmVUEvNHNpUFB1dGxmc3JjY3gweW43WlVkU0k1ZkVzWm9jUkJBSFN3WgpIUFVwTlBoMno1ajZEOUNDVG5jQTVNbXRHNCtjdjNtMyt3eHFseUozWFhrSGd3SUtwWkNjbFNyVXRkL2t2dz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURXakNDQWtLZ0F3SUJBZ0lVSk9taGNTTHR6LzVRU2tvcitaOFpvOWVocnlNd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0x6RVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkpibU11TVJZd0ZBWURWUVFEREEwcUxtVjRZVzF3YkdVdQpZMjl0TUI0WERUSTFNVEl3TlRBNE1EWXdNMW9YRFRNMU1USXdNekE0TURZd00xb3dMekVWTUJNR0ExVUVDZ3dNClpYaGhiWEJzWlNCSmJtTXVNUll3RkFZRFZRUUREQTBxTG1WNFlXMXdiR1V1WTI5dE1JSUJJakFOQmdrcWhraUcKOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQTU3SmJNZ3BsQVpYOWZEaDV1Z2lSUmw4WEMyUUx5NGEyUm1QZwpoUzJhVEp4NGx3ak9GLzlNVmhHeW9NQzIwc01QQkF4eUwza3lFWTk2QUpwSXJjSkwwQlcwUlVVY2dpVW5QYkM2CkV0M0lUcVNjalZOYlJmczcvb2Fmd1U4L3hCZEtZOVJTTGRGN0IrMFZSMDJZZElFdTNtNThEcld1VGJsd0oyMmcKWXg2cmtYd0ZUa0lQbmR3U0RuWHNiSHdhT0VzaXh2RTdaVy92SnJqWEp6V016MUpnSnVlZ1BDWEpaMUtySHU0dQpRbU1HTW9rSDZ3ZWpUQ2plN0ZkQm84ODZ1QTZjbDdOWG85WDR4UVl5VXFsVDl6WnhLU2RvbXBaZjYzUFUrYmVBCmlJemR6aXhFeDdFTGdDc3hsQVBkUVErdnZKMEJyY1lVd3g3QlYxYjdTSExVWHBuVml3SURBUUFCbzI0d2JEQkwKQmdOVkhSRUVSREJDZ2cwcUxtVjRZVzF3YkdVdVkyOXRnZzltYjI4dVpYaGhiWEJzWlM1amIyMkNEMkpoY2k1bAplR0Z0Y0d4bExtTnZiWUlQWW1GNkxtVjRZVzF3YkdVdVkyOXRNQjBHQTFVZERnUVdCQlFLbWNMbHFOVjlJei9DCnZZYWFhLzVaTkxESFJUQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFEZExaRHFQdllYc0d6YjFyektjY1pQV1IKNFMxYS9rNEl4Nk1yaExaRFc4YmdiL3hNalpqeHVMRVJGNk9YYlViazhuOFdaeWhpalY5SXZ2alZ2K1pGRVc4VQpnNjJnaWlyREFnVXp6SUc2RkdLejRvU2l5dmpGMnhUdURNY1J1Y0U5OFE4dnNUV0c1TU51L0lsdTlnbzg4Q3dwCkdNMlc0clRoVG05U3dBWi9XNE9NNlRpNHdBUldzUHJ5am5QZlIralQzUUVBcXJHMWNoZ3BKU29qSmhlK3p0RW4KaURkNmdMSFhKUUN5WnNJRklsRFdWVzdmVUEvNHNpUFB1dGxmc3JjY3gweW43WlVkU0k1ZkVzWm9jUkJBSFN3WgpIUFVwTlBoMno1ajZEOUNDVG5jQTVNbXRHNCtjdjNtMyt3eHFseUozWFhrSGd3SUtwWkNjbFNyVXRkL2t2dz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K +kind: Secret +metadata: + name: tls-termination-certificate + namespace: envoy-gateway-system +type: kubernetes.io/tls diff --git a/test/e2e/tests/sds.go b/test/e2e/tests/sds.go new file mode 100644 index 0000000000..b45782c970 --- /dev/null +++ b/test/e2e/tests/sds.go @@ -0,0 +1,160 @@ +// Copyright Envoy Gateway Authors +// SPDX-License-Identifier: Apache-2.0 +// The full text of the Apache license is available in the LICENSE file at +// the root of the repo. + +//go:build e2e + +package tests + +import ( + "bytes" + "crypto/tls" + "crypto/x509" + "encoding/pem" + "net" + "testing" + "time" + + "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" + "sigs.k8s.io/gateway-api/conformance/utils/http" + "sigs.k8s.io/gateway-api/conformance/utils/kubernetes" + "sigs.k8s.io/gateway-api/conformance/utils/suite" + tlsutils "sigs.k8s.io/gateway-api/conformance/utils/tls" +) + +func init() { + ConformanceTests = append(ConformanceTests, SDS) +} + +var SDS = suite.ConformanceTest{ + ShortName: "SDS", + Description: "Test SDS server providing secrets to Envoy, for both backend TLS policy client certificates and HTTPS listener certificates", + Manifests: []string{ + "testdata/sds.yaml", + "testdata/sds-listener-certificate.yaml", + }, + Test: func(t *testing.T, suite *suite.ConformanceTestSuite) { + t.Run("backend TLS policy client certificate", func(t *testing.T) { + ns := "gateway-conformance-infra" + acceptedCond := metav1.Condition{ + Type: string(gwapiv1.PolicyConditionAccepted), + Status: metav1.ConditionTrue, + Reason: string(gwapiv1.PolicyReasonAccepted), + } + resolvedRefsCond := metav1.Condition{ + Type: string(gwapiv1.BackendTLSPolicyConditionResolvedRefs), + Status: metav1.ConditionTrue, + Reason: string(gwapiv1.BackendTLSPolicyReasonResolvedRefs), + } + + routeNN := types.NamespacedName{Name: "sds-route", Namespace: ns} + gwNN := types.NamespacedName{Name: "sds-gateway", Namespace: ns} + validPolicyNN := types.NamespacedName{Name: "tls-backend-policy", Namespace: ns} + kubernetes.BackendTLSPolicyMustHaveCondition(t, suite.Client, suite.TimeoutConfig, validPolicyNN, gwNN, acceptedCond) + kubernetes.BackendTLSPolicyMustHaveCondition(t, suite.Client, suite.TimeoutConfig, validPolicyNN, gwNN, resolvedRefsCond) + gwAddr := GatewayAndTCPRoutesMustBeAccepted(t, suite.Client, &suite.TimeoutConfig, suite.ControllerName, NewGatewayRef(gwNN), routeNN) + + http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, http.ExpectedResponse{ + Request: http.Request{ + Path: "/", + }, + Response: http.Response{ + StatusCodes: []int{200}, + }, + Namespace: ns, + }) + }) + + t.Run("HTTPS listener certificate", func(t *testing.T) { + const ( + namespace = "gateway-conformance-infra" + serverName = "sds.example.com" + ) + gatewayName := types.NamespacedName{Name: "sds-listener-certificate", Namespace: namespace} + routeName := types.NamespacedName{Name: "sds-listener-certificate", Namespace: namespace} + + // Given an accepted HTTPS Gateway whose certificate reference is backed by SDS. + gatewayHost := kubernetes.GatewayAndRoutesMustBeAccepted( + t, + suite.Client, + suite.TimeoutConfig, + suite.ControllerName, + kubernetes.NewGatewayRef(gatewayName), + &gwapiv1.HTTPRoute{}, + false, + routeName, + ) + certificatePEM, _, _, err := GetTLSSecret( + suite.Client, + types.NamespacedName{Name: "sds-listener-certificate-source", Namespace: namespace}, + ) + require.NoError(t, err) + gwPodNamespace := GetGatewayResourceNamespace() + WaitForPods( + t, + suite.Client, + gwPodNamespace, + map[string]string{ + "gateway.envoyproxy.io/owning-gateway-name": gatewayName.Name, + "gateway.envoyproxy.io/owning-gateway-namespace": gatewayName.Namespace, + }, + corev1.PodRunning, + &PodReady, + ) + + // When traffic is sent through the SDS-backed HTTPS listener. + expected := http.ExpectedResponse{ + Request: http.Request{Host: serverName, Path: "/sds-listener"}, + Response: http.Response{ + StatusCodes: []int{200}, + }, + Namespace: namespace, + } + tlsutils.MakeTLSRequestAndExpectEventuallyConsistentResponse( + t, + suite.RoundTripper, + suite.TimeoutConfig, + gatewayHost, + certificatePEM, + nil, + nil, + serverName, + expected, + ) + + // Then Envoy presents the exact certificate delivered by the SDS server. + expectedCertificate := parseCertificate(t, certificatePEM) + rootCAs := x509.NewCertPool() + require.True(t, rootCAs.AppendCertsFromPEM(certificatePEM)) + tlsConfig := &tls.Config{ + MinVersion: tls.VersionTLS12, + RootCAs: rootCAs, + ServerName: serverName, + } + connection, err := tls.DialWithDialer( + &net.Dialer{Timeout: 10 * time.Second}, + "tcp", + net.JoinHostPort(gatewayHost, "443"), + tlsConfig, + ) + require.NoError(t, err) + t.Cleanup(func() { require.NoError(t, connection.Close()) }) + require.NotEmpty(t, connection.ConnectionState().PeerCertificates) + require.True(t, bytes.Equal(expectedCertificate.Raw, connection.ConnectionState().PeerCertificates[0].Raw)) + }) + }, +} + +func parseCertificate(t *testing.T, certificatePEM []byte) *x509.Certificate { + t.Helper() + block, _ := pem.Decode(certificatePEM) + require.NotNil(t, block) + certificate, err := x509.ParseCertificate(block.Bytes) + require.NoError(t, err) + return certificate +} diff --git a/test/e2e/tests/sds_listener_certificate.go b/test/e2e/tests/sds_listener_certificate.go deleted file mode 100644 index 0ae15627c6..0000000000 --- a/test/e2e/tests/sds_listener_certificate.go +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright Envoy Gateway Authors -// SPDX-License-Identifier: Apache-2.0 -// The full text of the Apache license is available in the LICENSE file at -// the root of the repo. - -//go:build e2e - -package tests - -import ( - "bytes" - "crypto/tls" - "crypto/x509" - "encoding/pem" - "net" - "testing" - "time" - - "github.com/stretchr/testify/require" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" - "sigs.k8s.io/gateway-api/conformance/utils/http" - "sigs.k8s.io/gateway-api/conformance/utils/kubernetes" - "sigs.k8s.io/gateway-api/conformance/utils/suite" - tlsutils "sigs.k8s.io/gateway-api/conformance/utils/tls" -) - -func init() { - ConformanceTests = append(ConformanceTests, SDSListenerCertificateTest) -} - -var SDSListenerCertificateTest = suite.ConformanceTest{ - ShortName: "SDSListenerCertificate", - Description: "Use an SDS-backed Secret for HTTPS listener certificate delivery", - Manifests: []string{"testdata/sds-listener-certificate.yaml"}, - Test: func(t *testing.T, suite *suite.ConformanceTestSuite) { - const ( - namespace = "gateway-conformance-infra" - serverName = "sds.example.com" - ) - gatewayName := types.NamespacedName{Name: "sds-listener-certificate", Namespace: namespace} - routeName := types.NamespacedName{Name: "sds-listener-certificate", Namespace: namespace} - - // Given an accepted HTTPS Gateway whose certificate reference is backed by SDS. - gatewayHost := kubernetes.GatewayAndRoutesMustBeAccepted( - t, - suite.Client, - suite.TimeoutConfig, - suite.ControllerName, - kubernetes.NewGatewayRef(gatewayName), - &gwapiv1.HTTPRoute{}, - false, - routeName, - ) - certificatePEM, _, _, err := GetTLSSecret( - suite.Client, - types.NamespacedName{Name: "sds-listener-certificate-source", Namespace: namespace}, - ) - require.NoError(t, err) - gwPodNamespace := GetGatewayResourceNamespace() - WaitForPods( - t, - suite.Client, - gwPodNamespace, - map[string]string{ - "gateway.envoyproxy.io/owning-gateway-name": gatewayName.Name, - "gateway.envoyproxy.io/owning-gateway-namespace": gatewayName.Namespace, - }, - corev1.PodRunning, - &PodReady, - ) - - // When traffic is sent through the SDS-backed HTTPS listener. - expected := http.ExpectedResponse{ - Request: http.Request{Host: serverName, Path: "/sds-listener"}, - Response: http.Response{ - StatusCodes: []int{200}, - }, - Namespace: namespace, - } - tlsutils.MakeTLSRequestAndExpectEventuallyConsistentResponse( - t, - suite.RoundTripper, - suite.TimeoutConfig, - gatewayHost, - certificatePEM, - nil, - nil, - serverName, - expected, - ) - - // Then Envoy presents the exact certificate delivered by the SDS server. - expectedCertificate := parseCertificate(t, certificatePEM) - rootCAs := x509.NewCertPool() - require.True(t, rootCAs.AppendCertsFromPEM(certificatePEM)) - tlsConfig := &tls.Config{ - MinVersion: tls.VersionTLS12, - RootCAs: rootCAs, - ServerName: serverName, - } - connection, err := tls.DialWithDialer( - &net.Dialer{Timeout: 10 * time.Second}, - "tcp", - net.JoinHostPort(gatewayHost, "443"), - tlsConfig, - ) - require.NoError(t, err) - t.Cleanup(func() { require.NoError(t, connection.Close()) }) - require.NotEmpty(t, connection.ConnectionState().PeerCertificates) - require.True(t, bytes.Equal(expectedCertificate.Raw, connection.ConnectionState().PeerCertificates[0].Raw)) - }, -} - -func parseCertificate(t *testing.T, certificatePEM []byte) *x509.Certificate { - t.Helper() - block, _ := pem.Decode(certificatePEM) - require.NotNil(t, block) - certificate, err := x509.ParseCertificate(block.Bytes) - require.NoError(t, err) - return certificate -} diff --git a/tools/make/examples.mk b/tools/make/examples.mk index f7b8708a94..eb451cd965 100644 --- a/tools/make/examples.mk +++ b/tools/make/examples.mk @@ -1,4 +1,14 @@ -EXAMPLE_APPS := simple-extension-server extension-server envoy-ext-auth grpc-ext-proc preserve-case-backend static-file-server dynamic-module-test backend-utilization remote-infra sds-test-server +EXAMPLE_APPS := \ + simple-extension-server \ + extension-server \ + envoy-ext-auth \ + grpc-ext-proc \ + preserve-case-backend \ + static-file-server \ + dynamic-module-test \ + backend-utilization \ + sds-test-server + EXAMPLE_IMAGE_PREFIX ?= envoyproxy/gateway- EXAMPLE_TAG ?= latest