From 70866622dd978979b5c069e0b9f138346b52ce3d Mon Sep 17 00:00:00 2001 From: Laurent Luce Date: Mon, 11 Dec 2023 16:03:01 -0500 Subject: [PATCH] feat: Docker Traefik routing based on host header (#1921) ## Description: Docker Traefik is currently configured to route traffic based on three custom headers: enclave short uuid, service short uuid and port number. This type of routing rule is not possible with the K8S Ingress provider so we are switching to use the single Host header instead with the format: `--`. ## Is this change user facing? NO ## References (if applicable): #1906 --- .circleci/config.yml | 4 ++-- .../enclave_object_attributes_provider.go | 14 +++++--------- .../enclave_object_attributes_provider_test.go | 2 +- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d53f12c984..3b47e1c7c0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -962,7 +962,7 @@ jobs: service_uuid=$(${KURTOSIS_BINPATH} enclave inspect test-enclave | tail -2 | awk '{print $1}') # Give the reverse proxy enough time to discover the httpd user service sleep 10 - status_code=$(curl -I http://localhost:<< pipeline.parameters.reverse-proxy-entrypoint-web-port >> -H "X-Kurtosis-Enclave-Short-UUID: $(echo $enclave_uuid)" -H "X-Kurtosis-Service-Short-UUID: $(echo $service_uuid)" -H "X-Kurtosis-Service-Port-Number: 80"| head -1 | awk '{print $2}') + status_code=$(curl -I http://localhost:<< pipeline.parameters.reverse-proxy-entrypoint-web-port >> -H "Host: 80-$(echo $service_uuid)-$(echo $enclave_uuid)" | head -1 | awk '{print $2}') if ! [ "${status_code}" -eq "200" ]; then echo 'HTTP request status code returned is '${status_code}' instead of 200' false @@ -975,7 +975,7 @@ jobs: service_uuid=$(${KURTOSIS_BINPATH} enclave inspect test-enclave | tail -2 | awk '{print $1}') # Give the reverse proxy enough time to discover the httpd user service sleep 10 - status_code=$(curl -I http://localhost:<< pipeline.parameters.reverse-proxy-entrypoint-web-port >> -H "X-Kurtosis-Enclave-Short-UUID: $(echo $enclave_uuid)" -H "X-Kurtosis-Service-Short-UUID: $(echo $service_uuid)" -H "X-Kurtosis-Service-Port-Number: 80"| head -1 | awk '{print $2}') + status_code=$(curl -I http://localhost:<< pipeline.parameters.reverse-proxy-entrypoint-web-port >> -H "Host: 80-$(echo $service_uuid)-$(echo $enclave_uuid)" | head -1 | awk '{print $2}') if ! [ "${status_code}" -eq "200" ]; then echo 'HTTP request status code returned is '${status_code}' instead of 200' false diff --git a/container-engine-lib/lib/backend_impls/docker/object_attributes_provider/enclave_object_attributes_provider.go b/container-engine-lib/lib/backend_impls/docker/object_attributes_provider/enclave_object_attributes_provider.go index a36dc7cd7a..c6840ef219 100644 --- a/container-engine-lib/lib/backend_impls/docker/object_attributes_provider/enclave_object_attributes_provider.go +++ b/container-engine-lib/lib/backend_impls/docker/object_attributes_provider/enclave_object_attributes_provider.go @@ -33,10 +33,6 @@ const ( logsCollectorFragment = "kurtosis-logs-collector" // The collector is per enclave so this is a suffix logsCollectorVolumeFragment = logsCollectorFragment + "-vol" - - reverseProxyEnclaveShortUuidHeader = "X-Kurtosis-Enclave-Short-UUID" - reverseProxyServiceShortUuidHeader = "X-Kurtosis-Service-Short-UUID" - reverseProxyServicePortNumberHeader = "X-Kurtosis-Service-Port-Number" ) type DockerEnclaveObjectAttributesProvider interface { @@ -533,7 +529,7 @@ func (provider *dockerEnclaveObjectAttributesProviderImpl) getLabelsForEnclaveOb } // Return Traefik labels -// Including the labels required to route traffic to the user service ports based on the header X-Kurtosis-Service-Port: +// Including the labels required to route traffic to the user service ports based on the Host header: // -- // The Traefik service name format is: -- // With the following input: @@ -546,10 +542,10 @@ func (provider *dockerEnclaveObjectAttributesProviderImpl) getLabelsForEnclaveOb // the following labels are returned: // // "traefik.enable": "true", -// "traefik.http.routers.65d2fb6d6732-3771c85af16a-80.rule": "Headers(`X-Kurtosis-Enclave-Short-UUID`, `65d2fb6d6732`) && Headers(`X-Kurtosis-Service-Short-UUID`, `3771c85af16a`) && Headers(`X-Kurtosis-Port-Number`, `80`)", +// "traefik.http.routers.65d2fb6d6732-3771c85af16a-80.rule": "Host(`80-3771c85af16a-65d2fb6d6732`)", // "traefik.http.routers.65d2fb6d6732-3771c85af16a-80.service": "65d2fb6d6732-3771c85af16a-80", // "traefik.http.services.65d2fb6d6732-3771c85af16a-80.loadbalancer.server.port": "80" -// "traefik.http.routers.65d2fb6d6732-3771c85af16a-81.rule": "Headers(`X-Kurtosis-Enclave-Short-UUID`, `65d2fb6d6732`) && Headers(`X-Kurtosis-Service-Short-UUID`, `3771c85af16a`) && Headers(`X-Kurtosis-Port-Number`, `81`)", +// "traefik.http.routers.65d2fb6d6732-3771c85af16a-80.rule": "Host(`81-3771c85af16a-65d2fb6d6732`)", // "traefik.http.routers.65d2fb6d6732-3771c85af16a-81.service": "65d2fb6d6732-3771c85af16a-81", // "traefik.http.services.65d2fb6d6732-3771c85af16a-81.loadbalancer.server.port": "81" func (provider *dockerEnclaveObjectAttributesProviderImpl) getTraefikLabelsForEnclaveObject(serviceUuid string, ports map[string]*port_spec.PortSpec) (map[*docker_label_key.DockerLabelKey]*docker_label_value.DockerLabelValue, error) { @@ -565,13 +561,13 @@ func (provider *dockerEnclaveObjectAttributesProviderImpl) getTraefikLabelsForEn shortServiceUuid := uuid_generator.ShortenedUUIDString(serviceUuid) servicePortStr := fmt.Sprintf("%s-%s-%d", shortEnclaveUuid, shortServiceUuid, portSpec.GetNumber()) - // Header X-Kurtosis-Service-Port rule + // Header Host rule ruleKeySuffix := fmt.Sprintf("http.routers.%s.rule", servicePortStr) ruleLabelKey, err := docker_label_key.CreateNewDockerTraefikLabelKey(ruleKeySuffix) if err != nil { return nil, stacktrace.Propagate(err, "An error occurred getting the traefik rule label key with suffix '%v'", ruleKeySuffix) } - ruleValue := fmt.Sprintf("Headers(`%s`, `%s`) && Headers(`%s`, `%s`) && Headers(`%s`, `%d`)", reverseProxyEnclaveShortUuidHeader, shortEnclaveUuid, reverseProxyServiceShortUuidHeader, shortServiceUuid, reverseProxyServicePortNumberHeader, portSpec.GetNumber()) + ruleValue := fmt.Sprintf("Host(`%d-%s-%s`)", portSpec.GetNumber(), shortServiceUuid, shortEnclaveUuid) ruleLabelValue, err := docker_label_value.CreateNewDockerLabelValue(ruleValue) if err != nil { return nil, stacktrace.Propagate(err, "An error occurred creating the traefik rule label value with value '%v'", ruleValue) diff --git a/container-engine-lib/lib/backend_impls/docker/object_attributes_provider/enclave_object_attributes_provider_test.go b/container-engine-lib/lib/backend_impls/docker/object_attributes_provider/enclave_object_attributes_provider_test.go index 64d3cf4678..1b91923413 100644 --- a/container-engine-lib/lib/backend_impls/docker/object_attributes_provider/enclave_object_attributes_provider_test.go +++ b/container-engine-lib/lib/backend_impls/docker/object_attributes_provider/enclave_object_attributes_provider_test.go @@ -68,7 +68,7 @@ func TestForUserServiceContainer(t *testing.T) { case "traefik.http.routers.65d2fb6d6732-3771c85af16a-23.rule": require.Fail(t, "A traefik label for port 23 should not be present") case "traefik.http.routers.65d2fb6d6732-3771c85af16a-45.rule": - require.Equal(t, labelValue.GetString(), "Headers(`X-Kurtosis-Enclave-Short-UUID`, `65d2fb6d6732`) && Headers(`X-Kurtosis-Service-Short-UUID`, `3771c85af16a`) && Headers(`X-Kurtosis-Service-Port-Number`, `45`)") + require.Equal(t, labelValue.GetString(), "Host(`45-3771c85af16a-65d2fb6d6732`)") case "traefik.http.routers.65d2fb6d6732-3771c85af16a-45.service": require.Equal(t, labelValue.GetString(), "65d2fb6d6732-3771c85af16a-45") case "traefik.http.services.65d2fb6d6732-3771c85af16a-45.loadbalancer.server.port":