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

Reply via email to