Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package linkerd-cli-edge for
openSUSE:Factory checked in at 2026-10-30 18:16:08
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/linkerd-cli-edge (Old)
and /work/SRC/openSUSE:Factory/.linkerd-cli-edge.new.1255 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "linkerd-cli-edge"
Fri Oct 30 18:16:08 2026 rev:86 rq:1393826 version:26.10.2
Changes:
--------
--- /work/SRC/openSUSE:Factory/linkerd-cli-edge/linkerd-cli-edge.changes
2026-10-06 19:17:54.862272673 +0200
+++
/work/SRC/openSUSE:Factory/.linkerd-cli-edge.new.1255/linkerd-cli-edge.changes
2026-10-30 18:22:57.063019004 +0100
@@ -1,0 +2,19 @@
+Fri Oct 30 06:20:35 UTC 2026 - Johannes Kastl
<[email protected]>
+
+- Update to version 26.10.2:
+ * chore(deps): upgrade proxy-init to v2.4.11 and cni-plugin to
+ v1.7.1 (#15754)
+ * build(deps): bump postcss-selector-parser in /web/app (#15751)
+ * build(deps): bump fast-uri from 3.1.8 to 3.1.9 in /web/app
+ (#15750)
+ * build(deps): bump github.com/go-test/deep from 1.1.1 to 1.1.2
+ (#15729)
+ * chore: update dependencies. (#15748)
+ * chore: update go version. (#15749)
+ * build(deps): bump golang.org/x/tools from 0.50.0 to 0.52.0
+ (#15721)
+ * chore(build): update golang to 1.26.9 (#15737)
+ * docs: update contribution guideilnes to include LLM code policy
+ (#15709)
+
+-------------------------------------------------------------------
Old:
----
linkerd-cli-edge-26.10.1.obscpio
New:
----
linkerd-cli-edge-26.10.2.obscpio
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ linkerd-cli-edge.spec ++++++
--- /var/tmp/diff_new_pack.h8TWxD/_old 2026-10-30 18:22:58.551081298 +0100
+++ /var/tmp/diff_new_pack.h8TWxD/_new 2026-10-30 18:22:58.553081381 +0100
@@ -19,7 +19,7 @@
%define linkerd_executable_name linkerd
Name: linkerd-cli-edge
-Version: 26.10.1
+Version: 26.10.2
Release: 0
Summary: CLI for the linkerd service mesh for Kubernetes
License: Apache-2.0
@@ -28,7 +28,7 @@
Source1: vendor.tar.gz
BuildRequires: bash-completion
BuildRequires: fish
-BuildRequires: go1.26 >= 1.26.7
+BuildRequires: go1.26 >= 1.26.10
BuildRequires: zsh
# cannot be installed in parallel to the stable version
++++++ _service ++++++
--- /var/tmp/diff_new_pack.h8TWxD/_old 2026-10-30 18:22:58.619084144 +0100
+++ /var/tmp/diff_new_pack.h8TWxD/_new 2026-10-30 18:22:58.625084396 +0100
@@ -3,7 +3,7 @@
<param name="url">https://github.com/linkerd/linkerd2</param>
<param name="scm">git</param>
<param name="exclude">.git</param>
- <param name="revision">edge-26.10.1</param>
+ <param name="revision">edge-26.10.2</param>
<param name="match-tag">edge-*.*.*</param>
<param name="versionformat">@PARENT_TAG@</param>
<param name="versionrewrite-pattern">edge-(.*)</param>
++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.h8TWxD/_old 2026-10-30 18:22:58.666086112 +0100
+++ /var/tmp/diff_new_pack.h8TWxD/_new 2026-10-30 18:22:58.671086321 +0100
@@ -1,6 +1,6 @@
<servicedata>
<service name="tar_scm">
<param name="url">https://github.com/linkerd/linkerd2</param>
- <param
name="changesrevision">f6415cf0f2a6e9e04aab969083907bde4be0ea20</param></service></servicedata>
+ <param
name="changesrevision">a4c00ac553f0f2ff84558dd7a35ed24dcd6cc6eb</param></service></servicedata>
(No newline at EOF)
++++++ linkerd-cli-edge-26.10.1.obscpio -> linkerd-cli-edge-26.10.2.obscpio
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/linkerd-cli-edge-26.10.1/.proxy-version
new/linkerd-cli-edge-26.10.2/.proxy-version
--- old/linkerd-cli-edge-26.10.1/.proxy-version 2026-10-05 18:50:45.000000000
+0200
+++ new/linkerd-cli-edge-26.10.2/.proxy-version 2026-10-29 16:54:14.000000000
+0100
@@ -1 +1 @@
-v2.370.0
+v2.372.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/linkerd-cli-edge-26.10.1/CONTRIBUTING.md
new/linkerd-cli-edge-26.10.2/CONTRIBUTING.md
--- old/linkerd-cli-edge-26.10.1/CONTRIBUTING.md 2026-10-05
18:50:45.000000000 +0200
+++ new/linkerd-cli-edge-26.10.2/CONTRIBUTING.md 2026-10-29
16:54:14.000000000 +0100
@@ -135,6 +135,46 @@
reviewers to replicate your tests. Performance-related changes should include
before- and after- benchmark results.
+## Policy on Generative AI & LLM-Assisted Contributions ##
+
+### Ultimate Human Accountability ###
+
+The human author submitting a contribution remains entirely and solely
+accountable for its content, correctness, security, and runtime functionality.
+Utilizing an LLM or AI tool does not shift, diminish, or share accountability
+with the software tool, model provider, or AI platform.
+
+- Architectural & Logic Mastery: The human contributor must thoroughly
+understand and be able to explain the entirety of their submission.
+- Maintainer review focuses entirely on the safety, logic, and quality of the
+contribution, regardless of whether generative AI or LLMs were used to create
+it.
+- Tool-assisted submissions must still adhere to all contribution guidelines
+set above in this document.
+
+### Attribution and Co-Author Guidelines ###
+
+Attributing AI tools, models, or assistant platforms (for example, via
+`Co-authored-by:` commit message trailers or pull request descriptions) is
+**optional**.
+
+- **Optional Tool Attribution:** Contributors who wish to acknowledge AI tool
+usage may optionally include a commit trailer or PR footnote.
+- **No Legal Co-Authorship:** AI tools and LLMs cannot be designated as legal
+copyright holders or primary authors, as accountability rests exclusively with
+the human contributor.
+
+### Maintainer Authority and Enforcement ###
+
+Linkerd maintainers reserve the right to:
+
+- Reject or close pull requests or issues that exhibit evidence of hallucinated
+content or lack of human oversight.
+- Require additional explanation, architectural rationale, or smaller
+surface-area iteration for complex AI-assisted contributions.
+- Block or restrict contributors who repeatedly submit unvalidated AI-generated
+pull requests.
+
[discourse]: https://discourse.linkerd.io/c/linkerd2
[issue]: https://github.com/linkerd/linkerd2/issues/new
[slack]: http://slack.linkerd.io/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/linkerd-cli-edge-26.10.1/Cargo.lock
new/linkerd-cli-edge-26.10.2/Cargo.lock
--- old/linkerd-cli-edge-26.10.1/Cargo.lock 2026-10-05 18:50:45.000000000
+0200
+++ new/linkerd-cli-edge-26.10.2/Cargo.lock 2026-10-29 16:54:14.000000000
+0100
@@ -526,7 +526,7 @@
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
dependencies = [
"libc",
- "windows-sys 0.52.0",
+ "windows-sys 0.61.0",
]
[[package]]
@@ -754,9 +754,9 @@
[[package]]
name = "h2"
-version = "0.4.17"
+version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9f877e75f39e9827ec50a572dd592684ac28c029578726c85f1b2aa6ab807449"
+checksum = "ef8e5e5a340588f4452631496976cf8636d4a7ecf600239fdc27615d2530bc16"
dependencies = [
"atomic-waker",
"bytes",
@@ -1407,6 +1407,8 @@
"clap",
"drain",
"futures",
+ "h2",
+ "http",
"http-body-util",
"hyper",
"hyper-util",
@@ -2013,14 +2015,14 @@
"errno",
"libc",
"linux-raw-sys",
- "windows-sys 0.52.0",
+ "windows-sys 0.61.0",
]
[[package]]
name = "rustls"
-version = "0.23.45"
+version = "0.23.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d41d731c7d2f962d1ccc364cec258de3c0e93b38c2fb3ba97ac74513048d634"
+checksum = "48e13bd8c0e9365c43cfa5c9e8f9ad49d3c8444926c9aac819e0e4dc503c8fdf"
dependencies = [
"aws-lc-rs",
"log",
@@ -2055,9 +2057,9 @@
[[package]]
name = "rustls-webpki"
-version = "0.103.15"
+version = "0.103.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3c3cf1d8b1e7d4927e2d154c3fcb02979afb9939629c62cd9048d4f07b60ac2"
+checksum = "4443b1b6d39d7c663139942cc4558262562d2c84123bb6282ef177009ca8b281"
dependencies = [
"aws-lc-rs",
"ring",
@@ -2355,9 +2357,9 @@
[[package]]
name = "tokio"
-version = "1.53.1"
+version = "1.54.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed"
+checksum = "b52fd3255258d26fac7264ab5a76b53c13367136dc011d3d6ad4f8ed070396a3"
dependencies = [
"bytes",
"libc",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/linkerd-cli-edge-26.10.1/Dockerfile.controller
new/linkerd-cli-edge-26.10.2/Dockerfile.controller
--- old/linkerd-cli-edge-26.10.1/Dockerfile.controller 2026-10-05
18:50:45.000000000 +0200
+++ new/linkerd-cli-edge-26.10.2/Dockerfile.controller 2026-10-29
16:54:14.000000000 +0100
@@ -1,5 +1,5 @@
# Precompile key slow-to-build dependencies
-FROM --platform=$BUILDPLATFORM golang:1.26.7-alpine AS go-deps
+FROM --platform=$BUILDPLATFORM golang:1.26.10-alpine AS go-deps
WORKDIR /linkerd-build
COPY go.mod go.sum ./
COPY bin/install-deps bin/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/linkerd-cli-edge-26.10.1/Dockerfile.proxy
new/linkerd-cli-edge-26.10.2/Dockerfile.proxy
--- old/linkerd-cli-edge-26.10.1/Dockerfile.proxy 2026-10-05
18:50:45.000000000 +0200
+++ new/linkerd-cli-edge-26.10.2/Dockerfile.proxy 2026-10-29
16:54:14.000000000 +0100
@@ -3,7 +3,7 @@
ARG TARGETARCH
# Precompile key slow-to-build dependencies
-FROM --platform=$BUILDPLATFORM golang:1.26.7-alpine AS go-deps
+FROM --platform=$BUILDPLATFORM golang:1.26.10-alpine AS go-deps
WORKDIR /linkerd-build
COPY go.mod go.sum ./
COPY bin/install-deps bin/
@@ -45,10 +45,10 @@
RUN CGO_ENABLED=0 GOOS=linux GOARCH=$TARGETARCH go build -o
/out/proxy-identity -mod=readonly -ldflags "-s -w" ./proxy-identity
## build proxy-init
-FROM --platform=$BUILDPLATFORM golang:1.26.7-alpine AS proxy-init
+FROM --platform=$BUILDPLATFORM golang:1.26.10-alpine AS proxy-init
WORKDIR /build
ARG PROXY_INIT_REPO="linkerd/linkerd2-proxy-init"
-ARG PROXY_INIT_REF="proxy-init/v2.4.10"
+ARG PROXY_INIT_REF="proxy-init/v2.4.11"
RUN apk add --no-cache ca-certificates git
RUN --mount=type=secret,id=github \
export GITHUB_TOKEN_FILE=/run/secrets/github; \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/linkerd-cli-edge-26.10.1/charts/linkerd2-cni/values.yaml
new/linkerd-cli-edge-26.10.2/charts/linkerd2-cni/values.yaml
--- old/linkerd-cli-edge-26.10.1/charts/linkerd2-cni/values.yaml
2026-10-05 18:50:45.000000000 +0200
+++ new/linkerd-cli-edge-26.10.2/charts/linkerd2-cni/values.yaml
2026-10-29 16:54:14.000000000 +0100
@@ -69,7 +69,7 @@
# -- Docker image for the CNI plugin
name: "cr.l5d.io/linkerd/cni-plugin"
# -- Tag for the CNI container Docker image
- version: "v1.7.0"
+ version: "v1.7.1"
# -- Pull policy for the linkerd-cni container
pullPolicy: IfNotPresent
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/linkerd-cli-edge-26.10.1/cli/Dockerfile
new/linkerd-cli-edge-26.10.2/cli/Dockerfile
--- old/linkerd-cli-edge-26.10.1/cli/Dockerfile 2026-10-05 18:50:45.000000000
+0200
+++ new/linkerd-cli-edge-26.10.2/cli/Dockerfile 2026-10-29 16:54:14.000000000
+0100
@@ -1,7 +1,7 @@
ARG BUILDPLATFORM=linux/amd64
# Precompile key slow-to-build dependencies
-FROM --platform=$BUILDPLATFORM golang:1.26.7-alpine AS go-deps
+FROM --platform=$BUILDPLATFORM golang:1.26.10-alpine AS go-deps
WORKDIR /linkerd-build
COPY go.mod go.sum ./
RUN go mod download
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/linkerd-cli-edge-26.10.1/cli/cmd/testdata/install-cni-plugin_default.golden
new/linkerd-cli-edge-26.10.2/cli/cmd/testdata/install-cni-plugin_default.golden
---
old/linkerd-cli-edge-26.10.1/cli/cmd/testdata/install-cni-plugin_default.golden
2026-10-05 18:50:45.000000000 +0200
+++
new/linkerd-cli-edge-26.10.2/cli/cmd/testdata/install-cni-plugin_default.golden
2026-10-29 16:54:14.000000000 +0100
@@ -117,7 +117,7 @@
# script copies the files into place and then sleeps so
# that Kubernetes doesn't keep trying to restart it.
- name: install-cni
- image: cr.l5d.io/linkerd/cni-plugin:v1.7.0
+ image: cr.l5d.io/linkerd/cni-plugin:v1.7.1
imagePullPolicy:
env:
- name: DEST_CNI_NET_DIR
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/linkerd-cli-edge-26.10.1/cli/cmd/testdata/install-cni-plugin_skip_ports.golden
new/linkerd-cli-edge-26.10.2/cli/cmd/testdata/install-cni-plugin_skip_ports.golden
---
old/linkerd-cli-edge-26.10.1/cli/cmd/testdata/install-cni-plugin_skip_ports.golden
2026-10-05 18:50:45.000000000 +0200
+++
new/linkerd-cli-edge-26.10.2/cli/cmd/testdata/install-cni-plugin_skip_ports.golden
2026-10-29 16:54:14.000000000 +0100
@@ -118,7 +118,7 @@
# script copies the files into place and then sleeps so
# that Kubernetes doesn't keep trying to restart it.
- name: install-cni
- image: cr.l5d.io/linkerd/cni-plugin:v1.7.0
+ image: cr.l5d.io/linkerd/cni-plugin:v1.7.1
imagePullPolicy:
env:
- name: DEST_CNI_NET_DIR
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/linkerd-cli-edge-26.10.1/cli/cmd/testdata/install_cni_helm_default_output.golden
new/linkerd-cli-edge-26.10.2/cli/cmd/testdata/install_cni_helm_default_output.golden
---
old/linkerd-cli-edge-26.10.1/cli/cmd/testdata/install_cni_helm_default_output.golden
2026-10-05 18:50:45.000000000 +0200
+++
new/linkerd-cli-edge-26.10.2/cli/cmd/testdata/install_cni_helm_default_output.golden
2026-10-29 16:54:14.000000000 +0100
@@ -110,7 +110,7 @@
# script copies the files into place and then sleeps so
# that Kubernetes doesn't keep trying to restart it.
- name: install-cni
- image: cr.l5d.io/linkerd/cni-plugin:v1.7.0
+ image: cr.l5d.io/linkerd/cni-plugin:v1.7.1
imagePullPolicy: IfNotPresent
env:
- name: DEST_CNI_NET_DIR
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/linkerd-cli-edge-26.10.1/deny.toml
new/linkerd-cli-edge-26.10.2/deny.toml
--- old/linkerd-cli-edge-26.10.1/deny.toml 2026-10-05 18:50:45.000000000
+0200
+++ new/linkerd-cli-edge-26.10.2/deny.toml 2026-10-29 16:54:14.000000000
+0100
@@ -8,6 +8,8 @@
db-path = "~/.cargo/advisory-db"
db-urls = ["https://github.com/rustsec/advisory-db"]
ignore = [
+ # unsafe-libyaml is unmaintained, but pulled in via kube and gateway-api
(serde_yaml)
+ "RUSTSEC-2024-0449",
]
[licenses]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/linkerd-cli-edge-26.10.1/go.mod
new/linkerd-cli-edge-26.10.2/go.mod
--- old/linkerd-cli-edge-26.10.1/go.mod 2026-10-05 18:50:45.000000000 +0200
+++ new/linkerd-cli-edge-26.10.2/go.mod 2026-10-29 16:54:14.000000000 +0100
@@ -1,6 +1,6 @@
module github.com/linkerd/linkerd2
-go 1.26.7
+go 1.26.10
require (
contrib.go.opencensus.io/exporter/ocagent v0.7.0
@@ -14,7 +14,7 @@
github.com/fatih/color v1.19.0
github.com/fsnotify/fsnotify v1.10.1
github.com/go-openapi/spec v1.0.1
- github.com/go-test/deep v1.1.1
+ github.com/go-test/deep v1.1.2
github.com/golang/protobuf v1.5.4
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674
github.com/grantae/certinfo v0.0.0-20170412194111-59d56a35515b
@@ -35,7 +35,7 @@
github.com/spf13/cobra v1.10.2
github.com/spf13/pflag v1.0.10
go.opencensus.io v0.24.0
- golang.org/x/tools v0.50.0
+ golang.org/x/tools v0.52.0
google.golang.org/grpc v1.84.0
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.6.2
google.golang.org/protobuf v1.36.12
@@ -61,7 +61,7 @@
github.com/go-openapi/swag/netutils v0.27.1 // indirect
github.com/go-openapi/swag/pools v0.29.1 // indirect
github.com/golang-jwt/jwt/v5 v5.3.1 // indirect
- golang.org/x/net v0.59.0 // indirect
+ golang.org/x/net v0.61.0 // indirect
k8s.io/streaming v0.37.1 // indirect
)
@@ -136,14 +136,14 @@
go.opentelemetry.io/otel/trace v1.44.0 // indirect
go.yaml.in/yaml/v2 v2.4.4 // indirect
go.yaml.in/yaml/v3 v3.0.5 // indirect
- golang.org/x/crypto v0.57.0 // indirect
- golang.org/x/mod v0.41.0 // indirect
+ golang.org/x/crypto v0.58.0 // indirect
+ golang.org/x/mod v0.42.0 // indirect
golang.org/x/oauth2 v0.36.0 // indirect
- golang.org/x/sync v0.23.0 // indirect
- golang.org/x/sys v0.48.0 // indirect
- golang.org/x/telemetry v0.0.0-20260908163034-4bcc4b2ee518 // indirect
- golang.org/x/term v0.46.0 // indirect
- golang.org/x/text v0.42.0 // indirect
+ golang.org/x/sync v0.24.0 // indirect
+ golang.org/x/sys v0.49.0 // indirect
+ golang.org/x/telemetry v0.0.0-20261009151841-97e8ea77aa2a // indirect
+ golang.org/x/term v0.47.0 // indirect
+ golang.org/x/text v0.43.0 // indirect
golang.org/x/time v0.15.0 // indirect
golang.org/x/tools/godoc v0.1.0-deprecated // indirect
google.golang.org/api v0.278.0 // indirect
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/linkerd-cli-edge-26.10.1/go.sum
new/linkerd-cli-edge-26.10.2/go.sum
--- old/linkerd-cli-edge-26.10.1/go.sum 2026-10-05 18:50:45.000000000 +0200
+++ new/linkerd-cli-edge-26.10.2/go.sum 2026-10-29 16:54:14.000000000 +0100
@@ -172,8 +172,8 @@
github.com/go-openapi/testify/v2 v2.7.0/go.mod
h1:SgsVHtfooshd0tublTtJ50FPKhujf47YRqauXXOUxfw=
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/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
-github.com/go-test/deep v1.1.1/go.mod
h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
+github.com/go-test/deep v1.1.2 h1:JUuyv17rKrqYfLFnP9A4Yh6hw0635ugB93bMg2bwuDQ=
+github.com/go-test/deep v1.1.2/go.mod
h1:lwVFiFFWPjydTsV3xGJ/YTQsnWwi8zxBFM+gOVcwINE=
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod
h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/golang-jwt/jwt/v5 v5.3.1
h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY=
@@ -463,8 +463,8 @@
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod
h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
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.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M=
-golang.org/x/crypto v0.57.0/go.mod
h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA=
+golang.org/x/crypto v0.58.0 h1:COkYLr4k7nDI4r6QtMML2AfzeIswWHAJthLS6K/M/54=
+golang.org/x/crypto v0.58.0/go.mod
h1:Xh+kl5A+M0gMiWDytH2Hhr5Z7WbNCpv/eB/EFgfSk+w=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod
h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod
h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod
h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -494,8 +494,8 @@
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod
h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod
h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.41.0 h1:qJmnOUb4YB+FsEuM3HcWucdZASCPGhsX6uljO6pog0c=
-golang.org/x/mod v0.41.0/go.mod h1:Ek9pY8RKWXwsWvd3rQiHYtMqkjSUV+s1Rj7j4H5Ur6o=
+golang.org/x/mod v0.42.0 h1:ICeL3t2L30ljSPHHxDnR4fqVcBt/zR2zJAb9juavmQg=
+golang.org/x/mod v0.42.0/go.mod h1:u5fzIrRInkL8MaO1cbRkUHT64v303YIT5KEqpNr7jRs=
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-20190108225652-1e06a53dbb7e/go.mod
h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -516,8 +516,8 @@
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod
h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod
h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod
h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.59.0 h1:5zfYln+w5XCxwrnMMJPufRgNoXEaGxl0wo5GqPXyues=
-golang.org/x/net v0.59.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg=
+golang.org/x/net v0.61.0 h1:RR+6j/BTBCrggOLugxa+66R8FvoN6MHlzDlZIbN9YFw=
+golang.org/x/net v0.61.0/go.mod h1:WgDCOTH8iwtB66T4/GfI94AHo/hhdb7Hah9NDseQfiI=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod
h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod
h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod
h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -532,8 +532,8 @@
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-20200317015054-43a5402ce75a/go.mod
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk=
-golang.org/x/sync v0.23.0/go.mod
h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0=
+golang.org/x/sync v0.24.0 h1:iqiDrGoDgyuvAKrhLQthUEzU/R378N78gXbBjxed7oA=
+golang.org/x/sync v0.24.0/go.mod
h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/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-20190312061237-fead79001313/go.mod
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -556,19 +556,19 @@
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo=
-golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og=
-golang.org/x/telemetry v0.0.0-20260908163034-4bcc4b2ee518
h1:F5BWKvW126NXR74uxkxuc1jQHhm/rwm/J3rSiFyuRs4=
-golang.org/x/telemetry v0.0.0-20260908163034-4bcc4b2ee518/go.mod
h1:i+ivNqjDnTF3WTElsdk5g9V5DTSBYgdNo7xTU9SDwYA=
-golang.org/x/term v0.46.0 h1:3+OXuTbaKDgwk8jTi3aSLHRlmWqHEUDUtxnbFigO4YE=
-golang.org/x/term v0.46.0/go.mod
h1:+K02xbkittuwc0Am4abfA3Fc+XRGXkvBXNO88NCXPoc=
+golang.org/x/sys v0.49.0 h1:XbzkgYJHdqh/8m2Uu0W/dQv8nktxx4BFHp1M0gROTXA=
+golang.org/x/sys v0.49.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og=
+golang.org/x/telemetry v0.0.0-20261009151841-97e8ea77aa2a
h1:wnveMBKHwx8/nIb8WYT5P9vtefdXOvIWxzycCkc5n6Q=
+golang.org/x/telemetry v0.0.0-20261009151841-97e8ea77aa2a/go.mod
h1:i+ivNqjDnTF3WTElsdk5g9V5DTSBYgdNo7xTU9SDwYA=
+golang.org/x/term v0.47.0 h1:cpyOwQkr2Nzxe2p6KnrTG7Ei2wtzjsuSjhpXXepZ/BM=
+golang.org/x/term v0.47.0/go.mod
h1:efAfAuG6RKABvg1ArGebRkvX6LXul14SM67o2e4mUCY=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod
h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/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.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI=
-golang.org/x/text v0.42.0/go.mod
h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E=
+golang.org/x/text v0.43.0 h1:1QivrlhwAsnMOcqgOdl9my7s9OyZl8O5/UGUTJVXoWc=
+golang.org/x/text v0.43.0/go.mod
h1:hbSIYA/amXcRXTFSZqh8tWHEoqRvvbKPJ2uz/KU+a+s=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod
h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod
h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod
h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -604,8 +604,8 @@
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod
h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod
h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod
h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
-golang.org/x/tools v0.50.0 h1:c2ifzfcuY7L90lZ2aKd8S4K2NpASF08SZx9ZuJkHmSU=
-golang.org/x/tools v0.50.0/go.mod
h1:7ulVMw3831Mwi5EZD6RomGyffr4VFjuNYXf2BbCEAV0=
+golang.org/x/tools v0.52.0 h1:ryxg4U63oaUYk7uOLTF37n43f4qgtGvqV4Ioit1BaEs=
+golang.org/x/tools v0.52.0/go.mod
h1:ItcP5UNaVGG+Yc4eIYmaFLNJ4soEopkx5Y2d4lcEurs=
golang.org/x/tools/go/expect v0.1.1-deprecated
h1:jpBZDwmgPhXsKZC6WhL20P4b/wmnpsEAGHaNy0n/rJM=
golang.org/x/tools/go/expect v0.1.1-deprecated/go.mod
h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY=
golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated
h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM=
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/linkerd-cli-edge-26.10.1/pkg/healthcheck/healthcheck_test.go
new/linkerd-cli-edge-26.10.2/pkg/healthcheck/healthcheck_test.go
--- old/linkerd-cli-edge-26.10.1/pkg/healthcheck/healthcheck_test.go
2026-10-05 18:50:45.000000000 +0200
+++ new/linkerd-cli-edge-26.10.2/pkg/healthcheck/healthcheck_test.go
2026-10-29 16:54:14.000000000 +0100
@@ -2441,7 +2441,7 @@
serviceAccountName: linkerd-cni
containers:
- name: install-cni
- image: cr.l5d.io/linkerd/cni-plugin:v1.7.0
+ image: cr.l5d.io/linkerd/cni-plugin:v1.7.1
env:
- name: DEST_CNI_NET_DIR
valueFrom:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/linkerd-cli-edge-26.10.1/pkg/version/version.go
new/linkerd-cli-edge-26.10.2/pkg/version/version.go
--- old/linkerd-cli-edge-26.10.1/pkg/version/version.go 2026-10-05
18:50:45.000000000 +0200
+++ new/linkerd-cli-edge-26.10.2/pkg/version/version.go 2026-10-29
16:54:14.000000000 +0100
@@ -12,7 +12,7 @@
// DO NOT EDIT
var Version = undefinedVersion
-var LinkerdCNIVersion = "v1.7.0"
+var LinkerdCNIVersion = "v1.7.1"
const (
// undefinedVersion should take the form `channel-version` to conform to
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/linkerd-cli-edge-26.10.1/policy-controller/runtime/Cargo.toml
new/linkerd-cli-edge-26.10.2/policy-controller/runtime/Cargo.toml
--- old/linkerd-cli-edge-26.10.1/policy-controller/runtime/Cargo.toml
2026-10-05 18:50:45.000000000 +0200
+++ new/linkerd-cli-edge-26.10.2/policy-controller/runtime/Cargo.toml
2026-10-29 16:54:14.000000000 +0100
@@ -65,3 +65,11 @@
workspace = true
default-features = false
features = ["transport", "router"]
+
+[dev-dependencies]
+h2 = "0.4.19"
+http = { workspace = true }
+
+[dev-dependencies.tokio]
+version = "1"
+features = ["io-util", "macros", "rt", "time"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/linkerd-cli-edge-26.10.1/policy-controller/runtime/src/args.rs
new/linkerd-cli-edge-26.10.2/policy-controller/runtime/src/args.rs
--- old/linkerd-cli-edge-26.10.1/policy-controller/runtime/src/args.rs
2026-10-05 18:50:45.000000000 +0200
+++ new/linkerd-cli-edge-26.10.2/policy-controller/runtime/src/args.rs
2026-10-29 16:54:14.000000000 +0100
@@ -27,6 +27,16 @@
// size to be the same as the reconciliation period in milliseconds.
const STATUS_UPDATE_QUEUE_SIZE: usize = RECONCILIATION_PERIOD.as_millis() as
usize;
+// h2 closes a connection with GOAWAY(ENHANCE_YOUR_CALM) once its budget for
+// small, non-final DATA frames is exhausted. Each such frame shorter than 256
+// bytes costs `256 - len` bytes of the budget until the server reads it. A
+// Watch() request body is one such frame, so a proxy that opens many watches
+// at once can exhaust the budget before the controller has read them. h2
+// sizes the budget at half the connection window, so a 2.5 MiB window gives a
+// 1.25 MiB budget: room for more than 5,000 unread Watch() requests on one
+// connection, where hyper's default 1 MiB window allows about 2,000.
+const GRPC_INITIAL_CONNECTION_WINDOW_SIZE: u32 = 5 * 512 * 1024;
+
#[derive(Debug, Parser)]
#[clap(name = "policy", about = "A policy resource controller")]
pub struct Args {
@@ -527,7 +537,11 @@
let (close_tx, close_rx) = tokio::sync::oneshot::channel();
tokio::pin! {
- let srv =
Server::builder().add_service(inbound_svc).add_service(outbound_svc).serve_with_shutdown(addr,
close_rx.map(|_| {}));
+ let srv = Server::builder()
+
.initial_connection_window_size(GRPC_INITIAL_CONNECTION_WINDOW_SIZE)
+ .add_service(inbound_svc)
+ .add_service(outbound_svc)
+ .serve_with_shutdown(addr, close_rx.map(|_| {}));
}
info!(%addr, "policy gRPC server listening");
@@ -630,3 +644,99 @@
}
})
}
+
+#[cfg(test)]
+mod tests {
+ use super::GRPC_INITIAL_CONNECTION_WINDOW_SIZE;
+ use bytes::Bytes;
+ use tokio::time::{timeout, Duration};
+
+ /// Concurrent Watch() requests that one connection must be able to open
+ /// before the server has read any of them.
+ const WATCHES: usize = (GRPC_INITIAL_CONNECTION_WINDOW_SIZE as usize /
256) / 2;
+
+ /// Opens `WATCHES` requests on one HTTP/2 connection, each framed like a
+ /// Watch() request (a non-final DATA frame, then an empty END_STREAM DATA
+ /// frame), against a server with the given connection window that accepts
+ /// the requests but never reads their bodies. The 1-byte bodies are the
+ /// worst case for h2's small DATA frame budget. Returns whether the
+ /// connection is still open afterwards.
+ async fn connection_survives_watches(connection_window: u32) -> bool {
+ let (client_io, server_io) = tokio::io::duplex(1024 * 1024);
+
+ let server = tokio::spawn(async move {
+ let mut builder = h2::server::Builder::new();
+ builder.initial_connection_window_size(connection_window);
+ let mut conn = builder
+ .handshake::<_, Bytes>(server_io)
+ .await
+ .expect("server handshake must succeed");
+ let mut held = Vec::new();
+ while let Some(Ok(req)) = conn.accept().await {
+ held.push(req);
+ }
+ });
+
+ let (mut client, mut conn) = h2::client::handshake(client_io)
+ .await
+ .expect("client handshake must succeed");
+ let mut ping_pong = conn.ping_pong().expect("ping pong must be
available");
+ let conn = tokio::spawn(conn);
+
+ let req = http::Request::post(
+
"http://policy.test/io.linkerd.proxy.outbound_policy.OutboundPolicies/Watch",
+ )
+ .body(())
+ .expect("request must be valid");
+ let mut streams = Vec::with_capacity(WATCHES);
+ let mut survived = true;
+ for _ in 0..WATCHES {
+ client = match client.ready().await {
+ Ok(client) => client,
+ Err(_) => {
+ survived = false;
+ break;
+ }
+ };
+ let Ok((rsp, mut stream)) = client.send_request(req.clone(),
false) else {
+ survived = false;
+ break;
+ };
+ // Frame the body like a Watch() request: the message in a
+ // non-final DATA frame, then an empty END_STREAM frame.
+ if stream.send_data(Bytes::from_static(b"x"), false).is_err()
+ || stream.send_data(Bytes::new(), true).is_err()
+ {
+ survived = false;
+ break;
+ }
+ // Hold both halves of the stream so that it isn't reset.
+ streams.push((rsp, stream));
+ }
+
+ // The server processes frames in order, so a PONG means it has
+ // handled every DATA frame sent before the PING.
+ survived &= timeout(Duration::from_secs(10),
ping_pong.ping(h2::Ping::opaque()))
+ .await
+ .expect("ping must complete or fail before the timeout")
+ .is_ok();
+
+ server.abort();
+ conn.abort();
+ survived
+ }
+
+ #[tokio::test]
+ async fn grpc_connection_window_allows_concurrent_watches() {
+
assert!(connection_survives_watches(GRPC_INITIAL_CONNECTION_WINDOW_SIZE).await);
+ }
+
+ #[tokio::test]
+ async fn default_connection_window_does_not_allow_concurrent_watches() {
+ // hyper's default HTTP/2 connection window, which tonic uses when the
+ // window isn't set.
+ //
+ //
https://github.com/hyperium/hyper/blob/f1b0876495cb042d228e8db00740056152ac131c/src/proto/h2/server.rs#L36
+ assert!(!connection_survives_watches(1024 * 1024).await);
+ }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/linkerd-cli-edge-26.10.1/policy-test/tests/e2e_http_local_ratelimit_policy.rs
new/linkerd-cli-edge-26.10.2/policy-test/tests/e2e_http_local_ratelimit_policy.rs
---
old/linkerd-cli-edge-26.10.1/policy-test/tests/e2e_http_local_ratelimit_policy.rs
2026-10-05 18:50:45.000000000 +0200
+++
new/linkerd-cli-edge-26.10.2/policy-test/tests/e2e_http_local_ratelimit_policy.rs
2026-10-29 16:54:14.000000000 +0100
@@ -244,6 +244,9 @@
..Default::default()
}],
service_account_name: Some(name.to_string()),
+ // fortio is one-shot; without this the kubelet restarts it
+ // immediately and the logs fetched are from the new run.
+ restart_policy: Some("Never".to_string()),
..Default::default()
}),
..k8s::Pod::default()
@@ -263,22 +266,21 @@
let log_params = LogParams {
container: Some("fortio".to_string()),
- tail_lines: Some(2),
..Default::default()
};
let api = kube::Api::<k8s::Pod>::namespaced(client.clone(), ns);
- let result = api
+ let logs = api
.logs(name, &log_params)
.await
- .expect("failed to fetch logs")
- .split('\n')
- .take(1)
- .collect::<String>();
+ .expect("failed to fetch logs");
- re.captures(&result)
- .unwrap_or_else(|| panic!("failed to parse log: {result}"))
+ // Scan the whole log rather than assuming the line's position, so that
+ // fortio output changes or an aborted run surface the full log.
+ logs.lines()
+ .find_map(|line| re.captures(line))
+ .unwrap_or_else(|| panic!("failed to parse log:\n{logs}"))
.get(1)
- .unwrap_or_else(|| panic!("failed to parse log: {result}"))
+ .expect("pattern has one capture group")
.as_str()
.parse()
.expect("failed to parse rate limit percentage")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/linkerd-cli-edge-26.10.1/viz/metrics-api/Dockerfile
new/linkerd-cli-edge-26.10.2/viz/metrics-api/Dockerfile
--- old/linkerd-cli-edge-26.10.1/viz/metrics-api/Dockerfile 2026-10-05
18:50:45.000000000 +0200
+++ new/linkerd-cli-edge-26.10.2/viz/metrics-api/Dockerfile 2026-10-29
16:54:14.000000000 +0100
@@ -1,7 +1,7 @@
ARG BUILDPLATFORM=linux/amd64
# Precompile key slow-to-build dependencies
-FROM --platform=$BUILDPLATFORM golang:1.26.7-alpine AS go-deps
+FROM --platform=$BUILDPLATFORM golang:1.26.10-alpine AS go-deps
WORKDIR /linkerd-build
COPY go.mod go.sum ./
COPY bin/install-deps bin/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/linkerd-cli-edge-26.10.1/viz/tap/Dockerfile
new/linkerd-cli-edge-26.10.2/viz/tap/Dockerfile
--- old/linkerd-cli-edge-26.10.1/viz/tap/Dockerfile 2026-10-05
18:50:45.000000000 +0200
+++ new/linkerd-cli-edge-26.10.2/viz/tap/Dockerfile 2026-10-29
16:54:14.000000000 +0100
@@ -1,7 +1,7 @@
ARG BUILDPLATFORM=linux/amd64
# Precompile key slow-to-build dependencies
-FROM --platform=$BUILDPLATFORM golang:1.26.7-alpine AS go-deps
+FROM --platform=$BUILDPLATFORM golang:1.26.10-alpine AS go-deps
WORKDIR /linkerd-build
COPY go.mod go.sum ./
COPY bin/install-deps bin/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/linkerd-cli-edge-26.10.1/viz/tap/api/server.go
new/linkerd-cli-edge-26.10.2/viz/tap/api/server.go
--- old/linkerd-cli-edge-26.10.1/viz/tap/api/server.go 2026-10-05
18:50:45.000000000 +0200
+++ new/linkerd-cli-edge-26.10.2/viz/tap/api/server.go 2026-10-29
16:54:14.000000000 +0100
@@ -24,6 +24,11 @@
const defaultExtraHeaderPrefix = "X-Remote-Extra-"
+var (
+ errNoTLS = errors.New("TLS client connection required")
+ errDidNotAppendCert = errors.New("unable to append cert from
client-ca-pem")
+)
+
// Server holds the underlying http server and its config
type Server struct {
*http.Server
@@ -67,14 +72,16 @@
"addr": addr,
})
- clientCertPool := x509.NewCertPool()
- clientCertPool.AppendCertsFromPEM([]byte(clientCAPem))
+ clientCertPool, err := newClientCertPool(clientCAPem)
+ if err != nil {
+ return nil, err
+ }
httpServer := &http.Server{
Addr: addr,
ReadHeaderTimeout: 15 * time.Second,
TLSConfig: &tls.Config{
- ClientAuth: tls.VerifyClientCertIfGiven,
+ ClientAuth: tls.RequireAndVerifyClientCert,
ClientCAs: clientCertPool,
MinVersion: tls.VersionTLS13,
},
@@ -143,6 +150,9 @@
// validate ensures that the request should be honored returning an error
otherwise.
func (a *Server) validate(req *http.Request) error {
+ if req.TLS == nil {
+ return errNoTLS
+ }
// if `requestheader-allowed-names` was empty, allow any CN
if len(a.allowedNames) > 0 {
for _, cn := range a.allowedNames {
@@ -163,6 +173,16 @@
return nil
}
+// newClientCertPool builds the pool used to verify client certificates,
+// returning an error if no certificates could be parsed from clientCAPem.
+func newClientCertPool(clientCAPem string) (*x509.CertPool, error) {
+ pool := x509.NewCertPool()
+ if !pool.AppendCertsFromPEM([]byte(clientCAPem)) {
+ return nil, errDidNotAppendCert
+ }
+ return pool, nil
+}
+
// serverAuth parses the relevant data out of a ConfigMap to enable client TLS
// authentication.
// kubectl -n kube-system get cm/extension-apiserver-authentication
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/linkerd-cli-edge-26.10.1/viz/tap/api/server_test.go
new/linkerd-cli-edge-26.10.2/viz/tap/api/server_test.go
--- old/linkerd-cli-edge-26.10.1/viz/tap/api/server_test.go 2026-10-05
18:50:45.000000000 +0200
+++ new/linkerd-cli-edge-26.10.2/viz/tap/api/server_test.go 2026-10-29
16:54:14.000000000 +0100
@@ -5,6 +5,7 @@
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
+ "errors"
"fmt"
"net"
"net/http"
@@ -14,6 +15,7 @@
"github.com/go-test/deep"
"github.com/linkerd/linkerd2/controller/k8s"
k8sutils "github.com/linkerd/linkerd2/pkg/k8s"
+ pkgTls "github.com/linkerd/linkerd2/pkg/tls"
)
func TestAPIServerAuth(t *testing.T) {
@@ -168,6 +170,67 @@
}
}
+func TestValidate_NoTLS(t *testing.T) {
+ testCases := []struct {
+ name string
+ allowedNames []string
+ }{
+ {name: "any name allowed", allowedNames: nil},
+ {name: "names restricted", allowedNames:
[]string{"name-trusted"}},
+ }
+
+ for _, tc := range testCases {
+ tc := tc // pin
+ t.Run(tc.name, func(t *testing.T) {
+ req := http.Request{}
+
+ server := Server{allowedNames: tc.allowedNames}
+ if err := server.validate(&req); !errors.Is(err,
errNoTLS) {
+ t.Fatalf("Expected %q but encountered %v",
errNoTLS, err)
+ }
+ })
+ }
+}
+
+func TestValidate_NoClientCertificate(t *testing.T) {
+ req := http.Request{TLS: &tls.ConnectionState{}}
+
+ server := Server{allowedNames: []string{"name-trusted"}}
+ if err := server.validate(&req); err == nil {
+ t.Fatal("Expected request without a client certificate to be
rejected")
+ }
+}
+
+func TestNewClientCertPool(t *testing.T) {
+ ca, err := pkgTls.GenerateRootCAWithDefaults("client-ca")
+ if err != nil {
+ t.Fatalf("Failed to generate CA: %s", err)
+ }
+
+ testCases := []struct {
+ name string
+ clientCAPem string
+ err error
+ }{
+ {name: "valid PEM", clientCAPem:
pkgTls.EncodeCertificatesPEM(ca.Cred.Crt.Certificate)},
+ {name: "empty", clientCAPem: "", err: errDidNotAppendCert},
+ {name: "not PEM", clientCAPem: "requestheader-client-ca-file",
err: errDidNotAppendCert},
+ }
+
+ for _, tc := range testCases {
+ tc := tc // pin
+ t.Run(tc.name, func(t *testing.T) {
+ pool, err := newClientCertPool(tc.clientCAPem)
+ if !errors.Is(err, tc.err) {
+ t.Fatalf("Expected error %v but encountered
%v", tc.err, err)
+ }
+ if tc.err == nil && pool == nil {
+ t.Fatal("Expected a cert pool")
+ }
+ })
+ }
+}
+
func TestIsSubjectAlternateName(t *testing.T) {
testCases := []struct {
name string
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/linkerd-cli-edge-26.10.1/web/Dockerfile
new/linkerd-cli-edge-26.10.2/web/Dockerfile
--- old/linkerd-cli-edge-26.10.1/web/Dockerfile 2026-10-05 18:50:45.000000000
+0200
+++ new/linkerd-cli-edge-26.10.2/web/Dockerfile 2026-10-29 16:54:14.000000000
+0100
@@ -1,7 +1,7 @@
ARG BUILDPLATFORM=linux/amd64
# Precompile key slow-to-build dependencies
-FROM --platform=$BUILDPLATFORM golang:1.26.7-alpine AS go-deps
+FROM --platform=$BUILDPLATFORM golang:1.26.10-alpine AS go-deps
WORKDIR /linkerd-build
COPY go.mod go.sum ./
COPY bin/install-deps bin/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/linkerd-cli-edge-26.10.1/web/app/yarn.lock
new/linkerd-cli-edge-26.10.2/web/app/yarn.lock
--- old/linkerd-cli-edge-26.10.1/web/app/yarn.lock 2026-10-05
18:50:45.000000000 +0200
+++ new/linkerd-cli-edge-26.10.2/web/app/yarn.lock 2026-10-29
16:54:14.000000000 +0100
@@ -5460,9 +5460,9 @@
integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
fast-uri@^3.0.1:
- version "3.1.8"
- resolved
"https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.1.8.tgz#f7db8d942e20eead3cfe93b0beeb4eb0169e938b"
- integrity
sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==
+ version "3.1.9"
+ resolved
"https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.1.9.tgz#f1deba822b1d6ac79da2f860e872a63470cff203"
+ integrity
sha512-hS/0Wt3Ya043oKXs0sIxrMpKQITXhMLIrVAKKXi4gozGC9v7YRWVnXIZzjNPTO02M9BdxLCWqK1yRXgNziVyJQ==
fastq@^1.6.0:
version "1.13.0"
@@ -8539,9 +8539,9 @@
icss-utils "^5.0.0"
postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4:
- version "6.0.6"
- resolved
"https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz#2c5bba8174ac2f6981ab631a42ab0ee54af332ea"
- integrity
sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==
+ version "6.1.5"
+ resolved
"https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.1.5.tgz#20e988ce8eab87575d54824d9800236c5fd872ca"
+ integrity
sha512-TEHFzb5KRDKaOgJ4TYE+0jyJtFbjLvkdVOu0fZ2b6MTWzoqZd4Le+61aEppWkvTlYePgOX4ATL1wsAIPMLTw6Q==
dependencies:
cssesc "^3.0.0"
util-deprecate "^1.0.2"
++++++ linkerd-cli-edge.obsinfo ++++++
--- /var/tmp/diff_new_pack.h8TWxD/_old 2026-10-30 18:23:00.015142586 +0100
+++ /var/tmp/diff_new_pack.h8TWxD/_new 2026-10-30 18:23:00.024142963 +0100
@@ -1,5 +1,5 @@
name: linkerd-cli-edge
-version: 26.10.1
-mtime: 1791219045
-commit: f6415cf0f2a6e9e04aab969083907bde4be0ea20
+version: 26.10.2
+mtime: 1793289254
+commit: a4c00ac553f0f2ff84558dd7a35ed24dcd6cc6eb
++++++ vendor.tar.gz ++++++
/work/SRC/openSUSE:Factory/linkerd-cli-edge/vendor.tar.gz
/work/SRC/openSUSE:Factory/.linkerd-cli-edge.new.1255/vendor.tar.gz differ:
char 139, line 1