diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index e15a2cd2b..07770e47c 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -37,7 +37,7 @@ This questions are the first thing we need to know to understand the context. -**NGINX Ingress controller version** (exec into the pod and run nginx-ingress-controller --version.): +**NGINX Ingress controller version** (exec into the pod and run `/nginx-ingress-controller --version`): |name: nginx| sb - sb --> |hello nginx!| sa - end - - subgraph otel - otc["Otel Collector"] - end - - subgraph observability - tempo["Tempo"] - grafana["Grafana"] - backend["Jaeger"] - zipkin["Zipkin"] - end - - subgraph ingress-nginx - ngx[nginx] - end - - subgraph ngx[nginx] - ng[nginx] - om[OpenTelemetry module] - end - - subgraph Node - app - otel - observability - ingress-nginx - om --> |otlp-gRPC| otc --> |jaeger| backend - otc --> |zipkin| zipkin - otc --> |otlp-gRPC| tempo --> grafana - sa --> |otlp-gRPC| otc - sb --> |otlp-gRPC| otc - start --> ng --> sa - end -``` - -To install the example and collectors run: - -1. Enable Ingress addon with: - - ```yaml - opentelemetry: - enabled: true - image: registry.k8s.io/ingress-nginx/opentelemetry-1.25.3:v20240813-b933310d@sha256:f7604ac0547ed64d79b98d92133234e66c2c8aade3c1f4809fed5eec1fb7f922 - containerSecurityContext: - allowPrivilegeEscalation: false - ``` - -2. Enable OpenTelemetry and set the otlp-collector-host: - - ```yaml - $ echo ' - apiVersion: v1 - kind: ConfigMap - data: - enable-opentelemetry: "true" - opentelemetry-config: "/etc/nginx/opentelemetry.toml" - opentelemetry-operation-name: "HTTP $request_method $service_name $uri" - opentelemetry-trust-incoming-span: "true" - otlp-collector-host: "otel-coll-collector.otel.svc" - otlp-collector-port: "4317" - otel-max-queuesize: "2048" - otel-schedule-delay-millis: "5000" - otel-max-export-batch-size: "512" - otel-service-name: "nginx-proxy" # Opentelemetry resource name - otel-sampler: "AlwaysOn" # Also: AlwaysOff, TraceIdRatioBased - otel-sampler-ratio: "1.0" - otel-sampler-parent-based: "false" - metadata: - name: ingress-nginx-controller - namespace: ingress-nginx - ' | kubectl replace -f - - ``` - -4. Deploy otel-collector, grafana and Jaeger backend: - - ```bash - # add helm charts needed for grafana and OpenTelemetry collector - helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts - helm repo add grafana https://grafana.github.io/helm-charts - helm repo update - # deply cert-manager needed for OpenTelemetry collector operator - kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.9.1/cert-manager.yaml - # create observability namespace - kubectl apply -f https://raw.githubusercontent.com/esigo/nginx-example/main/observability/namespace.yaml - # install OpenTelemetry collector operator - helm upgrade --install otel-collector-operator -n otel --create-namespace open-telemetry/opentelemetry-operator - # deploy OpenTelemetry collector - kubectl apply -f https://raw.githubusercontent.com/esigo/nginx-example/main/observability/collector.yaml - # deploy Jaeger all-in-one - kubectl apply -f https://github.com/jaegertracing/jaeger-operator/releases/download/v1.37.0/jaeger-operator.yaml -n observability - kubectl apply -f https://raw.githubusercontent.com/esigo/nginx-example/main/observability/jaeger.yaml -n observability - # deploy zipkin - kubectl apply -f https://raw.githubusercontent.com/esigo/nginx-example/main/observability/zipkin.yaml -n observability - # deploy tempo and grafana - helm upgrade --install tempo grafana/tempo --create-namespace -n observability - helm upgrade -f https://raw.githubusercontent.com/esigo/nginx-example/main/observability/grafana/grafana-values.yaml --install grafana grafana/grafana --create-namespace -n observability - ``` - -3. Build and deploy demo app: - - ```bash - # build images - make images - - # deploy demo app: - make deploy-app - ``` - -5. Make a few requests to the Service: - - ```bash - kubectl port-forward --namespace=ingress-nginx service/ingress-nginx-controller 8090:80 - curl http://esigo.dev:8090/hello/nginx - - - StatusCode : 200 - StatusDescription : OK - Content : {"v":"hello nginx!"} - - RawContent : HTTP/1.1 200 OK - Connection: keep-alive - Content-Length: 21 - Content-Type: text/plain; charset=utf-8 - Date: Mon, 10 Oct 2022 17:43:33 GMT - - {"v":"hello nginx!"} - - Forms : {} - Headers : {[Connection, keep-alive], [Content-Length, 21], [Content-Type, text/plain; charset=utf-8], [Date, - Mon, 10 Oct 2022 17:43:33 GMT]} - Images : {} - InputFields : {} - Links : {} - ParsedHtml : System.__ComObject - RawContentLength : 21 - ``` - -6. View the Grafana UI: - - ```bash - kubectl port-forward --namespace=observability service/grafana 3000:80 - ``` - In the Grafana interface we can see the details: - ![grafana screenshot](../../images/otel-grafana-demo.png "grafana screenshot") - -7. View the Jaeger UI: - - ```bash - kubectl port-forward --namespace=observability service/jaeger-all-in-one-query 16686:16686 - ``` - In the Jaeger interface we can see the details: - ![Jaeger screenshot](../../images/otel-jaeger-demo.png "Jaeger screenshot") - -8. View the Zipkin UI: - - ```bash - kubectl port-forward --namespace=observability service/zipkin 9411:9411 - ``` - In the Zipkin interface we can see the details: - ![zipkin screenshot](../../images/otel-zipkin-demo.png "zipkin screenshot") - -## Migration from OpenTracing, Jaeger, Zipkin and Datadog - -If you are migrating from OpenTracing, Jaeger, Zipkin, or Datadog to OpenTelemetry, -you may need to update various annotations and configurations. Here are the mappings -for common annotations and configurations: - -### Annotations - -| Legacy | OpenTelemetry | -|---------------------------------------------------------------|-----------------------------------------------------------------| -| `nginx.ingress.kubernetes.io/enable-opentracing` | `nginx.ingress.kubernetes.io/enable-opentelemetry` | -| `nginx.ingress.kubernetes.io/opentracing-trust-incoming-span` | `nginx.ingress.kubernetes.io/opentelemetry-trust-incoming-span` | - -### Configs - -| Legacy | OpenTelemetry | -|---------------------------------------|----------------------------------------------| -| `opentracing-operation-name` | `opentelemetry-operation-name` | -| `opentracing-location-operation-name` | `opentelemetry-operation-name` | -| `opentracing-trust-incoming-span` | `opentelemetry-trust-incoming-span` | -| `zipkin-collector-port` | `otlp-collector-port` | -| `zipkin-service-name` | `otel-service-name` | -| `zipkin-sample-rate` | `otel-sampler-ratio` | -| `jaeger-collector-port` | `otlp-collector-port` | -| `jaeger-endpoint` | `otlp-collector-port`, `otlp-collector-host` | -| `jaeger-service-name` | `otel-service-name` | -| `jaeger-propagation-format` | `N/A` | -| `jaeger-sampler-type` | `otel-sampler` | -| `jaeger-sampler-param` | `otel-sampler` | -| `jaeger-sampler-host` | `N/A` | -| `jaeger-sampler-port` | `N/A` | -| `jaeger-trace-context-header-name` | `N/A` | -| `jaeger-debug-header` | `N/A` | -| `jaeger-baggage-header` | `N/A` | -| `jaeger-tracer-baggage-header-prefix` | `N/A` | -| `datadog-collector-port` | `otlp-collector-port` | -| `datadog-service-name` | `otel-service-name` | -| `datadog-environment` | `N/A` | -| `datadog-operation-name-override` | `N/A` | -| `datadog-priority-sampling` | `otel-sampler` | -| `datadog-sample-rate` | `otel-sampler-ratio` | +# OpenTelemetry + +Enables requests served by NGINX for distributed telemetry via The OpenTelemetry Project. + +Using the third party module [opentelemetry-cpp-contrib/nginx](https://github.com/open-telemetry/opentelemetry-cpp-contrib/tree/main/instrumentation/nginx) the Ingress-Nginx Controller can configure NGINX to enable [OpenTelemetry](http://opentelemetry.io) instrumentation. +By default this feature is disabled. + +Check out this demo showcasing OpenTelemetry in Ingress NGINX. The video provides an overview and +practical demonstration of how OpenTelemetry can be utilized in Ingress NGINX for observability +and monitoring purposes. + +

+ + Video Thumbnail + +

+ +

Demo: OpenTelemetry in Ingress NGINX.

+ +## Usage + +To enable the instrumentation we must enable OpenTelemetry in the configuration ConfigMap: +```yaml +data: + enable-opentelemetry: "true" +``` + +To enable or disable instrumentation for a single Ingress, use +the `enable-opentelemetry` annotation: +```yaml +kind: Ingress +metadata: + annotations: + nginx.ingress.kubernetes.io/enable-opentelemetry: "true" +``` + +We must also set the host to use when uploading traces: + +```yaml +otlp-collector-host: "otel-coll-collector.otel.svc" +``` +NOTE: While the option is called `otlp-collector-host`, you will need to point this to any backend that receives otlp-grpc. + +Next you will need to deploy a distributed telemetry system which uses OpenTelemetry. +[opentelemetry-collector](https://github.com/open-telemetry/opentelemetry-collector), [Jaeger](https://www.jaegertracing.io/) +[Tempo](https://github.com/grafana/tempo), and [zipkin](https://zipkin.io/) +have been tested. + +Other optional configuration options: +```yaml +# specifies the name to use for the server span +opentelemetry-operation-name + +# sets whether or not to trust incoming telemetry spans +opentelemetry-trust-incoming-span + +# specifies the port to use when uploading traces, Default: 4317 +otlp-collector-port + +# specifies the service name to use for any traces created, Default: nginx +otel-service-name + +# The maximum queue size. After the size is reached data are dropped. +otel-max-queuesize + +# The delay interval in milliseconds between two consecutive exports. +otel-schedule-delay-millis + +# How long the export can run before it is cancelled. +otel-schedule-delay-millis + +# The maximum batch size of every export. It must be smaller or equal to maxQueueSize. +otel-max-export-batch-size + +# specifies sample rate for any traces created, Default: 0.01 +otel-sampler-ratio + +# specifies the sampler to be used when sampling traces. +# The available samplers are: AlwaysOn, AlwaysOff, TraceIdRatioBased, Default: AlwaysOff +otel-sampler + +# Uses sampler implementation which by default will take a sample if parent Activity is sampled, Default: false +otel-sampler-parent-based +``` + +Note that you can also set whether to trust incoming spans (global default is true) per-location using annotations like the following: +```yaml +kind: Ingress +metadata: + annotations: + nginx.ingress.kubernetes.io/opentelemetry-trust-incoming-span: "true" +``` + +## Examples + +The following examples show how to deploy and test different distributed telemetry systems. These example can be performed using Docker Desktop. + +In the [esigo/nginx-example](https://github.com/esigo/nginx-example) +GitHub repository is an example of a simple hello service: + +```mermaid +graph TB + subgraph Browser + start["http://esigo.dev/hello/nginx"] + end + + subgraph app + sa[service-a] + sb[service-b] + sa --> |name: nginx| sb + sb --> |hello nginx!| sa + end + + subgraph otel + otc["Otel Collector"] + end + + subgraph observability + tempo["Tempo"] + grafana["Grafana"] + backend["Jaeger"] + zipkin["Zipkin"] + end + + subgraph ingress-nginx + ngx[nginx] + end + + subgraph ngx[nginx] + ng[nginx] + om[OpenTelemetry module] + end + + subgraph Node + app + otel + observability + ingress-nginx + om --> |otlp-gRPC| otc --> |jaeger| backend + otc --> |zipkin| zipkin + otc --> |otlp-gRPC| tempo --> grafana + sa --> |otlp-gRPC| otc + sb --> |otlp-gRPC| otc + start --> ng --> sa + end +``` + +To install the example and collectors run: + +1. Enable OpenTelemetry and set the otlp-collector-host: + + ```yaml + $ echo ' + apiVersion: v1 + kind: ConfigMap + data: + enable-opentelemetry: "true" + opentelemetry-config: "/etc/nginx/opentelemetry.toml" + opentelemetry-operation-name: "HTTP $request_method $service_name $uri" + opentelemetry-trust-incoming-span: "true" + otlp-collector-host: "otel-coll-collector.otel.svc" + otlp-collector-port: "4317" + otel-max-queuesize: "2048" + otel-schedule-delay-millis: "5000" + otel-max-export-batch-size: "512" + otel-service-name: "nginx-proxy" # Opentelemetry resource name + otel-sampler: "AlwaysOn" # Also: AlwaysOff, TraceIdRatioBased + otel-sampler-ratio: "1.0" + otel-sampler-parent-based: "false" + metadata: + name: ingress-nginx-controller + namespace: ingress-nginx + ' | kubectl replace -f - + ``` + +2. Deploy otel-collector, grafana and Jaeger backend: + + ```bash + # add helm charts needed for grafana and OpenTelemetry collector + helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts + helm repo add grafana https://grafana.github.io/helm-charts + helm repo update + # deploy cert-manager needed for OpenTelemetry collector operator + kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.15.3/cert-manager.yaml + # create observability namespace + kubectl apply -f https://raw.githubusercontent.com/esigo/nginx-example/main/observability/namespace.yaml + # install OpenTelemetry collector operator + helm upgrade --install otel-collector-operator -n otel --create-namespace open-telemetry/opentelemetry-operator + # deploy OpenTelemetry collector + kubectl apply -f https://raw.githubusercontent.com/esigo/nginx-example/main/observability/collector.yaml + # deploy Jaeger all-in-one + kubectl apply -f https://github.com/jaegertracing/jaeger-operator/releases/download/v1.37.0/jaeger-operator.yaml -n observability + kubectl apply -f https://raw.githubusercontent.com/esigo/nginx-example/main/observability/jaeger.yaml -n observability + # deploy zipkin + kubectl apply -f https://raw.githubusercontent.com/esigo/nginx-example/main/observability/zipkin.yaml -n observability + # deploy tempo and grafana + helm upgrade --install tempo grafana/tempo --create-namespace -n observability + helm upgrade -f https://raw.githubusercontent.com/esigo/nginx-example/main/observability/grafana/grafana-values.yaml --install grafana grafana/grafana --create-namespace -n observability + ``` + +3. Build and deploy demo app: + + ```bash + # build images + make images + + # deploy demo app: + make deploy-app + ``` + +4. Make a few requests to the Service: + + ```bash + kubectl port-forward --namespace=ingress-nginx service/ingress-nginx-controller 8090:80 + curl http://esigo.dev:8090/hello/nginx + + + StatusCode : 200 + StatusDescription : OK + Content : {"v":"hello nginx!"} + + RawContent : HTTP/1.1 200 OK + Connection: keep-alive + Content-Length: 21 + Content-Type: text/plain; charset=utf-8 + Date: Mon, 10 Oct 2022 17:43:33 GMT + + {"v":"hello nginx!"} + + Forms : {} + Headers : {[Connection, keep-alive], [Content-Length, 21], [Content-Type, text/plain; charset=utf-8], [Date, + Mon, 10 Oct 2022 17:43:33 GMT]} + Images : {} + InputFields : {} + Links : {} + ParsedHtml : System.__ComObject + RawContentLength : 21 + ``` + +5. View the Grafana UI: + + ```bash + kubectl port-forward --namespace=observability service/grafana 3000:80 + ``` + In the Grafana interface we can see the details: + ![grafana screenshot](../../images/otel-grafana-demo.png "grafana screenshot") + +6. View the Jaeger UI: + + ```bash + kubectl port-forward --namespace=observability service/jaeger-all-in-one-query 16686:16686 + ``` + In the Jaeger interface we can see the details: + ![Jaeger screenshot](../../images/otel-jaeger-demo.png "Jaeger screenshot") + +7. View the Zipkin UI: + + ```bash + kubectl port-forward --namespace=observability service/zipkin 9411:9411 + ``` + In the Zipkin interface we can see the details: + ![zipkin screenshot](../../images/otel-zipkin-demo.png "zipkin screenshot") + +## Migration from OpenTracing, Jaeger, Zipkin and Datadog + +If you are migrating from OpenTracing, Jaeger, Zipkin, or Datadog to OpenTelemetry, +you may need to update various annotations and configurations. Here are the mappings +for common annotations and configurations: + +### Annotations + +| Legacy | OpenTelemetry | +|---------------------------------------------------------------|-----------------------------------------------------------------| +| `nginx.ingress.kubernetes.io/enable-opentracing` | `nginx.ingress.kubernetes.io/enable-opentelemetry` | +| `nginx.ingress.kubernetes.io/opentracing-trust-incoming-span` | `nginx.ingress.kubernetes.io/opentelemetry-trust-incoming-span` | + +### Configs + +| Legacy | OpenTelemetry | +|---------------------------------------|----------------------------------------------| +| `opentracing-operation-name` | `opentelemetry-operation-name` | +| `opentracing-location-operation-name` | `opentelemetry-operation-name` | +| `opentracing-trust-incoming-span` | `opentelemetry-trust-incoming-span` | +| `zipkin-collector-port` | `otlp-collector-port` | +| `zipkin-service-name` | `otel-service-name` | +| `zipkin-sample-rate` | `otel-sampler-ratio` | +| `jaeger-collector-port` | `otlp-collector-port` | +| `jaeger-endpoint` | `otlp-collector-port`, `otlp-collector-host` | +| `jaeger-service-name` | `otel-service-name` | +| `jaeger-propagation-format` | `N/A` | +| `jaeger-sampler-type` | `otel-sampler` | +| `jaeger-sampler-param` | `otel-sampler` | +| `jaeger-sampler-host` | `N/A` | +| `jaeger-sampler-port` | `N/A` | +| `jaeger-trace-context-header-name` | `N/A` | +| `jaeger-debug-header` | `N/A` | +| `jaeger-baggage-header` | `N/A` | +| `jaeger-tracer-baggage-header-prefix` | `N/A` | +| `datadog-collector-port` | `otlp-collector-port` | +| `datadog-service-name` | `otel-service-name` | +| `datadog-environment` | `N/A` | +| `datadog-operation-name-override` | `N/A` | +| `datadog-priority-sampling` | `otel-sampler` | +| `datadog-sample-rate` | `otel-sampler-ratio` | diff --git a/ginkgo_upgrade.md b/ginkgo_upgrade.md index 57db0f28f..87e6bd9fd 100644 --- a/ginkgo_upgrade.md +++ b/ginkgo_upgrade.md @@ -49,7 +49,7 @@ Promoting the images basically means that images, that were pushed to staging co ``` ... - pushing manifest for gcr.io/k8s-staging-ingress-nginx/controller:v1.0.2@sha256:e15fac6e8474d77e1f017edc33d804ce72a184e3c0a30963b2a0d7f0b89f6b16 + pushing manifest for us-central1-docker.pkg.dev/k8s-staging-images/ingress-nginx/controller:v1.0.2@sha256:e15fac6e8474d77e1f017edc33d804ce72a184e3c0a30963b2a0d7f0b89f6b16 ... ``` @@ -65,11 +65,11 @@ Promoting the images basically means that images, that were pushed to staging co - Create a branch in your fork, named as the issue number for this release -- In the related branch, of your fork, edit the file k8s.gcr.io/images/k8s-staging-ingress-nginx/images.yaml. +- In the related branch, of your fork, edit the file registry.k8s.io/images/k8s-staging-ingress-nginx/images.yaml. - For making it easier, you can edit your branch directly in the browser. But be careful about making any mistake. -- Insert the sha(s) & the tag(s), in a new line, in this file [Project kubernetes/k8s.io Ingress-Nginx-Controller Images](https://github.com/kubernetes/k8s.io/blob/main/k8s.gcr.io/images/k8s-staging-ingress-nginx/images.yaml) Look at this [example PR and the diff](https://github.com/kubernetes/k8s.io/pull/4499) to see how it was done before +- Insert the sha(s) & the tag(s), in a new line, in this file [Project kubernetes/k8s.io Ingress-Nginx-Controller Images](https://github.com/kubernetes/k8s.io/blob/main/registry.k8s.io/images/k8s-staging-ingress-nginx/images.yaml) Look at this [example PR and the diff](https://github.com/kubernetes/k8s.io/pull/4499) to see how it was done before - Save and commit @@ -128,4 +128,4 @@ Promoting the images basically means that images, that were pushed to staging co - Finally merge the PR. -## END ## \ No newline at end of file +## END ## diff --git a/go.mod b/go.mod index a65a3855c..34584bbf9 100644 --- a/go.mod +++ b/go.mod @@ -1,63 +1,74 @@ module k8s.io/ingress-nginx -go 1.22.6 +go 1.23.6 require ( - dario.cat/mergo v1.0.0 + dario.cat/mergo v1.0.1 github.com/armon/go-proxyproto v0.1.0 github.com/eapache/channels v1.1.0 - github.com/fsnotify/fsnotify v1.7.0 + github.com/fsnotify/fsnotify v1.8.0 github.com/json-iterator/go v1.1.12 github.com/kylelemons/godebug v1.1.0 github.com/mitchellh/go-ps v1.0.0 github.com/mitchellh/hashstructure/v2 v2.0.2 github.com/mitchellh/mapstructure v1.5.0 github.com/moul/pb v0.0.0-20220425114252-bca18df4138c - github.com/ncabatoff/process-exporter v0.8.3 - github.com/onsi/ginkgo/v2 v2.20.0 - github.com/opencontainers/runc v1.1.13 - github.com/pmezard/go-difflib v1.0.0 - github.com/prometheus/client_golang v1.19.1 + github.com/ncabatoff/process-exporter v0.8.5 + github.com/onsi/ginkgo/v2 v2.22.2 + github.com/opencontainers/runc v1.2.5 + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 + github.com/prometheus/client_golang v1.20.5 github.com/prometheus/client_model v0.6.1 - github.com/prometheus/common v0.55.0 - github.com/spf13/cobra v1.8.1 - github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.9.0 + github.com/prometheus/common v0.62.0 + github.com/spf13/cobra v1.9.1 + github.com/spf13/pflag v1.0.6 + github.com/stretchr/testify v1.10.0 github.com/yudai/gojsondiff v1.0.0 github.com/zakjan/cert-chain-resolver v0.0.0-20221221105603-fcedb00c5b30 - golang.org/x/crypto v0.26.0 - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 - google.golang.org/grpc v1.65.0 + golang.org/x/crypto v0.33.0 + google.golang.org/grpc v1.70.0 google.golang.org/grpc/examples v0.0.0-20240223204917-5ccf176a08ab gopkg.in/go-playground/pool.v3 v3.1.1 gopkg.in/mcuadros/go-syslog.v2 v2.3.0 - k8s.io/api v0.30.3 - k8s.io/apiextensions-apiserver v0.30.1 - k8s.io/apimachinery v0.30.3 - k8s.io/apiserver v0.30.1 - k8s.io/cli-runtime v0.30.0 - k8s.io/client-go v0.30.3 - k8s.io/code-generator v0.30.1 - k8s.io/component-base v0.30.3 + k8s.io/api v0.32.2 + k8s.io/apiextensions-apiserver v0.32.2 + k8s.io/apimachinery v0.32.2 + k8s.io/apiserver v0.32.2 + k8s.io/cli-runtime v0.32.2 + k8s.io/client-go v0.32.2 + k8s.io/code-generator v0.32.2 + k8s.io/component-base v0.32.2 k8s.io/klog/v2 v2.130.1 pault.ag/go/sniff v0.0.0-20200207005214-cf7e4d167732 - sigs.k8s.io/controller-runtime v0.18.4 - sigs.k8s.io/mdtoc v1.1.0 + sigs.k8s.io/controller-runtime v0.20.2 + sigs.k8s.io/mdtoc v1.4.0 ) require ( + github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be // indirect + github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/klauspost/compress v1.17.9 // indirect + github.com/moby/sys/userns v0.1.0 // indirect + github.com/x448/float16 v0.8.4 // indirect + go.opentelemetry.io/otel v1.32.0 // indirect + go.opentelemetry.io/otel/trace v1.32.0 // indirect + gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect + sigs.k8s.io/release-utils v0.8.3 // indirect +) + +require ( + github.com/Anddd7/pb v0.0.0-20240425032658-369b0f6a404c github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/BurntSushi/toml v1.3.2 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect - github.com/cyphar/filepath-securejoin v0.2.4 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect + github.com/cyphar/filepath-securejoin v0.4.1 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/eapache/queue v1.1.0 // indirect github.com/emicklei/go-restful/v3 v3.12.0 // indirect - github.com/evanphx/json-patch v5.9.0+incompatible // indirect - github.com/evanphx/json-patch/v5 v5.9.0 // indirect + github.com/evanphx/json-patch/v5 v5.9.11 // indirect github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa // indirect github.com/go-errors/errors v1.5.1 // indirect github.com/go-logr/logr v1.4.2 // indirect @@ -67,18 +78,16 @@ require ( github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect - github.com/gomarkdown/markdown v0.0.0-20231222211730-1d6d20845b47 // indirect - github.com/google/btree v1.1.2 // indirect + github.com/gomarkdown/markdown v0.0.0-20240328165702-4d01890c35c0 // indirect + github.com/google/btree v1.1.3 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect + github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect - github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect @@ -103,30 +112,26 @@ require ( github.com/xlab/treeprint v1.2.0 // indirect github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect github.com/yudai/pp v2.0.1+incompatible // indirect - go.starlark.net v0.0.0-20240123142251-f86470692795 // indirect - go.uber.org/zap v1.27.0 // indirect - golang.org/x/mod v0.20.0 // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/oauth2 v0.21.0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/term v0.23.0 // indirect - golang.org/x/text v0.17.0 // indirect - golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.24.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect - google.golang.org/protobuf v1.34.2 // indirect - gopkg.in/evanphx/json-patch.v5 v5.9.0 // indirect + golang.org/x/mod v0.22.0 // indirect + golang.org/x/net v0.33.0 // indirect + golang.org/x/oauth2 v0.24.0 // indirect + golang.org/x/sync v0.11.0 // indirect + golang.org/x/sys v0.30.0 // indirect + golang.org/x/term v0.29.0 // indirect + golang.org/x/text v0.22.0 // indirect + golang.org/x/time v0.7.0 // indirect + golang.org/x/tools v0.28.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a // indirect + google.golang.org/protobuf v1.36.1 // indirect gopkg.in/go-playground/assert.v1 v1.2.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/gengo/v2 v2.0.0-20240404160639-a0386bf69313 // indirect - k8s.io/kube-openapi v0.0.0-20240430033511-f0e62f92d13f // indirect - k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 // indirect - sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/kustomize/api v0.16.0 // indirect - sigs.k8s.io/kustomize/kyaml v0.16.0 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect + k8s.io/gengo/v2 v2.0.0-20240911193312-2b36238f13e9 // indirect + k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect + k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect + sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect + sigs.k8s.io/kustomize/api v0.18.0 // indirect + sigs.k8s.io/kustomize/kyaml v0.18.1 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) diff --git a/go.sum b/go.sum index 197c94cf1..6e933d349 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,9 @@ -dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= -dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= +dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/Anddd7/pb v0.0.0-20240425032658-369b0f6a404c h1:uhBf0CHXi7nCFZXxHV7l1cBcYFEEVRK4FYxvm1l9lKg= +github.com/Anddd7/pb v0.0.0-20240425032658-369b0f6a404c/go.mod h1:vYWKbnXd2KAZHUECLPzSE0Er3FgiEmOdPtxwSIRihck= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/armon/go-proxyproto v0.1.0 h1:TWWcSsjco7o2itn6r25/5AqKBiWmsiuzsUDLT/MTl7k= @@ -13,37 +14,42 @@ github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be h1:J5BL2kskAlV9ckgEsNQXscjIaLiOYiZ75d4e94E6dcQ= +github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be/go.mod h1:mk5IQ+Y0ZeO87b858TlA645sVcEcbiX6YqP98kt+7+w= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= -github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= -github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s= +github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/eapache/channels v1.1.0 h1:F1taHcn7/F0i8DYqKXJnyhJcVpp2kgFcNePxXtnyu4k= github.com/eapache/channels v1.1.0/go.mod h1:jMm2qB5Ubtg9zLd+inMZd2/NUvXgzmWXsDaLyQIGfH0= github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/emicklei/go-restful/v3 v3.12.0 h1:y2DdzBAURM29NFF94q6RaY4vjIH1rtwDapwQtU84iWk= github.com/emicklei/go-restful/v3 v3.12.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls= -github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= -github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= +github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= +github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= +github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/fullsailor/pkcs7 v0.0.0-20160414161337-2585af45975b/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa h1:RDBNVkRviHZtvDvId8XSGPu3rmpmSe+wKRcEWNgsfWU= github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= +github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk= github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= @@ -60,8 +66,6 @@ github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -71,11 +75,10 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/gomarkdown/markdown v0.0.0-20210514010506-3b9f47219fe7/go.mod h1:aii0r/K0ZnHv7G0KF7xy1v0A7s2Ljrb5byB7MO5p6TU= -github.com/gomarkdown/markdown v0.0.0-20231222211730-1d6d20845b47 h1:k4Tw0nt6lwro3Uin8eqoET7MDA4JnT8YgbCjc/g5E3k= -github.com/gomarkdown/markdown v0.0.0-20231222211730-1d6d20845b47/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= -github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= -github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/gomarkdown/markdown v0.0.0-20240328165702-4d01890c35c0 h1:4gjrh/PN2MuWCCElk8/I4OCKRKWCCo2zEct3VKCbibU= +github.com/gomarkdown/markdown v0.0.0-20240328165702-4d01890c35c0/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= +github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= +github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -87,8 +90,8 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= -github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= +github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg= +github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -96,8 +99,6 @@ github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= -github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -106,6 +107,8 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -134,6 +137,8 @@ github.com/mmarkdown/mmark v2.0.40+incompatible h1:vMeUeDzBK3H+/mU0oMVfMuhSXJlIA github.com/mmarkdown/mmark v2.0.40+incompatible/go.mod h1:Uvmoz7tvsWpr7bMVxIpqZPyN3FbOtzDmnsJDFp7ltJs= github.com/moby/sys/mountinfo v0.7.1 h1:/tTvQaSJRr2FshkhXiIpux6fQ2Zvc4j7tAhMTStAG2g= github.com/moby/sys/mountinfo v0.7.1/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= +github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g= +github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28= github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -149,8 +154,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/ncabatoff/go-seq v0.0.0-20180805175032-b08ef85ed833 h1:t4WWQ9I797y7QUgeEjeXnVb+oYuEDQc6gLvrZJTYo94= github.com/ncabatoff/go-seq v0.0.0-20180805175032-b08ef85ed833/go.mod h1:0CznHmXSjMEqs5Tezj/w2emQoM41wzYM9KpDKUHPYag= -github.com/ncabatoff/process-exporter v0.8.3 h1:ZJpzWhRfwdBisIpr2BkitAlUR6dt45hpQn8/AYgToO8= -github.com/ncabatoff/process-exporter v0.8.3/go.mod h1:MxEOWl740VK/hlWycJkq91VrA2mI+U9Bvc1wuyAaxA4= +github.com/ncabatoff/process-exporter v0.8.5 h1:Hk1sflgRWn0Xrh/OsupQLVVCTW01kv0YYrGxu7NvkmM= +github.com/ncabatoff/process-exporter v0.8.5/go.mod h1:IZndG/m2Y++D90y99NhDJfg0SOkpbx/Fl6MlnBr4SC0= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= @@ -158,41 +163,42 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.20.0 h1:PE84V2mHqoT1sglvHc8ZdQtPcwmvvt29WLEEO3xmdZw= -github.com/onsi/ginkgo/v2 v2.20.0/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI= +github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU= +github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= -github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= -github.com/opencontainers/runc v1.1.13 h1:98S2srgG9vw0zWcDpFMn5TRrh8kLxa/5OFUstuUhmRs= -github.com/opencontainers/runc v1.1.13/go.mod h1:R016aXacfp/gwQBYw2FDGa9m+n6atbLWrYY8hNMT/sA= +github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8= +github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY= +github.com/opencontainers/runc v1.2.5 h1:8KAkq3Wrem8bApgOHyhRI/8IeLXIfmZ6Qaw6DNSLnA4= +github.com/opencontainers/runc v1.2.5/go.mod h1:dOQeFo29xZKBNeRBI0B19mJtfHv68YgCTh1X+YphA+4= github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= -github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= +github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= -github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= +github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= +github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= -github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= +github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= +github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= +github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= @@ -201,9 +207,11 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/urfave/cli v1.17.1-0.20160602030128-01a33823596e/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA= @@ -216,42 +224,47 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/zakjan/cert-chain-resolver v0.0.0-20221221105603-fcedb00c5b30 h1:rzHvkiukOVYcf840FqAsHqBMhfLofvQIxWtczkGRklU= github.com/zakjan/cert-chain-resolver v0.0.0-20221221105603-fcedb00c5b30/go.mod h1:/Hzu8ych2oXCs1iNI+MeASyFzWTncQ6nlu/wgqbqC2A= -go.starlark.net v0.0.0-20240123142251-f86470692795 h1:LmbG8Pq7KDGkglKVn8VpZOZj6vb9b8nKEGcg9l03epM= -go.starlark.net v0.0.0-20240123142251-f86470692795/go.mod h1:LcLNIzVOMp4oV+uusnpk+VU+SzXaJakUuBjoCSWH5dM= +go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U= +go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg= +go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M= +go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8= +go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4= +go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU= +go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU= +go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ= +go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM= +go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/dl v0.0.0-20190829154251-82a15e2f2ead/go.mod h1:IUMfjQLJQd4UTqG1Z90tenwKoCX93Gn3MAQJMOSBsDQ= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= +golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= -golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= +golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= -golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= -golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= +golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -266,33 +279,33 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= -golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= +golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= +golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= -golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= +golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8= +golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 h1:Zy9XzmMEflZ/MAaA7vNcoebnRAld7FsPW1EeBB7V0m8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= -google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= -google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a h1:hgh8P4EuoxpsuKMXX/To36nOFD7vixReXgn8lPGnt+o= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= +google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ= +google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw= google.golang.org/grpc/examples v0.0.0-20240223204917-5ccf176a08ab h1:tg8hvIl5RmFBuXlcJMuL0h4Psh1gx5Q5xEMwzBZIzWA= google.golang.org/grpc/examples v0.0.0-20240223204917-5ccf176a08ab/go.mod h1:liVNnGuZDITxuksuZ+BBvdy7FcJfeNk+efF9qgqNUmc= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -301,14 +314,14 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= +google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/evanphx/json-patch.v5 v5.9.0 h1:hx1VU2SGj4F8r9b8GUwJLdc8DNO8sy79ZGui0G05GLo= -gopkg.in/evanphx/json-patch.v5 v5.9.0/go.mod h1:/kvTRh1TVm5wuM6OkHxqXtE/1nUZZpihg29RtuIyfvk= +gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= +gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= @@ -322,50 +335,50 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkep gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.30.3 h1:ImHwK9DCsPA9uoU3rVh4QHAHHK5dTSv1nxJUapx8hoQ= -k8s.io/api v0.30.3/go.mod h1:GPc8jlzoe5JG3pb0KJCSLX5oAFIW3/qNJITlDj8BH04= -k8s.io/apiextensions-apiserver v0.30.1 h1:4fAJZ9985BmpJG6PkoxVRpXv9vmPUOVzl614xarePws= -k8s.io/apiextensions-apiserver v0.30.1/go.mod h1:R4GuSrlhgq43oRY9sF2IToFh7PVlF1JjfWdoG3pixk4= -k8s.io/apimachinery v0.30.3 h1:q1laaWCmrszyQuSQCfNB8cFgCuDAoPszKY4ucAjDwHc= -k8s.io/apimachinery v0.30.3/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= -k8s.io/apiserver v0.30.1 h1:BEWEe8bzS12nMtDKXzCF5Q5ovp6LjjYkSp8qOPk8LZ8= -k8s.io/apiserver v0.30.1/go.mod h1:i87ZnQ+/PGAmSbD/iEKM68bm1D5reX8fO4Ito4B01mo= -k8s.io/cli-runtime v0.30.0 h1:0vn6/XhOvn1RJ2KJOC6IRR2CGqrpT6QQF4+8pYpWQ48= -k8s.io/cli-runtime v0.30.0/go.mod h1:vATpDMATVTMA79sZ0YUCzlMelf6rUjoBzlp+RnoM+cg= -k8s.io/client-go v0.30.3 h1:bHrJu3xQZNXIi8/MoxYtZBBWQQXwy16zqJwloXXfD3k= -k8s.io/client-go v0.30.3/go.mod h1:8d4pf8vYu665/kUbsxWAQ/JDBNWqfFeZnvFiVdmx89U= -k8s.io/code-generator v0.30.1 h1:ZsG++q5Vt0ScmKCeLhynUuWgcwFGg1Hl1AGfatqPJBI= -k8s.io/code-generator v0.30.1/go.mod h1:hFgxRsvOUg79mbpbVKfjJvRhVz1qLoe40yZDJ/hwRH4= -k8s.io/component-base v0.30.3 h1:Ci0UqKWf4oiwy8hr1+E3dsnliKnkMLZMVbWzeorlk7s= -k8s.io/component-base v0.30.3/go.mod h1:C1SshT3rGPCuNtBs14RmVD2xW0EhRSeLvBh7AGk1quA= -k8s.io/gengo/v2 v2.0.0-20240404160639-a0386bf69313 h1:bKcdZJOPICVmIIuaM9+MXmapE94dn5AYv5ODs1jA43o= -k8s.io/gengo/v2 v2.0.0-20240404160639-a0386bf69313/go.mod h1:VH3AT8AaQOqiGjMF9p0/IM1Dj+82ZwjfxUP1IxaHE+8= +k8s.io/api v0.32.2 h1:bZrMLEkgizC24G9eViHGOPbW+aRo9duEISRIJKfdJuw= +k8s.io/api v0.32.2/go.mod h1:hKlhk4x1sJyYnHENsrdCWw31FEmCijNGPJO5WzHiJ6Y= +k8s.io/apiextensions-apiserver v0.32.2 h1:2YMk285jWMk2188V2AERy5yDwBYrjgWYggscghPCvV4= +k8s.io/apiextensions-apiserver v0.32.2/go.mod h1:GPwf8sph7YlJT3H6aKUWtd0E+oyShk/YHWQHf/OOgCA= +k8s.io/apimachinery v0.32.2 h1:yoQBR9ZGkA6Rgmhbp/yuT9/g+4lxtsGYwW6dR6BDPLQ= +k8s.io/apimachinery v0.32.2/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= +k8s.io/apiserver v0.32.2 h1:WzyxAu4mvLkQxwD9hGa4ZfExo3yZZaYzoYvvVDlM6vw= +k8s.io/apiserver v0.32.2/go.mod h1:PEwREHiHNU2oFdte7BjzA1ZyjWjuckORLIK/wLV5goM= +k8s.io/cli-runtime v0.32.2 h1:aKQR4foh9qeyckKRkNXUccP9moxzffyndZAvr+IXMks= +k8s.io/cli-runtime v0.32.2/go.mod h1:a/JpeMztz3xDa7GCyyShcwe55p8pbcCVQxvqZnIwXN8= +k8s.io/client-go v0.32.2 h1:4dYCD4Nz+9RApM2b/3BtVvBHw54QjMFUl1OLcJG5yOA= +k8s.io/client-go v0.32.2/go.mod h1:fpZ4oJXclZ3r2nDOv+Ux3XcJutfrwjKTCHz2H3sww94= +k8s.io/code-generator v0.32.2 h1:CIvyPrLWP7cMgrqval2qYT839YAwCDeSvGfXgWSNpHQ= +k8s.io/code-generator v0.32.2/go.mod h1:plh7bWk7JztAUkHM4zpbdy0KOMdrhsePcZL2HLWFH7Y= +k8s.io/component-base v0.32.2 h1:1aUL5Vdmu7qNo4ZsE+569PV5zFatM9hl+lb3dEea2zU= +k8s.io/component-base v0.32.2/go.mod h1:PXJ61Vx9Lg+P5mS8TLd7bCIr+eMJRQTyXe8KvkrvJq0= +k8s.io/gengo/v2 v2.0.0-20240911193312-2b36238f13e9 h1:si3PfKm8dDYxgfbeA6orqrtLkvvIeH8UqffFJDl0bz4= +k8s.io/gengo/v2 v2.0.0-20240911193312-2b36238f13e9/go.mod h1:EJykeLsmFC60UQbYJezXkEsG2FLrt0GPNkU5iK5GWxU= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20240430033511-f0e62f92d13f h1:0LQagt0gDpKqvIkAMPaRGcXawNMouPECM1+F9BVxEaM= -k8s.io/kube-openapi v0.0.0-20240430033511-f0e62f92d13f/go.mod h1:S9tOR0FxgyusSNR+MboCuiDpVWkAifZvaYI1Q2ubgro= -k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 h1:jgGTlFYnhF1PM1Ax/lAlxUPE+KfCIXHaathvJg1C3ak= -k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJJ4JRdzg3+O6e8I+e+8T5Y= +k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f/go.mod h1:R/HEjbvWI0qdfb8viZUeVZm0X6IZnxAydC7YU42CMw4= +k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro= +k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= pault.ag/go/sniff v0.0.0-20200207005214-cf7e4d167732 h1:SAElp8THCfmBdM+4lmWX5gebiSSkEr7PAYDVF91qpfg= pault.ag/go/sniff v0.0.0-20200207005214-cf7e4d167732/go.mod h1:lpvCfhqEHNJSSpG5R5A2EgsVzG8RTt4RfPoQuRAcDmg= -sigs.k8s.io/controller-runtime v0.18.4 h1:87+guW1zhvuPLh1PHybKdYFLU0YJp4FhJRmiHvm5BZw= -sigs.k8s.io/controller-runtime v0.18.4/go.mod h1:TVoGrfdpbA9VRFaRnKgk9P5/atA0pMwq+f+msb9M8Sg= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/kustomize/api v0.16.0 h1:/zAR4FOQDCkgSDmVzV2uiFbuy9bhu3jEzthrHCuvm1g= -sigs.k8s.io/kustomize/api v0.16.0/go.mod h1:MnFZ7IP2YqVyVwMWoRxPtgl/5hpA+eCCrQR/866cm5c= -sigs.k8s.io/kustomize/kyaml v0.16.0 h1:6J33uKSoATlKZH16unr2XOhDI+otoe2sR3M8PDzW3K0= -sigs.k8s.io/kustomize/kyaml v0.16.0/go.mod h1:xOK/7i+vmE14N2FdFyugIshB8eF6ALpy7jI87Q2nRh4= -sigs.k8s.io/mdtoc v1.1.0 h1:q3YtqYzmC2e0hgLXRIOm7/QLuPux1CX3ZHCwlbABxZo= -sigs.k8s.io/mdtoc v1.1.0/go.mod h1:QZLVEdHH2iNIR4uHAZyvFRtjloHgVItk8lo/mzCtq3w= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= +sigs.k8s.io/controller-runtime v0.20.2 h1:/439OZVxoEc02psi1h4QO3bHzTgu49bb347Xp4gW1pc= +sigs.k8s.io/controller-runtime v0.20.2/go.mod h1:xg2XB0K5ShQzAgsoujxuKN4LNXR2LfwwHsPj7Iaw+XY= +sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8= +sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo= +sigs.k8s.io/kustomize/api v0.18.0 h1:hTzp67k+3NEVInwz5BHyzc9rGxIauoXferXyjv5lWPo= +sigs.k8s.io/kustomize/api v0.18.0/go.mod h1:f8isXnX+8b+SGLHQ6yO4JG1rdkZlvhaCf/uZbLVMb0U= +sigs.k8s.io/kustomize/kyaml v0.18.1 h1:WvBo56Wzw3fjS+7vBjN6TeivvpbW9GmRaWZ9CIVmt4E= +sigs.k8s.io/kustomize/kyaml v0.18.1/go.mod h1:C3L2BFVU1jgcddNBE1TxuVLgS46TjObMwW5FT9FcjYo= +sigs.k8s.io/mdtoc v1.4.0 h1:2pDEwJSjoVrGr5BPkG+LoLkYLKvgtGYurrBY8ul3SxQ= +sigs.k8s.io/mdtoc v1.4.0/go.mod h1:KVnRRtK1rX9aQ95qF0rt3x2ytTxf3r7W7N41H+0KF0k= +sigs.k8s.io/release-utils v0.8.3 h1:KtOtA4qDmzJyeQ2zkDsFVI25+NViwms/o5eL2NftFdA= +sigs.k8s.io/release-utils v0.8.3/go.mod h1:fp82Fma06OXBhEJ+GUJKqvcplDBomruK1R/1fWJnsrQ= +sigs.k8s.io/structured-merge-diff/v4 v4.4.2 h1:MdmvkGuXi/8io6ixD5wud3vOLwc1rj0aNqRlpuvjmwA= +sigs.k8s.io/structured-merge-diff/v4 v4.4.2/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/go.work b/go.work deleted file mode 100644 index ac741bb5a..000000000 --- a/go.work +++ /dev/null @@ -1,7 +0,0 @@ -go 1.22.6 - -use ( - . - ./images/kube-webhook-certgen/rootfs - ./magefiles -) diff --git a/go.work.sum b/go.work.sum deleted file mode 100644 index 3a38ab8ec..000000000 --- a/go.work.sum +++ /dev/null @@ -1,1093 +0,0 @@ -cel.dev/expr v0.15.0/go.mod h1:TRSuuV7DlVCE/uwv5QbAiW/v8l5O8C4eEPHeu7gf7Sg= -cloud.google.com/go v0.110.2 h1:sdFPBr6xG9/wkBbfhmUz/JmZC7X6LavQgcrVINrKiVA= -cloud.google.com/go v0.110.4/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI= -cloud.google.com/go v0.110.8/go.mod h1:Iz8AkXJf1qmxC3Oxoep8R1T36w8B92yU29PcBhHO5fk= -cloud.google.com/go v0.110.10/go.mod h1:v1OoFqYxiBkUrruItNM3eT4lLByNjxmJSV/xDKJNnic= -cloud.google.com/go v0.112.0/go.mod h1:3jEEVwZ/MHU4djK5t5RHuKOA/GbLddgTdVubX1qnPD4= -cloud.google.com/go/accessapproval v1.6.0 h1:x0cEHro/JFPd7eS4BlEWNTMecIj2HdXjOVB5BtvwER0= -cloud.google.com/go/accessapproval v1.7.1/go.mod h1:JYczztsHRMK7NTXb6Xw+dwbs/WnOJxbo/2mTI+Kgg68= -cloud.google.com/go/accessapproval v1.7.4/go.mod h1:/aTEh45LzplQgFYdQdwPMR9YdX0UlhBmvB84uAmQKUc= -cloud.google.com/go/accessapproval v1.7.5/go.mod h1:g88i1ok5dvQ9XJsxpUInWWvUBrIZhyPDPbk4T01OoJ0= -cloud.google.com/go/accesscontextmanager v1.7.0 h1:MG60JgnEoawHJrbWw0jGdv6HLNSf6gQvYRiXpuzqgEA= -cloud.google.com/go/accesscontextmanager v1.8.1/go.mod h1:JFJHfvuaTC+++1iL1coPiG1eu5D24db2wXCDWDjIrxo= -cloud.google.com/go/accesscontextmanager v1.8.4/go.mod h1:ParU+WbMpD34s5JFEnGAnPBYAgUHozaTmDJU7aCU9+M= -cloud.google.com/go/accesscontextmanager v1.8.5/go.mod h1:TInEhcZ7V9jptGNqN3EzZ5XMhT6ijWxTGjzyETwmL0Q= -cloud.google.com/go/aiplatform v1.37.0 h1:zTw+suCVchgZyO+k847wjzdVjWmrAuehxdvcZvJwfGg= -cloud.google.com/go/aiplatform v1.45.0/go.mod h1:Iu2Q7sC7QGhXUeOhAj/oCK9a+ULz1O4AotZiqjQ8MYA= -cloud.google.com/go/aiplatform v1.50.0/go.mod h1:IRc2b8XAMTa9ZmfJV1BCCQbieWWvDnP1A8znyz5N7y4= -cloud.google.com/go/aiplatform v1.52.0/go.mod h1:pwZMGvqe0JRkI1GWSZCtnAfrR4K1bv65IHILGA//VEU= -cloud.google.com/go/aiplatform v1.58.0/go.mod h1:pwZMGvqe0JRkI1GWSZCtnAfrR4K1bv65IHILGA//VEU= -cloud.google.com/go/aiplatform v1.60.0/go.mod h1:eTlGuHOahHprZw3Hio5VKmtThIOak5/qy6pzdsqcQnM= -cloud.google.com/go/analytics v0.19.0 h1:LqAo3tAh2FU9+w/r7vc3hBjU23Kv7GhO/PDIW7kIYgM= -cloud.google.com/go/analytics v0.21.2/go.mod h1:U8dcUtmDmjrmUTnnnRnI4m6zKn/yaA5N9RlEkYFHpQo= -cloud.google.com/go/analytics v0.21.3/go.mod h1:U8dcUtmDmjrmUTnnnRnI4m6zKn/yaA5N9RlEkYFHpQo= -cloud.google.com/go/analytics v0.21.6/go.mod h1:eiROFQKosh4hMaNhF85Oc9WO97Cpa7RggD40e/RBy8w= -cloud.google.com/go/analytics v0.22.0/go.mod h1:eiROFQKosh4hMaNhF85Oc9WO97Cpa7RggD40e/RBy8w= -cloud.google.com/go/analytics v0.23.0/go.mod h1:YPd7Bvik3WS95KBok2gPXDqQPHy08TsCQG6CdUCb+u0= -cloud.google.com/go/apigateway v1.5.0 h1:ZI9mVO7x3E9RK/BURm2p1aw9YTBSCQe3klmyP1WxWEg= -cloud.google.com/go/apigateway v1.6.1/go.mod h1:ufAS3wpbRjqfZrzpvLC2oh0MFlpRJm2E/ts25yyqmXA= -cloud.google.com/go/apigateway v1.6.4/go.mod h1:0EpJlVGH5HwAN4VF4Iec8TAzGN1aQgbxAWGJsnPCGGY= -cloud.google.com/go/apigateway v1.6.5/go.mod h1:6wCwvYRckRQogyDDltpANi3zsCDl6kWi0b4Je+w2UiI= -cloud.google.com/go/apigeeconnect v1.5.0 h1:sWOmgDyAsi1AZ48XRHcATC0tsi9SkPT7DA/+VCfkaeA= -cloud.google.com/go/apigeeconnect v1.6.1/go.mod h1:C4awq7x0JpLtrlQCr8AzVIzAaYgngRqWf9S5Uhg+wWs= -cloud.google.com/go/apigeeconnect v1.6.4/go.mod h1:CapQCWZ8TCjnU0d7PobxhpOdVz/OVJ2Hr/Zcuu1xFx0= -cloud.google.com/go/apigeeconnect v1.6.5/go.mod h1:MEKm3AiT7s11PqTfKE3KZluZA9O91FNysvd3E6SJ6Ow= -cloud.google.com/go/apigeeregistry v0.6.0 h1:E43RdhhCxdlV+I161gUY2rI4eOaMzHTA5kNkvRsFXvc= -cloud.google.com/go/apigeeregistry v0.7.1/go.mod h1:1XgyjZye4Mqtw7T9TsY4NW10U7BojBvG4RMD+vRDrIw= -cloud.google.com/go/apigeeregistry v0.8.2/go.mod h1:h4v11TDGdeXJDJvImtgK2AFVvMIgGWjSb0HRnBSjcX8= -cloud.google.com/go/apigeeregistry v0.8.3/go.mod h1:aInOWnqF4yMQx8kTjDqHNXjZGh/mxeNlAf52YqtASUs= -cloud.google.com/go/apikeys v0.6.0 h1:B9CdHFZTFjVti89tmyXXrO+7vSNo2jvZuHG8zD5trdQ= -cloud.google.com/go/appengine v1.7.1 h1:aBGDKmRIaRRoWJ2tAoN0oVSHoWLhtO9aj/NvUyP4aYs= -cloud.google.com/go/appengine v1.8.1/go.mod h1:6NJXGLVhZCN9aQ/AEDvmfzKEfoYBlfB80/BHiKVputY= -cloud.google.com/go/appengine v1.8.4/go.mod h1:TZ24v+wXBujtkK77CXCpjZbnuTvsFNT41MUaZ28D6vg= -cloud.google.com/go/appengine v1.8.5/go.mod h1:uHBgNoGLTS5di7BvU25NFDuKa82v0qQLjyMJLuPQrVo= -cloud.google.com/go/area120 v0.7.1 h1:ugckkFh4XkHJMPhTIx0CyvdoBxmOpMe8rNs4Ok8GAag= -cloud.google.com/go/area120 v0.8.1/go.mod h1:BVfZpGpB7KFVNxPiQBuHkX6Ed0rS51xIgmGyjrAfzsg= -cloud.google.com/go/area120 v0.8.4/go.mod h1:jfawXjxf29wyBXr48+W+GyX/f8fflxp642D/bb9v68M= -cloud.google.com/go/area120 v0.8.5/go.mod h1:BcoFCbDLZjsfe4EkCnEq1LKvHSK0Ew/zk5UFu6GMyA0= -cloud.google.com/go/artifactregistry v1.13.0 h1:o1Q80vqEB6Qp8WLEH3b8FBLNUCrGQ4k5RFj0sn/sgO8= -cloud.google.com/go/artifactregistry v1.14.1/go.mod h1:nxVdG19jTaSTu7yA7+VbWL346r3rIdkZ142BSQqhn5E= -cloud.google.com/go/artifactregistry v1.14.6/go.mod h1:np9LSFotNWHcjnOgh8UVK0RFPCTUGbO0ve3384xyHfE= -cloud.google.com/go/artifactregistry v1.14.7/go.mod h1:0AUKhzWQzfmeTvT4SjfI4zjot72EMfrkvL9g9aRjnnM= -cloud.google.com/go/asset v1.13.0 h1:YAsssO08BqZ6mncbb6FPlj9h6ACS7bJQUOlzciSfbNk= -cloud.google.com/go/asset v1.14.1/go.mod h1:4bEJ3dnHCqWCDbWJ/6Vn7GVI9LerSi7Rfdi03hd+WTQ= -cloud.google.com/go/asset v1.15.3/go.mod h1:yYLfUD4wL4X589A9tYrv4rFrba0QlDeag0CMcM5ggXU= -cloud.google.com/go/asset v1.17.0/go.mod h1:yYLfUD4wL4X589A9tYrv4rFrba0QlDeag0CMcM5ggXU= -cloud.google.com/go/asset v1.17.2/go.mod h1:SVbzde67ehddSoKf5uebOD1sYw8Ab/jD/9EIeWg99q4= -cloud.google.com/go/assuredworkloads v1.10.0 h1:VLGnVFta+N4WM+ASHbhc14ZOItOabDLH1MSoDv+Xuag= -cloud.google.com/go/assuredworkloads v1.11.1/go.mod h1:+F04I52Pgn5nmPG36CWFtxmav6+7Q+c5QyJoL18Lry0= -cloud.google.com/go/assuredworkloads v1.11.4/go.mod h1:4pwwGNwy1RP0m+y12ef3Q/8PaiWrIDQ6nD2E8kvWI9U= -cloud.google.com/go/assuredworkloads v1.11.5/go.mod h1:FKJ3g3ZvkL2D7qtqIGnDufFkHxwIpNM9vtmhvt+6wqk= -cloud.google.com/go/automl v1.12.0 h1:50VugllC+U4IGl3tDNcZaWvApHBTrn/TvyHDJ0wM+Uw= -cloud.google.com/go/automl v1.13.1/go.mod h1:1aowgAHWYZU27MybSCFiukPO7xnyawv7pt3zK4bheQE= -cloud.google.com/go/automl v1.13.4/go.mod h1:ULqwX/OLZ4hBVfKQaMtxMSTlPx0GqGbWN8uA/1EqCP8= -cloud.google.com/go/automl v1.13.5/go.mod h1:MDw3vLem3yh+SvmSgeYUmUKqyls6NzSumDm9OJ3xJ1Y= -cloud.google.com/go/baremetalsolution v0.5.0 h1:2AipdYXL0VxMboelTTw8c1UJ7gYu35LZYUbuRv9Q28s= -cloud.google.com/go/baremetalsolution v1.2.0/go.mod h1:68wi9AwPYkEWIUT4SvSGS9UJwKzNpshjHsH4lzk8iOw= -cloud.google.com/go/baremetalsolution v1.2.3/go.mod h1:/UAQ5xG3faDdy180rCUv47e0jvpp3BFxT+Cl0PFjw5g= -cloud.google.com/go/baremetalsolution v1.2.4/go.mod h1:BHCmxgpevw9IEryE99HbYEfxXkAEA3hkMJbYYsHtIuY= -cloud.google.com/go/batch v0.7.0 h1:YbMt0E6BtqeD5FvSv1d56jbVsWEzlGm55lYte+M6Mzs= -cloud.google.com/go/batch v1.4.1/go.mod h1:KdBmDD61K0ovcxoRHGrN6GmOBWeAOyCgKD0Mugx4Fkk= -cloud.google.com/go/batch v1.6.3/go.mod h1:J64gD4vsNSA2O5TtDB5AAux3nJ9iV8U3ilg3JDBYejU= -cloud.google.com/go/batch v1.7.0/go.mod h1:J64gD4vsNSA2O5TtDB5AAux3nJ9iV8U3ilg3JDBYejU= -cloud.google.com/go/batch v1.8.0/go.mod h1:k8V7f6VE2Suc0zUM4WtoibNrA6D3dqBpB+++e3vSGYc= -cloud.google.com/go/beyondcorp v0.5.0 h1:UkY2BTZkEUAVrgqnSdOJ4p3y9ZRBPEe1LkjgC8Bj/Pc= -cloud.google.com/go/beyondcorp v0.6.1/go.mod h1:YhxDWw946SCbmcWo3fAhw3V4XZMSpQ/VYfcKGAEU8/4= -cloud.google.com/go/beyondcorp v1.0.0/go.mod h1:YhxDWw946SCbmcWo3fAhw3V4XZMSpQ/VYfcKGAEU8/4= -cloud.google.com/go/beyondcorp v1.0.3/go.mod h1:HcBvnEd7eYr+HGDd5ZbuVmBYX019C6CEXBonXbCVwJo= -cloud.google.com/go/beyondcorp v1.0.4/go.mod h1:Gx8/Rk2MxrvWfn4WIhHIG1NV7IBfg14pTKv1+EArVcc= -cloud.google.com/go/bigquery v1.50.0 h1:RscMV6LbnAmhAzD893Lv9nXXy2WCaJmbxYPWDLbGqNQ= -cloud.google.com/go/bigquery v1.52.0/go.mod h1:3b/iXjRQGU4nKa87cXeg6/gogLjO8C6PmuM8i5Bi/u4= -cloud.google.com/go/bigquery v1.55.0/go.mod h1:9Y5I3PN9kQWuid6183JFhOGOW3GcirA5LpsKCUn+2ec= -cloud.google.com/go/bigquery v1.57.1/go.mod h1:iYzC0tGVWt1jqSzBHqCr3lrRn0u13E8e+AqowBsDgug= -cloud.google.com/go/bigquery v1.58.0/go.mod h1:0eh4mWNY0KrBTjUzLjoYImapGORq9gEPT7MWjCy9lik= -cloud.google.com/go/bigquery v1.59.1/go.mod h1:VP1UJYgevyTwsV7desjzNzDND5p6hZB+Z8gZJN1GQUc= -cloud.google.com/go/billing v1.13.0 h1:JYj28UYF5w6VBAh0gQYlgHJ/OD1oA+JgW29YZQU+UHM= -cloud.google.com/go/billing v1.16.0/go.mod h1:y8vx09JSSJG02k5QxbycNRrN7FGZB6F3CAcgum7jvGA= -cloud.google.com/go/billing v1.17.0/go.mod h1:Z9+vZXEq+HwH7bhJkyI4OQcR6TSbeMrjlpEjO2vzY64= -cloud.google.com/go/billing v1.17.4/go.mod h1:5DOYQStCxquGprqfuid/7haD7th74kyMBHkjO/OvDtk= -cloud.google.com/go/billing v1.18.0/go.mod h1:5DOYQStCxquGprqfuid/7haD7th74kyMBHkjO/OvDtk= -cloud.google.com/go/billing v1.18.2/go.mod h1:PPIwVsOOQ7xzbADCwNe8nvK776QpfrOAUkvKjCUcpSE= -cloud.google.com/go/binaryauthorization v1.5.0 h1:d3pMDBCCNivxt5a4eaV7FwL7cSH0H7RrEnFrTb1QKWs= -cloud.google.com/go/binaryauthorization v1.6.1/go.mod h1:TKt4pa8xhowwffiBmbrbcxijJRZED4zrqnwZ1lKH51U= -cloud.google.com/go/binaryauthorization v1.7.0/go.mod h1:Zn+S6QqTMn6odcMU1zDZCJxPjU2tZPV1oDl45lWY154= -cloud.google.com/go/binaryauthorization v1.7.3/go.mod h1:VQ/nUGRKhrStlGr+8GMS8f6/vznYLkdK5vaKfdCIpvU= -cloud.google.com/go/binaryauthorization v1.8.0/go.mod h1:VQ/nUGRKhrStlGr+8GMS8f6/vznYLkdK5vaKfdCIpvU= -cloud.google.com/go/binaryauthorization v1.8.1/go.mod h1:1HVRyBerREA/nhI7yLang4Zn7vfNVA3okoAR9qYQJAQ= -cloud.google.com/go/certificatemanager v1.6.0 h1:5C5UWeSt8Jkgp7OWn2rCkLmYurar/vIWIoSQ2+LaTOc= -cloud.google.com/go/certificatemanager v1.7.1/go.mod h1:iW8J3nG6SaRYImIa+wXQ0g8IgoofDFRp5UMzaNk1UqI= -cloud.google.com/go/certificatemanager v1.7.4/go.mod h1:FHAylPe/6IIKuaRmHbjbdLhGhVQ+CWHSD5Jq0k4+cCE= -cloud.google.com/go/certificatemanager v1.7.5/go.mod h1:uX+v7kWqy0Y3NG/ZhNvffh0kuqkKZIXdvlZRO7z0VtM= -cloud.google.com/go/channel v1.12.0 h1:GpcQY5UJKeOekYgsX3QXbzzAc/kRGtBq43fTmyKe6Uw= -cloud.google.com/go/channel v1.16.0/go.mod h1:eN/q1PFSl5gyu0dYdmxNXscY/4Fi7ABmeHCJNf/oHmc= -cloud.google.com/go/channel v1.17.0/go.mod h1:RpbhJsGi/lXWAUM1eF4IbQGbsfVlg2o8Iiy2/YLfVT0= -cloud.google.com/go/channel v1.17.3/go.mod h1:QcEBuZLGGrUMm7kNj9IbU1ZfmJq2apotsV83hbxX7eE= -cloud.google.com/go/channel v1.17.4/go.mod h1:QcEBuZLGGrUMm7kNj9IbU1ZfmJq2apotsV83hbxX7eE= -cloud.google.com/go/channel v1.17.5/go.mod h1:FlpaOSINDAXgEext0KMaBq/vwpLMkkPAw9b2mApQeHc= -cloud.google.com/go/cloudbuild v1.9.0 h1:GHQCjV4WlPPVU/j3Rlpc8vNIDwThhd1U9qSY/NPZdko= -cloud.google.com/go/cloudbuild v1.10.1/go.mod h1:lyJg7v97SUIPq4RC2sGsz/9tNczhyv2AjML/ci4ulzU= -cloud.google.com/go/cloudbuild v1.14.0/go.mod h1:lyJg7v97SUIPq4RC2sGsz/9tNczhyv2AjML/ci4ulzU= -cloud.google.com/go/cloudbuild v1.14.3/go.mod h1:eIXYWmRt3UtggLnFGx4JvXcMj4kShhVzGndL1LwleEM= -cloud.google.com/go/cloudbuild v1.15.0/go.mod h1:eIXYWmRt3UtggLnFGx4JvXcMj4kShhVzGndL1LwleEM= -cloud.google.com/go/cloudbuild v1.15.1/go.mod h1:gIofXZSu+XD2Uy+qkOrGKEx45zd7s28u/k8f99qKals= -cloud.google.com/go/clouddms v1.5.0 h1:E7v4TpDGUyEm1C/4KIrpVSOCTm0P6vWdHT0I4mostRA= -cloud.google.com/go/clouddms v1.6.1/go.mod h1:Ygo1vL52Ov4TBZQquhz5fiw2CQ58gvu+PlS6PVXCpZI= -cloud.google.com/go/clouddms v1.7.0/go.mod h1:MW1dC6SOtI/tPNCciTsXtsGNEM0i0OccykPvv3hiYeM= -cloud.google.com/go/clouddms v1.7.3/go.mod h1:fkN2HQQNUYInAU3NQ3vRLkV2iWs8lIdmBKOx4nrL6Hc= -cloud.google.com/go/clouddms v1.7.4/go.mod h1:RdrVqoFG9RWI5AvZ81SxJ/xvxPdtcRhFotwdE79DieY= -cloud.google.com/go/cloudtasks v1.10.0 h1:uK5k6abf4yligFgYFnG0ni8msai/dSv6mDmiBulU0hU= -cloud.google.com/go/cloudtasks v1.11.1/go.mod h1:a9udmnou9KO2iulGscKR0qBYjreuX8oHwpmFsKspEvM= -cloud.google.com/go/cloudtasks v1.12.1/go.mod h1:a9udmnou9KO2iulGscKR0qBYjreuX8oHwpmFsKspEvM= -cloud.google.com/go/cloudtasks v1.12.4/go.mod h1:BEPu0Gtt2dU6FxZHNqqNdGqIG86qyWKBPGnsb7udGY0= -cloud.google.com/go/cloudtasks v1.12.6/go.mod h1:b7c7fe4+TJsFZfDyzO51F7cjq7HLUlRi/KZQLQjDsaY= -cloud.google.com/go/compute v1.21.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= -cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= -cloud.google.com/go/compute v1.23.1/go.mod h1:CqB3xpmPKKt3OJpW2ndFIXnA9A4xAy/F3Xp1ixncW78= -cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI= -cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= -cloud.google.com/go/compute v1.24.0/go.mod h1:kw1/T+h/+tK2LJK0wiPPx1intgdAM3j/g3hFDlscY40= -cloud.google.com/go/compute v1.25.1/go.mod h1:oopOIR53ly6viBYxaDhBfJwzUAxf1zE//uf3IB011ls= -cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= -cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= -cloud.google.com/go/contactcenterinsights v1.6.0 h1:jXIpfcH/VYSE1SYcPzO0n1VVb+sAamiLOgCw45JbOQk= -cloud.google.com/go/contactcenterinsights v1.9.1/go.mod h1:bsg/R7zGLYMVxFFzfh9ooLTruLRCG9fnzhH9KznHhbM= -cloud.google.com/go/contactcenterinsights v1.10.0/go.mod h1:bsg/R7zGLYMVxFFzfh9ooLTruLRCG9fnzhH9KznHhbM= -cloud.google.com/go/contactcenterinsights v1.11.3/go.mod h1:HHX5wrz5LHVAwfI2smIotQG9x8Qd6gYilaHcLLLmNis= -cloud.google.com/go/contactcenterinsights v1.12.1/go.mod h1:HHX5wrz5LHVAwfI2smIotQG9x8Qd6gYilaHcLLLmNis= -cloud.google.com/go/contactcenterinsights v1.13.0/go.mod h1:ieq5d5EtHsu8vhe2y3amtZ+BE+AQwX5qAy7cpo0POsI= -cloud.google.com/go/container v1.15.0 h1:NKlY/wCDapfVZlbVVaeuu2UZZED5Dy1z4Zx1KhEzm8c= -cloud.google.com/go/container v1.22.1/go.mod h1:lTNExE2R7f+DLbAN+rJiKTisauFCaoDq6NURZ83eVH4= -cloud.google.com/go/container v1.26.0/go.mod h1:YJCmRet6+6jnYYRS000T6k0D0xUXQgBSaJ7VwI8FBj4= -cloud.google.com/go/container v1.27.1/go.mod h1:b1A1gJeTBXVLQ6GGw9/9M4FG94BEGsqJ5+t4d/3N7O4= -cloud.google.com/go/container v1.29.0/go.mod h1:b1A1gJeTBXVLQ6GGw9/9M4FG94BEGsqJ5+t4d/3N7O4= -cloud.google.com/go/container v1.31.0/go.mod h1:7yABn5s3Iv3lmw7oMmyGbeV6tQj86njcTijkkGuvdZA= -cloud.google.com/go/containeranalysis v0.9.0 h1:EQ4FFxNaEAg8PqQCO7bVQfWz9NVwZCUKaM1b3ycfx3U= -cloud.google.com/go/containeranalysis v0.10.1/go.mod h1:Ya2jiILITMY68ZLPaogjmOMNkwsDrWBSTyBubGXO7j0= -cloud.google.com/go/containeranalysis v0.11.0/go.mod h1:4n2e99ZwpGxpNcz+YsFT1dfOHPQFGcAC8FN2M2/ne/U= -cloud.google.com/go/containeranalysis v0.11.3/go.mod h1:kMeST7yWFQMGjiG9K7Eov+fPNQcGhb8mXj/UcTiWw9U= -cloud.google.com/go/containeranalysis v0.11.4/go.mod h1:cVZT7rXYBS9NG1rhQbWL9pWbXCKHWJPYraE8/FTSYPE= -cloud.google.com/go/datacatalog v1.13.0 h1:4H5IJiyUE0X6ShQBqgFFZvGGcrwGVndTwUSLP4c52gw= -cloud.google.com/go/datacatalog v1.14.1/go.mod h1:d2CevwTG4yedZilwe+v3E3ZBDRMobQfSG/a6cCCN5R4= -cloud.google.com/go/datacatalog v1.17.1/go.mod h1:nCSYFHgtxh2MiEktWIz71s/X+7ds/UT9kp0PC7waCzE= -cloud.google.com/go/datacatalog v1.18.3/go.mod h1:5FR6ZIF8RZrtml0VUao22FxhdjkoG+a0866rEnObryM= -cloud.google.com/go/datacatalog v1.19.2/go.mod h1:2YbODwmhpLM4lOFe3PuEhHK9EyTzQJ5AXgIy7EDKTEE= -cloud.google.com/go/datacatalog v1.19.3/go.mod h1:ra8V3UAsciBpJKQ+z9Whkxzxv7jmQg1hfODr3N3YPJ4= -cloud.google.com/go/dataflow v0.8.0 h1:eYyD9o/8Nm6EttsKZaEGD84xC17bNgSKCu0ZxwqUbpg= -cloud.google.com/go/dataflow v0.9.1/go.mod h1:Wp7s32QjYuQDWqJPFFlnBKhkAtiFpMTdg00qGbnIHVw= -cloud.google.com/go/dataflow v0.9.4/go.mod h1:4G8vAkHYCSzU8b/kmsoR2lWyHJD85oMJPHMtan40K8w= -cloud.google.com/go/dataflow v0.9.5/go.mod h1:udl6oi8pfUHnL0z6UN9Lf9chGqzDMVqcYTcZ1aPnCZQ= -cloud.google.com/go/dataform v0.7.0 h1:Dyk+fufup1FR6cbHjFpMuP4SfPiF3LI3JtoIIALoq48= -cloud.google.com/go/dataform v0.8.1/go.mod h1:3BhPSiw8xmppbgzeBbmDvmSWlwouuJkXsXsb8UBih9M= -cloud.google.com/go/dataform v0.9.1/go.mod h1:pWTg+zGQ7i16pyn0bS1ruqIE91SdL2FDMvEYu/8oQxs= -cloud.google.com/go/dataform v0.9.2/go.mod h1:S8cQUwPNWXo7m/g3DhWHsLBoufRNn9EgFrMgne2j7cI= -cloud.google.com/go/datafusion v1.6.0 h1:sZjRnS3TWkGsu1LjYPFD/fHeMLZNXDK6PDHi2s2s/bk= -cloud.google.com/go/datafusion v1.7.1/go.mod h1:KpoTBbFmoToDExJUso/fcCiguGDk7MEzOWXUsJo0wsI= -cloud.google.com/go/datafusion v1.7.4/go.mod h1:BBs78WTOLYkT4GVZIXQCZT3GFpkpDN4aBY4NDX/jVlM= -cloud.google.com/go/datafusion v1.7.5/go.mod h1:bYH53Oa5UiqahfbNK9YuYKteeD4RbQSNMx7JF7peGHc= -cloud.google.com/go/datalabeling v0.7.0 h1:ch4qA2yvddGRUrlfwrNJCr79qLqhS9QBwofPHfFlDIk= -cloud.google.com/go/datalabeling v0.8.1/go.mod h1:XS62LBSVPbYR54GfYQsPXZjTW8UxCK2fkDciSrpRFdY= -cloud.google.com/go/datalabeling v0.8.4/go.mod h1:Z1z3E6LHtffBGrNUkKwbwbDxTiXEApLzIgmymj8A3S8= -cloud.google.com/go/datalabeling v0.8.5/go.mod h1:IABB2lxQnkdUbMnQaOl2prCOfms20mcPxDBm36lps+s= -cloud.google.com/go/dataplex v1.6.0 h1:RvoZ5T7gySwm1CHzAw7yY1QwwqaGswunmqEssPxU/AM= -cloud.google.com/go/dataplex v1.8.1/go.mod h1:7TyrDT6BCdI8/38Uvp0/ZxBslOslP2X2MPDucliyvSE= -cloud.google.com/go/dataplex v1.9.1/go.mod h1:7TyrDT6BCdI8/38Uvp0/ZxBslOslP2X2MPDucliyvSE= -cloud.google.com/go/dataplex v1.11.1/go.mod h1:mHJYQQ2VEJHsyoC0OdNyy988DvEbPhqFs5OOLffLX0c= -cloud.google.com/go/dataplex v1.14.0/go.mod h1:mHJYQQ2VEJHsyoC0OdNyy988DvEbPhqFs5OOLffLX0c= -cloud.google.com/go/dataplex v1.14.2/go.mod h1:0oGOSFlEKef1cQeAHXy4GZPB/Ife0fz/PxBf+ZymA2U= -cloud.google.com/go/dataproc v1.12.0 h1:W47qHL3W4BPkAIbk4SWmIERwsWBaNnWm0P2sdx3YgGU= -cloud.google.com/go/dataproc/v2 v2.2.0/go.mod h1:lZR7AQtwZPvmINx5J87DSOOpTfof9LVZju6/Qo4lmcY= -cloud.google.com/go/dataproc/v2 v2.2.3/go.mod h1:G5R6GBc9r36SXv/RtZIVfB8SipI+xVn0bX5SxUzVYbY= -cloud.google.com/go/dataproc/v2 v2.3.0/go.mod h1:G5R6GBc9r36SXv/RtZIVfB8SipI+xVn0bX5SxUzVYbY= -cloud.google.com/go/dataproc/v2 v2.4.0/go.mod h1:3B1Ht2aRB8VZIteGxQS/iNSJGzt9+CA0WGnDVMEm7Z4= -cloud.google.com/go/dataqna v0.7.0 h1:yFzi/YU4YAdjyo7pXkBE2FeHbgz5OQQBVDdbErEHmVQ= -cloud.google.com/go/dataqna v0.8.1/go.mod h1:zxZM0Bl6liMePWsHA8RMGAfmTG34vJMapbHAxQ5+WA8= -cloud.google.com/go/dataqna v0.8.4/go.mod h1:mySRKjKg5Lz784P6sCov3p1QD+RZQONRMRjzGNcFd0c= -cloud.google.com/go/dataqna v0.8.5/go.mod h1:vgihg1mz6n7pb5q2YJF7KlXve6tCglInd6XO0JGOlWM= -cloud.google.com/go/datastore v1.11.0 h1:iF6I/HaLs3Ado8uRKMvZRvF/ZLkWaWE9i8AiHzbC774= -cloud.google.com/go/datastore v1.12.1/go.mod h1:KjdB88W897MRITkvWWJrg2OUtrR5XVj1EoLgSp6/N70= -cloud.google.com/go/datastore v1.14.0/go.mod h1:GAeStMBIt9bPS7jMJA85kgkpsMkvseWWXiaHya9Jes8= -cloud.google.com/go/datastore v1.15.0/go.mod h1:GAeStMBIt9bPS7jMJA85kgkpsMkvseWWXiaHya9Jes8= -cloud.google.com/go/datastream v1.7.0 h1:BBCBTnWMDwwEzQQmipUXxATa7Cm7CA/gKjKcR2w35T0= -cloud.google.com/go/datastream v1.9.1/go.mod h1:hqnmr8kdUBmrnk65k5wNRoHSCYksvpdZIcZIEl8h43Q= -cloud.google.com/go/datastream v1.10.0/go.mod h1:hqnmr8kdUBmrnk65k5wNRoHSCYksvpdZIcZIEl8h43Q= -cloud.google.com/go/datastream v1.10.3/go.mod h1:YR0USzgjhqA/Id0Ycu1VvZe8hEWwrkjuXrGbzeDOSEA= -cloud.google.com/go/datastream v1.10.4/go.mod h1:7kRxPdxZxhPg3MFeCSulmAJnil8NJGGvSNdn4p1sRZo= -cloud.google.com/go/deploy v1.8.0 h1:otshdKEbmsi1ELYeCKNYppwV0UH5xD05drSdBm7ouTk= -cloud.google.com/go/deploy v1.11.0/go.mod h1:tKuSUV5pXbn67KiubiUNUejqLs4f5cxxiCNCeyl0F2g= -cloud.google.com/go/deploy v1.13.0/go.mod h1:tKuSUV5pXbn67KiubiUNUejqLs4f5cxxiCNCeyl0F2g= -cloud.google.com/go/deploy v1.14.2/go.mod h1:e5XOUI5D+YGldyLNZ21wbp9S8otJbBE4i88PtO9x/2g= -cloud.google.com/go/deploy v1.17.0/go.mod h1:XBr42U5jIr64t92gcpOXxNrqL2PStQCXHuKK5GRUuYo= -cloud.google.com/go/deploy v1.17.1/go.mod h1:SXQyfsXrk0fBmgBHRzBjQbZhMfKZ3hMQBw5ym7MN/50= -cloud.google.com/go/dialogflow v1.32.0 h1:uVlKKzp6G/VtSW0E7IH1Y5o0H48/UOCmqksG2riYCwQ= -cloud.google.com/go/dialogflow v1.38.0/go.mod h1:L7jnH+JL2mtmdChzAIcXQHXMvQkE3U4hTaNltEuxXn4= -cloud.google.com/go/dialogflow v1.43.0/go.mod h1:pDUJdi4elL0MFmt1REMvFkdsUTYSHq+rTCS8wg0S3+M= -cloud.google.com/go/dialogflow v1.44.3/go.mod h1:mHly4vU7cPXVweuB5R0zsYKPMzy240aQdAu06SqBbAQ= -cloud.google.com/go/dialogflow v1.48.1/go.mod h1:C1sjs2/g9cEwjCltkKeYp3FFpz8BOzNondEaAlCpt+A= -cloud.google.com/go/dialogflow v1.49.0/go.mod h1:dhVrXKETtdPlpPhE7+2/k4Z8FRNUp6kMV3EW3oz/fe0= -cloud.google.com/go/dlp v1.9.0 h1:1JoJqezlgu6NWCroBxr4rOZnwNFILXr4cB9dMaSKO4A= -cloud.google.com/go/dlp v1.10.1/go.mod h1:IM8BWz1iJd8njcNcG0+Kyd9OPnqnRNkDV8j42VT5KOI= -cloud.google.com/go/dlp v1.11.1/go.mod h1:/PA2EnioBeXTL/0hInwgj0rfsQb3lpE3R8XUJxqUNKI= -cloud.google.com/go/dlp v1.11.2/go.mod h1:9Czi+8Y/FegpWzgSfkRlyz+jwW6Te9Rv26P3UfU/h/w= -cloud.google.com/go/documentai v1.18.0 h1:KM3Xh0QQyyEdC8Gs2vhZfU+rt6OCPF0dwVwxKgLmWfI= -cloud.google.com/go/documentai v1.20.0/go.mod h1:yJkInoMcK0qNAEdRnqY/D5asy73tnPe88I1YTZT+a8E= -cloud.google.com/go/documentai v1.22.1/go.mod h1:LKs22aDHbJv7ufXuPypzRO7rG3ALLJxzdCXDPutw4Qc= -cloud.google.com/go/documentai v1.23.5/go.mod h1:ghzBsyVTiVdkfKaUCum/9bGBEyBjDO4GfooEcYKhN+g= -cloud.google.com/go/documentai v1.23.7/go.mod h1:ghzBsyVTiVdkfKaUCum/9bGBEyBjDO4GfooEcYKhN+g= -cloud.google.com/go/documentai v1.25.0/go.mod h1:ftLnzw5VcXkLItp6pw1mFic91tMRyfv6hHEY5br4KzY= -cloud.google.com/go/domains v0.8.0 h1:2ti/o9tlWL4N+wIuWUNH+LbfgpwxPr8J1sv9RHA4bYQ= -cloud.google.com/go/domains v0.9.1/go.mod h1:aOp1c0MbejQQ2Pjf1iJvnVyT+z6R6s8pX66KaCSDYfE= -cloud.google.com/go/domains v0.9.4/go.mod h1:27jmJGShuXYdUNjyDG0SodTfT5RwLi7xmH334Gvi3fY= -cloud.google.com/go/domains v0.9.5/go.mod h1:dBzlxgepazdFhvG7u23XMhmMKBjrkoUNaw0A8AQB55Y= -cloud.google.com/go/edgecontainer v1.0.0 h1:O0YVE5v+O0Q/ODXYsQHmHb+sYM8KNjGZw2pjX2Ws41c= -cloud.google.com/go/edgecontainer v1.1.1/go.mod h1:O5bYcS//7MELQZs3+7mabRqoWQhXCzenBu0R8bz2rwk= -cloud.google.com/go/edgecontainer v1.1.4/go.mod h1:AvFdVuZuVGdgaE5YvlL1faAoa1ndRR/5XhXZvPBHbsE= -cloud.google.com/go/edgecontainer v1.1.5/go.mod h1:rgcjrba3DEDEQAidT4yuzaKWTbkTI5zAMu3yy6ZWS0M= -cloud.google.com/go/errorreporting v0.3.0 h1:kj1XEWMu8P0qlLhm3FwcaFsUvXChV/OraZwA70trRR0= -cloud.google.com/go/essentialcontacts v1.5.0 h1:gIzEhCoOT7bi+6QZqZIzX1Erj4SswMPIteNvYVlu+pM= -cloud.google.com/go/essentialcontacts v1.6.2/go.mod h1:T2tB6tX+TRak7i88Fb2N9Ok3PvY3UNbUsMag9/BARh4= -cloud.google.com/go/essentialcontacts v1.6.5/go.mod h1:jjYbPzw0x+yglXC890l6ECJWdYeZ5dlYACTFL0U/VuM= -cloud.google.com/go/essentialcontacts v1.6.6/go.mod h1:XbqHJGaiH0v2UvtuucfOzFXN+rpL/aU5BCZLn4DYl1Q= -cloud.google.com/go/eventarc v1.11.0 h1:fsJmNeqvqtk74FsaVDU6cH79lyZNCYP8Rrv7EhaB/PU= -cloud.google.com/go/eventarc v1.12.1/go.mod h1:mAFCW6lukH5+IZjkvrEss+jmt2kOdYlN8aMx3sRJiAI= -cloud.google.com/go/eventarc v1.13.0/go.mod h1:mAFCW6lukH5+IZjkvrEss+jmt2kOdYlN8aMx3sRJiAI= -cloud.google.com/go/eventarc v1.13.3/go.mod h1:RWH10IAZIRcj1s/vClXkBgMHwh59ts7hSWcqD3kaclg= -cloud.google.com/go/eventarc v1.13.4/go.mod h1:zV5sFVoAa9orc/52Q+OuYUG9xL2IIZTbbuTHC6JSY8s= -cloud.google.com/go/filestore v1.6.0 h1:ckTEXN5towyTMu4q0uQ1Mde/JwTHur0gXs8oaIZnKfw= -cloud.google.com/go/filestore v1.7.1/go.mod h1:y10jsorq40JJnjR/lQ8AfFbbcGlw3g+Dp8oN7i7FjV4= -cloud.google.com/go/filestore v1.7.4/go.mod h1:S5JCxIbFjeBhWMTfIYH2Jx24J6BqjwpkkPl+nBA5DlI= -cloud.google.com/go/filestore v1.8.0/go.mod h1:S5JCxIbFjeBhWMTfIYH2Jx24J6BqjwpkkPl+nBA5DlI= -cloud.google.com/go/filestore v1.8.1/go.mod h1:MbN9KcaM47DRTIuLfQhJEsjaocVebNtNQhSLhKCF5GM= -cloud.google.com/go/firestore v1.9.0 h1:IBlRyxgGySXu5VuW0RgGFlTtLukSnNkpDiEOMkQkmpA= -cloud.google.com/go/firestore v1.11.0/go.mod h1:b38dKhgzlmNNGTNZZwe7ZRFEuRab1Hay3/DBsIGKKy4= -cloud.google.com/go/firestore v1.13.0/go.mod h1:QojqqOh8IntInDUSTAh0c8ZsPYAr68Ma8c5DWOy8xb8= -cloud.google.com/go/firestore v1.14.0/go.mod h1:96MVaHLsEhbvkBEdZgfN+AS/GIkco1LRpH9Xp9YZfzQ= -cloud.google.com/go/functions v1.13.0 h1:pPDqtsXG2g9HeOQLoquLbmvmb82Y4Ezdo1GXuotFoWg= -cloud.google.com/go/functions v1.15.1/go.mod h1:P5yNWUTkyU+LvW/S9O6V+V423VZooALQlqoXdoPz5AE= -cloud.google.com/go/functions v1.15.4/go.mod h1:CAsTc3VlRMVvx+XqXxKqVevguqJpnVip4DdonFsX28I= -cloud.google.com/go/functions v1.16.0/go.mod h1:nbNpfAG7SG7Duw/o1iZ6ohvL7mc6MapWQVpqtM29n8k= -cloud.google.com/go/gaming v1.9.0 h1:7vEhFnZmd931Mo7sZ6pJy7uQPDxF7m7v8xtBheG08tc= -cloud.google.com/go/gkebackup v0.4.0 h1:za3QZvw6ujR0uyqkhomKKKNoXDyqYGPJies3voUK8DA= -cloud.google.com/go/gkebackup v1.3.1/go.mod h1:vUDOu++N0U5qs4IhG1pcOnD1Mac79xWy6GoBFlWCWBU= -cloud.google.com/go/gkebackup v1.3.4/go.mod h1:gLVlbM8h/nHIs09ns1qx3q3eaXcGSELgNu1DWXYz1HI= -cloud.google.com/go/gkebackup v1.3.5/go.mod h1:KJ77KkNN7Wm1LdMopOelV6OodM01pMuK2/5Zt1t4Tvc= -cloud.google.com/go/gkeconnect v0.7.0 h1:gXYKciHS/Lgq0GJ5Kc9SzPA35NGc3yqu6SkjonpEr2Q= -cloud.google.com/go/gkeconnect v0.8.1/go.mod h1:KWiK1g9sDLZqhxB2xEuPV8V9NYzrqTUmQR9shJHpOZw= -cloud.google.com/go/gkeconnect v0.8.4/go.mod h1:84hZz4UMlDCKl8ifVW8layK4WHlMAFeq8vbzjU0yJkw= -cloud.google.com/go/gkeconnect v0.8.5/go.mod h1:LC/rS7+CuJ5fgIbXv8tCD/mdfnlAadTaUufgOkmijuk= -cloud.google.com/go/gkehub v0.12.0 h1:TqCSPsEBQ6oZSJgEYZ3XT8x2gUadbvfwI32YB0kuHCs= -cloud.google.com/go/gkehub v0.14.1/go.mod h1:VEXKIJZ2avzrbd7u+zeMtW00Y8ddk/4V9511C9CQGTY= -cloud.google.com/go/gkehub v0.14.4/go.mod h1:Xispfu2MqnnFt8rV/2/3o73SK1snL8s9dYJ9G2oQMfc= -cloud.google.com/go/gkehub v0.14.5/go.mod h1:6bzqxM+a+vEH/h8W8ec4OJl4r36laxTs3A/fMNHJ0wA= -cloud.google.com/go/gkemulticloud v0.5.0 h1:8I84Q4vl02rJRsFiinBxl7WCozfdLlUVBQuSrqr9Wtk= -cloud.google.com/go/gkemulticloud v0.6.1/go.mod h1:kbZ3HKyTsiwqKX7Yw56+wUGwwNZViRnxWK2DVknXWfw= -cloud.google.com/go/gkemulticloud v1.0.0/go.mod h1:kbZ3HKyTsiwqKX7Yw56+wUGwwNZViRnxWK2DVknXWfw= -cloud.google.com/go/gkemulticloud v1.0.3/go.mod h1:7NpJBN94U6DY1xHIbsDqB2+TFZUfjLUKLjUX8NGLor0= -cloud.google.com/go/gkemulticloud v1.1.0/go.mod h1:7NpJBN94U6DY1xHIbsDqB2+TFZUfjLUKLjUX8NGLor0= -cloud.google.com/go/gkemulticloud v1.1.1/go.mod h1:C+a4vcHlWeEIf45IB5FFR5XGjTeYhF83+AYIpTy4i2Q= -cloud.google.com/go/grafeas v0.2.0 h1:CYjC+xzdPvbV65gi6Dr4YowKcmLo045pm18L0DhdELM= -cloud.google.com/go/gsuiteaddons v1.5.0 h1:1mvhXqJzV0Vg5Fa95QwckljODJJfDFXV4pn+iL50zzA= -cloud.google.com/go/gsuiteaddons v1.6.1/go.mod h1:CodrdOqRZcLp5WOwejHWYBjZvfY0kOphkAKpF/3qdZY= -cloud.google.com/go/gsuiteaddons v1.6.4/go.mod h1:rxtstw7Fx22uLOXBpsvb9DUbC+fiXs7rF4U29KHM/pE= -cloud.google.com/go/gsuiteaddons v1.6.5/go.mod h1:Lo4P2IvO8uZ9W+RaC6s1JVxo42vgy+TX5a6hfBZ0ubs= -cloud.google.com/go/iam v0.13.0 h1:+CmB+K0J/33d0zSQ9SlFWUeCCEn5XJA0ZMZ3pHE9u8k= -cloud.google.com/go/iam v1.1.1/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU= -cloud.google.com/go/iam v1.1.2/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU= -cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8= -cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= -cloud.google.com/go/iap v1.7.1 h1:PxVHFuMxmSZyfntKXHXhd8bo82WJ+LcATenq7HLdVnU= -cloud.google.com/go/iap v1.8.1/go.mod h1:sJCbeqg3mvWLqjZNsI6dfAtbbV1DL2Rl7e1mTyXYREQ= -cloud.google.com/go/iap v1.9.0/go.mod h1:01OFxd1R+NFrg78S+hoPV5PxEzv22HXaNqUUlmNHFuY= -cloud.google.com/go/iap v1.9.3/go.mod h1:DTdutSZBqkkOm2HEOTBzhZxh2mwwxshfD/h3yofAiCw= -cloud.google.com/go/iap v1.9.4/go.mod h1:vO4mSq0xNf/Pu6E5paORLASBwEmphXEjgCFg7aeNu1w= -cloud.google.com/go/ids v1.3.0 h1:fodnCDtOXuMmS8LTC2y3h8t24U8F3eKWfhi+3LY6Qf0= -cloud.google.com/go/ids v1.4.1/go.mod h1:np41ed8YMU8zOgv53MMMoCntLTn2lF+SUzlM+O3u/jw= -cloud.google.com/go/ids v1.4.4/go.mod h1:z+WUc2eEl6S/1aZWzwtVNWoSZslgzPxAboS0lZX0HjI= -cloud.google.com/go/ids v1.4.5/go.mod h1:p0ZnyzjMWxww6d2DvMGnFwCsSxDJM666Iir1bK1UuBo= -cloud.google.com/go/iot v1.6.0 h1:39W5BFSarRNZfVG0eXI5LYux+OVQT8GkgpHCnrZL2vM= -cloud.google.com/go/iot v1.7.1/go.mod h1:46Mgw7ev1k9KqK1ao0ayW9h0lI+3hxeanz+L1zmbbbk= -cloud.google.com/go/iot v1.7.4/go.mod h1:3TWqDVvsddYBG++nHSZmluoCAVGr1hAcabbWZNKEZLk= -cloud.google.com/go/iot v1.7.5/go.mod h1:nq3/sqTz3HGaWJi1xNiX7F41ThOzpud67vwk0YsSsqs= -cloud.google.com/go/kms v1.10.1 h1:7hm1bRqGCA1GBRQUrp831TwJ9TWhP+tvLuP497CQS2g= -cloud.google.com/go/kms v1.12.1/go.mod h1:c9J991h5DTl+kg7gi3MYomh12YEENGrf48ee/N/2CDM= -cloud.google.com/go/kms v1.15.2/go.mod h1:3hopT4+7ooWRCjc2DxgnpESFxhIraaI2IpAVUEhbT/w= -cloud.google.com/go/kms v1.15.5/go.mod h1:cU2H5jnp6G2TDpUGZyqTCoy1n16fbubHZjmVXSMtwDI= -cloud.google.com/go/kms v1.15.7/go.mod h1:ub54lbsa6tDkUwnu4W7Yt1aAIFLnspgh0kPGToDukeI= -cloud.google.com/go/language v1.9.0 h1:7Ulo2mDk9huBoBi8zCE3ONOoBrL6UXfAI71CLQ9GEIM= -cloud.google.com/go/language v1.10.1/go.mod h1:CPp94nsdVNiQEt1CNjF5WkTcisLiHPyIbMhvR8H2AW0= -cloud.google.com/go/language v1.11.0/go.mod h1:uDx+pFDdAKTY8ehpWbiXyQdz8tDSYLJbQcXsCkjYyvQ= -cloud.google.com/go/language v1.12.2/go.mod h1:9idWapzr/JKXBBQ4lWqVX/hcadxB194ry20m/bTrhWc= -cloud.google.com/go/language v1.12.3/go.mod h1:evFX9wECX6mksEva8RbRnr/4wi/vKGYnAJrTRXU8+f8= -cloud.google.com/go/lifesciences v0.8.0 h1:uWrMjWTsGjLZpCTWEAzYvyXj+7fhiZST45u9AgasasI= -cloud.google.com/go/lifesciences v0.9.1/go.mod h1:hACAOd1fFbCGLr/+weUKRAJas82Y4vrL3O5326N//Wc= -cloud.google.com/go/lifesciences v0.9.4/go.mod h1:bhm64duKhMi7s9jR9WYJYvjAFJwRqNj+Nia7hF0Z7JA= -cloud.google.com/go/lifesciences v0.9.5/go.mod h1:OdBm0n7C0Osh5yZB7j9BXyrMnTRGBJIZonUMxo5CzPw= -cloud.google.com/go/logging v1.7.0 h1:CJYxlNNNNAMkHp9em/YEXcfJg+rPDg7YfwoRpMU+t5I= -cloud.google.com/go/logging v1.8.1/go.mod h1:TJjR+SimHwuC8MZ9cjByQulAMgni+RkXeI3wwctHJEI= -cloud.google.com/go/logging v1.9.0/go.mod h1:1Io0vnZv4onoUnsVUQY3HZ3Igb1nBchky0A0y7BBBhE= -cloud.google.com/go/longrunning v0.4.1 h1:v+yFJOfKC3yZdY6ZUI933pIYdhyhV8S3NpWrXWmg7jM= -cloud.google.com/go/longrunning v0.5.0/go.mod h1:0JNuqRShmscVAhIACGtskSAWtqtOoPkwP0YF1oVEchc= -cloud.google.com/go/longrunning v0.5.1/go.mod h1:spvimkwdz6SPWKEt/XBij79E9fiTkHSQl/fRUUQJYJc= -cloud.google.com/go/longrunning v0.5.2/go.mod h1:nqo6DQbNV2pXhGDbDMoN2bWz68MjZUzqv2YttZiveCs= -cloud.google.com/go/longrunning v0.5.4/go.mod h1:zqNVncI0BOP8ST6XQD1+VcvuShMmq7+xFSzOL++V0dI= -cloud.google.com/go/longrunning v0.5.5/go.mod h1:WV2LAxD8/rg5Z1cNW6FJ/ZpX4E4VnDnoTk0yawPBB7s= -cloud.google.com/go/managedidentities v1.5.0 h1:ZRQ4k21/jAhrHBVKl/AY7SjgzeJwG1iZa+mJ82P+VNg= -cloud.google.com/go/managedidentities v1.6.1/go.mod h1:h/irGhTN2SkZ64F43tfGPMbHnypMbu4RB3yl8YcuEak= -cloud.google.com/go/managedidentities v1.6.4/go.mod h1:WgyaECfHmF00t/1Uk8Oun3CQ2PGUtjc3e9Alh79wyiM= -cloud.google.com/go/managedidentities v1.6.5/go.mod h1:fkFI2PwwyRQbjLxlm5bQ8SjtObFMW3ChBGNqaMcgZjI= -cloud.google.com/go/maps v0.7.0 h1:mv9YaczD4oZBZkM5XJl6fXQ984IkJNHPwkc8MUsdkBo= -cloud.google.com/go/maps v1.4.0/go.mod h1:6mWTUv+WhnOwAgjVsSW2QPPECmW+s3PcRyOa9vgG/5s= -cloud.google.com/go/maps v1.6.1/go.mod h1:4+buOHhYXFBp58Zj/K+Lc1rCmJssxxF4pJ5CJnhdz18= -cloud.google.com/go/maps v1.6.3/go.mod h1:VGAn809ADswi1ASofL5lveOHPnE6Rk/SFTTBx1yuOLw= -cloud.google.com/go/maps v1.6.4/go.mod h1:rhjqRy8NWmDJ53saCfsXQ0LKwBHfi6OSh5wkq6BaMhI= -cloud.google.com/go/mediatranslation v0.7.0 h1:anPxH+/WWt8Yc3EdoEJhPMBRF7EhIdz426A+tuoA0OU= -cloud.google.com/go/mediatranslation v0.8.1/go.mod h1:L/7hBdEYbYHQJhX2sldtTO5SZZ1C1vkapubj0T2aGig= -cloud.google.com/go/mediatranslation v0.8.4/go.mod h1:9WstgtNVAdN53m6TQa5GjIjLqKQPXe74hwSCxUP6nj4= -cloud.google.com/go/mediatranslation v0.8.5/go.mod h1:y7kTHYIPCIfgyLbKncgqouXJtLsU+26hZhHEEy80fSs= -cloud.google.com/go/memcache v1.9.0 h1:8/VEmWCpnETCrBwS3z4MhT+tIdKgR1Z4Tr2tvYH32rg= -cloud.google.com/go/memcache v1.10.1/go.mod h1:47YRQIarv4I3QS5+hoETgKO40InqzLP6kpNLvyXuyaA= -cloud.google.com/go/memcache v1.10.4/go.mod h1:v/d8PuC8d1gD6Yn5+I3INzLR01IDn0N4Ym56RgikSI0= -cloud.google.com/go/memcache v1.10.5/go.mod h1:/FcblbNd0FdMsx4natdj+2GWzTq+cjZvMa1I+9QsuMA= -cloud.google.com/go/metastore v1.10.0 h1:QCFhZVe2289KDBQ7WxaHV2rAmPrmRAdLC6gbjUd3HPo= -cloud.google.com/go/metastore v1.11.1/go.mod h1:uZuSo80U3Wd4zi6C22ZZliOUJ3XeM/MlYi/z5OAOWRA= -cloud.google.com/go/metastore v1.12.0/go.mod h1:uZuSo80U3Wd4zi6C22ZZliOUJ3XeM/MlYi/z5OAOWRA= -cloud.google.com/go/metastore v1.13.3/go.mod h1:K+wdjXdtkdk7AQg4+sXS8bRrQa9gcOr+foOMF2tqINE= -cloud.google.com/go/metastore v1.13.4/go.mod h1:FMv9bvPInEfX9Ac1cVcRXp8EBBQnBcqH6gz3KvJ9BAE= -cloud.google.com/go/monitoring v1.13.0 h1:2qsrgXGVoRXpP7otZ14eE1I568zAa92sJSDPyOJvwjM= -cloud.google.com/go/monitoring v1.15.1/go.mod h1:lADlSAlFdbqQuwwpaImhsJXu1QSdd3ojypXrFSMr2rM= -cloud.google.com/go/monitoring v1.16.0/go.mod h1:Ptp15HgAyM1fNICAojDMoNc/wUmn67mLHQfyqbw+poY= -cloud.google.com/go/monitoring v1.16.3/go.mod h1:KwSsX5+8PnXv5NJnICZzW2R8pWTis8ypC4zmdRD63Tw= -cloud.google.com/go/monitoring v1.17.0/go.mod h1:KwSsX5+8PnXv5NJnICZzW2R8pWTis8ypC4zmdRD63Tw= -cloud.google.com/go/monitoring v1.18.0/go.mod h1:c92vVBCeq/OB4Ioyo+NbN2U7tlg5ZH41PZcdvfc+Lcg= -cloud.google.com/go/networkconnectivity v1.11.0 h1:ZD6b4Pk1jEtp/cx9nx0ZYcL3BKqDa+KixNDZ6Bjs1B8= -cloud.google.com/go/networkconnectivity v1.12.1/go.mod h1:PelxSWYM7Sh9/guf8CFhi6vIqf19Ir/sbfZRUwXh92E= -cloud.google.com/go/networkconnectivity v1.13.0/go.mod h1:SAnGPes88pl7QRLUen2HmcBSE9AowVAcdug8c0RSBFk= -cloud.google.com/go/networkconnectivity v1.14.3/go.mod h1:4aoeFdrJpYEXNvrnfyD5kIzs8YtHg945Og4koAjHQek= -cloud.google.com/go/networkconnectivity v1.14.4/go.mod h1:PU12q++/IMnDJAB+3r+tJtuCXCfwfN+C6Niyj6ji1Po= -cloud.google.com/go/networkmanagement v1.6.0 h1:8KWEUNGcpSX9WwZXq7FtciuNGPdPdPN/ruDm769yAEM= -cloud.google.com/go/networkmanagement v1.8.0/go.mod h1:Ho/BUGmtyEqrttTgWEe7m+8vDdK74ibQc+Be0q7Fof0= -cloud.google.com/go/networkmanagement v1.9.0/go.mod h1:UTUaEU9YwbCAhhz3jEOHr+2/K/MrBk2XxOLS89LQzFw= -cloud.google.com/go/networkmanagement v1.9.3/go.mod h1:y7WMO1bRLaP5h3Obm4tey+NquUvB93Co1oh4wpL+XcU= -cloud.google.com/go/networkmanagement v1.9.4/go.mod h1:daWJAl0KTFytFL7ar33I6R/oNBH8eEOX/rBNHrC/8TA= -cloud.google.com/go/networksecurity v0.8.0 h1:sOc42Ig1K2LiKlzG71GUVloeSJ0J3mffEBYmvu+P0eo= -cloud.google.com/go/networksecurity v0.9.1/go.mod h1:MCMdxOKQ30wsBI1eI659f9kEp4wuuAueoC9AJKSPWZQ= -cloud.google.com/go/networksecurity v0.9.4/go.mod h1:E9CeMZ2zDsNBkr8axKSYm8XyTqNhiCHf1JO/Vb8mD1w= -cloud.google.com/go/networksecurity v0.9.5/go.mod h1:KNkjH/RsylSGyyZ8wXpue8xpCEK+bTtvof8SBfIhMG8= -cloud.google.com/go/notebooks v1.8.0 h1:Kg2K3K7CbSXYJHZ1aGQpf1xi5x2GUvQWf2sFVuiZh8M= -cloud.google.com/go/notebooks v1.9.1/go.mod h1:zqG9/gk05JrzgBt4ghLzEepPHNwE5jgPcHZRKhlC1A8= -cloud.google.com/go/notebooks v1.10.0/go.mod h1:SOPYMZnttHxqot0SGSFSkRrwE29eqnKPBJFqgWmiK2k= -cloud.google.com/go/notebooks v1.11.2/go.mod h1:z0tlHI/lREXC8BS2mIsUeR3agM1AkgLiS+Isov3SS70= -cloud.google.com/go/notebooks v1.11.3/go.mod h1:0wQyI2dQC3AZyQqWnRsp+yA+kY4gC7ZIVP4Qg3AQcgo= -cloud.google.com/go/optimization v1.3.1 h1:dj8O4VOJRB4CUwZXdmwNViH1OtI0WtWL867/lnYH248= -cloud.google.com/go/optimization v1.4.1/go.mod h1:j64vZQP7h9bO49m2rVaTVoNM0vEBEN5eKPUPbZyXOrk= -cloud.google.com/go/optimization v1.5.0/go.mod h1:evo1OvTxeBRBu6ydPlrIRizKY/LJKo/drDMMRKqGEUU= -cloud.google.com/go/optimization v1.6.2/go.mod h1:mWNZ7B9/EyMCcwNl1frUGEuY6CPijSkz88Fz2vwKPOY= -cloud.google.com/go/optimization v1.6.3/go.mod h1:8ve3svp3W6NFcAEFr4SfJxrldzhUl4VMUJmhrqVKtYA= -cloud.google.com/go/orchestration v1.6.0 h1:Vw+CEXo8M/FZ1rb4EjcLv0gJqqw89b7+g+C/EmniTb8= -cloud.google.com/go/orchestration v1.8.1/go.mod h1:4sluRF3wgbYVRqz7zJ1/EUNc90TTprliq9477fGobD8= -cloud.google.com/go/orchestration v1.8.4/go.mod h1:d0lywZSVYtIoSZXb0iFjv9SaL13PGyVOKDxqGxEf/qI= -cloud.google.com/go/orchestration v1.8.5/go.mod h1:C1J7HesE96Ba8/hZ71ISTV2UAat0bwN+pi85ky38Yq8= -cloud.google.com/go/orgpolicy v1.10.0 h1:XDriMWug7sd0kYT1QKofRpRHzjad0bK8Q8uA9q+XrU4= -cloud.google.com/go/orgpolicy v1.11.1/go.mod h1:8+E3jQcpZJQliP+zaFfayC2Pg5bmhuLK755wKhIIUCE= -cloud.google.com/go/orgpolicy v1.11.4/go.mod h1:0+aNV/nrfoTQ4Mytv+Aw+stBDBjNf4d8fYRA9herfJI= -cloud.google.com/go/orgpolicy v1.12.0/go.mod h1:0+aNV/nrfoTQ4Mytv+Aw+stBDBjNf4d8fYRA9herfJI= -cloud.google.com/go/orgpolicy v1.12.1/go.mod h1:aibX78RDl5pcK3jA8ysDQCFkVxLj3aOQqrbBaUL2V5I= -cloud.google.com/go/osconfig v1.11.0 h1:PkSQx4OHit5xz2bNyr11KGcaFccL5oqglFPdTboyqwQ= -cloud.google.com/go/osconfig v1.12.1/go.mod h1:4CjBxND0gswz2gfYRCUoUzCm9zCABp91EeTtWXyz0tE= -cloud.google.com/go/osconfig v1.12.4/go.mod h1:B1qEwJ/jzqSRslvdOCI8Kdnp0gSng0xW4LOnIebQomA= -cloud.google.com/go/osconfig v1.12.5/go.mod h1:D9QFdxzfjgw3h/+ZaAb5NypM8bhOMqBzgmbhzWViiW8= -cloud.google.com/go/oslogin v1.9.0 h1:whP7vhpmc+ufZa90eVpkfbgzJRK/Xomjz+XCD4aGwWw= -cloud.google.com/go/oslogin v1.10.1/go.mod h1:x692z7yAue5nE7CsSnoG0aaMbNoRJRXO4sn73R+ZqAs= -cloud.google.com/go/oslogin v1.12.2/go.mod h1:CQ3V8Jvw4Qo4WRhNPF0o+HAM4DiLuE27Ul9CX9g2QdY= -cloud.google.com/go/oslogin v1.13.0/go.mod h1:xPJqLwpTZ90LSE5IL1/svko+6c5avZLluiyylMb/sRA= -cloud.google.com/go/oslogin v1.13.1/go.mod h1:vS8Sr/jR7QvPWpCjNqy6LYZr5Zs1e8ZGW/KPn9gmhws= -cloud.google.com/go/phishingprotection v0.7.0 h1:l6tDkT7qAEV49MNEJkEJTB6vOO/onbSOcNtAT09HPuA= -cloud.google.com/go/phishingprotection v0.8.1/go.mod h1:AxonW7GovcA8qdEk13NfHq9hNx5KPtfxXNeUxTDxB6I= -cloud.google.com/go/phishingprotection v0.8.4/go.mod h1:6b3kNPAc2AQ6jZfFHioZKg9MQNybDg4ixFd4RPZZ2nE= -cloud.google.com/go/phishingprotection v0.8.5/go.mod h1:g1smd68F7mF1hgQPuYn3z8HDbNre8L6Z0b7XMYFmX7I= -cloud.google.com/go/policytroubleshooter v1.6.0 h1:yKAGC4p9O61ttZUswaq9GAn1SZnEzTd0vUYXD7ZBT7Y= -cloud.google.com/go/policytroubleshooter v1.7.1/go.mod h1:0NaT5v3Ag1M7U5r0GfDCpUFkWd9YqpubBWsQlhanRv0= -cloud.google.com/go/policytroubleshooter v1.9.0/go.mod h1:+E2Lga7TycpeSTj2FsH4oXxTnrbHJGRlKhVZBLGgU64= -cloud.google.com/go/policytroubleshooter v1.10.2/go.mod h1:m4uF3f6LseVEnMV6nknlN2vYGRb+75ylQwJdnOXfnv0= -cloud.google.com/go/policytroubleshooter v1.10.3/go.mod h1:+ZqG3agHT7WPb4EBIRqUv4OyIwRTZvsVDHZ8GlZaoxk= -cloud.google.com/go/privatecatalog v0.8.0 h1:EPEJ1DpEGXLDnmc7mnCAqFmkwUJbIsaLAiLHVOkkwtc= -cloud.google.com/go/privatecatalog v0.9.1/go.mod h1:0XlDXW2unJXdf9zFz968Hp35gl/bhF4twwpXZAW50JA= -cloud.google.com/go/privatecatalog v0.9.4/go.mod h1:SOjm93f+5hp/U3PqMZAHTtBtluqLygrDrVO8X8tYtG0= -cloud.google.com/go/privatecatalog v0.9.5/go.mod h1:fVWeBOVe7uj2n3kWRGlUQqR/pOd450J9yZoOECcQqJk= -cloud.google.com/go/pubsub v1.30.0 h1:vCge8m7aUKBJYOgrZp7EsNDf6QMd2CAlXZqWTn3yq6s= -cloud.google.com/go/pubsub v1.32.0/go.mod h1:f+w71I33OMyxf9VpMVcZbnG5KSUkCOUHYpFd5U1GdRc= -cloud.google.com/go/pubsub v1.33.0/go.mod h1:f+w71I33OMyxf9VpMVcZbnG5KSUkCOUHYpFd5U1GdRc= -cloud.google.com/go/pubsub v1.34.0/go.mod h1:alj4l4rBg+N3YTFDDC+/YyFTs6JAjam2QfYsddcAW4c= -cloud.google.com/go/pubsub v1.36.1/go.mod h1:iYjCa9EzWOoBiTdd4ps7QoMtMln5NwaZQpK1hbRfBDE= -cloud.google.com/go/pubsublite v1.7.0 h1:cb9fsrtpINtETHiJ3ECeaVzrfIVhcGjhhJEjybHXHao= -cloud.google.com/go/pubsublite v1.8.1/go.mod h1:fOLdU4f5xldK4RGJrBMm+J7zMWNj/k4PxwEZXy39QS0= -cloud.google.com/go/recaptchaenterprise v1.3.1 h1:u6EznTGzIdsyOsvm+Xkw0aSuKFXQlyjGE9a4exk6iNQ= -cloud.google.com/go/recaptchaenterprise/v2 v2.7.0 h1:6iOCujSNJ0YS7oNymI64hXsjGq60T4FK1zdLugxbzvU= -cloud.google.com/go/recaptchaenterprise/v2 v2.7.2/go.mod h1:kR0KjsJS7Jt1YSyWFkseQ756D45kaYNTlDPPaRAvDBU= -cloud.google.com/go/recaptchaenterprise/v2 v2.8.3/go.mod h1:Dak54rw6lC2gBY8FBznpOCAR58wKf+R+ZSJRoeJok4w= -cloud.google.com/go/recaptchaenterprise/v2 v2.9.0/go.mod h1:Dak54rw6lC2gBY8FBznpOCAR58wKf+R+ZSJRoeJok4w= -cloud.google.com/go/recaptchaenterprise/v2 v2.9.2/go.mod h1:trwwGkfhCmp05Ll5MSJPXY7yvnO0p4v3orGANAFHAuU= -cloud.google.com/go/recommendationengine v0.7.0 h1:VibRFCwWXrFebEWKHfZAt2kta6pS7Tlimsnms0fjv7k= -cloud.google.com/go/recommendationengine v0.8.1/go.mod h1:MrZihWwtFYWDzE6Hz5nKcNz3gLizXVIDI/o3G1DLcrE= -cloud.google.com/go/recommendationengine v0.8.4/go.mod h1:GEteCf1PATl5v5ZsQ60sTClUE0phbWmo3rQ1Js8louU= -cloud.google.com/go/recommendationengine v0.8.5/go.mod h1:A38rIXHGFvoPvmy6pZLozr0g59NRNREz4cx7F58HAsQ= -cloud.google.com/go/recommender v1.9.0 h1:ZnFRY5R6zOVk2IDS1Jbv5Bw+DExCI5rFumsTnMXiu/A= -cloud.google.com/go/recommender v1.10.1/go.mod h1:XFvrE4Suqn5Cq0Lf+mCP6oBHD/yRMA8XxP5sb7Q7gpA= -cloud.google.com/go/recommender v1.11.0/go.mod h1:kPiRQhPyTJ9kyXPCG6u/dlPLbYfFlkwHNRwdzPVAoII= -cloud.google.com/go/recommender v1.11.3/go.mod h1:+FJosKKJSId1MBFeJ/TTyoGQZiEelQQIZMKYYD8ruK4= -cloud.google.com/go/recommender v1.12.0/go.mod h1:+FJosKKJSId1MBFeJ/TTyoGQZiEelQQIZMKYYD8ruK4= -cloud.google.com/go/recommender v1.12.1/go.mod h1:gf95SInWNND5aPas3yjwl0I572dtudMhMIG4ni8nr+0= -cloud.google.com/go/redis v1.11.0 h1:JoAd3SkeDt3rLFAAxEvw6wV4t+8y4ZzfZcZmddqphQ8= -cloud.google.com/go/redis v1.13.1/go.mod h1:VP7DGLpE91M6bcsDdMuyCm2hIpB6Vp2hI090Mfd1tcg= -cloud.google.com/go/redis v1.14.1/go.mod h1:MbmBxN8bEnQI4doZPC1BzADU4HGocHBk2de3SbgOkqs= -cloud.google.com/go/redis v1.14.2/go.mod h1:g0Lu7RRRz46ENdFKQ2EcQZBAJ2PtJHJLuiiRuEXwyQw= -cloud.google.com/go/resourcemanager v1.7.0 h1:NRM0p+RJkaQF9Ee9JMnUV9BQ2QBIOq/v8M+Pbv/wmCs= -cloud.google.com/go/resourcemanager v1.9.1/go.mod h1:dVCuosgrh1tINZ/RwBufr8lULmWGOkPS8gL5gqyjdT8= -cloud.google.com/go/resourcemanager v1.9.4/go.mod h1:N1dhP9RFvo3lUfwtfLWVxfUWq8+KUQ+XLlHLH3BoFJ0= -cloud.google.com/go/resourcemanager v1.9.5/go.mod h1:hep6KjelHA+ToEjOfO3garMKi/CLYwTqeAw7YiEI9x8= -cloud.google.com/go/resourcesettings v1.5.0 h1:8Dua37kQt27CCWHm4h/Q1XqCF6ByD7Ouu49xg95qJzI= -cloud.google.com/go/resourcesettings v1.6.1/go.mod h1:M7mk9PIZrC5Fgsu1kZJci6mpgN8o0IUzVx3eJU3y4Jw= -cloud.google.com/go/resourcesettings v1.6.4/go.mod h1:pYTTkWdv2lmQcjsthbZLNBP4QW140cs7wqA3DuqErVI= -cloud.google.com/go/resourcesettings v1.6.5/go.mod h1:WBOIWZraXZOGAgoR4ukNj0o0HiSMO62H9RpFi9WjP9I= -cloud.google.com/go/retail v1.12.0 h1:1Dda2OpFNzIb4qWgFZjYlpP7sxX3aLeypKG6A3H4Yys= -cloud.google.com/go/retail v1.14.1/go.mod h1:y3Wv3Vr2k54dLNIrCzenyKG8g8dhvhncT2NcNjb/6gE= -cloud.google.com/go/retail v1.14.4/go.mod h1:l/N7cMtY78yRnJqp5JW8emy7MB1nz8E4t2yfOmklYfg= -cloud.google.com/go/retail v1.16.0/go.mod h1:LW7tllVveZo4ReWt68VnldZFWJRzsh9np+01J9dYWzE= -cloud.google.com/go/run v0.9.0 h1:ydJQo+k+MShYnBfhaRHSZYeD/SQKZzZLAROyfpeD9zw= -cloud.google.com/go/run v1.2.0/go.mod h1:36V1IlDzQ0XxbQjUx6IYbw8H3TJnWvhii963WW3B/bo= -cloud.google.com/go/run v1.3.3/go.mod h1:WSM5pGyJ7cfYyYbONVQBN4buz42zFqwG67Q3ch07iK4= -cloud.google.com/go/run v1.3.4/go.mod h1:FGieuZvQ3tj1e9GnzXqrMABSuir38AJg5xhiYq+SF3o= -cloud.google.com/go/scheduler v1.9.0 h1:NpQAHtx3sulByTLe2dMwWmah8PWgeoieFPpJpArwFV0= -cloud.google.com/go/scheduler v1.10.1/go.mod h1:R63Ldltd47Bs4gnhQkmNDse5w8gBRrhObZ54PxgR2Oo= -cloud.google.com/go/scheduler v1.10.4/go.mod h1:MTuXcrJC9tqOHhixdbHDFSIuh7xZF2IysiINDuiq6NI= -cloud.google.com/go/scheduler v1.10.5/go.mod h1:MTuXcrJC9tqOHhixdbHDFSIuh7xZF2IysiINDuiq6NI= -cloud.google.com/go/scheduler v1.10.6/go.mod h1:pe2pNCtJ+R01E06XCDOJs1XvAMbv28ZsQEbqknxGOuE= -cloud.google.com/go/secretmanager v1.10.0 h1:pu03bha7ukxF8otyPKTFdDz+rr9sE3YauS5PliDXK60= -cloud.google.com/go/secretmanager v1.11.1/go.mod h1:znq9JlXgTNdBeQk9TBW/FnR/W4uChEKGeqQWAJ8SXFw= -cloud.google.com/go/secretmanager v1.11.4/go.mod h1:wreJlbS9Zdq21lMzWmJ0XhWW2ZxgPeahsqeV/vZoJ3w= -cloud.google.com/go/secretmanager v1.11.5/go.mod h1:eAGv+DaCHkeVyQi0BeXgAHOU0RdrMeZIASKc+S7VqH4= -cloud.google.com/go/security v1.13.0 h1:PYvDxopRQBfYAXKAuDpFCKBvDOWPWzp9k/H5nB3ud3o= -cloud.google.com/go/security v1.15.1/go.mod h1:MvTnnbsWnehoizHi09zoiZob0iCHVcL4AUBj76h9fXA= -cloud.google.com/go/security v1.15.4/go.mod h1:oN7C2uIZKhxCLiAAijKUCuHLZbIt/ghYEo8MqwD/Ty4= -cloud.google.com/go/security v1.15.5/go.mod h1:KS6X2eG3ynWjqcIX976fuToN5juVkF6Ra6c7MPnldtc= -cloud.google.com/go/securitycenter v1.19.0 h1:AF3c2s3awNTMoBtMX3oCUoOMmGlYxGOeuXSYHNBkf14= -cloud.google.com/go/securitycenter v1.23.0/go.mod h1:8pwQ4n+Y9WCWM278R8W3nF65QtY172h4S8aXyI9/hsQ= -cloud.google.com/go/securitycenter v1.24.2/go.mod h1:l1XejOngggzqwr4Fa2Cn+iWZGf+aBLTXtB/vXjy5vXM= -cloud.google.com/go/securitycenter v1.24.3/go.mod h1:l1XejOngggzqwr4Fa2Cn+iWZGf+aBLTXtB/vXjy5vXM= -cloud.google.com/go/securitycenter v1.24.4/go.mod h1:PSccin+o1EMYKcFQzz9HMMnZ2r9+7jbc+LvPjXhpwcU= -cloud.google.com/go/servicecontrol v1.11.1 h1:d0uV7Qegtfaa7Z2ClDzr9HJmnbJW7jn0WhZ7wOX6hLE= -cloud.google.com/go/servicedirectory v1.9.0 h1:SJwk0XX2e26o25ObYUORXx6torSFiYgsGkWSkZgkoSU= -cloud.google.com/go/servicedirectory v1.10.1/go.mod h1:Xv0YVH8s4pVOwfM/1eMTl0XJ6bzIOSLDt8f8eLaGOxQ= -cloud.google.com/go/servicedirectory v1.11.0/go.mod h1:Xv0YVH8s4pVOwfM/1eMTl0XJ6bzIOSLDt8f8eLaGOxQ= -cloud.google.com/go/servicedirectory v1.11.3/go.mod h1:LV+cHkomRLr67YoQy3Xq2tUXBGOs5z5bPofdq7qtiAw= -cloud.google.com/go/servicedirectory v1.11.4/go.mod h1:Bz2T9t+/Ehg6x+Y7Ycq5xiShYLD96NfEsWNHyitj1qM= -cloud.google.com/go/servicemanagement v1.8.0 h1:fopAQI/IAzlxnVeiKn/8WiV6zKndjFkvi+gzu+NjywY= -cloud.google.com/go/serviceusage v1.6.0 h1:rXyq+0+RSIm3HFypctp7WoXxIA563rn206CfMWdqXX4= -cloud.google.com/go/shell v1.6.0 h1:wT0Uw7ib7+AgZST9eCDygwTJn4+bHMDtZo5fh7kGWDU= -cloud.google.com/go/shell v1.7.1/go.mod h1:u1RaM+huXFaTojTbW4g9P5emOrrmLE69KrxqQahKn4g= -cloud.google.com/go/shell v1.7.4/go.mod h1:yLeXB8eKLxw0dpEmXQ/FjriYrBijNsONpwnWsdPqlKM= -cloud.google.com/go/shell v1.7.5/go.mod h1:hL2++7F47/IfpfTO53KYf1EC+F56k3ThfNEXd4zcuiE= -cloud.google.com/go/spanner v1.45.0 h1:7VdjZ8zj4sHbDw55atp5dfY6kn1j9sam9DRNpPQhqR4= -cloud.google.com/go/spanner v1.47.0/go.mod h1:IXsJwVW2j4UKs0eYDqodab6HgGuA1bViSqW4uH9lfUI= -cloud.google.com/go/spanner v1.49.0/go.mod h1:eGj9mQGK8+hkgSVbHNQ06pQ4oS+cyc4tXXd6Dif1KoM= -cloud.google.com/go/spanner v1.51.0/go.mod h1:c5KNo5LQ1X5tJwma9rSQZsXNBDNvj4/n8BVc3LNahq0= -cloud.google.com/go/spanner v1.55.0/go.mod h1:HXEznMUVhC+PC+HDyo9YFG2Ajj5BQDkcbqB9Z2Ffxi0= -cloud.google.com/go/spanner v1.56.0/go.mod h1:DndqtUKQAt3VLuV2Le+9Y3WTnq5cNKrnLb/Piqcj+h0= -cloud.google.com/go/spanner v1.57.0/go.mod h1:aXQ5QDdhPRIqVhYmnkAdwPYvj/DRN0FguclhEWw+jOo= -cloud.google.com/go/speech v1.15.0 h1:JEVoWGNnTF128kNty7T4aG4eqv2z86yiMJPT9Zjp+iw= -cloud.google.com/go/speech v1.17.1/go.mod h1:8rVNzU43tQvxDaGvqOhpDqgkJTFowBpDvCJ14kGlJYo= -cloud.google.com/go/speech v1.19.0/go.mod h1:8rVNzU43tQvxDaGvqOhpDqgkJTFowBpDvCJ14kGlJYo= -cloud.google.com/go/speech v1.20.1/go.mod h1:wwolycgONvfz2EDU8rKuHRW3+wc9ILPsAWoikBEWavY= -cloud.google.com/go/speech v1.21.0/go.mod h1:wwolycgONvfz2EDU8rKuHRW3+wc9ILPsAWoikBEWavY= -cloud.google.com/go/speech v1.21.1/go.mod h1:E5GHZXYQlkqWQwY5xRSLHw2ci5NMQNG52FfMU1aZrIA= -cloud.google.com/go/storage v1.29.0 h1:6weCgzRvMg7lzuUurI4697AqIRPU1SvzHhynwpW31jI= -cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E= -cloud.google.com/go/storage v1.36.0/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8= -cloud.google.com/go/storagetransfer v1.8.0 h1:5T+PM+3ECU3EY2y9Brv0Sf3oka8pKmsCfpQ07+91G9o= -cloud.google.com/go/storagetransfer v1.10.0/go.mod h1:DM4sTlSmGiNczmV6iZyceIh2dbs+7z2Ayg6YAiQlYfA= -cloud.google.com/go/storagetransfer v1.10.3/go.mod h1:Up8LY2p6X68SZ+WToswpQbQHnJpOty/ACcMafuey8gc= -cloud.google.com/go/storagetransfer v1.10.4/go.mod h1:vef30rZKu5HSEf/x1tK3WfWrL0XVoUQN/EPDRGPzjZs= -cloud.google.com/go/talent v1.5.0 h1:nI9sVZPjMKiO2q3Uu0KhTDVov3Xrlpt63fghP9XjyEM= -cloud.google.com/go/talent v1.6.2/go.mod h1:CbGvmKCG61mkdjcqTcLOkb2ZN1SrQI8MDyma2l7VD24= -cloud.google.com/go/talent v1.6.5/go.mod h1:Mf5cma696HmE+P2BWJ/ZwYqeJXEeU0UqjHFXVLadEDI= -cloud.google.com/go/talent v1.6.6/go.mod h1:y/WQDKrhVz12WagoarpAIyKKMeKGKHWPoReZ0g8tseQ= -cloud.google.com/go/texttospeech v1.6.0 h1:H4g1ULStsbVtalbZGktyzXzw6jP26RjVGYx9RaYjBzc= -cloud.google.com/go/texttospeech v1.7.1/go.mod h1:m7QfG5IXxeneGqTapXNxv2ItxP/FS0hCZBwXYqucgSk= -cloud.google.com/go/texttospeech v1.7.4/go.mod h1:vgv0002WvR4liGuSd5BJbWy4nDn5Ozco0uJymY5+U74= -cloud.google.com/go/texttospeech v1.7.5/go.mod h1:tzpCuNWPwrNJnEa4Pu5taALuZL4QRRLcb+K9pbhXT6M= -cloud.google.com/go/tpu v1.5.0 h1:/34T6CbSi+kTv5E19Q9zbU/ix8IviInZpzwz3rsFE+A= -cloud.google.com/go/tpu v1.6.1/go.mod h1:sOdcHVIgDEEOKuqUoi6Fq53MKHJAtOwtz0GuKsWSH3E= -cloud.google.com/go/tpu v1.6.4/go.mod h1:NAm9q3Rq2wIlGnOhpYICNI7+bpBebMJbh0yyp3aNw1Y= -cloud.google.com/go/tpu v1.6.5/go.mod h1:P9DFOEBIBhuEcZhXi+wPoVy/cji+0ICFi4TtTkMHSSs= -cloud.google.com/go/trace v1.9.0 h1:olxC0QHC59zgJVALtgqfD9tGk0lfeCP5/AGXL3Px/no= -cloud.google.com/go/trace v1.10.1/go.mod h1:gbtL94KE5AJLH3y+WVpfWILmqgc6dXcqgNXdOPAQTYk= -cloud.google.com/go/trace v1.10.4/go.mod h1:Nso99EDIK8Mj5/zmB+iGr9dosS/bzWCJ8wGmE6TXNWY= -cloud.google.com/go/trace v1.10.5/go.mod h1:9hjCV1nGBCtXbAE4YK7OqJ8pmPYSxPA0I67JwRd5s3M= -cloud.google.com/go/translate v1.7.0 h1:GvLP4oQ4uPdChBmBaUSa/SaZxCdyWELtlAaKzpHsXdA= -cloud.google.com/go/translate v1.8.1/go.mod h1:d1ZH5aaOA0CNhWeXeC8ujd4tdCFw8XoNWRljklu5RHs= -cloud.google.com/go/translate v1.9.0/go.mod h1:d1ZH5aaOA0CNhWeXeC8ujd4tdCFw8XoNWRljklu5RHs= -cloud.google.com/go/translate v1.9.3/go.mod h1:Kbq9RggWsbqZ9W5YpM94Q1Xv4dshw/gr/SHfsl5yCZ0= -cloud.google.com/go/translate v1.10.0/go.mod h1:Kbq9RggWsbqZ9W5YpM94Q1Xv4dshw/gr/SHfsl5yCZ0= -cloud.google.com/go/translate v1.10.1/go.mod h1:adGZcQNom/3ogU65N9UXHOnnSvjPwA/jKQUMnsYXOyk= -cloud.google.com/go/video v1.15.0 h1:upIbnGI0ZgACm58HPjAeBMleW3sl5cT84AbYQ8PWOgM= -cloud.google.com/go/video v1.17.1/go.mod h1:9qmqPqw/Ib2tLqaeHgtakU+l5TcJxCJbhFXM7UJjVzU= -cloud.google.com/go/video v1.20.0/go.mod h1:U3G3FTnsvAGqglq9LxgqzOiBc/Nt8zis8S+850N2DUM= -cloud.google.com/go/video v1.20.3/go.mod h1:TnH/mNZKVHeNtpamsSPygSR0iHtvrR/cW1/GDjN5+GU= -cloud.google.com/go/video v1.20.4/go.mod h1:LyUVjyW+Bwj7dh3UJnUGZfyqjEto9DnrvTe1f/+QrW0= -cloud.google.com/go/videointelligence v1.10.0 h1:Uh5BdoET8XXqXX2uXIahGb+wTKbLkGH7s4GXR58RrG8= -cloud.google.com/go/videointelligence v1.11.1/go.mod h1:76xn/8InyQHarjTWsBR058SmlPCwQjgcvoW0aZykOvo= -cloud.google.com/go/videointelligence v1.11.4/go.mod h1:kPBMAYsTPFiQxMLmmjpcZUMklJp3nC9+ipJJtprccD8= -cloud.google.com/go/videointelligence v1.11.5/go.mod h1:/PkeQjpRponmOerPeJxNPuxvi12HlW7Em0lJO14FC3I= -cloud.google.com/go/vision v1.2.0 h1:/CsSTkbmO9HC8iQpxbK8ATms3OQaX3YQUeTMGCxlaK4= -cloud.google.com/go/vision/v2 v2.7.0 h1:8C8RXUJoflCI4yVdqhTy9tRyygSHmp60aP363z23HKg= -cloud.google.com/go/vision/v2 v2.7.2/go.mod h1:jKa8oSYBWhYiXarHPvP4USxYANYUEdEsQrloLjrSwJU= -cloud.google.com/go/vision/v2 v2.7.5/go.mod h1:GcviprJLFfK9OLf0z8Gm6lQb6ZFUulvpZws+mm6yPLM= -cloud.google.com/go/vision/v2 v2.8.0/go.mod h1:ocqDiA2j97pvgogdyhoxiQp2ZkDCyr0HWpicywGGRhU= -cloud.google.com/go/vmmigration v1.6.0 h1:Azs5WKtfOC8pxvkyrDvt7J0/4DYBch0cVbuFfCCFt5k= -cloud.google.com/go/vmmigration v1.7.1/go.mod h1:WD+5z7a/IpZ5bKK//YmT9E047AD+rjycCAvyMxGJbro= -cloud.google.com/go/vmmigration v1.7.4/go.mod h1:yBXCmiLaB99hEl/G9ZooNx2GyzgsjKnw5fWcINRgD70= -cloud.google.com/go/vmmigration v1.7.5/go.mod h1:pkvO6huVnVWzkFioxSghZxIGcsstDvYiVCxQ9ZH3eYI= -cloud.google.com/go/vmwareengine v0.3.0 h1:b0NBu7S294l0gmtrT0nOJneMYgZapr5x9tVWvgDoVEM= -cloud.google.com/go/vmwareengine v0.4.1/go.mod h1:Px64x+BvjPZwWuc4HdmVhoygcXqEkGHXoa7uyfTgSI0= -cloud.google.com/go/vmwareengine v1.0.0/go.mod h1:Px64x+BvjPZwWuc4HdmVhoygcXqEkGHXoa7uyfTgSI0= -cloud.google.com/go/vmwareengine v1.0.3/go.mod h1:QSpdZ1stlbfKtyt6Iu19M6XRxjmXO+vb5a/R6Fvy2y4= -cloud.google.com/go/vmwareengine v1.1.1/go.mod h1:nMpdsIVkUrSaX8UvmnBhzVzG7PPvNYc5BszcvIVudYs= -cloud.google.com/go/vpcaccess v1.6.0 h1:FOe6CuiQD3BhHJWt7E8QlbBcaIzVRddupwJlp7eqmn4= -cloud.google.com/go/vpcaccess v1.7.1/go.mod h1:FogoD46/ZU+JUBX9D606X21EnxiszYi2tArQwLY4SXs= -cloud.google.com/go/vpcaccess v1.7.4/go.mod h1:lA0KTvhtEOb/VOdnH/gwPuOzGgM+CWsmGu6bb4IoMKk= -cloud.google.com/go/vpcaccess v1.7.5/go.mod h1:slc5ZRvvjP78c2dnL7m4l4R9GwL3wDLcpIWz6P/ziig= -cloud.google.com/go/webrisk v1.8.0 h1:IY+L2+UwxcVm2zayMAtBhZleecdIFLiC+QJMzgb0kT0= -cloud.google.com/go/webrisk v1.9.1/go.mod h1:4GCmXKcOa2BZcZPn6DCEvE7HypmEJcJkr4mtM+sqYPc= -cloud.google.com/go/webrisk v1.9.4/go.mod h1:w7m4Ib4C+OseSr2GL66m0zMBywdrVNTDKsdEsfMl7X0= -cloud.google.com/go/webrisk v1.9.5/go.mod h1:aako0Fzep1Q714cPEM5E+mtYX8/jsfegAuS8aivxy3U= -cloud.google.com/go/websecurityscanner v1.5.0 h1:AHC1xmaNMOZtNqxI9Rmm87IJEyPaRkOxeI0gpAacXGk= -cloud.google.com/go/websecurityscanner v1.6.1/go.mod h1:Njgaw3rttgRHXzwCB8kgCYqv5/rGpFCsBOvPbYgszpg= -cloud.google.com/go/websecurityscanner v1.6.4/go.mod h1:mUiyMQ+dGpPPRkHgknIZeCzSHJ45+fY4F52nZFDHm2o= -cloud.google.com/go/websecurityscanner v1.6.5/go.mod h1:QR+DWaxAz2pWooylsBF854/Ijvuoa3FCyS1zBa1rAVQ= -cloud.google.com/go/workflows v1.10.0 h1:FfGp9w0cYnaKZJhUOMqCOJCYT/WlvYBfTQhFWV3sRKI= -cloud.google.com/go/workflows v1.11.1/go.mod h1:Z+t10G1wF7h8LgdY/EmRcQY8ptBD/nvofaL6FqlET6g= -cloud.google.com/go/workflows v1.12.0/go.mod h1:PYhSk2b6DhZ508tj8HXKaBh+OFe+xdl0dHF/tJdzPQM= -cloud.google.com/go/workflows v1.12.3/go.mod h1:fmOUeeqEwPzIU81foMjTRQIdwQHADi/vEr1cx9R1m5g= -cloud.google.com/go/workflows v1.12.4/go.mod h1:yQ7HUqOkdJK4duVtMeBCAOPiN1ZF1E9pAMX51vpwB/w= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9 h1:VpgP7xuJadIUuKccphEpTJnWhS2jkQyMt6Y7pJCD7fY= -gioui.org v0.0.0-20210308172011-57750fc8a0a6 h1:K72hopUosKG3ntOPNG4OzzbuhxGuVf06fa2la1/H/Ho= -git.sr.ht/~sbinet/gg v0.3.1 h1:LNhjNn8DerC8f9DHLz6lS0YYul/b602DUxDgGkd/Aik= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc= -github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c h1:RGWPOewvKIROun94nF7v2cua9qP+thov/7M50KEoeSU= -github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= -github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= -github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= -github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= -github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9 h1:7kQgkwGRoLzC9K0oyXdJo7nve/bynv/KwUsxbiTlzAM= -github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19 h1:iXUgAaqDcIUGbRoy2TdeofRG/j1zpGRSEmNK05T+bi8= -github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b h1:slYM766cy2nI3BwyRiyQj/Ud48djTMtMebDqepE95rw= -github.com/alecthomas/kingpin/v2 v2.4.0 h1:f48lwail6p8zpO1bC4TxtqACaGqHYA22qkHjHpqDjYY= -github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= -github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= -github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= -github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= -github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg= -github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df h1:7RFfzj4SSt6nnvCPbCqijJi1nWCd+TqAT3bYCStRC18= -github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM= -github.com/apache/arrow/go/v10 v10.0.1 h1:n9dERvixoC/1JjDmBcs9FPaEryoANa2sCgVFo6ez9cI= -github.com/apache/arrow/go/v11 v11.0.0 h1:hqauxvFQxww+0mEU/2XHG6LT7eZternCZq+A5Yly2uM= -github.com/apache/thrift v0.16.0 h1:qEy6UW60iVOlUy+b9ZR0d5WzUWYGOo4HfopoyBaNmoY= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= -github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= -github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= -github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= -github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs= -github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= -github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= -github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= -github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= -github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= -github.com/checkpoint-restore/go-criu/v5 v5.3.0 h1:wpFFOoomK3389ue2lAb0Boag6XPht5QYpipxmSNL4d8= -github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= -github.com/chromedp/cdproto v0.0.0-20230802225258-3cf4e6d46a89 h1:aPflPkRFkVwbW6dmcVqfgwp1i+UWGFH6VgR1Jim5Ygc= -github.com/chromedp/cdproto v0.0.0-20230802225258-3cf4e6d46a89/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs= -github.com/chromedp/chromedp v0.9.2 h1:dKtNz4kApb06KuSXoTQIyUC2TrA0fhGDwNZf3bcgfKw= -github.com/chromedp/chromedp v0.9.2/go.mod h1:LkSXJKONWTCHAfQasKFUZI+mxqS4tZqhmtGzzhLsnLs= -github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic= -github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM= -github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI= -github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04= -github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= -github.com/cilium/ebpf v0.7.0 h1:1k/q3ATgxSXRdrmPfH8d7YK0GfqVsEKZAX9dQZvs56k= -github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= -github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= -github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe h1:QQ3GSy+MqSHxm/d8nCtnAiZdYFd45cYZPs8vOOIYKfk= -github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa h1:jQCWAUqqlij9Pgj2i/PB79y4KOPYVyFYdROxgaCwdTQ= -github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq8dk6e9PdstVsDgu9RuyIIJqAaF//0IM= -github.com/cncf/xds/go v0.0.0-20240318125728-8a4994d93e50/go.mod h1:5e1+Vvlzido69INQaVO6d87Qn543Xr6nooe9Kz7oBFM= -github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= -github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw= -github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= -github.com/coreos/go-oidc v2.2.1+incompatible h1:mh48q/BqXqgjVHpy2ZY7WnWAbenxRjsz9N1i1YxjHAk= -github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= -github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= -github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8= -github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= -github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= -github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 h1:bWDMxwH3px2JBh6AyO7hdCn/PkvCZXii8TGj7sbtEbQ= -github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= -github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk= -github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/envoyproxy/go-control-plane v0.11.1/go.mod h1:uhMcXKCQMEJHiAb0w+YGefQLaTEw+YhGluxZkrTmD0g= -github.com/envoyproxy/go-control-plane v0.12.0 h1:4X+VP1GHd1Mhj6IB5mMeGbLCleqxjletLK6K0rbxyZI= -github.com/envoyproxy/go-control-plane v0.12.0/go.mod h1:ZBTaoJ23lqITozF0M6G4/IragXCQKCnYbmlmtHvwRG0= -github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= -github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A= -github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= -github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= -github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8= -github.com/fxamacker/cbor/v2 v2.6.0 h1:sU6J2usfADwWlYDAFhZBQ6TnLFBHxgesMrQfQgk1tWA= -github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= -github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= -github.com/getsentry/sentry-go v0.21.0 h1:c9l5F1nPF30JIppulk4veau90PK6Smu3abgVtVQWon4= -github.com/getsentry/sentry-go v0.21.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= -github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= -github.com/go-fonts/dejavu v0.1.0 h1:JSajPXURYqpr+Cu8U9bt8K+XcACIHWqWrvWCKyeFmVQ= -github.com/go-fonts/latin-modern v0.2.0 h1:5/Tv1Ek/QCr20C6ZOz15vw3g7GELYL98KWr8Hgo+3vk= -github.com/go-fonts/liberation v0.2.0 h1:jAkAWJP4S+OsrPLZM4/eC9iW7CtHy+HBXrEwZXWo5VM= -github.com/go-fonts/stix v0.1.0 h1:UlZlgrvvmT/58o573ot7NFw0vZasZ5I6bcIft/oMdgg= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4 h1:WtGNWLvXpe6ZudgnXrq0barxBImvnnJoMEhXAzcbM0I= -github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= -github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= -github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81 h1:6zl3BbBhdnMkpSj2YY30qV3gDcVBGtFgVsV3+/i+mKQ= -github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/swag v0.22.5/go.mod h1:Gl91UqO+btAM0plGGxHqJcQZ1ZTy6jbmridBTsDy8A0= -github.com/go-openapi/swag v0.22.6/go.mod h1:Gl91UqO+btAM0plGGxHqJcQZ1ZTy6jbmridBTsDy8A0= -github.com/go-pdf/fpdf v0.6.0 h1:MlgtGIfsdMEEQJr2le6b/HNr1ZlQwxyWr77r2aj2U/8= -github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= -github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= -github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= -github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= -github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= -github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= -github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= -github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= -github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= -github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.2.1 h1:F2aeBZrm2NDsc7vbovKrWSogd4wvfAxg0FQ89/iqOTk= -github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= -github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= -github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= -github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= -github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68= -github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= -github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= -github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= -github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= -github.com/google/cel-go v0.17.7/go.mod h1:HXZKzB0LXqer5lHHgfWAnlYwJaQBDKMjxjulNQzhwhY= -github.com/google/cel-go v0.17.8 h1:j9m730pMZt1Fc4oKhCLUHfjj6527LuhYcYw0Rl8gqto= -github.com/google/cel-go v0.17.8/go.mod h1:HXZKzB0LXqer5lHHgfWAnlYwJaQBDKMjxjulNQzhwhY= -github.com/google/flatbuffers v2.0.8+incompatible h1:ivUb1cGomAB101ZM1T0nOiWz9pSrTMoa9+EiY7igmkM= -github.com/google/go-pkcs11 v0.2.1-0.20230907215043-c6f79328ddf9/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY= -github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= -github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA= -github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc= -github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= -github.com/googleapis/enterprise-certificate-proxy v0.2.4/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= -github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= -github.com/googleapis/gax-go/v2 v2.11.0 h1:9V9PWXEsWnPpQhu/PeQIkS4eGzMlTLGgt80cUUI8Ki4= -github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= -github.com/googleapis/go-type-adapters v1.0.0 h1:9XdMn+d/G57qq1s8dNc5IesGCXHf6V2HZ2JwRxfA2tA= -github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8 h1:tlyzajkF3030q6M8SvmJSemC9DTHL/xaMa18b65+JM4= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= -github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= -github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0= -github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20230524184225-eabc099b10ab/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw= -github.com/ianlancetaylor/demangle v0.0.0-20240312041847-bd984b5ce465 h1:KwWnWVWCNtNq/ewIX7HIKnELmEx2nDP42yskD/pi7QE= -github.com/ianlancetaylor/demangle v0.0.0-20240312041847-bd984b5ce465/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw= -github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= -github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ= -github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= -github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= -github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5 h1:PJr+ZMXIecYc1Ey2zucXdR73SMBtgjPgwa31099IMv0= -github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= -github.com/kisielk/errcheck v1.5.0 h1:e8esj/e4R+SAOwFwN+n3zr0nYeCyeweozKfO23MvHzY= -github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= -github.com/klauspost/asmfmt v1.3.2 h1:4Ri7ox3EwapiOjCki+hw14RyKk201CN4rzyCJRFLpK4= -github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= -github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= -github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= -github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= -github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= -github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= -github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= -github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw= -github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN2M= -github.com/labstack/echo/v4 v4.10.2/go.mod h1:OEyqf2//K1DFdE57vw2DRgWY0M7s65IVQO2FzvI4J5k= -github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= -github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= -github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kULo2bwGEkFvCePZ3qHDDTC3/J9Swo= -github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= -github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= -github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= -github.com/lyft/protoc-gen-star v0.6.1 h1:erE0rdztuaDq3bpGifD95wfoPrSZc95nGA6tbiNYh6M= -github.com/lyft/protoc-gen-star/v2 v2.0.1 h1:keaAo8hRuAT0O3DfJ/wM3rufbAjGeJ1lAtWZHDjKGB0= -github.com/lyft/protoc-gen-star/v2 v2.0.3/go.mod h1:amey7yeodaJhXSbf/TlLvWiqQfLOSpEk//mLlc+axEk= -github.com/mattn/go-sqlite3 v1.14.14 h1:qZgc/Rwetq+MtyE18WhzjokPD93dNqLGNT3QJuLvBGw= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= -github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 h1:AMFGa4R4MiIpspGNG7Z948v4n35fFGB3RR3G/ry4FWs= -github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3 h1:+n/aFZefKZp7spd8DFdX7uMikMLXX4oubIzJF4kv/wI= -github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= -github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/mrunalp/fileutils v0.5.1 h1:F+S7ZlNKnrwHfSwdlgNSkKo67ReVf8o9fel6C3dkm/Q= -github.com/mrunalp/fileutils v0.5.1/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= -github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= -github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/ncabatoff/fakescraper v0.0.0-20201102132415-4b37ba603d65 h1:Og+dVkxEQNvRGU2vUKeOwYT2UJ+pEaDMWB6tIQnIh6A= -github.com/ncabatoff/fakescraper v0.0.0-20201102132415-4b37ba603d65/go.mod h1:Tx6UMSMyIsjLG/VU/F6xA1+0XI+/f9o1dGJnf1l+bPg= -github.com/onsi/ginkgo/v2 v/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= -github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= -github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= -github.com/onsi/ginkgo/v2 v2.17.2/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= -github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= -github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.31.0/go.mod h1:DW9aCi7U6Yi40wNVAvT6kzFnEVEI5n3DloYBiKiT6zk= -github.com/onsi/gomega v1.33.0/go.mod h1:+925n5YtiFsLzzafLUHzVMBpvvRAzrydIBiSIxjX3wY= -github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= -github.com/opencontainers/selinux v1.10.0 h1:rAiKF8hTcgLI3w0DHm6i0ylVVcOrlgR1kK99DRLDhyU= -github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= -github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde h1:x0TT0RDC7UhAVbbWWBzr41ElhJx5tXPWkIHA2HWPRuw= -github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0= -github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= -github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= -github.com/phpdave11/gofpdf v1.4.2 h1:KPKiIbfwbvC/wOncwhrpRdXVj2CZTCFlw4wnoyjtHfQ= -github.com/phpdave11/gofpdi v1.0.13 h1:o61duiW8M9sMlkVXWlvP92sZJtGKENvW3VExs6dZukQ= -github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0= -github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A= -github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -github.com/pkg/sftp v1.13.1 h1:I2qBYMChEhIjOgazfJmV3/mZM256btk6wkCDRmW7JYs= -github.com/pquerna/cachecontrol v0.1.0 h1:yJMy84ti9h/+OEWa752kBTKv4XC30OtVVHYv/8cTqKc= -github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI= -github.com/prometheus/exporter-toolkit v0.11.0 h1:yNTsuZ0aNCNFQ3aFTD2uhPOvr4iD7fdBvKPAEGkNf+g= -github.com/prometheus/exporter-toolkit v0.11.0/go.mod h1:BVnENhnNecpwoTLiABx7mrPB/OLRIgN74qlQbV+FK1Q= -github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk= -github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= -github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= -github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245 h1:K1Xf3bKttbF+koVGaX5xngRIZ5bVjbmPnaxE/dR08uY= -github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646 h1:RpforrEYXWkmGwJHIGnLZ3tTWStkjVVstwzNGqxX2Ds= -github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= -github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= -github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ= -github.com/spf13/afero v1.9.2 h1:j49Hj62F0n+DaZ1dDCvhABaPNSGNkt32oRFxI33IEMw= -github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= -github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU= -github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI= -github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= -github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE= -github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk= -github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= -github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= -github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY= -github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= -github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0= -github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= -github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df h1:OviZH7qLw/7ZovXvuNyL3XQl8UFofeikI1NW1Gypu7k= -github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= -github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= -github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -github.com/xhit/go-str2duration v1.2.0 h1:BcV5u025cITWxEQKGWr1URRzrcXtu7uk8+luz3Yuhwc= -github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc= -github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= -github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= -github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= -go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA= -go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= -go.etcd.io/etcd/api/v3 v3.5.10 h1:szRajuUUbLyppkhs9K6BRtjY37l66XQQmw7oZRANE4k= -go.etcd.io/etcd/api/v3 v3.5.10/go.mod h1:TidfmT4Uycad3NM/o25fG3J07odo4GBB9hoxaodFCtI= -go.etcd.io/etcd/client/pkg/v3 v3.5.10 h1:kfYIdQftBnbAq8pUWFXfpuuxFSKzlmM5cSn76JByiT0= -go.etcd.io/etcd/client/pkg/v3 v3.5.10/go.mod h1:DYivfIviIuQ8+/lCq4vcxuseg2P2XbHygkKwFo9fc8U= -go.etcd.io/etcd/client/v2 v2.305.10 h1:MrmRktzv/XF8CvtQt+P6wLUlURaNpSDJHFZhe//2QE4= -go.etcd.io/etcd/client/v2 v2.305.10/go.mod h1:m3CKZi69HzilhVqtPDcjhSGp+kA1OmbNn0qamH80xjA= -go.etcd.io/etcd/client/v3 v3.5.10 h1:W9TXNZ+oB3MCd/8UjxHTWK5J9Nquw9fQBLJd5ne5/Ao= -go.etcd.io/etcd/client/v3 v3.5.10/go.mod h1:RVeBnDz2PUEZqTpgqwAtUd8nAPf5kjyFyND7P1VkOKc= -go.etcd.io/etcd/pkg/v3 v3.5.10 h1:WPR8K0e9kWl1gAhB5A7gEa5ZBTNkT9NdNWrR8Qpo1CM= -go.etcd.io/etcd/pkg/v3 v3.5.10/go.mod h1:TKTuCKKcF1zxmfKWDkfz5qqYaE3JncKKZPFf8c1nFUs= -go.etcd.io/etcd/raft/v3 v3.5.10 h1:cgNAYe7xrsrn/5kXMSaH8kM/Ky8mAdMqGOxyYwpP0LA= -go.etcd.io/etcd/raft/v3 v3.5.10/go.mod h1:odD6kr8XQXTy9oQnyMPBOr0TVe+gT0neQhElQ6jbGRc= -go.etcd.io/etcd/server/v3 v3.5.10 h1:4NOGyOwD5sUZ22PiWYKmfxqoeh72z6EhYjNosKGLmZg= -go.etcd.io/etcd/server/v3 v3.5.10/go.mod h1:gBplPHfs6YI0L+RpGkTQO7buDbHv5HJGG/Bst0/zIPo= -go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0 h1:ZOLJc06r4CB42laIXg/7udr0pbZyuAihN10A/XuiQRY= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0/go.mod h1:5z+/ZWJQKXa9YT34fQNx5K8Hd1EoIhvtUygUQPqEOgQ= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1/go.mod h1:4UoMYEZOC0yN/sPGH76KPkkU7zgiEWYWL9vwmbnTJPE= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0/go.mod h1:r9vWsPS/3AQItv3OSlEJ/E4mbrhUbbw18meOjArPtKQ= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0 h1:KfYpVmrjI7JuToy5k8XV3nkapjWx48k4E4JOtVstzQI= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0/go.mod h1:SeQhzAEccGVZVEy7aH87Nh0km+utSpo1pTv6eMMop48= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0/go.mod h1:SK2UL73Zy1quvRPonmOmRDiWk1KBV3LyIeeIxcEApWw= -go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= -go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= -go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= -go.opentelemetry.io/otel v1.22.0/go.mod h1:eoV4iAi3Ea8LkAEI9+GFT44O6T/D0GWAVFyZVCC6pMI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 h1:3d+S281UTjM+AbF31XSOYn1qXn3BgIdWl8HNEpx08Jk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0/go.mod h1:0+KuTDyKL4gjKCF75pHOX4wuzYDUZYfAQdSu43o+Z2I= -go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE= -go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= -go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= -go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xCWdXjK8pzFvliY= -go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o= -go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A= -go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg= -go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= -go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= -go.opentelemetry.io/otel/trace v1.22.0/go.mod h1:RbbHXVqKES9QhzZq/fE5UnOSILqRt40a21sPw2He1xo= -go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= -go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= -go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= -go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -golang.org/dl v0.0.0-20190829154251-82a15e2f2ead h1:jeP6FgaSLNTMP+Yri3qjlACywQLye+huGLmNGhBzm6k= -golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= -golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= -golang.org/x/image v0.0.0-20220302094943-723b81ca9867 h1:TcHcE0vrmgzNH1v3ppjcMGbhG5+9fMuvOmUYwNEF4q4= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs= -golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= -golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= -golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= -golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk= -golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0= -golang.org/x/oauth2 v0.14.0/go.mod h1:lAtNWgaWfL4cm7j2OV8TxGi9Qb7ECORx8DktCY74OwM= -golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= -golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= -golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/telemetry v0.0.0-20240208230135-b75ee8823808/go.mod h1:KG1lNk5ZFNssSZLrpVb4sMXKMpGwGXOxSG3rnu2gZQQ= -golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2 h1:IRJeR9r1pYWsHKTRe/IInb7lYvbBVIqOgsX/u0mbOWY= -golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= -golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= -golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= -golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= -golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= -golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= -gonum.org/v1/gonum v0.11.0 h1:f1IJhK4Km5tBJmaiJXtk/PkL4cdVX6J+tGiM187uT5E= -gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0 h1:OE9mWmgKkjJyEmDAAtGMPjXu+YNeGvK9VTSHY6+Qihc= -gonum.org/v1/plot v0.10.1 h1:dnifSs43YJuNMDzB7v8wV64O4ABBHReuAVAoBxqBqS4= -google.golang.org/api v0.126.0 h1:q4GJq+cAdMAC7XP7njvQ4tvohGLiSlytuL4BQxbIZ+o= -google.golang.org/api v0.128.0/go.mod h1:Y611qgqaE92On/7g65MQgxYul3c0rEB894kniWLY750= -google.golang.org/api v0.149.0/go.mod h1:Mwn1B7JTXrzXtnvmzQE2BD6bYZQ8DShKZDZbeN9I7qI= -google.golang.org/api v0.155.0/go.mod h1:GI5qK5f40kCpHfPn6+YzGAByIKWv8ujFnmoWm7Igduk= -google.golang.org/api v0.162.0/go.mod h1:6SulDkfoBIg4NFmCuZ39XeeAgSHCPecfSUuDyYlAHs0= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4= -google.golang.org/genproto v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:CCviP9RmpZ1mxVr8MUjCnSiY09IbAXZxhLE6EhHIdPU= -google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97 h1:SeZZZx0cP0fqUyA+oRzP9k7cSwJlvDFiROO72uwD6i0= -google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97/go.mod h1:t1VqOqqvce95G3hIDCT5FeO3YUc6Q4Oe24L/+rNMxRk= -google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:CgAqfJo+Xmu0GwA0411Ht3OU3OntXwsGmrmjI8ioGXI= -google.golang.org/genproto v0.0.0-20231030173426-d783a09b4405/go.mod h1:3WDQMjmJk36UQhjQ89emUzb1mdaHcPeeAh4SCBKznB4= -google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 h1:wpZ8pe2x1Q3f2KyT5f8oP/fa9rHAKgFPr/HZdNuS+PQ= -google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:J7XzRzVy1+IPwWHZUzoD0IccYZIrXILAQpc+Qy9CMhY= -google.golang.org/genproto v0.0.0-20231211222908-989df2bf70f3/go.mod h1:5RBcpGRxr25RbDzY5w+dmaqpSEvl8Gwl1x2CICf60ic= -google.golang.org/genproto v0.0.0-20231212172506-995d672761c0/go.mod h1:l/k7rMz0vFTBPy+tFSGvXEd3z+BcoG1k7EHbqm+YBsY= -google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:+Rvu7ElI+aLzyDQhpHMFMMltsD6m7nqpuWDd2CwJw3k= -google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 h1:KAeGQVN3M9nD0/bQXnr/ClcEMJ968gUXJQ9pwfSynuQ= -google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80/go.mod h1:cc8bqMqtv9gMOr0zHg2Vzff5ULhhL2IXP4sbcn32Dro= -google.golang.org/genproto v0.0.0-20240125205218-1f4bbc51befe/go.mod h1:cc8bqMqtv9gMOr0zHg2Vzff5ULhhL2IXP4sbcn32Dro= -google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y= -google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s= -google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= -google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= -google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= -google.golang.org/genproto/googleapis/api v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:RdyHbowztCGQySiCvQPgWQWgWhGnouTdCflKoDBt32U= -google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97/go.mod h1:iargEX0SFPm3xcfMI0d1domjg0ZF4Aa0p2awqyxhvF0= -google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:IBQ646DjkDkvUIsVq/cc03FUFQ9wbZu7yE396YcL870= -google.golang.org/genproto/googleapis/api v0.0.0-20231030173426-d783a09b4405/go.mod h1:oT32Z4o8Zv2xPQTg0pbVaPr0MPOH6f14RgXt7zfIpwg= -google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:0xJLfVdJqpAPl8tDg1ujOCGzx6LFLttXT5NhllGOXY4= -google.golang.org/genproto/googleapis/api v0.0.0-20231211222908-989df2bf70f3/go.mod h1:k2dtGpRrbsSyKcNPKKI5sstZkrNCZwpU/ns96JoHbGg= -google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917/go.mod h1:CmlNWB9lSezaYELKS5Ym1r44VrrbPUa7JTvw+6MbpJ0= -google.golang.org/genproto/googleapis/api v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:B5xPO//w8qmBDjGReYLpR6UJPnkldGkCSMoH/2vxJeg= -google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80/go.mod h1:4jWUdICTdgc3Ibxmr8nAJiiLHwQBY0UI0XZcEMaFKaA= -google.golang.org/genproto/googleapis/api v0.0.0-20240205150955-31a09d347014/go.mod h1:rbHMSEDyoYX62nRVLOCc4Qt1HbsdytAYoVwgjiOhF3I= -google.golang.org/genproto/googleapis/api v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:PVreiBMirk8ypES6aw9d4p6iiBNSIfZEBqr3UGoAi2E= -google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de h1:jFNzHPIeuzhdRwVhbZdiym9q0ory/xY3sA+v2wPg8I0= -google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:5iCWqnniDlqZHrd3neWVTOwvh/v6s3232omMecelax8= -google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237/go.mod h1:Z5Iiy3jtmioajWHDGFk7CeugTyHtPvMHA4UTmUkyalE= -google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU= -google.golang.org/genproto/googleapis/bytestream v0.0.0-20230530153820-e85fd2cbaebc h1:g3hIDl0jRNd9PPTs2uBzYuaD5mQuwOkZY0vSc0LR32o= -google.golang.org/genproto/googleapis/bytestream v0.0.0-20231030173426-d783a09b4405/go.mod h1:GRUCuLdzVqZte8+Dl/D4N25yLzcGqqWaYkeVOwulFqw= -google.golang.org/genproto/googleapis/bytestream v0.0.0-20231212172506-995d672761c0/go.mod h1:guYXGPwC6jwxgWKW5Y405fKWOFNwlvUlUnzyp9i0uqo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:KSqppvjFjtoCI+KGd4PELB0qLNxdJHRGqRI09mB6pQA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97/go.mod h1:v7nGkzlmW8P3n/bKmWBn2WpBjpOEx8Q6gMueudAmKfY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:swOH3j0KzcDDgGUWr+SNpyTen5YrXjS3eyPzFYKc6lc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405/go.mod h1:67X1fPuzjcrkymZzZV1vvkFeTn2Rvc6lYF9MYFGCcwE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0/go.mod h1:FUoWkonphQm3RhTS+kOEhF8h0iDpm4tdXolVCeZ9KKA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917/go.mod h1:xtjpI3tXFPP051KaWnhvxkiubL/6dJ18vLVf7q2pTOU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:daQN87bsDqDoe316QbbvX60nMoJQa4r6Ds0ZuoAe5yA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240205150955-31a09d347014/go.mod h1:SaPjaZGWb0lPqs6Ittu0spdfrOArqji4ZdeP5IC/9N4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:YUWgXUFRPfoYK1IHMuxH5K6nPEXSCzIMljnQ59lLRCk= -google.golang.org/grpc v1.56.1/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= -google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= -google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= -google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= -google.golang.org/grpc v1.61.0/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= -google.golang.org/grpc v1.61.1/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= -google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE= -gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= -gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8= -gopkg.in/evanphx/json-patch.v5 v5.6.0 h1:BMT6KIwBD9CaU91PJCZIe46bDmBWa9ynTQgJIOpfQBk= -gopkg.in/evanphx/json-patch.v5 v5.6.0/go.mod h1:/kvTRh1TVm5wuM6OkHxqXtE/1nUZZpihg29RtuIyfvk= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= -gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= -gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= -gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= -gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -honnef.co/go/tools v0.1.3 h1:qTakTkI6ni6LFD5sBwwsdSO+AQqbSIxOauHTTQKZ/7o= -k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01 h1:pWEwq4Asjm4vjW7vcsmijwBhOr1/shsbSYiWXmNGlks= -k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70/go.mod h1:VH3AT8AaQOqiGjMF9p0/IM1Dj+82ZwjfxUP1IxaHE+8= -k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/kms v0.29.3/go.mod h1:TBGbJKpRUMk59neTMDMddjIDL+D4HuFUbpuiuzmOPg0= -k8s.io/kms v0.30.0 h1:ZlnD/ei5lpvUlPw6eLfVvH7d8i9qZ6HwUQgydNVks8g= -k8s.io/kms v0.30.0/go.mod h1:GrMurD0qk3G4yNgGcsCEmepqf9KyyIrTXYR2lyUOJC4= -k8s.io/kms v0.30.1/go.mod h1:GrMurD0qk3G4yNgGcsCEmepqf9KyyIrTXYR2lyUOJC4= -k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= -k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI= -modernc.org/cc/v3 v3.36.3 h1:uISP3F66UlixxWEcKuIWERa4TwrZENHSL8tWxZz8bHg= -modernc.org/ccgo/v3 v3.16.9 h1:AXquSwg7GuMk11pIdw7fmO1Y/ybgazVkMhsZWCV0mHM= -modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk= -modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM= -modernc.org/libc v1.17.1 h1:Q8/Cpi36V/QBfuQaFVeisEBs3WqoGAJprZzmf7TfEYI= -modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ= -modernc.org/memory v1.2.1 h1:dkRh86wgmq/bJu2cAS2oqBCz/KsMZU7TUM4CibQ7eBs= -modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= -modernc.org/sqlite v1.18.1 h1:ko32eKt3jf7eqIkCgPAeHMBXw3riNSLhl2f3loEF7o8= -modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY= -modernc.org/tcl v1.13.1 h1:npxzTwFTZYM8ghWicVIX1cRWzj7Nd8i6AqqX2p+IYao= -modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk= -modernc.org/z v1.5.1 h1:RTNHdsrOpeoSeOF4FbzTo8gBYByaJ5xT7NgZ9ZqRiJM= -rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE= -rsc.io/pdf v0.1.1 h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4= -rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY= -rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.28.0/go.mod h1:VHVDI/KrK4fjnV61bE2g3sA7tiETLn8sooImelsCx3Y= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.29.0 h1:/U5vjBbQn3RChhv7P11uhYvCSm5G2GaIi5AIGBS6r4c= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.29.0/go.mod h1:z7+wmGM2dfIiLRfrC6jb5kV2Mq/sK1ZP303cxzkV5Y4= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= -sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= -sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/hack/init-buildx.sh b/hack/init-buildx.sh index 1a47bf145..bac68e1ae 100755 --- a/hack/init-buildx.sh +++ b/hack/init-buildx.sh @@ -42,12 +42,11 @@ fi # We can skip setup if the current builder already has multi-arch # AND if it isn't the docker driver, which doesn't work current_builder="$(docker buildx inspect)" -# linux/amd64, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6 +# linux/amd64, linux/arm, linux/arm64 if ! grep -q "^Driver: docker$" <<<"${current_builder}" && \ grep -q "linux/amd64" <<<"${current_builder}" && \ grep -q "linux/arm" <<<"${current_builder}" && \ - grep -q "linux/arm64" <<<"${current_builder}" && \ - grep -q "linux/s390x" <<<"${current_builder}"; then + grep -q "linux/arm64" <<<"${current_builder}"; then exit 0 fi diff --git a/hack/manifest-templates/provider/kind/values.yaml b/hack/manifest-templates/provider/kind/values.yaml index ed636f372..6140f6500 100644 --- a/hack/manifest-templates/provider/kind/values.yaml +++ b/hack/manifest-templates/provider/kind/values.yaml @@ -8,11 +8,9 @@ controller: enabled: true terminationGracePeriodSeconds: 0 service: - type: NodePort + type: LoadBalancer watchIngressWithoutClass: true - nodeSelector: - ingress-ready: "true" tolerations: - key: "node-role.kubernetes.io/master" operator: "Equal" diff --git a/hack/update-annotation-doc.sh b/hack/update-annotation-doc.sh new file mode 100755 index 000000000..c4feb41ce --- /dev/null +++ b/hack/update-annotation-doc.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# Copyright 2024 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -o errexit +set -o nounset + +SCRIPT_ROOT=$(dirname "${BASH_SOURCE}")/.. +ANNOTATIONFILE="${SCRIPT_ROOT}/docs/user-guide/nginx-configuration/annotations-risk.md" + +go run "${SCRIPT_ROOT}"/cmd/annotations/main.go -output "${ANNOTATIONFILE}" \ No newline at end of file diff --git a/hack/verify-annotation-docs.sh b/hack/verify-annotation-docs.sh new file mode 100755 index 000000000..54034539b --- /dev/null +++ b/hack/verify-annotation-docs.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +# Copyright 2024 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -o errexit +set -o nounset +set -o pipefail + +SCRIPT_ROOT=$(dirname "${BASH_SOURCE}")/.. + +ANNOTATIONFILE="${SCRIPT_ROOT}/docs/user-guide/nginx-configuration/annotations-risk.md" +TMP_DIFFROOT="${SCRIPT_ROOT}/_tmp" +TMP_FILE="${TMP_DIFFROOT}/annotations-risk.md" + +cleanup() { + rm -rf "${TMP_DIFFROOT}" +} +trap "cleanup" EXIT SIGINT + +cleanup + +mkdir -p "${TMP_DIFFROOT}" + +go run cmd/annotations/main.go -output "${TMP_FILE}" +echo "diffing ${ANNOTATIONFILE} against freshly generated annotation doc" +ret=0 +diff -Naupr --no-dereference "${ANNOTATIONFILE}" "${TMP_FILE}" || ret=1 + +if [[ $ret -eq 0 ]]; then + echo "${ANNOTATIONFILE} up to date." +else + echo "${ANNOTATIONFILE} is out of date. Please run hack/update-annotation-doc.sh" + exit 1 +fi diff --git a/hack/verify-lualint.sh b/hack/verify-lualint.sh index 1f6048de0..769d7a6cd 100755 --- a/hack/verify-lualint.sh +++ b/hack/verify-lualint.sh @@ -18,6 +18,13 @@ set -o errexit set -o nounset set -o pipefail -luacheck --codes -q rootfs/etc/nginx/lua/ +luacheck --codes --globals lua_ingress \ + --globals configuration \ + --globals balancer \ + --globals monitor \ + --globals certificate \ + --globals tcp_udp_configuration \ + --globals tcp_udp_balancer \ + --no-max-comment-line-length -q rootfs/etc/nginx/lua/ find rootfs/etc/nginx/lua/ -name "*.lua" -not -path "*/test/*" -exec lj-releng -L -s {} + && echo "lj-releng validation is success!" diff --git a/images/Makefile b/images/Makefile index 990d77231..31560168d 100644 --- a/images/Makefile +++ b/images/Makefile @@ -41,7 +41,7 @@ EXTRAARGS ?= $(shell cat $(NAME)/EXTRAARGS) export DOCKER_CLI_EXPERIMENTAL=enabled # build with buildx -PLATFORMS?=linux/amd64,linux/arm,linux/arm64,linux/s390x +PLATFORMS?=linux/amd64,linux/arm,linux/arm64 OUTPUT= PROGRESS=plain diff --git a/images/cfssl/TAG b/images/cfssl/TAG index 0ec25f750..56130fb3a 100644 --- a/images/cfssl/TAG +++ b/images/cfssl/TAG @@ -1 +1 @@ -v1.0.0 +v1.1.1 diff --git a/images/cfssl/cloudbuild.yaml b/images/cfssl/cloudbuild.yaml index 6b5b0fc1b..33fafdb08 100644 --- a/images/cfssl/cloudbuild.yaml +++ b/images/cfssl/cloudbuild.yaml @@ -2,9 +2,9 @@ options: # Ignore Prow provided substitutions. substitution_option: ALLOW_LOOSE steps: - - name: gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20240523-a15ad90fc9 + - name: gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20250116-2a05ea7e3d env: - - REGISTRY=gcr.io/k8s-staging-ingress-nginx + - REGISTRY=us-central1-docker.pkg.dev/k8s-staging-images/ingress-nginx entrypoint: bash args: - -c diff --git a/images/cfssl/rootfs/Dockerfile b/images/cfssl/rootfs/Dockerfile index c23f66d49..3978c8f4b 100644 --- a/images/cfssl/rootfs/Dockerfile +++ b/images/cfssl/rootfs/Dockerfile @@ -12,9 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM alpine:3.20.0 +FROM alpine:3.21 -RUN echo "@testing http://nl.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories +RUN echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories RUN apk update \ && apk upgrade && \ apk add --no-cache \ diff --git a/images/custom-error-pages/TAG b/images/custom-error-pages/TAG index b18d46540..56130fb3a 100644 --- a/images/custom-error-pages/TAG +++ b/images/custom-error-pages/TAG @@ -1 +1 @@ -v1.0.1 +v1.1.1 diff --git a/images/custom-error-pages/cloudbuild.yaml b/images/custom-error-pages/cloudbuild.yaml index 772a7697f..324a8f19a 100644 --- a/images/custom-error-pages/cloudbuild.yaml +++ b/images/custom-error-pages/cloudbuild.yaml @@ -2,11 +2,10 @@ options: # Ignore Prow provided substitutions. substitution_option: ALLOW_LOOSE steps: - - name: gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20240523-a15ad90fc9 + - name: gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20250116-2a05ea7e3d env: - - REGISTRY=gcr.io/k8s-staging-ingress-nginx + - REGISTRY=us-central1-docker.pkg.dev/k8s-staging-images/ingress-nginx entrypoint: bash args: - -c - gcloud auth configure-docker && cd images && make NAME=custom-error-pages push -timeout: 3600s diff --git a/images/custom-error-pages/rootfs/Dockerfile b/images/custom-error-pages/rootfs/Dockerfile index 345f92ba3..478e4c22d 100755 --- a/images/custom-error-pages/rootfs/Dockerfile +++ b/images/custom-error-pages/rootfs/Dockerfile @@ -14,7 +14,7 @@ ARG GOLANG_VERSION -FROM golang:${GOLANG_VERSION}-alpine3.20 as builder +FROM golang:${GOLANG_VERSION}-alpine3.21 as builder RUN apk update \ && apk upgrade && apk add git diff --git a/images/custom-error-pages/rootfs/go.mod b/images/custom-error-pages/rootfs/go.mod index 264ebf427..5c0377284 100644 --- a/images/custom-error-pages/rootfs/go.mod +++ b/images/custom-error-pages/rootfs/go.mod @@ -1,17 +1,17 @@ module k8s.io/ingress-nginx/custom-error-pages -go 1.22.6 +go 1.23.6 -require github.com/prometheus/client_golang v1.11.1 +require github.com/prometheus/client_golang v1.20.5 require ( github.com/beorn7/perks v1.0.1 // indirect - github.com/cespare/xxhash/v2 v2.1.1 // indirect - github.com/golang/protobuf v1.5.0 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect - github.com/prometheus/client_model v0.2.0 // indirect - github.com/prometheus/common v0.26.0 // indirect - github.com/prometheus/procfs v0.6.0 // indirect - golang.org/x/sys v0.1.0 // indirect - google.golang.org/protobuf v1.33.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/klauspost/compress v1.17.9 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect + golang.org/x/sys v0.22.0 // indirect + google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/images/custom-error-pages/rootfs/go.sum b/images/custom-error-pages/rootfs/go.sum index 99c959a36..d5318cf86 100644 --- a/images/custom-error-pages/rootfs/go.sum +++ b/images/custom-error-pages/rootfs/go.sum @@ -1,141 +1,24 @@ -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.1 h1:+4eQaD7vAZ6DsfsxB15hbE0odUjGI5ARs9yskGu1v4s= -github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= +github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= +github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= diff --git a/images/e2e-test-echo/TAG b/images/e2e-test-echo/TAG index 0ec25f750..56130fb3a 100644 --- a/images/e2e-test-echo/TAG +++ b/images/e2e-test-echo/TAG @@ -1 +1 @@ -v1.0.0 +v1.1.1 diff --git a/images/e2e-test-echo/cloudbuild.yaml b/images/e2e-test-echo/cloudbuild.yaml index dc6e1dcf0..02bfc034a 100644 --- a/images/e2e-test-echo/cloudbuild.yaml +++ b/images/e2e-test-echo/cloudbuild.yaml @@ -2,9 +2,9 @@ options: # Ignore Prow provided substitutions. substitution_option: ALLOW_LOOSE steps: - - name: gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20240523-a15ad90fc9 + - name: gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20250116-2a05ea7e3d env: - - REGISTRY=gcr.io/k8s-staging-ingress-nginx + - REGISTRY=us-central1-docker.pkg.dev/k8s-staging-images/ingress-nginx entrypoint: bash args: - -c diff --git a/images/ext-auth-example-authsvc/TAG b/images/ext-auth-example-authsvc/TAG index 0ec25f750..56130fb3a 100644 --- a/images/ext-auth-example-authsvc/TAG +++ b/images/ext-auth-example-authsvc/TAG @@ -1 +1 @@ -v1.0.0 +v1.1.1 diff --git a/images/ext-auth-example-authsvc/rootfs/Dockerfile b/images/ext-auth-example-authsvc/rootfs/Dockerfile index 5942ac5b9..ca142e663 100644 --- a/images/ext-auth-example-authsvc/rootfs/Dockerfile +++ b/images/ext-auth-example-authsvc/rootfs/Dockerfile @@ -1,6 +1,6 @@ ARG GOLANG_VERSION -FROM golang:${GOLANG_VERSION}-alpine3.20 as builder +FROM golang:${GOLANG_VERSION}-alpine3.21 as builder RUN mkdir /authsvc WORKDIR /authsvc COPY . ./ diff --git a/images/ext-auth-example-authsvc/rootfs/go.mod b/images/ext-auth-example-authsvc/rootfs/go.mod index a3396b358..5f33a86ff 100644 --- a/images/ext-auth-example-authsvc/rootfs/go.mod +++ b/images/ext-auth-example-authsvc/rootfs/go.mod @@ -1,7 +1,7 @@ module example.com/authsvc -go 1.22.6 +go 1.23.6 -require k8s.io/apimachinery v0.23.1 +require k8s.io/apimachinery v0.32.2 -require github.com/google/uuid v1.1.2 // indirect +require github.com/google/uuid v1.6.0 // indirect diff --git a/images/ext-auth-example-authsvc/rootfs/go.sum b/images/ext-auth-example-authsvc/rootfs/go.sum index 6e3fab295..770c22f6a 100644 --- a/images/ext-auth-example-authsvc/rootfs/go.sum +++ b/images/ext-auth-example-authsvc/rootfs/go.sum @@ -1,215 +1,4 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= -github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= -github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= -github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= -github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/apimachinery v0.23.1 h1:sfBjlDFwj2onG0Ijx5C+SrAoeUscPrmghm7wHP+uXlo= -k8s.io/apimachinery v0.23.1/go.mod h1:SADt2Kl8/sttJ62RRsi9MIV4o8f5S3coArm0Iu3fBno= -k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= -k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk= -k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs= -sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= -sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +k8s.io/apimachinery v0.32.2 h1:yoQBR9ZGkA6Rgmhbp/yuT9/g+4lxtsGYwW6dR6BDPLQ= +k8s.io/apimachinery v0.32.2/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= diff --git a/images/fastcgi-helloserver/TAG b/images/fastcgi-helloserver/TAG index b18d46540..56130fb3a 100644 --- a/images/fastcgi-helloserver/TAG +++ b/images/fastcgi-helloserver/TAG @@ -1 +1 @@ -v1.0.1 +v1.1.1 diff --git a/images/fastcgi-helloserver/cloudbuild.yaml b/images/fastcgi-helloserver/cloudbuild.yaml index 5fb3e3318..c2c6135df 100644 --- a/images/fastcgi-helloserver/cloudbuild.yaml +++ b/images/fastcgi-helloserver/cloudbuild.yaml @@ -2,11 +2,10 @@ options: # Ignore Prow provided substitutions. substitution_option: ALLOW_LOOSE steps: - - name: gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20240523-a15ad90fc9 + - name: gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20250116-2a05ea7e3d env: - - REGISTRY=gcr.io/k8s-staging-ingress-nginx + - REGISTRY=us-central1-docker.pkg.dev/k8s-staging-images/ingress-nginx entrypoint: bash args: - -c - gcloud auth configure-docker && cd images && make NAME=fastcgi-helloserver push -timeout: 3600s diff --git a/images/fastcgi-helloserver/rootfs/Dockerfile b/images/fastcgi-helloserver/rootfs/Dockerfile index 2b91887c9..7d8e95c47 100755 --- a/images/fastcgi-helloserver/rootfs/Dockerfile +++ b/images/fastcgi-helloserver/rootfs/Dockerfile @@ -13,7 +13,7 @@ # limitations under the License. ARG GOLANG_VERSION -FROM golang:${GOLANG_VERSION}-alpine3.20 as builder +FROM golang:${GOLANG_VERSION}-alpine3.21 as builder WORKDIR /go/src/k8s.io/ingress-nginx/images/fastcgi diff --git a/images/go-grpc-greeter-server/TAG b/images/go-grpc-greeter-server/TAG index 0ec25f750..56130fb3a 100644 --- a/images/go-grpc-greeter-server/TAG +++ b/images/go-grpc-greeter-server/TAG @@ -1 +1 @@ -v1.0.0 +v1.1.1 diff --git a/images/go-grpc-greeter-server/rootfs/Dockerfile b/images/go-grpc-greeter-server/rootfs/Dockerfile index f07b1d667..39be2990f 100644 --- a/images/go-grpc-greeter-server/rootfs/Dockerfile +++ b/images/go-grpc-greeter-server/rootfs/Dockerfile @@ -1,6 +1,6 @@ ARG GOLANG_VERSION -FROM golang:${GOLANG_VERSION}-alpine3.20 as build +FROM golang:${GOLANG_VERSION}-alpine3.21 as build WORKDIR /go/src/greeter-server diff --git a/images/httpbun/TAG b/images/httpbun/TAG index b18d46540..56130fb3a 100644 --- a/images/httpbun/TAG +++ b/images/httpbun/TAG @@ -1 +1 @@ -v1.0.1 +v1.1.1 diff --git a/images/httpbun/cloudbuild.yaml b/images/httpbun/cloudbuild.yaml index 3d2662531..c56820d15 100644 --- a/images/httpbun/cloudbuild.yaml +++ b/images/httpbun/cloudbuild.yaml @@ -2,11 +2,10 @@ options: # Ignore Prow provided substitutions. substitution_option: ALLOW_LOOSE steps: - - name: gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20240523-a15ad90fc9 + - name: gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20250116-2a05ea7e3d env: - - REGISTRY=gcr.io/k8s-staging-ingress-nginx + - REGISTRY=us-central1-docker.pkg.dev/k8s-staging-images/ingress-nginx entrypoint: bash args: - -c - gcloud auth configure-docker && cd images && make NAME=httpbun push -timeout: 3600s diff --git a/images/kube-webhook-certgen/OWNERS b/images/kube-webhook-certgen/OWNERS deleted file mode 100644 index b4424221c..000000000 --- a/images/kube-webhook-certgen/OWNERS +++ /dev/null @@ -1,4 +0,0 @@ -# See the OWNERS docs: https://www.kubernetes.dev/docs/guide/owners - -reviewers: -- ingress-nginx-kube-webhook-certgen-reviewers diff --git a/images/kube-webhook-certgen/TAG b/images/kube-webhook-certgen/TAG index 92f76b423..53b5bbb12 100644 --- a/images/kube-webhook-certgen/TAG +++ b/images/kube-webhook-certgen/TAG @@ -1 +1 @@ -v1.4.3 +v1.5.1 diff --git a/images/kube-webhook-certgen/cloudbuild.yaml b/images/kube-webhook-certgen/cloudbuild.yaml index 8bf139423..e4118ff88 100644 --- a/images/kube-webhook-certgen/cloudbuild.yaml +++ b/images/kube-webhook-certgen/cloudbuild.yaml @@ -2,11 +2,10 @@ options: # Ignore Prow provided substitutions. substitution_option: ALLOW_LOOSE steps: - - name: gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20240523-a15ad90fc9 + - name: gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20250116-2a05ea7e3d env: - - REGISTRY=gcr.io/k8s-staging-ingress-nginx + - REGISTRY=us-central1-docker.pkg.dev/k8s-staging-images/ingress-nginx entrypoint: bash args: - -c - gcloud auth configure-docker && cd images && make NAME=kube-webhook-certgen push -timeout: 1800s diff --git a/images/kube-webhook-certgen/rootfs/go.mod b/images/kube-webhook-certgen/rootfs/go.mod index 52746ebd9..2b8567748 100644 --- a/images/kube-webhook-certgen/rootfs/go.mod +++ b/images/kube-webhook-certgen/rootfs/go.mod @@ -1,31 +1,31 @@ module github.com/jet/kube-webhook-certgen -go 1.22.6 +go 1.23.6 require ( github.com/onrik/logrus v0.11.0 github.com/sirupsen/logrus v1.9.3 - github.com/spf13/cobra v1.8.0 - k8s.io/api v0.29.3 - k8s.io/apimachinery v0.29.3 - k8s.io/client-go v0.29.3 - k8s.io/kube-aggregator v0.29.3 + github.com/spf13/cobra v1.9.1 + k8s.io/api v0.32.2 + k8s.io/apimachinery v0.32.2 + k8s.io/client-go v0.32.2 + k8s.io/kube-aggregator v0.32.2 ) require ( - github.com/davecgh/go-spew v1.1.1 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.11.3 // indirect - github.com/evanphx/json-patch v5.9.0+incompatible // indirect + github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-logr/logr v1.4.2 // indirect - github.com/go-openapi/jsonpointer v0.20.2 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/jsonreference v0.20.4 // indirect - github.com/go-openapi/swag v0.22.9 // indirect + github.com/go-openapi/swag v0.23.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect @@ -33,26 +33,25 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/onsi/ginkgo/v2 v2.20.0 // indirect - github.com/onsi/gomega v1.34.1 // indirect + github.com/onsi/ginkgo/v2 v2.22.2 // indirect + github.com/onsi/gomega v1.36.2 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/spf13/pflag v1.0.5 // indirect - github.com/stretchr/testify v1.9.0 // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/oauth2 v0.18.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/term v0.23.0 // indirect - golang.org/x/text v0.17.0 // indirect - golang.org/x/time v0.5.0 // indirect - google.golang.org/appengine v1.6.8 // indirect - google.golang.org/protobuf v1.34.1 // indirect + github.com/spf13/pflag v1.0.6 // indirect + github.com/x448/float16 v0.8.4 // indirect + golang.org/x/net v0.33.0 // indirect + golang.org/x/oauth2 v0.23.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/term v0.27.0 // indirect + golang.org/x/text v0.21.0 // indirect + golang.org/x/time v0.7.0 // indirect + google.golang.org/protobuf v1.36.1 // indirect + gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/klog/v2 v2.120.1 // indirect - k8s.io/kube-openapi v0.0.0-20240224005224-582cce78233b // indirect - k8s.io/utils v0.0.0-20240102154912-e7106e64919e // indirect - sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect + k8s.io/klog/v2 v2.130.1 // indirect + k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect + k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect + sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) diff --git a/images/kube-webhook-certgen/rootfs/go.sum b/images/kube-webhook-certgen/rootfs/go.sum index 8ce13c672..1c660f020 100644 --- a/images/kube-webhook-certgen/rootfs/go.sum +++ b/images/kube-webhook-certgen/rootfs/go.sum @@ -1,43 +1,38 @@ -github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/emicklei/go-restful/v3 v3.11.3 h1:yagOQz/38xJmcNeZJtrUcKjkHRltIaIFXKWeG1SkWGE= github.com/emicklei/go-restful/v3 v3.11.3/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls= -github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q= -github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU= github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4= -github.com/go-openapi/swag v0.22.9 h1:XX2DssF+mQKM2DHsbgZK74y/zj4mo9I99+89xUmuZCE= -github.com/go-openapi/swag v0.22.9/go.mod h1:3/OXnFfnMAwBD099SwYRk7GD3xOrr1iL7d/XNLXVVwE= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= -github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= +github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg= +github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= -github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -61,23 +56,24 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/onrik/logrus v0.11.0 h1:pu+BCaWL36t0yQaj/2UHK2erf88dwssAKOT51mxPUVs= github.com/onrik/logrus v0.11.0/go.mod h1:fO2vlZwIdti6PidD3gV5YKt9Lq5ptpnP293RAe1ITwk= -github.com/onsi/ginkgo/v2 v2.20.0 h1:PE84V2mHqoT1sglvHc8ZdQtPcwmvvt29WLEEO3xmdZw= -github.com/onsi/ginkgo/v2 v2.20.0/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI= -github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= -github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= +github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU= +github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk= +github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8= +github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= -github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= +github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= +github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= +github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -89,99 +85,79 @@ github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= -golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= -golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= +golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= -golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= +golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= -golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= +golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8= +golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= -google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= +google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= +gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.29.3 h1:2ORfZ7+bGC3YJqGpV0KSDDEVf8hdGQ6A03/50vj8pmw= -k8s.io/api v0.29.3/go.mod h1:y2yg2NTyHUUkIoTC+phinTnEa3KFM6RZ3szxt014a80= -k8s.io/apimachinery v0.29.3 h1:2tbx+5L7RNvqJjn7RIuIKu9XTsIZ9Z5wX2G22XAa5EU= -k8s.io/apimachinery v0.29.3/go.mod h1:hx/S4V2PNW4OMg3WizRrHutyB5la0iCUbZym+W0EQIU= -k8s.io/client-go v0.29.3 h1:R/zaZbEAxqComZ9FHeQwOh3Y1ZUs7FaHKZdQtIc2WZg= -k8s.io/client-go v0.29.3/go.mod h1:tkDisCvgPfiRpxGnOORfkljmS+UrW+WtXAy2fTvXJB0= -k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= -k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-aggregator v0.29.3 h1:5KvTyFN8sQq2imq8tMAHWEKoE64Zg9WSMaGX78KV6ps= -k8s.io/kube-aggregator v0.29.3/go.mod h1:xGJqV/SJJ1fbwTGfQLAZfwgqX1EMoaqfotDTkDrqqSk= -k8s.io/kube-openapi v0.0.0-20240224005224-582cce78233b h1:1dzw/KqgSPod72SUp2tuTOmK33TlY2fHlrVU2M9VrOM= -k8s.io/kube-openapi v0.0.0-20240224005224-582cce78233b/go.mod h1:Pa1PvrP7ACSkuX6I7KYomY6cmMA0Tx86waBhDUgoKPw= -k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCfRziVtos3ofG/sQ= -k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= +k8s.io/api v0.32.2 h1:bZrMLEkgizC24G9eViHGOPbW+aRo9duEISRIJKfdJuw= +k8s.io/api v0.32.2/go.mod h1:hKlhk4x1sJyYnHENsrdCWw31FEmCijNGPJO5WzHiJ6Y= +k8s.io/apimachinery v0.32.2 h1:yoQBR9ZGkA6Rgmhbp/yuT9/g+4lxtsGYwW6dR6BDPLQ= +k8s.io/apimachinery v0.32.2/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= +k8s.io/client-go v0.32.2 h1:4dYCD4Nz+9RApM2b/3BtVvBHw54QjMFUl1OLcJG5yOA= +k8s.io/client-go v0.32.2/go.mod h1:fpZ4oJXclZ3r2nDOv+Ux3XcJutfrwjKTCHz2H3sww94= +k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= +k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-aggregator v0.32.2 h1:kg9pke+i2qRbJwX1UKwZV4fsCRvmbaCEFk38R4FqHmw= +k8s.io/kube-aggregator v0.32.2/go.mod h1:rRm+xY1yIFIt3zBc727nG5SBLYywywD87klfIAw+7+c= +k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJJ4JRdzg3+O6e8I+e+8T5Y= +k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f/go.mod h1:R/HEjbvWI0qdfb8viZUeVZm0X6IZnxAydC7YU42CMw4= +k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro= +k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8= +sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo= +sigs.k8s.io/structured-merge-diff/v4 v4.4.2 h1:MdmvkGuXi/8io6ixD5wud3vOLwc1rj0aNqRlpuvjmwA= +sigs.k8s.io/structured-merge-diff/v4 v4.4.2/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/images/kube-webhook-certgen/rootfs/pkg/k8s/k8s_test.go b/images/kube-webhook-certgen/rootfs/pkg/k8s/k8s_test.go index f11bef981..b326697b6 100644 --- a/images/kube-webhook-certgen/rootfs/pkg/k8s/k8s_test.go +++ b/images/kube-webhook-certgen/rootfs/pkg/k8s/k8s_test.go @@ -186,7 +186,7 @@ func Test_Patching_objects(t *testing.T) { }) // This is to preserve old behavior and log format, it could be improved. - t.Run("diffent_non_empty_names_are_specified_for_validating_and_mutating_webhook", func(t *testing.T) { + t.Run("different_non_empty_names_are_specified_for_validating_and_mutating_webhook", func(t *testing.T) { t.Parallel() k := testK8sWithUnpatchedObjects() diff --git a/images/nginx-1.25/Makefile b/images/nginx-1.25/Makefile deleted file mode 100644 index cdd3e2a3c..000000000 --- a/images/nginx-1.25/Makefile +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright 2024 The Kubernetes Authors. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -.DEFAULT_GOAL:=build - -# set default shell -SHELL=/bin/bash -o pipefail -o errexit - -DIR:=$(strip $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))) -INIT_BUILDX=$(DIR)/../../hack/init-buildx.sh - -# 0.0.0 shouldn't clobber any released builds -SHORT_SHA ?=$(shell git rev-parse --short HEAD) -TAG ?=$(shell cat TAG) - -REGISTRY ?= gcr.io/k8s-staging-ingress-nginx - -IMAGE = $(REGISTRY)/nginx-1.25 - -# required to enable buildx -export DOCKER_CLI_EXPERIMENTAL=enabled - -# build with buildx -PLATFORMS?=linux/amd64,linux/arm,linux/arm64,linux/s390x -OUTPUT= -PROGRESS=plain -build: ensure-buildx - docker buildx build \ - --platform=${PLATFORMS} $(OUTPUT) \ - --progress=$(PROGRESS) \ - --pull \ - --tag $(IMAGE):$(TAG) rootfs - -# push the cross built image -push: OUTPUT=--push -push: build - -# enable buildx -ensure-buildx: -# this is required for cloudbuild -ifeq ("$(wildcard $(INIT_BUILDX))","") - @curl -sSL https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/hack/init-buildx.sh | bash -else - @exec $(INIT_BUILDX) -endif - @echo "done" - -.PHONY: build push ensure-buildx \ No newline at end of file diff --git a/images/nginx-1.25/README.md b/images/nginx-1.25/README.md deleted file mode 100644 index 35cccc100..000000000 --- a/images/nginx-1.25/README.md +++ /dev/null @@ -1,47 +0,0 @@ -NGINX 1.25 base image - -### HTTP/3 Support - -**HTTP/3 support is experimental and under development** - -[HTTP/3](https://datatracker.ietf.org/doc/html/rfc9114)\ -[QUIC](https://datatracker.ietf.org/doc/html/rfc9000) - -[According to the documentation, NGINX 1.25.0 or higher supports HTTP/3:](https://nginx.org/en/docs/quic.html) - -> Support for QUIC and HTTP/3 protocols is available since 1.25.0. - -But this requires adding a new flag during the build: - -> When configuring nginx, it is possible to enable QUIC and HTTP/3 using the --with-http_v3_module configuration parameter. - -[We have added this flag](https://github.com/kubernetes/ingress-nginx/pull/11470), but it is not enough to use HTTP/3 in ingress-nginx, this is the first step. - -The next steps will be: - -1. **Waiting for OpenSSL 3.4.**\ - The main problem is, that we still use OpenSSL (3.x) and it does not support the important mechanism of TLS 1.3 - [early_data](https://datatracker.ietf.org/doc/html/rfc8446#section-2.3): - - > Otherwise, the OpenSSL compatibility layer will be used that does not support early data. - - [And although another part of the documentation says that the directive is supported with OpenSSL:](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_early_data) - - > The directive is supported when using OpenSSL 1.1.1 or higher. - - But this is incomplete support, because OpenSSL does not support this feature, and [it has only client side support:](https://github.com/openssl/openssl) - - > ... the QUIC (currently client side only) version 1 protocol - - [And also there are some issues even with client side](https://github.com/openssl/openssl/discussions/23339) - - Due to this, we currently have incomplete HTTP/3 support, without important security and performance features.\ - But the good news is that [OpenSSL plans to add server-side support in 3.4](https://github.com/openssl/web/blob/master/roadmap.md): - - > Server-side QUIC support - - [Overview of SSL libraries(HAProxy Documentation)](https://github.com/haproxy/wiki/wiki/SSL-Libraries-Support-Status#tldr) - -2. **Adding [parameters](https://nginx.org/en/docs/http/ngx_http_v3_module.html) to the configmap to configure HTTP/3 and quic(enableHTTP3, enableHTTP/0.9, maxCurrentStream, and so on).** -3. **Adding options to the nginx config template(`listen 443 quic` to server blocks and `add_header Alt-Svc 'h3=":8443"; ma=86400';` to location blocks).** -4. **Opening the https port for UDP in the container(because QUIC uses UDP).** -5. **Adding tests.** diff --git a/images/nginx-1.25/TAG b/images/nginx-1.25/TAG deleted file mode 100644 index f25246219..000000000 --- a/images/nginx-1.25/TAG +++ /dev/null @@ -1 +0,0 @@ -v0.0.12 diff --git a/images/nginx-1.25/cloudbuild.yaml b/images/nginx-1.25/cloudbuild.yaml deleted file mode 100644 index d8bb1f2a9..000000000 --- a/images/nginx-1.25/cloudbuild.yaml +++ /dev/null @@ -1,14 +0,0 @@ -options: - # Increase machine type for multi-arch builds. - machineType: E2_HIGHCPU_32 - # Ignore Prow provided substitutions. - substitution_option: ALLOW_LOOSE -steps: - - name: gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20240523-a15ad90fc9 - env: - - REGISTRY=gcr.io/k8s-staging-ingress-nginx - entrypoint: bash - args: - - -c - - gcloud auth configure-docker && cd images/nginx-1.25 && make push -timeout: 7200s diff --git a/images/nginx-1.25/rootfs/Dockerfile b/images/nginx-1.25/rootfs/Dockerfile deleted file mode 100644 index 13dcec33d..000000000 --- a/images/nginx-1.25/rootfs/Dockerfile +++ /dev/null @@ -1,74 +0,0 @@ -# Copyright 2024 The Kubernetes Authors. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -FROM alpine:3.20.0 as builder - -COPY . / - -RUN apk update \ - && apk upgrade \ - && apk add -U bash --no-cache \ - && /build.sh - -# Use a multi-stage build -FROM alpine:3.20.0 - -ENV PATH=$PATH:/usr/local/luajit/bin:/usr/local/nginx/sbin:/usr/local/nginx/bin - -ENV LUA_PATH="/usr/local/share/luajit-2.1.0-beta3/?.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/lib/lua/?.lua;;" -ENV LUA_CPATH="/usr/local/lib/lua/?/?.so;/usr/local/lib/lua/?.so;;" - -COPY --from=builder /usr/local /usr/local -COPY --from=builder /usr/lib/libopentelemetry* /usr/local/lib -COPY --from=builder /opt /opt -COPY --from=builder /etc/nginx /etc/nginx - -RUN apk update \ - && apk upgrade \ - && apk add -U --no-cache \ - bash \ - openssl \ - pcre \ - zlib \ - ca-certificates \ - patch \ - yajl \ - lmdb \ - libxml2 \ - libmaxminddb \ - yaml-cpp \ - dumb-init \ - tzdata \ - grpc-cpp \ - libprotobuf \ - && ln -s /usr/local/nginx/sbin/nginx /sbin/nginx \ - && adduser -S -D -H -u 101 -h /usr/local/nginx \ - -s /sbin/nologin -G www-data -g www-data www-data \ - && bash -eu -c ' \ - writeDirs=( \ - /var/log/nginx \ - /var/lib/nginx/body \ - /var/lib/nginx/fastcgi \ - /var/lib/nginx/proxy \ - /var/lib/nginx/scgi \ - /var/lib/nginx/uwsgi \ - /var/log/audit \ - ); \ - for dir in "${writeDirs[@]}"; do \ - mkdir -p ${dir}; \ - chown -R www-data.www-data ${dir}; \ - done' - -EXPOSE 80 443 - -CMD ["nginx", "-g", "daemon off;"] diff --git a/images/nginx-1.25/rootfs/build.sh b/images/nginx-1.25/rootfs/build.sh deleted file mode 100755 index f60a260f9..000000000 --- a/images/nginx-1.25/rootfs/build.sh +++ /dev/null @@ -1,628 +0,0 @@ -#!/bin/bash - -# Copyright 2023 The Kubernetes Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -o errexit -set -o nounset -set -o pipefail - -export NGINX_VERSION=1.25.5 - -# Check for recent changes: https://github.com/vision5/ngx_devel_kit/compare/v0.3.3...master -export NDK_VERSION=v0.3.3 - -# Check for recent changes: https://github.com/openresty/set-misc-nginx-module/compare/v0.33...master -export SETMISC_VERSION=796f5a3e518748eb29a93bd450324e0ad45b704e - -# Check for recent changes: https://github.com/openresty/headers-more-nginx-module/compare/v0.37...master -export MORE_HEADERS_VERSION=v0.37 - -# Check for recent changes: https://github.com/atomx/nginx-http-auth-digest/compare/v1.0.0...atomx:master -export NGINX_DIGEST_AUTH=v1.0.0 - -# Check for recent changes: https://github.com/yaoweibin/ngx_http_substitutions_filter_module/compare/v0.6.4...master -export NGINX_SUBSTITUTIONS=e12e965ac1837ca709709f9a26f572a54d83430e - -# Check for recent changes: https://github.com/SpiderLabs/ModSecurity-nginx/compare/v1.0.3...master -export MODSECURITY_VERSION=v1.0.3 - -# Check for recent changes: https://github.com/SpiderLabs/ModSecurity/compare/v3.0.8...v3/master -export MODSECURITY_LIB_VERSION=v3.0.12 - -# Check for recent changes: https://github.com/coreruleset/coreruleset/compare/v3.3.5...v4.0/main -export OWASP_MODSECURITY_CRS_VERSION=v4.4.0 - -# Check for recent changes: https://github.com/openresty/lua-nginx-module/compare/v0.10.26``...master -export LUA_NGX_VERSION=v0.10.26 - -# Check for recent changes: https://github.com/openresty/stream-lua-nginx-module/compare/bea8a0c0de94cede71554f53818ac0267d675d63...master -export LUA_STREAM_NGX_VERSION=bea8a0c0de94cede71554f53818ac0267d675d63 - -# Check for recent changes: https://github.com/openresty/lua-upstream-nginx-module/compare/8aa93ead98ba2060d4efd594ae33a35d153589bf...master -export LUA_UPSTREAM_VERSION=542be0893543a4e42d89f6dd85372972f5ff2a36 - -# Check for recent changes: https://github.com/openresty/lua-cjson/compare/2.1.0.13...openresty:master -export LUA_CJSON_VERSION=2.1.0.13 - -# Check for recent changes: https://github.com/leev/ngx_http_geoip2_module/compare/a607a41a8115fecfc05b5c283c81532a3d605425...master -export GEOIP2_VERSION=a607a41a8115fecfc05b5c283c81532a3d605425 - -# Check for recent changes: https://github.com/openresty/luajit2/compare/v2.1-20240314...v2.1-agentzh -export LUAJIT_VERSION=v2.1-20240314 - -# Check for recent changes: https://github.com/openresty/lua-resty-balancer/compare/1cd4363c0a239afe4765ec607dcfbbb4e5900eea...master -export LUA_RESTY_BALANCER=1cd4363c0a239afe4765ec607dcfbbb4e5900eea - -# Check for recent changes: https://github.com/openresty/lua-resty-lrucache/compare/99e7578465b40f36f596d099b82eab404f2b42ed...master -export LUA_RESTY_CACHE=99e7578465b40f36f596d099b82eab404f2b42ed - -# Check for recent changes: https://github.com/openresty/lua-resty-core/compare/v0.1.27...master -export LUA_RESTY_CORE=v0.1.28 - -# Check for recent changes: https://github.com/cloudflare/lua-resty-cookie/compare/f418d77082eaef48331302e84330488fdc810ef4...master -export LUA_RESTY_COOKIE_VERSION=f418d77082eaef48331302e84330488fdc810ef4 - -# Check for recent changes: https://github.com/openresty/lua-resty-dns/compare/8bb53516e2933e61c317db740a9b7c2048847c2f...master -export LUA_RESTY_DNS=8bb53516e2933e61c317db740a9b7c2048847c2f - -# Check for recent changes: https://github.com/ledgetech/lua-resty-http/compare/v0.17.1...master -export LUA_RESTY_HTTP=v0.17.1 - -# Check for recent changes: https://github.com/openresty/lua-resty-lock/compare/v0.09...master -export LUA_RESTY_LOCK=405d0bf4cbfa74d742c6ed3158d442221e6212a9 - -# Check for recent changes: https://github.com/openresty/lua-resty-upload/compare/v0.11...master -export LUA_RESTY_UPLOAD_VERSION=979372cce011f3176af3c9aff53fd0e992c4bfd3 - -# Check for recent changes: https://github.com/openresty/lua-resty-string/compare/v0.15...master -export LUA_RESTY_STRING_VERSION=6f1bc21d86daef804df3cc34d6427ef68da26844 - -# Check for recent changes: https://github.com/openresty/lua-resty-memcached/compare/v0.17...master -export LUA_RESTY_MEMCACHED_VERSION=2f02b68bf65fa2332cce070674a93a69a6c7239b - -# Check for recent changes: https://github.com/openresty/lua-resty-redis/compare/v0.30...master -export LUA_RESTY_REDIS_VERSION=8641b9f1b6f75cca50c90cf8ca5c502ad8950aa8 - -# Check for recent changes: https://github.com/api7/lua-resty-ipmatcher/compare/v0.6.1...master -export LUA_RESTY_IPMATCHER_VERSION=3e93c53eb8c9884efe939ef070486a0e507cc5be - -# Check for recent changes: https://github.com/ElvinEfendi/lua-resty-global-throttle/compare/v0.2.0...main -export LUA_RESTY_GLOBAL_THROTTLE_VERSION=v0.2.0 - -# Check for recent changes: https://github.com/microsoft/mimalloc/compare/v2.1.7...master -export MIMALOC_VERSION=v2.1.7 - -# Check on https://github.com/open-telemetry/opentelemetry-cpp -export OPENTELEMETRY_CPP_VERSION="v1.11.0" -# Check on https://github.com/open-telemetry/opentelemetry-proto -export OPENTELEMETRY_PROTO_VERSION="v1.1.0" - -export BUILD_PATH=/tmp/build - -ARCH=$(uname -m) - -get_src() -{ - hash="$1" - url="$2" - dest="${3-}" - ARGS="" - f=$(basename "$url") - - echo "Downloading $url" - - curl -sSL "$url" -o "$f" - # TODO: Reenable checksum verification but make it smarter - # echo "$hash $f" | sha256sum -c - || exit 10 - if [ ! -z "$dest" ]; then - mkdir ${BUILD_PATH}/${dest} - ARGS="-C ${BUILD_PATH}/${dest} --strip-components=1" - fi - tar xvzf "$f" $ARGS - rm -rf "$f" -} - -# install required packages to build -# Dependencies from "ninja" and below are OTEL dependencies -apk add \ - bash \ - gcc \ - clang \ - libc-dev \ - make \ - automake \ - openssl-dev \ - pcre-dev \ - zlib-dev \ - linux-headers \ - libxslt-dev \ - gd-dev \ - perl-dev \ - libedit-dev \ - mercurial \ - alpine-sdk \ - findutils \ - curl \ - ca-certificates \ - patch \ - libaio-dev \ - openssl \ - cmake \ - util-linux \ - lmdb-tools \ - wget \ - curl-dev \ - libprotobuf \ - git g++ pkgconf flex bison doxygen yajl-dev lmdb-dev libtool autoconf libxml2 libxml2-dev \ - python3 \ - libmaxminddb-dev \ - bc \ - unzip \ - dos2unix \ - yaml-cpp \ - coreutils \ - ninja \ - gtest-dev \ - git \ - build-base \ - pkgconfig \ - c-ares-dev \ - re2-dev \ - grpc-dev \ - protobuf-dev - -# apk add -X http://dl-cdn.alpinelinux.org/alpine/edge/testing opentelemetry-cpp-dev - -# There is some bug with some platforms and git, so force HTTP/1.1 -git config --global http.version HTTP/1.1 -git config --global http.postBuffer 157286400 - -mkdir -p /etc/nginx - -mkdir --verbose -p "$BUILD_PATH" -cd "$BUILD_PATH" - -# download, verify and extract the source files -get_src 66dc7081488811e9f925719e34d1b4504c2801c81dee2920e5452a86b11405ae \ - "https://nginx.org/download/nginx-$NGINX_VERSION.tar.gz" - -get_src aa961eafb8317e0eb8da37eb6e2c9ff42267edd18b56947384e719b85188f58b \ - "https://github.com/vision5/ngx_devel_kit/archive/$NDK_VERSION.tar.gz" "ngx_devel_kit" - -get_src abc123 \ - "https://github.com/open-telemetry/opentelemetry-cpp/archive/$OPENTELEMETRY_CPP_VERSION.tar.gz" "opentelemetry-cpp" - -get_src abc123 \ - "https://github.com/open-telemetry/opentelemetry-proto/archive/$OPENTELEMETRY_PROTO_VERSION.tar.gz" "opentelemetry-proto" - -get_src cd5e2cc834bcfa30149e7511f2b5a2183baf0b70dc091af717a89a64e44a2985 \ - "https://github.com/openresty/set-misc-nginx-module/archive/$SETMISC_VERSION.tar.gz" "set-misc-nginx-module" - -get_src 0c0d2ced2ce895b3f45eb2b230cd90508ab2a773299f153de14a43e44c1209b3 \ - "https://github.com/openresty/headers-more-nginx-module/archive/$MORE_HEADERS_VERSION.tar.gz" "headers-more-nginx-module" - -get_src f09851e6309560a8ff3e901548405066c83f1f6ff88aa7171e0763bd9514762b \ - "https://github.com/atomx/nginx-http-auth-digest/archive/$NGINX_DIGEST_AUTH.tar.gz" "nginx-http-auth-digest" - -get_src a98b48947359166326d58700ccdc27256d2648218072da138ab6b47de47fbd8f \ - "https://github.com/yaoweibin/ngx_http_substitutions_filter_module/archive/$NGINX_SUBSTITUTIONS.tar.gz" "ngx_http_substitutions_filter_module" - -get_src 32a42256616cc674dca24c8654397390adff15b888b77eb74e0687f023c8751b \ - "https://github.com/SpiderLabs/ModSecurity-nginx/archive/$MODSECURITY_VERSION.tar.gz" "ModSecurity-nginx" - -get_src bc764db42830aeaf74755754b900253c233ad57498debe7a441cee2c6f4b07c2 \ - "https://github.com/openresty/lua-nginx-module/archive/$LUA_NGX_VERSION.tar.gz" "lua-nginx-module" - -get_src 01b715754a8248cc7228e0c8f97f7488ae429d90208de0481394e35d24cef32f \ - "https://github.com/openresty/stream-lua-nginx-module/archive/$LUA_STREAM_NGX_VERSION.tar.gz" "stream-lua-nginx-module" - -get_src a92c9ee6682567605ece55d4eed5d1d54446ba6fba748cff0a2482aea5713d5f \ - "https://github.com/openresty/lua-upstream-nginx-module/archive/$LUA_UPSTREAM_VERSION.tar.gz" "lua-upstream-nginx-module" - -get_src 77bbcbb24c3c78f51560017288f3118d995fe71240aa379f5818ff6b166712ff \ - "https://github.com/openresty/luajit2/archive/$LUAJIT_VERSION.tar.gz" "luajit2" - -get_src b6c9c09fd43eb34a71e706ad780b2ead26549a9a9f59280fe558f5b7b980b7c6 \ - "https://github.com/leev/ngx_http_geoip2_module/archive/$GEOIP2_VERSION.tar.gz" "ngx_http_geoip2_module" - -get_src deb4ab1ffb9f3d962c4b4a2c4bdff692b86a209e3835ae71ebdf3b97189e40a9 \ - "https://github.com/openresty/lua-resty-upload/archive/$LUA_RESTY_UPLOAD_VERSION.tar.gz" "lua-resty-upload" - -get_src bdbf271003d95aa91cab0a92f24dca129e99b33f79c13ebfcdbbcbb558129491 \ - "https://github.com/openresty/lua-resty-string/archive/$LUA_RESTY_STRING_VERSION.tar.gz" "lua-resty-string" - -get_src 16d72ed133f0c6df376a327386c3ef4e9406cf51003a700737c3805770ade7c5 \ - "https://github.com/openresty/lua-resty-balancer/archive/$LUA_RESTY_BALANCER.tar.gz" "lua-resty-balancer" - -get_src 39baab9e2b31cc48cecf896cea40ef6e80559054fd8a6e440cc804a858ea84d4 \ - "https://github.com/openresty/lua-resty-core/archive/$LUA_RESTY_CORE.tar.gz" "lua-resty-core" - -get_src a77b9de160d81712f2f442e1de8b78a5a7ef0d08f13430ff619f79235db974d4 \ - "https://github.com/openresty/lua-cjson/archive/$LUA_CJSON_VERSION.tar.gz" "lua-cjson" - -get_src 5ed48c36231e2622b001308622d46a0077525ac2f751e8cc0c9905914254baa4 \ - "https://github.com/cloudflare/lua-resty-cookie/archive/$LUA_RESTY_COOKIE_VERSION.tar.gz" "lua-resty-cookie" - -get_src 573184006b98ccee2594b0d134fa4d05e5d2afd5141cbad315051ccf7e9b6403 \ - "https://github.com/openresty/lua-resty-lrucache/archive/$LUA_RESTY_CACHE.tar.gz" "lua-resty-lrucache" - -get_src b4ddcd47db347e9adf5c1e1491a6279a6ae2a3aff3155ef77ea0a65c998a69c1 \ - "https://github.com/openresty/lua-resty-lock/archive/$LUA_RESTY_LOCK.tar.gz" "lua-resty-lock" - -get_src 70e9a01eb32ccade0d5116a25bcffde0445b94ad35035ce06b94ccd260ad1bf0 \ - "https://github.com/openresty/lua-resty-dns/archive/$LUA_RESTY_DNS.tar.gz" "lua-resty-dns" - -get_src 9fcb6db95bc37b6fce77d3b3dc740d593f9d90dce0369b405eb04844d56ac43f \ - "https://github.com/ledgetech/lua-resty-http/archive/$LUA_RESTY_HTTP.tar.gz" "lua-resty-http" - -get_src 02733575c4aed15f6cab662378e4b071c0a4a4d07940c4ef19a7319e9be943d4 \ - "https://github.com/openresty/lua-resty-memcached/archive/$LUA_RESTY_MEMCACHED_VERSION.tar.gz" "lua-resty-memcached" - -get_src c15aed1a01c88a3a6387d9af67a957dff670357f5fdb4ee182beb44635eef3f1 \ - "https://github.com/openresty/lua-resty-redis/archive/$LUA_RESTY_REDIS_VERSION.tar.gz" "lua-resty-redis" - -get_src efb767487ea3f6031577b9b224467ddbda2ad51a41c5867a47582d4ad85d609e \ - "https://github.com/api7/lua-resty-ipmatcher/archive/$LUA_RESTY_IPMATCHER_VERSION.tar.gz" "lua-resty-ipmatcher" - -get_src 0fb790e394510e73fdba1492e576aaec0b8ee9ef08e3e821ce253a07719cf7ea \ - "https://github.com/ElvinEfendi/lua-resty-global-throttle/archive/$LUA_RESTY_GLOBAL_THROTTLE_VERSION.tar.gz" "lua-resty-global-throttle" - -get_src d74f86ada2329016068bc5a243268f1f555edd620b6a7d6ce89295e7d6cf18da \ - "https://github.com/microsoft/mimalloc/archive/${MIMALOC_VERSION}.tar.gz" "mimalloc" - -# improve compilation times -CORES=$(($(grep -c ^processor /proc/cpuinfo) - 1)) - -export MAKEFLAGS=-j${CORES} -export CTEST_BUILD_FLAGS=${MAKEFLAGS} - -# Install luajit from openresty fork -export LUAJIT_LIB=/usr/local/lib -export LUA_LIB_DIR="$LUAJIT_LIB/lua" -export LUAJIT_INC=/usr/local/include/luajit-2.1 - -cd "$BUILD_PATH/luajit2" -make CCDEBUG=-g -make install - -ln -s /usr/local/bin/luajit /usr/local/bin/lua -ln -s "$LUAJIT_INC" /usr/local/include/lua - -cd "$BUILD_PATH/opentelemetry-cpp" -export CXXFLAGS="-DBENCHMARK_HAS_NO_INLINE_ASSEMBLY" -cmake -B build -G Ninja -Wno-dev \ - -DOTELCPP_PROTO_PATH="${BUILD_PATH}/opentelemetry-proto/" \ - -DCMAKE_INSTALL_PREFIX=/usr \ - -DBUILD_SHARED_LIBS=ON \ - -DBUILD_TESTING="OFF" \ - -DBUILD_W3CTRACECONTEXT_TEST="OFF" \ - -DCMAKE_BUILD_TYPE=None \ - -DWITH_ABSEIL=ON \ - -DWITH_STL=ON \ - -DWITH_EXAMPLES=OFF \ - -DWITH_ZPAGES=OFF \ - -DWITH_OTLP_GRPC=ON \ - -DWITH_OTLP_HTTP=ON \ - -DWITH_ZIPKIN=ON \ - -DWITH_PROMETHEUS=OFF \ - -DWITH_ASYNC_EXPORT_PREVIEW=OFF \ - -DWITH_METRICS_EXEMPLAR_PREVIEW=OFF - cmake --build build - cmake --install build - -# Git tuning -git config --global --add core.compression -1 - -# Get Brotli source and deps -cd "$BUILD_PATH" -git clone --depth=100 https://github.com/google/ngx_brotli.git -cd ngx_brotli -# https://github.com/google/ngx_brotli/issues/156 -git reset --hard 63ca02abdcf79c9e788d2eedcc388d2335902e52 -git submodule init -git submodule update - -cd "$BUILD_PATH" -git clone --depth=1 https://github.com/ssdeep-project/ssdeep -cd ssdeep/ - -./bootstrap -./configure - -make -make install - -# build modsecurity library -cd "$BUILD_PATH" -git clone -n https://github.com/SpiderLabs/ModSecurity -cd ModSecurity/ -git checkout $MODSECURITY_LIB_VERSION -git submodule init -git submodule update - -sh build.sh - -# https://github.com/SpiderLabs/ModSecurity/issues/1909#issuecomment-465926762 -sed -i '115i LUA_CFLAGS="${LUA_CFLAGS} -DWITH_LUA_JIT_2_1"' build/lua.m4 -sed -i '117i AC_SUBST(LUA_CFLAGS)' build/lua.m4 - -./configure \ - --disable-doxygen-doc \ - --disable-doxygen-html \ - --disable-examples - -make -make install - -mkdir -p /etc/nginx/modsecurity -cp modsecurity.conf-recommended /etc/nginx/modsecurity/modsecurity.conf -cp unicode.mapping /etc/nginx/modsecurity/unicode.mapping - -# Replace serial logging with concurrent -sed -i 's|SecAuditLogType Serial|SecAuditLogType Concurrent|g' /etc/nginx/modsecurity/modsecurity.conf - -# Concurrent logging implies the log is stored in several files -echo "SecAuditLogStorageDir /var/log/audit/" >> /etc/nginx/modsecurity/modsecurity.conf - -# Download owasp modsecurity crs -cd /etc/nginx/ - -git clone -b $OWASP_MODSECURITY_CRS_VERSION https://github.com/coreruleset/coreruleset -mv coreruleset owasp-modsecurity-crs -cd owasp-modsecurity-crs - -mv crs-setup.conf.example crs-setup.conf -mv rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf -mv rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf -cd .. - -# OWASP CRS v4 rules -echo " -Include /etc/nginx/owasp-modsecurity-crs/crs-setup.conf -Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf -Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-901-INITIALIZATION.conf -Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-905-COMMON-EXCEPTIONS.conf -Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-911-METHOD-ENFORCEMENT.conf -Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-913-SCANNER-DETECTION.conf -Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf -Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-921-PROTOCOL-ATTACK.conf -Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-922-MULTIPART-ATTACK.conf -Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf -Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-931-APPLICATION-ATTACK-RFI.conf -Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf -Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf -Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-934-APPLICATION-ATTACK-GENERIC.conf -Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf -Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf -Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION.conf -Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-944-APPLICATION-ATTACK-JAVA.conf -Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf -Include /etc/nginx/owasp-modsecurity-crs/rules/RESPONSE-950-DATA-LEAKAGES.conf -Include /etc/nginx/owasp-modsecurity-crs/rules/RESPONSE-951-DATA-LEAKAGES-SQL.conf -Include /etc/nginx/owasp-modsecurity-crs/rules/RESPONSE-952-DATA-LEAKAGES-JAVA.conf -Include /etc/nginx/owasp-modsecurity-crs/rules/RESPONSE-953-DATA-LEAKAGES-PHP.conf -Include /etc/nginx/owasp-modsecurity-crs/rules/RESPONSE-954-DATA-LEAKAGES-IIS.conf -Include /etc/nginx/owasp-modsecurity-crs/rules/RESPONSE-955-WEB-SHELLS.conf -Include /etc/nginx/owasp-modsecurity-crs/rules/RESPONSE-959-BLOCKING-EVALUATION.conf -Include /etc/nginx/owasp-modsecurity-crs/rules/RESPONSE-980-CORRELATION.conf -Include /etc/nginx/owasp-modsecurity-crs/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf -" > /etc/nginx/owasp-modsecurity-crs/nginx-modsecurity.conf - -# build nginx -cd "$BUILD_PATH/nginx-$NGINX_VERSION" - -# apply nginx patches -for PATCH in `ls /patches`;do - echo "Patch: $PATCH" - if [[ "$PATCH" == *.txt ]]; then - patch -p0 < /patches/$PATCH - else - patch -p1 < /patches/$PATCH - fi -done - -WITH_FLAGS="--with-debug \ - --with-compat \ - --with-pcre-jit \ - --with-http_ssl_module \ - --with-http_stub_status_module \ - --with-http_realip_module \ - --with-http_auth_request_module \ - --with-http_addition_module \ - --with-http_gzip_static_module \ - --with-http_sub_module \ - --with-http_v2_module \ - --with-http_v3_module \ - --with-stream \ - --with-stream_ssl_module \ - --with-stream_realip_module \ - --with-stream_ssl_preread_module \ - --with-threads \ - --with-http_secure_link_module \ - --with-http_gunzip_module" - -# "Combining -flto with -g is currently experimental and expected to produce unexpected results." -# https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html -CC_OPT="-g -O2 -fPIE -fstack-protector-strong \ - -Wformat \ - -Werror=format-security \ - -Wno-deprecated-declarations \ - -fno-strict-aliasing \ - -D_FORTIFY_SOURCE=2 \ - --param=ssp-buffer-size=4 \ - -DTCP_FASTOPEN=23 \ - -fPIC \ - -Wno-cast-function-type" - -LD_OPT="-fPIE -fPIC -pie -Wl,-z,relro -Wl,-z,now" - -if [[ ${ARCH} != "aarch64" ]]; then - WITH_FLAGS+=" --with-file-aio" -fi - -if [[ ${ARCH} == "x86_64" ]]; then - CC_OPT+=' -m64 -mtune=generic' -fi - -WITH_MODULES=" \ - --add-module=$BUILD_PATH/ngx_devel_kit \ - --add-module=$BUILD_PATH/set-misc-nginx-module \ - --add-module=$BUILD_PATH/headers-more-nginx-module \ - --add-module=$BUILD_PATH/ngx_http_substitutions_filter_module \ - --add-module=$BUILD_PATH/lua-nginx-module \ - --add-module=$BUILD_PATH/stream-lua-nginx-module \ - --add-module=$BUILD_PATH/lua-upstream-nginx-module \ - --add-dynamic-module=$BUILD_PATH/nginx-http-auth-digest \ - --add-dynamic-module=$BUILD_PATH/ModSecurity-nginx \ - --add-dynamic-module=$BUILD_PATH/ngx_http_geoip2_module \ - --add-dynamic-module=$BUILD_PATH/ngx_brotli" - -./configure \ - --prefix=/usr/local/nginx \ - --conf-path=/etc/nginx/nginx.conf \ - --modules-path=/etc/nginx/modules \ - --http-log-path=/var/log/nginx/access.log \ - --error-log-path=/var/log/nginx/error.log \ - --lock-path=/var/lock/nginx.lock \ - --pid-path=/run/nginx.pid \ - --http-client-body-temp-path=/var/lib/nginx/body \ - --http-fastcgi-temp-path=/var/lib/nginx/fastcgi \ - --http-proxy-temp-path=/var/lib/nginx/proxy \ - --http-scgi-temp-path=/var/lib/nginx/scgi \ - --http-uwsgi-temp-path=/var/lib/nginx/uwsgi \ - ${WITH_FLAGS} \ - --without-mail_pop3_module \ - --without-mail_smtp_module \ - --without-mail_imap_module \ - --without-http_uwsgi_module \ - --without-http_scgi_module \ - --with-cc-opt="${CC_OPT}" \ - --with-ld-opt="${LD_OPT}" \ - --user=www-data \ - --group=www-data \ - ${WITH_MODULES} - -make -make modules -make install - -export OPENTELEMETRY_CONTRIB_COMMIT=aaa51e2297bcb34297f3c7aa44fa790497d2f7f3 -cd "$BUILD_PATH" - -git clone https://github.com/open-telemetry/opentelemetry-cpp-contrib.git opentelemetry-cpp-contrib-${OPENTELEMETRY_CONTRIB_COMMIT} - -cd ${BUILD_PATH}/opentelemetry-cpp-contrib-${OPENTELEMETRY_CONTRIB_COMMIT} -git reset --hard ${OPENTELEMETRY_CONTRIB_COMMIT} - -export OTEL_TEMP_INSTALL=/tmp/otel -mkdir -p ${OTEL_TEMP_INSTALL} - -cd ${BUILD_PATH}/opentelemetry-cpp-contrib-${OPENTELEMETRY_CONTRIB_COMMIT}/instrumentation/nginx -mkdir -p build -cd build -cmake -DCMAKE_BUILD_TYPE=Release \ - -G Ninja \ - -DCMAKE_CXX_STANDARD=17 \ - -DCMAKE_INSTALL_PREFIX=${OTEL_TEMP_INSTALL} \ - -DBUILD_SHARED_LIBS=ON \ - -DNGINX_VERSION=${NGINX_VERSION} \ - .. -cmake --build . -j ${CORES} --target install - -mkdir -p /etc/nginx/modules -cp ${OTEL_TEMP_INSTALL}/otel_ngx_module.so /etc/nginx/modules/otel_ngx_module.so - - -cd "$BUILD_PATH/lua-resty-core" -make install - -cd "$BUILD_PATH/lua-resty-balancer" -make all -make install - -export LUA_INCLUDE_DIR=/usr/local/include/luajit-2.1 -ln -s $LUA_INCLUDE_DIR /usr/include/lua5.1 - -cd "$BUILD_PATH/lua-cjson" -make all -make install - -cd "$BUILD_PATH/lua-resty-cookie" -make all -make install - -cd "$BUILD_PATH/lua-resty-lrucache" -make install - -cd "$BUILD_PATH/lua-resty-dns" -make install - -cd "$BUILD_PATH/lua-resty-lock" -make install - -# required for OCSP verification -cd "$BUILD_PATH/lua-resty-http" -make install - -cd "$BUILD_PATH/lua-resty-upload" -make install - -cd "$BUILD_PATH/lua-resty-string" -make install - -cd "$BUILD_PATH/lua-resty-memcached" -make install - -cd "$BUILD_PATH/lua-resty-redis" -make install - -cd "$BUILD_PATH/lua-resty-ipmatcher" -INST_LUADIR=/usr/local/lib/lua make install - -cd "$BUILD_PATH/lua-resty-global-throttle" -make install - -cd "$BUILD_PATH/mimalloc" -mkdir -p out/release -cd out/release - -cmake ../.. - -make -make install - -# update image permissions -writeDirs=( \ - /etc/nginx \ - /usr/local/nginx \ - /opt/modsecurity/var/log \ - /opt/modsecurity/var/upload \ - /opt/modsecurity/var/audit \ - /var/log/audit \ - /var/log/nginx \ -); - -adduser -S -D -H -u 101 -h /usr/local/nginx -s /sbin/nologin -G www-data -g www-data www-data - -for dir in "${writeDirs[@]}"; do - mkdir -p ${dir}; - chown -R www-data.www-data ${dir}; -done - -rm -rf /etc/nginx/owasp-modsecurity-crs/.git -rm -rf /etc/nginx/owasp-modsecurity-crs/tests - -# remove .a files -find /usr/local -name "*.a" -print | xargs /bin/rm diff --git a/images/nginx-1.25/rootfs/patches/18_nginx-1.25.3-no_Werror.patch b/images/nginx-1.25/rootfs/patches/18_nginx-1.25.3-no_Werror.patch deleted file mode 100644 index f7176faff..000000000 --- a/images/nginx-1.25/rootfs/patches/18_nginx-1.25.3-no_Werror.patch +++ /dev/null @@ -1,36 +0,0 @@ -diff -urp nginx-1.25.3/auto/cc/clang nginx-1.25.3-patched/auto/cc/clang ---- nginx-1.25.3/auto/cc/clang 2014-03-04 03:39:24.000000000 -0800 -+++ nginx-1.25.3-patched/auto/cc/clang 2014-03-13 20:54:26.241413360 -0700 -@@ -89,7 +89,7 @@ CFLAGS="$CFLAGS -Wconditional-uninitiali - CFLAGS="$CFLAGS -Wno-unused-parameter" - - # stop on warning --CFLAGS="$CFLAGS -Werror" -+#CFLAGS="$CFLAGS -Werror" - - # debug - CFLAGS="$CFLAGS -g" -diff -urp nginx-1.25.3/auto/cc/gcc nginx-1.25.3-patched/auto/cc/gcc ---- nginx-1.25.3/auto/cc/gcc 2014-03-04 03:39:24.000000000 -0800 -+++ nginx-1.25.3-patched/auto/cc/gcc 2014-03-13 20:54:13.301355329 -0700 -@@ -168,7 +168,7 @@ esac - - - # stop on warning --CFLAGS="$CFLAGS -Werror" -+#CFLAGS="$CFLAGS -Werror" - - # debug - CFLAGS="$CFLAGS -g" -diff -urp nginx-1.25.3/auto/cc/icc nginx-1.25.3-patched/auto/cc/icc ---- nginx-1.25.3/auto/cc/icc 2014-03-04 03:39:24.000000000 -0800 -+++ nginx-1.25.3-patched/auto/cc/icc 2014-03-13 20:54:13.301355329 -0700 -@@ -115,7 +115,7 @@ case "$NGX_ICC_VER" in - esac - - # stop on warning --CFLAGS="$CFLAGS -Werror" -+#CFLAGS="$CFLAGS -Werror" - - # debug - CFLAGS="$CFLAGS -g" diff --git a/images/nginx/Makefile b/images/nginx/Makefile index b54a7739b..3cc14e5b3 100644 --- a/images/nginx/Makefile +++ b/images/nginx/Makefile @@ -1,4 +1,4 @@ -# Copyright 2017 The Kubernetes Authors. All rights reserved. +# Copyright 2024 The Kubernetes Authors. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -22,9 +22,9 @@ INIT_BUILDX=$(DIR)/../../hack/init-buildx.sh # 0.0.0 shouldn't clobber any released builds SHORT_SHA ?=$(shell git rev-parse --short HEAD) -TAG ?=v$(shell date +%Y%m%d)-$(SHORT_SHA) +TAG ?=$(shell cat TAG) -REGISTRY ?= gcr.io/k8s-staging-ingress-nginx +REGISTRY ?= us-central1-docker.pkg.dev/k8s-staging-images/ingress-nginx IMAGE = $(REGISTRY)/nginx @@ -32,7 +32,7 @@ IMAGE = $(REGISTRY)/nginx export DOCKER_CLI_EXPERIMENTAL=enabled # build with buildx -PLATFORMS?=linux/amd64,linux/arm,linux/arm64,linux/s390x +PLATFORMS?=linux/amd64,linux/arm,linux/arm64 OUTPUT= PROGRESS=plain build: ensure-buildx diff --git a/images/nginx/README.md b/images/nginx/README.md index da6994fb5..768077215 100644 --- a/images/nginx/README.md +++ b/images/nginx/README.md @@ -1,27 +1,47 @@ -NGINX base image using [alpine](https://www.alpinelinux.org/) +NGINX base image -This custom image contains: +### HTTP/3 Support -- [nginx-http-auth-digest](https://github.com/atomx/nginx-http-auth-digest) -- [ngx_http_substitutions_filter_module](https://github.com/yaoweibin/ngx_http_substitutions_filter_module) -- [OpenTelemetry-CPP](https://github.com/open-telemetry/opentelemetry-cpp) -- [OpenTelemetry-CPP-Nginx](https://github.com/open-telemetry/opentelemetry-cpp-contrib/tree/main/instrumentation/nginx) -- [nginx-opentracing](https://github.com/opentracing-contrib/nginx-opentracing) -- [opentracing-cpp](https://github.com/opentracing/opentracing-cpp) -- [zipkin-cpp-opentracing](https://github.com/rnburn/zipkin-cpp-opentracing) -- [dd-opentracing-cpp](https://github.com/DataDog/dd-opentracing-cpp) -- [ModSecurity-nginx](https://github.com/SpiderLabs/ModSecurity-nginx) (only supported in x86_64) -- [brotli](https://github.com/google/brotli) -- [geoip2](https://github.com/leev/ngx_http_geoip2_module) +**HTTP/3 support is experimental and under development** -**How to use this image:** -This image provides a default configuration file with no backend servers. +[HTTP/3](https://datatracker.ietf.org/doc/html/rfc9114)\ +[QUIC](https://datatracker.ietf.org/doc/html/rfc9000) -_Using docker_ +[According to the documentation, NGINX 1.25.0 or higher supports HTTP/3:](https://nginx.org/en/docs/quic.html) -NGINX base image we use is defined in NGINX_BASE file at the root of the project +> Support for QUIC and HTTP/3 protocols is available since 1.25.0. -```console -docker run -v /some/nginx.conf:/etc/nginx/nginx.conf:ro $(cat ../../NGINX_BASE) -``` +But this requires adding a new flag during the build: +> When configuring nginx, it is possible to enable QUIC and HTTP/3 using the --with-http_v3_module configuration parameter. + +[We have added this flag](https://github.com/kubernetes/ingress-nginx/pull/11470), but it is not enough to use HTTP/3 in ingress-nginx, this is the first step. + +The next steps will be: + +1. **Waiting for OpenSSL 3.4.**\ + The main problem is, that we still use OpenSSL (3.x) and it does not support the important mechanism of TLS 1.3 - [early_data](https://datatracker.ietf.org/doc/html/rfc8446#section-2.3): + + > Otherwise, the OpenSSL compatibility layer will be used that does not support early data. + + [And although another part of the documentation says that the directive is supported with OpenSSL:](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_early_data) + + > The directive is supported when using OpenSSL 1.1.1 or higher. + + But this is incomplete support, because OpenSSL does not support this feature, and [it has only client side support:](https://github.com/openssl/openssl) + + > ... the QUIC (currently client side only) version 1 protocol + + [And also there are some issues even with client side](https://github.com/openssl/openssl/discussions/23339) + + Due to this, we currently have incomplete HTTP/3 support, without important security and performance features.\ + But the good news is that [OpenSSL plans to add server-side support in 3.4](https://github.com/openssl/web/blob/master/roadmap.md): + + > Server-side QUIC support + + [Overview of SSL libraries(HAProxy Documentation)](https://github.com/haproxy/wiki/wiki/SSL-Libraries-Support-Status#tldr) + +2. **Adding [parameters](https://nginx.org/en/docs/http/ngx_http_v3_module.html) to the configmap to configure HTTP/3 and quic(enableHTTP3, enableHTTP/0.9, maxCurrentStream, and so on).** +3. **Adding options to the nginx config template(`listen 443 quic` to server blocks and `add_header Alt-Svc 'h3=":8443"; ma=86400';` to location blocks).** +4. **Opening the https port for UDP in the container(because QUIC uses UDP).** +5. **Adding tests.** diff --git a/images/nginx/TAG b/images/nginx/TAG index 0ec25f750..46b105a30 100644 --- a/images/nginx/TAG +++ b/images/nginx/TAG @@ -1 +1 @@ -v1.0.0 +v2.0.0 diff --git a/images/nginx/cloudbuild.yaml b/images/nginx/cloudbuild.yaml index a5ec1abd8..2563692d7 100644 --- a/images/nginx/cloudbuild.yaml +++ b/images/nginx/cloudbuild.yaml @@ -4,9 +4,9 @@ options: # Ignore Prow provided substitutions. substitution_option: ALLOW_LOOSE steps: - - name: gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20240523-a15ad90fc9 + - name: gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20250116-2a05ea7e3d env: - - REGISTRY=gcr.io/k8s-staging-ingress-nginx + - REGISTRY=us-central1-docker.pkg.dev/k8s-staging-images/ingress-nginx entrypoint: bash args: - -c diff --git a/images/nginx/rootfs/Dockerfile b/images/nginx/rootfs/Dockerfile index f3d61017e..834a9bcf3 100644 --- a/images/nginx/rootfs/Dockerfile +++ b/images/nginx/rootfs/Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2015 The Kubernetes Authors. All rights reserved. +# Copyright 2024 The Kubernetes Authors. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -11,7 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -FROM alpine:3.20.0 as builder +FROM alpine:3.21 as builder COPY . / @@ -21,7 +21,7 @@ RUN apk update \ && /build.sh # Use a multi-stage build -FROM alpine:3.20.0 +FROM alpine:3.21 ENV PATH=$PATH:/usr/local/luajit/bin:/usr/local/nginx/sbin:/usr/local/nginx/bin @@ -29,11 +29,10 @@ ENV LUA_PATH="/usr/local/share/luajit-2.1.0-beta3/?.lua;/usr/local/share/lua/5.1 ENV LUA_CPATH="/usr/local/lib/lua/?/?.so;/usr/local/lib/lua/?.so;;" COPY --from=builder /usr/local /usr/local +COPY --from=builder /usr/lib/libopentelemetry* /usr/local/lib COPY --from=builder /opt /opt COPY --from=builder /etc/nginx /etc/nginx -LABEL org.opencontainers.image.source=https://github.com/kubernetes/ingress-nginx - RUN apk update \ && apk upgrade \ && apk add -U --no-cache \ @@ -50,6 +49,10 @@ RUN apk update \ yaml-cpp \ dumb-init \ tzdata \ + grpc-cpp \ + libprotobuf \ + abseil-cpp-crc-cpu-detect \ + abseil-cpp-vlog-config-internal \ && ln -s /usr/local/nginx/sbin/nginx /sbin/nginx \ && adduser -S -D -H -u 101 -h /usr/local/nginx \ -s /sbin/nologin -G www-data -g www-data www-data \ @@ -65,7 +68,7 @@ RUN apk update \ ); \ for dir in "${writeDirs[@]}"; do \ mkdir -p ${dir}; \ - chown -R www-data.www-data ${dir}; \ + chown -R www-data:www-data ${dir}; \ done' EXPOSE 80 443 diff --git a/images/nginx/rootfs/build.sh b/images/nginx/rootfs/build.sh index 2f5f3c66f..297abf777 100755 --- a/images/nginx/rootfs/build.sh +++ b/images/nginx/rootfs/build.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2015 The Kubernetes Authors. +# Copyright 2023 The Kubernetes Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,139 +18,119 @@ set -o errexit set -o nounset set -o pipefail -export NGINX_VERSION=1.21.6 +export NGINX_VERSION=1.27.1 -# Check for recent changes: https://github.com/vision5/ngx_devel_kit/compare/v0.3.2...master -export NDK_VERSION=0.3.2 +# Check for recent changes: https://github.com/vision5/ngx_devel_kit/compare/v0.3.3...master +export NDK_VERSION=v0.3.3 # Check for recent changes: https://github.com/openresty/set-misc-nginx-module/compare/v0.33...master -export SETMISC_VERSION=0.33 +export SETMISC_VERSION=v0.33 # Check for recent changes: https://github.com/openresty/headers-more-nginx-module/compare/v0.37...master -export MORE_HEADERS_VERSION=0.37 +export MORE_HEADERS_VERSION=v0.37 -# Check for recent changes: https://github.com/atomx/nginx-http-auth-digest/compare/v1.0.0...atomx:master -export NGINX_DIGEST_AUTH=1.0.0 - -# Check for recent changes: https://github.com/yaoweibin/ngx_http_substitutions_filter_module/compare/v0.6.4...master -export NGINX_SUBSTITUTIONS=b8a71eacc7f986ba091282ab8b1bbbc6ae1807e0 - -# Check for recent changes: https://github.com/opentracing-contrib/nginx-opentracing/compare/v0.19.0...master -export NGINX_OPENTRACING_VERSION=0.19.0 - -#Check for recent changes: https://github.com/opentracing/opentracing-cpp/compare/v1.6.0...master -export OPENTRACING_CPP_VERSION=f86b33f3d9e7322b1298ba62d5ffa7a9519c4c41 - -# Check for recent changes: https://github.com/rnburn/zipkin-cpp-opentracing/compare/v0.5.2...master -export ZIPKIN_CPP_VERSION=f69593138ff84ca2f6bc115992e18ca3d35f344a - -# Check for recent changes: https://github.com/jbeder/yaml-cpp/compare/yaml-cpp-0.7.0...master -export YAML_CPP_VERSION=yaml-cpp-0.7.0 - -# Check for recent changes: https://github.com/jaegertracing/jaeger-client-cpp/compare/v0.7.0...master -export JAEGER_VERSION=0.7.0 - -# Check for recent changes: https://github.com/msgpack/msgpack-c/compare/cpp-3.3.0...master -export MSGPACK_VERSION=3.3.0 - -# Check for recent changes: https://github.com/DataDog/dd-opentracing-cpp/compare/v1.3.7...master -export DATADOG_CPP_VERSION=1.3.7 +# Check for recent changes: https://github.com/atomx/nginx-http-auth-digest/compare/v1.0.0...master +export NGINX_DIGEST_AUTH=v1.0.0 # Check for recent changes: https://github.com/SpiderLabs/ModSecurity-nginx/compare/v1.0.3...master -export MODSECURITY_VERSION=1.0.3 +export MODSECURITY_VERSION=v1.0.3 -# Check for recent changes: https://github.com/SpiderLabs/ModSecurity/compare/v3.0.11...v3/master -export MODSECURITY_LIB_VERSION=bbde9381cbccb49ea73f6194b08b478adc53f3bc +# Check for recent changes: https://github.com/SpiderLabs/ModSecurity/compare/v3.0.13...v3/master +export MODSECURITY_LIB_VERSION=v3.0.13 -# Check for recent changes: https://github.com/coreruleset/coreruleset/compare/v3.3.2...v3.3/master -export OWASP_MODSECURITY_CRS_VERSION=v3.3.5 +# Check for recent changes: https://github.com/coreruleset/coreruleset/compare/v4.10.0...main +export OWASP_MODSECURITY_CRS_VERSION=v4.10.0 -# Check for recent changes: https://github.com/openresty/lua-nginx-module/compare/v0.10.25...master -export LUA_NGX_VERSION=0.10.25 +# Check for recent changes: https://github.com/openresty/lua-nginx-module/compare/v0.10.27...master +export LUA_NGX_VERSION=v0.10.27 -# Check for recent changes: https://github.com/openresty/stream-lua-nginx-module/compare/v0.0.13...master -export LUA_STREAM_NGX_VERSION=0.0.13 +# Check for recent changes: https://github.com/openresty/stream-lua-nginx-module/compare/v0.0.15...master +export LUA_STREAM_NGX_VERSION=v0.0.15 -# Check for recent changes: https://github.com/openresty/lua-upstream-nginx-module/compare/8aa93ead98ba2060d4efd594ae33a35d153589bf...master -export LUA_UPSTREAM_VERSION=8aa93ead98ba2060d4efd594ae33a35d153589bf +# Check for recent changes: https://github.com/openresty/lua-upstream-nginx-module/compare/v0.07...master +export LUA_UPSTREAM_VERSION=v0.07 -# Check for recent changes: https://github.com/openresty/lua-cjson/compare/2.1.0.11...openresty:master -export LUA_CJSON_VERSION=2.1.0.11 +# Check for recent changes: https://github.com/openresty/lua-cjson/compare/2.1.0.14...master +export LUA_CJSON_VERSION=2.1.0.14 -# Check for recent changes: https://github.com/leev/ngx_http_geoip2_module/compare/3.4...master -export GEOIP2_VERSION=a607a41a8115fecfc05b5c283c81532a3d605425 +# Check for recent changes: https://github.com/leev/ngx_http_geoip2_module/compare/445df24ef3781e488cee3dfe8a1e111997fc1dfe...master +export GEOIP2_VERSION=445df24ef3781e488cee3dfe8a1e111997fc1dfe -# Check for recent changes: https://github.com/openresty/luajit2/compare/v2.1-20230410...v2.1-agentzh -export LUAJIT_VERSION=2.1-20230410 +# Check for recent changes: https://github.com/openresty/luajit2/compare/v2.1-20240815...v2.1-agentzh +export LUAJIT_VERSION=v2.1-20240815 -# Check for recent changes: https://github.com/openresty/lua-resty-balancer/compare/v0.04...master -export LUA_RESTY_BALANCER=0.04 +# Check for recent changes: https://github.com/openresty/lua-resty-balancer/compare/v0.05...master +export LUA_RESTY_BALANCER=v0.05 -# Check for recent changes: https://github.com/openresty/lua-resty-lrucache/compare/v0.13...master -export LUA_RESTY_CACHE=0.13 +# Check for recent changes: https://github.com/openresty/lua-resty-lrucache/compare/v0.15...master +export LUA_RESTY_CACHE=v0.15 -# Check for recent changes: https://github.com/openresty/lua-resty-core/compare/v0.1.27...master -export LUA_RESTY_CORE=0.1.27 +# Check for recent changes: https://github.com/openresty/lua-resty-core/compare/v0.1.30...master +export LUA_RESTY_CORE=v0.1.30 -# Check for recent changes: https://github.com/utix/lua-resty-cookie/compare/9533f47...master -export LUA_RESTY_COOKIE_VERSION=9533f479371663107b515590fc9daf00d61ebf11 +# Check for recent changes: https://github.com/cloudflare/lua-resty-cookie/compare/f418d77082eaef48331302e84330488fdc810ef4...master +export LUA_RESTY_COOKIE_VERSION=f418d77082eaef48331302e84330488fdc810ef4 -# Check for recent changes: https://github.com/openresty/lua-resty-dns/compare/v0.22...master -export LUA_RESTY_DNS=0.22 +# Check for recent changes: https://github.com/openresty/lua-resty-dns/compare/v0.23...master +export LUA_RESTY_DNS=v0.23 -# Check for recent changes: https://github.com/ledgetech/lua-resty-http/compare/v0.16.1...master -export LUA_RESTY_HTTP=0ce55d6d15da140ecc5966fa848204c6fd9074e8 +# Check for recent changes: https://github.com/ledgetech/lua-resty-http/compare/v0.17.2...master +export LUA_RESTY_HTTP=v0.17.2 # Check for recent changes: https://github.com/openresty/lua-resty-lock/compare/v0.09...master -export LUA_RESTY_LOCK=0.09 +export LUA_RESTY_LOCK=v0.09 # Check for recent changes: https://github.com/openresty/lua-resty-upload/compare/v0.11...master -export LUA_RESTY_UPLOAD_VERSION=0.11 +export LUA_RESTY_UPLOAD_VERSION=v0.11 -# Check for recent changes: https://github.com/openresty/lua-resty-string/compare/v0.15...master -export LUA_RESTY_STRING_VERSION=0.15 +# Check for recent changes: https://github.com/openresty/lua-resty-string/compare/v0.16...master +export LUA_RESTY_STRING_VERSION=v0.16 # Check for recent changes: https://github.com/openresty/lua-resty-memcached/compare/v0.17...master -export LUA_RESTY_MEMCACHED_VERSION=0.17 +export LUA_RESTY_MEMCACHED_VERSION=v0.17 -# Check for recent changes: https://github.com/openresty/lua-resty-redis/compare/v0.30...master -export LUA_RESTY_REDIS_VERSION=0.30 +# Check for recent changes: https://github.com/openresty/lua-resty-redis/compare/v0.31...master +export LUA_RESTY_REDIS_VERSION=v0.31 -# Check for recent changes: https://github.com/api7/lua-resty-ipmatcher/compare/v0.6.1...master -export LUA_RESTY_IPMATCHER_VERSION=0.6.1 +# Check for recent changes: https://github.com/api7/lua-resty-ipmatcher/compare/3e93c53eb8c9884efe939ef070486a0e507cc5be...master +export LUA_RESTY_IPMATCHER_VERSION=3e93c53eb8c9884efe939ef070486a0e507cc5be -# Check for recent changes: https://github.com/ElvinEfendi/lua-resty-global-throttle/compare/v0.2.0...main -export LUA_RESTY_GLOBAL_THROTTLE_VERSION=0.2.0 +# Check for recent changes: https://github.com/microsoft/mimalloc/compare/v2.1.9...master +export MIMALOC_VERSION=v2.1.9 -# Check for recent changes: https://github.com/microsoft/mimalloc/compare/v1.7.6...master -export MIMALOC_VERSION=1.7.6 +# Check for recent changes: https://github.com/open-telemetry/opentelemetry-cpp/compare/v1.18.0...main +export OPENTELEMETRY_CPP_VERSION=v1.18.0 + +# Check for recent changes: https://github.com/open-telemetry/opentelemetry-proto/compare/v1.5.0...main +export OPENTELEMETRY_PROTO_VERSION=v1.5.0 export BUILD_PATH=/tmp/build ARCH=$(uname -m) -if [[ ${ARCH} == "s390x" ]]; then - export LUAJIT_VERSION=9d5750d28478abfdcaefdfdc408f87752a21e431 - export LUA_RESTY_CORE=0.1.17 - export LUA_NGX_VERSION=0.10.15 - export LUA_STREAM_NGX_VERSION=0.0.7 -fi - get_src() { hash="$1" url="$2" + dest="${3-}" + ARGS="" f=$(basename "$url") echo "Downloading $url" curl -sSL "$url" -o "$f" - echo "$hash $f" | sha256sum -c - || exit 10 - tar xzf "$f" + # TODO: Reenable checksum verification but make it smarter + # echo "$hash $f" | sha256sum -c - || exit 10 + if [ ! -z "$dest" ]; then + mkdir ${BUILD_PATH}/${dest} + ARGS="-C ${BUILD_PATH}/${dest} --strip-components=1" + fi + tar xvzf "$f" $ARGS rm -rf "$f" } # install required packages to build +# Dependencies from "ninja" and below are OTEL dependencies apk add \ bash \ gcc \ @@ -187,7 +167,22 @@ apk add \ unzip \ dos2unix \ yaml-cpp \ - coreutils + coreutils \ + ninja \ + gtest-dev \ + git \ + build-base \ + pkgconfig \ + c-ares-dev \ + re2-dev \ + grpc-dev \ + protobuf-dev + +# apk add -X http://dl-cdn.alpinelinux.org/alpine/edge/testing opentelemetry-cpp-dev + +# There is some bug with some platforms and git, so force HTTP/1.1 +git config --global http.version HTTP/1.1 +git config --global http.postBuffer 157286400 mkdir -p /etc/nginx @@ -199,274 +194,131 @@ get_src 66dc7081488811e9f925719e34d1b4504c2801c81dee2920e5452a86b11405ae \ "https://nginx.org/download/nginx-$NGINX_VERSION.tar.gz" get_src aa961eafb8317e0eb8da37eb6e2c9ff42267edd18b56947384e719b85188f58b \ - "https://github.com/vision5/ngx_devel_kit/archive/v$NDK_VERSION.tar.gz" + "https://github.com/vision5/ngx_devel_kit/archive/$NDK_VERSION.tar.gz" "ngx_devel_kit" + +get_src abc123 \ + "https://github.com/open-telemetry/opentelemetry-cpp/archive/$OPENTELEMETRY_CPP_VERSION.tar.gz" "opentelemetry-cpp" + +get_src abc123 \ + "https://github.com/open-telemetry/opentelemetry-proto/archive/$OPENTELEMETRY_PROTO_VERSION.tar.gz" "opentelemetry-proto" get_src cd5e2cc834bcfa30149e7511f2b5a2183baf0b70dc091af717a89a64e44a2985 \ - "https://github.com/openresty/set-misc-nginx-module/archive/v$SETMISC_VERSION.tar.gz" + "https://github.com/openresty/set-misc-nginx-module/archive/$SETMISC_VERSION.tar.gz" "set-misc-nginx-module" -get_src cf6e169d6b350c06d0c730b0eaf4973394026ad40094cddd3b3a5b346577019d \ - "https://github.com/openresty/headers-more-nginx-module/archive/v$MORE_HEADERS_VERSION.tar.gz" +get_src 0c0d2ced2ce895b3f45eb2b230cd90508ab2a773299f153de14a43e44c1209b3 \ + "https://github.com/openresty/headers-more-nginx-module/archive/$MORE_HEADERS_VERSION.tar.gz" "headers-more-nginx-module" get_src f09851e6309560a8ff3e901548405066c83f1f6ff88aa7171e0763bd9514762b \ - "https://github.com/atomx/nginx-http-auth-digest/archive/v$NGINX_DIGEST_AUTH.tar.gz" - -get_src a98b48947359166326d58700ccdc27256d2648218072da138ab6b47de47fbd8f \ - "https://github.com/yaoweibin/ngx_http_substitutions_filter_module/archive/$NGINX_SUBSTITUTIONS.tar.gz" - -get_src 6f97776ebdf019b105a755c7736b70bdbd7e575c7f0d39db5fe127873c7abf17 \ - "https://github.com/opentracing-contrib/nginx-opentracing/archive/v$NGINX_OPENTRACING_VERSION.tar.gz" - -get_src cbe625cba85291712253db5bc3870d60c709acfad9a8af5a302673d3d201e3ea \ - "https://github.com/opentracing/opentracing-cpp/archive/$OPENTRACING_CPP_VERSION.tar.gz" - -get_src 71de3d0658935db7ccea20e006b35e58ddc7e4c18878b9523f2addc2371e9270 \ - "https://github.com/rnburn/zipkin-cpp-opentracing/archive/$ZIPKIN_CPP_VERSION.tar.gz" + "https://github.com/atomx/nginx-http-auth-digest/archive/$NGINX_DIGEST_AUTH.tar.gz" "nginx-http-auth-digest" get_src 32a42256616cc674dca24c8654397390adff15b888b77eb74e0687f023c8751b \ - "https://github.com/SpiderLabs/ModSecurity-nginx/archive/v$MODSECURITY_VERSION.tar.gz" + "https://github.com/SpiderLabs/ModSecurity-nginx/archive/$MODSECURITY_VERSION.tar.gz" "ModSecurity-nginx" -get_src 43e6a9fcb146ad871515f0d0873947e5d497a1c9c60c58cb102a97b47208b7c3 \ - "https://github.com/jbeder/yaml-cpp/archive/$YAML_CPP_VERSION.tar.gz" - -get_src 3a3a03060bf5e3fef52c9a2de02e6035cb557f389453d8f3b0c1d3d570636994 \ - "https://github.com/jaegertracing/jaeger-client-cpp/archive/v$JAEGER_VERSION.tar.gz" - -get_src 754c3ace499a63e45b77ef4bcab4ee602c2c414f58403bce826b76ffc2f77d0b \ - "https://github.com/msgpack/msgpack-c/archive/cpp-$MSGPACK_VERSION.tar.gz" - -if [[ ${ARCH} == "s390x" ]]; then -get_src 7d5f3439c8df56046d0564b5857fd8a30296ab1bd6df0f048aed7afb56a0a4c2 \ - "https://github.com/openresty/lua-nginx-module/archive/v$LUA_NGX_VERSION.tar.gz" -get_src 99c47c75c159795c9faf76bbb9fa58e5a50b75286c86565ffcec8514b1c74bf9 \ - "https://github.com/openresty/stream-lua-nginx-module/archive/v$LUA_STREAM_NGX_VERSION.tar.gz" -else get_src bc764db42830aeaf74755754b900253c233ad57498debe7a441cee2c6f4b07c2 \ - "https://github.com/openresty/lua-nginx-module/archive/v$LUA_NGX_VERSION.tar.gz" + "https://github.com/openresty/lua-nginx-module/archive/$LUA_NGX_VERSION.tar.gz" "lua-nginx-module" get_src 01b715754a8248cc7228e0c8f97f7488ae429d90208de0481394e35d24cef32f \ - "https://github.com/openresty/stream-lua-nginx-module/archive/v$LUA_STREAM_NGX_VERSION.tar.gz" - -fi + "https://github.com/openresty/stream-lua-nginx-module/archive/$LUA_STREAM_NGX_VERSION.tar.gz" "stream-lua-nginx-module" get_src a92c9ee6682567605ece55d4eed5d1d54446ba6fba748cff0a2482aea5713d5f \ - "https://github.com/openresty/lua-upstream-nginx-module/archive/$LUA_UPSTREAM_VERSION.tar.gz" + "https://github.com/openresty/lua-upstream-nginx-module/archive/$LUA_UPSTREAM_VERSION.tar.gz" "lua-upstream-nginx-module" -if [[ ${ARCH} == "s390x" ]]; then -get_src 266ed1abb70a9806d97cb958537a44b67db6afb33d3b32292a2d68a2acedea75 \ - "https://github.com/openresty/luajit2/archive/$LUAJIT_VERSION.tar.gz" -else get_src 77bbcbb24c3c78f51560017288f3118d995fe71240aa379f5818ff6b166712ff \ - "https://github.com/openresty/luajit2/archive/v$LUAJIT_VERSION.tar.gz" -fi - -get_src 8d39c6b23f941a2d11571daaccc04e69539a3fcbcc50a631837560d5861a7b96 \ - "https://github.com/DataDog/dd-opentracing-cpp/archive/v$DATADOG_CPP_VERSION.tar.gz" + "https://github.com/openresty/luajit2/archive/$LUAJIT_VERSION.tar.gz" "luajit2" get_src b6c9c09fd43eb34a71e706ad780b2ead26549a9a9f59280fe558f5b7b980b7c6 \ - "https://github.com/leev/ngx_http_geoip2_module/archive/$GEOIP2_VERSION.tar.gz" + "https://github.com/leev/ngx_http_geoip2_module/archive/$GEOIP2_VERSION.tar.gz" "ngx_http_geoip2_module" get_src deb4ab1ffb9f3d962c4b4a2c4bdff692b86a209e3835ae71ebdf3b97189e40a9 \ - "https://github.com/openresty/lua-resty-upload/archive/v$LUA_RESTY_UPLOAD_VERSION.tar.gz" + "https://github.com/openresty/lua-resty-upload/archive/$LUA_RESTY_UPLOAD_VERSION.tar.gz" "lua-resty-upload" get_src bdbf271003d95aa91cab0a92f24dca129e99b33f79c13ebfcdbbcbb558129491 \ - "https://github.com/openresty/lua-resty-string/archive/v$LUA_RESTY_STRING_VERSION.tar.gz" + "https://github.com/openresty/lua-resty-string/archive/$LUA_RESTY_STRING_VERSION.tar.gz" "lua-resty-string" get_src 16d72ed133f0c6df376a327386c3ef4e9406cf51003a700737c3805770ade7c5 \ - "https://github.com/openresty/lua-resty-balancer/archive/v$LUA_RESTY_BALANCER.tar.gz" + "https://github.com/openresty/lua-resty-balancer/archive/$LUA_RESTY_BALANCER.tar.gz" "lua-resty-balancer" -if [[ ${ARCH} == "s390x" ]]; then -get_src 8f5f76d2689a3f6b0782f0a009c56a65e4c7a4382be86422c9b3549fe95b0dc4 \ - "https://github.com/openresty/lua-resty-core/archive/v$LUA_RESTY_CORE.tar.gz" -else get_src 39baab9e2b31cc48cecf896cea40ef6e80559054fd8a6e440cc804a858ea84d4 \ - "https://github.com/openresty/lua-resty-core/archive/v$LUA_RESTY_CORE.tar.gz" -fi + "https://github.com/openresty/lua-resty-core/archive/$LUA_RESTY_CORE.tar.gz" "lua-resty-core" get_src a77b9de160d81712f2f442e1de8b78a5a7ef0d08f13430ff619f79235db974d4 \ - "https://github.com/openresty/lua-cjson/archive/$LUA_CJSON_VERSION.tar.gz" + "https://github.com/openresty/lua-cjson/archive/$LUA_CJSON_VERSION.tar.gz" "lua-cjson" -get_src a404c790553617424d743b82a9f01feccd0d2930b306b370c665ca3b7c09ccb6 \ - "https://github.com/utix/lua-resty-cookie/archive/$LUA_RESTY_COOKIE_VERSION.tar.gz" +get_src 5ed48c36231e2622b001308622d46a0077525ac2f751e8cc0c9905914254baa4 \ + "https://github.com/cloudflare/lua-resty-cookie/archive/$LUA_RESTY_COOKIE_VERSION.tar.gz" "lua-resty-cookie" get_src 573184006b98ccee2594b0d134fa4d05e5d2afd5141cbad315051ccf7e9b6403 \ - "https://github.com/openresty/lua-resty-lrucache/archive/v$LUA_RESTY_CACHE.tar.gz" + "https://github.com/openresty/lua-resty-lrucache/archive/$LUA_RESTY_CACHE.tar.gz" "lua-resty-lrucache" get_src b4ddcd47db347e9adf5c1e1491a6279a6ae2a3aff3155ef77ea0a65c998a69c1 \ - "https://github.com/openresty/lua-resty-lock/archive/v$LUA_RESTY_LOCK.tar.gz" + "https://github.com/openresty/lua-resty-lock/archive/$LUA_RESTY_LOCK.tar.gz" "lua-resty-lock" get_src 70e9a01eb32ccade0d5116a25bcffde0445b94ad35035ce06b94ccd260ad1bf0 \ - "https://github.com/openresty/lua-resty-dns/archive/v$LUA_RESTY_DNS.tar.gz" + "https://github.com/openresty/lua-resty-dns/archive/$LUA_RESTY_DNS.tar.gz" "lua-resty-dns" get_src 9fcb6db95bc37b6fce77d3b3dc740d593f9d90dce0369b405eb04844d56ac43f \ - "https://github.com/ledgetech/lua-resty-http/archive/$LUA_RESTY_HTTP.tar.gz" + "https://github.com/ledgetech/lua-resty-http/archive/$LUA_RESTY_HTTP.tar.gz" "lua-resty-http" get_src 02733575c4aed15f6cab662378e4b071c0a4a4d07940c4ef19a7319e9be943d4 \ - "https://github.com/openresty/lua-resty-memcached/archive/v$LUA_RESTY_MEMCACHED_VERSION.tar.gz" + "https://github.com/openresty/lua-resty-memcached/archive/$LUA_RESTY_MEMCACHED_VERSION.tar.gz" "lua-resty-memcached" get_src c15aed1a01c88a3a6387d9af67a957dff670357f5fdb4ee182beb44635eef3f1 \ - "https://github.com/openresty/lua-resty-redis/archive/v$LUA_RESTY_REDIS_VERSION.tar.gz" + "https://github.com/openresty/lua-resty-redis/archive/$LUA_RESTY_REDIS_VERSION.tar.gz" "lua-resty-redis" get_src efb767487ea3f6031577b9b224467ddbda2ad51a41c5867a47582d4ad85d609e \ - "https://github.com/api7/lua-resty-ipmatcher/archive/v$LUA_RESTY_IPMATCHER_VERSION.tar.gz" - -get_src 0fb790e394510e73fdba1492e576aaec0b8ee9ef08e3e821ce253a07719cf7ea \ - "https://github.com/ElvinEfendi/lua-resty-global-throttle/archive/v$LUA_RESTY_GLOBAL_THROTTLE_VERSION.tar.gz" + "https://github.com/api7/lua-resty-ipmatcher/archive/$LUA_RESTY_IPMATCHER_VERSION.tar.gz" "lua-resty-ipmatcher" get_src d74f86ada2329016068bc5a243268f1f555edd620b6a7d6ce89295e7d6cf18da \ - "https://github.com/microsoft/mimalloc/archive/refs/tags/v${MIMALOC_VERSION}.tar.gz" + "https://github.com/microsoft/mimalloc/archive/${MIMALOC_VERSION}.tar.gz" "mimalloc" # improve compilation times CORES=$(($(grep -c ^processor /proc/cpuinfo) - 1)) export MAKEFLAGS=-j${CORES} export CTEST_BUILD_FLAGS=${MAKEFLAGS} -export HUNTER_JOBS_NUMBER=${CORES} -export HUNTER_USE_CACHE_SERVERS=true # Install luajit from openresty fork export LUAJIT_LIB=/usr/local/lib export LUA_LIB_DIR="$LUAJIT_LIB/lua" export LUAJIT_INC=/usr/local/include/luajit-2.1 -cd "$BUILD_PATH/luajit2-$LUAJIT_VERSION" +cd "$BUILD_PATH/luajit2" make CCDEBUG=-g make install ln -s /usr/local/bin/luajit /usr/local/bin/lua ln -s "$LUAJIT_INC" /usr/local/include/lua -cd "$BUILD_PATH" +cd "$BUILD_PATH/opentelemetry-cpp" +export CXXFLAGS="-DBENCHMARK_HAS_NO_INLINE_ASSEMBLY" +cmake -B build -G Ninja -Wno-dev \ + -DOTELCPP_PROTO_PATH="${BUILD_PATH}/opentelemetry-proto/" \ + -DCMAKE_INSTALL_PREFIX=/usr \ + -DBUILD_SHARED_LIBS=ON \ + -DBUILD_TESTING="OFF" \ + -DBUILD_W3CTRACECONTEXT_TEST="OFF" \ + -DCMAKE_BUILD_TYPE=None \ + -DWITH_ABSEIL=ON \ + -DWITH_STL=ON \ + -DWITH_EXAMPLES=OFF \ + -DWITH_ZPAGES=OFF \ + -DWITH_OTLP_GRPC=ON \ + -DWITH_OTLP_HTTP=ON \ + -DWITH_ZIPKIN=ON \ + -DWITH_PROMETHEUS=OFF \ + -DWITH_ASYNC_EXPORT_PREVIEW=OFF \ + -DWITH_METRICS_EXEMPLAR_PREVIEW=OFF + cmake --build build + cmake --install build # Git tuning git config --global --add core.compression -1 -# build opentracing lib -cd "$BUILD_PATH/opentracing-cpp-$OPENTRACING_CPP_VERSION" -mkdir .build -cd .build - -cmake -DCMAKE_BUILD_TYPE=Release \ - -DBUILD_TESTING=OFF \ - -DBUILD_SHARED_LIBS=OFF \ - -DBUILD_MOCKTRACER=OFF \ - -DBUILD_STATIC_LIBS=ON \ - -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=true \ - .. - -make -make install - -# build yaml-cpp -# TODO @timmysilv: remove this and jaeger sed calls once it is fixed in jaeger-client-cpp -cd "$BUILD_PATH/yaml-cpp-$YAML_CPP_VERSION" -mkdir .build -cd .build - -cmake -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=true \ - -DYAML_BUILD_SHARED_LIBS=ON \ - -DYAML_CPP_BUILD_TESTS=OFF \ - -DYAML_CPP_BUILD_TOOLS=OFF \ - .. - -make -make install - -# build jaeger lib -cd "$BUILD_PATH/jaeger-client-cpp-$JAEGER_VERSION" -sed -i 's/-Werror/-Wno-psabi/' CMakeLists.txt -# use the above built yaml-cpp instead until a new version of jaeger-client-cpp fixes the yaml-cpp issue -# tl;dr new hunter is needed for new yaml-cpp, but new hunter has a conflict with old Thrift and new Boost -sed -i 's/hunter_add_package(yaml-cpp)/#hunter_add_package(yaml-cpp)/' CMakeLists.txt -sed -i 's/yaml-cpp::yaml-cpp/yaml-cpp/' CMakeLists.txt - -cat < export.map -{ - global: - OpenTracingMakeTracerFactory; - local: *; -}; -EOF - -mkdir .build -cd .build - -cmake -DCMAKE_BUILD_TYPE=Release \ - -DBUILD_TESTING=OFF \ - -DJAEGERTRACING_BUILD_EXAMPLES=OFF \ - -DJAEGERTRACING_BUILD_CROSSDOCK=OFF \ - -DJAEGERTRACING_COVERAGE=OFF \ - -DJAEGERTRACING_PLUGIN=ON \ - -DHUNTER_CONFIGURATION_TYPES=Release \ - -DBUILD_SHARED_LIBS=OFF \ - -DJAEGERTRACING_WITH_YAML_CPP=ON \ - -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=true \ - .. - -make -make install - -export HUNTER_INSTALL_DIR=$(cat _3rdParty/Hunter/install-root-dir) \ - -mv libjaegertracing_plugin.so /usr/local/lib/libjaegertracing_plugin.so - - -# build zipkin lib -cd "$BUILD_PATH/zipkin-cpp-opentracing-$ZIPKIN_CPP_VERSION" - -cat < export.map -{ - global: - OpenTracingMakeTracerFactory; - local: *; -}; -EOF - -mkdir .build -cd .build - -cmake -DCMAKE_BUILD_TYPE=Release \ - -DBUILD_SHARED_LIBS=OFF \ - -DBUILD_PLUGIN=ON \ - -DBUILD_TESTING=OFF \ - -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=true \ - .. - -make -make install - -# build msgpack lib -cd "$BUILD_PATH/msgpack-c-cpp-$MSGPACK_VERSION" - -mkdir .build -cd .build -cmake -DCMAKE_BUILD_TYPE=Release \ - -DBUILD_SHARED_LIBS=OFF \ - -DMSGPACK_BUILD_EXAMPLES=OFF \ - -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=true \ - .. - -make -make install - -# build datadog lib -cd "$BUILD_PATH/dd-opentracing-cpp-$DATADOG_CPP_VERSION" - -mkdir .build -cd .build - -cmake -DCMAKE_BUILD_TYPE=Release \ - -DBUILD_TESTING=OFF \ - -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=true \ - .. - -make -make install - # Get Brotli source and deps cd "$BUILD_PATH" -git clone --depth=1 https://github.com/google/ngx_brotli.git +git clone --depth=100 https://github.com/google/ngx_brotli.git cd ngx_brotli +git reset --hard a71f9312c2deb28875acc7bacfdd5695a111aa53 git submodule init git submodule update @@ -524,17 +376,13 @@ mv rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example rules/REQUEST-900-E mv rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf cd .. -# OWASP CRS v3 rules +# OWASP CRS v4 rules echo " Include /etc/nginx/owasp-modsecurity-crs/crs-setup.conf Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-901-INITIALIZATION.conf -Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-903.9001-DRUPAL-EXCLUSION-RULES.conf -Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-903.9002-WORDPRESS-EXCLUSION-RULES.conf Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-905-COMMON-EXCEPTIONS.conf -Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-910-IP-REPUTATION.conf Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-911-METHOD-ENFORCEMENT.conf -Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-912-DOS-PROTECTION.conf Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-913-SCANNER-DETECTION.conf Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-921-PROTOCOL-ATTACK.conf @@ -543,7 +391,7 @@ Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-930-APPLICATION-ATTACK-LF Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-931-APPLICATION-ATTACK-RFI.conf Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf -Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-934-APPLICATION-ATTACK-NODEJS.conf +Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-934-APPLICATION-ATTACK-GENERIC.conf Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf Include /etc/nginx/owasp-modsecurity-crs/rules/REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION.conf @@ -554,11 +402,27 @@ Include /etc/nginx/owasp-modsecurity-crs/rules/RESPONSE-951-DATA-LEAKAGES-SQL.co Include /etc/nginx/owasp-modsecurity-crs/rules/RESPONSE-952-DATA-LEAKAGES-JAVA.conf Include /etc/nginx/owasp-modsecurity-crs/rules/RESPONSE-953-DATA-LEAKAGES-PHP.conf Include /etc/nginx/owasp-modsecurity-crs/rules/RESPONSE-954-DATA-LEAKAGES-IIS.conf +Include /etc/nginx/owasp-modsecurity-crs/rules/RESPONSE-955-WEB-SHELLS.conf Include /etc/nginx/owasp-modsecurity-crs/rules/RESPONSE-959-BLOCKING-EVALUATION.conf Include /etc/nginx/owasp-modsecurity-crs/rules/RESPONSE-980-CORRELATION.conf Include /etc/nginx/owasp-modsecurity-crs/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf " > /etc/nginx/owasp-modsecurity-crs/nginx-modsecurity.conf +# NGINX compiles a small test program to check if an added module works as expected. +# +# ModSecurity-nginx provides 'printf("hello");' as a test, but newer versions of GCC, +# as included in Alpine 3.21, do not allow implicit declaration of function 'printf': +# +# objs/autotest.c:7:5: error: implicit declaration of function 'printf' [-Wimplicit-function-declaration] +# +# For this reason we replace 'printf("hello");' by 'msc_init();', which is always available. +# +# This fix is taken from a PR, that has been proposed to the ModSecurity-nginx project: +# +# https://github.com/owasp-modsecurity/ModSecurity-nginx/pull/275 +# +sed -i "s/ngx_feature_test='printf(\"hello\");'/ngx_feature_test='msc_init();'/" $BUILD_PATH/ModSecurity-nginx/config + # build nginx cd "$BUILD_PATH/nginx-$NGINX_VERSION" @@ -583,6 +447,7 @@ WITH_FLAGS="--with-debug \ --with-http_gzip_static_module \ --with-http_sub_module \ --with-http_v2_module \ + --with-http_v3_module \ --with-stream \ --with-stream_ssl_module \ --with-stream_realip_module \ @@ -602,10 +467,9 @@ CC_OPT="-g -O2 -fPIE -fstack-protector-strong \ --param=ssp-buffer-size=4 \ -DTCP_FASTOPEN=23 \ -fPIC \ - -I$HUNTER_INSTALL_DIR/include \ -Wno-cast-function-type" -LD_OPT="-fPIE -fPIC -pie -Wl,-z,relro -Wl,-z,now -L$HUNTER_INSTALL_DIR/lib" +LD_OPT="-fPIE -fPIC -pie -Wl,-z,relro -Wl,-z,now" if [[ ${ARCH} != "aarch64" ]]; then WITH_FLAGS+=" --with-file-aio" @@ -616,17 +480,15 @@ if [[ ${ARCH} == "x86_64" ]]; then fi WITH_MODULES=" \ - --add-module=$BUILD_PATH/ngx_devel_kit-$NDK_VERSION \ - --add-module=$BUILD_PATH/set-misc-nginx-module-$SETMISC_VERSION \ - --add-module=$BUILD_PATH/headers-more-nginx-module-$MORE_HEADERS_VERSION \ - --add-module=$BUILD_PATH/ngx_http_substitutions_filter_module-$NGINX_SUBSTITUTIONS \ - --add-module=$BUILD_PATH/lua-nginx-module-$LUA_NGX_VERSION \ - --add-module=$BUILD_PATH/stream-lua-nginx-module-$LUA_STREAM_NGX_VERSION \ - --add-module=$BUILD_PATH/lua-upstream-nginx-module-$LUA_UPSTREAM_VERSION \ - --add-dynamic-module=$BUILD_PATH/nginx-http-auth-digest-$NGINX_DIGEST_AUTH \ - --add-dynamic-module=$BUILD_PATH/nginx-opentracing-$NGINX_OPENTRACING_VERSION/opentracing \ - --add-dynamic-module=$BUILD_PATH/ModSecurity-nginx-$MODSECURITY_VERSION \ - --add-dynamic-module=$BUILD_PATH/ngx_http_geoip2_module-${GEOIP2_VERSION} \ + --add-module=$BUILD_PATH/ngx_devel_kit \ + --add-module=$BUILD_PATH/set-misc-nginx-module \ + --add-module=$BUILD_PATH/headers-more-nginx-module \ + --add-module=$BUILD_PATH/lua-nginx-module \ + --add-module=$BUILD_PATH/stream-lua-nginx-module \ + --add-module=$BUILD_PATH/lua-upstream-nginx-module \ + --add-dynamic-module=$BUILD_PATH/nginx-http-auth-digest \ + --add-dynamic-module=$BUILD_PATH/ModSecurity-nginx \ + --add-dynamic-module=$BUILD_PATH/ngx_http_geoip2_module \ --add-dynamic-module=$BUILD_PATH/ngx_brotli" ./configure \ @@ -658,56 +520,81 @@ make make modules make install -cd "$BUILD_PATH/lua-resty-core-$LUA_RESTY_CORE" +# Check for recent changes: https://github.com/open-telemetry/opentelemetry-cpp-contrib/compare/8933841f0a7f8737f61404cf0a64acf6b079c8a5...main +export OPENTELEMETRY_CONTRIB_COMMIT=8933841f0a7f8737f61404cf0a64acf6b079c8a5 +cd "$BUILD_PATH" + +git clone https://github.com/open-telemetry/opentelemetry-cpp-contrib.git opentelemetry-cpp-contrib-${OPENTELEMETRY_CONTRIB_COMMIT} + +cd ${BUILD_PATH}/opentelemetry-cpp-contrib-${OPENTELEMETRY_CONTRIB_COMMIT} +git reset --hard ${OPENTELEMETRY_CONTRIB_COMMIT} + +export OTEL_TEMP_INSTALL=/tmp/otel +mkdir -p ${OTEL_TEMP_INSTALL} + +cd ${BUILD_PATH}/opentelemetry-cpp-contrib-${OPENTELEMETRY_CONTRIB_COMMIT}/instrumentation/nginx +mkdir -p build +cd build +cmake -DCMAKE_BUILD_TYPE=Release \ + -G Ninja \ + -DCMAKE_CXX_STANDARD=17 \ + -DCMAKE_INSTALL_PREFIX=${OTEL_TEMP_INSTALL} \ + -DBUILD_SHARED_LIBS=ON \ + -DNGINX_VERSION=${NGINX_VERSION} \ + .. +cmake --build . -j ${CORES} --target install + +mkdir -p /etc/nginx/modules +cp ${OTEL_TEMP_INSTALL}/otel_ngx_module.so /etc/nginx/modules/otel_ngx_module.so + + +cd "$BUILD_PATH/lua-resty-core" make install -cd "$BUILD_PATH/lua-resty-balancer-$LUA_RESTY_BALANCER" +cd "$BUILD_PATH/lua-resty-balancer" make all make install export LUA_INCLUDE_DIR=/usr/local/include/luajit-2.1 ln -s $LUA_INCLUDE_DIR /usr/include/lua5.1 -cd "$BUILD_PATH/lua-cjson-$LUA_CJSON_VERSION" +cd "$BUILD_PATH/lua-cjson" make all make install -cd "$BUILD_PATH/lua-resty-cookie-$LUA_RESTY_COOKIE_VERSION" +cd "$BUILD_PATH/lua-resty-cookie" make all make install -cd "$BUILD_PATH/lua-resty-lrucache-$LUA_RESTY_CACHE" +cd "$BUILD_PATH/lua-resty-lrucache" make install -cd "$BUILD_PATH/lua-resty-dns-$LUA_RESTY_DNS" +cd "$BUILD_PATH/lua-resty-dns" make install -cd "$BUILD_PATH/lua-resty-lock-$LUA_RESTY_LOCK" +cd "$BUILD_PATH/lua-resty-lock" make install # required for OCSP verification -cd "$BUILD_PATH/lua-resty-http-$LUA_RESTY_HTTP" +cd "$BUILD_PATH/lua-resty-http" make install -cd "$BUILD_PATH/lua-resty-upload-$LUA_RESTY_UPLOAD_VERSION" +cd "$BUILD_PATH/lua-resty-upload" make install -cd "$BUILD_PATH/lua-resty-string-$LUA_RESTY_STRING_VERSION" +cd "$BUILD_PATH/lua-resty-string" make install -cd "$BUILD_PATH/lua-resty-memcached-$LUA_RESTY_MEMCACHED_VERSION" +cd "$BUILD_PATH/lua-resty-memcached" make install -cd "$BUILD_PATH/lua-resty-redis-$LUA_RESTY_REDIS_VERSION" +cd "$BUILD_PATH/lua-resty-redis" make install -cd "$BUILD_PATH/lua-resty-ipmatcher-$LUA_RESTY_IPMATCHER_VERSION" +cd "$BUILD_PATH/lua-resty-ipmatcher" INST_LUADIR=/usr/local/lib/lua make install -cd "$BUILD_PATH/lua-resty-global-throttle-$LUA_RESTY_GLOBAL_THROTTLE_VERSION" -make install - -cd "$BUILD_PATH/mimalloc-$MIMALOC_VERSION" +cd "$BUILD_PATH/mimalloc" mkdir -p out/release cd out/release @@ -731,7 +618,7 @@ adduser -S -D -H -u 101 -h /usr/local/nginx -s /sbin/nologin -G www-data -g www- for dir in "${writeDirs[@]}"; do mkdir -p ${dir}; - chown -R www-data.www-data ${dir}; + chown -R www-data:www-data ${dir}; done rm -rf /etc/nginx/owasp-modsecurity-crs/.git diff --git a/images/nginx-1.25/rootfs/patches/00_drop-alias-root.patch b/images/nginx/rootfs/patches/00_drop-alias-root.patch similarity index 100% rename from images/nginx-1.25/rootfs/patches/00_drop-alias-root.patch rename to images/nginx/rootfs/patches/00_drop-alias-root.patch diff --git a/images/nginx-1.25/rootfs/patches/01_nginx-1.25.3-win32_max_err_str.patch b/images/nginx/rootfs/patches/01_nginx-1.27.1-win32_max_err_str.patch similarity index 100% rename from images/nginx-1.25/rootfs/patches/01_nginx-1.25.3-win32_max_err_str.patch rename to images/nginx/rootfs/patches/01_nginx-1.27.1-win32_max_err_str.patch diff --git a/images/nginx-1.25/rootfs/patches/02_nginx-1.25.3-stream_balancer_export.patch b/images/nginx/rootfs/patches/02_nginx-1.27.1-stream_balancer_export.patch similarity index 100% rename from images/nginx-1.25/rootfs/patches/02_nginx-1.25.3-stream_balancer_export.patch rename to images/nginx/rootfs/patches/02_nginx-1.27.1-stream_balancer_export.patch diff --git a/images/nginx-1.25/rootfs/patches/03_nginx-1.25.3-stream_proxy_get_next_upstream_tries.patch b/images/nginx/rootfs/patches/03_nginx-1.27.1-stream_proxy_get_next_upstream_tries.patch similarity index 100% rename from images/nginx-1.25/rootfs/patches/03_nginx-1.25.3-stream_proxy_get_next_upstream_tries.patch rename to images/nginx/rootfs/patches/03_nginx-1.27.1-stream_proxy_get_next_upstream_tries.patch diff --git a/images/nginx-1.25/rootfs/patches/04_nginx-1.25.3-stream_proxy_timeout_fields.patch b/images/nginx/rootfs/patches/04_nginx-1.27.1-stream_proxy_timeout_fields.patch similarity index 92% rename from images/nginx-1.25/rootfs/patches/04_nginx-1.25.3-stream_proxy_timeout_fields.patch rename to images/nginx/rootfs/patches/04_nginx-1.27.1-stream_proxy_timeout_fields.patch index 39c59e206..e205abb8b 100644 --- a/images/nginx-1.25/rootfs/patches/04_nginx-1.25.3-stream_proxy_timeout_fields.patch +++ b/images/nginx/rootfs/patches/04_nginx-1.27.1-stream_proxy_timeout_fields.patch @@ -1,6 +1,6 @@ -diff -u -r -p -Naur nginx-1.25.3/src/stream/ngx_stream.h nginx-1.25.3-patched/src/stream/ngx_stream.h ---- nginx-1.25.3/src/stream/ngx_stream.h 2021-11-04 21:27:55.288708527 +0800 -+++ nginx-1.25.3-patched/src/stream/ngx_stream.h 2021-11-04 21:28:50.768035209 +0800 +diff -u -r -p -Naur nginx-1.27.1/src/stream/ngx_stream.h nginx-1.27.1-patched/src/stream/ngx_stream.h +--- nginx-1.27.1/src/stream/ngx_stream.h 2021-11-04 21:27:55.288708527 +0800 ++++ nginx-1.27.1-patched/src/stream/ngx_stream.h 2021-11-04 21:28:50.768035209 +0800 @@ -254,6 +254,15 @@ typedef struct { } ngx_stream_module_t; @@ -25,9 +25,9 @@ diff -u -r -p -Naur nginx-1.25.3/src/stream/ngx_stream.h nginx-1.25.3-patched/sr typedef ngx_int_t (*ngx_stream_filter_pt)(ngx_stream_session_t *s, -diff -u -r -p -Naur nginx-1.25.3/src/stream/ngx_stream_proxy_module.c nginx-1.25.3-patched/src/stream/ngx_stream_proxy_module.c ---- nginx-1.25.3/src/stream/ngx_stream_proxy_module.c 2021-11-04 21:27:55.289708533 +0800 -+++ nginx-1.25.3-patched/src/stream/ngx_stream_proxy_module.c 2021-11-04 21:37:03.578936990 +0800 +diff -u -r -p -Naur nginx-1.27.1/src/stream/ngx_stream_proxy_module.c nginx-1.27.1-patched/src/stream/ngx_stream_proxy_module.c +--- nginx-1.27.1/src/stream/ngx_stream_proxy_module.c 2021-11-04 21:27:55.289708533 +0800 ++++ nginx-1.27.1-patched/src/stream/ngx_stream_proxy_module.c 2021-11-04 21:37:03.578936990 +0800 @@ -400,6 +400,7 @@ ngx_stream_proxy_handler(ngx_stream_sess ngx_stream_proxy_srv_conf_t *pscf; ngx_stream_upstream_srv_conf_t *uscf, **uscfp; diff --git a/images/nginx-1.25/rootfs/patches/05_nginx-1.25.3-stream_ssl_preread_no_skip.patch b/images/nginx/rootfs/patches/05_nginx-1.27.1-stream_ssl_preread_no_skip.patch similarity index 100% rename from images/nginx-1.25/rootfs/patches/05_nginx-1.25.3-stream_ssl_preread_no_skip.patch rename to images/nginx/rootfs/patches/05_nginx-1.27.1-stream_ssl_preread_no_skip.patch diff --git a/images/nginx-1.25/rootfs/patches/06_nginx-1.25.3-resolver_conf_parsing.patch b/images/nginx/rootfs/patches/06_nginx-1.27.1-resolver_conf_parsing.patch similarity index 100% rename from images/nginx-1.25/rootfs/patches/06_nginx-1.25.3-resolver_conf_parsing.patch rename to images/nginx/rootfs/patches/06_nginx-1.27.1-resolver_conf_parsing.patch diff --git a/images/nginx-1.25/rootfs/patches/07_nginx-1.25.3-daemon_destroy_pool.patch b/images/nginx/rootfs/patches/07_nginx-1.27.1-daemon_destroy_pool.patch similarity index 100% rename from images/nginx-1.25/rootfs/patches/07_nginx-1.25.3-daemon_destroy_pool.patch rename to images/nginx/rootfs/patches/07_nginx-1.27.1-daemon_destroy_pool.patch diff --git a/images/nginx-1.25/rootfs/patches/08_nginx-1.25.3-init_cycle_pool_release.patch b/images/nginx/rootfs/patches/08_nginx-1.27.1-init_cycle_pool_release.patch similarity index 65% rename from images/nginx-1.25/rootfs/patches/08_nginx-1.25.3-init_cycle_pool_release.patch rename to images/nginx/rootfs/patches/08_nginx-1.27.1-init_cycle_pool_release.patch index bd2e9a7d9..4a26b92c5 100644 --- a/images/nginx-1.25/rootfs/patches/08_nginx-1.25.3-init_cycle_pool_release.patch +++ b/images/nginx/rootfs/patches/08_nginx-1.27.1-init_cycle_pool_release.patch @@ -1,6 +1,6 @@ -diff -rup nginx-1.25.3/src/core/nginx.c nginx-1.25.3-patched/src/core/nginx.c ---- nginx-1.25.3/src/core/nginx.c 2017-12-17 00:00:38.136470108 -0800 -+++ nginx-1.25.3-patched/src/core/nginx.c 2017-12-16 23:59:51.680958322 -0800 +diff -rup nginx-1.27.1/src/core/nginx.c nginx-1.27.1-patched/src/core/nginx.c +--- nginx-1.27.1/src/core/nginx.c 2017-12-17 00:00:38.136470108 -0800 ++++ nginx-1.27.1-patched/src/core/nginx.c 2017-12-16 23:59:51.680958322 -0800 @@ -186,6 +186,7 @@ static u_char *ngx_prefix; static u_char *ngx_conf_file; static u_char *ngx_conf_params; @@ -18,9 +18,9 @@ diff -rup nginx-1.25.3/src/core/nginx.c nginx-1.25.3-patched/src/core/nginx.c if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK) { return 1; } -diff -rup nginx-1.25.3/src/core/ngx_core.h nginx-1.25.3-patched/src/core/ngx_core.h ---- nginx-1.25.3/src/core/ngx_core.h 2017-10-10 08:22:51.000000000 -0700 -+++ nginx-1.25.3-patched/src/core/ngx_core.h 2017-12-16 23:59:51.679958370 -0800 +diff -rup nginx-1.27.1/src/core/ngx_core.h nginx-1.27.1-patched/src/core/ngx_core.h +--- nginx-1.27.1/src/core/ngx_core.h 2017-10-10 08:22:51.000000000 -0700 ++++ nginx-1.27.1-patched/src/core/ngx_core.h 2017-12-16 23:59:51.679958370 -0800 @@ -108,4 +108,6 @@ void ngx_cpuinfo(void); #define NGX_DISABLE_SYMLINKS_NOTOWNER 2 #endif @@ -28,9 +28,9 @@ diff -rup nginx-1.25.3/src/core/ngx_core.h nginx-1.25.3-patched/src/core/ngx_cor +extern ngx_pool_t *saved_init_cycle_pool; + #endif /* _NGX_CORE_H_INCLUDED_ */ -diff -rup nginx-1.25.3/src/core/ngx_cycle.c nginx-1.25.3-patched/src/core/ngx_cycle.c ---- nginx-1.25.3/src/core/ngx_cycle.c 2017-10-10 08:22:51.000000000 -0700 -+++ nginx-1.25.3-patched/src/core/ngx_cycle.c 2017-12-16 23:59:51.678958419 -0800 +diff -rup nginx-1.27.1/src/core/ngx_cycle.c nginx-1.27.1-patched/src/core/ngx_cycle.c +--- nginx-1.27.1/src/core/ngx_cycle.c 2017-10-10 08:22:51.000000000 -0700 ++++ nginx-1.27.1-patched/src/core/ngx_cycle.c 2017-12-16 23:59:51.678958419 -0800 @@ -748,6 +748,10 @@ old_shm_zone_done: if (ngx_process == NGX_PROCESS_MASTER || ngx_is_init_cycle(old_cycle)) { @@ -42,9 +42,9 @@ diff -rup nginx-1.25.3/src/core/ngx_cycle.c nginx-1.25.3-patched/src/core/ngx_cy ngx_destroy_pool(old_cycle->pool); cycle->old_cycle = NULL; -diff -rup nginx-1.25.3/src/os/unix/ngx_process_cycle.c nginx-1.25.3-patched/src/os/unix/ngx_process_cycle.c ---- nginx-1.25.3/src/os/unix/ngx_process_cycle.c 2017-12-17 00:00:38.142469762 -0800 -+++ nginx-1.25.3-patched/src/os/unix/ngx_process_cycle.c 2017-12-16 23:59:51.691957791 -0800 +diff -rup nginx-1.27.1/src/os/unix/ngx_process_cycle.c nginx-1.27.1-patched/src/os/unix/ngx_process_cycle.c +--- nginx-1.27.1/src/os/unix/ngx_process_cycle.c 2017-12-17 00:00:38.142469762 -0800 ++++ nginx-1.27.1-patched/src/os/unix/ngx_process_cycle.c 2017-12-16 23:59:51.691957791 -0800 @@ -687,6 +692,11 @@ ngx_master_process_exit(ngx_cycle_t *cyc ngx_exit_cycle.files_n = ngx_cycle->files_n; ngx_cycle = &ngx_exit_cycle; diff --git a/images/nginx-1.25/rootfs/patches/09_nginx-1.25.3-balancer_status_code.patch b/images/nginx/rootfs/patches/09_nginx-1.27.1-balancer_status_code.patch similarity index 100% rename from images/nginx-1.25/rootfs/patches/09_nginx-1.25.3-balancer_status_code.patch rename to images/nginx/rootfs/patches/09_nginx-1.27.1-balancer_status_code.patch diff --git a/images/nginx-1.25/rootfs/patches/10_nginx-1.25.3-delayed_posted_events.patch b/images/nginx/rootfs/patches/10_nginx-1.27.1-delayed_posted_events.patch similarity index 100% rename from images/nginx-1.25/rootfs/patches/10_nginx-1.25.3-delayed_posted_events.patch rename to images/nginx/rootfs/patches/10_nginx-1.27.1-delayed_posted_events.patch diff --git a/images/nginx-1.25/rootfs/patches/11_nginx-1.25.3-privileged_agent_process.patch b/images/nginx/rootfs/patches/11_nginx-1.27.1-privileged_agent_process.patch similarity index 100% rename from images/nginx-1.25/rootfs/patches/11_nginx-1.25.3-privileged_agent_process.patch rename to images/nginx/rootfs/patches/11_nginx-1.27.1-privileged_agent_process.patch diff --git a/images/nginx-1.25/rootfs/patches/12_nginx-1.25.3-privileged_agent_process_connections.patch b/images/nginx/rootfs/patches/12_nginx-1.27.1-privileged_agent_process_connections.patch similarity index 100% rename from images/nginx-1.25/rootfs/patches/12_nginx-1.25.3-privileged_agent_process_connections.patch rename to images/nginx/rootfs/patches/12_nginx-1.27.1-privileged_agent_process_connections.patch diff --git a/images/nginx-1.25/rootfs/patches/13_nginx-1.25.3-privileged_agent_process_thread_pool.patch b/images/nginx/rootfs/patches/13_nginx-1.27.1-privileged_agent_process_thread_pool.patch similarity index 100% rename from images/nginx-1.25/rootfs/patches/13_nginx-1.25.3-privileged_agent_process_thread_pool.patch rename to images/nginx/rootfs/patches/13_nginx-1.27.1-privileged_agent_process_thread_pool.patch diff --git a/images/nginx-1.25/rootfs/patches/14_nginx-1.25.3-single_process_graceful_exit.patch b/images/nginx/rootfs/patches/14_nginx-1.27.1-single_process_graceful_exit.patch similarity index 100% rename from images/nginx-1.25/rootfs/patches/14_nginx-1.25.3-single_process_graceful_exit.patch rename to images/nginx/rootfs/patches/14_nginx-1.27.1-single_process_graceful_exit.patch diff --git a/images/nginx-1.25/rootfs/patches/15_nginx-1.25.3-intercept_error_log.patch b/images/nginx/rootfs/patches/15_nginx-1.27.1-intercept_error_log.patch similarity index 100% rename from images/nginx-1.25/rootfs/patches/15_nginx-1.25.3-intercept_error_log.patch rename to images/nginx/rootfs/patches/15_nginx-1.27.1-intercept_error_log.patch diff --git a/images/nginx-1.25/rootfs/patches/16_nginx-1.25.3-upstream_pipelining.patch b/images/nginx/rootfs/patches/16_nginx-1.27.1-upstream_pipelining.patch similarity index 100% rename from images/nginx-1.25/rootfs/patches/16_nginx-1.25.3-upstream_pipelining.patch rename to images/nginx/rootfs/patches/16_nginx-1.27.1-upstream_pipelining.patch diff --git a/images/nginx-1.25/rootfs/patches/17_nginx-1.25.3-no_error_pages.patch b/images/nginx/rootfs/patches/17_nginx-1.27.1-no_error_pages.patch similarity index 93% rename from images/nginx-1.25/rootfs/patches/17_nginx-1.25.3-no_error_pages.patch rename to images/nginx/rootfs/patches/17_nginx-1.27.1-no_error_pages.patch index aceb2e988..593fcefd6 100644 --- a/images/nginx-1.25/rootfs/patches/17_nginx-1.25.3-no_error_pages.patch +++ b/images/nginx/rootfs/patches/17_nginx-1.27.1-no_error_pages.patch @@ -1,6 +1,6 @@ -diff -upr nginx-1.25.3/src/http/ngx_http_core_module.c nginx-1.25.3-patched/src/http/ngx_http_core_module.c ---- nginx-1.25.3/src/http/ngx_http_core_module.c 2017-08-31 18:14:41.000000000 -0700 -+++ nginx-1.25.3-patched/src/http/ngx_http_core_module.c 2017-08-31 18:21:31.638098196 -0700 +diff -upr nginx-1.27.1/src/http/ngx_http_core_module.c nginx-1.27.1-patched/src/http/ngx_http_core_module.c +--- nginx-1.27.1/src/http/ngx_http_core_module.c 2017-08-31 18:14:41.000000000 -0700 ++++ nginx-1.27.1-patched/src/http/ngx_http_core_module.c 2017-08-31 18:21:31.638098196 -0700 @@ -64,6 +64,8 @@ static char *ngx_http_core_directio(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static char *ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, diff --git a/images/nginx/rootfs/patches/18_nginx-1.27.1-no_Werror.patch b/images/nginx/rootfs/patches/18_nginx-1.27.1-no_Werror.patch new file mode 100644 index 000000000..d0aa7a31e --- /dev/null +++ b/images/nginx/rootfs/patches/18_nginx-1.27.1-no_Werror.patch @@ -0,0 +1,36 @@ +diff -urp nginx-1.27.1/auto/cc/clang nginx-1.27.1-patched/auto/cc/clang +--- nginx-1.27.1/auto/cc/clang 2014-03-04 03:39:24.000000000 -0800 ++++ nginx-1.27.1-patched/auto/cc/clang 2014-03-13 20:54:26.241413360 -0700 +@@ -89,7 +89,7 @@ CFLAGS="$CFLAGS -Wconditional-uninitiali + CFLAGS="$CFLAGS -Wno-unused-parameter" + + # stop on warning +-CFLAGS="$CFLAGS -Werror" ++#CFLAGS="$CFLAGS -Werror" + + # debug + CFLAGS="$CFLAGS -g" +diff -urp nginx-1.27.1/auto/cc/gcc nginx-1.27.1-patched/auto/cc/gcc +--- nginx-1.27.1/auto/cc/gcc 2014-03-04 03:39:24.000000000 -0800 ++++ nginx-1.27.1-patched/auto/cc/gcc 2014-03-13 20:54:13.301355329 -0700 +@@ -168,7 +168,7 @@ esac + + + # stop on warning +-CFLAGS="$CFLAGS -Werror" ++#CFLAGS="$CFLAGS -Werror" + + # debug + CFLAGS="$CFLAGS -g" +diff -urp nginx-1.27.1/auto/cc/icc nginx-1.27.1-patched/auto/cc/icc +--- nginx-1.27.1/auto/cc/icc 2014-03-04 03:39:24.000000000 -0800 ++++ nginx-1.27.1-patched/auto/cc/icc 2014-03-13 20:54:13.301355329 -0700 +@@ -115,7 +115,7 @@ case "$NGX_ICC_VER" in + esac + + # stop on warning +-CFLAGS="$CFLAGS -Werror" ++#CFLAGS="$CFLAGS -Werror" + + # debug + CFLAGS="$CFLAGS -g" diff --git a/images/nginx-1.25/rootfs/patches/19_nginx-1.25.3-log_escape_non_ascii.patch b/images/nginx/rootfs/patches/19_nginx-1.27.1-log_escape_non_ascii.patch similarity index 100% rename from images/nginx-1.25/rootfs/patches/19_nginx-1.25.3-log_escape_non_ascii.patch rename to images/nginx/rootfs/patches/19_nginx-1.27.1-log_escape_non_ascii.patch diff --git a/images/nginx-1.25/rootfs/patches/20_nginx-1.25.3-proxy_host_port_vars.patch b/images/nginx/rootfs/patches/20_nginx-1.27.1-proxy_host_port_vars.patch similarity index 87% rename from images/nginx-1.25/rootfs/patches/20_nginx-1.25.3-proxy_host_port_vars.patch rename to images/nginx/rootfs/patches/20_nginx-1.27.1-proxy_host_port_vars.patch index 82a344324..b81a299c8 100644 --- a/images/nginx-1.25/rootfs/patches/20_nginx-1.25.3-proxy_host_port_vars.patch +++ b/images/nginx/rootfs/patches/20_nginx-1.27.1-proxy_host_port_vars.patch @@ -1,5 +1,5 @@ ---- nginx-1.25.3/src/http/modules/ngx_http_proxy_module.c 2017-07-16 14:02:51.000000000 +0800 -+++ nginx-1.25.3-patched/src/http/modules/ngx_http_proxy_module.c 2017-07-16 14:02:51.000000000 +0800 +--- nginx-1.27.1/src/http/modules/ngx_http_proxy_module.c 2017-07-16 14:02:51.000000000 +0800 ++++ nginx-1.27.1-patched/src/http/modules/ngx_http_proxy_module.c 2017-07-16 14:02:51.000000000 +0800 @@ -793,13 +793,13 @@ static ngx_keyval_t ngx_http_proxy_cach static ngx_http_variable_t ngx_http_proxy_vars[] = { diff --git a/images/nginx-1.25/rootfs/patches/21_nginx-1.25.3-cache_manager_exit.patch b/images/nginx/rootfs/patches/21_nginx-1.27.1-cache_manager_exit.patch similarity index 100% rename from images/nginx-1.25/rootfs/patches/21_nginx-1.25.3-cache_manager_exit.patch rename to images/nginx/rootfs/patches/21_nginx-1.27.1-cache_manager_exit.patch diff --git a/images/nginx-1.25/rootfs/patches/22_nginx-1.25.3-larger_max_error_str.patch b/images/nginx/rootfs/patches/22_nginx-1.27.1-larger_max_error_str.patch similarity index 62% rename from images/nginx-1.25/rootfs/patches/22_nginx-1.25.3-larger_max_error_str.patch rename to images/nginx/rootfs/patches/22_nginx-1.27.1-larger_max_error_str.patch index e5cd07e67..b821297e6 100644 --- a/images/nginx-1.25/rootfs/patches/22_nginx-1.25.3-larger_max_error_str.patch +++ b/images/nginx/rootfs/patches/22_nginx-1.27.1-larger_max_error_str.patch @@ -1,5 +1,5 @@ ---- nginx-1.25.3/src/core/ngx_log.h 2013-10-08 05:07:14.000000000 -0700 -+++ nginx-1.25.3-patched/src/core/ngx_log.h 2013-12-05 20:35:35.996236720 -0800 +--- nginx-1.27.1/src/core/ngx_log.h 2013-10-08 05:07:14.000000000 -0700 ++++ nginx-1.27.1-patched/src/core/ngx_log.h 2013-12-05 20:35:35.996236720 -0800 @@ -64,7 +64,9 @@ struct ngx_log_s { }; diff --git a/images/nginx-1.25/rootfs/patches/23_nginx-1.25.3-pcre_conf_opt.patch b/images/nginx/rootfs/patches/23_nginx-1.27.1-pcre_conf_opt.patch similarity index 100% rename from images/nginx-1.25/rootfs/patches/23_nginx-1.25.3-pcre_conf_opt.patch rename to images/nginx/rootfs/patches/23_nginx-1.27.1-pcre_conf_opt.patch diff --git a/images/nginx-1.25/rootfs/patches/24_nginx-1.25.3-always_enable_cc_feature_tests.patch b/images/nginx/rootfs/patches/24_nginx-1.27.1-always_enable_cc_feature_tests.patch similarity index 65% rename from images/nginx-1.25/rootfs/patches/24_nginx-1.25.3-always_enable_cc_feature_tests.patch rename to images/nginx/rootfs/patches/24_nginx-1.27.1-always_enable_cc_feature_tests.patch index b381d9b07..9517e92c4 100644 --- a/images/nginx-1.25/rootfs/patches/24_nginx-1.25.3-always_enable_cc_feature_tests.patch +++ b/images/nginx/rootfs/patches/24_nginx-1.27.1-always_enable_cc_feature_tests.patch @@ -1,5 +1,5 @@ ---- nginx-1.25.3/auto/cc/conf 2015-10-30 22:47:50.000000000 +0800 -+++ nginx-1.25.3-patched/auto/cc/conf 2015-11-02 12:23:05.385156987 +0800 +--- nginx-1.27.1/auto/cc/conf 2015-10-30 22:47:50.000000000 +0800 ++++ nginx-1.27.1-patched/auto/cc/conf 2015-11-02 12:23:05.385156987 +0800 @@ -144,7 +144,7 @@ fi CFLAGS="$CFLAGS $NGX_CC_OPT" NGX_TEST_LD_OPT="$NGX_LD_OPT" diff --git a/images/nginx-1.25/rootfs/patches/25_nginx-1.25.3-ssl_cert_cb_yield.patch b/images/nginx/rootfs/patches/25_nginx-1.27.1-ssl_cert_cb_yield.patch similarity index 100% rename from images/nginx-1.25/rootfs/patches/25_nginx-1.25.3-ssl_cert_cb_yield.patch rename to images/nginx/rootfs/patches/25_nginx-1.27.1-ssl_cert_cb_yield.patch diff --git a/images/nginx-1.25/rootfs/patches/26_nginx-1.25.3-ssl_sess_cb_yield.patch b/images/nginx/rootfs/patches/26_nginx-1.27.1-ssl_sess_cb_yield.patch similarity index 100% rename from images/nginx-1.25/rootfs/patches/26_nginx-1.25.3-ssl_sess_cb_yield.patch rename to images/nginx/rootfs/patches/26_nginx-1.27.1-ssl_sess_cb_yield.patch diff --git a/images/nginx-1.25/rootfs/patches/27_nginx-1.25.3-ssl_client_hello_cb_yield.patch b/images/nginx/rootfs/patches/27_nginx-1.27.1-ssl_client_hello_cb_yield.patch similarity index 100% rename from images/nginx-1.25/rootfs/patches/27_nginx-1.25.3-ssl_client_hello_cb_yield.patch rename to images/nginx/rootfs/patches/27_nginx-1.27.1-ssl_client_hello_cb_yield.patch diff --git a/images/nginx-1.25/rootfs/patches/28_nginx-1.25.3-upstream_timeout_fields.patch b/images/nginx/rootfs/patches/28_nginx-1.27.1-upstream_timeout_fields.patch similarity index 100% rename from images/nginx-1.25/rootfs/patches/28_nginx-1.25.3-upstream_timeout_fields.patch rename to images/nginx/rootfs/patches/28_nginx-1.27.1-upstream_timeout_fields.patch diff --git a/images/nginx-1.25/rootfs/patches/29_nginx-1.25.3-safe_resolver_ipv6_option.patch b/images/nginx/rootfs/patches/29_nginx-1.27.1-safe_resolver_ipv6_option.patch similarity index 100% rename from images/nginx-1.25/rootfs/patches/29_nginx-1.25.3-safe_resolver_ipv6_option.patch rename to images/nginx/rootfs/patches/29_nginx-1.27.1-safe_resolver_ipv6_option.patch diff --git a/images/nginx-1.25/rootfs/patches/30_nginx-1.25.3-socket_cloexec.patch b/images/nginx/rootfs/patches/30_nginx-1.27.1-socket_cloexec.patch similarity index 100% rename from images/nginx-1.25/rootfs/patches/30_nginx-1.25.3-socket_cloexec.patch rename to images/nginx/rootfs/patches/30_nginx-1.27.1-socket_cloexec.patch diff --git a/images/nginx-1.25/rootfs/patches/31_nginx-1.25.3-reuseport_close_unused_fds.patch b/images/nginx/rootfs/patches/31_nginx-1.27.1-reuseport_close_unused_fds.patch similarity index 100% rename from images/nginx-1.25/rootfs/patches/31_nginx-1.25.3-reuseport_close_unused_fds.patch rename to images/nginx/rootfs/patches/31_nginx-1.27.1-reuseport_close_unused_fds.patch diff --git a/images/nginx/rootfs/patches/32_nginx-1.27.1-proc_exit_handler.patch b/images/nginx/rootfs/patches/32_nginx-1.27.1-proc_exit_handler.patch new file mode 100644 index 000000000..f050c09d8 --- /dev/null +++ b/images/nginx/rootfs/patches/32_nginx-1.27.1-proc_exit_handler.patch @@ -0,0 +1,77 @@ +diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c +index c4e3c50..fa1408b 100644 +--- a/src/core/ngx_cycle.c ++++ b/src/core/ngx_cycle.c +@@ -264,6 +264,9 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) + } + + ++#if !(NGX_WIN32) ++ ngx_proc_exit_top_handler = ngx_proc_exit_def_handler; ++#endif + conf.ctx = cycle->conf_ctx; + conf.cycle = cycle; + conf.pool = pool; +diff --git a/src/os/unix/ngx_process.c b/src/os/unix/ngx_process.c +index 12a8c68..874c9bf 100644 +--- a/src/os/unix/ngx_process.c ++++ b/src/os/unix/ngx_process.c +@@ -34,6 +34,7 @@ ngx_int_t ngx_process_slot; + ngx_socket_t ngx_channel; + ngx_int_t ngx_last_process; + ngx_process_t ngx_processes[NGX_MAX_PROCESSES]; ++ngx_proc_exit_pt ngx_proc_exit_top_handler; + + + ngx_signal_t signals[] = { +@@ -83,6 +84,13 @@ ngx_signal_t signals[] = { + }; + + ++void ++ngx_proc_exit_def_handler(ngx_pid_t pid) ++{ ++ /* do nothing */ ++} ++ ++ + ngx_pid_t + ngx_spawn_process(ngx_cycle_t *cycle, ngx_spawn_proc_pt proc, void *data, + char *name, ngx_int_t respawn) +@@ -564,6 +572,7 @@ ngx_process_get_status(void) + } + + ngx_unlock_mutexes(pid); ++ ngx_proc_exit_top_handler(pid); + } + } + +diff --git a/src/os/unix/ngx_process.h b/src/os/unix/ngx_process.h +index 3986639..0b55d98 100644 +--- a/src/os/unix/ngx_process.h ++++ b/src/os/unix/ngx_process.h +@@ -18,6 +18,8 @@ typedef pid_t ngx_pid_t; + #define NGX_INVALID_PID -1 + + typedef void (*ngx_spawn_proc_pt) (ngx_cycle_t *cycle, void *data); ++#define NGX_HAVE_PROC_EXIT 1 ++typedef void (*ngx_proc_exit_pt)(ngx_pid_t pid); + + typedef struct { + ngx_pid_t pid; +@@ -66,6 +68,7 @@ ngx_pid_t ngx_spawn_process(ngx_cycle_t *cycle, + ngx_pid_t ngx_execute(ngx_cycle_t *cycle, ngx_exec_ctx_t *ctx); + ngx_int_t ngx_init_signals(ngx_log_t *log); + void ngx_debug_point(void); ++void ngx_proc_exit_def_handler(ngx_pid_t pid); + + + #if (NGX_HAVE_SCHED_YIELD) +@@ -85,6 +88,7 @@ extern ngx_socket_t ngx_channel; + extern ngx_int_t ngx_process_slot; + extern ngx_int_t ngx_last_process; + extern ngx_process_t ngx_processes[NGX_MAX_PROCESSES]; ++extern ngx_proc_exit_pt ngx_proc_exit_top_handler; + + + #endif /* _NGX_PROCESS_H_INCLUDED_ */ diff --git a/images/nginx/rootfs/patches/drop-alias-root.patch b/images/nginx/rootfs/patches/drop-alias-root.patch deleted file mode 100644 index a92e08bd0..000000000 --- a/images/nginx/rootfs/patches/drop-alias-root.patch +++ /dev/null @@ -1,144 +0,0 @@ -:100644 100644 c7463dcd 00000000 M src/http/ngx_http_core_module.c -diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c -index c7463dcd..e2e45931 100644 ---- a/src/http/ngx_http_core_module.c -+++ b/src/http/ngx_http_core_module.c -@@ -55,7 +55,6 @@ static char *ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); - static char *ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); --static char *ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); - static char *ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); - static char *ngx_http_core_set_aio(ngx_conf_t *cf, ngx_command_t *cmd, -@@ -323,21 +322,6 @@ static ngx_command_t ngx_http_core_commands[] = { - offsetof(ngx_http_core_loc_conf_t, default_type), - NULL }, - -- { ngx_string("root"), -- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF -- |NGX_CONF_TAKE1, -- ngx_http_core_root, -- NGX_HTTP_LOC_CONF_OFFSET, -- 0, -- NULL }, -- -- { ngx_string("alias"), -- NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, -- ngx_http_core_root, -- NGX_HTTP_LOC_CONF_OFFSET, -- 0, -- NULL }, -- - { ngx_string("limit_except"), - NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_1MORE, - ngx_http_core_limit_except, -@@ -4312,108 +4296,6 @@ ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) - } - - --static char * --ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) --{ -- ngx_http_core_loc_conf_t *clcf = conf; -- -- ngx_str_t *value; -- ngx_int_t alias; -- ngx_uint_t n; -- ngx_http_script_compile_t sc; -- -- alias = (cmd->name.len == sizeof("alias") - 1) ? 1 : 0; -- -- if (clcf->root.data) { -- -- if ((clcf->alias != 0) == alias) { -- return "is duplicate"; -- } -- -- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, -- "\"%V\" directive is duplicate, " -- "\"%s\" directive was specified earlier", -- &cmd->name, clcf->alias ? "alias" : "root"); -- -- return NGX_CONF_ERROR; -- } -- -- if (clcf->named && alias) { -- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, -- "the \"alias\" directive cannot be used " -- "inside the named location"); -- -- return NGX_CONF_ERROR; -- } -- -- value = cf->args->elts; -- -- if (ngx_strstr(value[1].data, "$document_root") -- || ngx_strstr(value[1].data, "${document_root}")) -- { -- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, -- "the $document_root variable cannot be used " -- "in the \"%V\" directive", -- &cmd->name); -- -- return NGX_CONF_ERROR; -- } -- -- if (ngx_strstr(value[1].data, "$realpath_root") -- || ngx_strstr(value[1].data, "${realpath_root}")) -- { -- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, -- "the $realpath_root variable cannot be used " -- "in the \"%V\" directive", -- &cmd->name); -- -- return NGX_CONF_ERROR; -- } -- -- clcf->alias = alias ? clcf->name.len : 0; -- clcf->root = value[1]; -- -- if (!alias && clcf->root.len > 0 -- && clcf->root.data[clcf->root.len - 1] == '/') -- { -- clcf->root.len--; -- } -- -- if (clcf->root.data[0] != '$') { -- if (ngx_conf_full_name(cf->cycle, &clcf->root, 0) != NGX_OK) { -- return NGX_CONF_ERROR; -- } -- } -- -- n = ngx_http_script_variables_count(&clcf->root); -- -- ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); -- sc.variables = n; -- --#if (NGX_PCRE) -- if (alias && clcf->regex) { -- clcf->alias = NGX_MAX_SIZE_T_VALUE; -- n = 1; -- } --#endif -- -- if (n) { -- sc.cf = cf; -- sc.source = &clcf->root; -- sc.lengths = &clcf->root_lengths; -- sc.values = &clcf->root_values; -- sc.complete_lengths = 1; -- sc.complete_values = 1; -- -- if (ngx_http_script_compile(&sc) != NGX_OK) { -- return NGX_CONF_ERROR; -- } -- } -- -- return NGX_CONF_OK; --} -- -- - static ngx_http_method_name_t ngx_methods_names[] = { - { (u_char *) "GET", (uint32_t) ~NGX_HTTP_GET }, - { (u_char *) "HEAD", (uint32_t) ~NGX_HTTP_HEAD }, diff --git a/images/nginx/rootfs/patches/nginx-1.21.4-balancer_status_code.patch b/images/nginx/rootfs/patches/nginx-1.21.4-balancer_status_code.patch deleted file mode 100644 index c4d87e2fb..000000000 --- a/images/nginx/rootfs/patches/nginx-1.21.4-balancer_status_code.patch +++ /dev/null @@ -1,72 +0,0 @@ -diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c -index f8d5707d..6efe0047 100644 ---- a/src/http/ngx_http_upstream.c -+++ b/src/http/ngx_http_upstream.c -@@ -1515,6 +1515,11 @@ ngx_http_upstream_connect(ngx_http_request_t *r, ngx_http_upstream_t *u) - return; - } - -+ if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { -+ ngx_http_upstream_finalize_request(r, u, rc); -+ return; -+ } -+ - u->state->peer = u->peer.name; - - if (rc == NGX_BUSY) { -diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h -index 3e714e5b..dfbb25e0 100644 ---- a/src/http/ngx_http_upstream.h -+++ b/src/http/ngx_http_upstream.h -@@ -427,4 +427,9 @@ extern ngx_conf_bitmask_t ngx_http_upstream_cache_method_mask[]; - extern ngx_conf_bitmask_t ngx_http_upstream_ignore_headers_masks[]; - - -+#ifndef HAVE_BALANCER_STATUS_CODE_PATCH -+#define HAVE_BALANCER_STATUS_CODE_PATCH -+#endif -+ -+ - #endif /* _NGX_HTTP_UPSTREAM_H_INCLUDED_ */ -diff --git a/src/stream/ngx_stream.h b/src/stream/ngx_stream.h -index 09d24593..d8b4b584 100644 ---- a/src/stream/ngx_stream.h -+++ b/src/stream/ngx_stream.h -@@ -27,6 +27,7 @@ typedef struct ngx_stream_session_s ngx_stream_session_t; - - - #define NGX_STREAM_OK 200 -+#define NGX_STREAM_SPECIAL_RESPONSE 300 - #define NGX_STREAM_BAD_REQUEST 400 - #define NGX_STREAM_FORBIDDEN 403 - #define NGX_STREAM_INTERNAL_SERVER_ERROR 500 -diff --git a/src/stream/ngx_stream_proxy_module.c b/src/stream/ngx_stream_proxy_module.c -index 818d7329..329dcdc6 100644 ---- a/src/stream/ngx_stream_proxy_module.c -+++ b/src/stream/ngx_stream_proxy_module.c -@@ -691,6 +691,11 @@ ngx_stream_proxy_connect(ngx_stream_session_t *s) - return; - } - -+ if (rc >= NGX_STREAM_SPECIAL_RESPONSE) { -+ ngx_stream_proxy_finalize(s, rc); -+ return; -+ } -+ - u->state->peer = u->peer.name; - - if (rc == NGX_BUSY) { -diff --git a/src/stream/ngx_stream_upstream.h b/src/stream/ngx_stream_upstream.h -index 73947f46..21bc0ad7 100644 ---- a/src/stream/ngx_stream_upstream.h -+++ b/src/stream/ngx_stream_upstream.h -@@ -151,4 +151,9 @@ ngx_stream_upstream_srv_conf_t *ngx_stream_upstream_add(ngx_conf_t *cf, - extern ngx_module_t ngx_stream_upstream_module; - - -+#ifndef HAVE_BALANCER_STATUS_CODE_PATCH -+#define HAVE_BALANCER_STATUS_CODE_PATCH -+#endif -+ -+ - #endif /* _NGX_STREAM_UPSTREAM_H_INCLUDED_ */ diff --git a/images/nginx/rootfs/patches/nginx-1.21.4-cache_manager_exit.patch b/images/nginx/rootfs/patches/nginx-1.21.4-cache_manager_exit.patch deleted file mode 100644 index 91ee63a26..000000000 --- a/images/nginx/rootfs/patches/nginx-1.21.4-cache_manager_exit.patch +++ /dev/null @@ -1,19 +0,0 @@ -# HG changeset patch -# User Yichun Zhang -# Date 1383598130 28800 -# Node ID f64218e1ac963337d84092536f588b8e0d99bbaa -# Parent dea321e5c0216efccbb23e84bbce7cf3e28f130c -Cache: gracefully exit the cache manager process. - -diff -r dea321e5c021 -r f64218e1ac96 src/os/unix/ngx_process_cycle.c ---- a/src/os/unix/ngx_process_cycle.c Thu Oct 31 18:23:49 2013 +0400 -+++ b/src/os/unix/ngx_process_cycle.c Mon Nov 04 12:48:50 2013 -0800 -@@ -1134,7 +1134,7 @@ - - if (ngx_terminate || ngx_quit) { - ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting"); -- exit(0); -+ ngx_worker_process_exit(cycle); - } - - if (ngx_reopen) { diff --git a/images/nginx/rootfs/patches/nginx-1.21.4-delayed_posted_events.patch b/images/nginx/rootfs/patches/nginx-1.21.4-delayed_posted_events.patch deleted file mode 100644 index 687584324..000000000 --- a/images/nginx/rootfs/patches/nginx-1.21.4-delayed_posted_events.patch +++ /dev/null @@ -1,98 +0,0 @@ -diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c -index 57af8132..4853945f 100644 ---- a/src/event/ngx_event.c -+++ b/src/event/ngx_event.c -@@ -196,6 +196,9 @@ ngx_process_events_and_timers(ngx_cycle_t *cycle) - ngx_uint_t flags; - ngx_msec_t timer, delta; - -+ ngx_queue_t *q; -+ ngx_event_t *ev; -+ - if (ngx_timer_resolution) { - timer = NGX_TIMER_INFINITE; - flags = 0; -@@ -215,6 +218,13 @@ ngx_process_events_and_timers(ngx_cycle_t *cycle) - #endif - } - -+ if (!ngx_queue_empty(&ngx_posted_delayed_events)) { -+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, -+ "posted delayed event queue not empty" -+ " making poll timeout 0"); -+ timer = 0; -+ } -+ - if (ngx_use_accept_mutex) { - if (ngx_accept_disabled > 0) { - ngx_accept_disabled--; -@@ -257,6 +267,35 @@ ngx_process_events_and_timers(ngx_cycle_t *cycle) - } - - ngx_event_process_posted(cycle, &ngx_posted_events); -+ -+ while (!ngx_queue_empty(&ngx_posted_delayed_events)) { -+ q = ngx_queue_head(&ngx_posted_delayed_events); -+ -+ ev = ngx_queue_data(q, ngx_event_t, queue); -+ if (ev->delayed) { -+ /* start of newly inserted nodes */ -+ for (/* void */; -+ q != ngx_queue_sentinel(&ngx_posted_delayed_events); -+ q = ngx_queue_next(q)) -+ { -+ ev = ngx_queue_data(q, ngx_event_t, queue); -+ ev->delayed = 0; -+ -+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, -+ "skipping delayed posted event %p," -+ " till next iteration", ev); -+ } -+ -+ break; -+ } -+ -+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, -+ "delayed posted event %p", ev); -+ -+ ngx_delete_posted_event(ev); -+ -+ ev->handler(ev); -+ } - } - - -@@ -600,6 +639,7 @@ ngx_event_process_init(ngx_cycle_t *cycle) - - ngx_queue_init(&ngx_posted_accept_events); - ngx_queue_init(&ngx_posted_events); -+ ngx_queue_init(&ngx_posted_delayed_events); - - if (ngx_event_timer_init(cycle->log) == NGX_ERROR) { - return NGX_ERROR; -diff --git a/src/event/ngx_event_posted.c b/src/event/ngx_event_posted.c -index d851f3d1..b6cea009 100644 ---- a/src/event/ngx_event_posted.c -+++ b/src/event/ngx_event_posted.c -@@ -12,6 +12,7 @@ - - ngx_queue_t ngx_posted_accept_events; - ngx_queue_t ngx_posted_events; -+ngx_queue_t ngx_posted_delayed_events; - - - void -diff --git a/src/event/ngx_event_posted.h b/src/event/ngx_event_posted.h -index 145d30fe..6c388553 100644 ---- a/src/event/ngx_event_posted.h -+++ b/src/event/ngx_event_posted.h -@@ -43,6 +43,9 @@ void ngx_event_process_posted(ngx_cycle_t *cycle, ngx_queue_t *posted); - - extern ngx_queue_t ngx_posted_accept_events; - extern ngx_queue_t ngx_posted_events; -+extern ngx_queue_t ngx_posted_delayed_events; -+ -+#define HAVE_POSTED_DELAYED_EVENTS_PATCH - - - #endif /* _NGX_EVENT_POSTED_H_INCLUDED_ */ diff --git a/images/nginx/rootfs/patches/nginx-1.21.4-hash_overflow.patch b/images/nginx/rootfs/patches/nginx-1.21.4-hash_overflow.patch deleted file mode 100644 index 449d214ba..000000000 --- a/images/nginx/rootfs/patches/nginx-1.21.4-hash_overflow.patch +++ /dev/null @@ -1,20 +0,0 @@ -# HG changeset patch -# User Yichun Zhang -# Date 1412276417 25200 -# Thu Oct 02 12:00:17 2014 -0700 -# Node ID 4032b992f23b054c1a2cfb0be879330d2c6708e5 -# Parent 1ff0f68d9376e3d184d65814a6372856bf65cfcd -Hash: buffer overflow might happen when exceeding the pre-configured limits. - -diff -r 1ff0f68d9376 -r 4032b992f23b src/core/ngx_hash.c ---- a/src/core/ngx_hash.c Tue Sep 30 15:50:28 2014 -0700 -+++ b/src/core/ngx_hash.c Thu Oct 02 12:00:17 2014 -0700 -@@ -312,6 +312,8 @@ ngx_hash_init(ngx_hash_init_t *hinit, ng - continue; - } - -+ size--; -+ - ngx_log_error(NGX_LOG_WARN, hinit->pool->log, 0, - "could not build optimal %s, you should increase " - "either %s_max_size: %i or %s_bucket_size: %i; " diff --git a/images/nginx/rootfs/patches/nginx-1.21.4-http2.patch b/images/nginx/rootfs/patches/nginx-1.21.4-http2.patch deleted file mode 100644 index 3b9d57736..000000000 --- a/images/nginx/rootfs/patches/nginx-1.21.4-http2.patch +++ /dev/null @@ -1,57 +0,0 @@ -#commit 6ceef192e7af1c507826ac38a2d43f08bf265fb9 -#repository: https://github.com/nginx/nginx -#Author: Maxim Dounin -#Date: Tue Oct 10 15:13:39 2023 +0300 -diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c -index 7c05ff1e7..410a8be24 100644 ---- a/src/http/v2/ngx_http_v2.c -+++ b/src/http/v2/ngx_http_v2.c -@@ -347,6 +347,7 @@ ngx_http_v2_read_handler(ngx_event_t *rev) - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http2 read handler"); - - h2c->blocked = 1; -+ h2c->new_streams = 0; - - if (c->close) { - c->close = 0; -@@ -1284,6 +1285,14 @@ ngx_http_v2_state_headers(ngx_http_v2_connection_t *h2c, u_char *pos, - goto rst_stream; - } - -+ if (h2c->new_streams++ >= 2 * h2scf->concurrent_streams) { -+ ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0, -+ "client sent too many streams at once"); -+ -+ status = NGX_HTTP_V2_REFUSED_STREAM; -+ goto rst_stream; -+ } -+ - if (!h2c->settings_ack - && !(h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG) - && h2scf->preread_size < NGX_HTTP_V2_DEFAULT_WINDOW) -@@ -1349,6 +1358,12 @@ ngx_http_v2_state_headers(ngx_http_v2_connection_t *h2c, u_char *pos, - - rst_stream: - -+ if (h2c->refused_streams++ > ngx_max(h2scf->concurrent_streams, 100)) { -+ ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0, -+ "client sent too many refused streams"); -+ return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_NO_ERROR); -+ } -+ - if (ngx_http_v2_send_rst_stream(h2c, h2c->state.sid, status) != NGX_OK) { - return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR); - } -diff --git a/src/http/v2/ngx_http_v2.h b/src/http/v2/ngx_http_v2.h -index cb9014ccf..6751b3026 100644 ---- a/src/http/v2/ngx_http_v2.h -+++ b/src/http/v2/ngx_http_v2.h -@@ -131,6 +131,8 @@ struct ngx_http_v2_connection_s { - ngx_uint_t processing; - ngx_uint_t frames; - ngx_uint_t idle; -+ ngx_uint_t new_streams; -+ ngx_uint_t refused_streams; - ngx_uint_t priority_limit; - - size_t send_window; \ No newline at end of file diff --git a/images/nginx/rootfs/patches/nginx-1.21.4-init_cycle_pool_release.patch b/images/nginx/rootfs/patches/nginx-1.21.4-init_cycle_pool_release.patch deleted file mode 100644 index 9cfa4f7cb..000000000 --- a/images/nginx/rootfs/patches/nginx-1.21.4-init_cycle_pool_release.patch +++ /dev/null @@ -1,59 +0,0 @@ -diff -rup nginx-1.21.4/src/core/nginx.c nginx-1.21.4-patched/src/core/nginx.c ---- nginx-1.21.4/src/core/nginx.c 2017-12-17 00:00:38.136470108 -0800 -+++ nginx-1.21.4-patched/src/core/nginx.c 2017-12-16 23:59:51.680958322 -0800 -@@ -186,6 +186,7 @@ static u_char *ngx_prefix; - static u_char *ngx_conf_file; - static u_char *ngx_conf_params; - static char *ngx_signal; -+ngx_pool_t *saved_init_cycle_pool = NULL; - - - static char **ngx_os_environ; -@@ -253,6 +254,8 @@ main(int argc, char *const *argv) - return 1; - } - -+ saved_init_cycle_pool = init_cycle.pool; -+ - if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK) { - return 1; - } -diff -rup nginx-1.21.4/src/core/ngx_core.h nginx-1.21.4-patched/src/core/ngx_core.h ---- nginx-1.21.4/src/core/ngx_core.h 2017-10-10 08:22:51.000000000 -0700 -+++ nginx-1.21.4-patched/src/core/ngx_core.h 2017-12-16 23:59:51.679958370 -0800 -@@ -108,4 +108,6 @@ void ngx_cpuinfo(void); - #define NGX_DISABLE_SYMLINKS_NOTOWNER 2 - #endif - -+extern ngx_pool_t *saved_init_cycle_pool; -+ - #endif /* _NGX_CORE_H_INCLUDED_ */ -diff -rup nginx-1.21.4/src/core/ngx_cycle.c nginx-1.21.4-patched/src/core/ngx_cycle.c ---- nginx-1.21.4/src/core/ngx_cycle.c 2017-10-10 08:22:51.000000000 -0700 -+++ nginx-1.21.4-patched/src/core/ngx_cycle.c 2017-12-16 23:59:51.678958419 -0800 -@@ -748,6 +748,10 @@ old_shm_zone_done: - - if (ngx_process == NGX_PROCESS_MASTER || ngx_is_init_cycle(old_cycle)) { - -+ if (ngx_is_init_cycle(old_cycle)) { -+ saved_init_cycle_pool = NULL; -+ } -+ - ngx_destroy_pool(old_cycle->pool); - cycle->old_cycle = NULL; - -diff -rup nginx-1.21.4/src/os/unix/ngx_process_cycle.c nginx-1.21.4-patched/src/os/unix/ngx_process_cycle.c ---- nginx-1.21.4/src/os/unix/ngx_process_cycle.c 2017-12-17 00:00:38.142469762 -0800 -+++ nginx-1.21.4-patched/src/os/unix/ngx_process_cycle.c 2017-12-16 23:59:51.691957791 -0800 -@@ -687,6 +692,11 @@ ngx_master_process_exit(ngx_cycle_t *cyc - ngx_exit_cycle.files_n = ngx_cycle->files_n; - ngx_cycle = &ngx_exit_cycle; - -+ if (saved_init_cycle_pool != NULL && saved_init_cycle_pool != cycle->pool) { -+ ngx_destroy_pool(saved_init_cycle_pool); -+ saved_init_cycle_pool = NULL; -+ } -+ - ngx_destroy_pool(cycle->pool); - - exit(0); diff --git a/images/nginx/rootfs/patches/nginx-1.21.4-larger_max_error_str.patch b/images/nginx/rootfs/patches/nginx-1.21.4-larger_max_error_str.patch deleted file mode 100644 index c89032c9f..000000000 --- a/images/nginx/rootfs/patches/nginx-1.21.4-larger_max_error_str.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- nginx-1.21.4/src/core/ngx_log.h 2013-10-08 05:07:14.000000000 -0700 -+++ nginx-1.21.4-patched/src/core/ngx_log.h 2013-12-05 20:35:35.996236720 -0800 -@@ -64,7 +64,9 @@ struct ngx_log_s { - }; - - --#define NGX_MAX_ERROR_STR 2048 -+#ifndef NGX_MAX_ERROR_STR -+#define NGX_MAX_ERROR_STR 4096 -+#endif - - - /*********************************/ diff --git a/images/nginx/rootfs/patches/nginx-1.21.4-no_Werror.patch b/images/nginx/rootfs/patches/nginx-1.21.4-no_Werror.patch deleted file mode 100644 index f4d6fd0e5..000000000 --- a/images/nginx/rootfs/patches/nginx-1.21.4-no_Werror.patch +++ /dev/null @@ -1,36 +0,0 @@ -diff -urp nginx-1.21.4/auto/cc/clang nginx-1.21.4-patched/auto/cc/clang ---- nginx-1.21.4/auto/cc/clang 2014-03-04 03:39:24.000000000 -0800 -+++ nginx-1.21.4-patched/auto/cc/clang 2014-03-13 20:54:26.241413360 -0700 -@@ -89,7 +89,7 @@ CFLAGS="$CFLAGS -Wconditional-uninitiali - CFLAGS="$CFLAGS -Wno-unused-parameter" - - # stop on warning --CFLAGS="$CFLAGS -Werror" -+#CFLAGS="$CFLAGS -Werror" - - # debug - CFLAGS="$CFLAGS -g" -diff -urp nginx-1.21.4/auto/cc/gcc nginx-1.21.4-patched/auto/cc/gcc ---- nginx-1.21.4/auto/cc/gcc 2014-03-04 03:39:24.000000000 -0800 -+++ nginx-1.21.4-patched/auto/cc/gcc 2014-03-13 20:54:13.301355329 -0700 -@@ -168,7 +168,7 @@ esac - - - # stop on warning --CFLAGS="$CFLAGS -Werror" -+#CFLAGS="$CFLAGS -Werror" - - # debug - CFLAGS="$CFLAGS -g" -diff -urp nginx-1.21.4/auto/cc/icc nginx-1.21.4-patched/auto/cc/icc ---- nginx-1.21.4/auto/cc/icc 2014-03-04 03:39:24.000000000 -0800 -+++ nginx-1.21.4-patched/auto/cc/icc 2014-03-13 20:54:13.301355329 -0700 -@@ -115,7 +115,7 @@ case "$NGX_ICC_VER" in - esac - - # stop on warning --CFLAGS="$CFLAGS -Werror" -+#CFLAGS="$CFLAGS -Werror" - - # debug - CFLAGS="$CFLAGS -g" diff --git a/images/nginx/rootfs/patches/nginx-1.21.4-proxy_host_port_vars.patch b/images/nginx/rootfs/patches/nginx-1.21.4-proxy_host_port_vars.patch deleted file mode 100644 index 01cebd65a..000000000 --- a/images/nginx/rootfs/patches/nginx-1.21.4-proxy_host_port_vars.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- nginx-1.21.4/src/http/modules/ngx_http_proxy_module.c 2017-07-16 14:02:51.000000000 +0800 -+++ nginx-1.21.4-patched/src/http/modules/ngx_http_proxy_module.c 2017-07-16 14:02:51.000000000 +0800 -@@ -793,13 +793,13 @@ static ngx_keyval_t ngx_http_proxy_cach - static ngx_http_variable_t ngx_http_proxy_vars[] = { - - { ngx_string("proxy_host"), NULL, ngx_http_proxy_host_variable, 0, -- NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 }, -+ NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 }, - - { ngx_string("proxy_port"), NULL, ngx_http_proxy_port_variable, 0, -- NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 }, -+ NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 }, - - { ngx_string("proxy_add_x_forwarded_for"), NULL, -- ngx_http_proxy_add_x_forwarded_for_variable, 0, NGX_HTTP_VAR_NOHASH, 0 }, -+ ngx_http_proxy_add_x_forwarded_for_variable, 0, 0, 0 }, - - #if 0 - { ngx_string("proxy_add_via"), NULL, NULL, 0, NGX_HTTP_VAR_NOHASH, 0 }, diff --git a/images/nginx/rootfs/patches/nginx-1.21.4-resolver_conf_parsing.patch b/images/nginx/rootfs/patches/nginx-1.21.4-resolver_conf_parsing.patch deleted file mode 100644 index 8638cdf2a..000000000 --- a/images/nginx/rootfs/patches/nginx-1.21.4-resolver_conf_parsing.patch +++ /dev/null @@ -1,263 +0,0 @@ -diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c -index cd55520c..dade1846 100644 ---- a/src/core/ngx_resolver.c -+++ b/src/core/ngx_resolver.c -@@ -9,12 +9,26 @@ - #include - #include - -+#if !(NGX_WIN32) -+#include -+#endif -+ - - #define NGX_RESOLVER_UDP_SIZE 4096 - - #define NGX_RESOLVER_TCP_RSIZE (2 + 65535) - #define NGX_RESOLVER_TCP_WSIZE 8192 - -+#if !(NGX_WIN32) -+/* -+ * note that 2KB should be more than enough for majority of the -+ * resolv.conf files out there. it also acts as a safety guard to prevent -+ * abuse. -+ */ -+#define NGX_RESOLVER_FILE_BUF_SIZE 2048 -+#define NGX_RESOLVER_FILE_NAME "/etc/resolv.conf" -+#endif -+ - - typedef struct { - u_char ident_hi; -@@ -131,6 +145,191 @@ static ngx_resolver_node_t *ngx_resolver_lookup_addr6(ngx_resolver_t *r, - #endif - - -+#if !(NGX_WIN32) -+static ngx_int_t -+ngx_resolver_read_resolv_conf(ngx_conf_t *cf, ngx_resolver_t *r, u_char *path, -+ size_t path_len) -+{ -+ ngx_url_t u; -+ ngx_resolver_connection_t *rec; -+ ngx_fd_t fd; -+ ngx_file_t file; -+ u_char buf[NGX_RESOLVER_FILE_BUF_SIZE]; -+ u_char ipv6_buf[NGX_INET6_ADDRSTRLEN]; -+ ngx_uint_t address = 0, j, total = 0; -+ ssize_t n, i; -+ enum { -+ sw_nameserver, -+ sw_spaces, -+ sw_address, -+ sw_skip -+ } state; -+ -+ file.name.data = path; -+ file.name.len = path_len; -+ -+ if (ngx_conf_full_name(cf->cycle, &file.name, 1) != NGX_OK) { -+ return NGX_ERROR; -+ } -+ -+ fd = ngx_open_file(file.name.data, NGX_FILE_RDONLY, -+ NGX_FILE_OPEN, 0); -+ -+ if (fd == NGX_INVALID_FILE) { -+ ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno, -+ ngx_open_file_n " \"%s\" failed", file.name.data); -+ -+ return NGX_ERROR; -+ } -+ -+ ngx_memzero(&file, sizeof(ngx_file_t)); -+ -+ file.fd = fd; -+ file.log = cf->log; -+ -+ state = sw_nameserver; -+ -+ n = ngx_read_file(&file, buf, NGX_RESOLVER_FILE_BUF_SIZE, 0); -+ -+ if (n == NGX_ERROR) { -+ ngx_conf_log_error(NGX_LOG_ALERT, cf, ngx_errno, -+ ngx_read_file_n " \"%s\" failed", file.name.data); -+ } -+ -+ if (ngx_close_file(file.fd) == NGX_FILE_ERROR) { -+ ngx_conf_log_error(NGX_LOG_ALERT, cf, ngx_errno, -+ ngx_close_file_n " \"%s\" failed", file.name.data); -+ } -+ -+ if (n == NGX_ERROR) { -+ return NGX_ERROR; -+ } -+ -+ if (n == 0) { -+ return NGX_OK; -+ } -+ -+ for (i = 0; i < n && total < MAXNS; /* void */) { -+ if (buf[i] == '#' || buf[i] == ';') { -+ state = sw_skip; -+ } -+ -+ switch (state) { -+ -+ case sw_nameserver: -+ -+ if ((size_t) n - i >= sizeof("nameserver") - 1 -+ && ngx_memcmp(buf + i, "nameserver", -+ sizeof("nameserver") - 1) == 0) -+ { -+ state = sw_spaces; -+ i += sizeof("nameserver") - 1; -+ -+ continue; -+ } -+ -+ break; -+ -+ case sw_spaces: -+ if (buf[i] != '\t' && buf[i] != ' ') { -+ address = i; -+ state = sw_address; -+ } -+ -+ break; -+ -+ case sw_address: -+ -+ if (buf[i] == CR || buf[i] == LF || i == n - 1) { -+ ngx_memzero(&u, sizeof(ngx_url_t)); -+ -+ u.url.data = buf + address; -+ -+ if (i == n - 1 && buf[i] != CR && buf[i] != LF) { -+ u.url.len = n - address; -+ -+ } else { -+ u.url.len = i - address; -+ } -+ -+ u.default_port = 53; -+ -+ /* IPv6? */ -+ if (ngx_strlchr(u.url.data, u.url.data + u.url.len, -+ ':') != NULL) -+ { -+ if (u.url.len + 2 > sizeof(ipv6_buf)) { -+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, -+ "IPv6 resolver address is too long:" -+ " \"%V\"", &u.url); -+ -+ return NGX_ERROR; -+ } -+ -+ ipv6_buf[0] = '['; -+ ngx_memcpy(ipv6_buf + 1, u.url.data, u.url.len); -+ ipv6_buf[u.url.len + 1] = ']'; -+ -+ u.url.data = ipv6_buf; -+ u.url.len = u.url.len + 2; -+ } -+ -+ if (ngx_parse_url(cf->pool, &u) != NGX_OK) { -+ if (u.err) { -+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, -+ "%s in resolver \"%V\"", -+ u.err, &u.url); -+ } -+ -+ return NGX_ERROR; -+ } -+ -+ rec = ngx_array_push_n(&r->connections, u.naddrs); -+ if (rec == NULL) { -+ return NGX_ERROR; -+ } -+ -+ ngx_memzero(rec, u.naddrs * sizeof(ngx_resolver_connection_t)); -+ -+ for (j = 0; j < u.naddrs; j++) { -+ rec[j].sockaddr = u.addrs[j].sockaddr; -+ rec[j].socklen = u.addrs[j].socklen; -+ rec[j].server = u.addrs[j].name; -+ rec[j].resolver = r; -+ } -+ -+ total++; -+ -+#if (NGX_DEBUG) -+ /* -+ * logs with level below NGX_LOG_NOTICE will not be printed -+ * in this early phase -+ */ -+ ngx_conf_log_error(NGX_LOG_NOTICE, cf, 0, -+ "parsed a resolver: \"%V\"", &u.url); -+#endif -+ -+ state = sw_nameserver; -+ } -+ -+ break; -+ -+ case sw_skip: -+ if (buf[i] == CR || buf[i] == LF) { -+ state = sw_nameserver; -+ } -+ -+ break; -+ } -+ -+ i++; -+ } -+ -+ return NGX_OK; -+} -+#endif -+ -+ - ngx_resolver_t * - ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n) - { -@@ -246,6 +445,39 @@ ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n) - } - #endif - -+#if !(NGX_WIN32) -+ if (ngx_strncmp(names[i].data, "local=", 6) == 0) { -+ -+ if (ngx_strcmp(&names[i].data[6], "on") == 0) { -+ if (ngx_resolver_read_resolv_conf(cf, r, -+ (u_char *) -+ NGX_RESOLVER_FILE_NAME, -+ sizeof(NGX_RESOLVER_FILE_NAME) -+ - 1) -+ != NGX_OK) -+ { -+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, -+ "unable to parse local resolver"); -+ return NULL; -+ } -+ -+ } else if (ngx_strcmp(&names[i].data[6], "off") != 0) { -+ if (ngx_resolver_read_resolv_conf(cf, r, -+ &names[i].data[6], -+ names[i].len - 6) -+ != NGX_OK) -+ { -+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, -+ "unable to parse local resolver"); -+ return NULL; -+ } -+ -+ } -+ -+ continue; -+ } -+#endif -+ - ngx_memzero(&u, sizeof(ngx_url_t)); - - u.url = names[i]; diff --git a/images/nginx/rootfs/patches/nginx-1.21.4-reuseport_close_unused_fds.patch b/images/nginx/rootfs/patches/nginx-1.21.4-reuseport_close_unused_fds.patch deleted file mode 100644 index ff4a36fd2..000000000 --- a/images/nginx/rootfs/patches/nginx-1.21.4-reuseport_close_unused_fds.patch +++ /dev/null @@ -1,38 +0,0 @@ -diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c ---- a/src/core/ngx_connection.c -+++ b/src/core/ngx_connection.c -@@ -1118,6 +1118,12 @@ ngx_close_listening_sockets(ngx_cycle_t *cycle) - ls = cycle->listening.elts; - for (i = 0; i < cycle->listening.nelts; i++) { - -+#if (NGX_HAVE_REUSEPORT) -+ if (ls[i].fd == (ngx_socket_t) -1) { -+ continue; -+ } -+#endif -+ - c = ls[i].connection; - - if (c) { -diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c ---- a/src/event/ngx_event.c -+++ b/src/event/ngx_event.c -@@ -775,6 +775,18 @@ ngx_event_process_init(ngx_cycle_t *cycle) - - #if (NGX_HAVE_REUSEPORT) - if (ls[i].reuseport && ls[i].worker != ngx_worker) { -+ ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0, -+ "closing unused fd:%d listening on %V", -+ ls[i].fd, &ls[i].addr_text); -+ -+ if (ngx_close_socket(ls[i].fd) == -1) { -+ ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno, -+ ngx_close_socket_n " %V failed", -+ &ls[i].addr_text); -+ } -+ -+ ls[i].fd = (ngx_socket_t) -1; -+ - continue; - } - #endif diff --git a/images/nginx/rootfs/patches/nginx-1.21.4-single_process_graceful_exit.patch b/images/nginx/rootfs/patches/nginx-1.21.4-single_process_graceful_exit.patch deleted file mode 100644 index 2754fc2fe..000000000 --- a/images/nginx/rootfs/patches/nginx-1.21.4-single_process_graceful_exit.patch +++ /dev/null @@ -1,75 +0,0 @@ -diff --git a/src/os/unix/ngx_process.c b/src/os/unix/ngx_process.c -index 15680237..12a8c687 100644 ---- a/src/os/unix/ngx_process.c -+++ b/src/os/unix/ngx_process.c -@@ -362,8 +362,15 @@ ngx_signal_handler(int signo, siginfo_t *siginfo, void *ucontext) - break; - - case ngx_signal_value(NGX_RECONFIGURE_SIGNAL): -- ngx_reconfigure = 1; -- action = ", reconfiguring"; -+ if (ngx_process == NGX_PROCESS_SINGLE) { -+ ngx_terminate = 1; -+ action = ", exiting"; -+ -+ } else { -+ ngx_reconfigure = 1; -+ action = ", reconfiguring"; -+ } -+ - break; - - case ngx_signal_value(NGX_REOPEN_SIGNAL): -diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c -index 5817a2c2..f3d58e97 100644 ---- a/src/os/unix/ngx_process_cycle.c -+++ b/src/os/unix/ngx_process_cycle.c -@@ -305,11 +305,26 @@ ngx_single_process_cycle(ngx_cycle_t *cycle) - } - - for ( ;; ) { -+ if (ngx_exiting) { -+ if (ngx_event_no_timers_left() == NGX_OK) { -+ ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting"); -+ -+ for (i = 0; cycle->modules[i]; i++) { -+ if (cycle->modules[i]->exit_process) { -+ cycle->modules[i]->exit_process(cycle); -+ } -+ } -+ -+ ngx_master_process_exit(cycle); -+ } -+ } -+ - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle"); - - ngx_process_events_and_timers(cycle); - -- if (ngx_terminate || ngx_quit) { -+ if (ngx_terminate) { -+ ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting"); - - for (i = 0; cycle->modules[i]; i++) { - if (cycle->modules[i]->exit_process) { -@@ -320,6 +335,20 @@ ngx_single_process_cycle(ngx_cycle_t *cycle) - ngx_master_process_exit(cycle); - } - -+ if (ngx_quit) { -+ ngx_quit = 0; -+ ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, -+ "gracefully shutting down"); -+ ngx_setproctitle("process is shutting down"); -+ -+ if (!ngx_exiting) { -+ ngx_exiting = 1; -+ ngx_set_shutdown_timer(cycle); -+ ngx_close_listening_sockets(cycle); -+ ngx_close_idle_connections(cycle); -+ } -+ } -+ - if (ngx_reconfigure) { - ngx_reconfigure = 0; - ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reconfiguring"); diff --git a/images/nginx/rootfs/patches/nginx-1.21.4-socket_cloexec.patch b/images/nginx/rootfs/patches/nginx-1.21.4-socket_cloexec.patch deleted file mode 100644 index 8ffe4c167..000000000 --- a/images/nginx/rootfs/patches/nginx-1.21.4-socket_cloexec.patch +++ /dev/null @@ -1,185 +0,0 @@ -diff --git a/auto/unix b/auto/unix -index 10835f6c..b5b33bb3 100644 ---- a/auto/unix -+++ b/auto/unix -@@ -990,3 +990,27 @@ ngx_feature_test='struct addrinfo *res; - if (getaddrinfo("localhost", NULL, NULL, &res) != 0) return 1; - freeaddrinfo(res)' - . auto/feature -+ -+ngx_feature="SOCK_CLOEXEC support" -+ngx_feature_name="NGX_HAVE_SOCKET_CLOEXEC" -+ngx_feature_run=no -+ngx_feature_incs="#include -+ #include " -+ngx_feature_path= -+ngx_feature_libs= -+ngx_feature_test="int fd; -+ fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);" -+. auto/feature -+ -+ngx_feature="FD_CLOEXEC support" -+ngx_feature_name="NGX_HAVE_FD_CLOEXEC" -+ngx_feature_run=no -+ngx_feature_incs="#include -+ #include -+ #include " -+ngx_feature_path= -+ngx_feature_libs= -+ngx_feature_test="int fd; -+ fd = socket(AF_INET, SOCK_STREAM, 0); -+ fcntl(fd, F_SETFD, FD_CLOEXEC);" -+. auto/feature -diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c -index cd55520c..438e0806 100644 ---- a/src/core/ngx_resolver.c -+++ b/src/core/ngx_resolver.c -@@ -4466,8 +4466,14 @@ ngx_tcp_connect(ngx_resolver_connection_t *rec) - ngx_event_t *rev, *wev; - ngx_connection_t *c; - -+#if (NGX_HAVE_SOCKET_CLOEXEC) -+ s = ngx_socket(rec->sockaddr->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0); -+ -+#else - s = ngx_socket(rec->sockaddr->sa_family, SOCK_STREAM, 0); - -+#endif -+ - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, &rec->log, 0, "TCP socket %d", s); - - if (s == (ngx_socket_t) -1) { -@@ -4494,6 +4500,15 @@ ngx_tcp_connect(ngx_resolver_connection_t *rec) - goto failed; - } - -+#if (NGX_HAVE_FD_CLOEXEC) -+ if (ngx_cloexec(s) == -1) { -+ ngx_log_error(NGX_LOG_ALERT, &rec->log, ngx_socket_errno, -+ ngx_cloexec_n " failed"); -+ -+ goto failed; -+ } -+#endif -+ - rev = c->read; - wev = c->write; - -diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h -index 19fec68..8c2f01a 100644 ---- a/src/event/ngx_event.h -+++ b/src/event/ngx_event.h -@@ -73,6 +73,9 @@ struct ngx_event_s { - /* to test on worker exit */ - unsigned channel:1; - unsigned resolver:1; -+#if (HAVE_SOCKET_CLOEXEC_PATCH) -+ unsigned skip_socket_leak_check:1; -+#endif - - unsigned cancelable:1; - -diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c -index 77563709..5827b9d0 100644 ---- a/src/event/ngx_event_accept.c -+++ b/src/event/ngx_event_accept.c -@@ -62,7 +62,9 @@ ngx_event_accept(ngx_event_t *ev) - - #if (NGX_HAVE_ACCEPT4) - if (use_accept4) { -- s = accept4(lc->fd, &sa.sockaddr, &socklen, SOCK_NONBLOCK); -+ s = accept4(lc->fd, &sa.sockaddr, &socklen, -+ SOCK_NONBLOCK | SOCK_CLOEXEC); -+ - } else { - s = accept(lc->fd, &sa.sockaddr, &socklen); - } -@@ -202,6 +204,16 @@ ngx_event_accept(ngx_event_t *ev) - ngx_close_accepted_connection(c); - return; - } -+ -+#if (NGX_HAVE_FD_CLOEXEC) -+ if (ngx_cloexec(s) == -1) { -+ ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, -+ ngx_cloexec_n " failed"); -+ ngx_close_accepted_connection(c); -+ return; -+ } -+#endif -+ - } - } - -diff --git a/src/event/ngx_event_connect.c b/src/event/ngx_event_connect.c -index c5bb8068..cf33b1d2 100644 ---- a/src/event/ngx_event_connect.c -+++ b/src/event/ngx_event_connect.c -@@ -38,8 +38,15 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc) - - type = (pc->type ? pc->type : SOCK_STREAM); - -+#if (NGX_HAVE_SOCKET_CLOEXEC) -+ s = ngx_socket(pc->sockaddr->sa_family, type | SOCK_CLOEXEC, 0); -+ -+#else - s = ngx_socket(pc->sockaddr->sa_family, type, 0); - -+#endif -+ -+ - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, pc->log, 0, "%s socket %d", - (type == SOCK_STREAM) ? "stream" : "dgram", s); - -@@ -80,6 +87,15 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc) - goto failed; - } - -+#if (NGX_HAVE_FD_CLOEXEC) -+ if (ngx_cloexec(s) == -1) { -+ ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, -+ ngx_cloexec_n " failed"); -+ -+ goto failed; -+ } -+#endif -+ - if (pc->local) { - - #if (NGX_HAVE_TRANSPARENT_PROXY) -diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c -index c4376a5..48e8fa8 100644 ---- a/src/os/unix/ngx_process_cycle.c -+++ b/src/os/unix/ngx_process_cycle.c -@@ -960,6 +1029,9 @@ ngx_worker_process_exit(ngx_cycle_t *cycle) - for (i = 0; i < cycle->connection_n; i++) { - if (c[i].fd != -1 - && c[i].read -+#if (HAVE_SOCKET_CLOEXEC_PATCH) -+ && !c[i].read->skip_socket_leak_check -+#endif - && !c[i].read->accept - && !c[i].read->channel - && !c[i].read->resolver) -diff --git a/src/os/unix/ngx_socket.h b/src/os/unix/ngx_socket.h -index fcc51533..d1eebf47 100644 ---- a/src/os/unix/ngx_socket.h -+++ b/src/os/unix/ngx_socket.h -@@ -38,6 +38,17 @@ int ngx_blocking(ngx_socket_t s); - - #endif - -+#if (NGX_HAVE_FD_CLOEXEC) -+ -+#define ngx_cloexec(s) fcntl(s, F_SETFD, FD_CLOEXEC) -+#define ngx_cloexec_n "fcntl(FD_CLOEXEC)" -+ -+/* at least FD_CLOEXEC is required to ensure connection fd is closed -+ * after execve */ -+#define HAVE_SOCKET_CLOEXEC_PATCH 1 -+ -+#endif -+ - int ngx_tcp_nopush(ngx_socket_t s); - int ngx_tcp_push(ngx_socket_t s); - diff --git a/images/nginx/rootfs/patches/nginx-1.21.4-ssl_cert_cb_yield.patch b/images/nginx/rootfs/patches/nginx-1.21.4-ssl_cert_cb_yield.patch deleted file mode 100644 index 89773c05e..000000000 --- a/images/nginx/rootfs/patches/nginx-1.21.4-ssl_cert_cb_yield.patch +++ /dev/null @@ -1,64 +0,0 @@ -# HG changeset patch -# User Yichun Zhang -# Date 1451762084 28800 -# Sat Jan 02 11:14:44 2016 -0800 -# Node ID 449f0461859c16e95bdb18e8be6b94401545d3dd -# Parent 78b4e10b4367b31367aad3c83c9c3acdd42397c4 -SSL: handled SSL_CTX_set_cert_cb() callback yielding. - -OpenSSL 1.0.2+ introduces SSL_CTX_set_cert_cb() to allow custom -callbacks to serve the SSL certificiates and private keys dynamically -and lazily. The callbacks may yield for nonblocking I/O or sleeping. -Here we added support for such usage in NGINX 3rd-party modules -(like ngx_lua) in NGINX's event handlers for downstream SSL -connections. - -diff -r 78b4e10b4367 -r 449f0461859c src/event/ngx_event_openssl.c ---- a/src/event/ngx_event_openssl.c Thu Dec 17 16:39:15 2015 +0300 -+++ b/src/event/ngx_event_openssl.c Sat Jan 02 11:14:44 2016 -0800 -@@ -1445,6 +1445,23 @@ ngx_ssl_handshake(ngx_connection_t *c) - return NGX_AGAIN; - } - -+#if OPENSSL_VERSION_NUMBER >= 0x10002000L -+ if (sslerr == SSL_ERROR_WANT_X509_LOOKUP) { -+ c->read->handler = ngx_ssl_handshake_handler; -+ c->write->handler = ngx_ssl_handshake_handler; -+ -+ if (ngx_handle_read_event(c->read, 0) != NGX_OK) { -+ return NGX_ERROR; -+ } -+ -+ if (ngx_handle_write_event(c->write, 0) != NGX_OK) { -+ return NGX_ERROR; -+ } -+ -+ return NGX_AGAIN; -+ } -+#endif -+ - err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0; - - c->ssl->no_wait_shutdown = 1; -@@ -1558,6 +1575,21 @@ ngx_ssl_try_early_data(ngx_connection_t *c) - return NGX_AGAIN; - } - -+ if (sslerr == SSL_ERROR_WANT_X509_LOOKUP) { -+ c->read->handler = ngx_ssl_handshake_handler; -+ c->write->handler = ngx_ssl_handshake_handler; -+ -+ if (ngx_handle_read_event(c->read, 0) != NGX_OK) { -+ return NGX_ERROR; -+ } -+ -+ if (ngx_handle_write_event(c->write, 0) != NGX_OK) { -+ return NGX_ERROR; -+ } -+ -+ return NGX_AGAIN; -+ } -+ - err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0; - - c->ssl->no_wait_shutdown = 1; diff --git a/images/nginx/rootfs/patches/nginx-1.21.4-ssl_sess_cb_yield.patch b/images/nginx/rootfs/patches/nginx-1.21.4-ssl_sess_cb_yield.patch deleted file mode 100644 index ac5fe65eb..000000000 --- a/images/nginx/rootfs/patches/nginx-1.21.4-ssl_sess_cb_yield.patch +++ /dev/null @@ -1,41 +0,0 @@ -diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c ---- a/src/event/ngx_event_openssl.c -+++ b/src/event/ngx_event_openssl.c -@@ -1446,7 +1446,12 @@ ngx_ssl_handshake(ngx_connection_t *c) - } - - #if OPENSSL_VERSION_NUMBER >= 0x10002000L -- if (sslerr == SSL_ERROR_WANT_X509_LOOKUP) { -+ if (sslerr == SSL_ERROR_WANT_X509_LOOKUP -+# ifdef SSL_ERROR_PENDING_SESSION -+ || sslerr == SSL_ERROR_PENDING_SESSION -+# endif -+ ) -+ { - c->read->handler = ngx_ssl_handshake_handler; - c->write->handler = ngx_ssl_handshake_handler; - -@@ -1575,6 +1580,23 @@ ngx_ssl_try_early_data(ngx_connection_t *c) - return NGX_AGAIN; - } - -+#ifdef SSL_ERROR_PENDING_SESSION -+ if (sslerr == SSL_ERROR_PENDING_SESSION) { -+ c->read->handler = ngx_ssl_handshake_handler; -+ c->write->handler = ngx_ssl_handshake_handler; -+ -+ if (ngx_handle_read_event(c->read, 0) != NGX_OK) { -+ return NGX_ERROR; -+ } -+ -+ if (ngx_handle_write_event(c->write, 0) != NGX_OK) { -+ return NGX_ERROR; -+ } -+ -+ return NGX_AGAIN; -+ } -+#endif -+ - err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0; - - c->ssl->no_wait_shutdown = 1; diff --git a/images/nginx/rootfs/patches/nginx-1.21.4-stream_proxy_get_next_upstream_tries.patch b/images/nginx/rootfs/patches/nginx-1.21.4-stream_proxy_get_next_upstream_tries.patch deleted file mode 100644 index cb881f070..000000000 --- a/images/nginx/rootfs/patches/nginx-1.21.4-stream_proxy_get_next_upstream_tries.patch +++ /dev/null @@ -1,31 +0,0 @@ -diff --git a/src/stream/ngx_stream.h b/src/stream/ngx_stream.h -index 09d2459..de92724 100644 ---- a/src/stream/ngx_stream.h -+++ b/src/stream/ngx_stream.h -@@ -303,4 +303,7 @@ typedef ngx_int_t (*ngx_stream_filter_pt)(ngx_stream_session_t *s, - extern ngx_stream_filter_pt ngx_stream_top_filter; - - -+#define HAS_NGX_STREAM_PROXY_GET_NEXT_UPSTREAM_TRIES_PATCH 1 -+ -+ - #endif /* _NGX_STREAM_H_INCLUDED_ */ -diff --git a/src/stream/ngx_stream_proxy_module.c b/src/stream/ngx_stream_proxy_module.c -index 0afde1c..3254ce1 100644 ---- a/src/stream/ngx_stream_proxy_module.c -+++ b/src/stream/ngx_stream_proxy_module.c -@@ -2156,3 +2156,14 @@ ngx_stream_proxy_bind(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) - - return NGX_CONF_OK; - } -+ -+ -+ngx_uint_t -+ngx_stream_proxy_get_next_upstream_tries(ngx_stream_session_t *s) -+{ -+ ngx_stream_proxy_srv_conf_t *pscf; -+ -+ pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); -+ -+ return pscf->next_upstream_tries; -+} diff --git a/images/nginx/rootfs/patches/nginx-1.21.4-stream_ssl_preread_no_skip.patch b/images/nginx/rootfs/patches/nginx-1.21.4-stream_ssl_preread_no_skip.patch deleted file mode 100644 index e45e9f69a..000000000 --- a/images/nginx/rootfs/patches/nginx-1.21.4-stream_ssl_preread_no_skip.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/src/stream/ngx_stream_ssl_preread_module.c b/src/stream/ngx_stream_ssl_preread_module.c -index e3d11fd9..3717b5fe 100644 ---- a/src/stream/ngx_stream_ssl_preread_module.c -+++ b/src/stream/ngx_stream_ssl_preread_module.c -@@ -159,7 +159,7 @@ ngx_stream_ssl_preread_handler(ngx_stream_session_t *s) - - rc = ngx_stream_ssl_preread_parse_record(ctx, p, p + len); - if (rc != NGX_AGAIN) { -- return rc; -+ return rc == NGX_OK ? NGX_DECLINED : rc; - } - - p += len; diff --git a/images/nginx/rootfs/patches/nginx-1.21.4-upstream_pipelining.patch b/images/nginx/rootfs/patches/nginx-1.21.4-upstream_pipelining.patch deleted file mode 100644 index aed80365a..000000000 --- a/images/nginx/rootfs/patches/nginx-1.21.4-upstream_pipelining.patch +++ /dev/null @@ -1,23 +0,0 @@ -commit f9907b72a76a21ac5413187b83177a919475c75f -Author: Yichun Zhang (agentzh) -Date: Wed Feb 10 16:05:08 2016 -0800 - - bugfix: upstream: keep sending request data after the first write attempt. - - See - http://mailman.nginx.org/pipermail/nginx-devel/2012-March/002040.html - for more details on the issue. - -diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c -index 69019417..92b7c97f 100644 ---- a/src/http/ngx_http_upstream.c -+++ b/src/http/ngx_http_upstream.c -@@ -2239,7 +2239,7 @@ ngx_http_upstream_send_request_handler(ngx_http_request_t *r, - - #endif - -- if (u->header_sent && !u->conf->preserve_output) { -+ if (u->request_body_sent && !u->conf->preserve_output) { - u->write_event_handler = ngx_http_upstream_dummy_handler; - - (void) ngx_handle_write_event(c->write, 0); diff --git a/images/nginx/rootfs/patches/nginx-1.21.4-upstream_timeout_fields.patch b/images/nginx/rootfs/patches/nginx-1.21.4-upstream_timeout_fields.patch deleted file mode 100644 index 2314ddf80..000000000 --- a/images/nginx/rootfs/patches/nginx-1.21.4-upstream_timeout_fields.patch +++ /dev/null @@ -1,112 +0,0 @@ -diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c -index 69019417..2265d8f7 100644 ---- a/src/http/ngx_http_upstream.c -+++ b/src/http/ngx_http_upstream.c -@@ -509,12 +509,19 @@ void - ngx_http_upstream_init(ngx_http_request_t *r) - { - ngx_connection_t *c; -+ ngx_http_upstream_t *u; - - c = r->connection; - - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, - "http init upstream, client timer: %d", c->read->timer_set); - -+ u = r->upstream; -+ -+ u->connect_timeout = u->conf->connect_timeout; -+ u->send_timeout = u->conf->send_timeout; -+ u->read_timeout = u->conf->read_timeout; -+ - #if (NGX_HTTP_V2) - if (r->stream) { - ngx_http_upstream_init_request(r); -@@ -1626,7 +1633,7 @@ ngx_http_upstream_connect(ngx_http_request_t *r, ngx_http_upstream_t *u) - u->request_body_blocked = 0; - - if (rc == NGX_AGAIN) { -- ngx_add_timer(c->write, u->conf->connect_timeout); -+ ngx_add_timer(c->write, u->connect_timeout); - return; - } - -@@ -1704,7 +1711,7 @@ ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r, - if (rc == NGX_AGAIN) { - - if (!c->write->timer_set) { -- ngx_add_timer(c->write, u->conf->connect_timeout); -+ ngx_add_timer(c->write, u->connect_timeout); - } - - c->ssl->handler = ngx_http_upstream_ssl_handshake_handler; -@@ -2022,7 +2029,7 @@ ngx_http_upstream_send_request(ngx_http_request_t *r, ngx_http_upstream_t *u, - - if (rc == NGX_AGAIN) { - if (!c->write->ready || u->request_body_blocked) { -- ngx_add_timer(c->write, u->conf->send_timeout); -+ ngx_add_timer(c->write, u->send_timeout); - - } else if (c->write->timer_set) { - ngx_del_timer(c->write); -@@ -2084,7 +2091,7 @@ ngx_http_upstream_send_request(ngx_http_request_t *r, ngx_http_upstream_t *u, - return; - } - -- ngx_add_timer(c->read, u->conf->read_timeout); -+ ngx_add_timer(c->read, u->read_timeout); - - if (c->read->ready) { - ngx_http_upstream_process_header(r, u); -@@ -3213,7 +3220,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) - p->cyclic_temp_file = 0; - } - -- p->read_timeout = u->conf->read_timeout; -+ p->read_timeout = u->read_timeout; - p->send_timeout = clcf->send_timeout; - p->send_lowat = clcf->send_lowat; - -@@ -3458,7 +3465,7 @@ ngx_http_upstream_process_upgraded(ngx_http_request_t *r, - } - - if (upstream->write->active && !upstream->write->ready) { -- ngx_add_timer(upstream->write, u->conf->send_timeout); -+ ngx_add_timer(upstream->write, u->send_timeout); - - } else if (upstream->write->timer_set) { - ngx_del_timer(upstream->write); -@@ -3470,7 +3477,7 @@ ngx_http_upstream_process_upgraded(ngx_http_request_t *r, - } - - if (upstream->read->active && !upstream->read->ready) { -- ngx_add_timer(upstream->read, u->conf->read_timeout); -+ ngx_add_timer(upstream->read, u->read_timeout); - - } else if (upstream->read->timer_set) { - ngx_del_timer(upstream->read); -@@ -3664,7 +3671,7 @@ ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r, - } - - if (upstream->read->active && !upstream->read->ready) { -- ngx_add_timer(upstream->read, u->conf->read_timeout); -+ ngx_add_timer(upstream->read, u->read_timeout); - - } else if (upstream->read->timer_set) { - ngx_del_timer(upstream->read); -diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h -index c2f4dc0b..b9eef118 100644 ---- a/src/http/ngx_http_upstream.h -+++ b/src/http/ngx_http_upstream.h -@@ -333,6 +333,11 @@ struct ngx_http_upstream_s { - ngx_array_t *caches; - #endif - -+#define HAVE_NGX_UPSTREAM_TIMEOUT_FIELDS 1 -+ ngx_msec_t connect_timeout; -+ ngx_msec_t send_timeout; -+ ngx_msec_t read_timeout; -+ - ngx_http_upstream_headers_in_t headers_in; - - ngx_http_upstream_resolved_t *resolved; diff --git a/images/opentelemetry/Makefile b/images/opentelemetry/Makefile deleted file mode 100644 index eae435bef..000000000 --- a/images/opentelemetry/Makefile +++ /dev/null @@ -1,69 +0,0 @@ -# Copyright 2024 The Kubernetes Authors. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -.DEFAULT_GOAL:=build - -# set default shell -SHELL=/bin/bash -o pipefail -o errexit - -DIR:=$(strip $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))) -INIT_BUILDX=$(DIR)/../../hack/init-buildx.sh - -# 0.0.0 shouldn't clobber any released builds -SHORT_SHA ?=$(shell git rev-parse --short HEAD) -TAG ?=v$(shell date +%Y%m%d)-$(SHORT_SHA) - -REGISTRY ?= gcr.io/k8s-staging-ingress-nginx - -IMAGE = $(REGISTRY)/opentelemetry - -# required to enable buildx -export DOCKER_CLI_EXPERIMENTAL=enabled - -# build with buildx -PLATFORMS?=linux/amd64,linux/arm,linux/arm64 -OUTPUT= -PROGRESS=plain - -precheck: -ifndef NGINX_VERSION - $(error NGINX_VERSION variable is required) -endif - -build: precheck ensure-buildx - docker buildx build \ - --label=org.opencontainers.image.source=https://github.com/kubernetes/ingress-nginx \ - --label=org.opencontainers.image.licenses=Apache-2.0 \ - --label=org.opencontainers.image.description="Ingress NGINX Opentelemetry image" \ - --platform=${PLATFORMS} $(OUTPUT) \ - --progress=$(PROGRESS) \ - --build-arg=NGINX_VERSION=$(NGINX_VERSION) \ - --pull \ - --tag $(IMAGE)-$(NGINX_VERSION):$(TAG) rootfs - -# push the cross built image -push: OUTPUT=--push -push: build - -# enable buildx -ensure-buildx: -# this is required for cloudbuild -ifeq ("$(wildcard $(INIT_BUILDX))","") - @curl -sSL https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/hack/init-buildx.sh | bash -else - @exec $(INIT_BUILDX) -endif - @echo "done" - -.PHONY: build precheck push ensure-buildx diff --git a/images/opentelemetry/TAG b/images/opentelemetry/TAG deleted file mode 100644 index 0ec25f750..000000000 --- a/images/opentelemetry/TAG +++ /dev/null @@ -1 +0,0 @@ -v1.0.0 diff --git a/images/opentelemetry/cloudbuild.yaml b/images/opentelemetry/cloudbuild.yaml deleted file mode 100644 index df86d37e7..000000000 --- a/images/opentelemetry/cloudbuild.yaml +++ /dev/null @@ -1,14 +0,0 @@ -options: - # Increase machine type for multi-arch builds. - machineType: E2_HIGHCPU_8 - # Ignore Prow provided substitutions. - substitution_option: ALLOW_LOOSE -steps: - - name: gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20240523-a15ad90fc9 - env: - - REGISTRY=gcr.io/k8s-staging-ingress-nginx - entrypoint: bash - args: - - -c - - gcloud auth configure-docker && cd images/opentelemetry && make NGINX_VERSION=1.21.6 push && make NGINX_VERSION=1.25.3 push -timeout: 1800s diff --git a/images/opentelemetry/rootfs/CMakeLists.txt b/images/opentelemetry/rootfs/CMakeLists.txt deleted file mode 100644 index 1c68d6fc6..000000000 --- a/images/opentelemetry/rootfs/CMakeLists.txt +++ /dev/null @@ -1,74 +0,0 @@ -#!/bin/bash - -# Copyright 2021 The Kubernetes Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -cmake_minimum_required(VERSION 3.11 FATAL_ERROR) - -project( - dependencies - LANGUAGES CXX - VERSION 0.0.1) - -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_EXTENSIONS OFF) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_CXX_FLAGS "-O2 -fpic") -set(CMAKE_VERBOSE_MAKEFILE ON CACHE BOOL "ON" FORCE) - -set(CMAKE_BUILD_TYPE - Release - CACHE STRING "Build type" FORCE) - -include(GNUInstallDirs) - -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY - ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY - ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY - ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}) - -set(INSTALL_LIBDIR - ${CMAKE_INSTALL_LIBDIR} - CACHE PATH "directory for libraries") -set(INSTALL_BINDIR - ${CMAKE_INSTALL_BINDIR} - CACHE PATH "directory for executables") -set(INSTALL_INCLUDEDIR - ${CMAKE_INSTALL_INCLUDEDIR} - CACHE PATH "directory for header files") - -set(DEF_INSTALL_CMAKEDIR share/cmake/${PROJECT_NAME}) -set(INSTALL_CMAKEDIR - ${DEF_INSTALL_CMAKEDIR} - CACHE PATH "directory for CMake files") - -set_property(DIRECTORY PROPERTY EP_BASE ${CMAKE_BINARY_DIR}/subs) - -set(STAGED_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/stage) -message(STATUS "${PROJECT_NAME} staged install: ${STAGED_INSTALL_PREFIX}") - -find_package(OpenSSL REQUIRED) -message("OpenSSL include dir: ${OPENSSL_INCLUDE_DIR}") -message("OpenSSL libraries: ${OPENSSL_LIBRARIES}") - -find_package(Protobuf REQUIRED) -find_package(gRPC REQUIRED) -find_package(OpentelemetryCPP REQUIRED) - -install( - DIRECTORY ${STAGED_INSTALL_PREFIX}/ - DESTINATION . - USE_SOURCE_PERMISSIONS) diff --git a/images/opentelemetry/rootfs/Dockerfile b/images/opentelemetry/rootfs/Dockerfile deleted file mode 100644 index f67948b86..000000000 --- a/images/opentelemetry/rootfs/Dockerfile +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright 2021 The Kubernetes Authors. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -FROM alpine:3.20.0 AS base - -RUN mkdir -p /opt/third_party/install -COPY . /opt/third_party/ - -# install build tools -RUN apk update \ - && apk upgrade \ - && apk add -U bash \ - && bash /opt/third_party/build.sh -p - -ENV NINJA_STATUS="[%p/%f/%t] " - -# install otel_ngx_module.so -FROM base AS nginx -ARG NGINX_VERSION=1.25.3 -RUN bash /opt/third_party/build.sh -n ${NGINX_VERSION} - -FROM golang:1.22.6-bullseye AS build-init - -WORKDIR /go/src/app -COPY . . - -RUN go mod download -RUN CGO_ENABLED=0 go build -o /go/bin/init_module - -FROM gcr.io/distroless/static-debian11 AS final -COPY --from=build-init /go/bin/init_module / -COPY --from=nginx /etc/nginx/modules /etc/nginx/modules - -CMD ["/init_module"] diff --git a/images/opentelemetry/rootfs/build.sh b/images/opentelemetry/rootfs/build.sh deleted file mode 100755 index 649595a75..000000000 --- a/images/opentelemetry/rootfs/build.sh +++ /dev/null @@ -1,165 +0,0 @@ -#!/bin/bash - -# Copyright 2021 The Kubernetes Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -o errexit -set -o nounset -set -o pipefail -set -x -# Check for recent changes: https://github.com/open-telemetry/opentelemetry-cpp/compare/v1.2.0...main -export OPENTELEMETRY_CPP_VERSION=${OPENTELEMETRY_CPP_VERSION:="v1.11.0"} -export INSTALL_DIR=/opt/third_party/install - -export NGINX_VERSION=${NGINX_VERSION:="1.25.3"} -# improve compilation times -CORES=$(($(grep -c ^processor /proc/cpuinfo) - 1)) - -rm -rf \ - /var/cache/debconf/* \ - /var/lib/apt/lists/* \ - /var/log/* \ - /tmp/* \ - /var/tmp/* - -export BUILD_PATH=/tmp/build -mkdir --verbose -p "$BUILD_PATH" - -Help() -{ - # Display Help - echo "Add description of the script functions here." - echo - echo "Syntax: scriptTemplate [-h|o|n|p|]" - echo "options:" - echo "h Print Help." - echo "o OpenTelemetry git tag" - echo "n install nginx" - echo "p prepare" - echo -} - -prepare() -{ - echo "https://dl-cdn.alpinelinux.org/alpine/edge/main" >> /etc/apk/repositories - echo "https://dl-cdn.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories - echo "https://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories - - apk add \ - linux-headers \ - cmake \ - ninja \ - openssl \ - curl-dev \ - openssl-dev \ - gtest-dev \ - c-ares-dev \ - pcre-dev \ - curl \ - git \ - build-base \ - coreutils \ - build-base \ - openssl-dev \ - pkgconfig \ - c-ares-dev \ - re2-dev \ - grpc-dev \ - protobuf-dev \ - opentelemetry-cpp-dev - - git config --global http.version HTTP/1.1 - git config --global http.postBuffer 157286400 -} - -install_otel() -{ - cd ${BUILD_PATH} - export LD_LIBRARY_PATH="${LD_LIBRARY_PATH:+LD_LIBRARY_PATH:}${INSTALL_DIR}/lib:/usr/local" - export PATH="${PATH}:${INSTALL_DIR}/bin" - git clone --recurse-submodules -j ${CORES} --depth=1 -b \ - ${OPENTELEMETRY_CPP_VERSION} https://github.com/open-telemetry/opentelemetry-cpp.git opentelemetry-cpp-${OPENTELEMETRY_CPP_VERSION} - cd "opentelemetry-cpp-${OPENTELEMETRY_CPP_VERSION}" - mkdir -p .build - cd .build - - cmake -DCMAKE_BUILD_TYPE=Release \ - -G Ninja \ - -DCMAKE_CXX_STANDARD=17 \ - -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE \ - -DWITH_ZIPKIN=OFF \ - -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} \ - -DBUILD_TESTING=OFF \ - -DWITH_BENCHMARK=OFF \ - -DWITH_FUNC_TESTS=OFF \ - -DBUILD_SHARED_LIBS=OFF \ - -DWITH_OTLP_GRPC=ON \ - -DWITH_OTLP_HTTP=OFF \ - -DWITH_ABSEIL=ON \ - -DWITH_EXAMPLES=OFF \ - -DWITH_NO_DEPRECATED_CODE=ON \ - .. - cmake --build . -j ${CORES} --target install -} - -install_nginx() -{ - - # Check for recent changes: https://github.com/open-telemetry/opentelemetry-cpp-contrib/compare/2656a4...main - export OPENTELEMETRY_CONTRIB_COMMIT=aaa51e2297bcb34297f3c7aa44fa790497d2f7f3 - - mkdir -p /etc/nginx - cd "$BUILD_PATH" - - # TODO fix curl - # get_src 0528e793a97f942868616449d49326160f9cb67b2253fb2c4864603ac6ab09a9 \ - # "https://github.com/open-telemetry/opentelemetry-cpp-contrib/archive/$OPENTELEMETRY_CONTRIB_COMMIT.tar.gz" - - git clone https://github.com/open-telemetry/opentelemetry-cpp-contrib.git \ - opentelemetry-cpp-contrib-${OPENTELEMETRY_CONTRIB_COMMIT} - cd ${BUILD_PATH}/opentelemetry-cpp-contrib-${OPENTELEMETRY_CONTRIB_COMMIT} - git reset --hard ${OPENTELEMETRY_CONTRIB_COMMIT} - cd ${BUILD_PATH}/opentelemetry-cpp-contrib-${OPENTELEMETRY_CONTRIB_COMMIT}/instrumentation/nginx - mkdir -p build - cd build - cmake -DCMAKE_BUILD_TYPE=Release \ - -G Ninja \ - -DCMAKE_CXX_STANDARD=17 \ - -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} \ - -DBUILD_SHARED_LIBS=ON \ - -DNGINX_VERSION=${NGINX_VERSION} \ - .. - cmake --build . -j ${CORES} --target install - - mkdir -p /etc/nginx/modules - cp ${INSTALL_DIR}/otel_ngx_module.so /etc/nginx/modules/otel_ngx_module.so -} - -while getopts ":phn:" option; do - case $option in - h) # display Help - Help - exit;; - p) # prepare - prepare - exit;; - n) # install nginx - NGINX_VERSION=${OPTARG} - install_nginx - exit;; - \?) - Help - exit;; - esac -done diff --git a/images/opentelemetry/rootfs/go.mod b/images/opentelemetry/rootfs/go.mod deleted file mode 100644 index 115ef686a..000000000 --- a/images/opentelemetry/rootfs/go.mod +++ /dev/null @@ -1,3 +0,0 @@ -module init-otel - -go 1.22.6 diff --git a/images/opentelemetry/rootfs/init_module.go b/images/opentelemetry/rootfs/init_module.go deleted file mode 100644 index 5d285052d..000000000 --- a/images/opentelemetry/rootfs/init_module.go +++ /dev/null @@ -1,103 +0,0 @@ -/* -Copyright 2023 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package main - -import ( - "fmt" - "io" - "os" - "path/filepath" -) - -func main() { - // Enable error handling for all operations - err := run() - if err != nil { - fmt.Fprintf(os.Stderr, "Error: %v\n", err) - os.Exit(1) - } -} - -func run() error { - // Create the target directory if it doesn't exist - targetDir := "/modules_mount/etc/nginx/modules/otel" - err := os.MkdirAll(targetDir, os.ModePerm) - if err != nil { - return fmt.Errorf("failed to create target directory: %w", err) - } - - // Copy files from source directory to target directory - sourceDir := "/etc/nginx/modules/" - err = filepath.Walk(sourceDir, func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - - // Skip directories - if info.IsDir() { - return nil - } - - // Calculate the destination path - relPath, err := filepath.Rel(sourceDir, path) - if err != nil { - return err - } - destPath := filepath.Join(targetDir, relPath) - - // Create the destination directory if it doesn't exist - destDir := filepath.Dir(destPath) - err = os.MkdirAll(destDir, os.ModePerm) - if err != nil { - return err - } - - // Copy the file - err = copyFile(path, destPath) - if err != nil { - return err - } - - return nil - }) - if err != nil { - return fmt.Errorf("failed to copy files: %w", err) - } - - return nil -} - -func copyFile(sourcePath, destPath string) error { - sourceFile, err := os.Open(sourcePath) - if err != nil { - return err - } - defer sourceFile.Close() - - destFile, err := os.Create(destPath) - if err != nil { - return err - } - defer destFile.Close() - - _, err = io.Copy(destFile, sourceFile) - if err != nil { - return err - } - - return nil -} diff --git a/images/test-runner/Makefile b/images/test-runner/Makefile index 3d60a5313..8adbf0b41 100644 --- a/images/test-runner/Makefile +++ b/images/test-runner/Makefile @@ -50,7 +50,7 @@ image: --build-arg BASE_IMAGE=${NGINX_BASE_IMAGE} \ --build-arg GOLANG_VERSION=${GO_VERSION} \ --build-arg ETCD_VERSION=3.5.13-0 \ - --build-arg K8S_RELEASE=v1.29.2 \ + --build-arg K8S_RELEASE=v1.32.2 \ --build-arg RESTY_CLI_VERSION=0.27 \ --build-arg RESTY_CLI_SHA=e5f4f3128af49ba5c4d039d0554e5ae91bbe05866f60eccfa96d3653274bff90 \ --build-arg LUAROCKS_VERSION=3.8.0 \ @@ -59,7 +59,7 @@ image: --build-arg YAML_LINT_VERSION=1.33.0 \ --build-arg YAMALE_VERSION=4.0.4 \ --build-arg HELM_VERSION=3.14.4 \ - --build-arg GINKGO_VERSION=2.20.0 \ + --build-arg GINKGO_VERSION=2.22.2 \ --build-arg GOLINT_VERSION=latest \ -t ${IMAGE}:${TAG} rootfs @@ -71,7 +71,7 @@ build: ensure-buildx --build-arg BASE_IMAGE=${NGINX_BASE_IMAGE} \ --build-arg GOLANG_VERSION=${GO_VERSION} \ --build-arg ETCD_VERSION=3.5.13-0 \ - --build-arg K8S_RELEASE=v1.29.2 \ + --build-arg K8S_RELEASE=v1.32.2 \ --build-arg RESTY_CLI_VERSION=0.27 \ --build-arg RESTY_CLI_SHA=e5f4f3128af49ba5c4d039d0554e5ae91bbe05866f60eccfa96d3653274bff90 \ --build-arg LUAROCKS_VERSION=3.8.0 \ @@ -80,7 +80,7 @@ build: ensure-buildx --build-arg YAML_LINT_VERSION=1.33.0 \ --build-arg YAMALE_VERSION=4.0.4 \ --build-arg HELM_VERSION=3.14.4 \ - --build-arg GINKGO_VERSION=2.20.0 \ + --build-arg GINKGO_VERSION=2.22.2 \ --build-arg GOLINT_VERSION=latest \ -t ${IMAGE}:${TAG} rootfs diff --git a/images/test-runner/TAG b/images/test-runner/TAG index 384942600..46b105a30 100644 --- a/images/test-runner/TAG +++ b/images/test-runner/TAG @@ -1 +1 @@ -v0.0.9 +v2.0.0 diff --git a/images/test-runner/cloudbuild.yaml b/images/test-runner/cloudbuild.yaml index 6efe5eeaf..93dce3ec9 100644 --- a/images/test-runner/cloudbuild.yaml +++ b/images/test-runner/cloudbuild.yaml @@ -2,11 +2,10 @@ options: # Ignore Prow provided substitutions. substitution_option: ALLOW_LOOSE steps: - - name: gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20240523-a15ad90fc9 + - name: gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20250116-2a05ea7e3d env: - - REGISTRY=gcr.io/k8s-staging-ingress-nginx + - REGISTRY=us-central1-docker.pkg.dev/k8s-staging-images/ingress-nginx entrypoint: bash args: - -c - gcloud auth configure-docker && cd images/test-runner && make push -timeout: 1800s diff --git a/images/test-runner/rootfs/Dockerfile b/images/test-runner/rootfs/Dockerfile index fd664f2e5..d871461bf 100644 --- a/images/test-runner/rootfs/Dockerfile +++ b/images/test-runner/rootfs/Dockerfile @@ -15,7 +15,7 @@ ARG BASE_IMAGE ARG GOLANG_VERSION ARG ETCD_VERSION -FROM golang:${GOLANG_VERSION}-alpine3.20 as GO +FROM golang:${GOLANG_VERSION}-alpine3.21 as GO FROM registry.k8s.io/etcd:${ETCD_VERSION} as etcd FROM ${BASE_IMAGE} @@ -48,7 +48,7 @@ RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" && chmod -R 777 "$GOPATH" COPY --from=etcd /usr/local/bin/etcd /usr/local/bin/etcd -RUN echo "@testing https://nl.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories +RUN echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories RUN apk update && apk upgrade && apk add --no-cache \ bash \ diff --git a/internal/admission/controller/server.go b/internal/admission/controller/server.go index 7fc61bcbb..74f55fd01 100644 --- a/internal/admission/controller/server.go +++ b/internal/admission/controller/server.go @@ -47,7 +47,7 @@ type AdmissionControllerServer struct { AdmissionController AdmissionController } -// NewAdmissionControllerServer instanciates an admission controller server with +// NewAdmissionControllerServer instantiates an admission controller server with // a default codec func NewAdmissionControllerServer(ac AdmissionController) *AdmissionControllerServer { return &AdmissionControllerServer{ diff --git a/internal/ingress/annotations/annotations.go b/internal/ingress/annotations/annotations.go index 302f0b4b1..e10cc9be1 100644 --- a/internal/ingress/annotations/annotations.go +++ b/internal/ingress/annotations/annotations.go @@ -19,18 +19,10 @@ package annotations import ( "dario.cat/mergo" - "k8s.io/ingress-nginx/internal/ingress/annotations/canary" - "k8s.io/ingress-nginx/internal/ingress/annotations/disableproxyintercepterrors" - "k8s.io/ingress-nginx/internal/ingress/annotations/modsecurity" - "k8s.io/ingress-nginx/internal/ingress/annotations/opentelemetry" - "k8s.io/ingress-nginx/internal/ingress/annotations/proxyssl" - "k8s.io/ingress-nginx/internal/ingress/annotations/sslcipher" - "k8s.io/ingress-nginx/internal/ingress/annotations/streamsnippet" - "k8s.io/klog/v2" - apiv1 "k8s.io/api/core/v1" networking "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/klog/v2" "k8s.io/ingress-nginx/internal/ingress/annotations/alias" "k8s.io/ingress-nginx/internal/ingress/annotations/auth" @@ -38,22 +30,27 @@ import ( "k8s.io/ingress-nginx/internal/ingress/annotations/authreqglobal" "k8s.io/ingress-nginx/internal/ingress/annotations/authtls" "k8s.io/ingress-nginx/internal/ingress/annotations/backendprotocol" + "k8s.io/ingress-nginx/internal/ingress/annotations/canary" "k8s.io/ingress-nginx/internal/ingress/annotations/clientbodybuffersize" "k8s.io/ingress-nginx/internal/ingress/annotations/connection" "k8s.io/ingress-nginx/internal/ingress/annotations/cors" + "k8s.io/ingress-nginx/internal/ingress/annotations/customheaders" "k8s.io/ingress-nginx/internal/ingress/annotations/customhttperrors" "k8s.io/ingress-nginx/internal/ingress/annotations/defaultbackend" + "k8s.io/ingress-nginx/internal/ingress/annotations/disableproxyintercepterrors" "k8s.io/ingress-nginx/internal/ingress/annotations/fastcgi" - "k8s.io/ingress-nginx/internal/ingress/annotations/globalratelimit" "k8s.io/ingress-nginx/internal/ingress/annotations/http2pushpreload" "k8s.io/ingress-nginx/internal/ingress/annotations/ipallowlist" "k8s.io/ingress-nginx/internal/ingress/annotations/ipdenylist" "k8s.io/ingress-nginx/internal/ingress/annotations/loadbalancing" "k8s.io/ingress-nginx/internal/ingress/annotations/log" "k8s.io/ingress-nginx/internal/ingress/annotations/mirror" + "k8s.io/ingress-nginx/internal/ingress/annotations/modsecurity" + "k8s.io/ingress-nginx/internal/ingress/annotations/opentelemetry" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/annotations/portinredirect" "k8s.io/ingress-nginx/internal/ingress/annotations/proxy" + "k8s.io/ingress-nginx/internal/ingress/annotations/proxyssl" "k8s.io/ingress-nginx/internal/ingress/annotations/ratelimit" "k8s.io/ingress-nginx/internal/ingress/annotations/redirect" "k8s.io/ingress-nginx/internal/ingress/annotations/rewrite" @@ -62,7 +59,9 @@ import ( "k8s.io/ingress-nginx/internal/ingress/annotations/serviceupstream" "k8s.io/ingress-nginx/internal/ingress/annotations/sessionaffinity" "k8s.io/ingress-nginx/internal/ingress/annotations/snippet" + "k8s.io/ingress-nginx/internal/ingress/annotations/sslcipher" "k8s.io/ingress-nginx/internal/ingress/annotations/sslpassthrough" + "k8s.io/ingress-nginx/internal/ingress/annotations/streamsnippet" "k8s.io/ingress-nginx/internal/ingress/annotations/upstreamhashby" "k8s.io/ingress-nginx/internal/ingress/annotations/upstreamvhost" "k8s.io/ingress-nginx/internal/ingress/annotations/xforwardedprefix" @@ -82,6 +81,7 @@ type Ingress struct { Canary canary.Config CertificateAuth authtls.Config ClientBodyBufferSize string + CustomHeaders customheaders.Config ConfigurationSnippet string Connection connection.Config CorsConfig cors.Config @@ -97,7 +97,6 @@ type Ingress struct { Proxy proxy.Config ProxySSL proxyssl.Config RateLimit ratelimit.Config - GlobalRateLimit globalratelimit.Config Redirect redirect.Config Rewrite rewrite.Config Satisfy string @@ -124,51 +123,55 @@ type Extractor struct { annotations map[string]parser.IngressAnnotation } +func NewAnnotationFactory(cfg resolver.Resolver) map[string]parser.IngressAnnotation { + return map[string]parser.IngressAnnotation{ + "Aliases": alias.NewParser(cfg), + "BasicDigestAuth": auth.NewParser(auth.AuthDirectory, cfg), + "Canary": canary.NewParser(cfg), + "CertificateAuth": authtls.NewParser(cfg), + "ClientBodyBufferSize": clientbodybuffersize.NewParser(cfg), + "CustomHeaders": customheaders.NewParser(cfg), + "ConfigurationSnippet": snippet.NewParser(cfg), + "Connection": connection.NewParser(cfg), + "CorsConfig": cors.NewParser(cfg), + "CustomHTTPErrors": customhttperrors.NewParser(cfg), + "DisableProxyInterceptErrors": disableproxyintercepterrors.NewParser(cfg), + "DefaultBackend": defaultbackend.NewParser(cfg), + "FastCGI": fastcgi.NewParser(cfg), + "ExternalAuth": authreq.NewParser(cfg), + "EnableGlobalAuth": authreqglobal.NewParser(cfg), + "HTTP2PushPreload": http2pushpreload.NewParser(cfg), + "Opentelemetry": opentelemetry.NewParser(cfg), + "Proxy": proxy.NewParser(cfg), + "ProxySSL": proxyssl.NewParser(cfg), + "RateLimit": ratelimit.NewParser(cfg), + "Redirect": redirect.NewParser(cfg), + "Rewrite": rewrite.NewParser(cfg), + "Satisfy": satisfy.NewParser(cfg), + "ServerSnippet": serversnippet.NewParser(cfg), + "ServiceUpstream": serviceupstream.NewParser(cfg), + "SessionAffinity": sessionaffinity.NewParser(cfg), + "SSLPassthrough": sslpassthrough.NewParser(cfg), + "UsePortInRedirects": portinredirect.NewParser(cfg), + "UpstreamHashBy": upstreamhashby.NewParser(cfg), + "LoadBalancing": loadbalancing.NewParser(cfg), + "UpstreamVhost": upstreamvhost.NewParser(cfg), + "Allowlist": ipallowlist.NewParser(cfg), + "Denylist": ipdenylist.NewParser(cfg), + "XForwardedPrefix": xforwardedprefix.NewParser(cfg), + "SSLCipher": sslcipher.NewParser(cfg), + "Logs": log.NewParser(cfg), + "BackendProtocol": backendprotocol.NewParser(cfg), + "ModSecurity": modsecurity.NewParser(cfg), + "Mirror": mirror.NewParser(cfg), + "StreamSnippet": streamsnippet.NewParser(cfg), + } +} + // NewAnnotationExtractor creates a new annotations extractor func NewAnnotationExtractor(cfg resolver.Resolver) Extractor { return Extractor{ - map[string]parser.IngressAnnotation{ - "Aliases": alias.NewParser(cfg), - "BasicDigestAuth": auth.NewParser(auth.AuthDirectory, cfg), - "Canary": canary.NewParser(cfg), - "CertificateAuth": authtls.NewParser(cfg), - "ClientBodyBufferSize": clientbodybuffersize.NewParser(cfg), - "ConfigurationSnippet": snippet.NewParser(cfg), - "Connection": connection.NewParser(cfg), - "CorsConfig": cors.NewParser(cfg), - "CustomHTTPErrors": customhttperrors.NewParser(cfg), - "DisableProxyInterceptErrors": disableproxyintercepterrors.NewParser(cfg), - "DefaultBackend": defaultbackend.NewParser(cfg), - "FastCGI": fastcgi.NewParser(cfg), - "ExternalAuth": authreq.NewParser(cfg), - "EnableGlobalAuth": authreqglobal.NewParser(cfg), - "HTTP2PushPreload": http2pushpreload.NewParser(cfg), - "Opentelemetry": opentelemetry.NewParser(cfg), - "Proxy": proxy.NewParser(cfg), - "ProxySSL": proxyssl.NewParser(cfg), - "RateLimit": ratelimit.NewParser(cfg), - "GlobalRateLimit": globalratelimit.NewParser(cfg), - "Redirect": redirect.NewParser(cfg), - "Rewrite": rewrite.NewParser(cfg), - "Satisfy": satisfy.NewParser(cfg), - "ServerSnippet": serversnippet.NewParser(cfg), - "ServiceUpstream": serviceupstream.NewParser(cfg), - "SessionAffinity": sessionaffinity.NewParser(cfg), - "SSLPassthrough": sslpassthrough.NewParser(cfg), - "UsePortInRedirects": portinredirect.NewParser(cfg), - "UpstreamHashBy": upstreamhashby.NewParser(cfg), - "LoadBalancing": loadbalancing.NewParser(cfg), - "UpstreamVhost": upstreamvhost.NewParser(cfg), - "Allowlist": ipallowlist.NewParser(cfg), - "Denylist": ipdenylist.NewParser(cfg), - "XForwardedPrefix": xforwardedprefix.NewParser(cfg), - "SSLCipher": sslcipher.NewParser(cfg), - "Logs": log.NewParser(cfg), - "BackendProtocol": backendprotocol.NewParser(cfg), - "ModSecurity": modsecurity.NewParser(cfg), - "Mirror": mirror.NewParser(cfg), - "StreamSnippet": streamsnippet.NewParser(cfg), - }, + NewAnnotationFactory(cfg), } } diff --git a/internal/ingress/annotations/annotations_test.go b/internal/ingress/annotations/annotations_test.go index 0f4f8f7d7..5df3cdc0e 100644 --- a/internal/ingress/annotations/annotations_test.go +++ b/internal/ingress/annotations/annotations_test.go @@ -43,16 +43,20 @@ var ( annotationAffinityCookieName = parser.GetAnnotationWithPrefix("session-cookie-name") annotationUpstreamHashBy = parser.GetAnnotationWithPrefix("upstream-hash-by") annotationCustomHTTPErrors = parser.GetAnnotationWithPrefix("custom-http-errors") + annotationCustomHeaders = parser.GetAnnotationWithPrefix("custom-headers") ) type mockCfg struct { resolver.Mock - MockSecrets map[string]*apiv1.Secret - MockServices map[string]*apiv1.Service + MockSecrets map[string]*apiv1.Secret + MockServices map[string]*apiv1.Service + MockConfigMaps map[string]*apiv1.ConfigMap } func (m mockCfg) GetDefaultBackend() defaults.Backend { - return defaults.Backend{} + return defaults.Backend{ + AllowedResponseHeaders: []string{"Content-Type"}, + } } func (m mockCfg) GetSecret(name string) (*apiv1.Secret, error) { @@ -63,6 +67,10 @@ func (m mockCfg) GetService(name string) (*apiv1.Service, error) { return m.MockServices[name], nil } +func (m mockCfg) GetConfigMap(name string) (*apiv1.ConfigMap, error) { + return m.MockConfigMaps[name], nil +} + func (m mockCfg) GetAuthCertificate(name string) (*resolver.AuthSSLCert, error) { secret, err := m.GetSecret(name) if err != nil { @@ -317,3 +325,44 @@ func TestCustomHTTPErrors(t *testing.T) { } } } + +func TestCustomResponseHeaders(t *testing.T) { + mockObj := mockCfg{} + mockObj.MockConfigMaps = map[string]*apiv1.ConfigMap{} + mockObj.MockConfigMaps["custom-headers"] = &apiv1.ConfigMap{Data: map[string]string{"Content-Type": "application/json"}} + mockObj.MockConfigMaps["empty-custom-headers"] = &apiv1.ConfigMap{Data: map[string]string{}} + + ec := NewAnnotationExtractor(mockObj) + ing := buildIngress() + fooAnns := []struct { + annotations map[string]string + headers map[string]string + }{ + {map[string]string{annotationCustomHeaders: "custom-headers"}, map[string]string{"Content-Type": "application/json"}}, + {map[string]string{annotationCustomHeaders: "empty-custom-headers"}, map[string]string{}}, + {nil, map[string]string{}}, + } + + for _, foo := range fooAnns { + ing.SetAnnotations(foo.annotations) + rann, err := ec.Extract(ing) + if err != nil { + t.Errorf("error should be null: %v", err) + } + r := rann.CustomHeaders.Headers + + // Check that expected headers were created + for i := range foo.headers { + if r[i] != foo.headers[i] { + t.Errorf("Returned %v but expected %v", r, foo.headers) + } + } + + // Check that no unexpected headers were created + for i := range r { + if r[i] != foo.headers[i] { + t.Errorf("Returned %v but expected %v", r, foo.headers) + } + } + } +} diff --git a/internal/ingress/annotations/authtls/main.go b/internal/ingress/annotations/authtls/main.go index 1c6bad485..de4d1cc1d 100644 --- a/internal/ingress/annotations/authtls/main.go +++ b/internal/ingress/annotations/authtls/main.go @@ -42,7 +42,7 @@ const ( var ( authVerifyClientRegex = regexp.MustCompile(`^(on|off|optional|optional_no_ca)$`) - redirectRegex = regexp.MustCompile(`^((https?://)?[A-Za-z0-9\-.]*(:\d+)?/[A-Za-z0-9\-.]*)?$`) + redirectRegex = regexp.MustCompile(`^((https?://)?[A-Za-z0-9\-.]+(:\d+)?)?(/[A-Za-z0-9\-_.]+)*/?$`) ) var authTLSAnnotations = parser.Annotation{ diff --git a/internal/ingress/annotations/cors/main.go b/internal/ingress/annotations/cors/main.go index d6e92b34d..cef4fb1b2 100644 --- a/internal/ingress/annotations/cors/main.go +++ b/internal/ingress/annotations/cors/main.go @@ -40,12 +40,12 @@ var ( // that could cause the Response to contain some internal value/variable (like returning $pid, $upstream_addr, etc) // Origin must contain a http/s Origin (including or not the port) or the value '*' // This Regex is composed of the following: - // * Sets a group that can be (https?://)?*?.something.com:port? + // * Sets a group that can be (https?://)?*?.something.com:port? OR null // * Allows this to be repeated as much as possible, and separated by comma // Otherwise it should be '*' - corsOriginRegexValidator = regexp.MustCompile(`^((((https?://)?(\*\.)?[A-Za-z0-9\-.]*(:\d+)?,?)+)|\*)?$`) + corsOriginRegexValidator = regexp.MustCompile(`^((((([a-z]+://)?(\*\.)?[A-Za-z0-9\-.]*(:\d+)?,?)|null)+)|\*)?$`) // corsOriginRegex defines the regex for validation inside Parse - corsOriginRegex = regexp.MustCompile(`^(https?://(\*\.)?[A-Za-z0-9\-.]*(:\d+)?|\*)?$`) + corsOriginRegex = regexp.MustCompile(`^([a-z]+://(\*\.)?[A-Za-z0-9\-.]*(:\d+)?|\*|null)?$`) // Method must contain valid methods list (PUT, GET, POST, BLA) // May contain or not spaces between each verb corsMethodsRegex = regexp.MustCompile(`^([A-Za-z]+,?\s?)+$`) @@ -78,8 +78,9 @@ var corsAnnotation = parser.Annotation{ Scope: parser.AnnotationScopeIngress, Risk: parser.AnnotationRiskMedium, Documentation: `This annotation controls what's the accepted Origin for CORS. - This is a multi-valued field, separated by ','. It must follow this format: http(s)://origin-site.com or http(s)://origin-site.com:port - It also supports single level wildcard subdomains and follows this format: http(s)://*.foo.bar, http(s)://*.bar.foo:8080 or http(s)://*.abc.bar.foo:9000`, + This is a multi-valued field, separated by ','. It must follow this format: protocol://origin-site.com, protocol://origin-site.com:port, null, or *. + It also supports single level wildcard subdomains and follows this format: https://*.foo.bar, http://*.bar.foo:8080 or myprotocol://*.abc.bar.foo:9000 + Protocol can be any lowercase string, like http, https, or mycustomprotocol.`, }, corsAllowHeadersAnnotation: { Validator: parser.ValidateRegex(parser.HeadersVariable, true), diff --git a/internal/ingress/annotations/cors/main_test.go b/internal/ingress/annotations/cors/main_test.go index a69390a17..0b6b3671b 100644 --- a/internal/ingress/annotations/cors/main_test.go +++ b/internal/ingress/annotations/cors/main_test.go @@ -27,6 +27,8 @@ import ( "k8s.io/ingress-nginx/internal/ingress/resolver" ) +const enableAnnotation = "true" + func buildIngress() *networking.Ingress { defaultBackend := networking.IngressBackend{ Service: &networking.IngressServiceBackend{ @@ -76,11 +78,11 @@ func TestIngressCorsConfigValid(t *testing.T) { data := map[string]string{} // Valid - data[parser.GetAnnotationWithPrefix(corsEnableAnnotation)] = "true" + data[parser.GetAnnotationWithPrefix(corsEnableAnnotation)] = enableAnnotation data[parser.GetAnnotationWithPrefix(corsAllowHeadersAnnotation)] = "DNT,X-CustomHeader, Keep-Alive,User-Agent" data[parser.GetAnnotationWithPrefix(corsAllowCredentialsAnnotation)] = "false" data[parser.GetAnnotationWithPrefix(corsAllowMethodsAnnotation)] = "GET, PATCH" - data[parser.GetAnnotationWithPrefix(corsAllowOriginAnnotation)] = "https://origin123.test.com:4443" + data[parser.GetAnnotationWithPrefix(corsAllowOriginAnnotation)] = "null, https://origin123.test.com:4443" data[parser.GetAnnotationWithPrefix(corsExposeHeadersAnnotation)] = "*, X-CustomResponseHeader" data[parser.GetAnnotationWithPrefix(corsMaxAgeAnnotation)] = "600" ing.SetAnnotations(data) @@ -111,7 +113,7 @@ func TestIngressCorsConfigValid(t *testing.T) { t.Errorf("expected %v but returned %v", data[parser.GetAnnotationWithPrefix(corsAllowMethodsAnnotation)], nginxCors.CorsAllowMethods) } - if nginxCors.CorsAllowOrigin[0] != "https://origin123.test.com:4443" { + if !reflect.DeepEqual(nginxCors.CorsAllowOrigin, []string{"null", "https://origin123.test.com:4443"}) { t.Errorf("expected %v but returned %v", data[parser.GetAnnotationWithPrefix(corsAllowOriginAnnotation)], nginxCors.CorsAllowOrigin) } @@ -174,11 +176,11 @@ func TestIngressCorsConfigInvalid(t *testing.T) { } } -func TestIngresCorsConfigAllowOriginWithTrailingComma(t *testing.T) { +func TestIngressCorsConfigAllowOriginWithTrailingComma(t *testing.T) { ing := buildIngress() data := map[string]string{} - data[parser.GetAnnotationWithPrefix(corsEnableAnnotation)] = "true" + data[parser.GetAnnotationWithPrefix(corsEnableAnnotation)] = enableAnnotation // Include a trailing comma and an empty value between the commas. data[parser.GetAnnotationWithPrefix(corsAllowOriginAnnotation)] = "https://origin123.test.com:4443, ,https://origin321.test.com:4443," @@ -203,3 +205,63 @@ func TestIngresCorsConfigAllowOriginWithTrailingComma(t *testing.T) { t.Errorf("expected %v but returned %v", expectedCorsAllowOrigins, nginxCors.CorsAllowOrigin) } } + +func TestIngressCorsConfigAllowOriginNull(t *testing.T) { + ing := buildIngress() + + data := map[string]string{} + data[parser.GetAnnotationWithPrefix(corsEnableAnnotation)] = enableAnnotation + + // Include a trailing comma and an empty value between the commas. + data[parser.GetAnnotationWithPrefix(corsAllowOriginAnnotation)] = "https://origin123.test.com:4443,null,https://origin321.test.com:4443" + ing.SetAnnotations(data) + + corst, err := NewParser(&resolver.Mock{}).Parse(ing) + if err != nil { + t.Errorf("error parsing annotations: %v", err) + } + + nginxCors, ok := corst.(*Config) + if !ok { + t.Errorf("expected a Config type but returned %t", corst) + } + + if !nginxCors.CorsEnabled { + t.Errorf("expected %v but returned %v", data[parser.GetAnnotationWithPrefix(corsEnableAnnotation)], nginxCors.CorsEnabled) + } + + expectedCorsAllowOrigins := []string{"https://origin123.test.com:4443", "null", "https://origin321.test.com:4443"} + if !reflect.DeepEqual(nginxCors.CorsAllowOrigin, expectedCorsAllowOrigins) { + t.Errorf("expected %v but returned %v", expectedCorsAllowOrigins, nginxCors.CorsAllowOrigin) + } +} + +func TestIngressCorsConfigAllowOriginWithNonHttpProtocol(t *testing.T) { + ing := buildIngress() + + data := map[string]string{} + data[parser.GetAnnotationWithPrefix(corsEnableAnnotation)] = enableAnnotation + + // Include a trailing comma and an empty value between the commas. + data[parser.GetAnnotationWithPrefix(corsAllowOriginAnnotation)] = "test://localhost" + ing.SetAnnotations(data) + + corst, err := NewParser(&resolver.Mock{}).Parse(ing) + if err != nil { + t.Errorf("error parsing annotations: %v", err) + } + + nginxCors, ok := corst.(*Config) + if !ok { + t.Errorf("expected a Config type but returned %t", corst) + } + + if !nginxCors.CorsEnabled { + t.Errorf("expected %v but returned %v", data[parser.GetAnnotationWithPrefix(corsEnableAnnotation)], nginxCors.CorsEnabled) + } + + expectedCorsAllowOrigins := []string{"test://localhost"} + if !reflect.DeepEqual(nginxCors.CorsAllowOrigin, expectedCorsAllowOrigins) { + t.Errorf("expected %v but returned %v", expectedCorsAllowOrigins, nginxCors.CorsAllowOrigin) + } +} diff --git a/internal/ingress/annotations/customheaders/main.go b/internal/ingress/annotations/customheaders/main.go new file mode 100644 index 000000000..d48018d8c --- /dev/null +++ b/internal/ingress/annotations/customheaders/main.go @@ -0,0 +1,137 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package customheaders + +import ( + "fmt" + "reflect" + "regexp" + "slices" + + "k8s.io/klog/v2" + + networking "k8s.io/api/networking/v1" + + "k8s.io/ingress-nginx/internal/ingress/annotations/parser" + ing_errors "k8s.io/ingress-nginx/internal/ingress/errors" + "k8s.io/ingress-nginx/internal/ingress/resolver" +) + +// Config returns the custom response headers for an Ingress rule +type Config struct { + Headers map[string]string `json:"headers,omitempty"` +} + +// Equal tests for equality between two Config types +func (c1 *Config) Equal(c2 *Config) bool { + if c1 == c2 { + return true + } + if c1 == nil || c2 == nil { + return false + } + + return reflect.DeepEqual(c1.Headers, c2.Headers) +} + +var ( + headerRegexp = regexp.MustCompile(`^[a-zA-Z\d\-_]+$`) + valueRegexp = regexp.MustCompile(`^[a-zA-Z\d_ :;.,\\/"'?!(){}\[\]@<>=\-+*#$&\x60|~^%]+$`) +) + +// ValidHeader checks is the provided string satisfies the header's name regex +func ValidHeader(header string) bool { + return headerRegexp.MatchString(header) +} + +// ValidValue checks is the provided string satisfies the value regex +func ValidValue(header string) bool { + return valueRegexp.MatchString(header) +} + +const ( + customHeadersConfigMapAnnotation = "custom-headers" +) + +var customHeadersAnnotation = parser.Annotation{ + Group: "backend", + Annotations: parser.AnnotationFields{ + customHeadersConfigMapAnnotation: { + Validator: parser.ValidateRegex(parser.BasicCharsRegex, true), + Scope: parser.AnnotationScopeLocation, + Risk: parser.AnnotationRiskMedium, + Documentation: `This annotation sets the name of a ConfigMap that specifies headers to pass to the client. + Only ConfigMaps on the same namespace are allowed`, + }, + }, +} + +type customHeaders struct { + r resolver.Resolver + annotationConfig parser.Annotation +} + +// NewParser creates a new custom response headers annotation parser +func NewParser(r resolver.Resolver) parser.IngressAnnotation { + return customHeaders{r: r, annotationConfig: customHeadersAnnotation} +} + +func (a customHeaders) GetDocumentation() parser.AnnotationFields { + return a.annotationConfig.Annotations +} + +// Parse parses the annotations contained in the ingress to use +// custom response headers +func (a customHeaders) Parse(ing *networking.Ingress) (interface{}, error) { + clientHeadersConfigMapName, err := parser.GetStringAnnotation(customHeadersConfigMapAnnotation, ing, a.annotationConfig.Annotations) + if err != nil { + klog.V(3).InfoS("client-headers annotation is undefined and will not be set") + } + + var headers map[string]string + defBackend := a.r.GetDefaultBackend() + + if clientHeadersConfigMapName != "" { + clientHeadersMapContents, err := a.r.GetConfigMap(clientHeadersConfigMapName) + if err != nil { + return nil, ing_errors.NewLocationDenied(fmt.Sprintf("unable to find configMap %q", clientHeadersConfigMapName)) + } + + for header, value := range clientHeadersMapContents.Data { + if !ValidHeader(header) { + return nil, ing_errors.NewLocationDenied("invalid header name in configmap") + } + if !ValidValue(value) { + return nil, ing_errors.NewLocationDenied("invalid header value in configmap") + } + if !slices.Contains(defBackend.AllowedResponseHeaders, header) { + return nil, ing_errors.NewLocationDenied(fmt.Sprintf("header %s is not allowed, defined allowed headers inside global-allowed-response-headers %v", header, defBackend.AllowedResponseHeaders)) + } + } + + headers = clientHeadersMapContents.Data + } + + return &Config{ + Headers: headers, + }, nil +} + +func (a customHeaders) Validate(anns map[string]string) error { + maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRiskLevel) + return parser.CheckAnnotationRisk(anns, maxrisk, customHeadersAnnotation.Annotations) +} diff --git a/internal/ingress/annotations/customheaders/main_test.go b/internal/ingress/annotations/customheaders/main_test.go new file mode 100644 index 000000000..81c0b795a --- /dev/null +++ b/internal/ingress/annotations/customheaders/main_test.go @@ -0,0 +1,113 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package customheaders + +import ( + "reflect" + "testing" + + api "k8s.io/api/core/v1" + networking "k8s.io/api/networking/v1" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/ingress-nginx/internal/ingress/annotations/parser" + "k8s.io/ingress-nginx/internal/ingress/defaults" + "k8s.io/ingress-nginx/internal/ingress/resolver" +) + +func buildIngress() *networking.Ingress { + return &networking.Ingress{ + ObjectMeta: meta_v1.ObjectMeta{ + Name: "foo", + Namespace: api.NamespaceDefault, + }, + Spec: networking.IngressSpec{ + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, + }, + }, + } +} + +type mockBackend struct { + resolver.Mock +} + +// GetDefaultBackend returns the backend that must be used as default +func (m mockBackend) GetDefaultBackend() defaults.Backend { + return defaults.Backend{ + AllowedResponseHeaders: []string{"Content-Type", "Access-Control-Max-Age"}, + } +} + +func TestCustomHeadersParseInvalidAnnotations(t *testing.T) { + ing := buildIngress() + configMapResolver := mockBackend{} + configMapResolver.ConfigMaps = map[string]*api.ConfigMap{} + + _, err := NewParser(configMapResolver).Parse(ing) + if err != nil { + t.Errorf("expected error parsing ingress with custom-response-headers") + } + + data := map[string]string{} + data[parser.GetAnnotationWithPrefix("custom-headers")] = "custom-headers-configmap" + ing.SetAnnotations(data) + i, err := NewParser(&resolver.Mock{}).Parse(ing) + if err == nil { + t.Errorf("expected error parsing ingress with custom-response-headers") + } + if i != nil { + t.Errorf("expected %v but got %v", nil, i) + } +} + +func TestCustomHeadersParseAnnotations(t *testing.T) { + ing := buildIngress() + + data := map[string]string{} + data[parser.GetAnnotationWithPrefix("custom-headers")] = "custom-headers-configmap" + ing.SetAnnotations(data) + + configMapResolver := mockBackend{} + configMapResolver.ConfigMaps = map[string]*api.ConfigMap{} + + configMapResolver.ConfigMaps["custom-headers-configmap"] = &api.ConfigMap{Data: map[string]string{"Content-Type": "application/json", "Access-Control-Max-Age": "600"}} + + i, err := NewParser(configMapResolver).Parse(ing) + if err != nil { + t.Errorf("unexpected error parsing ingress with custom-response-headers: %s", err) + } + val, ok := i.(*Config) + if !ok { + t.Errorf("expected a *Config type") + } + + expectedResponseHeaders := map[string]string{} + expectedResponseHeaders["Content-Type"] = "application/json" + expectedResponseHeaders["Access-Control-Max-Age"] = "600" + + c := &Config{expectedResponseHeaders} + + if !reflect.DeepEqual(c, val) { + t.Errorf("expected %v but got %v", c, val) + } +} diff --git a/internal/ingress/annotations/globalratelimit/main.go b/internal/ingress/annotations/globalratelimit/main.go deleted file mode 100644 index 0aec29f66..000000000 --- a/internal/ingress/annotations/globalratelimit/main.go +++ /dev/null @@ -1,179 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package globalratelimit - -import ( - "fmt" - "strings" - "time" - - networking "k8s.io/api/networking/v1" - "k8s.io/klog/v2" - - "k8s.io/ingress-nginx/internal/ingress/annotations/parser" - ing_errors "k8s.io/ingress-nginx/internal/ingress/errors" - "k8s.io/ingress-nginx/internal/ingress/resolver" - "k8s.io/ingress-nginx/internal/net" - "k8s.io/ingress-nginx/pkg/util/sets" -) - -const defaultKey = "$remote_addr" - -const ( - globalRateLimitAnnotation = "global-rate-limit" - globalRateLimitWindowAnnotation = "global-rate-limit-window" - globalRateLimitKeyAnnotation = "global-rate-limit-key" - globalRateLimitIgnoredCidrsAnnotation = "global-rate-limit-ignored-cidrs" -) - -var globalRateLimitAnnotationConfig = parser.Annotation{ - Group: "ratelimit", - Annotations: parser.AnnotationFields{ - globalRateLimitAnnotation: { - Validator: parser.ValidateInt, - Scope: parser.AnnotationScopeIngress, - Risk: parser.AnnotationRiskLow, - Documentation: `This annotation configures maximum allowed number of requests per window`, - }, - globalRateLimitWindowAnnotation: { - Validator: parser.ValidateDuration, - Scope: parser.AnnotationScopeIngress, - Risk: parser.AnnotationRiskLow, - Documentation: `Configures a time window (i.e 1m) that the limit is applied`, - }, - globalRateLimitKeyAnnotation: { - Validator: parser.ValidateRegex(parser.NGINXVariable, true), - Scope: parser.AnnotationScopeIngress, - Risk: parser.AnnotationRiskHigh, - Documentation: `This annotation Configures a key for counting the samples. Defaults to $remote_addr. - You can also combine multiple NGINX variables here, like ${remote_addr}-${http_x_api_client} which would mean the limit will be applied to - requests coming from the same API client (indicated by X-API-Client HTTP request header) with the same source IP address`, - }, - globalRateLimitIgnoredCidrsAnnotation: { - Validator: parser.ValidateCIDRs, - Scope: parser.AnnotationScopeIngress, - Risk: parser.AnnotationRiskMedium, - Documentation: `This annotation defines a comma separated list of IPs and CIDRs to match client IP against. - When there's a match request is not considered for rate limiting.`, - }, - }, -} - -// Config encapsulates all global rate limit attributes -type Config struct { - Namespace string `json:"namespace"` - Limit int `json:"limit"` - WindowSize int `json:"window-size"` - Key string `json:"key"` - IgnoredCIDRs []string `json:"ignored-cidrs"` -} - -// Equal tests for equality between two Config types -func (l *Config) Equal(r *Config) bool { - if l.Namespace != r.Namespace { - return false - } - if l.Limit != r.Limit { - return false - } - if l.WindowSize != r.WindowSize { - return false - } - if l.Key != r.Key { - return false - } - if len(l.IgnoredCIDRs) != len(r.IgnoredCIDRs) || !sets.StringElementsMatch(l.IgnoredCIDRs, r.IgnoredCIDRs) { - return false - } - - return true -} - -type globalratelimit struct { - r resolver.Resolver - annotationConfig parser.Annotation -} - -// NewParser creates a new globalratelimit annotation parser -func NewParser(r resolver.Resolver) parser.IngressAnnotation { - return globalratelimit{ - r: r, - annotationConfig: globalRateLimitAnnotationConfig, - } -} - -// Parse extracts globalratelimit annotations from the given ingress -// and returns them structured as Config type -func (a globalratelimit) Parse(ing *networking.Ingress) (interface{}, error) { - config := &Config{} - - limit, err := parser.GetIntAnnotation(globalRateLimitAnnotation, ing, a.annotationConfig.Annotations) - if err != nil && ing_errors.IsInvalidContent(err) { - return nil, err - } - rawWindowSize, err := parser.GetStringAnnotation(globalRateLimitWindowAnnotation, ing, a.annotationConfig.Annotations) - if err != nil && ing_errors.IsValidationError(err) { - return config, ing_errors.LocationDeniedError{ - Reason: fmt.Errorf("failed to parse 'global-rate-limit-window' value: %w", err), - } - } - - if limit == 0 || rawWindowSize == "" { - return config, nil - } - - windowSize, err := time.ParseDuration(rawWindowSize) - if err != nil { - return config, ing_errors.LocationDeniedError{ - Reason: fmt.Errorf("failed to parse 'global-rate-limit-window' value: %w", err), - } - } - - key, err := parser.GetStringAnnotation(globalRateLimitKeyAnnotation, ing, a.annotationConfig.Annotations) - if err != nil { - klog.Warningf("invalid %s, defaulting to %s", globalRateLimitKeyAnnotation, defaultKey) - } - if key == "" { - key = defaultKey - } - - rawIgnoredCIDRs, err := parser.GetStringAnnotation(globalRateLimitIgnoredCidrsAnnotation, ing, a.annotationConfig.Annotations) - if err != nil && ing_errors.IsInvalidContent(err) { - return nil, err - } - ignoredCIDRs, err := net.ParseCIDRs(rawIgnoredCIDRs) - if err != nil { - return nil, err - } - - config.Namespace = strings.ReplaceAll(string(ing.UID), "-", "") - config.Limit = limit - config.WindowSize = int(windowSize.Seconds()) - config.Key = key - config.IgnoredCIDRs = ignoredCIDRs - - return config, nil -} - -func (a globalratelimit) GetDocumentation() parser.AnnotationFields { - return a.annotationConfig.Annotations -} - -func (a globalratelimit) Validate(anns map[string]string) error { - maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRiskLevel) - return parser.CheckAnnotationRisk(anns, maxrisk, globalRateLimitAnnotationConfig.Annotations) -} diff --git a/internal/ingress/annotations/globalratelimit/main_test.go b/internal/ingress/annotations/globalratelimit/main_test.go deleted file mode 100644 index b1a7ab71b..000000000 --- a/internal/ingress/annotations/globalratelimit/main_test.go +++ /dev/null @@ -1,211 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package globalratelimit - -import ( - "encoding/json" - "fmt" - "testing" - - api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1" - meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "k8s.io/ingress-nginx/internal/ingress/annotations/parser" - ing_errors "k8s.io/ingress-nginx/internal/ingress/errors" - "k8s.io/ingress-nginx/internal/ingress/resolver" -) - -const ( - UID = "31285d47-b150-4dcf-bd6f-12c46d769f6e" - expectedUID = "31285d47b1504dcfbd6f12c46d769f6e" -) - -func buildIngress() *networking.Ingress { - defaultBackend := networking.IngressBackend{ - Service: &networking.IngressServiceBackend{ - Name: "default-backend", - Port: networking.ServiceBackendPort{ - Number: 80, - }, - }, - } - - return &networking.Ingress{ - ObjectMeta: meta_v1.ObjectMeta{ - Name: "foo", - Namespace: api.NamespaceDefault, - UID: UID, - }, - Spec: networking.IngressSpec{ - DefaultBackend: &networking.IngressBackend{ - Service: &networking.IngressServiceBackend{ - Name: "default-backend", - Port: networking.ServiceBackendPort{ - Number: 80, - }, - }, - }, - Rules: []networking.IngressRule{ - { - Host: "foo.bar.com", - IngressRuleValue: networking.IngressRuleValue{ - HTTP: &networking.HTTPIngressRuleValue{ - Paths: []networking.HTTPIngressPath{ - { - Path: "/foo", - Backend: defaultBackend, - }, - }, - }, - }, - }, - }, - }, - } -} - -type mockBackend struct { - resolver.Mock -} - -func TestGlobalRateLimiting(t *testing.T) { - ing := buildIngress() - - annRateLimit := parser.GetAnnotationWithPrefix("global-rate-limit") - annRateLimitWindow := parser.GetAnnotationWithPrefix("global-rate-limit-window") - annRateLimitKey := parser.GetAnnotationWithPrefix("global-rate-limit-key") - annRateLimitIgnoredCIDRs := parser.GetAnnotationWithPrefix("global-rate-limit-ignored-cidrs") - - testCases := []struct { - title string - annotations map[string]string - expectedConfig *Config - expectedErr error - }{ - { - "no annotation", - nil, - &Config{}, - nil, - }, - { - "minimum required annotations", - map[string]string{ - annRateLimit: "100", - annRateLimitWindow: "2m", - }, - &Config{ - Namespace: expectedUID, - Limit: 100, - WindowSize: 120, - Key: "$remote_addr", - IgnoredCIDRs: make([]string, 0), - }, - nil, - }, - { - "global-rate-limit-key annotation", - map[string]string{ - annRateLimit: "100", - annRateLimitWindow: "2m", - annRateLimitKey: "$http_x_api_user", - }, - &Config{ - Namespace: expectedUID, - Limit: 100, - WindowSize: 120, - Key: "$http_x_api_user", - IgnoredCIDRs: make([]string, 0), - }, - nil, - }, - { - "global-rate-limit-ignored-cidrs annotation", - map[string]string{ - annRateLimit: "100", - annRateLimitWindow: "2m", - annRateLimitKey: "$http_x_api_user", - annRateLimitIgnoredCIDRs: "127.0.0.1, 200.200.24.0/24", - }, - &Config{ - Namespace: expectedUID, - Limit: 100, - WindowSize: 120, - Key: "$http_x_api_user", - IgnoredCIDRs: []string{"127.0.0.1", "200.200.24.0/24"}, - }, - nil, - }, - { - "global-rate-limit-complex-key", - map[string]string{ - annRateLimit: "100", - annRateLimitWindow: "2m", - annRateLimitKey: "${http_x_api_user}${otherinfo}", - }, - &Config{ - Namespace: expectedUID, - Limit: 100, - WindowSize: 120, - Key: "${http_x_api_user}${otherinfo}", - IgnoredCIDRs: make([]string, 0), - }, - nil, - }, - { - "incorrect duration for window", - map[string]string{ - annRateLimit: "100", - annRateLimitWindow: "2mb", - annRateLimitKey: "$http_x_api_user", - }, - &Config{}, - ing_errors.ValidationError{ - Reason: fmt.Errorf("failed to parse 'global-rate-limit-window' value: annotation nginx.ingress.kubernetes.io/global-rate-limit-window contains invalid value"), - }, - }, - } - - for _, testCase := range testCases { - ing.SetAnnotations(testCase.annotations) - - i, actualErr := NewParser(mockBackend{}).Parse(ing) - if (testCase.expectedErr == nil || actualErr == nil) && testCase.expectedErr != actualErr { - t.Errorf("%s expected error '%v' but got '%v'", testCase.title, testCase.expectedErr, actualErr) - } else if testCase.expectedErr != nil && actualErr != nil && - testCase.expectedErr.Error() != actualErr.Error() { - t.Errorf("expected error '%v' but got '%v'", testCase.expectedErr, actualErr) - } - - actualConfig, ok := i.(*Config) - if !ok { - t.Errorf("expected Config type but got %T", i) - } - if !testCase.expectedConfig.Equal(actualConfig) { - expectedJSON, err := json.Marshal(testCase.expectedConfig) - if err != nil { - t.Errorf("failed to marshal expected config: %v", err) - } - actualJSON, err := json.Marshal(actualConfig) - if err != nil { - t.Errorf("failed to marshal actual config: %v", err) - } - t.Errorf("%v: expected config '%s' but got '%s'", testCase.title, expectedJSON, actualJSON) - } - } -} diff --git a/internal/ingress/annotations/loadbalancing/main.go b/internal/ingress/annotations/loadbalancing/main.go index ee89d2c1b..0e5ca8bd8 100644 --- a/internal/ingress/annotations/loadbalancing/main.go +++ b/internal/ingress/annotations/loadbalancing/main.go @@ -23,22 +23,22 @@ import ( "k8s.io/ingress-nginx/internal/ingress/resolver" ) -// LB Alghorithms are defined in https://github.com/kubernetes/ingress-nginx/blob/d3e75b056f77be54e01bdb18675f1bb46caece31/rootfs/etc/nginx/lua/balancer.lua#L28 +// LB Algorithms are defined in https://github.com/kubernetes/ingress-nginx/blob/d3e75b056f77be54e01bdb18675f1bb46caece31/rootfs/etc/nginx/lua/balancer.lua#L28 const ( - loadBalanceAlghoritmAnnotation = "load-balance" + loadBalanceAlgorithmAnnotation = "load-balance" ) -var loadBalanceAlghoritms = []string{"round_robin", "chash", "chashsubset", "sticky_balanced", "sticky_persistent", "ewma"} +var loadBalanceAlgorithms = []string{"round_robin", "chash", "chashsubset", "sticky_balanced", "sticky_persistent", "ewma"} var loadBalanceAnnotations = parser.Annotation{ Group: "backend", Annotations: parser.AnnotationFields{ - loadBalanceAlghoritmAnnotation: { - Validator: parser.ValidateOptions(loadBalanceAlghoritms, true, true), + loadBalanceAlgorithmAnnotation: { + Validator: parser.ValidateOptions(loadBalanceAlgorithms, true, true), Scope: parser.AnnotationScopeLocation, Risk: parser.AnnotationRiskLow, - Documentation: `This annotation allows setting the load balancing alghorithm that should be used. If none is specified, defaults to + Documentation: `This annotation allows setting the load balancing algorithm that should be used. If none is specified, defaults to the default configured by Ingress admin, otherwise to round_robin`, }, }, @@ -61,7 +61,7 @@ func NewParser(r resolver.Resolver) parser.IngressAnnotation { // used to indicate if the location/s contains a fragment of // configuration to be included inside the paths of the rules func (a loadbalancing) Parse(ing *networking.Ingress) (interface{}, error) { - return parser.GetStringAnnotation(loadBalanceAlghoritmAnnotation, ing, a.annotationConfig.Annotations) + return parser.GetStringAnnotation(loadBalanceAlgorithmAnnotation, ing, a.annotationConfig.Annotations) } func (a loadbalancing) GetDocumentation() parser.AnnotationFields { diff --git a/internal/ingress/annotations/mirror/main_test.go b/internal/ingress/annotations/mirror/main_test.go index 1f6b44d61..805f1ef6d 100644 --- a/internal/ingress/annotations/mirror/main_test.go +++ b/internal/ingress/annotations/mirror/main_test.go @@ -90,7 +90,7 @@ func TestParse(t *testing.T) { Target: "http://some.test.env.com:2121/$someparam=1&$someotherparam=2", Host: "some.test.env.com", }}, - {map[string]string{backendURL: "http://some.test.env.com", host: "someInvalidParm.%^&*()_=!@#'\""}, &Config{ + {map[string]string{backendURL: "http://some.test.env.com", host: "someInvalidParam.%^&*()_=!@#'\""}, &Config{ Source: ngxURI, RequestBody: "on", Target: "http://some.test.env.com", diff --git a/internal/ingress/annotations/parser/main.go b/internal/ingress/annotations/parser/main.go index 554ad9dde..3137afbfd 100644 --- a/internal/ingress/annotations/parser/main.go +++ b/internal/ingress/annotations/parser/main.go @@ -210,6 +210,21 @@ func StringRiskToRisk(risk string) AnnotationRisk { } } +func (a AnnotationRisk) ToString() string { + switch a { + case AnnotationRiskCritical: + return "Critical" + case AnnotationRiskHigh: + return "High" + case AnnotationRiskMedium: + return "Medium" + case AnnotationRiskLow: + return "Low" + default: + return "Unknown" + } +} + func normalizeString(input string) string { trimmedContent := []string{} for _, line := range strings.Split(input, "\n") { diff --git a/internal/ingress/annotations/parser/validators.go b/internal/ingress/annotations/parser/validators.go index ffb4d9ba9..3c724a311 100644 --- a/internal/ingress/annotations/parser/validators.go +++ b/internal/ingress/annotations/parser/validators.go @@ -44,7 +44,7 @@ var ( alphaNumericChars = `\-\.\_\~a-zA-Z0-9\/:` extendedAlphaNumeric = alphaNumericChars + ", " regexEnabledChars = regexp.QuoteMeta(`^$[](){}*+?|&=\`) - urlEnabledChars = regexp.QuoteMeta(`:?&=`) + urlEnabledChars = regexp.QuoteMeta(`,:?&=`) ) // IsValidRegex checks if the tested string can be used as a regex, but without any weird character. @@ -79,6 +79,8 @@ var ( // URLWithNginxVariableRegex defines a url that can contain nginx variables. // It is a risky operation URLWithNginxVariableRegex = regexp.MustCompile("^[" + extendedAlphaNumeric + urlEnabledChars + "$]*$") + // MaliciousRegex defines chars that are known to inject RCE + MaliciousRegex = regexp.MustCompile(`\r|\n`) ) // ValidateArrayOfServerName validates if all fields on a Server name annotation are @@ -113,6 +115,10 @@ func ValidateRegex(regex *regexp.Regexp, removeSpace bool) AnnotationValidator { if !regex.MatchString(s) { return fmt.Errorf("value %s is invalid", s) } + if MaliciousRegex.MatchString(s) { + return fmt.Errorf("value %s contains malicious string", s) + } + return nil } } diff --git a/internal/ingress/annotations/parser/validators_test.go b/internal/ingress/annotations/parser/validators_test.go index ed8449452..49923ba76 100644 --- a/internal/ingress/annotations/parser/validators_test.go +++ b/internal/ingress/annotations/parser/validators_test.go @@ -55,11 +55,21 @@ func TestValidateArrayOfServerName(t *testing.T) { value: "*.so*mething.com,bla.com", wantErr: false, }, + { + name: "should allow comma separated query params", + value: "https://oauth.example/oauth2/auth?allowed_groups=gid1,gid2", + wantErr: false, + }, { name: "should deny names with weird characters", value: "something.com,lolo;xpto.com,nothing.com", wantErr: true, }, + { + name: "should deny names with malicous chars", + value: "http://something.com/#;\nournewinjection", + wantErr: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/internal/ingress/annotations/proxy/main.go b/internal/ingress/annotations/proxy/main.go index 9d2646261..aaa093eaf 100644 --- a/internal/ingress/annotations/proxy/main.go +++ b/internal/ingress/annotations/proxy/main.go @@ -31,6 +31,7 @@ const ( proxyReadTimeoutAnnotation = "proxy-read-timeout" proxyBuffersNumberAnnotation = "proxy-buffers-number" proxyBufferSizeAnnotation = "proxy-buffer-size" + proxyBusyBuffersSizeAnnotation = "proxy-busy-buffers-size" proxyCookiePathAnnotation = "proxy-cookie-path" proxyCookieDomainAnnotation = "proxy-cookie-domain" proxyBodySizeAnnotation = "proxy-body-size" @@ -82,6 +83,12 @@ var proxyAnnotations = parser.Annotation{ Documentation: `This annotation sets the size of the buffer proxy_buffer_size used for reading the first part of the response received from the proxied server. By default proxy buffer size is set as "4k".`, }, + proxyBusyBuffersSizeAnnotation: { + Validator: parser.ValidateRegex(parser.SizeRegex, true), + Scope: parser.AnnotationScopeLocation, + Risk: parser.AnnotationRiskLow, + Documentation: `This annotation limits the total size of buffers that can be busy sending a response to the client while the response is not yet fully read. By default proxy busy buffers size is set as "8k".`, + }, proxyCookiePathAnnotation: { Validator: parser.ValidateRegex(parser.URLIsValidRegex, true), Scope: parser.AnnotationScopeLocation, @@ -167,6 +174,7 @@ type Config struct { ReadTimeout int `json:"readTimeout"` BuffersNumber int `json:"buffersNumber"` BufferSize string `json:"bufferSize"` + BusyBuffersSize string `json:"busyBuffersSize"` CookieDomain string `json:"cookieDomain"` CookiePath string `json:"cookiePath"` NextUpstream string `json:"nextUpstream"` @@ -206,6 +214,9 @@ func (l1 *Config) Equal(l2 *Config) bool { if l1.BufferSize != l2.BufferSize { return false } + if l1.BusyBuffersSize != l2.BusyBuffersSize { + return false + } if l1.CookieDomain != l2.CookieDomain { return false } @@ -290,6 +301,11 @@ func (a proxy) Parse(ing *networking.Ingress) (interface{}, error) { config.BufferSize = defBackend.ProxyBufferSize } + config.BusyBuffersSize, err = parser.GetStringAnnotation(proxyBusyBuffersSizeAnnotation, ing, a.annotationConfig.Annotations) + if err != nil { + config.BusyBuffersSize = defBackend.ProxyBusyBuffersSize + } + config.CookiePath, err = parser.GetStringAnnotation(proxyCookiePathAnnotation, ing, a.annotationConfig.Annotations) if err != nil { config.CookiePath = defBackend.ProxyCookiePath diff --git a/internal/ingress/annotations/proxy/main_test.go b/internal/ingress/annotations/proxy/main_test.go index 9446ae970..b6ce07fb2 100644 --- a/internal/ingress/annotations/proxy/main_test.go +++ b/internal/ingress/annotations/proxy/main_test.go @@ -88,6 +88,7 @@ func (m mockBackend) GetDefaultBackend() defaults.Backend { ProxyReadTimeout: 20, ProxyBuffersNumber: 4, ProxyBufferSize: "10k", + ProxyBusyBuffersSize: "15k", ProxyBodySize: "3k", ProxyNextUpstream: "error", ProxyNextUpstreamTimeout: 0, @@ -108,6 +109,7 @@ func TestProxy(t *testing.T) { data[parser.GetAnnotationWithPrefix("proxy-read-timeout")] = "3" data[parser.GetAnnotationWithPrefix("proxy-buffers-number")] = "8" data[parser.GetAnnotationWithPrefix("proxy-buffer-size")] = "1k" + data[parser.GetAnnotationWithPrefix("proxy-busy-buffers-size")] = "4k" data[parser.GetAnnotationWithPrefix("proxy-body-size")] = "2k" data[parser.GetAnnotationWithPrefix("proxy-next-upstream")] = off data[parser.GetAnnotationWithPrefix("proxy-next-upstream-timeout")] = "5" @@ -141,6 +143,9 @@ func TestProxy(t *testing.T) { if p.BufferSize != "1k" { t.Errorf("expected 1k as buffer-size but returned %v", p.BufferSize) } + if p.BusyBuffersSize != "4k" { + t.Errorf("expected 4k as busy-buffers-size but returned %v", p.BusyBuffersSize) + } if p.BodySize != "2k" { t.Errorf("expected 2k as body-size but returned %v", p.BodySize) } @@ -176,6 +181,7 @@ func TestProxyComplex(t *testing.T) { data[parser.GetAnnotationWithPrefix("proxy-read-timeout")] = "3" data[parser.GetAnnotationWithPrefix("proxy-buffers-number")] = "8" data[parser.GetAnnotationWithPrefix("proxy-buffer-size")] = "1k" + data[parser.GetAnnotationWithPrefix("proxy-busy-buffers-size")] = "4k" data[parser.GetAnnotationWithPrefix("proxy-body-size")] = "2k" data[parser.GetAnnotationWithPrefix("proxy-next-upstream")] = "error http_502" data[parser.GetAnnotationWithPrefix("proxy-next-upstream-timeout")] = "5" @@ -209,6 +215,9 @@ func TestProxyComplex(t *testing.T) { if p.BufferSize != "1k" { t.Errorf("expected 1k as buffer-size but returned %v", p.BufferSize) } + if p.BusyBuffersSize != "4k" { + t.Errorf("expected 4k as buffer-size but returned %v", p.BusyBuffersSize) + } if p.BodySize != "2k" { t.Errorf("expected 2k as body-size but returned %v", p.BodySize) } @@ -264,6 +273,9 @@ func TestProxyWithNoAnnotation(t *testing.T) { if p.BufferSize != "10k" { t.Errorf("expected 10k as buffer-size but returned %v", p.BufferSize) } + if p.BusyBuffersSize != "15k" { + t.Errorf("expected 15k as buffer-size but returned %v", p.BusyBuffersSize) + } if p.BodySize != "3k" { t.Errorf("expected 3k as body-size but returned %v", p.BodySize) } diff --git a/internal/ingress/annotations/redirect/redirect.go b/internal/ingress/annotations/redirect/redirect.go index e774b2fe8..edc3d279c 100644 --- a/internal/ingress/annotations/redirect/redirect.go +++ b/internal/ingress/annotations/redirect/redirect.go @@ -28,20 +28,26 @@ import ( "k8s.io/ingress-nginx/internal/ingress/resolver" ) -const defaultPermanentRedirectCode = http.StatusMovedPermanently +const ( + defaultPermanentRedirectCode = http.StatusMovedPermanently + defaultTemporalRedirectCode = http.StatusFound +) // Config returns the redirect configuration for an Ingress rule type Config struct { URL string `json:"url"` Code int `json:"code"` FromToWWW bool `json:"fromToWWW"` + Relative bool `json:"relative"` } const ( fromToWWWRedirAnnotation = "from-to-www-redirect" temporalRedirectAnnotation = "temporal-redirect" + temporalRedirectAnnotationCode = "temporal-redirect-code" permanentRedirectAnnotation = "permanent-redirect" permanentRedirectAnnotationCode = "permanent-redirect-code" + relativeRedirectsAnnotation = "relative-redirects" ) var redirectAnnotations = parser.Annotation{ @@ -60,6 +66,12 @@ var redirectAnnotations = parser.Annotation{ Documentation: `This annotation allows you to return a temporal redirect (Return Code 302) instead of sending data to the upstream. For example setting this annotation to https://www.google.com would redirect everything to Google with a Return Code of 302 (Moved Temporarily).`, }, + temporalRedirectAnnotationCode: { + Validator: parser.ValidateInt, + Scope: parser.AnnotationScopeLocation, + Risk: parser.AnnotationRiskLow, // Low, as it allows just a set of options + Documentation: `This annotation allows you to modify the status code used for temporal redirects.`, + }, permanentRedirectAnnotation: { Validator: parser.ValidateRegex(parser.URLIsValidRegex, false), Scope: parser.AnnotationScopeLocation, @@ -73,6 +85,12 @@ var redirectAnnotations = parser.Annotation{ Risk: parser.AnnotationRiskLow, // Low, as it allows just a set of options Documentation: `This annotation allows you to modify the status code used for permanent redirects.`, }, + relativeRedirectsAnnotation: { + Validator: parser.ValidateBool, + Scope: parser.AnnotationScopeLocation, + Risk: parser.AnnotationRiskLow, + Documentation: `If enabled, redirects issued by nginx will be relative. See https://nginx.org/en/docs/http/ngx_http_core_module.html#absolute_redirect`, + }, }, } @@ -99,20 +117,35 @@ func (r redirect) Parse(ing *networking.Ingress) (interface{}, error) { return nil, err } + rr, err := parser.GetBoolAnnotation(relativeRedirectsAnnotation, ing, r.annotationConfig.Annotations) + if err != nil && !errors.IsMissingAnnotations(err) { + return nil, err + } + tr, err := parser.GetStringAnnotation(temporalRedirectAnnotation, ing, r.annotationConfig.Annotations) if err != nil && !errors.IsMissingAnnotations(err) { return nil, err } if tr != "" { + trc, err := parser.GetIntAnnotation(temporalRedirectAnnotationCode, ing, r.annotationConfig.Annotations) + if err != nil && !errors.IsMissingAnnotations(err) { + return nil, err + } + + if trc < http.StatusMultipleChoices || trc > http.StatusTemporaryRedirect { + trc = defaultTemporalRedirectCode + } + if err := isValidURL(tr); err != nil { return nil, err } return &Config{ URL: tr, - Code: http.StatusFound, + Code: trc, FromToWWW: r3w, + Relative: rr, }, nil } @@ -135,6 +168,13 @@ func (r redirect) Parse(ing *networking.Ingress) (interface{}, error) { URL: pr, Code: prc, FromToWWW: r3w, + Relative: rr, + }, nil + } + + if rr { + return &Config{ + Relative: rr, }, nil } @@ -158,6 +198,9 @@ func (r1 *Config) Equal(r2 *Config) bool { if r1.FromToWWW != r2.FromToWWW { return false } + if r1.Relative != r2.Relative { + return false + } return true } diff --git a/internal/ingress/annotations/redirect/redirect_test.go b/internal/ingress/annotations/redirect/redirect_test.go index bd2f98211..f4734ae5b 100644 --- a/internal/ingress/annotations/redirect/redirect_test.go +++ b/internal/ingress/annotations/redirect/redirect_test.go @@ -103,7 +103,7 @@ func TestPermanentRedirectWithCustomCode(t *testing.T) { } } -func TestTemporalRedirect(t *testing.T) { +func TestTemporalRedirectWithDefaultCode(t *testing.T) { rp := NewParser(resolver.Mock{}) if rp == nil { t.Fatalf("Expected a parser.IngressAnnotation but returned nil") @@ -128,10 +128,49 @@ func TestTemporalRedirect(t *testing.T) { t.Errorf("Expected %v as redirect but returned %s", defRedirectURL, redirect.URL) } if redirect.Code != http.StatusFound { - t.Errorf("Expected %v as redirect to have a code %d but had %d", defRedirectURL, defaultPermanentRedirectCode, redirect.Code) + t.Errorf("Expected %v as redirect to have a code %d but had %d", defRedirectURL, http.StatusFound, redirect.Code) } - if redirect.FromToWWW != true { - t.Errorf("Expected %v as redirect to have from-to-www as %v but got %v", defRedirectURL, true, redirect.FromToWWW) +} + +func TestTemporalRedirectWithCustomCode(t *testing.T) { + rp := NewParser(resolver.Mock{}) + if rp == nil { + t.Fatalf("Expected a parser.IngressAnnotation but returned nil") + } + + testCases := map[string]struct { + input int + expectOutput int + }{ + "valid code": {http.StatusTemporaryRedirect, http.StatusTemporaryRedirect}, + "invalid code": {http.StatusTeapot, http.StatusFound}, + } + + for n, tc := range testCases { + t.Run(n, func(t *testing.T) { + ing := new(networking.Ingress) + + data := make(map[string]string, 2) + data[parser.GetAnnotationWithPrefix(fromToWWWRedirAnnotation)] = "true" + data[parser.GetAnnotationWithPrefix(temporalRedirectAnnotation)] = defRedirectURL + data[parser.GetAnnotationWithPrefix(temporalRedirectAnnotationCode)] = strconv.Itoa(tc.input) + ing.SetAnnotations(data) + + i, err := rp.Parse(ing) + if err != nil { + t.Errorf("Unexpected error with ingress: %v", err) + } + redirect, ok := i.(*Config) + if !ok { + t.Errorf("Expected a Redirect type") + } + if redirect.URL != defRedirectURL { + t.Errorf("Expected %v as redirect but returned %s", defRedirectURL, redirect.URL) + } + if redirect.Code != tc.expectOutput { + t.Errorf("Expected %v as redirect to have a code %d but had %d", defRedirectURL, tc.expectOutput, redirect.Code) + } + }) } } @@ -154,3 +193,22 @@ func TestIsValidURL(t *testing.T) { t.Errorf("expected nil but got %v", err) } } + +func TestParseAnnotations(t *testing.T) { + ing := new(networking.Ingress) + + data := map[string]string{} + data[parser.GetAnnotationWithPrefix(relativeRedirectsAnnotation)] = "true" + ing.SetAnnotations(data) + + _, err := NewParser(&resolver.Mock{}).Parse(ing) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + + // test ingress using the annotation without a TLS section + _, err = NewParser(&resolver.Mock{}).Parse(ing) + if err != nil { + t.Errorf("unexpected error parsing ingress with relative-redirects") + } +} diff --git a/internal/ingress/annotations/serversnippet/main.go b/internal/ingress/annotations/serversnippet/main.go index aa15608d0..bce764e69 100644 --- a/internal/ingress/annotations/serversnippet/main.go +++ b/internal/ingress/annotations/serversnippet/main.go @@ -33,7 +33,7 @@ var serverSnippetAnnotations = parser.Annotation{ serverSnippetAnnotation: { Validator: parser.ValidateNull, Scope: parser.AnnotationScopeIngress, - Risk: parser.AnnotationRiskCritical, // Critical, this annotation is not validated at all and allows arbitrary configutations + Risk: parser.AnnotationRiskCritical, // Critical, this annotation is not validated at all and allows arbitrary configurations Documentation: `This annotation allows setting a custom NGINX configuration on a server block. This annotation does not contain any validation and it's usage is not recommended!`, }, }, diff --git a/internal/ingress/annotations/serviceupstream/main.go b/internal/ingress/annotations/serviceupstream/main.go index d1851bc7b..7819d87d8 100644 --- a/internal/ingress/annotations/serviceupstream/main.go +++ b/internal/ingress/annotations/serviceupstream/main.go @@ -34,7 +34,7 @@ var serviceUpstreamAnnotations = parser.Annotation{ serviceUpstreamAnnotation: { Validator: parser.ValidateBool, Scope: parser.AnnotationScopeIngress, - Risk: parser.AnnotationRiskLow, // Critical, this annotation is not validated at all and allows arbitrary configutations + Risk: parser.AnnotationRiskLow, // Critical, this annotation is not validated at all and allows arbitrary configurations Documentation: `This annotation makes NGINX use Service's Cluster IP and Port instead of Endpoints as the backend endpoints`, }, }, diff --git a/internal/ingress/annotations/snippet/main.go b/internal/ingress/annotations/snippet/main.go index 2406093c5..c2df84cdd 100644 --- a/internal/ingress/annotations/snippet/main.go +++ b/internal/ingress/annotations/snippet/main.go @@ -33,7 +33,7 @@ var configurationSnippetAnnotations = parser.Annotation{ configurationSnippetAnnotation: { Validator: parser.ValidateNull, Scope: parser.AnnotationScopeLocation, - Risk: parser.AnnotationRiskCritical, // Critical, this annotation is not validated at all and allows arbitrary configutations + Risk: parser.AnnotationRiskCritical, // Critical, this annotation is not validated at all and allows arbitrary configurations Documentation: `This annotation allows setting a custom NGINX configuration on a location block. This annotation does not contain any validation and it's usage is not recommended!`, }, }, diff --git a/internal/ingress/annotations/streamsnippet/main.go b/internal/ingress/annotations/streamsnippet/main.go index 71ff3b140..7743d3fee 100644 --- a/internal/ingress/annotations/streamsnippet/main.go +++ b/internal/ingress/annotations/streamsnippet/main.go @@ -33,7 +33,7 @@ var streamSnippetAnnotations = parser.Annotation{ streamSnippetAnnotation: { Validator: parser.ValidateNull, Scope: parser.AnnotationScopeIngress, - Risk: parser.AnnotationRiskCritical, // Critical, this annotation is not validated at all and allows arbitrary configutations + Risk: parser.AnnotationRiskCritical, // Critical, this annotation is not validated at all and allows arbitrary configurations Documentation: `This annotation allows setting a custom NGINX configuration on a stream block. This annotation does not contain any validation and it's usage is not recommended!`, }, }, diff --git a/internal/ingress/controller/config/config.go b/internal/ingress/controller/config/config.go index 3098f5cba..beac1405d 100644 --- a/internal/ingress/controller/config/config.go +++ b/internal/ingress/controller/config/config.go @@ -20,9 +20,8 @@ import ( "strconv" "time" - "k8s.io/klog/v2" - apiv1 "k8s.io/api/core/v1" + "k8s.io/klog/v2" "k8s.io/ingress-nginx/internal/ingress/defaults" "k8s.io/ingress-nginx/pkg/apis/ingress" @@ -120,7 +119,7 @@ type Configuration struct { // By default this is disabled AllowBackendServerHeader bool `json:"allow-backend-server-header"` - // AccessLogParams sets additionals params for access_log + // AccessLogParams sets additional params for access_log // http://nginx.org/en/docs/http/ngx_http_log_module.html#access_log // By default it's empty AccessLogParams string `json:"access-log-params,omitempty"` @@ -319,11 +318,6 @@ type Configuration struct { NginxStatusIpv4Whitelist []string `json:"nginx-status-ipv4-whitelist,omitempty"` NginxStatusIpv6Whitelist []string `json:"nginx-status-ipv6-whitelist,omitempty"` - // Plugins configures plugins to use placed in the directory /etc/nginx/lua/plugins. - // Every plugin has to have main.lua in the root. Every plugin has to bundle all of its dependencies. - // The execution order follows the definition. - Plugins []string `json:"plugins,omitempty"` - // If UseProxyProtocol is enabled ProxyRealIPCIDR defines the default the IP/network address // of your external load balancer ProxyRealIPCIDR []string `json:"proxy-real-ip-cidr,omitempty"` @@ -424,7 +418,7 @@ type Configuration struct { // Example '60s' ProxyProtocolHeaderTimeout time.Duration `json:"proxy-protocol-header-timeout,omitempty"` - // Enables or disables the directive aio_write that writes files files asynchronously + // Enables or disables the directive aio_write that writes files asynchronously // https://nginx.org/en/docs/http/ngx_http_core_module.html#aio_write EnableAioWrite bool `json:"enable-aio-write,omitempty"` @@ -436,6 +430,10 @@ type Configuration struct { // By default this is disabled UseGeoIP2 bool `json:"use-geoip2,omitempty"` + // GeoIP2AutoReloadMinutes enables autoreload on geoip2 setting the interval in minutes + // By default this is disabled using 0 + GeoIP2AutoReloadMinutes int `json:"geoip2-autoreload-in-minutes,omitempty"` + // Enables or disables the use of the NGINX Brotli Module for compression // https://github.com/google/ngx_brotli EnableBrotli bool `json:"enable-brotli,omitempty"` @@ -474,6 +472,13 @@ type Configuration struct { // http://nginx.org/en/docs/ngx_core_module.html#worker_processes WorkerProcesses string `json:"worker-processes,omitempty"` + // Defines whether multiple concurrent reloads of worker processes should occur. + // Set this to false to prevent more than n x 2 workers to exist at any time, to avoid potential OOM situations and high CPU load + // With this setting on false, configuration changes in the queue will be re-queued with an exponential backoff, until the number of worker process is the expected value. + // By default new worker processes are spawned every time there's a change that cannot be applied dynamically with no upper limit to the number of running workers + // http://nginx.org/en/docs/ngx_core_module.html#worker_processes + WorkerSerialReloads bool `json:"enable-serial-reloads,omitempty"` + // Defines a timeout for a graceful shutdown of worker processes // http://nginx.org/en/docs/ngx_core_module.html#worker_shutdown_timeout WorkerShutdownTimeout string `json:"worker-shutdown-timeout,omitempty"` @@ -544,6 +549,10 @@ type Configuration struct { // https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_intercept_errors DisableProxyInterceptErrors bool `json:"disable-proxy-intercept-errors,omitempty"` + // Disable absolute redirects and enables relative redirects. + // https://nginx.org/en/docs/http/ngx_http_core_module.html#absolute_redirect + RelativeRedirects bool `json:"relative-redirects"` + // Sets the ipv4 addresses on which the server will accept requests. BindAddressIpv4 []string `json:"bind-address-ipv4,omitempty"` @@ -607,7 +616,7 @@ type Configuration struct { // Default: 0.01 OtelSamplerRatio float32 `json:"otel-sampler-ratio"` - // OtelSamplerParentBased specifies the parent based sampler to be use for any traces created + // OtelSamplerParentBased specifies the parent based sampler to be used for any traces created // Default: true OtelSamplerParentBased bool `json:"otel-sampler-parent-based"` @@ -704,7 +713,7 @@ type Configuration struct { DefaultSSLCertificate *ingress.SSLCert `json:"-"` // ProxySSLLocationOnly controls whether the proxy-ssl parameters defined in the - // proxy-ssl-* annotations are applied on on location level only in the nginx.conf file + // proxy-ssl-* annotations are applied on location level only in the nginx.conf file // Default is that those are applied on server level, too ProxySSLLocationOnly bool `json:"proxy-ssl-location-only"` @@ -713,31 +722,6 @@ type Configuration struct { // Default: text/html DefaultType string `json:"default-type"` - // GlobalRateLimitMemcachedHost configures memcached host. - GlobalRateLimitMemcachedHost string `json:"global-rate-limit-memcached-host"` - - // GlobalRateLimitMemcachedPort configures memcached port. - GlobalRateLimitMemcachedPort int `json:"global-rate-limit-memcached-port"` - - // GlobalRateLimitMemcachedConnectTimeout configures timeout when connecting to memcached. - // The unit is millisecond. - GlobalRateLimitMemcachedConnectTimeout int `json:"global-rate-limit-memcached-connect-timeout"` - - // GlobalRateLimitMemcachedMaxIdleTimeout configured how long connections - // should be kept alive in idle state. The unit is millisecond. - GlobalRateLimitMemcachedMaxIdleTimeout int `json:"global-rate-limit-memcached-max-idle-timeout"` - - // GlobalRateLimitMemcachedPoolSize configures how many connections - // should be kept alive in the pool. - // Note that this is per NGINX worker. Make sure your memcached server can - // handle `MemcachedPoolSize * * ` - // simultaneous connections. - GlobalRateLimitMemcachedPoolSize int `json:"global-rate-limit-memcached-pool-size"` - - // GlobalRateLimitStatusCode determines the HTTP status code to return - // when limit is exceeding during global rate limiting. - GlobalRateLimitStatusCode int `json:"global-rate-limit-status-code"` - // DebugConnections Enables debugging log for selected client connections // http://nginx.org/en/docs/ngx_core_module.html#debug_connection // Default: "" @@ -748,6 +732,11 @@ type Configuration struct { // alphanumeric chars, "-", "_", "/".In case of additional characters, // like used on Rewrite configurations the user should use pathType as ImplementationSpecific StrictValidatePathType bool `json:"strict-validate-path-type"` + + // GRPCBufferSizeKb Sets the size of the buffer used for reading the response received + // from the gRPC server. The response is passed to the client synchronously, + // as soon as it is received. + GRPCBufferSizeKb int `json:"grpc-buffer-size-kb"` } // NewDefault returns the default nginx configuration @@ -766,10 +755,10 @@ func NewDefault() Configuration { cfg := Configuration{ AllowSnippetAnnotations: false, - AllowCrossNamespaceResources: true, + AllowCrossNamespaceResources: false, AllowBackendServerHeader: false, AnnotationValueWordBlocklist: "", - AnnotationsRiskLevel: "Critical", + AnnotationsRiskLevel: "High", AccessLogPath: "/var/log/nginx/access.log", AccessLogParams: "", EnableAccessLogForDefaultBackend: false, @@ -841,12 +830,15 @@ func NewDefault() Configuration { EnableAioWrite: true, UseGzip: false, UseGeoIP2: false, + GeoIP2AutoReloadMinutes: 0, WorkerProcesses: strconv.Itoa(runtime.NumCPU()), + WorkerSerialReloads: false, WorkerShutdownTimeout: "240s", VariablesHashBucketSize: 256, VariablesHashMaxSize: 2048, UseHTTP2: true, DisableProxyInterceptErrors: false, + RelativeRedirects: false, ProxyStreamTimeout: "600s", ProxyStreamNextUpstream: true, ProxyStreamNextUpstreamTimeout: "600s", @@ -858,6 +850,7 @@ func NewDefault() Configuration { ProxySendTimeout: 60, ProxyBuffersNumber: 4, ProxyBufferSize: "4k", + ProxyBusyBuffersSize: "8k", ProxyCookieDomain: "off", ProxyCookiePath: "off", ProxyNextUpstream: "error timeout", @@ -870,6 +863,7 @@ func NewDefault() Configuration { SSLRedirect: true, CustomHTTPErrors: []int{}, DisableProxyInterceptErrors: false, + RelativeRedirects: false, DenylistSourceRange: []string{}, WhitelistSourceRange: []string{}, SkipAccessLogURLs: []string{}, @@ -879,39 +873,36 @@ func NewDefault() Configuration { ProxyHTTPVersion: "1.1", ProxyMaxTempFileSize: "1024m", ServiceUpstream: false, + AllowedResponseHeaders: []string{}, }, - UpstreamKeepaliveConnections: 320, - UpstreamKeepaliveTime: "1h", - UpstreamKeepaliveTimeout: 60, - UpstreamKeepaliveRequests: 10000, - LimitConnZoneVariable: defaultLimitConnZoneVariable, - BindAddressIpv4: defBindAddress, - BindAddressIpv6: defBindAddress, - OpentelemetryTrustIncomingSpan: true, - OpentelemetryConfig: "/etc/ingress-controller/telemetry/opentelemetry.toml", - OtlpCollectorPort: "4317", - OtelServiceName: "nginx", - OtelSampler: "AlwaysOn", - OtelSamplerRatio: 0.01, - OtelSamplerParentBased: true, - OtelScheduleDelayMillis: 5000, - OtelMaxExportBatchSize: 512, - OtelMaxQueueSize: 2048, - LimitReqStatusCode: 503, - LimitConnStatusCode: 503, - SyslogPort: 514, - NoTLSRedirectLocations: "/.well-known/acme-challenge", - NoAuthLocations: "/.well-known/acme-challenge", - GlobalExternalAuth: defGlobalExternalAuth, - ProxySSLLocationOnly: false, - DefaultType: "text/html", - GlobalRateLimitMemcachedPort: 11211, - GlobalRateLimitMemcachedConnectTimeout: 50, - GlobalRateLimitMemcachedMaxIdleTimeout: 10000, - GlobalRateLimitMemcachedPoolSize: 50, - GlobalRateLimitStatusCode: 429, - DebugConnections: []string{}, - StrictValidatePathType: false, // TODO: This will be true in future releases + UpstreamKeepaliveConnections: 320, + UpstreamKeepaliveTime: "1h", + UpstreamKeepaliveTimeout: 60, + UpstreamKeepaliveRequests: 10000, + LimitConnZoneVariable: defaultLimitConnZoneVariable, + BindAddressIpv4: defBindAddress, + BindAddressIpv6: defBindAddress, + OpentelemetryTrustIncomingSpan: true, + OpentelemetryConfig: "/etc/ingress-controller/telemetry/opentelemetry.toml", + OtlpCollectorPort: "4317", + OtelServiceName: "nginx", + OtelSampler: "AlwaysOn", + OtelSamplerRatio: 0.01, + OtelSamplerParentBased: true, + OtelScheduleDelayMillis: 5000, + OtelMaxExportBatchSize: 512, + OtelMaxQueueSize: 2048, + LimitReqStatusCode: 503, + LimitConnStatusCode: 503, + SyslogPort: 514, + NoTLSRedirectLocations: "/.well-known/acme-challenge", + NoAuthLocations: "/.well-known/acme-challenge", + GlobalExternalAuth: defGlobalExternalAuth, + ProxySSLLocationOnly: false, + DefaultType: "text/html", + DebugConnections: []string{}, + StrictValidatePathType: true, + GRPCBufferSizeKb: 0, } if klog.V(5).Enabled() { diff --git a/internal/ingress/controller/controller.go b/internal/ingress/controller/controller.go index de8eb97fc..652a80e49 100644 --- a/internal/ingress/controller/controller.go +++ b/internal/ingress/controller/controller.go @@ -91,6 +91,7 @@ type Configuration struct { UpdateStatus bool UseNodeInternalIP bool ElectionID string + ElectionTTL time.Duration UpdateStatusOnShutdown bool HealthCheckHost string @@ -100,13 +101,18 @@ type Configuration struct { EnableSSLPassthrough bool + DisableLeaderElection bool + EnableProfiling bool - EnableMetrics bool - MetricsPerHost bool - MetricsBuckets *collectors.HistogramBuckets - ReportStatusClasses bool - ExcludeSocketMetrics []string + EnableMetrics bool + MetricsPerHost bool + MetricsPerUndefinedHost bool + MetricsBuckets *collectors.HistogramBuckets + MetricsBucketFactor float64 + MetricsMaxBuckets uint32 + ReportStatusClasses bool + ExcludeSocketMetrics []string FakeCertificate *ingress.SSLCert @@ -374,10 +380,6 @@ func (n *NGINXController) CheckIngress(ing *networking.Ingress) error { if !cfg.AllowSnippetAnnotations && strings.HasSuffix(key, "-snippet") { return fmt.Errorf("%s annotation cannot be used. Snippet directives are disabled by the Ingress administrator", key) } - - if cfg.GlobalRateLimitMemcachedHost == "" && strings.HasPrefix(key, fmt.Sprintf("%s/%s", parser.AnnotationsPrefix, "global-rate-limit")) { - return fmt.Errorf("'global-rate-limit*' annotations require 'global-rate-limit-memcached-host' settings configured in the global configmap") - } } k8s.SetDefaultNGINXPathType(ing) @@ -1253,6 +1255,7 @@ func (n *NGINXController) createServers(data []*ingress.Ingress, ReadTimeout: bdef.ProxyReadTimeout, BuffersNumber: bdef.ProxyBuffersNumber, BufferSize: bdef.ProxyBufferSize, + BusyBuffersSize: bdef.ProxyBusyBuffersSize, CookieDomain: bdef.ProxyCookieDomain, CookiePath: bdef.ProxyCookiePath, NextUpstream: bdef.ProxyNextUpstream, @@ -1501,6 +1504,7 @@ func (n *NGINXController) createServers(data []*ingress.Ingress, func locationApplyAnnotations(loc *ingress.Location, anns *annotations.Ingress) { loc.BasicDigestAuth = anns.BasicDigestAuth loc.ClientBodyBufferSize = anns.ClientBodyBufferSize + loc.CustomHeaders = anns.CustomHeaders loc.ConfigurationSnippet = anns.ConfigurationSnippet loc.CorsConfig = anns.CorsConfig loc.ExternalAuth = anns.ExternalAuth @@ -1510,7 +1514,6 @@ func locationApplyAnnotations(loc *ingress.Location, anns *annotations.Ingress) loc.Proxy = anns.Proxy loc.ProxySSL = anns.ProxySSL loc.RateLimit = anns.RateLimit - loc.GlobalRateLimit = anns.GlobalRateLimit loc.Redirect = anns.Redirect loc.Rewrite = anns.Rewrite loc.UpstreamVhost = anns.UpstreamVhost diff --git a/internal/ingress/controller/endpointslices.go b/internal/ingress/controller/endpointslices.go index 4f98e3ce7..ed46e2c85 100644 --- a/internal/ingress/controller/endpointslices.go +++ b/internal/ingress/controller/endpointslices.go @@ -115,7 +115,7 @@ func getEndpointsFromSlices(s *corev1.Service, port *corev1.ServicePort, proto c useTopologyHints = false if zoneForHints != emptyZone { useTopologyHints = true - // check if all endpointslices has zone hints + // check if all endpointslices have zone hints for _, ep := range eps.Endpoints { if ep.Hints == nil || len(ep.Hints.ForZones) == 0 { useTopologyHints = false diff --git a/internal/ingress/controller/nginx.go b/internal/ingress/controller/nginx.go index e19ee8bb3..20fad5afb 100644 --- a/internal/ingress/controller/nginx.go +++ b/internal/ingress/controller/nginx.go @@ -35,6 +35,7 @@ import ( "syscall" "text/template" "time" + "unicode" proxyproto "github.com/armon/go-proxyproto" "github.com/eapache/channels" @@ -87,9 +88,10 @@ func NewNGINXController(config *Configuration, mc metric.Collector) *NGINXContro n := &NGINXController{ isIPV6Enabled: ing_net.IsIPv6Enabled(), - resolver: h, - cfg: config, - syncRateLimiter: flowcontrol.NewTokenBucketRateLimiter(config.SyncRateLimit, 1), + resolver: h, + cfg: config, + syncRateLimiter: flowcontrol.NewTokenBucketRateLimiter(config.SyncRateLimit, 1), + workersReloading: false, recorder: eventBroadcaster.NewRecorder(scheme.Scheme, apiv1.EventSource{ Component: "nginx-ingress-controller", @@ -229,6 +231,8 @@ type NGINXController struct { syncRateLimiter flowcontrol.RateLimiter + workersReloading bool + // stopLock is used to enforce that only a single call to Stop send at // a given time. We allow stopping through an HTTP endpoint and // allowing concurrent stoppers leads to stack traces. @@ -273,26 +277,29 @@ func (n *NGINXController) Start() { // TODO: For now, as the the IngressClass logics has changed, is up to the // cluster admin to create different Leader Election IDs. // Should revisit this in a future - electionID := n.cfg.ElectionID - setupLeaderElection(&leaderElectionConfig{ - Client: n.cfg.Client, - ElectionID: electionID, - OnStartedLeading: func(stopCh chan struct{}) { - if n.syncStatus != nil { - go n.syncStatus.Run(stopCh) - } + if !n.cfg.DisableLeaderElection { + electionID := n.cfg.ElectionID + setupLeaderElection(&leaderElectionConfig{ + Client: n.cfg.Client, + ElectionID: electionID, + ElectionTTL: n.cfg.ElectionTTL, + OnStartedLeading: func(stopCh chan struct{}) { + if n.syncStatus != nil { + go n.syncStatus.Run(stopCh) + } - n.metricCollector.OnStartedLeading(electionID) - // manually update SSL expiration metrics - // (to not wait for a reload) - n.metricCollector.SetSSLExpireTime(n.runningConfig.Servers) - n.metricCollector.SetSSLInfo(n.runningConfig.Servers) - }, - OnStoppedLeading: func() { - n.metricCollector.OnStoppedLeading(electionID) - }, - }) + n.metricCollector.OnStartedLeading(electionID) + // manually update SSL expiration metrics + // (to not wait for a reload) + n.metricCollector.SetSSLExpireTime(n.runningConfig.Servers) + n.metricCollector.SetSSLInfo(n.runningConfig.Servers) + }, + OnStoppedLeading: func() { + n.metricCollector.OnStoppedLeading(electionID) + }, + }) + } cmd := n.command.ExecCommand() @@ -636,8 +643,7 @@ func (n *NGINXController) testTemplate(cfg []byte) error { if len(cfg) == 0 { return fmt.Errorf("invalid NGINX configuration (empty)") } - tmpDir := os.TempDir() + "/nginx" - tmpfile, err := os.CreateTemp(tmpDir, tempNginxPattern) + tmpfile, err := os.CreateTemp(filepath.Join(os.TempDir(), "nginx"), tempNginxPattern) if err != nil { return err } @@ -673,11 +679,20 @@ func (n *NGINXController) OnUpdate(ingressCfg ingress.Configuration) error { cfg := n.store.GetBackendConfiguration() cfg.Resolver = n.resolver + workerSerialReloads := cfg.WorkerSerialReloads + if workerSerialReloads && n.workersReloading { + return errors.New("worker reload already in progress, requeuing reload") + } + content, err := n.generateTemplate(cfg, ingressCfg) if err != nil { return err } + err = n.createLuaConfig(&cfg) + if err != nil { + return err + } err = createOpentelemetryCfg(&cfg) if err != nil { return err @@ -735,9 +750,41 @@ func (n *NGINXController) OnUpdate(ingressCfg ingress.Configuration) error { return fmt.Errorf("%v\n%v", err, string(o)) } + // Reload status checking runs in a separate goroutine to avoid blocking the sync queue + if workerSerialReloads { + go n.awaitWorkersReload() + } + return nil } +// awaitWorkersReload checks if the number of workers has returned to the expected count +func (n *NGINXController) awaitWorkersReload() { + n.workersReloading = true + defer func() { n.workersReloading = false }() + + expectedWorkers := n.store.GetBackendConfiguration().WorkerProcesses + var numWorkers string + klog.V(3).Infof("waiting for worker count to be equal to %s", expectedWorkers) + for numWorkers != expectedWorkers { + time.Sleep(time.Second) + o, err := exec.Command("/bin/sh", "-c", "pgrep worker | wc -l").Output() + if err != nil { + klog.ErrorS(err, numWorkers) + return + } + // cleanup any non-printable chars from shell output + numWorkers = strings.Map(func(r rune) rune { + if unicode.IsPrint(r) { + return r + } + return -1 + }, string(o)) + + klog.V(3).Infof("Currently running nginx worker processes: %s, expected %s", numWorkers, expectedWorkers) + } +} + // nginxHashBucketSize computes the correct NGINX hash_bucket_size for a hash // with the given longest key. func nginxHashBucketSize(longestString int) int { @@ -1035,14 +1082,40 @@ func createOpentelemetryCfg(cfg *ngx_config.Configuration) error { return os.WriteFile(cfg.OpentelemetryConfig, tmplBuf.Bytes(), file.ReadWriteByUser) } +func (n *NGINXController) createLuaConfig(cfg *ngx_config.Configuration) error { + luaconfigs := &ngx_template.LuaConfig{ + EnableMetrics: n.cfg.EnableMetrics, + ListenPorts: ngx_template.LuaListenPorts{ + HTTPSPort: strconv.Itoa(n.cfg.ListenPorts.HTTPS), + StatusPort: strconv.Itoa(nginx.StatusPort), + SSLProxyPort: strconv.Itoa(n.cfg.ListenPorts.SSLProxy), + }, + UseProxyProtocol: cfg.UseProxyProtocol, + UseForwardedHeaders: cfg.UseForwardedHeaders, + IsSSLPassthroughEnabled: n.cfg.EnableSSLPassthrough, + HTTPRedirectCode: cfg.HTTPRedirectCode, + EnableOCSP: cfg.EnableOCSP, + MonitorBatchMaxSize: n.cfg.MonitorMaxBatchSize, + HSTS: cfg.HSTS, + HSTSMaxAge: cfg.HSTSMaxAge, + HSTSIncludeSubdomains: cfg.HSTSIncludeSubdomains, + HSTSPreload: cfg.HSTSPreload, + } + jsonCfg, err := json.Marshal(luaconfigs) + if err != nil { + return err + } + return os.WriteFile(luaCfgPath, jsonCfg, file.ReadWriteByUser) +} + func cleanTempNginxCfg() error { var files []string - err := filepath.Walk(os.TempDir(), func(path string, info os.FileInfo, err error) error { + err := filepath.Walk(filepath.Join(os.TempDir(), "nginx"), func(path string, info os.FileInfo, err error) error { if err != nil { return err } - if info.IsDir() && os.TempDir() != path { + if info.IsDir() && path != filepath.Join(os.TempDir(), "nginx") { return filepath.SkipDir } @@ -1061,7 +1134,7 @@ func cleanTempNginxCfg() error { } for _, file := range files { - err := os.Remove(file) + err = os.Remove(file) if err != nil { return err } diff --git a/internal/ingress/controller/nginx_test.go b/internal/ingress/controller/nginx_test.go index 27180e066..fc0a5b6d2 100644 --- a/internal/ingress/controller/nginx_test.go +++ b/internal/ingress/controller/nginx_test.go @@ -361,10 +361,11 @@ func TestCleanTempNginxCfg(t *testing.T) { t.Fatal(err) } - tmpfile, err := os.CreateTemp("", tempNginxPattern) + tmpfile, err := os.CreateTemp(filepath.Join(os.TempDir(), "nginx"), tempNginxPattern) if err != nil { t.Fatal(err) } + expectedDeletedFile := tmpfile.Name() defer tmpfile.Close() dur, err := time.ParseDuration("-10m") @@ -378,10 +379,11 @@ func TestCleanTempNginxCfg(t *testing.T) { t.Fatal(err) } - tmpfile, err = os.CreateTemp("", tempNginxPattern) + tmpfile, err = os.CreateTemp(filepath.Join(os.TempDir(), "nginx"), tempNginxPattern) if err != nil { t.Fatal(err) } + expectedFile := tmpfile.Name() defer tmpfile.Close() err = cleanTempNginxCfg() @@ -391,8 +393,8 @@ func TestCleanTempNginxCfg(t *testing.T) { var files []string - err = filepath.Walk(os.TempDir(), func(path string, info os.FileInfo, _ error) error { - if info.IsDir() && os.TempDir() != path { + err = filepath.Walk(filepath.Join(os.TempDir(), "nginx"), func(path string, info os.FileInfo, _ error) error { + if info.IsDir() && filepath.Join(os.TempDir(), "nginx") != path { return filepath.SkipDir } @@ -405,12 +407,22 @@ func TestCleanTempNginxCfg(t *testing.T) { t.Fatal(err) } - if len(files) != 1 { - t.Errorf("expected one file but %d were found", len(files)) + // some other files can be created by other tests + var found bool + for _, file := range files { + if file == expectedDeletedFile { + t.Errorf("file %s should be deleted", file) + } + if file == expectedFile { + found = true + } + } + if !found { + t.Errorf("file %s should not be deleted", expectedFile) } } -//nolint:unparam // Ingnore `network` always receives `"tcp"` error +//nolint:unparam // Ignore `network` always receives `"tcp"` error func tryListen(network, address string) (l net.Listener, err error) { condFunc := func() (bool, error) { l, err = net.Listen(network, address) diff --git a/internal/ingress/controller/status.go b/internal/ingress/controller/status.go index 6bab7c2ad..5a169e1c3 100644 --- a/internal/ingress/controller/status.go +++ b/internal/ingress/controller/status.go @@ -36,7 +36,8 @@ import ( type leaderElectionConfig struct { Client clientset.Interface - ElectionID string + ElectionID string + ElectionTTL time.Duration OnStartedLeading func(chan struct{}) OnStoppedLeading func() @@ -107,13 +108,11 @@ func setupLeaderElection(config *leaderElectionConfig) { LockConfig: resourceLockConfig, } - ttl := 30 * time.Second - elector, err = leaderelection.NewLeaderElector(leaderelection.LeaderElectionConfig{ Lock: lock, - LeaseDuration: ttl, - RenewDeadline: ttl / 2, - RetryPeriod: ttl / 4, + LeaseDuration: config.ElectionTTL, + RenewDeadline: config.ElectionTTL / 2, + RetryPeriod: config.ElectionTTL / 4, Callbacks: callbacks, }) diff --git a/internal/ingress/controller/store/endpointslice_test.go b/internal/ingress/controller/store/endpointslice_test.go index 5d423a3a6..0bdb3aa33 100644 --- a/internal/ingress/controller/store/endpointslice_test.go +++ b/internal/ingress/controller/store/endpointslice_test.go @@ -88,7 +88,7 @@ func TestEndpointSliceLister(t *testing.T) { } eps, err := el.MatchByKey(key) if err != nil { - t.Errorf("unexpeted error %v", err) + t.Errorf("unexpected error %v", err) } if err == nil && len(eps) != 1 { t.Errorf("expected one slice %v, error, got %d slices", endpointSlice, len(eps)) @@ -130,7 +130,7 @@ func TestEndpointSliceLister(t *testing.T) { } eps, err := el.MatchByKey(key) if err != nil { - t.Errorf("unexpeted error %v", err) + t.Errorf("unexpected error %v", err) } if len(eps) != 1 { t.Errorf("expected one slice %v, error, got %d slices", endpointSlice, len(eps)) diff --git a/internal/ingress/controller/store/store.go b/internal/ingress/controller/store/store.go index 284f53209..d4bd6136f 100644 --- a/internal/ingress/controller/store/store.go +++ b/internal/ingress/controller/store/store.go @@ -240,6 +240,8 @@ type k8sStore struct { backendConfigMu *sync.RWMutex defaultSSLCertificate string + + recorder record.EventRecorder } // New creates a new object store to be used in the ingress controller. @@ -279,6 +281,7 @@ func New( recorder := eventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{ Component: "nginx-ingress-controller", }) + store.recorder = recorder // k8sStore fulfills resolver.Resolver interface store.annotations = annotations.NewAnnotationExtractor(store) @@ -938,6 +941,9 @@ func (s *k8sStore) syncIngress(ing *networkingv1.Ingress) { klog.Error(err) return } + if parsed.Denied != nil { + s.recorder.Eventf(ing, corev1.EventTypeWarning, "AnnotationParsingFailed", fmt.Sprintf("Error parsing annotations: %v", *parsed.Denied)) + } err = s.listers.IngressWithAnnotation.Update(&ingress.Ingress{ Ingress: *copyIng, ParsedAnnotations: parsed, diff --git a/internal/ingress/controller/store/store_test.go b/internal/ingress/controller/store/store_test.go index 317c0f36c..9c719af3b 100644 --- a/internal/ingress/controller/store/store_test.go +++ b/internal/ingress/controller/store/store_test.go @@ -1208,13 +1208,13 @@ func TestStore(t *testing.T) { } }(updateCh) - namesapceSelector, err := labels.Parse("foo=bar") + namespaceSelector, err := labels.Parse("foo=bar") if err != nil { t.Errorf("unexpected error: %v", err) } storer := New( ns, - namesapceSelector, + namespaceSelector, fmt.Sprintf("%v/config", ns), fmt.Sprintf("%v/tcp", ns), fmt.Sprintf("%v/udp", ns), @@ -1274,7 +1274,7 @@ func TestStore(t *testing.T) { t.Errorf("expected 0 events of type Delete but %v occurred", del) } }) - // test add ingress with secret it doesn't exists and then add secret + // test add ingress with secret it doesn't exist and then add secret // check secret is generated on fs // check ocsp // check invalid secret (missing crt) diff --git a/internal/ingress/controller/template/configmap.go b/internal/ingress/controller/template/configmap.go index 9dc019bcc..febf20be0 100644 --- a/internal/ingress/controller/template/configmap.go +++ b/internal/ingress/controller/template/configmap.go @@ -31,6 +31,7 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "k8s.io/ingress-nginx/internal/ingress/annotations/authreq" + "k8s.io/ingress-nginx/internal/ingress/annotations/customheaders" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/controller/config" ing_net "k8s.io/ingress-nginx/internal/net" @@ -54,6 +55,7 @@ const ( nginxStatusIpv6Whitelist = "nginx-status-ipv6-whitelist" proxyHeaderTimeout = "proxy-protocol-header-timeout" workerProcesses = "worker-processes" + globalAllowedResponseHeaders = "global-allowed-response-headers" globalAuthURL = "global-auth-url" globalAuthMethod = "global-auth-method" globalAuthSignin = "global-auth-signin" @@ -65,8 +67,8 @@ const ( globalAuthCacheDuration = "global-auth-cache-duration" globalAuthAlwaysSetCookie = "global-auth-always-set-cookie" luaSharedDictsKey = "lua-shared-dicts" - plugins = "plugins" debugConnections = "debug-connections" + workerSerialReloads = "enable-serial-reloads" ) var ( @@ -80,7 +82,6 @@ var ( "balancer_ewma_locks": 1024, "certificate_servers": 5120, "ocsp_response_cache": 5120, // keep this same as certificate_servers - "global_throttle_cache": 10240, } defaultGlobalAuthRedirectParam = "rd" ) @@ -115,6 +116,7 @@ func ReadConfig(src map[string]string) config.Configuration { blockUserAgentList := make([]string, 0) blockRefererList := make([]string, 0) responseHeaders := make([]string, 0) + allowedResponseHeaders := make([]string, 0) luaSharedDicts := make(map[string]int) debugConnectionsList := make([]string, 0) @@ -123,8 +125,11 @@ func ReadConfig(src map[string]string) config.Configuration { delete(conf, luaSharedDictsKey) lsd := splitAndTrimSpace(val, ",") for _, v := range lsd { - v = strings.ReplaceAll(v, " ", "") - results := strings.SplitN(v, ":", 2) + results := strings.SplitN(strings.ReplaceAll(v, " ", ""), ":", 2) + if len(results) != 2 { + klog.Errorf("Ignoring poorly formatted Lua dictionary %v", v) + continue + } dictName := results[0] size := dictStrToKb(results[1]) if size < 0 { @@ -248,6 +253,22 @@ func ReadConfig(src map[string]string) config.Configuration { } } + // Verify that the configured global external authorization response headers are valid. if not, set the default value + if val, ok := conf[globalAllowedResponseHeaders]; ok { + delete(conf, globalAllowedResponseHeaders) + + if val != "" { + harr := splitAndTrimSpace(val, ",") + for _, header := range harr { + if !customheaders.ValidHeader(header) { + klog.Warningf("Global allowed response headers denied - %s.", header) + } else { + allowedResponseHeaders = append(allowedResponseHeaders, header) + } + } + } + } + // Verify that the configured global external authorization method is a valid HTTP method. if not, set the default value if val, ok := conf[globalAuthMethod]; ok { delete(conf, globalAuthMethod) @@ -385,9 +406,15 @@ func ReadConfig(src map[string]string) config.Configuration { delete(conf, workerProcesses) } - if val, ok := conf[plugins]; ok { - to.Plugins = splitAndTrimSpace(val, ",") - delete(conf, plugins) + if val, ok := conf[workerSerialReloads]; ok { + boolVal, err := strconv.ParseBool(val) + if err != nil { + to.WorkerSerialReloads = false + klog.Warningf("failed to parse enable-serial-reloads setting, valid values are true or false, found %s", val) + } else { + to.WorkerSerialReloads = boolVal + } + delete(conf, workerSerialReloads) } if val, ok := conf[debugConnections]; ok { @@ -422,6 +449,7 @@ func ReadConfig(src map[string]string) config.Configuration { to.ProxyStreamResponses = streamResponses to.DisableIpv6DNS = !ing_net.IsIPv6Enabled() to.LuaSharedDicts = luaSharedDicts + to.Backend.AllowedResponseHeaders = allowedResponseHeaders decoderConfig := &mapstructure.DecoderConfig{ Metadata: nil, diff --git a/internal/ingress/controller/template/configmap_test.go b/internal/ingress/controller/template/configmap_test.go index dad841694..6c7468303 100644 --- a/internal/ingress/controller/template/configmap_test.go +++ b/internal/ingress/controller/template/configmap_test.go @@ -390,6 +390,11 @@ func TestLuaSharedDictsParsing(t *testing.T) { entry: map[string]string{"lua-shared-dicts": "configuration_data: 10, my_random_dict:15 , another_example:2"}, expect: map[string]int{"configuration_data": 10240, "my_random_dict": 15360, "another_example": 2048}, }, + { + name: "invalid format", + entry: map[string]string{"lua-shared-dicts": "mydict: 10, invalid_dict 100"}, + expect: map[string]int{"mydict": 10240}, + }, { name: "invalid size value should be ignored", entry: map[string]string{"lua-shared-dicts": "mydict: 10, invalid_dict: 1a, bad_mb_dict:10mb"}, diff --git a/internal/ingress/controller/template/template.go b/internal/ingress/controller/template/template.go index 8628f8090..ed052e4ec 100644 --- a/internal/ingress/controller/template/template.go +++ b/internal/ingress/controller/template/template.go @@ -194,6 +194,41 @@ func cleanConf(in, out *bytes.Buffer) error { } } +/* LuaConfig defines the structure that will be written as a config for lua scripts +The json format should follow what's expected by lua: + use_forwarded_headers = %t, + use_proxy_protocol = %t, + is_ssl_passthrough_enabled = %t, + http_redirect_code = %v, + listen_ports = { ssl_proxy = "%v", https = "%v" }, + + hsts = %t, + hsts_max_age = %v, + hsts_include_subdomains = %t, + hsts_preload = %t, +*/ + +type LuaConfig struct { + EnableMetrics bool `json:"enable_metrics"` + ListenPorts LuaListenPorts `json:"listen_ports"` + UseForwardedHeaders bool `json:"use_forwarded_headers"` + UseProxyProtocol bool `json:"use_proxy_protocol"` + IsSSLPassthroughEnabled bool `json:"is_ssl_passthrough_enabled"` + HTTPRedirectCode int `json:"http_redirect_code"` + EnableOCSP bool `json:"enable_ocsp"` + MonitorBatchMaxSize int `json:"monitor_batch_max_size"` + HSTS bool `json:"hsts"` + HSTSMaxAge string `json:"hsts_max_age"` + HSTSIncludeSubdomains bool `json:"hsts_include_subdomains"` + HSTSPreload bool `json:"hsts_preload"` +} + +type LuaListenPorts struct { + HTTPSPort string `json:"https"` + StatusPort string `json:"status_port"` + SSLProxyPort string `json:"ssl_proxy"` +} + // Write populates a buffer using a template with NGINX configuration // and the servers and upstreams created by Ingress rules func (t *Template) Write(conf *config.TemplateConfig) ([]byte, error) { @@ -256,7 +291,6 @@ var funcMap = text_template.FuncMap{ "filterRateLimits": filterRateLimits, "buildRateLimitZones": buildRateLimitZones, "buildRateLimit": buildRateLimit, - "configForLua": configForLua, "locationConfigForLua": locationConfigForLua, "buildResolvers": buildResolvers, "buildUpstreamName": buildUpstreamName, @@ -383,54 +417,6 @@ func luaConfigurationRequestBodySize(c interface{}) string { return dictKbToStr(size) } -// configForLua returns some general configuration as Lua table represented as string -func configForLua(input interface{}) string { - all, ok := input.(config.TemplateConfig) - if !ok { - klog.Errorf("expected a 'config.TemplateConfig' type but %T was given", input) - return "{}" - } - - return fmt.Sprintf(`{ - use_forwarded_headers = %t, - use_proxy_protocol = %t, - is_ssl_passthrough_enabled = %t, - http_redirect_code = %v, - listen_ports = { ssl_proxy = "%v", https = "%v" }, - - hsts = %t, - hsts_max_age = %v, - hsts_include_subdomains = %t, - hsts_preload = %t, - - global_throttle = { - memcached = { - host = "%v", port = %d, connect_timeout = %d, max_idle_timeout = %d, pool_size = %d, - }, - status_code = %d, - } - }`, - all.Cfg.UseForwardedHeaders, - all.Cfg.UseProxyProtocol, - all.IsSSLPassthroughEnabled, - all.Cfg.HTTPRedirectCode, - all.ListenPorts.SSLProxy, - all.ListenPorts.HTTPS, - - all.Cfg.HSTS, - all.Cfg.HSTSMaxAge, - all.Cfg.HSTSIncludeSubdomains, - all.Cfg.HSTSPreload, - - all.Cfg.GlobalRateLimitMemcachedHost, - all.Cfg.GlobalRateLimitMemcachedPort, - all.Cfg.GlobalRateLimitMemcachedConnectTimeout, - all.Cfg.GlobalRateLimitMemcachedMaxIdleTimeout, - all.Cfg.GlobalRateLimitMemcachedPoolSize, - all.Cfg.GlobalRateLimitStatusCode, - ) -} - // locationConfigForLua formats some location specific configuration into Lua table represented as string func locationConfigForLua(l, a interface{}) string { location, ok := l.(*ingress.Location) @@ -445,30 +431,26 @@ func locationConfigForLua(l, a interface{}) string { return "{}" } - ignoredCIDRs, err := convertGoSliceIntoLuaTable(location.GlobalRateLimit.IgnoredCIDRs, false) - if err != nil { - klog.Errorf("failed to convert %v into Lua table: %q", location.GlobalRateLimit.IgnoredCIDRs, err) - ignoredCIDRs = "{}" - } + /* Lua expects the following vars + force_ssl_redirect = string_to_bool(ngx.var.force_ssl_redirect), + ssl_redirect = string_to_bool(ngx.var.ssl_redirect), + force_no_ssl_redirect = string_to_bool(ngx.var.force_no_ssl_redirect), + preserve_trailing_slash = string_to_bool(ngx.var.preserve_trailing_slash), + use_port_in_redirects = string_to_bool(ngx.var.use_port_in_redirects), + */ - return fmt.Sprintf(`{ - force_ssl_redirect = %t, - ssl_redirect = %t, - force_no_ssl_redirect = %t, - preserve_trailing_slash = %t, - use_port_in_redirects = %t, - global_throttle = { namespace = "%v", limit = %d, window_size = %d, key = %v, ignored_cidrs = %v }, - }`, + return fmt.Sprintf(` + set $force_ssl_redirect "%t"; + set $ssl_redirect "%t"; + set $force_no_ssl_redirect "%t"; + set $preserve_trailing_slash "%t"; + set $use_port_in_redirects "%t"; + `, location.Rewrite.ForceSSLRedirect, location.Rewrite.SSLRedirect, isLocationInLocationList(l, all.Cfg.NoTLSRedirectLocations), location.Rewrite.PreserveTrailingSlash, location.UsePortInRedirects, - location.GlobalRateLimit.Namespace, - location.GlobalRateLimit.Limit, - location.GlobalRateLimit.WindowSize, - parseComplexNginxVarIntoLuaTable(location.GlobalRateLimit.Key), - ignoredCIDRs, ) } @@ -620,17 +602,12 @@ func buildAuthResponseHeaders(proxySetHeader string, headers []string, lua bool) return res } -func buildAuthUpstreamLuaHeaders(headers []string) []string { - res := []string{} - +func buildAuthUpstreamLuaHeaders(headers []string) string { if len(headers) == 0 { - return res + return "" } - for i, h := range headers { - res = append(res, fmt.Sprintf("ngx.var.authHeader%d = res.header['%s']", i, h)) - } - return res + return strings.Join(headers, ",") } func buildAuthProxySetHeaders(headers map[string]string) []string { @@ -1690,54 +1667,6 @@ func buildServerName(hostname string) string { return `~^(?[\w-]+)\.` + strings.Join(parts, "\\.") + `$` } -// parseComplexNginxVarIntoLuaTable parses things like "$my${complex}ngx\$var" into -// [["$var", "complex", "my", "ngx"]]. In other words, 2nd and 3rd elements -// in the result are actual NGINX variable names, whereas first and 4th elements -// are string literals. -func parseComplexNginxVarIntoLuaTable(ngxVar string) string { - r := regexp.MustCompile(`(\\\$[0-9a-zA-Z_]+)|\$\{([0-9a-zA-Z_]+)\}|\$([0-9a-zA-Z_]+)|(\$|[^$\\]+)`) - matches := r.FindAllStringSubmatch(ngxVar, -1) - components := make([][]string, len(matches)) - for i, match := range matches { - components[i] = match[1:] - } - - luaTable, err := convertGoSliceIntoLuaTable(components, true) - if err != nil { - klog.Errorf("unexpected error: %v", err) - luaTable = "{}" - } - return luaTable -} - -func convertGoSliceIntoLuaTable(goSliceInterface interface{}, emptyStringAsNil bool) (string, error) { - goSlice := reflect.ValueOf(goSliceInterface) - kind := goSlice.Kind() - - switch kind { - case reflect.String: - if emptyStringAsNil && goSlice.Interface().(string) == "" { - return "nil", nil - } - return fmt.Sprintf(`"%v"`, goSlice.Interface()), nil - case reflect.Int, reflect.Bool: - return fmt.Sprintf(`%v`, goSlice.Interface()), nil - case reflect.Slice, reflect.Array: - luaTable := "{ " - for i := 0; i < goSlice.Len(); i++ { - luaEl, err := convertGoSliceIntoLuaTable(goSlice.Index(i).Interface(), emptyStringAsNil) - if err != nil { - return "", err - } - luaTable = luaTable + luaEl + ", " - } - luaTable += "}" - return luaTable, nil - default: - return "", fmt.Errorf("could not process type: %s", kind) - } -} - func buildOriginRegex(origin string) string { origin = regexp.QuoteMeta(origin) origin = strings.Replace(origin, "\\*", `[A-Za-z0-9\-]+`, 1) diff --git a/internal/ingress/controller/template/template_test.go b/internal/ingress/controller/template/template_test.go index 3089e3b32..6553f5daf 100644 --- a/internal/ingress/controller/template/template_test.go +++ b/internal/ingress/controller/template/template_test.go @@ -537,10 +537,7 @@ func TestBuildAuthResponseHeaders(t *testing.T) { func TestBuildAuthResponseLua(t *testing.T) { externalAuthResponseHeaders := []string{"h1", "H-With-Caps-And-Dashes"} - expected := []string{ - "ngx.var.authHeader0 = res.header['h1']", - "ngx.var.authHeader1 = res.header['H-With-Caps-And-Dashes']", - } + expected := "h1,H-With-Caps-And-Dashes" headers := buildAuthUpstreamLuaHeaders(externalAuthResponseHeaders) @@ -1926,89 +1923,6 @@ func TestBuildServerName(t *testing.T) { } } -func TestParseComplexNginxVarIntoLuaTable(t *testing.T) { - testCases := []struct { - ngxVar string - expectedLuaTable string - }{ - {"foo", `{ { nil, nil, nil, "foo", }, }`}, - {"$foo", `{ { nil, nil, "foo", nil, }, }`}, - {"${foo}", `{ { nil, "foo", nil, nil, }, }`}, - {"\\$foo", `{ { "\$foo", nil, nil, nil, }, }`}, - { - "foo\\$bar$baz${daz}xiyar$pomidor", - `{ { nil, nil, nil, "foo", }, { "\$bar", nil, nil, nil, }, { nil, nil, "baz", nil, }, ` + - `{ nil, "daz", nil, nil, }, { nil, nil, nil, "xiyar", }, { nil, nil, "pomidor", nil, }, }`, - }, - } - - for _, testCase := range testCases { - actualLuaTable := parseComplexNginxVarIntoLuaTable(testCase.ngxVar) - if actualLuaTable != testCase.expectedLuaTable { - t.Errorf("expected %v but returned %v", testCase.expectedLuaTable, actualLuaTable) - } - } -} - -func TestConvertGoSliceIntoLuaTablet(t *testing.T) { - testCases := []struct { - title string - goSlice interface{} - emptyStringAsNil bool - expectedLuaTable string - expectedErr error - }{ - { - "flat string slice", - []string{"one", "two", "three"}, - false, - `{ "one", "two", "three", }`, - nil, - }, - { - "nested string slice", - [][]string{{"one", "", "three"}, {"foo", "bar"}}, - false, - `{ { "one", "", "three", }, { "foo", "bar", }, }`, - nil, - }, - { - "converts empty string to nil when enabled", - [][]string{{"one", "", "three"}, {"foo", "bar"}}, - true, - `{ { "one", nil, "three", }, { "foo", "bar", }, }`, - nil, - }, - { - "boolean slice", - []bool{true, true, false}, - false, - `{ true, true, false, }`, - nil, - }, - { - "integer slice", - []int{4, 3, 6}, - false, - `{ 4, 3, 6, }`, - nil, - }, - } - - for _, testCase := range testCases { - actualLuaTable, err := convertGoSliceIntoLuaTable(testCase.goSlice, testCase.emptyStringAsNil) - if testCase.expectedErr != nil && err != nil && testCase.expectedErr.Error() != err.Error() { - t.Errorf("expected error '%v' but returned '%v'", testCase.expectedErr, err) - } - if testCase.expectedErr == nil && err != nil { - t.Errorf("expected error to be nil but returned '%v'", err) - } - if testCase.expectedLuaTable != actualLuaTable { - t.Errorf("%v: expected '%v' but returned '%v'", testCase.title, testCase.expectedLuaTable, actualLuaTable) - } - } -} - func TestCleanConf(t *testing.T) { testDataDir, err := getTestDataDir() if err != nil { diff --git a/internal/ingress/controller/util.go b/internal/ingress/controller/util.go index 8851f323f..975fb822a 100644 --- a/internal/ingress/controller/util.go +++ b/internal/ingress/controller/util.go @@ -98,8 +98,9 @@ func rlimitMaxNumFiles() int { } const ( - defBinary = "/usr/bin/nginx" - cfgPath = "/etc/nginx/nginx.conf" + defBinary = "/usr/bin/nginx" + cfgPath = "/etc/nginx/nginx.conf" + luaCfgPath = "/etc/nginx/lua/cfg.json" ) // NginxExecTester defines the interface to execute @@ -129,7 +130,7 @@ func NewNginxCommand() NginxCommand { return command } -// ExecCommand instanciates an exec.Cmd object to call nginx program +// ExecCommand instantiates an exec.Cmd object to call nginx program func (nc NginxCommand) ExecCommand(args ...string) *exec.Cmd { cmdArgs := []string{} diff --git a/internal/ingress/defaults/main.go b/internal/ingress/defaults/main.go index 2bb58c858..bec1b08e2 100644 --- a/internal/ingress/defaults/main.go +++ b/internal/ingress/defaults/main.go @@ -69,6 +69,11 @@ type Backend struct { // http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size) ProxyBufferSize string `json:"proxy-buffer-size"` + // Limits the total size of buffers that can be busy sending a response to the client while + // the response is not yet fully read. + // http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_busy_buffers_size + ProxyBusyBuffersSize string `json:"proxy-busy-buffers-size"` + // Sets a text that should be changed in the path attribute of the “Set-Cookie” header fields of // a proxied server response. // http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cookie_path @@ -125,6 +130,11 @@ type Backend struct { // Default: false UsePortInRedirects bool `json:"use-port-in-redirects"` + // Enables or disables relative redirects. By default nginx uses absolute redirects. + // http://nginx.org/en/docs/http/ngx_http_core_module.html#absolute_redirect + // Default: false + RelativeRedirects bool `json:"relative-redirects"` + // Enable stickiness by client-server mapping based on a NGINX variable, text or a combination of both. // A consistent hashing method will be used which ensures only a few keys would be remapped to different // servers on upstream group changes @@ -176,6 +186,9 @@ type Backend struct { // By default, the NGINX ingress controller uses a list of all endpoints (Pod IP/port) in the NGINX upstream configuration. // It disables that behavior and instead uses a single upstream in NGINX, the service's Cluster IP and port. ServiceUpstream bool `json:"service-upstream"` + + // AllowedResponseHeaders allows to define allow response headers for custom header annotation + AllowedResponseHeaders []string `json:"global-allowed-response-headers"` } type SecurityConfiguration struct { diff --git a/internal/ingress/metric/collectors/controller.go b/internal/ingress/metric/collectors/controller.go index 4ee84bc56..0df04c1d0 100644 --- a/internal/ingress/metric/collectors/controller.go +++ b/internal/ingress/metric/collectors/controller.go @@ -225,7 +225,7 @@ func (cm *Controller) IncCheckErrorCount(namespace, name string) { cm.checkIngressOperationErrors.MustCurryWith(cm.constLabels).With(labels).Inc() } -// IncOrphanIngress sets the the orphaned ingress gauge to one +// IncOrphanIngress sets the orphaned ingress gauge to one func (cm *Controller) IncOrphanIngress(namespace, name, orphanityType string) { labels := prometheus.Labels{ "namespace": namespace, @@ -235,7 +235,7 @@ func (cm *Controller) IncOrphanIngress(namespace, name, orphanityType string) { cm.OrphanIngress.MustCurryWith(cm.constLabels).With(labels).Set(1.0) } -// DecOrphanIngress sets the the orphaned ingress gauge to zero (all services has their endpoints) +// DecOrphanIngress sets the orphaned ingress gauge to zero (all services has their endpoints) func (cm *Controller) DecOrphanIngress(namespace, name, orphanityType string) { labels := prometheus.Labels{ "namespace": namespace, @@ -305,13 +305,14 @@ func (cm *Controller) SetSSLExpireTime(servers []*ingress.Server) { } labels["host"] = s.Hostname labels["secret_name"] = s.SSLCert.Name + labels["namespace"] = s.SSLCert.Namespace labels["identifier"] = s.SSLCert.Identifier() cm.sslExpireTime.With(labels).Set(float64(s.SSLCert.ExpireTime.Unix())) } } -// SetSSLInfo creates a metric with all certificates informations +// SetSSLInfo creates a metric with all certificate information func (cm *Controller) SetSSLInfo(servers []*ingress.Server) { for _, s := range servers { if s.SSLCert == nil || s.SSLCert.Certificate == nil || s.SSLCert.Certificate.SerialNumber == nil { diff --git a/internal/ingress/metric/collectors/controller_test.go b/internal/ingress/metric/collectors/controller_test.go index 7c7ea8a67..a77293c20 100644 --- a/internal/ingress/metric/collectors/controller_test.go +++ b/internal/ingress/metric/collectors/controller_test.go @@ -88,6 +88,8 @@ func TestControllerCounters(t *testing.T) { Hostname: "demo", SSLCert: &ingress.SSLCert{ ExpireTime: t1, + Name: "secret-name", + Namespace: "secret-namespace", Certificate: &x509.Certificate{ PublicKeyAlgorithm: x509.ECDSA, Issuer: pkix.Name{ @@ -111,7 +113,7 @@ func TestControllerCounters(t *testing.T) { want: ` # HELP nginx_ingress_controller_ssl_expire_time_seconds Number of seconds since 1970 to the SSL Certificate expire.\n An example to check if this certificate will expire in 10 days is: "nginx_ingress_controller_ssl_expire_time_seconds < (time() + (10 * 24 * 3600))" # TYPE nginx_ingress_controller_ssl_expire_time_seconds gauge - nginx_ingress_controller_ssl_expire_time_seconds{class="nginx",host="demo",identifier="abcd1234-100",namespace="default",secret_name=""} 1.351807721e+09 + nginx_ingress_controller_ssl_expire_time_seconds{class="nginx",host="demo",identifier="abcd1234-100",namespace="secret-namespace",secret_name="secret-name"} 1.351807721e+09 `, metrics: []string{"nginx_ingress_controller_ssl_expire_time_seconds"}, }, diff --git a/internal/ingress/metric/collectors/socket.go b/internal/ingress/metric/collectors/socket.go index 248f23f63..0bdd816ae 100644 --- a/internal/ingress/metric/collectors/socket.go +++ b/internal/ingress/metric/collectors/socket.go @@ -64,11 +64,10 @@ type metricMapping map[string]prometheus.Collector type SocketCollector struct { prometheus.Collector - upstreamLatency *prometheus.SummaryVec // TODO: DEPRECATED, remove - connectTime *prometheus.HistogramVec - headerTime *prometheus.HistogramVec - requestTime *prometheus.HistogramVec - responseTime *prometheus.HistogramVec + connectTime *prometheus.HistogramVec + headerTime *prometheus.HistogramVec + requestTime *prometheus.HistogramVec + responseTime *prometheus.HistogramVec requestLength *prometheus.HistogramVec responseLength *prometheus.HistogramVec @@ -82,8 +81,9 @@ type SocketCollector struct { hosts sets.Set[string] - metricsPerHost bool - reportStatusClasses bool + metricsPerHost bool + metricsPerUndefinedHost bool + reportStatusClasses bool } var requestTags = []string{ @@ -98,13 +98,9 @@ var requestTags = []string{ "canary", } -// DefObjectives was removed in https://github.com/prometheus/client_golang/pull/262 -// updating the library to latest version changed the output of the metrics -var defObjectives = map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001} - // NewSocketCollector creates a new SocketCollector instance using // the ingress watch namespace and class used by the controller -func NewSocketCollector(pod, namespace, class string, metricsPerHost, reportStatusClasses bool, buckets HistogramBuckets, excludeMetrics []string) (*SocketCollector, error) { +func NewSocketCollector(pod, namespace, class string, metricsPerHost, metricsPerUndefinedHost, reportStatusClasses bool, buckets HistogramBuckets, bucketFactor float64, maxBuckets uint32, excludeMetrics []string) (*SocketCollector, error) { socket := "/tmp/nginx/prometheus-nginx.socket" // unix sockets must be unlink()ed before being used //nolint:errcheck // Ignore unlink error @@ -144,16 +140,19 @@ func NewSocketCollector(pod, namespace, class string, metricsPerHost, reportStat sc := &SocketCollector{ listener: listener, - metricsPerHost: metricsPerHost, - reportStatusClasses: reportStatusClasses, + metricsPerHost: metricsPerHost, + metricsPerUndefinedHost: metricsPerUndefinedHost, + reportStatusClasses: reportStatusClasses, connectTime: histogramMetric( &prometheus.HistogramOpts{ - Name: "connect_duration_seconds", - Help: "The time spent on establishing a connection with the upstream server", - Namespace: PrometheusNamespace, - ConstLabels: constLabels, - Buckets: buckets.TimeBuckets, + Name: "connect_duration_seconds", + Help: "The time spent on establishing a connection with the upstream server", + Namespace: PrometheusNamespace, + ConstLabels: constLabels, + Buckets: buckets.TimeBuckets, + NativeHistogramBucketFactor: bucketFactor, + NativeHistogramMaxBucketNumber: maxBuckets, }, requestTags, em, @@ -162,11 +161,13 @@ func NewSocketCollector(pod, namespace, class string, metricsPerHost, reportStat headerTime: histogramMetric( &prometheus.HistogramOpts{ - Name: "header_duration_seconds", - Help: "The time spent on receiving first header from the upstream server", - Namespace: PrometheusNamespace, - ConstLabels: constLabels, - Buckets: buckets.TimeBuckets, + Name: "header_duration_seconds", + Help: "The time spent on receiving first header from the upstream server", + Namespace: PrometheusNamespace, + ConstLabels: constLabels, + Buckets: buckets.TimeBuckets, + NativeHistogramBucketFactor: bucketFactor, + NativeHistogramMaxBucketNumber: maxBuckets, }, requestTags, em, @@ -174,11 +175,13 @@ func NewSocketCollector(pod, namespace, class string, metricsPerHost, reportStat ), responseTime: histogramMetric( &prometheus.HistogramOpts{ - Name: "response_duration_seconds", - Help: "The time spent on receiving the response from the upstream server", - Namespace: PrometheusNamespace, - ConstLabels: constLabels, - Buckets: buckets.TimeBuckets, + Name: "response_duration_seconds", + Help: "The time spent on receiving the response from the upstream server", + Namespace: PrometheusNamespace, + ConstLabels: constLabels, + Buckets: buckets.TimeBuckets, + NativeHistogramBucketFactor: bucketFactor, + NativeHistogramMaxBucketNumber: maxBuckets, }, requestTags, em, @@ -187,11 +190,13 @@ func NewSocketCollector(pod, namespace, class string, metricsPerHost, reportStat requestTime: histogramMetric( &prometheus.HistogramOpts{ - Name: "request_duration_seconds", - Help: "The request processing time in milliseconds", - Namespace: PrometheusNamespace, - ConstLabels: constLabels, - Buckets: buckets.TimeBuckets, + Name: "request_duration_seconds", + Help: "The request processing time in milliseconds", + Namespace: PrometheusNamespace, + ConstLabels: constLabels, + Buckets: buckets.TimeBuckets, + NativeHistogramBucketFactor: bucketFactor, + NativeHistogramMaxBucketNumber: maxBuckets, }, requestTags, em, @@ -200,11 +205,13 @@ func NewSocketCollector(pod, namespace, class string, metricsPerHost, reportStat responseLength: histogramMetric( &prometheus.HistogramOpts{ - Name: "response_size", - Help: "The response length (including request line, header, and request body)", - Namespace: PrometheusNamespace, - ConstLabels: constLabels, - Buckets: buckets.LengthBuckets, + Name: "response_size", + Help: "The response length (including request line, header, and request body)", + Namespace: PrometheusNamespace, + ConstLabels: constLabels, + Buckets: buckets.LengthBuckets, + NativeHistogramBucketFactor: bucketFactor, + NativeHistogramMaxBucketNumber: maxBuckets, }, requestTags, em, @@ -213,11 +220,13 @@ func NewSocketCollector(pod, namespace, class string, metricsPerHost, reportStat requestLength: histogramMetric( &prometheus.HistogramOpts{ - Name: "request_size", - Help: "The request length (including request line, header, and request body)", - Namespace: PrometheusNamespace, - ConstLabels: constLabels, - Buckets: buckets.LengthBuckets, + Name: "request_size", + Help: "The request length (including request line, header, and request body)", + Namespace: PrometheusNamespace, + ConstLabels: constLabels, + Buckets: buckets.LengthBuckets, + NativeHistogramBucketFactor: bucketFactor, + NativeHistogramMaxBucketNumber: maxBuckets, }, requestTags, em, @@ -248,19 +257,6 @@ func NewSocketCollector(pod, namespace, class string, metricsPerHost, reportStat em, mm, ), - - upstreamLatency: summaryMetric( - &prometheus.SummaryOpts{ - Name: "ingress_upstream_latency_seconds", - Help: "DEPRECATED Upstream service latency per Ingress", - Namespace: PrometheusNamespace, - ConstLabels: constLabels, - Objectives: defObjectives, - }, - []string{"ingress", "namespace", "service", "canary"}, - em, - mm, - ), } sc.metricMapping = mm @@ -275,18 +271,6 @@ func containsMetric(excludeMetrics map[string]struct{}, name string) bool { return false } -func summaryMetric(opts *prometheus.SummaryOpts, requestTags []string, excludeMetrics map[string]struct{}, metricMapping metricMapping) *prometheus.SummaryVec { - if containsMetric(excludeMetrics, opts.Name) { - return nil - } - m := prometheus.NewSummaryVec( - *opts, - requestTags, - ) - metricMapping[prometheus.BuildFQName(PrometheusNamespace, "", opts.Name)] = m - return m -} - func counterMetric(opts *prometheus.CounterOpts, requestTags []string, excludeMetrics map[string]struct{}, metricMapping metricMapping) *prometheus.CounterVec { if containsMetric(excludeMetrics, opts.Name) { return nil @@ -324,8 +308,8 @@ func (sc *SocketCollector) handleMessage(msg []byte) { for i := range statsBatch { stats := &statsBatch[i] - if sc.metricsPerHost && !sc.hosts.Has(stats.Host) { - klog.V(3).InfoS("Skipping metric for host not being served", "host", stats.Host) + if sc.metricsPerHost && !sc.hosts.Has(stats.Host) && !sc.metricsPerUndefinedHost { + klog.V(3).InfoS("Skipping metric for host not explicitly defined in an ingress", "host", stats.Host) continue } @@ -358,13 +342,6 @@ func (sc *SocketCollector) handleMessage(msg []byte) { collectorLabels["host"] = stats.Host } - latencyLabels := prometheus.Labels{ - "namespace": stats.Namespace, - "ingress": stats.Ingress, - "service": stats.Service, - "canary": stats.Canary, - } - if sc.requests != nil { requestsMetric, err := sc.requests.GetMetricWith(collectorLabels) if err != nil { @@ -383,15 +360,6 @@ func (sc *SocketCollector) handleMessage(msg []byte) { connectTimeMetric.Observe(stats.Latency) } } - - if sc.upstreamLatency != nil { - latencyMetric, err := sc.upstreamLatency.GetMetricWith(latencyLabels) - if err != nil { - klog.ErrorS(err, "Error fetching latency metric") - } else { - latencyMetric.Observe(stats.Latency) - } - } } if stats.HeaderTime != -1 && sc.headerTime != nil { diff --git a/internal/ingress/metric/collectors/socket_test.go b/internal/ingress/metric/collectors/socket_test.go index 2113b4725..3a1f29f35 100644 --- a/internal/ingress/metric/collectors/socket_test.go +++ b/internal/ingress/metric/collectors/socket_test.go @@ -83,15 +83,19 @@ func TestCollector(t *testing.T) { prometheus.ExponentialBuckets(10, 10, 7), } + bucketFactor := 1.1 + maxBuckets := uint32(100) + cases := []struct { - name string - data []string - metrics []string - useStatusClasses bool - excludeMetrics []string - wantBefore string - removeIngresses []string - wantAfter string + name string + data []string + metrics []string + metricsPerUndefinedHost bool + useStatusClasses bool + excludeMetrics []string + wantBefore string + removeIngresses []string + wantAfter string }{ { name: "invalid metric object should not increase prometheus metrics", @@ -588,13 +592,69 @@ func TestCollector(t *testing.T) { nginx_ingress_controller_response_duration_seconds_count{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx"} 1 `, }, + { + name: "metrics with a host should not be dropped when the host is not in the hosts slice but metricsPerUndefinedHost is true", + data: []string{`[{ + "host":"wildcard.testshop.com", + "status":"200", + "bytesSent":150.0, + "method":"GET", + "path":"/admin", + "requestLength":300.0, + "requestTime":60.0, + "upstreamLatency":1.0, + "upstreamHeaderTime":5.0, + "upstreamName":"test-upstream", + "upstreamIP":"1.1.1.1:8080", + "upstreamResponseTime":200, + "upstreamStatus":"220", + "namespace":"test-app-production", + "ingress":"web-yml", + "service":"test-app", + "canary":"" + }]`}, + excludeMetrics: []string{"response_duration_seconds2", "test.*", "nginx_ingress_.*", "response_duration_secon"}, + metrics: []string{"nginx_ingress_controller_requests"}, + metricsPerUndefinedHost: true, + useStatusClasses: true, + wantBefore: ` + # HELP nginx_ingress_controller_requests The total number of client requests + # TYPE nginx_ingress_controller_requests counter + nginx_ingress_controller_requests{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="wildcard.testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx"} 1 + `, + }, + { + name: "metrics with a host should be dropped when the host is not in the hosts slice", + data: []string{`[{ + "host":"wildcard.testshop.com", + "status":"200", + "bytesSent":150.0, + "method":"GET", + "path":"/admin", + "requestLength":300.0, + "requestTime":60.0, + "upstreamLatency":1.0, + "upstreamHeaderTime":5.0, + "upstreamName":"test-upstream", + "upstreamIP":"1.1.1.1:8080", + "upstreamResponseTime":200, + "upstreamStatus":"220", + "namespace":"test-app-production", + "ingress":"web-yml", + "service":"test-app", + "canary":"" + }]`}, + excludeMetrics: []string{"response_duration_seconds2", "test.*", "nginx_ingress_.*", "response_duration_secon"}, + metrics: []string{"nginx_ingress_controller_requests"}, + useStatusClasses: true, + }, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { registry := prometheus.NewPedanticRegistry() - sc, err := NewSocketCollector("pod", "default", "ingress", true, c.useStatusClasses, buckets, c.excludeMetrics) + sc, err := NewSocketCollector("pod", "default", "ingress", true, c.metricsPerUndefinedHost, c.useStatusClasses, buckets, bucketFactor, maxBuckets, c.excludeMetrics) if err != nil { t.Errorf("%v: unexpected error creating new SocketCollector: %v", c.name, err) } diff --git a/internal/ingress/metric/main.go b/internal/ingress/metric/main.go index 93c31622c..9ed401d19 100644 --- a/internal/ingress/metric/main.go +++ b/internal/ingress/metric/main.go @@ -71,7 +71,7 @@ type collector struct { } // NewCollector creates a new metric collector the for ingress controller -func NewCollector(metricsPerHost, reportStatusClasses bool, registry *prometheus.Registry, ingressclass string, buckets collectors.HistogramBuckets, excludedSocketMetrics []string) (Collector, error) { +func NewCollector(metricsPerHost, metricsPerUndefinedHost, reportStatusClasses bool, registry *prometheus.Registry, ingressclass string, buckets collectors.HistogramBuckets, bucketFactor float64, maxBuckets uint32, excludedSocketMetrics []string) (Collector, error) { podNamespace := os.Getenv("POD_NAMESPACE") if podNamespace == "" { podNamespace = "default" @@ -89,7 +89,7 @@ func NewCollector(metricsPerHost, reportStatusClasses bool, registry *prometheus return nil, err } - s, err := collectors.NewSocketCollector(podName, podNamespace, ingressclass, metricsPerHost, reportStatusClasses, buckets, excludedSocketMetrics) + s, err := collectors.NewSocketCollector(podName, podNamespace, ingressclass, metricsPerHost, metricsPerUndefinedHost, reportStatusClasses, buckets, bucketFactor, maxBuckets, excludedSocketMetrics) if err != nil { return nil, err } diff --git a/internal/ingress/resolver/main.go b/internal/ingress/resolver/main.go index 7d17f4e16..259f44e49 100644 --- a/internal/ingress/resolver/main.go +++ b/internal/ingress/resolver/main.go @@ -29,10 +29,10 @@ type Resolver interface { // GetSecurityConfiguration returns the configuration options from Ingress GetSecurityConfiguration() defaults.SecurityConfiguration - // GetConfigMap searches for configmap containing the namespace and name usting the character / + // GetConfigMap searches for configmap containing the namespace and name using the character / GetConfigMap(string) (*apiv1.ConfigMap, error) - // GetSecret searches for secrets containing the namespace and name using a the character / + // GetSecret searches for secrets containing the namespace and name using the character / GetSecret(string) (*apiv1.Secret, error) // GetAuthCertificate resolves a given secret name into an SSL certificate and CRL. @@ -42,7 +42,7 @@ type Resolver interface { // ca.crl: contains the revocation list used for authentication GetAuthCertificate(string) (*AuthSSLCert, error) - // GetService searches for services containing the namespace and name using a the character / + // GetService searches for services containing the namespace and name using the character / GetService(string) (*apiv1.Service, error) } diff --git a/internal/ingress/resolver/mock.go b/internal/ingress/resolver/mock.go index 679c3b13c..3abfe7eda 100644 --- a/internal/ingress/resolver/mock.go +++ b/internal/ingress/resolver/mock.go @@ -39,7 +39,7 @@ func (m Mock) GetDefaultBackend() defaults.Backend { func (m Mock) GetSecurityConfiguration() defaults.SecurityConfiguration { defRisk := m.AnnotationsRiskLevel if defRisk == "" { - defRisk = "Critical" + defRisk = "High" } return defaults.SecurityConfiguration{ AnnotationsRiskLevel: defRisk, @@ -47,7 +47,7 @@ func (m Mock) GetSecurityConfiguration() defaults.SecurityConfiguration { } } -// GetSecret searches for secrets contenating the namespace and name using a the character / +// GetSecret searches for secrets containing the namespace and name using the character / func (m Mock) GetSecret(string) (*apiv1.Secret, error) { return nil, nil } @@ -60,12 +60,12 @@ func (m Mock) GetAuthCertificate(string) (*AuthSSLCert, error) { return nil, nil } -// GetService searches for services contenating the namespace and name using a the character / +// GetService searches for services containing the namespace and name using the character / func (m Mock) GetService(string) (*apiv1.Service, error) { return nil, nil } -// GetConfigMap searches for configMaps contenating the namespace and name using a the character / +// GetConfigMap searches for configMaps containing the namespace and name using the character / func (m Mock) GetConfigMap(name string) (*apiv1.ConfigMap, error) { if v, ok := m.ConfigMaps[name]; ok { return v, nil diff --git a/internal/net/ssl/ssl.go b/internal/net/ssl/ssl.go index f8bac2377..0592303bc 100644 --- a/internal/net/ssl/ssl.go +++ b/internal/net/ssl/ssl.go @@ -442,7 +442,7 @@ func getFakeHostSSLCert(host string) (cert, key []byte) { // fullChainCert checks if a certificate file contains issues in the intermediate CA chain // Returns a new certificate with the intermediate certificates. -// If the certificate does not contains issues with the chain it return an empty byte array +// If the certificate does not contain issues with the chain it returns an empty byte array func fullChainCert(in []byte) ([]byte, error) { cert, err := certUtil.DecodeCertificate(in) if err != nil { @@ -523,7 +523,7 @@ func (tl *TLSListener) GetCertificate(*tls.ClientHelloInfo) (*tls.Certificate, e return tl.certificate, tl.err } -// TLSConfig instanciates a TLS configuration, always providing an up to date certificate +// TLSConfig instantiates a TLS configuration, always providing an up to date certificate func (tl *TLSListener) TLSConfig() *tls.Config { return &tls.Config{ GetCertificate: tl.GetCertificate, diff --git a/internal/task/queue.go b/internal/task/queue.go index f92f2a501..8753bed34 100644 --- a/internal/task/queue.go +++ b/internal/task/queue.go @@ -36,7 +36,7 @@ var keyFunc = cache.DeletionHandlingMetaNamespaceKeyFunc // which timestamp is older than the last successful get operation. type Queue struct { // queue is the work queue the worker polls - queue workqueue.RateLimitingInterface + queue workqueue.TypedRateLimitingInterface[any] // sync is called for each item in the queue sync func(interface{}) error // workerDone is closed when the worker exits @@ -172,7 +172,7 @@ func NewTaskQueue(syncFn func(interface{}) error) *Queue { // NewCustomTaskQueue creates a new custom task queue with the given sync function. func NewCustomTaskQueue(syncFn func(interface{}) error, fn func(interface{}) (interface{}, error)) *Queue { q := &Queue{ - queue: workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()), + queue: workqueue.NewTypedRateLimitingQueue(workqueue.DefaultTypedControllerRateLimiter[any]()), sync: syncFn, workerDone: make(chan bool), fn: fn, diff --git a/magefiles/go.mod b/magefiles/go.mod index 8e146d70e..f11ab740e 100644 --- a/magefiles/go.mod +++ b/magefiles/go.mod @@ -1,6 +1,6 @@ module k8s.io/ingress-nginx/magefiles -go 1.22.6 +go 1.23.6 require ( github.com/blang/semver/v4 v4.0.0 @@ -28,7 +28,7 @@ require ( github.com/rogpeppe/go-internal v1.11.0 // indirect github.com/sergi/go-diff v1.3.1 // indirect github.com/stretchr/testify v1.9.0 // indirect - golang.org/x/crypto v0.21.0 // indirect + golang.org/x/crypto v0.31.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect diff --git a/magefiles/go.sum b/magefiles/go.sum index 16bc8460f..8684d4701 100644 --- a/magefiles/go.sum +++ b/magefiles/go.sum @@ -89,8 +89,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -121,16 +121,16 @@ golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= diff --git a/magefiles/steps/helm.go b/magefiles/steps/helm.go index 245f5e1c0..73c9b0b3b 100644 --- a/magefiles/steps/helm.go +++ b/magefiles/steps/helm.go @@ -170,7 +170,7 @@ func runHelmDocs() error { if err != nil { return err } - err = sh.RunV("helm-docs", "--chart-search-root=${PWD}/charts") + err = sh.RunV("helm-docs", "--chart-search-root", "${PWD}/charts") if err != nil { return err } @@ -181,7 +181,7 @@ func installHelmDocs() error { utils.Info("HELM Install HelmDocs") g0 := sh.RunCmd("go") - err := g0("install", "github.com/norwoodj/helm-docs/cmd/helm-docs@v1.11.0") + err := g0("install", "github.com/norwoodj/helm-docs/cmd/helm-docs@latest") if err != nil { return err } diff --git a/magefiles/utils/helm.go b/magefiles/utils/helm.go index dea68caab..cb8acae57 100644 --- a/magefiles/utils/helm.go +++ b/magefiles/utils/helm.go @@ -31,7 +31,6 @@ type IngressChartValue struct { RunAsUser int `yaml:"runAsUser"` AllowPrivilegeEscalation bool `yaml:"allowPrivilegeEscalation"` } `yaml:"image"` - ExistingPsp string `yaml:"existingPsp"` ContainerName string `yaml:"containerName"` ContainerPort struct { HTTP int `yaml:"http"` @@ -208,13 +207,6 @@ type IngressChartValue struct { ExtraVolumes []interface{} `yaml:"extraVolumes"` ExtraInitContainers []interface{} `yaml:"extraInitContainers"` ExtraModules []interface{} `yaml:"extraModules"` - Opentelemetry struct { - Enabled bool `yaml:"enabled"` - Image string `yaml:"image"` - ContainerSecurityContext struct { - AllowPrivilegeEscalation bool `yaml:"allowPrivilegeEscalation"` - } `yaml:"containerSecurityContext"` - } `yaml:"opentelemetry"` AdmissionWebhooks struct { Annotations struct{} `yaml:"annotations"` Enabled bool `yaml:"enabled"` @@ -226,7 +218,6 @@ type IngressChartValue struct { NamespaceSelector struct{} `yaml:"namespaceSelector"` ObjectSelector struct{} `yaml:"objectSelector"` Labels struct{} `yaml:"labels"` - ExistingPsp string `yaml:"existingPsp"` NetworkPolicyEnabled bool `yaml:"networkPolicyEnabled"` Service struct { Annotations struct{} `yaml:"annotations"` @@ -329,7 +320,6 @@ type IngressChartValue struct { ReadOnlyRootFilesystem bool `yaml:"readOnlyRootFilesystem"` AllowPrivilegeEscalation bool `yaml:"allowPrivilegeEscalation"` } `yaml:"image"` - ExistingPsp string `yaml:"existingPsp"` ExtraArgs struct{} `yaml:"extraArgs"` ServiceAccount struct { Create bool `yaml:"create"` @@ -388,9 +378,6 @@ type IngressChartValue struct { Create bool `yaml:"create"` Scope bool `yaml:"scope"` } `yaml:"rbac"` - PodSecurityPolicy struct { - Enabled bool `yaml:"enabled"` - } `yaml:"podSecurityPolicy"` ServiceAccount struct { Create bool `yaml:"create"` Name string `yaml:"name"` diff --git a/mkdocs.yml b/mkdocs.yml index cbc2988ce..b59546c9c 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -50,6 +50,7 @@ theme: - navigation.tabs.sticky - navigation.instant - navigation.sections + - content.code.copy palette: primary: "teal" @@ -83,6 +84,7 @@ nav: - Introduction: "user-guide/nginx-configuration/index.md" - Basic usage: "user-guide/basic-usage.md" - Annotations: "user-guide/nginx-configuration/annotations.md" + - Annotations Risks: "user-guide/nginx-configuration/annotations-risk.md" - ConfigMap: "user-guide/nginx-configuration/configmap.md" - Custom NGINX template: "user-guide/nginx-configuration/custom-template.md" - Log format: "user-guide/nginx-configuration/log-format.md" @@ -123,7 +125,6 @@ nav: - Rewrite: "examples/rewrite/README.md" - Static IPs: "examples/static-ip/README.md" - TLS termination: "examples/tls-termination/README.md" - - Pod Security Policy (PSP): "examples/psp/README.md" - Open Policy Agent rules: "examples/openpolicyagent/README.md" - Canary Deployments: "examples/canary/README.md" - Developer Guide: diff --git a/pkg/apis/ingress/types.go b/pkg/apis/ingress/types.go index ca5df56c9..ccdd49fe9 100644 --- a/pkg/apis/ingress/types.go +++ b/pkg/apis/ingress/types.go @@ -27,8 +27,8 @@ import ( "k8s.io/ingress-nginx/internal/ingress/annotations/authtls" "k8s.io/ingress-nginx/internal/ingress/annotations/connection" "k8s.io/ingress-nginx/internal/ingress/annotations/cors" + "k8s.io/ingress-nginx/internal/ingress/annotations/customheaders" "k8s.io/ingress-nginx/internal/ingress/annotations/fastcgi" - "k8s.io/ingress-nginx/internal/ingress/annotations/globalratelimit" "k8s.io/ingress-nginx/internal/ingress/annotations/ipallowlist" "k8s.io/ingress-nginx/internal/ingress/annotations/ipdenylist" "k8s.io/ingress-nginx/internal/ingress/annotations/log" @@ -198,10 +198,10 @@ type Server struct { Aliases []string `json:"aliases,omitempty"` // RedirectFromToWWW returns if a redirect to/from prefix www is required RedirectFromToWWW bool `json:"redirectFromToWWW,omitempty"` - // CertificateAuth indicates the this server requires mutual authentication + // CertificateAuth indicates this server requires mutual authentication // +optional CertificateAuth authtls.Config `json:"certificateAuth"` - // ProxySSL indicates the this server uses client certificate to access backends + // ProxySSL indicates this server uses client certificate to access backends // +optional ProxySSL proxyssl.Config `json:"proxySSL"` // ServerSnippet returns the snippet of server @@ -219,7 +219,7 @@ type Server struct { // Location describes an URI inside a server. // Also contains additional information about annotations in the Ingress. // -// In some cases when more than one annotations is defined a particular order in the execution +// In some cases when more than one annotation is defined a particular order in the execution // is required. // The chain in the execution order of annotations should be: // - Denylist @@ -263,7 +263,8 @@ type Location struct { BasicDigestAuth auth.Config `json:"basicDigestAuth,omitempty"` // Denied returns an error when this location cannot not be allowed // Requesting a denied location should return HTTP code 403. - Denied *string `json:"denied,omitempty"` + Denied *string `json:"denied,omitempty"` + CustomHeaders customheaders.Config `json:"customHeaders,omitempty"` // CorsConfig returns the Cors Configuration for the ingress rule // +optional CorsConfig cors.Config `json:"corsConfig,omitempty"` @@ -283,10 +284,6 @@ type Location struct { // The Redirect annotation precedes RateLimit // +optional RateLimit ratelimit.Config `json:"rateLimit,omitempty"` - // GlobalRateLimit similar to RateLimit - // but this is applied globally across multiple replicas. - // +optional - GlobalRateLimit globalratelimit.Config `json:"globalRateLimit,omitempty"` // Redirect describes a temporal o permanent redirection this location. // +optional Redirect redirect.Config `json:"redirect,omitempty"` @@ -345,7 +342,7 @@ type Location struct { // CustomHTTPErrors specifies the error codes that should be intercepted. // +optional CustomHTTPErrors []int `json:"custom-http-errors"` - // ProxyInterceptErrors disables error intecepting when using CustomHTTPErrors + // ProxyInterceptErrors disables error interception when using CustomHTTPErrors // e.g. custom 404 and 503 when service-a does not exist or is not available // but service-a can return 404 and 503 error codes without intercept // +optional diff --git a/pkg/apis/ingress/types_equals.go b/pkg/apis/ingress/types_equals.go index eeed9a06e..6fba3bd45 100644 --- a/pkg/apis/ingress/types_equals.go +++ b/pkg/apis/ingress/types_equals.go @@ -390,9 +390,6 @@ func (l1 *Location) Equal(l2 *Location) bool { if !(&l1.RateLimit).Equal(&l2.RateLimit) { return false } - if !(&l1.GlobalRateLimit).Equal(&l2.GlobalRateLimit) { - return false - } if !(&l1.Redirect).Equal(&l2.Redirect) { return false } @@ -470,6 +467,10 @@ func (l1 *Location) Equal(l2 *Location) bool { return false } + if !l1.CustomHeaders.Equal(&l2.CustomHeaders) { + return false + } + return true } diff --git a/pkg/flags/flags.go b/pkg/flags/flags.go index d3bc4ee86..ce24160fd 100644 --- a/pkg/flags/flags.go +++ b/pkg/flags/flags.go @@ -17,6 +17,7 @@ limitations under the License. package flags import ( + "errors" "flag" "fmt" "net" @@ -132,6 +133,9 @@ Requires setting the publish-service parameter to a valid Service reference.`) electionID = flags.String("election-id", "ingress-controller-leader", `Election id to use for Ingress status updates.`) + electionTTL = flags.Duration("election-ttl", 30*time.Second, + `Duration a leader election is valid before it's getting re-elected`) + updateStatusOnShutdown = flags.Bool("update-status-on-shutdown", true, `Update the load-balancer status of Ingress objects when the controller shuts down. Requires the update-status parameter.`) @@ -146,14 +150,17 @@ Requires the update-status parameter.`) enableSSLPassthrough = flags.Bool("enable-ssl-passthrough", false, `Enable SSL Passthrough.`) + disableLeaderElection = flags.Bool("disable-leader-election", false, + `Disable Leader Election on NGINX Controller.`) + disableServiceExternalName = flags.Bool("disable-svc-external-name", false, `Disable support for Services of type ExternalName.`) annotationsPrefix = flags.String("annotations-prefix", parser.DefaultAnnotationsPrefix, `Prefix of the Ingress annotations specific to the NGINX controller.`) - enableAnnotationValidation = flags.Bool("enable-annotation-validation", false, - `If true, will enable the annotation validation feature. This value will be defaulted to true on a future release`) + enableAnnotationValidation = flags.Bool("enable-annotation-validation", true, + `If true, will enable the annotation validation feature. Defaults to true`) enableSSLChainCompletion = flags.Bool("enable-ssl-chain-completion", false, `Autocomplete SSL certificate chains with missing intermediate CA certificates. @@ -167,16 +174,20 @@ extension for this to succeed.`) `Customized address (or addresses, separated by comma) to set as the load-balancer status of Ingress objects this controller satisfies. Requires the update-status parameter.`) - enableMetrics = flags.Bool("enable-metrics", true, + enableMetrics = flags.Bool("enable-metrics", false, `Enables the collection of NGINX metrics.`) metricsPerHost = flags.Bool("metrics-per-host", true, `Export metrics per-host.`) + metricsPerUndefinedHost = flags.Bool("metrics-per-undefined-host", false, + `Export metrics per-host even if the host is not defined in an ingress. Requires --metrics-per-host to be set to true.`) reportStatusClasses = flags.Bool("report-status-classes", false, `Use status classes (2xx, 3xx, 4xx and 5xx) instead of status codes in metrics.`) timeBuckets = flags.Float64Slice("time-buckets", prometheus.DefBuckets, "Set of buckets which will be used for prometheus histogram metrics such as RequestTime, ResponseTime.") lengthBuckets = flags.Float64Slice("length-buckets", prometheus.LinearBuckets(10, 10, 10), "Set of buckets which will be used for prometheus histogram metrics such as RequestLength, ResponseLength.") sizeBuckets = flags.Float64Slice("size-buckets", prometheus.ExponentialBuckets(10, 10, 7), "Set of buckets which will be used for prometheus histogram metrics such as BytesSent.") + bucketFactor = flags.Float64("bucket-factor", 0, "Bucket factor for native histograms. Value must be > 1 for enabling native histograms.") + maxBuckets = flags.Uint32("max-buckets", 100, "Maximum number of buckets for native histograms.") excludeSocketMetrics = flags.StringSlice("exclude-socket-metrics", []string{}, "et of socket request metrics to exclude which won't be exported nor being calculated. E.g. 'nginx_ingress_controller_success,nginx_ingress_controller_header_duration_seconds'.") monitorMaxBatchSize = flags.Int("monitor-max-batch-size", 10000, "Max batch size of NGINX metrics.") @@ -226,7 +237,7 @@ Takes the form ":port". If not provided, no admission controller is starte flags.StringVar(&nginx.MaxmindMirror, "maxmind-mirror", "", `Maxmind mirror url (example: http://geoip.local/databases.`) flags.StringVar(&nginx.MaxmindLicenseKey, "maxmind-license-key", "", `Maxmind license key to download GeoLite2 Databases. -https://blog.maxmind.com/2019/12/18/significant-changes-to-accessing-and-using-geolite2-databases .`) +https://blog.maxmind.com/2019/12/significant-changes-to-accessing-and-using-geolite2-databases/ .`) flags.StringVar(&nginx.MaxmindEditionIDs, "maxmind-edition-ids", "GeoLite2-City,GeoLite2-ASN", `Maxmind edition ids to download GeoLite2 Databases.`) flags.IntVar(&nginx.MaxmindRetriesCount, "maxmind-retries-count", 1, "Number of attempts to download the GeoIP DB.") flags.DurationVar(&nginx.MaxmindRetriesTimeout, "maxmind-retries-timeout", time.Second*0, "Maxmind downloading delay between 1st and 2nd attempt, 0s - do not retry to download if something went wrong.") @@ -311,6 +322,14 @@ https://blog.maxmind.com/2019/12/18/significant-changes-to-accessing-and-using-g } } + if *metricsPerUndefinedHost && !*metricsPerHost { + return false, nil, errors.New("--metrics-per-undefined-host=true must be passed with --metrics-per-host=true") + } + + if *electionTTL <= 0 { + *electionTTL = 30 * time.Second + } + histogramBuckets := &collectors.HistogramBuckets{ TimeBuckets: *timeBuckets, LengthBuckets: *lengthBuckets, @@ -324,15 +343,20 @@ https://blog.maxmind.com/2019/12/18/significant-changes-to-accessing-and-using-g KubeConfigFile: *kubeConfigFile, UpdateStatus: *updateStatus, ElectionID: *electionID, + ElectionTTL: *electionTTL, EnableProfiling: *profiling, EnableMetrics: *enableMetrics, MetricsPerHost: *metricsPerHost, + MetricsPerUndefinedHost: *metricsPerUndefinedHost, MetricsBuckets: histogramBuckets, + MetricsBucketFactor: *bucketFactor, + MetricsMaxBuckets: *maxBuckets, ReportStatusClasses: *reportStatusClasses, ExcludeSocketMetrics: *excludeSocketMetrics, MonitorMaxBatchSize: *monitorMaxBatchSize, DisableServiceExternalName: *disableServiceExternalName, EnableSSLPassthrough: *enableSSLPassthrough, + DisableLeaderElection: *disableLeaderElection, ResyncPeriod: *resyncPeriod, DefaultService: *defaultSvc, Namespace: *watchNamespace, diff --git a/pkg/flags/flags_test.go b/pkg/flags/flags_test.go index bffe2b16d..fdf153021 100644 --- a/pkg/flags/flags_test.go +++ b/pkg/flags/flags_test.go @@ -19,6 +19,7 @@ package flags import ( "os" "testing" + "time" ) func TestNoMandatoryFlag(t *testing.T) { @@ -109,3 +110,131 @@ func TestMaxmindRetryDownload(t *testing.T) { t.Fatalf("Expected an error parsing flags but none returned") } } + +func TestDisableLeaderElectionFlag(t *testing.T) { + ResetForTesting(func() { t.Fatal("Parsing failed") }) + + oldArgs := os.Args + defer func() { os.Args = oldArgs }() + os.Args = []string{"cmd", "--disable-leader-election", "--http-port", "80", "--https-port", "443"} + + _, conf, err := ParseFlags() + if err != nil { + t.Fatalf("Unexpected error parsing default flags: %v", err) + } + + if !conf.DisableLeaderElection { + t.Fatalf("Expected --disable-leader-election and conf.DisableLeaderElection as true, but found: %v", conf.DisableLeaderElection) + } +} + +func TestIfLeaderElectionDisabledFlagIsFalse(t *testing.T) { + ResetForTesting(func() { t.Fatal("Parsing failed") }) + + oldArgs := os.Args + defer func() { os.Args = oldArgs }() + os.Args = []string{"cmd", "--http-port", "80", "--https-port", "443"} + + _, conf, err := ParseFlags() + if err != nil { + t.Fatalf("Unexpected error parsing default flags: %v", err) + } + + if conf.DisableLeaderElection { + t.Fatalf("Expected --disable-leader-election and conf.DisableLeaderElection as false, but found: %v", conf.DisableLeaderElection) + } +} + +func TestLeaderElectionTTLDefaultValue(t *testing.T) { + ResetForTesting(func() { t.Fatal("Parsing failed") }) + + oldArgs := os.Args + defer func() { os.Args = oldArgs }() + os.Args = []string{"cmd", "--http-port", "80", "--https-port", "443"} + + _, conf, err := ParseFlags() + if err != nil { + t.Fatalf("Unexpected error parsing default flags: %v", err) + } + + if conf.ElectionTTL != 30*time.Second { + t.Fatalf("Expected --election-ttl and conf.ElectionTTL as 30s, but found: %v", conf.ElectionTTL) + } +} + +func TestLeaderElectionTTLParseValueInSeconds(t *testing.T) { + ResetForTesting(func() { t.Fatal("Parsing failed") }) + + oldArgs := os.Args + defer func() { os.Args = oldArgs }() + os.Args = []string{"cmd", "--http-port", "80", "--https-port", "443", "--election-ttl", "10s"} + + _, conf, err := ParseFlags() + if err != nil { + t.Fatalf("Unexpected error parsing default flags: %v", err) + } + + if conf.ElectionTTL != 10*time.Second { + t.Fatalf("Expected --election-ttl and conf.ElectionTTL as 10s, but found: %v", conf.ElectionTTL) + } +} + +func TestLeaderElectionTTLParseValueInMinutes(t *testing.T) { + ResetForTesting(func() { t.Fatal("Parsing failed") }) + + oldArgs := os.Args + defer func() { os.Args = oldArgs }() + os.Args = []string{"cmd", "--http-port", "80", "--https-port", "443", "--election-ttl", "10m"} + + _, conf, err := ParseFlags() + if err != nil { + t.Fatalf("Unexpected error parsing default flags: %v", err) + } + + if conf.ElectionTTL != 10*time.Minute { + t.Fatalf("Expected --election-ttl and conf.ElectionTTL as 10m, but found: %v", conf.ElectionTTL) + } +} + +func TestLeaderElectionTTLParseValueInHours(t *testing.T) { + ResetForTesting(func() { t.Fatal("Parsing failed") }) + + oldArgs := os.Args + defer func() { os.Args = oldArgs }() + os.Args = []string{"cmd", "--http-port", "80", "--https-port", "443", "--election-ttl", "1h"} + + _, conf, err := ParseFlags() + if err != nil { + t.Fatalf("Unexpected error parsing default flags: %v", err) + } + + if conf.ElectionTTL != 1*time.Hour { + t.Fatalf("Expected --election-ttl and conf.ElectionTTL as 1h, but found: %v", conf.ElectionTTL) + } +} + +func TestMetricsPerUndefinedHost(t *testing.T) { + ResetForTesting(func() { t.Fatal("Parsing failed") }) + + oldArgs := os.Args + defer func() { os.Args = oldArgs }() + os.Args = []string{"cmd", "--metrics-per-undefined-host=true"} + + _, _, err := ParseFlags() + if err != nil { + t.Fatalf("Expected no error but got: %s", err) + } +} + +func TestMetricsPerUndefinedHostWithMetricsPerHostFalse(t *testing.T) { + ResetForTesting(func() { t.Fatal("Parsing failed") }) + + oldArgs := os.Args + defer func() { os.Args = oldArgs }() + os.Args = []string{"cmd", "--metrics-per-host=false", "--metrics-per-undefined-host=true"} + + _, _, err := ParseFlags() + if err == nil { + t.Fatalf("Expected an error parsing flags but none returned") + } +} diff --git a/rootfs/Dockerfile b/rootfs/Dockerfile index a04cfe3de..9b7753b5d 100644 --- a/rootfs/Dockerfile +++ b/rootfs/Dockerfile @@ -59,7 +59,7 @@ RUN bash -xeu -c ' \ ); \ for dir in "${writeDirs[@]}"; do \ mkdir -p ${dir}; \ - chown -R www-data.www-data ${dir}; \ + chown -R www-data:www-data ${dir}; \ done' \ # LD_LIBRARY_PATH does not work so below is needed for opentelemetry/other modules # Put libs of newer modules under `/modules_mount//lib` and add that path below diff --git a/rootfs/Dockerfile-chroot b/rootfs/Dockerfile-chroot index c06db2252..481b311e2 100644 --- a/rootfs/Dockerfile-chroot +++ b/rootfs/Dockerfile-chroot @@ -23,7 +23,7 @@ RUN apk update \ && apk upgrade \ && /chroot.sh -FROM alpine:3.20.0 +FROM alpine:3.21 ARG TARGETARCH ARG VERSION @@ -78,7 +78,7 @@ RUN bash -xeu -c ' \ ); \ for dir in "${writeDirs[@]}"; do \ mkdir -p ${dir}; \ - chown -R www-data.www-data ${dir}; \ + chown -R www-data:www-data ${dir}; \ done' \ # LD_LIBRARY_PATH does not work so below is needed for opentelemetry/other modules # Put libs of newer modules under `/modules_mount//lib` and add that path below @@ -103,7 +103,7 @@ RUN ln -sf /chroot/etc/nginx /etc/nginx \ && touch /chroot/var/log/nginx/access.log \ && chown www-data:www-data /chroot/var/log/nginx/access.log \ && echo "" > /chroot/etc/resolv.conf \ - && chown -R www-data.www-data /chroot/var/log/nginx /chroot/etc/resolv.conf \ + && chown -R www-data:www-data /chroot/var/log/nginx /chroot/etc/resolv.conf \ && mknod -m 0666 /chroot/dev/null c 1 3 \ && mknod -m 0666 /chroot/dev/random c 1 8 \ && mknod -m 0666 /chroot/dev/urandom c 1 9 \ diff --git a/rootfs/chroot.sh b/rootfs/chroot.sh index 38547b69c..4875ae535 100755 --- a/rootfs/chroot.sh +++ b/rootfs/chroot.sh @@ -39,7 +39,7 @@ writeDirs=( \ for dir in "${writeDirs[@]}"; do mkdir -p ${dir}; - chown -R www-data.www-data ${dir}; + chown -R www-data:www-data ${dir}; done mkdir -p /chroot/lib /chroot/proc /chroot/usr /chroot/bin /chroot/dev /chroot/run @@ -47,4 +47,5 @@ cp /etc/passwd /etc/group /etc/hosts /chroot/etc/ cp -a /usr/* /chroot/usr/ cp -a /etc/nginx/* /chroot/etc/nginx/ cp -a /etc/ingress-controller/* /chroot/etc/ingress-controller/ -cp /lib/ld-musl-* /lib/libcrypto* /lib/libssl* /lib/libz* /chroot/lib/ +cp /lib/ld-musl-* /chroot/lib/ +cp /usr/lib/libcrypto* /usr/lib/libssl* /usr/lib/libz* /chroot/usr/lib/ diff --git a/rootfs/etc/nginx/lua/global_throttle.lua b/rootfs/etc/nginx/lua/global_throttle.lua deleted file mode 100644 index bea8cfd17..000000000 --- a/rootfs/etc/nginx/lua/global_throttle.lua +++ /dev/null @@ -1,131 +0,0 @@ -local resty_global_throttle = require("resty.global_throttle") -local resty_ipmatcher = require("resty.ipmatcher") -local util = require("util") - -local ngx = ngx -local ngx_exit = ngx.exit -local ngx_log = ngx.log -local ngx_ERR = ngx.ERR -local ngx_INFO = ngx.INFO - -local _M = {} - -local DECISION_CACHE = ngx.shared.global_throttle_cache - --- it does not make sense to cache decision for too little time --- the benefit of caching likely is negated if we cache for too little time --- Lua Shared Dict's time resolution for expiry is 0.001. -local CACHE_THRESHOLD = 0.001 - -local DEFAULT_RAW_KEY = "remote_addr" - -local function should_ignore_request(ignored_cidrs) - if not ignored_cidrs or #ignored_cidrs == 0 then - return false - end - - local ignored_cidrs_matcher, err = resty_ipmatcher.new(ignored_cidrs) - if not ignored_cidrs_matcher then - ngx_log(ngx_ERR, "failed to initialize resty-ipmatcher: ", err) - return false - end - - local is_ignored - is_ignored, err = ignored_cidrs_matcher:match(ngx.var.remote_addr) - if err then - ngx_log(ngx_ERR, "failed to match ip: '", - ngx.var.remote_addr, "': ", err) - return false - end - - return is_ignored -end - -local function is_enabled(config, location_config) - if config.memcached.host == "" or config.memcached.port == 0 then - return false - end - if location_config.limit == 0 or - location_config.window_size == 0 then - return false - end - - if should_ignore_request(location_config.ignored_cidrs) then - return false - end - - return true -end - -local function get_namespaced_key_value(namespace, key_value) - return namespace .. key_value -end - -function _M.throttle(config, location_config) - if not is_enabled(config, location_config) then - return - end - - local key_value = util.generate_var_value(location_config.key) - if not key_value or key_value == "" then - key_value = ngx.var[DEFAULT_RAW_KEY] - end - - local namespaced_key_value = - get_namespaced_key_value(location_config.namespace, key_value) - - local is_limit_exceeding = DECISION_CACHE:get(namespaced_key_value) - if is_limit_exceeding then - ngx.var.global_rate_limit_exceeding = "c" - return ngx_exit(config.status_code) - end - - local my_throttle, err = resty_global_throttle.new( - location_config.namespace, - location_config.limit, - location_config.window_size, - { - provider = "memcached", - host = config.memcached.host, - port = config.memcached.port, - connect_timeout = config.memcached.connect_timeout, - max_idle_timeout = config.memcached.max_idle_timeout, - pool_size = config.memcached.pool_size, - } - ) - if err then - ngx.log(ngx.ERR, "faled to initialize resty_global_throttle: ", err) - -- fail open - return - end - - local desired_delay, estimated_final_count - estimated_final_count, desired_delay, err = my_throttle:process(key_value) - if err then - ngx.log(ngx.ERR, "error while processing key: ", err) - -- fail open - return - end - - if desired_delay then - if desired_delay > CACHE_THRESHOLD then - local ok - ok, err = - DECISION_CACHE:safe_add(namespaced_key_value, true, desired_delay) - if not ok then - if err ~= "exists" then - ngx_log(ngx_ERR, "failed to cache decision: ", err) - end - end - end - - ngx.var.global_rate_limit_exceeding = "y" - ngx_log(ngx_INFO, "limit is exceeding for ", - location_config.namespace, "/", key_value, - " with estimated_final_count: ", estimated_final_count) - - return ngx_exit(config.status_code) - end -end - -return _M diff --git a/rootfs/etc/nginx/lua/lua_ingress.lua b/rootfs/etc/nginx/lua/lua_ingress.lua index 49e0f5b05..a513928cf 100644 --- a/rootfs/etc/nginx/lua/lua_ingress.lua +++ b/rootfs/etc/nginx/lua/lua_ingress.lua @@ -1,8 +1,8 @@ local ngx_re_split = require("ngx.re").split +local string_to_bool = require("util").string_to_bool local certificate_configured_for_current_request = require("certificate").configured_for_current_request -local global_throttle = require("global_throttle") local ngx = ngx local io = io @@ -109,7 +109,16 @@ end -- rewrite gets called in every location context. -- This is where we do variable assignments to be used in subsequent -- phases or redirection -function _M.rewrite(location_config) +function _M.rewrite() + + local location_config = { + force_ssl_redirect = string_to_bool(ngx.var.force_ssl_redirect), + ssl_redirect = string_to_bool(ngx.var.ssl_redirect), + force_no_ssl_redirect = string_to_bool(ngx.var.force_no_ssl_redirect), + preserve_trailing_slash = string_to_bool(ngx.var.preserve_trailing_slash), + use_port_in_redirects = string_to_bool(ngx.var.use_port_in_redirects), + } + ngx.var.pass_access_scheme = ngx.var.scheme ngx.var.best_http_host = ngx.var.http_host or ngx.var.host @@ -164,7 +173,6 @@ function _M.rewrite(location_config) return ngx_redirect(uri, config.http_redirect_code) end - global_throttle.throttle(config.global_throttle, location_config.global_throttle) end function _M.header() diff --git a/rootfs/etc/nginx/lua/nginx/ngx_conf_balancer.lua b/rootfs/etc/nginx/lua/nginx/ngx_conf_balancer.lua new file mode 100644 index 000000000..977d3e964 --- /dev/null +++ b/rootfs/etc/nginx/lua/nginx/ngx_conf_balancer.lua @@ -0,0 +1,2 @@ +local balancer = require("balancer") +balancer.balance() \ No newline at end of file diff --git a/rootfs/etc/nginx/lua/nginx/ngx_conf_balancer_tcp_udp.lua b/rootfs/etc/nginx/lua/nginx/ngx_conf_balancer_tcp_udp.lua new file mode 100644 index 000000000..0442df7d8 --- /dev/null +++ b/rootfs/etc/nginx/lua/nginx/ngx_conf_balancer_tcp_udp.lua @@ -0,0 +1,2 @@ +local tcp_udp_balancer = require("tcp_udp_balancer") +tcp_udp_balancer.balance() \ No newline at end of file diff --git a/rootfs/etc/nginx/lua/nginx/ngx_conf_certificate.lua b/rootfs/etc/nginx/lua/nginx/ngx_conf_certificate.lua new file mode 100644 index 000000000..d33d2171b --- /dev/null +++ b/rootfs/etc/nginx/lua/nginx/ngx_conf_certificate.lua @@ -0,0 +1,2 @@ +local certificate = require("certificate") +certificate.call() \ No newline at end of file diff --git a/rootfs/etc/nginx/lua/nginx/ngx_conf_configuration.lua b/rootfs/etc/nginx/lua/nginx/ngx_conf_configuration.lua new file mode 100644 index 000000000..7864f40ef --- /dev/null +++ b/rootfs/etc/nginx/lua/nginx/ngx_conf_configuration.lua @@ -0,0 +1,2 @@ +local configuration = require("configuration") +configuration.call() \ No newline at end of file diff --git a/rootfs/etc/nginx/lua/nginx/ngx_conf_content_tcp_udp.lua b/rootfs/etc/nginx/lua/nginx/ngx_conf_content_tcp_udp.lua new file mode 100644 index 000000000..ed81e7ff3 --- /dev/null +++ b/rootfs/etc/nginx/lua/nginx/ngx_conf_content_tcp_udp.lua @@ -0,0 +1,2 @@ +local tcp_udp_configuration = require("tcp_udp_configuration") +tcp_udp_configuration.call() \ No newline at end of file diff --git a/rootfs/etc/nginx/lua/nginx/ngx_conf_external_auth.lua b/rootfs/etc/nginx/lua/nginx/ngx_conf_external_auth.lua new file mode 100644 index 000000000..6c68cf07c --- /dev/null +++ b/rootfs/etc/nginx/lua/nginx/ngx_conf_external_auth.lua @@ -0,0 +1,30 @@ +local auth_path = ngx.var.auth_path +local auth_keepalive_share_vars = ngx.var.auth_keepalive_share_vars +local auth_response_headers = ngx.var.auth_response_headers +local ngx_re_split = require("ngx.re").split +local ipairs = ipairs +local ngx_log = ngx.log +local ngx_ERR = ngx.ERR + +local res = ngx.location.capture(auth_path, { + method = ngx.HTTP_GET, body = '', + share_all_vars = auth_keepalive_share_vars }) + +if res.status == ngx.HTTP_OK then + local header_parts, err = ngx_re_split(auth_response_headers, ",") + if err then + ngx_log(ngx_ERR, err) + return + end + ngx.var.auth_cookie = res.header['Set-Cookie'] + for i, header_name in ipairs(header_parts) do + local varname = "authHeader" .. tostring(i) + ngx.var[varname] = res.header[header_name] + end + return +end + +if res.status == ngx.HTTP_UNAUTHORIZED or res.status == ngx.HTTP_FORBIDDEN then + ngx.exit(res.status) +end +ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) \ No newline at end of file diff --git a/rootfs/etc/nginx/lua/nginx/ngx_conf_init_tcp_udp.lua b/rootfs/etc/nginx/lua/nginx/ngx_conf_init_tcp_udp.lua new file mode 100644 index 000000000..926ab7a03 --- /dev/null +++ b/rootfs/etc/nginx/lua/nginx/ngx_conf_init_tcp_udp.lua @@ -0,0 +1,2 @@ +local tcp_udp_balancer = require("tcp_udp_balancer") +tcp_udp_balancer.init_worker() \ No newline at end of file diff --git a/rootfs/etc/nginx/lua/nginx/ngx_conf_is_dynamic_lb_initialized.lua b/rootfs/etc/nginx/lua/nginx/ngx_conf_is_dynamic_lb_initialized.lua new file mode 100644 index 000000000..ade3114b1 --- /dev/null +++ b/rootfs/etc/nginx/lua/nginx/ngx_conf_is_dynamic_lb_initialized.lua @@ -0,0 +1,9 @@ +local configuration = require("configuration") +local backend_data = configuration.get_backends_data() +if not backend_data then + ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) + return +end + +ngx.say("OK") +ngx.exit(ngx.HTTP_OK) \ No newline at end of file diff --git a/rootfs/etc/nginx/lua/nginx/ngx_conf_log.lua b/rootfs/etc/nginx/lua/nginx/ngx_conf_log.lua new file mode 100644 index 000000000..8f3d57be6 --- /dev/null +++ b/rootfs/etc/nginx/lua/nginx/ngx_conf_log.lua @@ -0,0 +1,2 @@ +local monitor = require("monitor") +monitor.call() \ No newline at end of file diff --git a/rootfs/etc/nginx/lua/nginx/ngx_conf_log_block.lua b/rootfs/etc/nginx/lua/nginx/ngx_conf_log_block.lua new file mode 100644 index 000000000..72f6a6430 --- /dev/null +++ b/rootfs/etc/nginx/lua/nginx/ngx_conf_log_block.lua @@ -0,0 +1,11 @@ +local balancer = require("balancer") +local monitor = require("monitor") + +local luaconfig = ngx.shared.luaconfig +local enablemetrics = luaconfig:get("enablemetrics") + +balancer.log() + +if enablemetrics then + monitor.call() +end \ No newline at end of file diff --git a/rootfs/etc/nginx/lua/nginx/ngx_conf_rewrite_auth.lua b/rootfs/etc/nginx/lua/nginx/ngx_conf_rewrite_auth.lua new file mode 100644 index 000000000..0d16faba0 --- /dev/null +++ b/rootfs/etc/nginx/lua/nginx/ngx_conf_rewrite_auth.lua @@ -0,0 +1 @@ +ngx.var.cache_key = ngx.encode_base64(ngx.sha1_bin(ngx.var.tmp_cache_key)) \ No newline at end of file diff --git a/rootfs/etc/nginx/lua/nginx/ngx_conf_srv_hdr_filter.lua b/rootfs/etc/nginx/lua/nginx/ngx_conf_srv_hdr_filter.lua new file mode 100644 index 000000000..311a9b433 --- /dev/null +++ b/rootfs/etc/nginx/lua/nginx/ngx_conf_srv_hdr_filter.lua @@ -0,0 +1,2 @@ +local lua_ingress = require("lua_ingress") +lua_ingress.header() \ No newline at end of file diff --git a/rootfs/etc/nginx/lua/nginx/ngx_rewrite.lua b/rootfs/etc/nginx/lua/nginx/ngx_rewrite.lua new file mode 100644 index 000000000..66fdd6d55 --- /dev/null +++ b/rootfs/etc/nginx/lua/nginx/ngx_rewrite.lua @@ -0,0 +1,5 @@ +local lua_ingress = require("lua_ingress") +local balancer = require("balancer") + +lua_ingress.rewrite() +balancer.rewrite() \ No newline at end of file diff --git a/rootfs/etc/nginx/lua/nginx/ngx_srv_redirect.lua b/rootfs/etc/nginx/lua/nginx/ngx_srv_redirect.lua new file mode 100644 index 000000000..4b9445d00 --- /dev/null +++ b/rootfs/etc/nginx/lua/nginx/ngx_srv_redirect.lua @@ -0,0 +1,24 @@ +local request_uri = ngx.var.request_uri +local redirect_to = ngx.arg[1] + +local luaconfig = ngx.shared.luaconfig +local use_forwarded_headers = luaconfig:get("use_forwarded_headers") + +if string.sub(request_uri, -1) == "/" then + request_uri = string.sub(request_uri, 1, -2) +end + +local redirectScheme = ngx.var.scheme +local redirectPort = ngx.var.server_port + +if use_forwarded_headers then + if ngx.var.http_x_forwarded_proto then + redirectScheme = ngx.var.http_x_forwarded_proto + end + if ngx.var.http_x_forwarded_port then + redirectPort = ngx.var.http_x_forwarded_port + end +end + +return string.format("%s://%s:%s%s", redirectScheme, + redirect_to, redirectPort, request_uri) \ No newline at end of file diff --git a/rootfs/etc/nginx/lua/ngx_conf_init.lua b/rootfs/etc/nginx/lua/ngx_conf_init.lua new file mode 100644 index 000000000..9789386ac --- /dev/null +++ b/rootfs/etc/nginx/lua/ngx_conf_init.lua @@ -0,0 +1,53 @@ +local cjson = require("cjson.safe") + +collectgarbage("collect") +local f = io.open("/etc/nginx/lua/cfg.json", "r") +local content = f:read("*a") +f:close() +local configfile = cjson.decode(content) + +local luaconfig = ngx.shared.luaconfig +luaconfig:set("enablemetrics", configfile.enable_metrics) +luaconfig:set("use_forwarded_headers", configfile.use_forwarded_headers) +-- init modules +local ok, res +ok, res = pcall(require, "lua_ingress") +if not ok then + error("require failed: " .. tostring(res)) +else + lua_ingress = res + lua_ingress.set_config(configfile) +end +ok, res = pcall(require, "configuration") +if not ok then + error("require failed: " .. tostring(res)) +else + configuration = res + if not configfile.listen_ports.status_port then + error("required status port not found") + end + configuration.prohibited_localhost_port = configfile.listen_ports.status_port +end +ok, res = pcall(require, "balancer") +if not ok then + error("require failed: " .. tostring(res)) +else + balancer = res +end +if configfile.enable_metrics then + ok, res = pcall(require, "monitor") + if not ok then + error("require failed: " .. tostring(res)) + else + monitor = res + end +end +ok, res = pcall(require, "certificate") +if not ok then + error("require failed: " .. tostring(res)) +else + certificate = res + if configfile.enable_ocsp then + certificate.is_ocsp_stapling_enabled = configfile.enable_ocsp + end +end \ No newline at end of file diff --git a/rootfs/etc/nginx/lua/ngx_conf_init_stream.lua b/rootfs/etc/nginx/lua/ngx_conf_init_stream.lua new file mode 100644 index 000000000..a78062d0a --- /dev/null +++ b/rootfs/etc/nginx/lua/ngx_conf_init_stream.lua @@ -0,0 +1,30 @@ +local cjson = require("cjson.safe") +collectgarbage("collect") +local f = io.open("/etc/nginx/lua/cfg.json", "r") +local content = f:read("*a") +f:close() +local configfile = cjson.decode(content) +-- init modules +local ok, res +ok, res = pcall(require, "configuration") +if not ok then + error("require failed: " .. tostring(res)) +else + configuration = res +end +ok, res = pcall(require, "tcp_udp_configuration") +if not ok then + error("require failed: " .. tostring(res)) +else + tcp_udp_configuration = res + if not configfile.listen_ports.status_port then + error("required status port not found") + end + tcp_udp_configuration.prohibited_localhost_port = configfile.listen_ports.status_port +end +ok, res = pcall(require, "tcp_udp_balancer") +if not ok then + error("require failed: " .. tostring(res)) +else + tcp_udp_balancer = res +end diff --git a/rootfs/etc/nginx/lua/ngx_conf_init_worker.lua b/rootfs/etc/nginx/lua/ngx_conf_init_worker.lua new file mode 100644 index 000000000..cba866136 --- /dev/null +++ b/rootfs/etc/nginx/lua/ngx_conf_init_worker.lua @@ -0,0 +1,15 @@ +local cjson = require("cjson.safe") + +local f = io.open("/etc/nginx/lua/cfg.json", "r") +local content = f:read("*a") +f:close() +local configfile = cjson.decode(content) + +local lua_ingress = require("lua_ingress") +local balancer = require("balancer") +local monitor = require("monitor") +lua_ingress.init_worker() +balancer.init_worker() +if configfile.enable_metrics and configfile.monitor_batch_max_size then + monitor.init_worker(configfile.monitor_batch_max_size) +end \ No newline at end of file diff --git a/rootfs/etc/nginx/lua/plugins.lua b/rootfs/etc/nginx/lua/plugins.lua deleted file mode 100644 index 55e208a32..000000000 --- a/rootfs/etc/nginx/lua/plugins.lua +++ /dev/null @@ -1,61 +0,0 @@ -local require = require -local ngx = ngx -local ipairs = ipairs -local string_format = string.format -local ngx_log = ngx.log -local INFO = ngx.INFO -local ERR = ngx.ERR -local pcall = pcall - -local _M = {} -local MAX_NUMBER_OF_PLUGINS = 20 -local plugins = {} - -local function load_plugin(name) - local path = string_format("plugins.%s.main", name) - - local ok, plugin = pcall(require, path) - if not ok then - ngx_log(ERR, string_format("error loading plugin \"%s\": %s", path, plugin)) - return - end - local index = #plugins - if (plugin.name == nil or plugin.name == '') then - plugin.name = name - end - plugins[index + 1] = plugin -end - -function _M.init(names) - local count = 0 - for _, name in ipairs(names) do - if count >= MAX_NUMBER_OF_PLUGINS then - ngx_log(ERR, "the total number of plugins exceed the maximum number: ", MAX_NUMBER_OF_PLUGINS) - break - end - load_plugin(name) - count = count + 1 -- ignore loading failure, just count the total - end -end - -function _M.run() - local phase = ngx.get_phase() - - for _, plugin in ipairs(plugins) do - if plugin[phase] then - ngx_log(INFO, string_format("running plugin \"%s\" in phase \"%s\"", plugin.name, phase)) - - -- TODO: consider sandboxing this, should we? - -- probably yes, at least prohibit plugin from accessing env vars etc - -- but since the plugins are going to be installed by ingress-nginx - -- operator they can be assumed to be safe also - local ok, err = pcall(plugin[phase]) - if not ok then - ngx_log(ERR, string_format("error while running plugin \"%s\" in phase \"%s\": %s", - plugin.name, phase, err)) - end - end - end -end - -return _M diff --git a/rootfs/etc/nginx/lua/plugins/README.md b/rootfs/etc/nginx/lua/plugins/README.md deleted file mode 100644 index 64f4912f0..000000000 --- a/rootfs/etc/nginx/lua/plugins/README.md +++ /dev/null @@ -1,36 +0,0 @@ -# Custom Lua plugins - -ingress-nginx uses [https://github.com/openresty/lua-nginx-module](https://github.com/openresty/lua-nginx-module) to run custom Lua code -within Nginx workers. It is recommended to familiarize yourself with that ecosystem before deploying your custom Lua based ingress-nginx plugin. - -### Writing a plugin - -Every ingress-nginx Lua plugin is expected to have `main.lua` file and all of its dependencies. -`main.lua` is the entry point of the plugin. The plugin manager uses convention over configuration -strategy and automatically runs functions defined in `main.lua` in the corresponding Nginx phase based on their name. - -Nginx has different [request processing phases](https://nginx.org/en/docs/dev/development_guide.html#http_phases). -By defining functions with the following names, you can run your custom Lua code in the corresponding Nginx phase: - - - `init_worker`: useful for initializing some data per Nginx worker process - - `rewrite`: useful for modifying request, changing headers, redirection, dropping request, doing authentication etc - - `header_filter`: this is called when backend response header is received, it is useful for modifying response headers - - `body_filter`: this is called when response body is received, it is useful for logging response body - - `log`: this is called when request processing is completed and a response is delivered to the client - -Check this [`hello_world`](https://github.com/kubernetes/ingress-nginx/tree/main/rootfs/etc/nginx/lua/plugins/hello_world) plugin as a simple example or refer to [OpenID Connect integration](https://github.com/ElvinEfendi/ingress-nginx-openidc/tree/master/rootfs/etc/nginx/lua/plugins/openidc) for more advanced usage. - -Do not forget to write tests for your plugin. - -### Installing a plugin - -There are two options: - - - mount your plugin into `/etc/nginx/lua/plugins/` in the ingress-nginx pod - - build your own ingress-nginx image like it is done in the [example](https://github.com/ElvinEfendi/ingress-nginx-openidc/tree/master/rootfs/etc/nginx/lua/plugins/openidc) and install your plugin during image build - -Mounting is the quickest option. - -### Enabling plugins - -Once your plugin is ready you need to use [`plugins` configuration setting](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#plugins) to activate it. Let's say you want to activate `hello_world` and `open_idc` plugins, then you set `plugins` setting to `"hello_world, open_idc"`. _Note_ that the plugins will be executed in the given order. diff --git a/rootfs/etc/nginx/lua/plugins/hello_world/main.lua b/rootfs/etc/nginx/lua/plugins/hello_world/main.lua deleted file mode 100644 index 03316c3ee..000000000 --- a/rootfs/etc/nginx/lua/plugins/hello_world/main.lua +++ /dev/null @@ -1,13 +0,0 @@ -local ngx = ngx - -local _M = {} - -function _M.rewrite() - local ua = ngx.var.http_user_agent - - if ua == "hello" then - ngx.req.set_header("x-hello-world", "1") - end -end - -return _M diff --git a/rootfs/etc/nginx/lua/plugins/hello_world/test/main_test.lua b/rootfs/etc/nginx/lua/plugins/hello_world/test/main_test.lua deleted file mode 100644 index 5eda52259..000000000 --- a/rootfs/etc/nginx/lua/plugins/hello_world/test/main_test.lua +++ /dev/null @@ -1,24 +0,0 @@ - -local main = require("plugins.hello_world.main") - --- The unit tests are run within a timer phase in a headless Nginx process. --- Since `set_header` and `ngx.var.http_` API are disabled in this phase we have to stub it --- to avoid `API disabled in the current context` error. - -describe("main", function() - describe("rewrite", function() - it("sets x-hello-world header to 1 when user agent is hello", function() - ngx.var = { http_user_agent = "hello" } - stub(ngx.req, "set_header") - main.rewrite() - assert.stub(ngx.req.set_header).was_called_with("x-hello-world", "1") - end) - - it("does not set x-hello-world header to 1 when user agent is not hello", function() - ngx.var = { http_user_agent = "not-hello" } - stub(ngx.req, "set_header") - main.rewrite() - assert.stub(ngx.req.set_header).was_not_called_with("x-hello-world", "1") - end) - end) -end) diff --git a/rootfs/etc/nginx/lua/test/balancer/sticky_test.lua b/rootfs/etc/nginx/lua/test/balancer/sticky_test.lua index 80d0c0d0e..70723143b 100644 --- a/rootfs/etc/nginx/lua/test/balancer/sticky_test.lua +++ b/rootfs/etc/nginx/lua/test/balancer/sticky_test.lua @@ -357,7 +357,7 @@ describe("Sticky", function() for _ = 1, 100 do local new_upstream = sticky_balancer_instance:balance() if change_on_failure == false then - -- upstream should be the same inspite of error, if change_on_failure option is false + -- upstream should be the same in spite of error, if change_on_failure option is false assert.equal(new_upstream, old_upstream) else -- upstream should change after error, if change_on_failure option is true diff --git a/rootfs/etc/nginx/lua/test/global_throttle_test.lua b/rootfs/etc/nginx/lua/test/global_throttle_test.lua deleted file mode 100644 index b8db740ad..000000000 --- a/rootfs/etc/nginx/lua/test/global_throttle_test.lua +++ /dev/null @@ -1,258 +0,0 @@ -local util = require("util") - -local function assert_request_rejected(config, location_config, opts) - stub(ngx, "exit") - - local global_throttle = require_without_cache("global_throttle") - assert.has_no.errors(function() - global_throttle.throttle(config, location_config) - end) - - assert.stub(ngx.exit).was_called_with(config.status_code) - if opts.with_cache then - assert.are.same("c", ngx.var.global_rate_limit_exceeding) - else - assert.are.same("y", ngx.var.global_rate_limit_exceeding) - end -end - -local function assert_request_not_rejected(config, location_config) - stub(ngx, "exit") - local cache_safe_add_spy = spy.on(ngx.shared.global_throttle_cache, "safe_add") - - local global_throttle = require_without_cache("global_throttle") - assert.has_no.errors(function() - global_throttle.throttle(config, location_config) - end) - - assert.stub(ngx.exit).was_not_called() - assert.is_nil(ngx.var.global_rate_limit_exceeding) - assert.spy(cache_safe_add_spy).was_not_called() -end - -local function assert_short_circuits(f) - local cache_get_spy = spy.on(ngx.shared.global_throttle_cache, "get") - - local resty_global_throttle = require_without_cache("resty.global_throttle") - local resty_global_throttle_new_spy = spy.on(resty_global_throttle, "new") - - local global_throttle = require_without_cache("global_throttle") - - f(global_throttle) - - assert.spy(resty_global_throttle_new_spy).was_not_called() - assert.spy(cache_get_spy).was_not_called() -end - -local function assert_fails_open(config, location_config, ...) - stub(ngx, "exit") - stub(ngx, "log") - - local global_throttle = require_without_cache("global_throttle") - - assert.has_no.errors(function() - global_throttle.throttle(config, location_config) - end) - - assert.stub(ngx.exit).was_not_called() - assert.stub(ngx.log).was_called_with(ngx.ERR, ...) - assert.is_nil(ngx.var.global_rate_limit_exceeding) -end - -local function stub_resty_global_throttle_process(ret1, ret2, ret3, f) - local resty_global_throttle = require_without_cache("resty.global_throttle") - local resty_global_throttle_mock = { - process = function(self, key) return ret1, ret2, ret3 end - } - stub(resty_global_throttle, "new", resty_global_throttle_mock) - - f() - - assert.stub(resty_global_throttle.new).was_called() -end - -local function cache_rejection_decision(namespace, key_value, desired_delay) - local namespaced_key_value = namespace .. key_value - local ok, err = ngx.shared.global_throttle_cache:safe_add(namespaced_key_value, true, desired_delay) - assert.is_nil(err) - assert.is_true(ok) - assert.is_true(ngx.shared.global_throttle_cache:get(namespaced_key_value)) -end - -describe("global_throttle", function() - local snapshot - - local NAMESPACE = "31285d47b1504dcfbd6f12c46d769f6e" - local LOCATION_CONFIG = { - namespace = NAMESPACE, - limit = 10, - window_size = 60, - key = {}, - ignored_cidrs = {}, - } - local CONFIG = { - memcached = { - host = "memc.default.svc.cluster.local", port = 11211, - connect_timeout = 50, max_idle_timeout = 10000, pool_size = 50, - }, - status_code = 429, - } - - before_each(function() - snapshot = assert:snapshot() - - ngx.var = { remote_addr = "127.0.0.1", global_rate_limit_exceeding = nil } - end) - - after_each(function() - snapshot:revert() - - ngx.shared.global_throttle_cache:flush_all() - reset_ngx() - end) - - it("short circuits when memcached is not configured", function() - assert_short_circuits(function(global_throttle) - assert.has_no.errors(function() - global_throttle.throttle({ memcached = { host = "", port = 0 } }, LOCATION_CONFIG) - end) - end) - end) - - it("short circuits when limit or window_size is not configured", function() - assert_short_circuits(function(global_throttle) - local location_config_copy = util.deepcopy(LOCATION_CONFIG) - location_config_copy.limit = 0 - assert.has_no.errors(function() - global_throttle.throttle(CONFIG, location_config_copy) - end) - end) - - assert_short_circuits(function(global_throttle) - local location_config_copy = util.deepcopy(LOCATION_CONFIG) - location_config_copy.window_size = 0 - assert.has_no.errors(function() - global_throttle.throttle(CONFIG, location_config_copy) - end) - end) - end) - - it("short circuits when remote_addr is in ignored_cidrs", function() - local global_throttle = require_without_cache("global_throttle") - local location_config = util.deepcopy(LOCATION_CONFIG) - location_config.ignored_cidrs = { ngx.var.remote_addr } - assert_short_circuits(function(global_throttle) - assert.has_no.errors(function() - global_throttle.throttle(CONFIG, location_config) - end) - end) - end) - - it("rejects when exceeding limit has already been cached", function() - local key_value = "foo" - local location_config = util.deepcopy(LOCATION_CONFIG) - location_config.key = { { nil, nil, nil, key_value } } - cache_rejection_decision(NAMESPACE, key_value, 0.5) - - assert_request_rejected(CONFIG, location_config, { with_cache = true }) - end) - - describe("when resty_global_throttle fails", function() - it("fails open in case of initialization error", function() - local too_long_namespace = "" - for i=1,36,1 do - too_long_namespace = too_long_namespace .. "a" - end - - local location_config = util.deepcopy(LOCATION_CONFIG) - location_config.namespace = too_long_namespace - - assert_fails_open(CONFIG, location_config, "faled to initialize resty_global_throttle: ", "'namespace' can be at most 35 characters") - end) - - it("fails open in case of key processing error", function() - stub_resty_global_throttle_process(nil, nil, "failed to process", function() - assert_fails_open(CONFIG, LOCATION_CONFIG, "error while processing key: ", "failed to process") - end) - end) - end) - - it("initializes resty_global_throttle with the right parameters", function() - local resty_global_throttle = require_without_cache("resty.global_throttle") - local resty_global_throttle_original_new = resty_global_throttle.new - resty_global_throttle.new = function(namespace, limit, window_size, store_opts) - local o, err = resty_global_throttle_original_new(namespace, limit, window_size, store_opts) - if not o then - return nil, err - end - o.process = function(self, key) return 1, nil, nil end - - local expected = LOCATION_CONFIG - assert.are.same(expected.namespace, namespace) - assert.are.same(expected.limit, limit) - assert.are.same(expected.window_size, window_size) - - assert.are.same("memcached", store_opts.provider) - assert.are.same(CONFIG.memcached.host, store_opts.host) - assert.are.same(CONFIG.memcached.port, store_opts.port) - assert.are.same(CONFIG.memcached.connect_timeout, store_opts.connect_timeout) - assert.are.same(CONFIG.memcached.max_idle_timeout, store_opts.max_idle_timeout) - assert.are.same(CONFIG.memcached.pool_size, store_opts.pool_size) - - return o, nil - end - local resty_global_throttle_new_spy = spy.on(resty_global_throttle, "new") - - local global_throttle = require_without_cache("global_throttle") - - assert.has_no.errors(function() - global_throttle.throttle(CONFIG, LOCATION_CONFIG) - end) - - assert.spy(resty_global_throttle_new_spy).was_called() - end) - - it("rejects request and caches decision when limit is exceeding after processing a key", function() - local desired_delay = 0.015 - - stub_resty_global_throttle_process(LOCATION_CONFIG.limit + 1, desired_delay, nil, function() - assert_request_rejected(CONFIG, LOCATION_CONFIG, { with_cache = false }) - - local cache_key = LOCATION_CONFIG.namespace .. ngx.var.remote_addr - assert.is_true(ngx.shared.global_throttle_cache:get(cache_key)) - - -- we assume it won't take more than this after caching - -- until we execute the assertion below - local delta = 0.001 - local ttl = ngx.shared.global_throttle_cache:ttl(cache_key) - assert.is_true(ttl > desired_delay - delta) - assert.is_true(ttl <= desired_delay) - end) - end) - - it("rejects request and skip caching of decision when limit is exceeding after processing a key but desired delay is lower than the threshold", function() - local desired_delay = 0.0009 - - stub_resty_global_throttle_process(LOCATION_CONFIG.limit, desired_delay, nil, function() - assert_request_rejected(CONFIG, LOCATION_CONFIG, { with_cache = false }) - - local cache_key = LOCATION_CONFIG.namespace .. ngx.var.remote_addr - assert.is_nil(ngx.shared.global_throttle_cache:get(cache_key)) - end) - end) - - it("allows the request when limit is not exceeding after processing a key", function() - stub_resty_global_throttle_process(LOCATION_CONFIG.limit - 3, nil, nil, - function() - assert_request_not_rejected(CONFIG, LOCATION_CONFIG) - end - ) - end) - - it("rejects with custom status code", function() - cache_rejection_decision(NAMESPACE, ngx.var.remote_addr, 0.3) - local config = util.deepcopy(CONFIG) - config.status_code = 503 - assert_request_rejected(config, LOCATION_CONFIG, { with_cache = true }) - end) -end) diff --git a/rootfs/etc/nginx/lua/test/plugins_test.lua b/rootfs/etc/nginx/lua/test/plugins_test.lua deleted file mode 100644 index d7f789d0f..000000000 --- a/rootfs/etc/nginx/lua/test/plugins_test.lua +++ /dev/null @@ -1,23 +0,0 @@ -describe("plugins", function() - describe("#run", function() - it("runs the plugins in the given order", function() - ngx.get_phase = function() return "rewrite" end - local plugins = require("plugins") - local called_plugins = {} - local plugins_to_mock = {"plugins.pluginfirst.main", "plugins.pluginsecond.main", "plugins.pluginthird.main"} - for i=1, 3, 1 - do - package.loaded[plugins_to_mock[i]] = { - rewrite = function() - called_plugins[#called_plugins + 1] = plugins_to_mock[i] - end - } - end - assert.has_no.errors(function() - plugins.init({"pluginfirst", "pluginsecond", "pluginthird"}) - end) - assert.has_no.errors(plugins.run) - assert.are.same(plugins_to_mock, called_plugins) - end) - end) -end) \ No newline at end of file diff --git a/rootfs/etc/nginx/lua/util.lua b/rootfs/etc/nginx/lua/util.lua index 7389f3226..1e4cd7c01 100644 --- a/rootfs/etc/nginx/lua/util.lua +++ b/rootfs/etc/nginx/lua/util.lua @@ -146,6 +146,10 @@ function _M.is_blank(str) return str == nil or string_len(str) == 0 end +function _M.string_to_bool(str) + return str == "true" +end + -- this implementation is taken from: -- https://github.com/luafun/luafun/blob/master/fun.lua#L33 -- SHA: 04c99f9c393e54a604adde4b25b794f48104e0d0 diff --git a/rootfs/etc/nginx/template/nginx.tmpl b/rootfs/etc/nginx/template/nginx.tmpl index d58be2880..6b8e750b0 100644 --- a/rootfs/etc/nginx/template/nginx.tmpl +++ b/rootfs/etc/nginx/template/nginx.tmpl @@ -68,71 +68,11 @@ http { {{ buildLuaSharedDictionaries $cfg $servers }} - init_by_lua_block { - collectgarbage("collect") + lua_shared_dict luaconfig 5m; - -- init modules - local ok, res + init_by_lua_file /etc/nginx/lua/ngx_conf_init.lua; - ok, res = pcall(require, "lua_ingress") - if not ok then - error("require failed: " .. tostring(res)) - else - lua_ingress = res - lua_ingress.set_config({{ configForLua $all }}) - end - - ok, res = pcall(require, "configuration") - if not ok then - error("require failed: " .. tostring(res)) - else - configuration = res - configuration.prohibited_localhost_port = '{{ .StatusPort }}' - end - - ok, res = pcall(require, "balancer") - if not ok then - error("require failed: " .. tostring(res)) - else - balancer = res - end - - {{ if $all.EnableMetrics }} - ok, res = pcall(require, "monitor") - if not ok then - error("require failed: " .. tostring(res)) - else - monitor = res - end - {{ end }} - - ok, res = pcall(require, "certificate") - if not ok then - error("require failed: " .. tostring(res)) - else - certificate = res - certificate.is_ocsp_stapling_enabled = {{ $cfg.EnableOCSP }} - end - - ok, res = pcall(require, "plugins") - if not ok then - error("require failed: " .. tostring(res)) - else - plugins = res - end - -- load all plugins that'll be used here - plugins.init({ {{ range $idx, $plugin := $cfg.Plugins }}{{ if $idx }},{{ end }}{{ $plugin | quote }}{{ end }} }) - } - - init_worker_by_lua_block { - lua_ingress.init_worker() - balancer.init_worker() - {{ if $all.EnableMetrics }} - monitor.init_worker({{ $all.MonitorMaxBatchSize }}) - {{ end }} - - plugins.run() - } + init_worker_by_lua_file /etc/nginx/lua/ngx_conf_init_worker.lua; {{/* Enable the real_ip module only if we use either X-Forwarded headers or Proxy Protocol. */}} {{/* we use the value of the real IP for the geo_ip module */}} @@ -172,6 +112,9 @@ http { {{ range $index, $file := $all.MaxmindEditionFiles }} {{ if eq $file "GeoLite2-Country.mmdb" }} geoip2 /etc/ingress-controller/geoip/GeoLite2-Country.mmdb { + {{ if (gt $cfg.GeoIP2AutoReloadMinutes 0) }} + auto_reload {{ $cfg.GeoIP2AutoReloadMinutes }}m; + {{ end }} $geoip2_country_code source=$remote_addr country iso_code; $geoip2_country_name source=$remote_addr country names en; $geoip2_country_geoname_id source=$remote_addr country geoname_id; @@ -183,6 +126,9 @@ http { {{ if eq $file "GeoIP2-Country.mmdb" }} geoip2 /etc/ingress-controller/geoip/GeoIP2-Country.mmdb { + {{ if (gt $cfg.GeoIP2AutoReloadMinutes 0) }} + auto_reload {{ $cfg.GeoIP2AutoReloadMinutes }}m; + {{ end }} $geoip2_country_code source=$remote_addr country iso_code; $geoip2_country_name source=$remote_addr country names en; $geoip2_country_geoname_id source=$remote_addr country geoname_id; @@ -194,6 +140,9 @@ http { {{ if eq $file "GeoLite2-City.mmdb" }} geoip2 /etc/ingress-controller/geoip/GeoLite2-City.mmdb { + {{ if (gt $cfg.GeoIP2AutoReloadMinutes 0) }} + auto_reload {{ $cfg.GeoIP2AutoReloadMinutes }}m; + {{ end }} $geoip2_city_country_code source=$remote_addr country iso_code; $geoip2_city_country_name source=$remote_addr country names en; $geoip2_city_country_geoname_id source=$remote_addr country geoname_id; @@ -217,6 +166,9 @@ http { {{ if eq $file "GeoIP2-City.mmdb" }} geoip2 /etc/ingress-controller/geoip/GeoIP2-City.mmdb { + {{ if (gt $cfg.GeoIP2AutoReloadMinutes 0) }} + auto_reload {{ $cfg.GeoIP2AutoReloadMinutes }}m; + {{ end }} $geoip2_city_country_code source=$remote_addr country iso_code; $geoip2_city_country_name source=$remote_addr country names en; $geoip2_city_country_geoname_id source=$remote_addr country geoname_id; @@ -240,6 +192,9 @@ http { {{ if eq $file "GeoLite2-ASN.mmdb" }} geoip2 /etc/ingress-controller/geoip/GeoLite2-ASN.mmdb { + {{ if (gt $cfg.GeoIP2AutoReloadMinutes 0) }} + auto_reload {{ $cfg.GeoIP2AutoReloadMinutes }}m; + {{ end }} $geoip2_asn source=$remote_addr autonomous_system_number; $geoip2_org source=$remote_addr autonomous_system_organization; } @@ -247,6 +202,9 @@ http { {{ if eq $file "GeoIP2-ASN.mmdb" }} geoip2 /etc/ingress-controller/geoip/GeoIP2-ASN.mmdb { + {{ if (gt $cfg.GeoIP2AutoReloadMinutes 0) }} + auto_reload {{ $cfg.GeoIP2AutoReloadMinutes }}m; + {{ end }} $geoip2_asn source=$remote_addr autonomous_system_number; $geoip2_org source=$remote_addr autonomous_system_organization; } @@ -254,6 +212,9 @@ http { {{ if eq $file "GeoIP2-ISP.mmdb" }} geoip2 /etc/ingress-controller/geoip/GeoIP2-ISP.mmdb { + {{ if (gt $cfg.GeoIP2AutoReloadMinutes 0) }} + auto_reload {{ $cfg.GeoIP2AutoReloadMinutes }}m; + {{ end }} $geoip2_isp source=$remote_addr isp; $geoip2_isp_org source=$remote_addr organization; $geoip2_asn source=$remote_addr default=0 autonomous_system_number; @@ -268,6 +229,9 @@ http { {{ if eq $file "GeoIP2-Anonymous-IP.mmdb" }} geoip2 /etc/ingress-controller/geoip/GeoIP2-Anonymous-IP.mmdb { + {{ if (gt $cfg.GeoIP2AutoReloadMinutes 0) }} + auto_reload {{ $cfg.GeoIP2AutoReloadMinutes }}m; + {{ end }} $geoip2_is_anon source=$remote_addr is_anonymous; $geoip2_is_anonymous source=$remote_addr default=0 is_anonymous; $geoip2_is_anonymous_vpn source=$remote_addr default=0 is_anonymous_vpn; @@ -307,6 +271,10 @@ http { client_body_buffer_size {{ $cfg.ClientBodyBufferSize }}; client_body_timeout {{ $cfg.ClientBodyTimeout }}s; + {{ if gt $cfg.GRPCBufferSizeKb 0 }} + grpc_buffer_size {{ $cfg.GRPCBufferSizeKb }}k; + {{ end }} + {{ if and (ne $cfg.HTTP2MaxHeaderSize "") (ne $cfg.HTTP2MaxFieldSize "") }} http2_max_field_size {{ $cfg.HTTP2MaxFieldSize }}; http2_max_header_size {{ $cfg.HTTP2MaxHeaderSize }}; @@ -491,6 +459,10 @@ http { proxy_intercept_errors on; {{ end }} + {{ if $cfg.RelativeRedirects }} + absolute_redirect off; + {{ end }} + {{ range $errCode := $cfg.CustomHTTPErrors }} error_page {{ $errCode }} = @custom_upstream-default-backend_{{ $errCode }};{{ end }} @@ -522,9 +494,7 @@ http { server 0.0.0.1; # placeholder - balancer_by_lua_block { - balancer.balance() - } + balancer_by_lua_file /etc/nginx/lua/nginx/ngx_conf_balancer.lua; {{ if (gt $cfg.UpstreamKeepaliveConnections 0) }} keepalive {{ $cfg.UpstreamKeepaliveConnections }}; @@ -589,9 +559,7 @@ http { {{ buildHTTPListener $all $redirect.From }} {{ buildHTTPSListener $all $redirect.From }} - ssl_certificate_by_lua_block { - certificate.call() - } + ssl_certificate_by_lua_file /etc/nginx/lua/nginx/ngx_conf_certificate.lua; {{ if gt (len $cfg.BlockUserAgents) 0 }} if ($block_ua) { @@ -604,30 +572,7 @@ http { } {{ end }} - set_by_lua_block $redirect_to { - local request_uri = ngx.var.request_uri - if string.sub(request_uri, -1) == "/" then - request_uri = string.sub(request_uri, 1, -2) - end - - {{ if $cfg.UseForwardedHeaders }} - local redirectScheme - if not ngx.var.http_x_forwarded_proto then - redirectScheme = ngx.var.scheme - else - redirectScheme = ngx.var.http_x_forwarded_proto - end - {{ else }} - local redirectScheme = ngx.var.scheme - {{ end }} - - {{ if ne $all.ListenPorts.HTTPS 443 }} - {{ $redirect_port := (printf ":%v" $all.ListenPorts.HTTPS) }} - return string.format("%s://%s%s%s", redirectScheme, "{{ $redirect.To }}", "{{ $redirect_port }}", request_uri) - {{ else }} - return string.format("%s://%s%s", redirectScheme, "{{ $redirect.To }}", request_uri) - {{ end }} - } + set_by_lua_file $redirect_to /etc/nginx/lua/nginx/ngx_srv_redirect.lua {{ $redirect.To }}; return {{ $all.Cfg.HTTPRedirectCode }} $redirect_to; } @@ -722,17 +667,7 @@ http { } location /is-dynamic-lb-initialized { - content_by_lua_block { - local configuration = require("configuration") - local backend_data = configuration.get_backends_data() - if not backend_data then - ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) - return - end - - ngx.say("OK") - ngx.exit(ngx.HTTP_OK) - } + content_by_lua_file /etc/nginx/lua/nginx/ngx_conf_is_dynamic_lb_initialized.lua; } location {{ .StatusPath }} { @@ -744,15 +679,11 @@ http { client_body_buffer_size {{ luaConfigurationRequestBodySize $cfg }}; proxy_buffering off; - content_by_lua_block { - configuration.call() - } + content_by_lua_file /etc/nginx/lua/nginx/ngx_conf_configuration.lua; } location / { - content_by_lua_block { - ngx.exit(ngx.HTTP_NOT_FOUND) - } + return 404; } } } @@ -764,39 +695,9 @@ stream { {{ buildResolvers $cfg.Resolver $cfg.DisableIpv6DNS }} - init_by_lua_block { - collectgarbage("collect") + init_by_lua_file /etc/nginx/lua/ngx_conf_init_stream.lua; - -- init modules - local ok, res - - ok, res = pcall(require, "configuration") - if not ok then - error("require failed: " .. tostring(res)) - else - configuration = res - end - - ok, res = pcall(require, "tcp_udp_configuration") - if not ok then - error("require failed: " .. tostring(res)) - else - tcp_udp_configuration = res - tcp_udp_configuration.prohibited_localhost_port = '{{ .StatusPort }}' - - end - - ok, res = pcall(require, "tcp_udp_balancer") - if not ok then - error("require failed: " .. tostring(res)) - else - tcp_udp_balancer = res - end - } - - init_worker_by_lua_block { - tcp_udp_balancer.init_worker() - } + init_worker_by_lua_file /etc/nginx/lua/nginx/ngx_conf_init_tcp_udp.lua; lua_add_variable $proxy_upstream_name; @@ -818,10 +719,7 @@ stream { upstream upstream_balancer { server 0.0.0.1:1234; # placeholder - - balancer_by_lua_block { - tcp_udp_balancer.balance() - } + balancer_by_lua_file /etc/nginx/lua/nginx/ngx_conf_balancer_tcp_udp.lua; } server { @@ -829,9 +727,7 @@ stream { access_log off; - content_by_lua_block { - tcp_udp_configuration.call() - } + content_by_lua_file /etc/nginx/lua/nginx/ngx_conf_content_tcp_udp.lua; } # TCP services @@ -931,11 +827,9 @@ stream { rewrite (.*) / break; proxy_pass http://upstream_balancer; - log_by_lua_block { - {{ if $enableMetrics }} - monitor.call() - {{ end }} - } + {{ if $enableMetrics }} + log_by_lua_file /etc/nginx/lua/nginx/ngx_conf_log.lua; + {{ end }} } {{ end }} {{ end }} @@ -995,9 +889,7 @@ stream { ssl_reject_handshake {{ if $all.Cfg.SSLRejectHandshake }}on{{ else }}off{{ end }}; {{ end }} - ssl_certificate_by_lua_block { - certificate.call() - } + ssl_certificate_by_lua_file /etc/nginx/lua/nginx/ngx_conf_certificate.lua; {{ if not (empty $server.AuthTLSError) }} # {{ $server.AuthTLSError }} @@ -1098,9 +990,7 @@ stream { set $tmp_cache_key '{{ $server.Hostname }}{{ $authPath }}{{ $externalAuth.AuthCacheKey }}'; set $cache_key ''; - rewrite_by_lua_block { - ngx.var.cache_key = ngx.encode_base64(ngx.sha1_bin(ngx.var.tmp_cache_key)) - } + rewrite_by_lua_file /etc/nginx/lua/nginx/ngx_conf_rewrite_auth.lua; proxy_cache auth_cache; @@ -1151,6 +1041,7 @@ stream { {{ end }} proxy_buffer_size {{ $location.Proxy.BufferSize }}; proxy_buffers {{ $location.Proxy.BuffersNumber }} {{ $location.Proxy.BufferSize }}; + proxy_busy_buffers_size {{ $location.Proxy.BusyBuffersSize }}; proxy_request_buffering {{ $location.Proxy.RequestBuffering }}; proxy_ssl_server_name on; @@ -1225,7 +1116,6 @@ stream { set $service_name {{ $ing.Service | quote }}; set $service_port {{ $ing.ServicePort | quote }}; set $location_path {{ $ing.Path | escapeLiteralDollar | quote }}; - set $global_rate_limit_exceeding n; {{ buildOpentelemetryForLocation $all.Cfg.EnableOpentelemetry $all.Cfg.OpentelemetryTrustIncomingSpan $location }} @@ -1234,35 +1124,13 @@ stream { mirror_request_body {{ $location.Mirror.RequestBody }}; {{ end }} - rewrite_by_lua_block { - lua_ingress.rewrite({{ locationConfigForLua $location $all }}) - balancer.rewrite() - plugins.run() - } + {{ locationConfigForLua $location $all }} - # be careful with `access_by_lua_block` and `satisfy any` directives as satisfy any - # will always succeed when there's `access_by_lua_block` that does not have any lua code doing `ngx.exit(ngx.DECLINED)` - # other authentication method such as basic auth or external auth useless - all requests will be allowed. - #access_by_lua_block { - #} + rewrite_by_lua_file /etc/nginx/lua/nginx/ngx_rewrite.lua; - header_filter_by_lua_block { - lua_ingress.header() - plugins.run() - } + header_filter_by_lua_file /etc/nginx/lua/nginx/ngx_conf_srv_hdr_filter.lua; - body_filter_by_lua_block { - plugins.run() - } - - log_by_lua_block { - balancer.log() - {{ if $all.EnableMetrics }} - monitor.call() - {{ end }} - - plugins.run() - } + log_by_lua_file /etc/nginx/lua/nginx/ngx_conf_log_block.lua; {{ if not $location.Logs.Access }} access_log off; @@ -1322,20 +1190,10 @@ stream { {{- end }} # `auth_request` module does not support HTTP keepalives in upstream block: # https://trac.nginx.org/nginx/ticket/1579 - access_by_lua_block { - local res = ngx.location.capture('{{ $authPath }}', { method = ngx.HTTP_GET, body = '', share_all_vars = {{ $externalAuth.KeepaliveShareVars }} }) - if res.status == ngx.HTTP_OK then - ngx.var.auth_cookie = res.header['Set-Cookie'] - {{- range $line := buildAuthUpstreamLuaHeaders $externalAuth.ResponseHeaders }} - {{ $line }} - {{- end }} - return - end - if res.status == ngx.HTTP_UNAUTHORIZED or res.status == ngx.HTTP_FORBIDDEN then - ngx.exit(res.status) - end - ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) - } + set $auth_path '{{ $authPath }}'; + set $auth_keepalive_share_vars {{ $externalAuth.KeepaliveShareVars }}; + set $auth_response_headers '{{ buildAuthUpstreamLuaHeaders $externalAuth.ResponseHeaders }}'; + access_by_lua_file /etc/nginx/lua/nginx/ngx_conf_external_auth.lua; {{ else }} auth_request {{ $authPath }}; auth_request_set $auth_cookie $upstream_http_set_cookie; @@ -1439,6 +1297,7 @@ stream { proxy_buffering {{ $location.Proxy.ProxyBuffering }}; proxy_buffer_size {{ $location.Proxy.BufferSize }}; proxy_buffers {{ $location.Proxy.BuffersNumber }} {{ $location.Proxy.BufferSize }}; + proxy_busy_buffers_size {{ $location.Proxy.BusyBuffersSize }}; {{ if isValidByteSize $location.Proxy.ProxyMaxTempFileSize true }} proxy_max_temp_file_size {{ $location.Proxy.ProxyMaxTempFileSize }}; {{ end }} @@ -1453,6 +1312,13 @@ stream { proxy_next_upstream_timeout {{ $location.Proxy.NextUpstreamTimeout }}; proxy_next_upstream_tries {{ $location.Proxy.NextUpstreamTries }}; + {{ if or (eq $location.BackendProtocol "GRPC") (eq $location.BackendProtocol "GRPCS") }} + # Grpc settings + grpc_connect_timeout {{ $location.Proxy.ConnectTimeout }}s; + grpc_send_timeout {{ $location.Proxy.SendTimeout }}s; + grpc_read_timeout {{ $location.Proxy.ReadTimeout }}s; + {{ end }} + {{/* Add any additional configuration defined */}} {{ $location.ConfigurationSnippet }} @@ -1461,6 +1327,13 @@ stream { {{ $all.Cfg.LocationSnippet }} {{ end }} + {{ if $location.CustomHeaders }} + # Custom Response Headers + {{ range $k, $v := $location.CustomHeaders.Headers }} + more_set_headers {{ printf "%s: %s" $k $v | escapeLiteralDollar | quote }}; + {{ end }} + {{ end }} + {{/* if we are sending the request to a custom default backend, we add the required headers */}} {{ if (hasPrefix $location.Backend "custom-default-backend-") }} proxy_set_header X-Code 503; @@ -1476,6 +1349,10 @@ stream { satisfy {{ $location.Satisfy }}; {{ end }} + {{ if $location.Redirect.Relative }} + absolute_redirect off; + {{ end }} + {{/* if a location-specific error override is set, add the proxy_intercept here */}} {{ if and $location.CustomHTTPErrors (not $location.DisableProxyInterceptErrors) }} # Custom error pages per ingress diff --git a/test/data/cleanConf.expected.conf b/test/data/cleanConf.expected.conf index 7c4a16824..9c0513b37 100644 --- a/test/data/cleanConf.expected.conf +++ b/test/data/cleanConf.expected.conf @@ -67,8 +67,6 @@ http { balancer.init_worker() monitor.init_worker(10000) - - plugins.run() } map $request_uri $loggable { @@ -120,7 +118,6 @@ http { use_port_in_redirects = false, }) balancer.rewrite() - plugins.run() } # be careful with `access_by_lua_block` and `satisfy any` directives as satisfy any @@ -130,7 +127,6 @@ http { header_filter_by_lua_block { lua_ingress.header() - plugins.run() } } diff --git a/test/data/cleanConf.src.conf b/test/data/cleanConf.src.conf index 89954cf0d..6da578106 100644 --- a/test/data/cleanConf.src.conf +++ b/test/data/cleanConf.src.conf @@ -86,11 +86,8 @@ lua_shared_dict ocsp_response_cache 5M; init_worker_by_lua_block { lua_ingress.init_worker() balancer.init_worker() - - monitor.init_worker(10000) - - plugins.run() + monitor.init_worker(10000) } @@ -164,7 +161,6 @@ lua_shared_dict ocsp_response_cache 5M; use_port_in_redirects = false, }) balancer.rewrite() - plugins.run() } # be careful with `access_by_lua_block` and `satisfy any` directives as satisfy any @@ -174,7 +170,6 @@ lua_shared_dict ocsp_response_cache 5M; header_filter_by_lua_block { lua_ingress.header() - plugins.run() } diff --git a/test/e2e-image/Dockerfile b/test/e2e-image/Dockerfile index 7bd7c9c1c..c16545e43 100644 --- a/test/e2e-image/Dockerfile +++ b/test/e2e-image/Dockerfile @@ -1,7 +1,7 @@ ARG E2E_BASE_IMAGE FROM ${E2E_BASE_IMAGE} AS BASE -FROM alpine:3.20.0 +FROM alpine:3.21 RUN apk update \ && apk upgrade && apk add -U --no-cache \ diff --git a/test/e2e-image/Makefile b/test/e2e-image/Makefile index 74f3cc437..f72651f48 100644 --- a/test/e2e-image/Makefile +++ b/test/e2e-image/Makefile @@ -1,6 +1,6 @@ DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) -E2E_BASE_IMAGE ?= "registry.k8s.io/ingress-nginx/e2e-test-runner:v20240812-3f0129aa@sha256:95c2aaf2a66e8cbbf7a7453046f3b024383c273a0988efab841cd96116afd1a9" +E2E_BASE_IMAGE ?= "registry.k8s.io/ingress-nginx/e2e-test-runner:v20250112-a188f4eb@sha256:043038b1e30e5a0b64f3f919f096c5c9488ac3f617ac094b07fb9db8215f9441" image: echo "..entered Makefile in /test/e2e-image" diff --git a/test/e2e-image/namespace-overlays/disableleaderelection/values.yaml b/test/e2e-image/namespace-overlays/disableleaderelection/values.yaml new file mode 100644 index 000000000..f312a9fb4 --- /dev/null +++ b/test/e2e-image/namespace-overlays/disableleaderelection/values.yaml @@ -0,0 +1,34 @@ +# TODO: remove the need to use fullnameOverride +fullnameOverride: nginx-ingress +controller: + image: + repository: ingress-controller/controller + chroot: true + tag: 1.0.0-dev + digest: + digestChroot: + scope: + # Necessary to allow the ingress controller to get the topology information from the nodes + enabled: false + config: + worker-processes: "1" + readinessProbe: + initialDelaySeconds: 3 + periodSeconds: 1 + livenessProbe: + initialDelaySeconds: 3 + periodSeconds: 1 + service: + type: NodePort + extraArgs: + # e2e tests do not require information about ingress status + update-status: "false" + terminationGracePeriodSeconds: 1 + admissionWebhooks: + enabled: false + + disableLeaderElection: true + +rbac: + create: true + scope: false diff --git a/test/e2e/HTTPBUN_IMAGE b/test/e2e/HTTPBUN_IMAGE index 7deb1e1cb..491b333c7 100644 --- a/test/e2e/HTTPBUN_IMAGE +++ b/test/e2e/HTTPBUN_IMAGE @@ -1 +1 @@ -registry.k8s.io/ingress-nginx/httpbun:v1.0.1@sha256:264371edd5b19ddc2da9333bb4d87c0ce3c0cf37c73c4adeb8bc641b872bc9da +registry.k8s.io/ingress-nginx/httpbun:v1.1.1@sha256:4569515d9b74470c915566a010792e7202b6769443fb1f3bb1b1e87376028634 diff --git a/test/e2e/admission/admission.go b/test/e2e/admission/admission.go index c41105e2d..873e6719d 100644 --- a/test/e2e/admission/admission.go +++ b/test/e2e/admission/admission.go @@ -44,33 +44,6 @@ var _ = framework.IngressNginxDescribeSerial("[Admission] admission controller", f.NewSlowEchoDeployment() }) - ginkgo.It("reject ingress with global-rate-limit annotations when memcached is not configured", func() { - host := admissionTestHost - - annotations := map[string]string{ - "nginx.ingress.kubernetes.io/global-rate-limit": "100", - "nginx.ingress.kubernetes.io/global-rate-limit-window": "1m", - } - ing := framework.NewSingleIngress("first-ingress", "/", host, f.Namespace, framework.EchoService, 80, annotations) - - ginkgo.By("rejects ingress when memcached is not configured") - - _, err := f.KubeClientSet.NetworkingV1().Ingresses(f.Namespace).Create(context.TODO(), ing, metav1.CreateOptions{}) - assert.NotNil(ginkgo.GinkgoT(), err, "creating ingress with global throttle annotations when memcached is not configured") - - ginkgo.By("accepts ingress when memcached is not configured") - - f.UpdateNginxConfigMapData("global-rate-limit-memcached-host", "memc.default.svc.cluster.local") - - _, err = f.KubeClientSet.NetworkingV1().Ingresses(f.Namespace).Create(context.TODO(), ing, metav1.CreateOptions{}) - assert.Nil(ginkgo.GinkgoT(), err, "creating ingress with global throttle annotations when memcached is configured") - - f.WaitForNginxServer(host, - func(server string) bool { - return strings.Contains(server, fmt.Sprintf("server_name %v", host)) - }) - }) - ginkgo.It("should not allow overlaps of host and paths without canary annotations", func() { host := admissionTestHost @@ -127,14 +100,8 @@ var _ = framework.IngressNginxDescribeSerial("[Admission] admission controller", }) ginkgo.It("should return an error if there is an error validating the ingress definition", func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "true", - }) - defer func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "false", - }) - }() + disableSnippet := f.AllowSnippetConfiguration() + defer disableSnippet() host := admissionTestHost @@ -241,14 +208,8 @@ var _ = framework.IngressNginxDescribeSerial("[Admission] admission controller", }) ginkgo.It("should return an error if the Ingress V1 definition contains invalid annotations", func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "true", - }) - defer func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "false", - }) - }() + disableSnippet := f.AllowSnippetConfiguration() + defer disableSnippet() out, err := createIngress(f.Namespace, invalidV1Ingress) assert.Empty(ginkgo.GinkgoT(), out) @@ -261,14 +222,8 @@ var _ = framework.IngressNginxDescribeSerial("[Admission] admission controller", }) ginkgo.It("should not return an error for an invalid Ingress when it has unknown class", func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "true", - }) - defer func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "false", - }) - }() + disableSnippet := f.AllowSnippetConfiguration() + defer disableSnippet() out, err := createIngress(f.Namespace, invalidV1IngressWithOtherClass) assert.Equal(ginkgo.GinkgoT(), "ingress.networking.k8s.io/extensions-invalid-other created\n", out) assert.Nil(ginkgo.GinkgoT(), err, "creating an invalid ingress with unknown class using kubectl") diff --git a/test/e2e/annotations/auth.go b/test/e2e/annotations/auth.go index ea33fdf32..ddda1dce5 100644 --- a/test/e2e/annotations/auth.go +++ b/test/e2e/annotations/auth.go @@ -277,14 +277,8 @@ var _ = framework.DescribeAnnotation("auth-*", func() { "nginx.ingress.kubernetes.io/auth-snippet": ` proxy_set_header My-Custom-Header 42;`, } - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "true", - }) - defer func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "false", - }) - }() + disableSnippet := f.AllowSnippetConfiguration() + defer disableSnippet() ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations) f.EnsureIngress(ing) @@ -297,15 +291,8 @@ var _ = framework.DescribeAnnotation("auth-*", func() { ginkgo.It(`should not set snippet "proxy_set_header My-Custom-Header 42;" when external auth is not configured`, func() { host := authHost - - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "true", - }) - defer func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "false", - }) - }() + disableSnippet := f.AllowSnippetConfiguration() + defer disableSnippet() annotations := map[string]string{ "nginx.ingress.kubernetes.io/auth-snippet": ` @@ -666,7 +653,7 @@ http { func(server string) bool { return strings.Contains(server, `upstream auth-external-auth`) && strings.Contains(server, `keepalive 10;`) && - strings.Contains(server, `share_all_vars = false`) + strings.Contains(server, `set $auth_keepalive_share_vars false;`) }) }) @@ -686,7 +673,7 @@ http { func(server string) bool { return strings.Contains(server, `upstream auth-external-auth`) && strings.Contains(server, `keepalive 10;`) && - strings.Contains(server, `share_all_vars = true`) + strings.Contains(server, `set $auth_keepalive_share_vars true;`) }) }) }) diff --git a/test/e2e/annotations/cors.go b/test/e2e/annotations/cors.go index a14a5761f..58f4445f7 100644 --- a/test/e2e/annotations/cors.go +++ b/test/e2e/annotations/cors.go @@ -669,4 +669,33 @@ var _ = framework.DescribeAnnotation("cors-*", func() { Headers(). NotContainsKey("Access-Control-Allow-Origin") }) + + ginkgo.It("should allow - origins with non-http[s] protocols", func() { + host := corsHost + origin := "test://localhost" + origin2 := "tauri://localhost:3000" + annotations := map[string]string{ + "nginx.ingress.kubernetes.io/enable-cors": "true", + "nginx.ingress.kubernetes.io/cors-allow-origin": "test://localhost, tauri://localhost:3000", + } + + ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations) + f.EnsureIngress(ing) + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", host). + WithHeader("Origin", origin). + Expect(). + Status(http.StatusOK).Headers(). + ValueEqual("Access-Control-Allow-Origin", []string{"test://localhost"}) + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", host). + WithHeader("Origin", origin2). + Expect(). + Status(http.StatusOK).Headers(). + ValueEqual("Access-Control-Allow-Origin", []string{"tauri://localhost:3000"}) + }) }) diff --git a/test/e2e/annotations/customheaders.go b/test/e2e/annotations/customheaders.go new file mode 100644 index 000000000..274ce8278 --- /dev/null +++ b/test/e2e/annotations/customheaders.go @@ -0,0 +1,110 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package annotations + +import ( + "fmt" + "net/http" + "strings" + + "github.com/onsi/ginkgo/v2" + + "k8s.io/ingress-nginx/test/e2e/framework" +) + +const ( + customHeaderHost = "custom-headers" +) + +var _ = framework.DescribeAnnotation("custom-headers-*", func() { + f := framework.NewDefaultFramework("custom-headers") + + ginkgo.BeforeEach(func() { + f.NewEchoDeployment() + }) + + ginkgo.It("should return status code 200 when no custom-headers is configured", func() { + ing := framework.NewSingleIngress(customHeaderHost, "/", customHeaderHost, f.Namespace, framework.EchoService, 80, nil) + f.EnsureIngress(ing) + + f.WaitForNginxServer(customHeaderHost, + func(server string) bool { + return strings.Contains(server, "server_name custom-headers") + }) + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", customHeaderHost). + Expect(). + Status(http.StatusOK). + Body().Contains(fmt.Sprintf("host=%v", customHeaderHost)) + }) + + ginkgo.It("should return status code 503 when custom-headers is configured with an invalid secret", func() { + annotations := map[string]string{ + "nginx.ingress.kubernetes.io/custom-headers": f.Namespace + "/custom-headers", + } + + ing := framework.NewSingleIngress(customHeaderHost, "/", customHeaderHost, f.Namespace, framework.EchoService, 80, annotations) + f.EnsureIngress(ing) + + f.WaitForNginxServer(customHeaderHost, + func(server string) bool { + return strings.Contains(server, "server_name custom-headers") + }) + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", customHeaderHost). + Expect(). + Status(http.StatusServiceUnavailable). + Body().Contains("503 Service Temporarily Unavailable") + }) + + ginkgo.It(`should set "more_set_headers 'My-Custom-Header' '42';" when custom-headers are set`, func() { + annotations := map[string]string{ + "nginx.ingress.kubernetes.io/custom-headers": f.Namespace + "/custom-headers", + } + + f.CreateConfigMap("custom-headers", map[string]string{ + "My-Custom-Header": "42", + "My-Custom-Header-Dollar": "$remote_addr", + }) + f.UpdateNginxConfigMapData("global-allowed-response-headers", "My-Custom-Header,My-Custom-Header-Dollar") + + ing := framework.NewSingleIngress(customHeaderHost, "/", customHeaderHost, f.Namespace, framework.EchoService, 80, annotations) + f.EnsureIngress(ing) + + f.WaitForNginxServer(customHeaderHost, + func(server string) bool { + return strings.Contains(server, `more_set_headers "My-Custom-Header: 42";`) + }) + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", customHeaderHost). + Expect(). + Status(http.StatusOK). + Header("My-Custom-Header").Contains("42") + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", customHeaderHost). + Expect(). + Status(http.StatusOK). + Header("My-Custom-Header-Dollar").Contains("$remote_addr") + }) +}) diff --git a/test/e2e/annotations/fromtowwwredirect.go b/test/e2e/annotations/fromtowwwredirect.go index b69cce93e..a3fb3b9b5 100644 --- a/test/e2e/annotations/fromtowwwredirect.go +++ b/test/e2e/annotations/fromtowwwredirect.go @@ -58,18 +58,12 @@ var _ = framework.DescribeAnnotation("from-to-www-redirect", func() { WithHeader("Host", fmt.Sprintf("%s.%s", "www", host)). Expect(). Status(http.StatusPermanentRedirect). - Header("Location").Equal("http://fromtowwwredirect.bar.com/foo") + Header("Location").Equal("http://fromtowwwredirect.bar.com:80/foo") }) ginkgo.It("should redirect from www HTTPS to HTTPS", func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "true", - }) - defer func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "false", - }) - }() + disableSnippet := f.AllowSnippetConfiguration() + defer disableSnippet() ginkgo.By("setting up server for redirect from www") @@ -107,7 +101,7 @@ var _ = framework.DescribeAnnotation("from-to-www-redirect", func() { WithHeader("Host", toHost). Expect(). Status(http.StatusPermanentRedirect). - Header("Location").Equal(fmt.Sprintf("https://%v", fromHost)) + Header("Location").Equal(fmt.Sprintf("https://%v:443", fromHost)) ginkgo.By("sending request to domain should not redirect to www") f.HTTPTestClientWithTLSConfig(&tls.Config{ diff --git a/test/e2e/annotations/globalratelimit.go b/test/e2e/annotations/globalratelimit.go deleted file mode 100644 index 96be467fe..000000000 --- a/test/e2e/annotations/globalratelimit.go +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package annotations - -import ( - "fmt" - "net/http" - "strings" - - "github.com/onsi/ginkgo/v2" - "github.com/stretchr/testify/assert" - - "k8s.io/ingress-nginx/test/e2e/framework" -) - -var _ = framework.DescribeAnnotation("annotation-global-rate-limit", func() { - f := framework.NewDefaultFramework("global-rate-limit") - host := "global-rate-limit-annotation" - - ginkgo.BeforeEach(func() { - f.NewEchoDeployment() - }) - - ginkgo.It("generates correct configuration", func() { - annotations := make(map[string]string) - annotations["nginx.ingress.kubernetes.io/global-rate-limit"] = "5" - annotations["nginx.ingress.kubernetes.io/global-rate-limit-window"] = "2m" - - // We need to allow { and } characters for this annotation to work - f.UpdateNginxConfigMapData("annotation-value-word-blocklist", "load_module, lua_package, _by_lua, location, root") - // Sleep a while just to guarantee that the configmap is applied - framework.Sleep() - - ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations) - ing = f.EnsureIngress(ing) - namespace := strings.ReplaceAll(string(ing.UID), "-", "") - - serverConfig := "" - f.WaitForNginxServer(host, func(server string) bool { - serverConfig = server - return true - }) - assert.Contains(ginkgo.GinkgoT(), serverConfig, - fmt.Sprintf(`global_throttle = { namespace = "%v", `+ - `limit = 5, window_size = 120, key = { { nil, nil, "remote_addr", nil, }, }, `+ - `ignored_cidrs = { } }`, - namespace)) - - f.HTTPTestClient().GET("/").WithHeader("Host", host).Expect().Status(http.StatusOK) - - ginkgo.By("regenerating the correct configuration after update") - annotations["nginx.ingress.kubernetes.io/global-rate-limit-key"] = "${remote_addr}${http_x_api_client}" - annotations["nginx.ingress.kubernetes.io/global-rate-limit-ignored-cidrs"] = "192.168.1.1, 234.234.234.0/24" - ing.SetAnnotations(annotations) - - f.WaitForReload(func() { - ing = f.UpdateIngress(ing) - }) - - serverConfig = "" - f.WaitForNginxServer(host, func(server string) bool { - serverConfig = server - return true - }) - assert.Contains(ginkgo.GinkgoT(), serverConfig, - fmt.Sprintf(`global_throttle = { namespace = "%v", `+ - `limit = 5, window_size = 120, `+ - `key = { { nil, "remote_addr", nil, nil, }, { nil, "http_x_api_client", nil, nil, }, }, `+ - `ignored_cidrs = { "192.168.1.1", "234.234.234.0/24", } }`, - namespace)) - - f.HTTPTestClient().GET("/").WithHeader("Host", host).Expect().Status(http.StatusOK) - }) -}) diff --git a/test/e2e/annotations/grpc.go b/test/e2e/annotations/grpc.go index c7228cd0e..2a9c5a983 100644 --- a/test/e2e/annotations/grpc.go +++ b/test/e2e/annotations/grpc.go @@ -22,11 +22,13 @@ import ( "fmt" "strings" + delaypb "github.com/Anddd7/pb/grpcbin" pb "github.com/moul/pb/grpcbin/go-grpc" "github.com/onsi/ginkgo/v2" "github.com/stretchr/testify/assert" "google.golang.org/grpc" "google.golang.org/grpc/credentials" + "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/metadata" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -35,7 +37,10 @@ import ( "k8s.io/ingress-nginx/test/e2e/framework" ) -const echoHost = "echo" +const ( + echoHost = "echo" + host = "grpc" +) var _ = framework.DescribeAnnotation("backend-protocol - GRPC", func() { f := framework.NewDefaultFramework("grpc", framework.WithHTTPBunEnabled()) @@ -43,8 +48,6 @@ var _ = framework.DescribeAnnotation("backend-protocol - GRPC", func() { ginkgo.It("should use grpc_pass in the configuration file", func() { f.NewGRPCFortuneTellerDeployment() - host := "grpc" - annotations := map[string]string{ "nginx.ingress.kubernetes.io/backend-protocol": "GRPC", } @@ -190,14 +193,8 @@ var _ = framework.DescribeAnnotation("backend-protocol - GRPC", func() { ginkgo.It("should return OK for service with backend protocol GRPCS", func() { f.NewGRPCBinDeployment() - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "true", - }) - defer func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "false", - }) - }() + disableSnippet := f.AllowSnippetConfiguration() + defer disableSnippet() host := echoHost @@ -259,4 +256,89 @@ var _ = framework.DescribeAnnotation("backend-protocol - GRPC", func() { metadata := res.GetMetadata() assert.Equal(ginkgo.GinkgoT(), metadata["content-type"].Values[0], "application/grpc") }) + + ginkgo.It("should return OK when request not exceed timeout", func() { + f.NewGRPCBinDelayDeployment() + + proxyTimeout := "10" + ingressName := "grpcbin-delay" + + annotations := make(map[string]string) + annotations["nginx.ingress.kubernetes.io/backend-protocol"] = "GRPC" + annotations["nginx.ingress.kubernetes.io/proxy-connect-timeout"] = proxyTimeout + annotations["nginx.ingress.kubernetes.io/proxy-send-timeout"] = proxyTimeout + annotations["nginx.ingress.kubernetes.io/proxy-read-timeout"] = proxyTimeout + + ing := framework.NewSingleIngress(host, "/", host, f.Namespace, ingressName, 50051, annotations) + + f.EnsureIngress(ing) + + f.WaitForNginxServer(host, + func(server string) bool { + return strings.Contains(server, fmt.Sprintf("grpc_connect_timeout %ss;", proxyTimeout)) && + strings.Contains(server, fmt.Sprintf("grpc_send_timeout %ss;", proxyTimeout)) && + strings.Contains(server, fmt.Sprintf("grpc_read_timeout %ss;", proxyTimeout)) + }) + + conn, err := grpc.NewClient( + f.GetNginxIP()+":80", + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithAuthority(host), + ) + assert.Nil(ginkgo.GinkgoT(), err, "error creating a connection") + defer conn.Close() + + client := delaypb.NewGrpcbinServiceClient(conn) + + res, err := client.Unary(context.Background(), &delaypb.UnaryRequest{ + Data: "hello", + }) + assert.Nil(ginkgo.GinkgoT(), err) + + metadata := res.GetResponseAttributes().RequestHeaders + assert.Equal(ginkgo.GinkgoT(), metadata["content-type"], "application/grpc") + assert.Equal(ginkgo.GinkgoT(), metadata[":authority"], host) + }) + + ginkgo.It("should return Error when request exceed timeout", func() { + f.NewGRPCBinDelayDeployment() + + proxyTimeout := "10" + ingressName := "grpcbin-delay" + + annotations := make(map[string]string) + annotations["nginx.ingress.kubernetes.io/backend-protocol"] = "GRPC" + annotations["nginx.ingress.kubernetes.io/proxy-connect-timeout"] = proxyTimeout + annotations["nginx.ingress.kubernetes.io/proxy-send-timeout"] = proxyTimeout + annotations["nginx.ingress.kubernetes.io/proxy-read-timeout"] = proxyTimeout + + ing := framework.NewSingleIngress(host, "/", host, f.Namespace, ingressName, 50051, annotations) + + f.EnsureIngress(ing) + + f.WaitForNginxServer(host, + func(server string) bool { + return strings.Contains(server, fmt.Sprintf("grpc_connect_timeout %ss;", proxyTimeout)) && + strings.Contains(server, fmt.Sprintf("grpc_send_timeout %ss;", proxyTimeout)) && + strings.Contains(server, fmt.Sprintf("grpc_read_timeout %ss;", proxyTimeout)) + }) + + conn, err := grpc.NewClient( + f.GetNginxIP()+":80", + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithAuthority(host), + ) + assert.Nil(ginkgo.GinkgoT(), err, "error creating a connection") + defer conn.Close() + + client := delaypb.NewGrpcbinServiceClient(conn) + + _, err = client.Unary(context.Background(), &delaypb.UnaryRequest{ + Data: "hello", + RequestAttributes: &delaypb.RequestAttributes{ + Delay: 15, + }, + }) + assert.Error(ginkgo.GinkgoT(), err) + }) }) diff --git a/test/e2e/annotations/modsecurity/modsecurity.go b/test/e2e/annotations/modsecurity/modsecurity.go index a3e7d80ba..730fc76e7 100644 --- a/test/e2e/annotations/modsecurity/modsecurity.go +++ b/test/e2e/annotations/modsecurity/modsecurity.go @@ -100,14 +100,8 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() { }) ginkgo.It("should enable modsecurity with snippet", func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "true", - }) - defer func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "false", - }) - }() + disableSnippet := f.AllowSnippetConfiguration() + defer disableSnippet() host := modSecurityFooHost nameSpace := f.Namespace @@ -173,14 +167,8 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() { }) ginkgo.It("should enable modsecurity with snippet and block requests", func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "true", - }) - defer func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "false", - }) - }() + disableSnippet := f.AllowSnippetConfiguration() + defer disableSnippet() host := modSecurityFooHost nameSpace := f.Namespace @@ -212,14 +200,8 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() { }) ginkgo.It("should enable modsecurity globally and with modsecurity-snippet block requests", func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "true", - }) - defer func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "false", - }) - }() + disableSnippet := f.AllowSnippetConfiguration() + defer disableSnippet() host := modSecurityFooHost nameSpace := f.Namespace @@ -251,16 +233,11 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() { }) ginkgo.It("should enable modsecurity when enable-owasp-modsecurity-crs is set to true", func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "true", - "enable-modsecurity": "true", - "enable-owasp-modsecurity-crs": "true", - }) - defer func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "false", - }) - }() + disableSnippet := f.AllowSnippetConfiguration() + defer disableSnippet() + + f.UpdateNginxConfigMapData("enable-modsecurity", "true") + f.UpdateNginxConfigMapData("enable-owasp-modsecurity-crs", "true") host := modSecurityFooHost nameSpace := f.Namespace @@ -290,6 +267,8 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() { }) ginkgo.It("should enable modsecurity through the config map", func() { + disableSnippet := f.AllowSnippetConfiguration() + defer disableSnippet() host := modSecurityFooHost nameSpace := f.Namespace @@ -310,17 +289,9 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() { f.EnsureIngress(ing) expectedComment := "SecRuleEngine On" - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "true", - "enable-modsecurity": "true", - "enable-owasp-modsecurity-crs": "true", - "modsecurity-snippet": expectedComment, - }) - defer func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "false", - }) - }() + f.UpdateNginxConfigMapData("enable-modsecurity", "true") + f.UpdateNginxConfigMapData("enable-owasp-modsecurity-crs", "true") + f.UpdateNginxConfigMapData("modsecurity-snippet", expectedComment) f.WaitForNginxServer(host, func(server string) bool { @@ -339,6 +310,9 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() { host := modSecurityFooHost nameSpace := f.Namespace + f.UpdateNginxConfigMapData("annotations-risk-level", "Critical") // To enable snippet configurations + defer f.UpdateNginxConfigMapData("annotations-risk-level", "High") + snippet := `SecRequestBodyAccess On SecAuditEngine RelevantOnly SecAuditLogParts ABIJDEFHZ @@ -378,14 +352,9 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() { }) ginkgo.It("should disable default modsecurity conf setting when modsecurity-snippet is specified", func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "true", - }) - defer func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "false", - }) - }() + disableSnippet := f.AllowSnippetConfiguration() + defer disableSnippet() + host := modSecurityFooHost nameSpace := f.Namespace diff --git a/test/e2e/annotations/proxy.go b/test/e2e/annotations/proxy.go index 235b828e7..8e9866021 100644 --- a/test/e2e/annotations/proxy.go +++ b/test/e2e/annotations/proxy.go @@ -160,11 +160,13 @@ var _ = framework.DescribeAnnotation("proxy-*", func() { proxyBuffering := "on" proxyBuffersNumber := "8" proxyBufferSize := "8k" + proxyBusyBuffersSize := "16k" annotations := make(map[string]string) annotations["nginx.ingress.kubernetes.io/proxy-buffering"] = proxyBuffering annotations["nginx.ingress.kubernetes.io/proxy-buffers-number"] = proxyBuffersNumber annotations["nginx.ingress.kubernetes.io/proxy-buffer-size"] = proxyBufferSize + annotations["nginx.ingress.kubernetes.io/proxy-busy-buffers-size"] = proxyBusyBuffersSize ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations) f.EnsureIngress(ing) @@ -174,6 +176,7 @@ var _ = framework.DescribeAnnotation("proxy-*", func() { return strings.Contains(server, fmt.Sprintf("proxy_buffering %s;", proxyBuffering)) && strings.Contains(server, fmt.Sprintf("proxy_buffer_size %s;", proxyBufferSize)) && strings.Contains(server, fmt.Sprintf("proxy_buffers %s %s;", proxyBuffersNumber, proxyBufferSize)) && + strings.Contains(server, fmt.Sprintf("proxy_busy_buffers_size %s;", proxyBusyBuffersSize)) && strings.Contains(server, fmt.Sprintf("proxy_request_buffering %s;", proxyBuffering)) }) }) diff --git a/test/e2e/annotations/relativeredirects.go b/test/e2e/annotations/relativeredirects.go new file mode 100644 index 000000000..430b357e4 --- /dev/null +++ b/test/e2e/annotations/relativeredirects.go @@ -0,0 +1,107 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package annotations + +import ( + "fmt" + "net/http" + "strings" + + "github.com/onsi/ginkgo/v2" + "github.com/stretchr/testify/assert" + "k8s.io/ingress-nginx/test/e2e/framework" +) + +const ( + relativeRedirectsHostname = "rr.foo.com" + relativeRedirectsRedirectPath = "/something" + relativeRedirectsRelativeRedirectURL = "/new-location" +) + +var _ = framework.DescribeAnnotation("relative-redirects", func() { + f := framework.NewDefaultFramework("relative-redirects") + + ginkgo.BeforeEach(func() { + f.NewHttpbunDeployment() + f.NewEchoDeployment() + }) + + ginkgo.It("configures Nginx correctly", func() { + annotations := map[string]string{ + "nginx.ingress.kubernetes.io/relative-redirects": "true", + } + + ing := framework.NewSingleIngress(relativeRedirectsHostname, "/", relativeRedirectsHostname, f.Namespace, framework.HTTPBunService, 80, annotations) + f.EnsureIngress(ing) + + var serverConfig string + f.WaitForNginxServer(relativeRedirectsHostname, func(srvCfg string) bool { + serverConfig = srvCfg + return strings.Contains(serverConfig, fmt.Sprintf("server_name %s", relativeRedirectsHostname)) + }) + + ginkgo.By("turning off absolute_redirect directive") + assert.Contains(ginkgo.GinkgoT(), serverConfig, "absolute_redirect off;") + }) + + ginkgo.It("should respond with absolute URL in Location", func() { + absoluteRedirectURL := fmt.Sprintf("http://%s%s", relativeRedirectsHostname, relativeRedirectsRelativeRedirectURL) + annotations := map[string]string{ + "nginx.ingress.kubernetes.io/permanent-redirect": relativeRedirectsRelativeRedirectURL, + "nginx.ingress.kubernetes.io/relative-redirects": "false", + } + + ginkgo.By("setup ingress") + ing := framework.NewSingleIngress(relativeRedirectsHostname, relativeRedirectsRedirectPath, relativeRedirectsHostname, f.Namespace, framework.EchoService, 80, annotations) + f.EnsureIngress(ing) + + f.WaitForNginxServer(relativeRedirectsHostname, func(srvCfg string) bool { + return strings.Contains(srvCfg, fmt.Sprintf("server_name %s", relativeRedirectsHostname)) + }) + + ginkgo.By("sending request to redirected URL path") + f.HTTPTestClient(). + GET(relativeRedirectsRedirectPath). + WithHeader("Host", relativeRedirectsHostname). + Expect(). + Status(http.StatusMovedPermanently). + Header("Location").Equal(absoluteRedirectURL) + }) + + ginkgo.It("should respond with relative URL in Location", func() { + annotations := map[string]string{ + "nginx.ingress.kubernetes.io/permanent-redirect": relativeRedirectsRelativeRedirectURL, + "nginx.ingress.kubernetes.io/relative-redirects": "true", + } + + ginkgo.By("setup ingress") + ing := framework.NewSingleIngress(relativeRedirectsHostname, relativeRedirectsRedirectPath, relativeRedirectsHostname, f.Namespace, framework.EchoService, 80, annotations) + f.EnsureIngress(ing) + + f.WaitForNginxServer(relativeRedirectsHostname, func(srvCfg string) bool { + return strings.Contains(srvCfg, fmt.Sprintf("server_name %s", relativeRedirectsHostname)) + }) + + ginkgo.By("sending request to redirected URL path") + f.HTTPTestClient(). + GET(relativeRedirectsRedirectPath). + WithHeader("Host", relativeRedirectsHostname). + Expect(). + Status(http.StatusMovedPermanently). + Header("Location").Equal(relativeRedirectsRelativeRedirectURL) + }) +}) diff --git a/test/e2e/annotations/serversnippet.go b/test/e2e/annotations/serversnippet.go index 1195b728a..c94960a3d 100644 --- a/test/e2e/annotations/serversnippet.go +++ b/test/e2e/annotations/serversnippet.go @@ -33,14 +33,8 @@ var _ = framework.DescribeAnnotation("server-snippet", func() { }) ginkgo.It(`add valid directives to server via server snippet`, func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "true", - }) - defer func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "false", - }) - }() + disableSnippet := f.AllowSnippetConfiguration() + defer disableSnippet() host := "serversnippet.foo.com" annotations := map[string]string{ @@ -68,14 +62,8 @@ var _ = framework.DescribeAnnotation("server-snippet", func() { }) ginkgo.It(`drops server snippet if disabled by the administrator`, func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "true", - }) - defer func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "false", - }) - }() + f.UpdateNginxConfigMapData("annotations-risk-level", "Critical") // To enable snippet configurations + defer f.UpdateNginxConfigMapData("annotations-risk-level", "High") host := "noserversnippet.foo.com" annotations := map[string]string{ @@ -85,11 +73,6 @@ var _ = framework.DescribeAnnotation("server-snippet", func() { } ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations) - f.UpdateNginxConfigMapData("allow-snippet-annotations", "false") - defer func() { - // Return to the original value - f.UpdateNginxConfigMapData("allow-snippet-annotations", "true") - }() // Sleep a while just to guarantee that the configmap is applied framework.Sleep() f.EnsureIngress(ing) diff --git a/test/e2e/annotations/snippet.go b/test/e2e/annotations/snippet.go index 0c6148a4f..9e3160dcc 100644 --- a/test/e2e/annotations/snippet.go +++ b/test/e2e/annotations/snippet.go @@ -33,15 +33,8 @@ var _ = framework.DescribeAnnotation("configuration-snippet", func() { ginkgo.It("set snippet more_set_headers in all locations", func() { host := "configurationsnippet.foo.com" - - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "true", - }) - defer func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "false", - }) - }() + disableSnippet := f.AllowSnippetConfiguration() + defer disableSnippet() annotations := map[string]string{ "nginx.ingress.kubernetes.io/configuration-snippet": `more_set_headers "Foo1: Bar1";`, @@ -71,6 +64,8 @@ var _ = framework.DescribeAnnotation("configuration-snippet", func() { }) ginkgo.It("drops snippet more_set_header in all locations if disabled by admin", func() { + f.UpdateNginxConfigMapData("annotations-risk-level", "Critical") // To enable snippet configurations + defer f.UpdateNginxConfigMapData("annotations-risk-level", "High") host := "noconfigurationsnippet.foo.com" annotations := map[string]string{ "nginx.ingress.kubernetes.io/configuration-snippet": `more_set_headers "Foo1: Bar1";`, diff --git a/test/e2e/annotations/streamsnippet.go b/test/e2e/annotations/streamsnippet.go index 432537b4a..f91cdc34e 100644 --- a/test/e2e/annotations/streamsnippet.go +++ b/test/e2e/annotations/streamsnippet.go @@ -39,14 +39,8 @@ var _ = framework.DescribeSetting("stream-snippet", func() { }) ginkgo.It("should add value of stream-snippet to nginx config", func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "true", - }) - defer func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "false", - }) - }() + disableSnippet := f.AllowSnippetConfiguration() + defer disableSnippet() host := "foo.com" diff --git a/test/e2e/disableleaderelection/disable_leader.go b/test/e2e/disableleaderelection/disable_leader.go new file mode 100644 index 000000000..fd7369dfb --- /dev/null +++ b/test/e2e/disableleaderelection/disable_leader.go @@ -0,0 +1,93 @@ +/* +Copyright 2024 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package disableleaderelection + +import ( + "net/http" + "strings" + + "github.com/onsi/ginkgo/v2" + + "k8s.io/ingress-nginx/test/e2e/framework" +) + +var _ = framework.IngressNginxDescribe("[Disable Leader] Routing works when leader election was disabled", func() { + f := framework.NewDefaultFramework("disableleaderelection") + + ginkgo.BeforeEach(func() { + f.NewEchoDeployment() + }) + + ginkgo.It("should create multiple ingress routings rules when leader election has disabled", func() { + host1 := "leader.election.disabled.com" + host2 := "leader.election.disabled2.com" + + ing1 := framework.NewSingleIngress(host1, "/foo", host1, f.Namespace, framework.EchoService, 80, nil) + f.EnsureIngress(ing1) + + ing2 := framework.NewSingleIngress(host2, "/ping", host2, f.Namespace, framework.EchoService, 80, nil) + f.EnsureIngress(ing2) + + f.WaitForNginxServer(host1, + func(server string) bool { + return strings.Contains(server, host1) && + strings.Contains(server, "location /foo") + }) + + f.WaitForNginxServer(host2, + func(server string) bool { + return strings.Contains(server, host2) && + strings.Contains(server, "location /ping") + }) + + f.HTTPTestClient(). + GET("/foo"). + WithHeader("Host", host1). + Expect(). + Status(http.StatusOK) + + f.HTTPTestClient(). + GET("/bar"). + WithHeader("Host", host1). + Expect(). + Status(http.StatusNotFound) + + f.HTTPTestClient(). + GET("/foo"). + WithHeader("Host", host2). + Expect(). + Status(http.StatusNotFound) + + f.HTTPTestClient(). + GET("/ping"). + WithHeader("Host", host2). + Expect(). + Status(http.StatusOK) + + f.HTTPTestClient(). + GET("/pong"). + WithHeader("Host", host2). + Expect(). + Status(http.StatusNotFound) + + f.HTTPTestClient(). + GET("/ping"). + WithHeader("Host", host1). + Expect(). + Status(http.StatusNotFound) + }) +}) diff --git a/test/e2e/e2e.go b/test/e2e/e2e.go index 631e70ae4..9bf005164 100644 --- a/test/e2e/e2e.go +++ b/test/e2e/e2e.go @@ -35,6 +35,7 @@ import ( _ "k8s.io/ingress-nginx/test/e2e/cgroups" _ "k8s.io/ingress-nginx/test/e2e/dbg" _ "k8s.io/ingress-nginx/test/e2e/defaultbackend" + _ "k8s.io/ingress-nginx/test/e2e/disableleaderelection" _ "k8s.io/ingress-nginx/test/e2e/endpointslices" _ "k8s.io/ingress-nginx/test/e2e/gracefulshutdown" _ "k8s.io/ingress-nginx/test/e2e/ingress" diff --git a/test/e2e/endpointslices/topology.go b/test/e2e/endpointslices/topology.go index 38c5f8b76..70f7ff86b 100644 --- a/test/e2e/endpointslices/topology.go +++ b/test/e2e/endpointslices/topology.go @@ -84,7 +84,7 @@ var _ = framework.IngressNginxDescribeSerial("[TopologyHints] topology aware rou } if gotHints { - // we have 2 replics, if there is just one backend it means that we are routing according slices hints to same zone as controller is + // we have 2 replicas, if there is just one backend it means that we are routing according slices hints to same zone as controller is assert.Equal(ginkgo.GinkgoT(), 1, gotBackends) } else { // two replicas should have two endpoints without topology hints diff --git a/test/e2e/framework/deployment.go b/test/e2e/framework/deployment.go index 08a5353b2..f213e2e98 100644 --- a/test/e2e/framework/deployment.go +++ b/test/e2e/framework/deployment.go @@ -43,11 +43,11 @@ const HTTPBunService = "httpbun" // NipService name of external service using nip.io const NIPService = "external-nip" -// HTTPBunImage is the default image that is used to deploy HTTPBun with the framwork +// HTTPBunImage is the default image that is used to deploy HTTPBun with the framework var HTTPBunImage = os.Getenv("HTTPBUN_IMAGE") // EchoImage is the default image to be used by the echo service -const EchoImage = "registry.k8s.io/ingress-nginx/e2e-test-echo@sha256:4938d1d91a2b7d19454460a8c1b010b89f6ff92d2987fd889ac3e8fc3b70d91a" //#nosec G101 +const EchoImage = "registry.k8s.io/ingress-nginx/e2e-test-echo:v1.1.1@sha256:a1e0152e2eeab26e3f6fd3986f3d82b17bc7711717cae5392dcd18dd447ba6ef" //#nosec G101 // TODO: change all Deployment functions to use these options // in order to reduce complexity and have a unified API across the diff --git a/test/e2e/framework/exec.go b/test/e2e/framework/exec.go index 580a8f58e..8d528c37a 100644 --- a/test/e2e/framework/exec.go +++ b/test/e2e/framework/exec.go @@ -117,11 +117,7 @@ func (f *Framework) newIngressController(namespace, namespaceOverlay string) err isChroot = "false" } - enableAnnotationValidations, ok := os.LookupEnv("ENABLE_VALIDATIONS") - if !ok { - enableAnnotationValidations = "false" - } - cmd := exec.Command("./wait-for-nginx.sh", namespace, namespaceOverlay, isChroot, enableAnnotationValidations) + cmd := exec.Command("./wait-for-nginx.sh", namespace, namespaceOverlay, isChroot) out, err := cmd.CombinedOutput() if err != nil { return fmt.Errorf("unexpected error waiting for ingress controller deployment: %v.\nLogs:\n%v", err, string(out)) diff --git a/test/e2e/framework/fastcgi_helloserver.go b/test/e2e/framework/fastcgi_helloserver.go index 60482c067..c414c4da3 100644 --- a/test/e2e/framework/fastcgi_helloserver.go +++ b/test/e2e/framework/fastcgi_helloserver.go @@ -59,7 +59,7 @@ func (f *Framework) NewNewFastCGIHelloServerDeploymentWithReplicas(replicas int3 Containers: []corev1.Container{ { Name: "fastcgi-helloserver", - Image: "registry.k8s.io/ingress-nginx/fastcgi-helloserver:v1.0.1@sha256:bfcce5866d106450f41af15af868886c953c3661373f34aa6d99bcc6f44c6ba6", + Image: "registry.k8s.io/ingress-nginx/fastcgi-helloserver:v1.1.1@sha256:6af4d8c7745c6727aab759db616a58fd68d784d07ce7a32d1ad149c331fd9a6f", Env: []corev1.EnvVar{}, Ports: []corev1.ContainerPort{ { diff --git a/test/e2e/framework/framework.go b/test/e2e/framework/framework.go index b71d84baa..204da7df0 100644 --- a/test/e2e/framework/framework.go +++ b/test/e2e/framework/framework.go @@ -16,6 +16,7 @@ package framework import ( "context" "crypto/tls" + "encoding/json" "fmt" "net" "net/http" @@ -100,7 +101,7 @@ func NewDefaultFramework(baseName string, opts ...func(*Framework)) *Framework { } // NewSimpleFramework makes a new framework that allows the usage of a namespace -// for arbitraty tests. +// for arbitrary tests. func NewSimpleFramework(baseName string, opts ...func(*Framework)) *Framework { defer ginkgo.GinkgoRecover() @@ -283,6 +284,15 @@ func (f *Framework) WaitForNginxConfiguration(matcher func(cfg string) bool) { Sleep(1 * time.Second) } +// WaitForLuaConfiguration waits until the nginx configuration contains a particular configuration +// `cfg` passed to matcher is normalized by replacing all tabs and spaces with single space. +func (f *Framework) WaitForLuaConfiguration(matcher func(jsonCfg map[string]interface{}) bool) { + //nolint:staticcheck // TODO: will replace it since wait.Poll is deprecated + err := wait.Poll(Poll, DefaultTimeout, f.matchLuaConditions(matcher)) + assert.Nil(ginkgo.GinkgoT(), err, "waiting for nginx lua configuration condition/s") + Sleep(1 * time.Second) +} + // WaitForNginxCustomConfiguration waits until the nginx configuration given part (from, to) contains a particular configuration func (f *Framework) WaitForNginxCustomConfiguration(from, to string, matcher func(cfg string) bool) { //nolint:staticcheck // TODO: will replace it since wait.Poll is deprecated @@ -326,6 +336,29 @@ func (f *Framework) matchNginxConditions(name string, matcher func(cfg string) b } } +func (f *Framework) matchLuaConditions(matcher func(jsonCfg map[string]interface{}) bool) wait.ConditionFunc { + return func() (bool, error) { + cmd := "cat /etc/nginx/lua/cfg.json" + + o, err := f.ExecCommand(f.pod, cmd) + if err != nil { + return false, nil + } + + if klog.V(10).Enabled() && o != "" { + klog.InfoS("Lua", "configuration", o) + } + + luaConfig := make(map[string]interface{}) // Use unstructured so we can walk through JSON + if err := json.Unmarshal([]byte(o), &luaConfig); err != nil { + return false, err + } + + // passes the lua interface to the function + return matcher(luaConfig), nil + } +} + func (f *Framework) matchNginxCustomConditions(from, to string, matcher func(cfg string) bool) wait.ConditionFunc { return func() (bool, error) { cmd := fmt.Sprintf("cat /etc/nginx/nginx.conf| awk '/%v/,/%v/'", from, to) @@ -383,6 +416,20 @@ func (f *Framework) SetNginxConfigMapData(cmData map[string]string) { f.WaitForReload(fn) } +// SetNginxConfigMapData sets ingress-nginx's nginx-ingress-controller configMap data +func (f *Framework) AllowSnippetConfiguration() func() { + f.SetNginxConfigMapData(map[string]string{ + "allow-snippet-annotations": "true", + "annotations-risk-level": "Critical", // To enable snippet configurations + }) + return func() { + f.SetNginxConfigMapData(map[string]string{ + "allow-snippet-annotations": "false", + "annotations-risk-level": "High", + }) + } +} + // CreateConfigMap creates a new configmap in the current namespace func (f *Framework) CreateConfigMap(name string, data map[string]string) { _, err := f.KubeClientSet.CoreV1().ConfigMaps(f.Namespace).Create(context.TODO(), &v1.ConfigMap{ diff --git a/test/e2e/framework/grpc_delay.go b/test/e2e/framework/grpc_delay.go new file mode 100644 index 000000000..58d10b2e9 --- /dev/null +++ b/test/e2e/framework/grpc_delay.go @@ -0,0 +1,109 @@ +/* +Copyright 2024 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package framework + +import ( + "github.com/onsi/ginkgo/v2" + "github.com/stretchr/testify/assert" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/util/intstr" +) + +// NewGRPCBinDelayDeployment creates a new single replica +// deployment of the grpcbin image in a particular namespace +func (f *Framework) NewGRPCBinDelayDeployment() { + f.NewNewGRPCBinDelayDeploymentWithReplicas(1) +} + +// NewNewGRPCBinDelayDeploymentWithReplicas creates a new deployment of the +// grpcbin image in a particular namespace. Number of replicas is configurable +func (f *Framework) NewNewGRPCBinDelayDeploymentWithReplicas(replicas int32) { + name := "grpcbin-delay" + + deployment := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: f.Namespace, + }, + Spec: appsv1.DeploymentSpec{ + Replicas: NewInt32(replicas), + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": name, + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "app": name, + }, + }, + Spec: corev1.PodSpec{ + TerminationGracePeriodSeconds: NewInt64(0), + Containers: []corev1.Container{ + { + Name: name, + Image: "ghcr.io/anddd7/grpcbin:v1.0.6", + Env: []corev1.EnvVar{}, + Ports: []corev1.ContainerPort{ + { + Name: "grpc", + ContainerPort: 50051, + }, + }, + }, + }, + }, + }, + }, + } + + d := f.EnsureDeployment(deployment) + + err := waitForPodsReady(f.KubeClientSet, DefaultTimeout, int(replicas), f.Namespace, &metav1.ListOptions{ + LabelSelector: fields.SelectorFromSet(fields.Set(d.Spec.Template.ObjectMeta.Labels)).String(), + }) + assert.Nil(ginkgo.GinkgoT(), err, "failed to wait for to become ready") + + service := &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: f.Namespace, + }, + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ + { + Name: "grpc", + Port: 50051, + TargetPort: intstr.FromInt(50051), + Protocol: "TCP", + }, + }, + Selector: map[string]string{ + "app": name, + }, + }, + } + + f.EnsureService(service) + + err = WaitForEndpoints(f.KubeClientSet, DefaultTimeout, name, f.Namespace, int(replicas)) + assert.Nil(ginkgo.GinkgoT(), err, "waiting for endpoints to become ready") +} diff --git a/test/e2e/gracefulshutdown/shutdown.go b/test/e2e/gracefulshutdown/shutdown.go index 604143da8..e9883338f 100644 --- a/test/e2e/gracefulshutdown/shutdown.go +++ b/test/e2e/gracefulshutdown/shutdown.go @@ -37,7 +37,7 @@ var _ = framework.IngressNginxDescribe("[Shutdown] ingress controller", func() { f.NewSlowEchoDeployment() }) - ginkgo.It("should shutdown in less than 60 secons without pending connections", func() { + ginkgo.It("should shutdown in less than 60 seconds without pending connections", func() { f.EnsureIngress(framework.NewSingleIngress(host, "/", host, f.Namespace, framework.SlowEchoService, 80, nil)) f.WaitForNginxServer(host, diff --git a/test/e2e/ingress/multiple_rules.go b/test/e2e/ingress/multiple_rules.go index f44b2f8dd..9247dc1d3 100644 --- a/test/e2e/ingress/multiple_rules.go +++ b/test/e2e/ingress/multiple_rules.go @@ -36,14 +36,8 @@ var _ = framework.IngressNginxDescribe("single ingress - multiple hosts", func() }) ginkgo.It("should set the correct $service_name NGINX variable", func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "true", - }) - defer func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "false", - }) - }() + disableSnippet := f.AllowSnippetConfiguration() + defer disableSnippet() annotations := map[string]string{ "nginx.ingress.kubernetes.io/configuration-snippet": `more_set_input_headers "service-name: $service_name";`, diff --git a/test/e2e/ingress/pathtype_exact.go b/test/e2e/ingress/pathtype_exact.go index d0564cbf6..2660e32a4 100644 --- a/test/e2e/ingress/pathtype_exact.go +++ b/test/e2e/ingress/pathtype_exact.go @@ -35,14 +35,8 @@ var _ = framework.IngressNginxDescribe("[Ingress] [PathType] exact", func() { }) ginkgo.It("should choose exact location for /exact", func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "true", - }) - defer func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "false", - }) - }() + disableSnippet := f.AllowSnippetConfiguration() + defer disableSnippet() host := "exact.path" diff --git a/test/e2e/ingress/pathtype_mixed.go b/test/e2e/ingress/pathtype_mixed.go index e7bf2532e..3212089c9 100644 --- a/test/e2e/ingress/pathtype_mixed.go +++ b/test/e2e/ingress/pathtype_mixed.go @@ -37,14 +37,8 @@ var _ = framework.IngressNginxDescribe("[Ingress] [PathType] mix Exact and Prefi exactPathType := networking.PathTypeExact ginkgo.It("should choose the correct location", func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "true", - }) - defer func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "false", - }) - }() + disableSnippet := f.AllowSnippetConfiguration() + defer disableSnippet() host := "mixed.path" diff --git a/test/e2e/lua/dynamic_configuration.go b/test/e2e/lua/dynamic_configuration.go index 8ec1ef839..a5e2196ce 100644 --- a/test/e2e/lua/dynamic_configuration.go +++ b/test/e2e/lua/dynamic_configuration.go @@ -48,12 +48,7 @@ var _ = framework.IngressNginxDescribe("[Lua] dynamic configuration", func() { ginkgo.It("configures balancer Lua middleware correctly", func() { f.WaitForNginxConfiguration(func(cfg string) bool { - return strings.Contains(cfg, "balancer.init_worker()") && strings.Contains(cfg, "balancer.balance()") - }) - - host := "foo.com" - f.WaitForNginxServer(host, func(server string) bool { - return strings.Contains(server, "balancer.rewrite()") && strings.Contains(server, "balancer.log()") + return strings.Contains(cfg, "balancer_by_lua_file /etc/nginx/lua/nginx/ngx_conf_balancer.lua") }) }) diff --git a/test/e2e/metrics/metrics.go b/test/e2e/metrics/metrics.go index 907b53732..bec09bb37 100644 --- a/test/e2e/metrics/metrics.go +++ b/test/e2e/metrics/metrics.go @@ -36,6 +36,7 @@ const waitForMetrics = 2 * time.Second var _ = framework.IngressNginxDescribe("[metrics] exported prometheus metrics", func() { f := framework.NewDefaultFramework("metrics") host := "foo.com" + wildcardHost := "wildcard." + host ginkgo.BeforeEach(func() { f.NewEchoDeployment() @@ -91,4 +92,50 @@ var _ = framework.IngressNginxDescribe("[metrics] exported prometheus metrics", assert.Nil(ginkgo.GinkgoT(), err) assert.NotNil(ginkgo.GinkgoT(), mf) }) + ginkgo.It("request metrics per undefined host are present when flag is set", func() { + err := f.UpdateIngressControllerDeployment(func(deployment *appsv1.Deployment) error { + args := deployment.Spec.Template.Spec.Containers[0].Args + args = append(args, "--metrics-per-undefined-host=true") + deployment.Spec.Template.Spec.Containers[0].Args = args + _, err := f.KubeClientSet.AppsV1().Deployments(f.Namespace).Update(context.TODO(), deployment, metav1.UpdateOptions{}) + return err + }) + assert.Nil(ginkgo.GinkgoT(), err, "updating deployment") + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", wildcardHost). + Expect(). + Status(http.StatusNotFound) + time.Sleep(waitForMetrics) + + ip := f.GetNginxPodIP() + reqMetrics, err := f.GetMetric("nginx_ingress_controller_requests", ip) + assert.Nil(ginkgo.GinkgoT(), err) + assert.NotNil(ginkgo.GinkgoT(), reqMetrics.Metric) + assert.Len(ginkgo.GinkgoT(), reqMetrics.Metric, 1) + + containedLabel := false + for _, label := range reqMetrics.Metric[0].Label { + if *label.Name == "host" && *label.Value == wildcardHost { + containedLabel = true + break + } + } + + assert.Truef(ginkgo.GinkgoT(), containedLabel, "expected reqMetrics to contain label with \"name\"=\"host\" \"value\"=%q, but it did not: %s", wildcardHost, reqMetrics.String()) + }) + ginkgo.It("request metrics per undefined host are not present when flag is not set", func() { + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", wildcardHost). + Expect(). + Status(http.StatusNotFound) + time.Sleep(waitForMetrics) + + ip := f.GetNginxPodIP() + reqMetrics, err := f.GetMetric("nginx_ingress_controller_requests", ip) + assert.EqualError(ginkgo.GinkgoT(), err, "there is no metric with name nginx_ingress_controller_requests") + assert.Nil(ginkgo.GinkgoT(), reqMetrics) + }) }) diff --git a/test/e2e/run-chart-test.sh b/test/e2e/run-chart-test.sh index 7d388c215..7e3f2fe9b 100755 --- a/test/e2e/run-chart-test.sh +++ b/test/e2e/run-chart-test.sh @@ -62,7 +62,7 @@ export KUBECONFIG="${KUBECONFIG:-$HOME/.kube/kind-config-$KIND_CLUSTER_NAME}" if [ "${SKIP_CLUSTER_CREATION:-false}" = "false" ]; then echo "[dev-env] creating Kubernetes cluster with kind" - export K8S_VERSION=${K8S_VERSION:-v1.29.2@sha256:51a1434a5397193442f0be2a297b488b6c919ce8a3931be0ce822606ea5ca245} + export K8S_VERSION=${K8S_VERSION:-v1.32.0@sha256:c48c62eac5da28cdadcf560d1d8616cfa6783b58f0d94cf63ad1bf49600cb027} kind create cluster \ --verbosity=${KIND_LOG_LEVEL} \ @@ -78,7 +78,7 @@ fi if [ "${SKIP_IMAGE_CREATION:-false}" = "false" ]; then if ! command -v ginkgo &> /dev/null; then - go install github.com/onsi/ginkgo/v2/ginkgo@v2.20.0 + go install github.com/onsi/ginkgo/v2/ginkgo@v2.22.2 fi echo "[dev-env] building image" make -C ${DIR}/../../ clean-image build image @@ -91,25 +91,28 @@ echo "[dev-env] copying docker images to cluster..." kind load docker-image --name="${KIND_CLUSTER_NAME}" --nodes=${KIND_WORKERS} ${REGISTRY}/controller:${TAG} if [ "${SKIP_CERT_MANAGER_CREATION:-false}" = "false" ]; then - curl -fsSL -o cmctl.tar.gz https://github.com/cert-manager/cert-manager/releases/download/v1.11.1/cmctl-linux-amd64.tar.gz - tar xzf cmctl.tar.gz - chmod +x cmctl - ./cmctl help - echo "[dev-env] apply cert-manager ..." - kubectl apply --wait -f https://github.com/cert-manager/cert-manager/releases/download/v1.11.0/cert-manager.yaml - kubectl wait --timeout=30s --for=condition=available deployment/cert-manager -n cert-manager - kubectl get validatingwebhookconfigurations cert-manager-webhook -ojson | jq '.webhooks[].clientConfig' - kubectl get endpoints -n cert-manager cert-manager-webhook - ./cmctl check api --wait=2m + echo "[dev-env] deploying cert-manager..." + + # Get OS & platform for downloading cmctl. + os="$(uname -o | tr "[:upper:]" "[:lower:]" | sed "s/gnu\///")" + platform="$(uname -m | sed "s/aarch64/arm64/;s/x86_64/amd64/")" + + # Download cmctl. Cannot validate checksum as OS & platform may vary. + curl --fail --location "https://github.com/cert-manager/cmctl/releases/download/v2.1.1/cmctl_${os}_${platform}.tar.gz" | tar --extract --gzip cmctl + + # Install cert-manager. + ./cmctl x install + ./cmctl check api --wait 1m fi echo "[dev-env] running helm chart e2e tests..." -docker run --rm --interactive --network host \ - --name ct \ - --volume $KUBECONFIG:/root/.kube/config \ - --volume "${DIR}/../../":/workdir \ - --workdir /workdir \ - registry.k8s.io/ingress-nginx/e2e-test-runner:v20240812-3f0129aa@sha256:95c2aaf2a66e8cbbf7a7453046f3b024383c273a0988efab841cd96116afd1a9 \ - ct install \ - --charts charts/ingress-nginx \ - --helm-extra-args "--timeout 60s" +docker run \ + --name ct \ + --volume "${KUBECONFIG}:/root/.kube/config:ro" \ + --volume "${DIR}/../../:/workdir" \ + --network host \ + --workdir /workdir \ + --entrypoint ct \ + --rm \ + registry.k8s.io/ingress-nginx/e2e-test-runner:v20250112-a188f4eb@sha256:043038b1e30e5a0b64f3f919f096c5c9488ac3f617ac094b07fb9db8215f9441 \ + install --charts charts/ingress-nginx diff --git a/test/e2e/run-e2e-suite.sh b/test/e2e/run-e2e-suite.sh index 9333ee61f..909368e96 100755 --- a/test/e2e/run-e2e-suite.sh +++ b/test/e2e/run-e2e-suite.sh @@ -78,7 +78,6 @@ kubectl run --rm \ --env="E2E_NODES=${E2E_NODES}" \ --env="FOCUS=${FOCUS}" \ --env="IS_CHROOT=${IS_CHROOT:-false}"\ - --env="ENABLE_VALIDATIONS=${ENABLE_VALIDATIONS:-false}"\ --env="SKIP_OPENTELEMETRY_TESTS=${SKIP_OPENTELEMETRY_TESTS:-false}"\ --env="E2E_CHECK_LEAKS=${E2E_CHECK_LEAKS}" \ --env="NGINX_BASE_IMAGE=${NGINX_BASE_IMAGE}" \ diff --git a/test/e2e/run-kind-e2e.sh b/test/e2e/run-kind-e2e.sh index ab2cb2dd7..e41d31afd 100755 --- a/test/e2e/run-kind-e2e.sh +++ b/test/e2e/run-kind-e2e.sh @@ -39,7 +39,6 @@ fi KIND_LOG_LEVEL="1" IS_CHROOT="${IS_CHROOT:-false}" -ENABLE_VALIDATIONS="${ENABLE_VALIDATIONS:-false}" export KIND_CLUSTER_NAME=${KIND_CLUSTER_NAME:-ingress-nginx-dev} DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" # Use 1.0.0-dev to make sure we use the latest configuration in the helm template @@ -64,7 +63,7 @@ echo "Running e2e with nginx base image ${NGINX_BASE_IMAGE}" if [ "${SKIP_CLUSTER_CREATION}" = "false" ]; then echo "[dev-env] creating Kubernetes cluster with kind" - export K8S_VERSION=${K8S_VERSION:-v1.29.2@sha256:51a1434a5397193442f0be2a297b488b6c919ce8a3931be0ce822606ea5ca245} + export K8S_VERSION=${K8S_VERSION:-v1.32.0@sha256:c48c62eac5da28cdadcf560d1d8616cfa6783b58f0d94cf63ad1bf49600cb027} # delete the cluster if it exists if kind get clusters | grep "${KIND_CLUSTER_NAME}"; then @@ -96,7 +95,7 @@ fi if [ "${SKIP_E2E_IMAGE_CREATION}" = "false" ]; then if ! command -v ginkgo &> /dev/null; then - go install github.com/onsi/ginkgo/v2/ginkgo@v2.20.0 + go install github.com/onsi/ginkgo/v2/ginkgo@v2.22.2 fi echo "[dev-env] .. done building controller images" diff --git a/test/e2e/settings/badannotationvalues.go b/test/e2e/settings/badannotationvalues.go index f61b5bada..aa9906909 100644 --- a/test/e2e/settings/badannotationvalues.go +++ b/test/e2e/settings/badannotationvalues.go @@ -34,14 +34,8 @@ var _ = framework.DescribeAnnotation("Bad annotation values", func() { }) ginkgo.It("[BAD_ANNOTATIONS] should drop an ingress if there is an invalid character in some annotation", func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "true", - }) - defer func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "false", - }) - }() + disableSnippet := f.AllowSnippetConfiguration() + defer disableSnippet() host := "invalid-value-test" annotations := map[string]string{ @@ -50,7 +44,6 @@ var _ = framework.DescribeAnnotation("Bad annotation values", func() { } ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations) - f.UpdateNginxConfigMapData("allow-snippet-annotations", "true") f.UpdateNginxConfigMapData("annotation-value-word-blocklist", "something_forbidden,otherthing_forbidden,{") f.EnsureIngress(ing) @@ -73,14 +66,8 @@ var _ = framework.DescribeAnnotation("Bad annotation values", func() { }) ginkgo.It("[BAD_ANNOTATIONS] should drop an ingress if there is a forbidden word in some annotation", func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "true", - }) - defer func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "false", - }) - }() + disableSnippet := f.AllowSnippetConfiguration() + defer disableSnippet() host := "forbidden-value-test" @@ -93,7 +80,6 @@ var _ = framework.DescribeAnnotation("Bad annotation values", func() { } ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations) - f.UpdateNginxConfigMapData("allow-snippet-annotations", "true") f.UpdateNginxConfigMapData("annotation-value-word-blocklist", "something_forbidden,otherthing_forbidden,content_by_lua_block") // Sleep a while just to guarantee that the configmap is applied framework.Sleep() @@ -117,14 +103,9 @@ var _ = framework.DescribeAnnotation("Bad annotation values", func() { }) ginkgo.It("[BAD_ANNOTATIONS] should allow an ingress if there is a default blocklist config in place", func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "true", - }) - defer func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "false", - }) - }() + disableSnippet := f.AllowSnippetConfiguration() + defer disableSnippet() + hostValid := "custom-allowed-value-test" annotationsValid := map[string]string{ "nginx.ingress.kubernetes.io/configuration-snippet": ` @@ -155,14 +136,8 @@ var _ = framework.DescribeAnnotation("Bad annotation values", func() { }) ginkgo.It("[BAD_ANNOTATIONS] should drop an ingress if there is a custom blocklist config in place and allow others to pass", func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "true", - }) - defer func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "false", - }) - }() + disableSnippet := f.AllowSnippetConfiguration() + defer disableSnippet() host := "custom-forbidden-value-test" annotations := map[string]string{ diff --git a/test/e2e/settings/geoip2.go b/test/e2e/settings/geoip2.go index 7da26d810..9c6d59dc5 100644 --- a/test/e2e/settings/geoip2.go +++ b/test/e2e/settings/geoip2.go @@ -69,15 +69,9 @@ var _ = framework.DescribeSetting("Geoip2", func() { ginkgo.It("should only allow requests from specific countries", func() { ginkgo.Skip("GeoIP test are temporarily disabled") - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "true", - "use-geoip2": "true", - }) - defer func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "false", - }) - }() + disableSnippet := f.AllowSnippetConfiguration() + defer disableSnippet() + f.UpdateNginxConfigMapData("use-geoip2", "true") httpSnippetAllowingOnlyAustralia := `map $geoip2_city_country_code $blocked_country { default 1; @@ -124,4 +118,52 @@ var _ = framework.DescribeSetting("Geoip2", func() { Expect(). Status(http.StatusOK) }) + + ginkgo.It("should up and running nginx controller using autoreload flag", func() { + edition := "GeoLite2-Country" + + err := f.UpdateIngressControllerDeployment(func(deployment *appsv1.Deployment) error { + args := deployment.Spec.Template.Spec.Containers[0].Args + args = append(args, "--maxmind-edition-ids="+edition) + deployment.Spec.Template.Spec.Containers[0].Args = args + _, err := f.KubeClientSet.AppsV1().Deployments(f.Namespace).Update(context.TODO(), deployment, metav1.UpdateOptions{}) + return err + }) + assert.Nil(ginkgo.GinkgoT(), err, "updating ingress controller deployment flags") + + filename := fmt.Sprintf("/etc/ingress-controller/geoip/%s.mmdb", edition) + exec, err := f.ExecIngressPod(fmt.Sprintf(`sh -c "mkdir -p '%s' && wget -O '%s' '%s' 2>&1"`, filepath.Dir(filename), filename, testdataURL)) + framework.Logf(exec) + assert.Nil(ginkgo.GinkgoT(), err, fmt.Sprintln("error downloading test geoip2 db", filename)) + + f.SetNginxConfigMapData(map[string]string{ + "use-geoip2": "true", + "geoip2-autoreload-in-minutes": "5", + }) + + // Check Configmap Autoreload Patterns + f.WaitForNginxConfiguration( + func(cfg string) bool { + return strings.Contains(cfg, fmt.Sprintf("geoip2 %s", filename)) && + strings.Contains(cfg, "auto_reload 5m;") + }, + ) + + // Check if Nginx could up, running and routing with auto_reload configs + host := "ping.com" + ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, nil) + f.EnsureIngress(ing) + + f.WaitForNginxServer(host, + func(server string) bool { + return strings.Contains(server, host) && + strings.Contains(server, "location /") + }) + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", host). + Expect(). + Status(http.StatusOK) + }) }) diff --git a/test/e2e/settings/global_external_auth.go b/test/e2e/settings/global_external_auth.go index 741e6f955..f589a63e9 100644 --- a/test/e2e/settings/global_external_auth.go +++ b/test/e2e/settings/global_external_auth.go @@ -32,8 +32,8 @@ import ( ) const ( - disable = "false" - noAuthLocaltionSetting = "no-auth-locations" + disable = "false" + noAuthLocationSetting = "no-auth-locations" ) var _ = framework.DescribeSetting("[Security] global-auth-url", func() { @@ -51,7 +51,7 @@ var _ = framework.DescribeSetting("[Security] global-auth-url", func() { fooPath := "/foo" barPath := "/bar" - noAuthSetting := noAuthLocaltionSetting + noAuthSetting := noAuthLocationSetting noAuthLocations := barPath enableGlobalExternalAuthAnnotation := "nginx.ingress.kubernetes.io/enable-global-auth" diff --git a/test/e2e/settings/globalratelimit.go b/test/e2e/settings/globalratelimit.go deleted file mode 100644 index e266350ad..000000000 --- a/test/e2e/settings/globalratelimit.go +++ /dev/null @@ -1,96 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package settings - -import ( - "fmt" - "net/http" - "strconv" - "strings" - - "github.com/onsi/ginkgo/v2" - "github.com/stretchr/testify/assert" - "k8s.io/ingress-nginx/test/e2e/framework" -) - -var _ = framework.DescribeSetting("settings-global-rate-limit", func() { - f := framework.NewDefaultFramework("global-rate-limit") - host := "global-rate-limit" - - ginkgo.BeforeEach(func() { - f.NewEchoDeployment() - }) - - ginkgo.It("generates correct NGINX configuration", func() { - annotations := make(map[string]string) - ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations) - f.EnsureIngress(ing) - - ginkgo.By("generating correct defaults") - - ngxCfg := "" - f.WaitForNginxConfiguration(func(cfg string) bool { - if strings.Contains(cfg, "global_throttle") { - ngxCfg = cfg - return true - } - return false - }) - - assert.Contains(ginkgo.GinkgoT(), ngxCfg, fmt.Sprintf(`global_throttle = { `+ - `memcached = { host = "%v", port = %d, connect_timeout = %d, max_idle_timeout = %d, `+ - `pool_size = %d, }, status_code = %d, }`, - "", 11211, 50, 10000, 50, 429)) - - f.HTTPTestClient().GET("/").WithHeader("Host", host).Expect().Status(http.StatusOK) - - ginkgo.By("applying customizations") - - memcachedHost := "memc.default.svc.cluster.local" - memcachedPort := 11211 - memcachedConnectTimeout := 100 - memcachedMaxIdleTimeout := 5000 - memcachedPoolSize := 100 - statusCode := 503 - - f.SetNginxConfigMapData(map[string]string{ - "global-rate-limit-memcached-host": memcachedHost, - "global-rate-limit-memcached-port": strconv.Itoa(memcachedPort), - "global-rate-limit-memcached-connect-timeout": strconv.Itoa(memcachedConnectTimeout), - "global-rate-limit-memcached-max-idle-timeout": strconv.Itoa(memcachedMaxIdleTimeout), - "global-rate-limit-memcached-pool-size": strconv.Itoa(memcachedPoolSize), - "global-rate-limit-status-code": strconv.Itoa(statusCode), - }) - - ngxCfg = "" - f.WaitForNginxConfiguration(func(cfg string) bool { - if strings.Contains(cfg, "global_throttle") { - ngxCfg = cfg - return true - } - return false - }) - - assert.Contains(ginkgo.GinkgoT(), ngxCfg, fmt.Sprintf(`global_throttle = { `+ - `memcached = { host = "%v", port = %d, connect_timeout = %d, max_idle_timeout = %d, `+ - `pool_size = %d, }, status_code = %d, }`, - memcachedHost, memcachedPort, memcachedConnectTimeout, memcachedMaxIdleTimeout, - memcachedPoolSize, statusCode)) - - f.HTTPTestClient().GET("/").WithHeader("Host", host).Expect().Status(http.StatusOK) - }) -}) diff --git a/test/e2e/settings/grpc.go b/test/e2e/settings/grpc.go new file mode 100644 index 000000000..ae3175034 --- /dev/null +++ b/test/e2e/settings/grpc.go @@ -0,0 +1,110 @@ +/* +Copyright 2024 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package settings + +import ( + "context" + "crypto/tls" + "fmt" + "strings" + + pb "github.com/moul/pb/grpcbin/go-grpc" + "github.com/onsi/ginkgo/v2" + "github.com/stretchr/testify/assert" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" + + "k8s.io/ingress-nginx/test/e2e/framework" +) + +const echoHost = "echo" + +var _ = framework.DescribeSetting("GRPC", func() { + f := framework.NewDefaultFramework("grpc-buffersize", framework.WithHTTPBunEnabled()) + + ginkgo.It("should set the correct GRPC Buffer Size", func() { + f.SetNginxConfigMapData(map[string]string{ + "grpc-buffer-size-kb": "8", + }) + + f.WaitForNginxConfiguration( + func(cfg string) bool { + return strings.Contains(cfg, "grpc_buffer_size 8k") + }) + + f.NewGRPCBinDeployment() + + host := echoHost + + svc := &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: "grpcbin-test", + Namespace: f.Namespace, + }, + Spec: corev1.ServiceSpec{ + ExternalName: fmt.Sprintf("grpcbin.%v.svc.cluster.local", f.Namespace), + Type: corev1.ServiceTypeExternalName, + Ports: []corev1.ServicePort{ + { + Name: host, + Port: 9000, + TargetPort: intstr.FromInt(9000), + Protocol: "TCP", + }, + }, + }, + } + f.EnsureService(svc) + + annotations := map[string]string{ + "nginx.ingress.kubernetes.io/backend-protocol": "GRPC", + } + + ing := framework.NewSingleIngressWithTLS(host, "/", host, []string{host}, f.Namespace, "grpcbin-test", 9000, annotations) + + f.EnsureIngress(ing) + + f.WaitForNginxServer(host, + func(server string) bool { + return strings.Contains(server, "grpc_pass grpc://upstream_balancer;") + }) + + conn, err := grpc.NewClient(f.GetNginxIP()+":443", + grpc.WithTransportCredentials( + credentials.NewTLS(&tls.Config{ + ServerName: echoHost, + InsecureSkipVerify: true, //nolint:gosec // Ignore certificate validation in testing + }), + ), + ) + assert.Nil(ginkgo.GinkgoT(), err, "error creating a connection") + defer conn.Close() + + client := pb.NewGRPCBinClient(conn) + ctx := context.Background() + + res, err := client.HeadersUnary(ctx, &pb.EmptyMessage{}) + assert.Nil(ginkgo.GinkgoT(), err) + + metadata := res.GetMetadata() + assert.Equal(ginkgo.GinkgoT(), metadata["content-type"].Values[0], "application/grpc") + assert.Equal(ginkgo.GinkgoT(), metadata[":authority"].Values[0], host) + }) +}) diff --git a/test/e2e/settings/no_tls_redirect_locations.go b/test/e2e/settings/no_tls_redirect_locations.go index 8339eb23e..18fd09e26 100644 --- a/test/e2e/settings/no_tls_redirect_locations.go +++ b/test/e2e/settings/no_tls_redirect_locations.go @@ -33,7 +33,7 @@ var _ = framework.DescribeSetting("Add no tls redirect locations", func() { f.EnsureIngress(ing) f.WaitForNginxConfiguration(func(server string) bool { - return !strings.Contains(server, "force_no_ssl_redirect = true,") + return strings.Contains(server, "set $force_no_ssl_redirect \"false\"") }) wlKey := "no-tls-redirect-locations" @@ -42,7 +42,7 @@ var _ = framework.DescribeSetting("Add no tls redirect locations", func() { f.UpdateNginxConfigMapData(wlKey, wlValue) f.WaitForNginxConfiguration(func(server string) bool { - return strings.Contains(server, "force_no_ssl_redirect = true,") + return strings.Contains(server, "set $force_no_ssl_redirect \"true\"") }) }) }) diff --git a/test/e2e/settings/ocsp/ocsp.go b/test/e2e/settings/ocsp/ocsp.go index ef3bfb58a..b2d50292a 100644 --- a/test/e2e/settings/ocsp/ocsp.go +++ b/test/e2e/settings/ocsp/ocsp.go @@ -34,6 +34,7 @@ import ( appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/ingress-nginx/test/e2e/framework" @@ -107,8 +108,9 @@ var _ = framework.DescribeSetting("OCSP", func() { err = framework.WaitForEndpoints(f.KubeClientSet, framework.DefaultTimeout, "ocspserve", f.Namespace, 1) assert.Nil(ginkgo.GinkgoT(), err, "waiting for endpoints to become ready") - f.WaitForNginxConfiguration(func(cfg string) bool { - return strings.Contains(cfg, "certificate.is_ocsp_stapling_enabled = true") + f.WaitForLuaConfiguration(func(jsonCfg map[string]interface{}) bool { + val, ok, err := unstructured.NestedBool(jsonCfg, "enable_ocsp") + return err == nil && ok && val }) f.WaitForNginxServer(host, @@ -295,7 +297,7 @@ func ocspserveDeployment(namespace string) (*appsv1.Deployment, *corev1.Service) Containers: []corev1.Container{ { Name: name, - Image: "registry.k8s.io/ingress-nginx/cfssl:v1.0.0@sha256:fffd36e2f1c8fd485ec6fd24c6d55f0817b54352274293d2a247b8a0d924c5b0", + Image: "registry.k8s.io/ingress-nginx/cfssl:v1.1.1@sha256:bcd576c6d0a01d4710969195e804c02da62b71b5c35c6816df9b7584d5445437", Command: []string{ "/bin/bash", "-c", diff --git a/test/e2e/settings/plugins.go b/test/e2e/settings/plugins.go deleted file mode 100644 index 659acd42c..000000000 --- a/test/e2e/settings/plugins.go +++ /dev/null @@ -1,55 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package settings - -import ( - "fmt" - "net/http" - "strings" - - "github.com/onsi/ginkgo/v2" - "k8s.io/ingress-nginx/test/e2e/framework" -) - -var _ = framework.IngressNginxDescribe("plugins", func() { - f := framework.NewDefaultFramework("plugins") - - ginkgo.BeforeEach(func() { - f.NewEchoDeployment() - }) - - ginkgo.It("should exist a x-hello-world header", func() { - f.UpdateNginxConfigMapData("plugins", "hello_world, invalid") - - host := "example.com" - f.EnsureIngress(framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, nil)) - - f.WaitForNginxConfiguration( - func(server string) bool { - return strings.Contains(server, fmt.Sprintf("server_name %v", host)) && - strings.Contains(server, `plugins.init({ "hello_world","invalid" })`) - }) - - f.HTTPTestClient(). - GET("/"). - WithHeader("Host", host). - WithHeader("User-Agent", "hello"). - Expect(). - Status(http.StatusOK). - Body().Contains("x-hello-world=1") - }) -}) diff --git a/test/e2e/settings/proxy_host.go b/test/e2e/settings/proxy_host.go index 35aafc53d..bb5dc9c01 100644 --- a/test/e2e/settings/proxy_host.go +++ b/test/e2e/settings/proxy_host.go @@ -34,14 +34,9 @@ var _ = framework.IngressNginxDescribe("Dynamic $proxy_host", func() { }) ginkgo.It("should exist a proxy_host", func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "true", - }) - defer func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "false", - }) - }() + disableSnippet := f.AllowSnippetConfiguration() + defer disableSnippet() + upstreamName := fmt.Sprintf("%v-%v-80", f.Namespace, framework.EchoService) annotations := map[string]string{ "nginx.ingress.kubernetes.io/configuration-snippet": `more_set_headers "Custom-Header: $proxy_host"`, @@ -63,14 +58,8 @@ var _ = framework.IngressNginxDescribe("Dynamic $proxy_host", func() { }) ginkgo.It("should exist a proxy_host using the upstream-vhost annotation value", func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "true", - }) - defer func() { - f.SetNginxConfigMapData(map[string]string{ - "allow-snippet-annotations": "false", - }) - }() + disableSnippet := f.AllowSnippetConfiguration() + defer disableSnippet() upstreamName := fmt.Sprintf("%v-%v-80", f.Namespace, framework.EchoService) upstreamVHost := "different.host" diff --git a/test/e2e/settings/server_snippet.go b/test/e2e/settings/server_snippet.go index 8ddf10fd9..1e2084bd8 100644 --- a/test/e2e/settings/server_snippet.go +++ b/test/e2e/settings/server_snippet.go @@ -38,6 +38,7 @@ var _ = framework.DescribeSetting("configmap server-snippet", func() { f.SetNginxConfigMapData(map[string]string{ "allow-snippet-annotations": "true", + "annotations-risk-level": "Critical", "server-snippet": ` more_set_headers "Globalfoo: Foooo";`, }) @@ -45,6 +46,7 @@ var _ = framework.DescribeSetting("configmap server-snippet", func() { defer func() { f.SetNginxConfigMapData(map[string]string{ "allow-snippet-annotations": "false", + "annotations-risk-level": "High", }) }() annotations := map[string]string{ @@ -101,6 +103,7 @@ var _ = framework.DescribeSetting("configmap server-snippet", func() { f.SetNginxConfigMapData(map[string]string{ "allow-snippet-annotations": "false", + "annotations-risk-level": "Critical", // To allow Configuration Snippet "server-snippet": ` more_set_headers "Globalfoo: Foooo";`, }) @@ -108,6 +111,7 @@ var _ = framework.DescribeSetting("configmap server-snippet", func() { defer func() { f.SetNginxConfigMapData(map[string]string{ "allow-snippet-annotations": "false", + "annotations-risk-level": "High", }) }() annotations := map[string]string{ diff --git a/test/e2e/settings/tls.go b/test/e2e/settings/tls.go index 51f760df8..1ebf358c1 100644 --- a/test/e2e/settings/tls.go +++ b/test/e2e/settings/tls.go @@ -25,10 +25,11 @@ import ( "github.com/onsi/ginkgo/v2" "github.com/stretchr/testify/assert" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/ingress-nginx/test/e2e/framework" ) -var _ = framework.DescribeSetting("[SSL] TLS protocols, ciphers and headers)", func() { +var _ = framework.DescribeSetting("[SSL] TLS protocols, ciphers and headers", func() { f := framework.NewDefaultFramework("settings-tls") host := "settings-tls" @@ -109,8 +110,9 @@ var _ = framework.DescribeSetting("[SSL] TLS protocols, ciphers and headers)", f ginkgo.It("setting max-age parameter", func() { f.UpdateNginxConfigMapData(hstsMaxAge, "86400") - f.WaitForNginxConfiguration(func(server string) bool { - return strings.Contains(server, `hsts_max_age = 86400,`) + f.WaitForLuaConfiguration(func(jsonCfg map[string]interface{}) bool { + val, ok, err := unstructured.NestedString(jsonCfg, "hsts_max_age") + return err == nil && ok && val == "86400" }) f.HTTPTestClientWithTLSConfig(tlsConfig). @@ -128,8 +130,9 @@ var _ = framework.DescribeSetting("[SSL] TLS protocols, ciphers and headers)", f hstsIncludeSubdomains: "false", }) - f.WaitForNginxConfiguration(func(server string) bool { - return strings.Contains(server, `hsts_include_subdomains = false,`) + f.WaitForLuaConfiguration(func(jsonCfg map[string]interface{}) bool { + val, ok, err := unstructured.NestedBool(jsonCfg, "hsts_include_subdomains") + return err == nil && ok && !val }) f.HTTPTestClientWithTLSConfig(tlsConfig). @@ -148,8 +151,9 @@ var _ = framework.DescribeSetting("[SSL] TLS protocols, ciphers and headers)", f hstsIncludeSubdomains: "false", }) - f.WaitForNginxConfiguration(func(server string) bool { - return strings.Contains(server, `hsts_preload = true,`) + f.WaitForLuaConfiguration(func(jsonCfg map[string]interface{}) bool { + val, ok, err := unstructured.NestedBool(jsonCfg, "hsts_preload") + return err == nil && ok && val }) f.HTTPTestClientWithTLSConfig(tlsConfig). diff --git a/test/e2e/settings/validations/validations.go b/test/e2e/settings/validations/validations.go index ac95a453a..881de39b4 100644 --- a/test/e2e/settings/validations/validations.go +++ b/test/e2e/settings/validations/validations.go @@ -48,8 +48,8 @@ var _ = framework.IngressNginxDescribeSerial("annotation validations", func() { framework.Sleep() annotations := map[string]string{ - "nginx.ingress.kubernetes.io/default-backend": "default/bla", // low risk - "nginx.ingress.kubernetes.io/denylist-source-range": "1.1.1.1/32", // medium risk + "nginx.ingress.kubernetes.io/default-backend": "bla", // low risk + "nginx.ingress.kubernetes.io/denylist-source-range": "1.1.1.1/32", // medium risk } ginkgo.By("allow ingress with low/medium risk annotations") @@ -82,8 +82,8 @@ var _ = framework.IngressNginxDescribeSerial("annotation validations", func() { framework.Sleep() annotations := map[string]string{ - "nginx.ingress.kubernetes.io/default-backend": "default/bla", // low risk - "nginx.ingress.kubernetes.io/denylist-source-range": "1.1.1.1/32", // medium risk + "nginx.ingress.kubernetes.io/default-backend": "bla", // low risk + "nginx.ingress.kubernetes.io/denylist-source-range": "1.1.1.1/32", // medium risk } ginkgo.By("allow ingress with low/medium risk annotations") diff --git a/test/e2e/wait-for-nginx.sh b/test/e2e/wait-for-nginx.sh index ac0584962..73023aba1 100755 --- a/test/e2e/wait-for-nginx.sh +++ b/test/e2e/wait-for-nginx.sh @@ -24,7 +24,6 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" export NAMESPACE=$1 export NAMESPACE_OVERLAY=$2 export IS_CHROOT=$3 -export ENABLE_VALIDATIONS=$4 echo "deploying NGINX Ingress controller in namespace $NAMESPACE" @@ -59,7 +58,6 @@ else # TODO: remove the need to use fullnameOverride fullnameOverride: nginx-ingress controller: - enableAnnotationValidations: ${ENABLE_VALIDATIONS} image: repository: ingress-controller/controller chroot: ${IS_CHROOT} diff --git a/test/k6/loadtest.js b/test/k6/loadtest.js index 2396948fc..51801765e 100644 --- a/test/k6/loadtest.js +++ b/test/k6/loadtest.js @@ -1,6 +1,6 @@ // This is a loadtest under development // Test here is spec'd to have 100virtual-users -// Other specs currently similar to smoktest +// Other specs currently similar to smoketest // But loadtest needs testplan that likely uses auth & data-transfer import http from 'k6/http'; @@ -35,7 +35,7 @@ export default function () { const req3 = { params: { headers: { - 'Content-Type': 'application/x-www-form-urlencoded' + 'Content-Type': 'application/x-www-form-urlencoded' }, }, method: 'POST', diff --git a/test/k6/smoketest.js b/test/k6/smoketest.js index 8fe9e950a..12691b63a 100644 --- a/test/k6/smoketest.js +++ b/test/k6/smoketest.js @@ -1,4 +1,4 @@ -// smotest.js edited after copy/pasting from https://k6.io docs +// smoketest.js edited after copy/pasting from https://k6.io docs // Using this like loadtest because of limited cpu/memory/other import http from 'k6/http'; @@ -22,7 +22,7 @@ export const options = { }; export default function () { - // docs of k6 say this is how to adds host header + // docs of k6 say this is how to add host header // needed as ingress is created with this host value const params = { headers: {'host': 'test.ingress-nginx-controller.ga'}, @@ -39,7 +39,7 @@ export default function () { const req3 = { params: { headers: { - 'Content-Type': 'application/json' + 'Content-Type': 'application/json' }, }, method: 'POST', diff --git a/test/manifests/configuration-a.json b/test/manifests/configuration-a.json index ba513c616..f9599d77c 100644 --- a/test/manifests/configuration-a.json +++ b/test/manifests/configuration-a.json @@ -302,7 +302,12 @@ "validationDepth": 0 }, "use-port-in-redirects": false, - "configuration-snippet": "" + "configuration-snippet": "", + "customHeaders": { + "headers": { + "Server": "HAL9000" + } + } }] }, { "hostname": "dev.mycompany.com", diff --git a/test/manifests/configuration-b.json b/test/manifests/configuration-b.json index 9e40785b4..d2e71bb29 100644 --- a/test/manifests/configuration-b.json +++ b/test/manifests/configuration-b.json @@ -302,7 +302,12 @@ "validationDepth": 0 }, "use-port-in-redirects": false, - "configuration-snippet": "" + "configuration-snippet": "", + "customHeaders": { + "headers": { + "Server": "HAL9000" + } + } }] }, { "hostname": "dev.mycompany.com", diff --git a/test/test-lua.sh b/test/test-lua.sh index fc60023f8..e7ee5843e 100755 --- a/test/test-lua.sh +++ b/test/test-lua.sh @@ -36,12 +36,11 @@ SHDICT_ARGS=( "--shdict" "high_throughput_tracker 1M" "--shdict" "balancer_ewma_last_touched_at 1M" "--shdict" "balancer_ewma_locks 512k" - "--shdict" "global_throttle_cache 5M" "./rootfs/etc/nginx/lua/test/run.lua" ) if [ $# -eq 0 ]; then - resty "${SHDICT_ARGS[@]}" ./rootfs/etc/nginx/lua/test/ ./rootfs/etc/nginx/lua/plugins/**/test ${BUSTED_ARGS} + resty "${SHDICT_ARGS[@]}" ./rootfs/etc/nginx/lua/test/ ${BUSTED_ARGS} else resty "${SHDICT_ARGS[@]}" $@ ${BUSTED_ARGS} fi