From 59aa4450039a301fa00c0f2b55eaff58fdc26965 Mon Sep 17 00:00:00 2001 From: "v.oleynikov" Date: Fri, 14 Mar 2025 10:22:30 +0300 Subject: [PATCH 1/6] [internal] switch from python to go hooks and some images refactoring Signed-off-by: v.oleynikov --- .github/workflows/deploy_dev.yml | 2 +- .golangci.yaml | 40 +- api/go.mod | 4 +- hooks/common.py | 34 - hooks/ensure_crds.py | 79 - hooks/generate_webhook_certs.py | 42 - hooks/go/020-webhook-certs/webhook-certs.go | 22 + .../remove-sc-and-secrets-on-module-delete.go | 116 + .../migrate-from-ceph-csi-module.go | 10 +- .../remove-finalizers-on-module-delete.go | 65 - hooks/go/consts/consts.go | 10 +- hooks/go/funcs/funcs.go | 6 +- hooks/go/go.mod | 23 +- hooks/go/go.sum | 116 +- hooks/go/main.go | 6 +- hooks/lib/__init__.py | 0 hooks/lib/certificate/__init__.py | 0 hooks/lib/certificate/certificate.py | 265 - hooks/lib/certificate/parse.py | 31 - hooks/lib/hooks/__init__.py | 0 hooks/lib/hooks/copy_custom_certificate.py | 84 - hooks/lib/hooks/hook.py | 56 - hooks/lib/hooks/internal_tls.py | 434 - hooks/lib/hooks/manage_tenant_secrets.py | 140 - hooks/lib/module/__init__.py | 0 hooks/lib/module/module.py | 38 - hooks/lib/module/values.py | 60 - hooks/lib/password_generator/__init__.py | 0 .../password_generator/password_generator.py | 77 - hooks/lib/tests/__init__.py | 0 .../lib/tests/test_copy_custom_certificate.py | 110 - hooks/lib/tests/test_internal_tls_test.py | 159 - hooks/lib/tests/test_manage_tenant_secrets.py | 102 - hooks/lib/tests/testing.py | 57 - hooks/lib/utils.py | 54 - .../remove_sc_and_secrets_on_module_delete.py | 53 - images/controller/{src => }/cmd/main.go | 11 +- images/controller/{src => }/go.mod | 4 +- images/controller/{src => }/go.sum | 0 .../controller/{src => }/pkg/config/config.go | 2 +- .../ceph_cluster_authentication_watcher.go | 6 +- .../ceph_cluster_connection_watcher.go | 8 +- .../ceph_cluster_connection_watcher_func.go | 6 +- .../ceph_cluster_connection_watcher_test.go | 8 +- .../controller/ceph_storage_class_watcher.go | 8 +- .../ceph_storage_class_watcher_func.go | 6 +- .../ceph_storage_class_watcher_test.go | 8 +- .../{src => }/pkg/controller/common_func.go | 0 .../pkg/controller/controller_suite_test.go | 3 +- .../{src => }/pkg/internal/const.go | 0 .../{src => }/pkg/kubutils/kubernetes.go | 0 .../controller/{src => }/pkg/logger/logger.go | 0 images/controller/werf.inc.yaml | 25 +- ...-gomod.patch => 0001-Modules-update.patch} | 9568 ++++++++++------- .../patches/0002-Modules-update.patch | 2985 +++++ images/webhooks/{src => }/cmd/main.go | 2 +- images/webhooks/{src => }/go.mod | 2 +- images/webhooks/{src => }/go.sum | 0 images/webhooks/{src => }/handlers/func.go | 0 .../{src => }/handlers/scValidator.go | 0 images/webhooks/werf.inc.yaml | 25 +- templates/webhooks/secret.yaml | 6 +- templates/webhooks/webhook.yaml | 3 +- 63 files changed, 9129 insertions(+), 5852 deletions(-) delete mode 100644 hooks/common.py delete mode 100755 hooks/ensure_crds.py delete mode 100755 hooks/generate_webhook_certs.py create mode 100644 hooks/go/020-webhook-certs/webhook-certs.go create mode 100644 hooks/go/030-remove-sc-and-secrets-on-module-delete/remove-sc-and-secrets-on-module-delete.go delete mode 100644 hooks/go/070-remove-finalizers-on-module-delete/remove-finalizers-on-module-delete.go delete mode 100644 hooks/lib/__init__.py delete mode 100644 hooks/lib/certificate/__init__.py delete mode 100644 hooks/lib/certificate/certificate.py delete mode 100644 hooks/lib/certificate/parse.py delete mode 100644 hooks/lib/hooks/__init__.py delete mode 100644 hooks/lib/hooks/copy_custom_certificate.py delete mode 100644 hooks/lib/hooks/hook.py delete mode 100644 hooks/lib/hooks/internal_tls.py delete mode 100644 hooks/lib/hooks/manage_tenant_secrets.py delete mode 100644 hooks/lib/module/__init__.py delete mode 100644 hooks/lib/module/module.py delete mode 100644 hooks/lib/module/values.py delete mode 100644 hooks/lib/password_generator/__init__.py delete mode 100644 hooks/lib/password_generator/password_generator.py delete mode 100644 hooks/lib/tests/__init__.py delete mode 100644 hooks/lib/tests/test_copy_custom_certificate.py delete mode 100644 hooks/lib/tests/test_internal_tls_test.py delete mode 100644 hooks/lib/tests/test_manage_tenant_secrets.py delete mode 100644 hooks/lib/tests/testing.py delete mode 100644 hooks/lib/utils.py delete mode 100755 hooks/remove_sc_and_secrets_on_module_delete.py rename images/controller/{src => }/cmd/main.go (94%) rename images/controller/{src => }/go.mod (96%) rename images/controller/{src => }/go.sum (100%) rename images/controller/{src => }/pkg/config/config.go (97%) rename images/controller/{src => }/pkg/controller/ceph_cluster_authentication_watcher.go (97%) rename images/controller/{src => }/pkg/controller/ceph_cluster_connection_watcher.go (97%) rename images/controller/{src => }/pkg/controller/ceph_cluster_connection_watcher_func.go (99%) rename images/controller/{src => }/pkg/controller/ceph_cluster_connection_watcher_test.go (99%) rename images/controller/{src => }/pkg/controller/ceph_storage_class_watcher.go (98%) rename images/controller/{src => }/pkg/controller/ceph_storage_class_watcher_func.go (99%) rename images/controller/{src => }/pkg/controller/ceph_storage_class_watcher_test.go (99%) rename images/controller/{src => }/pkg/controller/common_func.go (100%) rename images/controller/{src => }/pkg/controller/controller_suite_test.go (99%) rename images/controller/{src => }/pkg/internal/const.go (100%) rename images/controller/{src => }/pkg/kubutils/kubernetes.go (100%) rename images/controller/{src => }/pkg/logger/logger.go (100%) rename images/csi-ceph/patches/{0001-fix-gomod.patch => 0001-Modules-update.patch} (75%) create mode 100644 images/csi-ceph/patches/0002-Modules-update.patch rename images/webhooks/{src => }/cmd/main.go (97%) rename images/webhooks/{src => }/go.mod (95%) rename images/webhooks/{src => }/go.sum (100%) rename images/webhooks/{src => }/handlers/func.go (100%) rename images/webhooks/{src => }/handlers/scValidator.go (100%) diff --git a/.github/workflows/deploy_dev.yml b/.github/workflows/deploy_dev.yml index 7146505e..612c23ac 100644 --- a/.github/workflows/deploy_dev.yml +++ b/.github/workflows/deploy_dev.yml @@ -66,5 +66,5 @@ jobs: with: module_source: "${{ vars.DEV_MODULE_SOURCE }}" module_name: ${{ vars.MODULE_NAME }} - module_tag: $(echo pr${{ github.ref_name }} | sed 's/\/.*//g') + module_tag: $(echo ${{ github.ref_name }} | sed 's/\/.*//g') - uses: deckhouse/modules-actions/deploy@v2 diff --git a/.golangci.yaml b/.golangci.yaml index 06979dad..f7970cae 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -13,9 +13,7 @@ linters-settings: sections: - standard - default - - prefix(d8-controller) - - prefix(webhooks) - + - prefix(github.com/deckhouse) errcheck: ignore: fmt:.*,[rR]ead|[wW]rite|[cC]lose,io:Copy @@ -23,21 +21,21 @@ linters-settings: linters: disable-all: true enable: - - dogsled - - errcheck - - gci - - gocritic - - gofmt -# - goimports - - gosimple - - govet - - ineffassign - - misspell - - revive - - staticcheck -# - structcheck - - typecheck - - unconvert - - unparam - - whitespace - - copyloopvar + - dogsled + - errcheck + - gci + - gocritic + - gofmt + # - goimports + - gosimple + - govet + - ineffassign + - misspell + - revive + - staticcheck + # - structcheck + - typecheck + - unconvert + - unparam + - whitespace + - copyloopvar diff --git a/api/go.mod b/api/go.mod index 1a14dc2b..1f842163 100644 --- a/api/go.mod +++ b/api/go.mod @@ -1,8 +1,6 @@ module github.com/deckhouse/csi-ceph/api -go 1.23.0 - -toolchain go1.23.6 +go 1.23.6 require k8s.io/apimachinery v0.32.3 diff --git a/hooks/common.py b/hooks/common.py deleted file mode 100644 index fab7288b..00000000 --- a/hooks/common.py +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2023 Flant JSC -# -# 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 deckhouse import hook -from lib.module import module -from typing import Callable -import json -import os -import unittest - - -NAMESPACE = "d8-csi-ceph" -MODULE_NAME = "csiCeph" - -def json_load(path: str): - with open(path, "r", encoding="utf-8") as f: - data = json.load(f) - return data - -def get_dir_path() -> str: - return os.path.dirname(os.path.abspath(__file__)) diff --git a/hooks/ensure_crds.py b/hooks/ensure_crds.py deleted file mode 100755 index b00fa3a5..00000000 --- a/hooks/ensure_crds.py +++ /dev/null @@ -1,79 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2023 Flant JSC -# -# 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. - -import os - -import yaml -from deckhouse import hook - -# We expect structure with possible subdirectories like this: -# -# my-module/ -# crds/ -# crd1.yaml -# crd2.yaml -# subdir/ -# crd3.yaml -# hooks/ -# ensure_crds.py # this file - - -config = """ -configVersion: v1 -onStartup: 5 -""" - - -def main(ctx: hook.Context): - for crd in iter_manifests(find_crds_root(__file__)): - ctx.kubernetes.create_or_update(crd) - - -def iter_manifests(root_path: str): - if not os.path.exists(root_path): - return - - for dirpath, dirnames, filenames in os.walk(top=root_path): - for filename in filenames: - if not filename.endswith(".yaml"): - # Wee only seek manifests - continue - if filename.startswith("doc-"): - # Skip dedicated doc yamls, common for Deckhouse internal modules - continue - - crd_path = os.path.join(dirpath, filename) - with open(crd_path, "r", encoding="utf-8") as f: - for manifest in yaml.safe_load_all(f): - if manifest is None: - continue - yield manifest - - for dirname in dirnames: - subroot = os.path.join(dirpath, dirname) - for manifest in iter_manifests(subroot): - yield manifest - - -def find_crds_root(hookpath): - hooks_root = os.path.dirname(hookpath) - module_root = os.path.dirname(hooks_root) - crds_root = os.path.join(module_root, "crds") - return crds_root - - -if __name__ == "__main__": - hook.run(main, config=config) diff --git a/hooks/generate_webhook_certs.py b/hooks/generate_webhook_certs.py deleted file mode 100755 index e1446042..00000000 --- a/hooks/generate_webhook_certs.py +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2023 Flant JSC -# -# 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 lib.hooks.internal_tls import GenerateCertificateHook, TlsSecret, default_sans -from lib.module import values as module_values -from deckhouse import hook -from typing import Callable -import common - -def main(): - hook = GenerateCertificateHook( - TlsSecret( - cn="webhooks", - name="webhooks-https-certs", - sansGenerator=default_sans([ - "webhooks", - f"webhooks.{common.NAMESPACE}", - f"webhooks.{common.NAMESPACE}.svc"]), - values_path_prefix=f"{common.MODULE_NAME}.internal.customWebhookCert" - ), - cn="csi-nfs-webhooks", - common_ca=True, - namespace=common.NAMESPACE) - - hook.run() - -if __name__ == "__main__": - main() diff --git a/hooks/go/020-webhook-certs/webhook-certs.go b/hooks/go/020-webhook-certs/webhook-certs.go new file mode 100644 index 00000000..ff17ca64 --- /dev/null +++ b/hooks/go/020-webhook-certs/webhook-certs.go @@ -0,0 +1,22 @@ +package hooks_common + +import ( + "fmt" + + consts "github.com/deckhouse/csi-ceph/hooks/go/consts" + tlscertificate "github.com/deckhouse/module-sdk/common-hooks/tls-certificate" +) + +var _ = tlscertificate.RegisterInternalTLSHookEM(tlscertificate.GenSelfSignedTLSHookConf{ + CN: consts.WebhookCertCn, + TLSSecretName: fmt.Sprintf("%s-webhook-cert", consts.WebhookCertCn), + Namespace: consts.ModuleNamespace, + SANs: tlscertificate.DefaultSANs([]string{ + consts.WebhookCertCn, + fmt.Sprintf("%s.%s", consts.WebhookCertCn, consts.ModuleNamespace), + fmt.Sprintf("%s.%s.svc", consts.WebhookCertCn, consts.ModuleNamespace), + // %CLUSTER_DOMAIN%:// is a special value to generate SAN like 'svc_name.svc_namespace.svc.cluster.local' + fmt.Sprintf("%%CLUSTER_DOMAIN%%://%s.%s.svc", consts.WebhookCertCn, consts.ModuleNamespace), + }), + FullValuesPathPrefix: fmt.Sprintf("%s.internal.customWebhookCert", consts.ModuleName), +}) diff --git a/hooks/go/030-remove-sc-and-secrets-on-module-delete/remove-sc-and-secrets-on-module-delete.go b/hooks/go/030-remove-sc-and-secrets-on-module-delete/remove-sc-and-secrets-on-module-delete.go new file mode 100644 index 00000000..4655164a --- /dev/null +++ b/hooks/go/030-remove-sc-and-secrets-on-module-delete/remove-sc-and-secrets-on-module-delete.go @@ -0,0 +1,116 @@ +package hooks_common + +import ( + "context" + "fmt" + + snapv1 "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumesnapshot/v1" + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" + storagev1 "k8s.io/api/storage/v1" + sv1 "k8s.io/api/storage/v1" + extv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" + "sigs.k8s.io/controller-runtime/pkg/client" + + "github.com/deckhouse/csi-ceph/api/v1alpha1" + "github.com/deckhouse/csi-ceph/hooks/go/consts" + "github.com/deckhouse/module-sdk/pkg" + "github.com/deckhouse/module-sdk/pkg/registry" + "github.com/deckhouse/sds-common-lib/kubeclient" +) + +var _ = registry.RegisterFunc(configRemoveScAndSecretsOnModuleDelete, handlerRemoveScAndSecretsOnModuleDelete) + +var configRemoveScAndSecretsOnModuleDelete = &pkg.HookConfig{ + OnAfterDeleteHelm: &pkg.OrderedConfig{Order: 10}, +} + +func handlerRemoveScAndSecretsOnModuleDelete(ctx context.Context, input *pkg.HookInput) error { + input.Logger.Info("[remove-sc-and-secrets-on-module-delete]: Started removing SC and Secrets on module delete") + cl, err := kubeclient.NewKubeClient("", + v1alpha1.AddToScheme, + clientgoscheme.AddToScheme, + extv1.AddToScheme, + v1.AddToScheme, + sv1.AddToScheme, + snapv1.AddToScheme) + if err != nil { + input.Logger.Error(fmt.Sprintf("Failed to initialize kube client: %v", err)) + return err + } + + secretList := &corev1.SecretList{} + err = cl.List(ctx, secretList, client.InNamespace(consts.ModuleNamespace)) + if err != nil { + input.Logger.Error(fmt.Sprintf("[remove-sc-and-secrets-on-module-delete]: Failed to list secrets: %v", err)) + return err + } + + for _, secret := range secretList.Items { + input.Logger.Info(fmt.Sprintf("[remove-sc-and-secrets-on-module-delete]: Removing finalizers from %s secret\n", secret.Name)) + + patch := client.MergeFrom(secret.DeepCopy()) + secret.ObjectMeta.Finalizers = nil + + err = cl.Patch(ctx, &secret, patch) + if err != nil { + input.Logger.Error(fmt.Sprintf("[remove-sc-and-secrets-on-module-delete]: Failed to patch secret %s: %v", secret.Name, err)) + return err + } + } + + configMapList := &corev1.ConfigMapList{} + err = cl.List(ctx, configMapList, client.InNamespace(consts.ModuleNamespace)) + if err != nil { + input.Logger.Error(fmt.Sprintf("[remove-sc-and-secrets-on-module-delete]: Failed to list configmaps: %v", err)) + return err + } + for _, configMap := range configMapList.Items { + input.Logger.Info(fmt.Sprintf("[remove-sc-and-secrets-on-module-delete]: Removing finalizers from %s configmap\n", configMap.Name)) + + patch := client.MergeFrom(configMap.DeepCopy()) + configMap.ObjectMeta.Finalizers = nil + + err = cl.Patch(ctx, &configMap, patch) + if err != nil { + input.Logger.Error(fmt.Sprintf("[remove-sc-and-secrets-on-module-delete]: Failed to patch configmap %s: %v", configMap.Name, err)) + return err + } + } + + scList := &storagev1.StorageClassList{} + err = cl.List(ctx, scList) + if err != nil { + input.Logger.Error(fmt.Sprintf("[remove-sc-and-secrets-on-module-delete]: Failed to list storage classes: %v", err)) + return err + } + + for _, sc := range scList.Items { + for _, provisioner := range consts.AllowedProvisioners { + if sc.Provisioner == provisioner { + input.Logger.Info(fmt.Sprintf("[remove-sc-and-secrets-on-module-delete]: Removing finalizers from %s storage class\n", sc.Name)) + + patch := client.MergeFrom(sc.DeepCopy()) + sc.ObjectMeta.Finalizers = nil + + err = cl.Patch(ctx, &sc, patch) + if err != nil { + input.Logger.Error(fmt.Sprintf("[remove-sc-and-secrets-on-module-delete]: Failed to patch storage class %s: %v", sc.Name, err)) + return err + } + + input.Logger.Info(fmt.Sprintf("[remove-sc-and-secrets-on-module-delete]: Removing %s storage class\n", sc.Name)) + err = cl.Delete(ctx, &sc) + if err != nil { + input.Logger.Error(fmt.Sprintf("[remove-sc-and-secrets-on-module-delete]: Failed to delete storage class %s: %v", sc.Name, err)) + return err + } + } + } + } + + input.Logger.Info("[remove-sc-and-secrets-on-module-delete]: Stoped removing SC and Secrets on module delete\n") + + return nil +} diff --git a/hooks/go/060-migrate-from-ceph-csi-module/migrate-from-ceph-csi-module.go b/hooks/go/060-migrate-from-ceph-csi-module/migrate-from-ceph-csi-module.go index 3d5280c6..8f12c15c 100644 --- a/hooks/go/060-migrate-from-ceph-csi-module/migrate-from-ceph-csi-module.go +++ b/hooks/go/060-migrate-from-ceph-csi-module/migrate-from-ceph-csi-module.go @@ -6,17 +6,17 @@ import ( "strings" "time" - "github.com/deckhouse/csi-ceph/api/v1alpha1" - "github.com/deckhouse/module-sdk/pkg" - "github.com/deckhouse/module-sdk/pkg/registry" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/selection" "sigs.k8s.io/controller-runtime/pkg/client" - oldApi "csi-ceph/api/v1alpha1" - funcs "csi-ceph/funcs" + "github.com/deckhouse/csi-ceph/api/v1alpha1" + oldApi "github.com/deckhouse/csi-ceph/hooks/go/api/v1alpha1" + funcs "github.com/deckhouse/csi-ceph/hooks/go/funcs" + "github.com/deckhouse/module-sdk/pkg" + "github.com/deckhouse/module-sdk/pkg/registry" ) const ( diff --git a/hooks/go/070-remove-finalizers-on-module-delete/remove-finalizers-on-module-delete.go b/hooks/go/070-remove-finalizers-on-module-delete/remove-finalizers-on-module-delete.go deleted file mode 100644 index 00f5d98c..00000000 --- a/hooks/go/070-remove-finalizers-on-module-delete/remove-finalizers-on-module-delete.go +++ /dev/null @@ -1,65 +0,0 @@ -package hooks_common - -import ( - "context" - "fmt" - - "github.com/deckhouse/module-sdk/pkg" - "github.com/deckhouse/module-sdk/pkg/registry" - - funcs "csi-ceph/funcs" - - v1 "k8s.io/api/core/v1" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -const ( - configMapName = "ceph-csi-config" - namespace = "d8-csi-ceph" -) - -var _ = registry.RegisterFunc(configMigrateAuthToConnection, handlerRemoveFinalizersOnModuleDelete) - -var configMigrateAuthToConnection = &pkg.HookConfig{ - OnAfterDeleteHelm: &pkg.OrderedConfig{Order: 5}, -} - -func handlerRemoveFinalizersOnModuleDelete(ctx context.Context, input *pkg.HookInput) error { - fmt.Printf("[csi-ceph-remove-finalizers-on-module-delete]: removing finalizers\n") - - cephConfigMap := &v1.ConfigMap{} - - cl, err := funcs.NewKubeClient() - if err != nil { - fmt.Printf("%s", err.Error()) - return err - } - - err = cl.Get(ctx, client.ObjectKey{Name: configMapName, Namespace: namespace}, cephConfigMap) - if err != nil { - if client.IgnoreNotFound(err) != nil { - fmt.Printf("[csi-ceph-remove-finalizers-on-module-delete]: error getting configmap %s: %s\n", configMapName, err) - return err - } - fmt.Printf("[csi-ceph-remove-finalizers-on-module-delete]: configmap %s not found, nothing to clean up\n", configMapName) - return nil - } - - if len(cephConfigMap.Finalizers) == 0 { - fmt.Printf("[csi-ceph-remove-finalizers-on-module-delete]: configmap %s has no finalizers, nothing to clean up\n", configMapName) - return nil - } - - fmt.Printf("[csi-ceph-remove-finalizers-on-module-delete]: configmap %s has finalizers %v. Removing them\n", configMapName, cephConfigMap.Finalizers) - - cephConfigMap.Finalizers = nil - err = cl.Update(ctx, cephConfigMap) - if err != nil { - fmt.Printf("[csi-ceph-remove-finalizers-on-module-delete]: configmap %s update error %s\n", configMapName, err) - return err - } - - fmt.Printf("[csi-ceph-remove-finalizers-on-module-delete]: finalizers removed\n") - - return nil -} diff --git a/hooks/go/consts/consts.go b/hooks/go/consts/consts.go index dfc4a35f..0d16e605 100644 --- a/hooks/go/consts/consts.go +++ b/hooks/go/consts/consts.go @@ -1,6 +1,12 @@ package consts const ( - MODULE_NAME string = "csiCeph" - MODULE_NAMESPACE string = "d8-csi-ceph" + ModuleName string = "csiCeph" + ModuleNamespace string = "d8-csi-ceph" + WebhookCertCn string = "webhooks" ) + +var AllowedProvisioners = []string{ + "rbd.csi.ceph.com", + "cephfs.csi.ceph.com", +} diff --git a/hooks/go/funcs/funcs.go b/hooks/go/funcs/funcs.go index 0bdce465..62a04cf1 100644 --- a/hooks/go/funcs/funcs.go +++ b/hooks/go/funcs/funcs.go @@ -9,9 +9,6 @@ import ( "strings" "time" - oldApi "csi-ceph/api/v1alpha1" - - "github.com/deckhouse/csi-ceph/api/v1alpha1" "github.com/google/go-cmp/cmp" snapv1 "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumesnapshot/v1" appsv1 "k8s.io/api/apps/v1" @@ -30,6 +27,9 @@ import ( "k8s.io/client-go/util/retry" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/apiutil" + + "github.com/deckhouse/csi-ceph/api/v1alpha1" + oldApi "github.com/deckhouse/csi-ceph/hooks/go/api/v1alpha1" ) const ( diff --git a/hooks/go/go.mod b/hooks/go/go.mod index df302c02..3b821b2f 100644 --- a/hooks/go/go.mod +++ b/hooks/go/go.mod @@ -1,14 +1,15 @@ -module csi-ceph +module github.com/deckhouse/csi-ceph/hooks/go go 1.23.6 require ( - github.com/deckhouse/csi-ceph/api v0.0.0-20250314071238-6a7df30c52cc + github.com/deckhouse/csi-ceph/api v0.0.0-20250207141553-9b2c9a45ba22 github.com/deckhouse/module-sdk v0.2.0 + github.com/deckhouse/sds-common-lib v0.0.0-20250322050030-9c6b017469ce github.com/google/go-cmp v0.7.0 github.com/kubernetes-csi/external-snapshotter/client/v8 v8.2.0 k8s.io/api v0.32.3 - k8s.io/apiextensions-apiserver v0.32.3 + k8s.io/apiextensions-apiserver v0.32.2 k8s.io/apimachinery v0.32.3 k8s.io/client-go v0.32.3 sigs.k8s.io/controller-runtime v0.20.3 @@ -19,6 +20,7 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/caarlos0/env/v11 v11.3.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/cloudflare/cfssl v1.6.5 // indirect github.com/containerd/stargz-snapshotter/estargz v0.16.3 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/deckhouse/deckhouse/pkg/log v0.0.0-20250320042525-77d066cf8f00 // indirect @@ -38,11 +40,13 @@ require ( github.com/gojuno/minimock/v3 v3.4.5 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/btree v1.1.3 // indirect + github.com/google/certificate-transparency-go v1.1.7 // indirect github.com/google/gnostic-models v0.6.9 // indirect github.com/google/go-containerregistry v0.20.3 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jmoiron/sqlx v1.3.5 // indirect github.com/jonboulle/clockwork v0.5.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect @@ -53,7 +57,8 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.1 // indirect + github.com/opencontainers/image-spec v1.1.0 // indirect + github.com/pelletier/go-toml v1.9.3 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.21.1 // indirect @@ -68,15 +73,19 @@ require ( github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect github.com/vbatts/tar-split v0.12.1 // indirect + github.com/weppos/publicsuffix-go v0.30.0 // indirect github.com/x448/float16 v0.8.4 // indirect + github.com/zmap/zcrypto v0.0.0-20230310154051-c8b263fd8300 // indirect + github.com/zmap/zlint/v3 v3.5.0 // indirect + golang.org/x/crypto v0.36.0 // indirect golang.org/x/net v0.37.0 // indirect - golang.org/x/oauth2 v0.28.0 // indirect + golang.org/x/oauth2 v0.27.0 // indirect golang.org/x/sync v0.12.0 // indirect golang.org/x/sys v0.31.0 // indirect golang.org/x/term v0.30.0 // indirect golang.org/x/text v0.23.0 // indirect - golang.org/x/time v0.11.0 // indirect - gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect + golang.org/x/time v0.10.0 // indirect + gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/protobuf v1.36.5 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect diff --git a/hooks/go/go.sum b/hooks/go/go.sum index 1095c672..73dc08de 100644 --- a/hooks/go/go.sum +++ b/hooks/go/go.sum @@ -6,6 +6,8 @@ github.com/caarlos0/env/v11 v11.3.1 h1:cArPWC15hWmEt+gWk7YBi7lEXTXCvpaSdCiZE2X5m github.com/caarlos0/env/v11 v11.3.1/go.mod h1:qupehSf/Y0TUTsxKywqRt/vJjN5nz6vauiYEUUr8P4U= 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/cloudflare/cfssl v1.6.5 h1:46zpNkm6dlNkMZH/wMW22ejih6gIaJbzL2du6vD7ZeI= +github.com/cloudflare/cfssl v1.6.5/go.mod h1:Bk1si7sq8h2+yVEDrFJiz3d7Aw+pfjjJSZVaD+Taky4= github.com/containerd/stargz-snapshotter/estargz v0.16.3 h1:7evrXtoh1mSbGj/pfRccTampEyKpjpOnS3CyiV1Ebr8= github.com/containerd/stargz-snapshotter/estargz v0.16.3/go.mod h1:uyr4BfYfOj3G9WBVE8cOlQmXAbPN9VEQpBBeJIuOipU= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= @@ -17,6 +19,8 @@ github.com/deckhouse/deckhouse/pkg/log v0.0.0-20250320042525-77d066cf8f00 h1:KRh github.com/deckhouse/deckhouse/pkg/log v0.0.0-20250320042525-77d066cf8f00/go.mod h1:pbAxTSDcPmwyl3wwKDcEB3qdxHnRxqTV+J0K+sha8bw= github.com/deckhouse/module-sdk v0.2.0 h1:MOK03UZ88T7T52bk+lmAz0bRJiljtN5ysq7y8FjEF3s= github.com/deckhouse/module-sdk v0.2.0/go.mod h1:fbs0X7myE8zrPKxs3eoIoFWf68E7r1tZ64uJfYJCsKc= +github.com/deckhouse/sds-common-lib v0.0.0-20250322050030-9c6b017469ce h1:aXWbHqtY7pE7SiunSYED7XfT0bDPZpOSIEWeHzjufvU= +github.com/deckhouse/sds-common-lib v0.0.0-20250322050030-9c6b017469ce/go.mod h1:HEYiROA+n+p/pljW8k25mp+oS7fij9fIWdKzyeLan9s= github.com/docker/cli v28.0.2+incompatible h1:cRPZ77FK3/IXTAIQQj1vmhlxiLS5m+MIUDwS6f57lrE= github.com/docker/cli v28.0.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= @@ -45,6 +49,7 @@ github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= 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= @@ -55,6 +60,8 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= 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/certificate-transparency-go v1.1.7 h1:IASD+NtgSTJLPdzkthwvAG1ZVbF2WtFg4IvoA68XGSw= +github.com/google/certificate-transparency-go v1.1.7/go.mod h1:FSSBo8fyMVgqptbfF6j5p/XNdgQftAhSmXcIxV9iphE= github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw= github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -62,6 +69,8 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/go-containerregistry v0.20.3 h1:oNx7IdTI936V8CQRveCjaxOiegWwvM7kqkbXTpyiovI= github.com/google/go-containerregistry v0.20.3/go.mod h1:w00pIgBRDVUDFM6bq+Qx8lwNWK+cxgCuX1vd3PIBDNI= +github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= 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= @@ -71,6 +80,12 @@ 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/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/itchyny/gojq v0.12.17 h1:8av8eGduDb5+rvEdaOO+zQUjA04MS0m3Ps8HiD+fceg= +github.com/itchyny/gojq v0.12.17/go.mod h1:WBrEMkgAfAGO1LUcGOckBl5O726KPp+OlkKug0I/FEY= +github.com/itchyny/timefmt-go v0.1.6 h1:ia3s54iciXDdzWzwaVKXZPbiXzxxnv1SPGFfM/myJ5Q= +github.com/itchyny/timefmt-go v0.1.6/go.mod h1:RRDZYC5s9ErkjQvTvvU7keJjxUYzIISJGxm9/mAERQg= +github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= +github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I= github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -81,16 +96,23 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +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/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= +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 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kubernetes-csi/external-snapshotter/client/v8 v8.2.0 h1:Q3jQ1NkFqv5o+F8dMmHd8SfEmlcwNeo1immFApntEwE= github.com/kubernetes-csi/external-snapshotter/client/v8 v8.2.0/go.mod h1:E3vdYxHj2C2q6qo8/Da4g7P+IcwqRZyy3gJBzYybV9Y= 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/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -98,16 +120,21 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474/go.mod h1:OQA4XLvDbMgS8P0CevmM4m9Q3Jq4phKUzcocxuGJ5m8= +github.com/mreiferson/go-httpclient v0.0.0-20201222173833-5e475fde3a4d/go.mod h1:OQA4XLvDbMgS8P0CevmM4m9Q3Jq4phKUzcocxuGJ5m8= 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/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg= github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw= github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= -github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= +github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= +github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= +github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ= +github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= 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/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -126,8 +153,11 @@ github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sebdah/goldie/v2 v2.5.5 h1:rx1mwF95RxZ3/83sdS4Yp7t2C5TCokvWP4TBRbAyEWY= github.com/sebdah/goldie/v2 v2.5.5/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI= -github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= -github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +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.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= 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.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= @@ -135,7 +165,10 @@ github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wx 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.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= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= @@ -152,69 +185,128 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/vbatts/tar-split v0.12.1 h1:CqKoORW7BUWBe7UL/iqTVvkTBOF8UvOMKOIZykxnnbo= github.com/vbatts/tar-split v0.12.1/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA= +github.com/weppos/publicsuffix-go v0.12.0/go.mod h1:z3LCPQ38eedDQSwmsSRW4Y7t2L8Ln16JPQ02lHAdn5k= +github.com/weppos/publicsuffix-go v0.13.0/go.mod h1:z3LCPQ38eedDQSwmsSRW4Y7t2L8Ln16JPQ02lHAdn5k= +github.com/weppos/publicsuffix-go v0.30.0 h1:QHPZ2GRu/YE7cvejH9iyavPOkVCB4dNxp2ZvtT+vQLY= +github.com/weppos/publicsuffix-go v0.30.0/go.mod h1:kBi8zwYnR0zrbm8RcuN1o9Fzgpnnn+btVN8uWPMyXAY= +github.com/weppos/publicsuffix-go/publicsuffix/generator v0.0.0-20220927085643-dc0d00c92642/go.mod h1:GHfoeIdZLdZmLjMlzBftbTDntahTttUMWjxZwQJhULE= 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= +github.com/zmap/rc2 v0.0.0-20131011165748-24b9757f5521/go.mod h1:3YZ9o3WnatTIZhuOtot4IcUfzoKVjUHqu6WALIyI0nE= +github.com/zmap/rc2 v0.0.0-20190804163417-abaa70531248/go.mod h1:3YZ9o3WnatTIZhuOtot4IcUfzoKVjUHqu6WALIyI0nE= +github.com/zmap/zcertificate v0.0.0-20180516150559-0e3d58b1bac4/go.mod h1:5iU54tB79AMBcySS0R2XIyZBAVmeHranShAFELYx7is= +github.com/zmap/zcertificate v0.0.1/go.mod h1:q0dlN54Jm4NVSSuzisusQY0hqDWvu92C+TWveAxiVWk= +github.com/zmap/zcrypto v0.0.0-20201128221613-3719af1573cf/go.mod h1:aPM7r+JOkfL+9qSB4KbYjtoEzJqUK50EXkkJabeNJDQ= +github.com/zmap/zcrypto v0.0.0-20201211161100-e54a5822fb7e/go.mod h1:aPM7r+JOkfL+9qSB4KbYjtoEzJqUK50EXkkJabeNJDQ= +github.com/zmap/zcrypto v0.0.0-20230310154051-c8b263fd8300 h1:DZH5n7L3L8RxKdSyJHZt7WePgwdhHnPhQFdQSJaHF+o= +github.com/zmap/zcrypto v0.0.0-20230310154051-c8b263fd8300/go.mod h1:mOd4yUMgn2fe2nV9KXsa9AyQBFZGzygVPovsZR+Rl5w= +github.com/zmap/zlint/v3 v3.0.0/go.mod h1:paGwFySdHIBEMJ61YjoqT4h7Ge+fdYG4sUQhnTb1lJ8= +github.com/zmap/zlint/v3 v3.5.0 h1:Eh2B5t6VKgVH0DFmTwOqE50POvyDhUaU9T2mJOe1vfQ= +github.com/zmap/zlint/v3 v3.5.0/go.mod h1:JkNSrsDJ8F4VRtBZcYUQSvnWFL7utcjDIn+FE64mlBI= 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/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-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-20201124201722-c8d3bf9c5392/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= 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/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 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-20200202094626-16171245cfb2/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-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +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.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= -golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc= -golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= +golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M= +golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= 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/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/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-20191026070338-33540a1f6037/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-20201126233918-771906719818/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.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= 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.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= -golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4= +golang.org/x/time v0.10.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.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE= golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588= 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.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0= -gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= +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/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= google.golang.org/protobuf v1.36.5/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-20180628173108-788fd7840127/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.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 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= @@ -222,8 +314,8 @@ gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g= k8s.io/api v0.32.3 h1:Hw7KqxRusq+6QSplE3NYG4MBxZw1BZnq4aP4cJVINls= k8s.io/api v0.32.3/go.mod h1:2wEDTXADtm/HA7CCMD8D8bK4yuBUptzaRhYcYEEYA3k= -k8s.io/apiextensions-apiserver v0.32.3 h1:4D8vy+9GWerlErCwVIbcQjsWunF9SUGNu7O7hiQTyPY= -k8s.io/apiextensions-apiserver v0.32.3/go.mod h1:8YwcvVRMVzw0r1Stc7XfGAzB/SIVLunqApySV5V7Dss= +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.3 h1:JmDuDarhDmA/Li7j3aPrwhpNBA94Nvk5zLeOge9HH1U= k8s.io/apimachinery v0.32.3/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= k8s.io/client-go v0.32.3 h1:RKPVltzopkSgHS7aS98QdscAgtgah/+zmpAogooIqVU= diff --git a/hooks/go/main.go b/hooks/go/main.go index c1424c0a..0c25ef58 100644 --- a/hooks/go/main.go +++ b/hooks/go/main.go @@ -1,10 +1,10 @@ package main import ( + _ "github.com/deckhouse/csi-ceph/hooks/go/020-webhook-certs" + _ "github.com/deckhouse/csi-ceph/hooks/go/030-remove-sc-and-secrets-on-module-delete" + _ "github.com/deckhouse/csi-ceph/hooks/go/060-migrate-from-ceph-csi-module" "github.com/deckhouse/module-sdk/pkg/app" - - _ "csi-ceph/060-migrate-from-ceph-csi-module" - _ "csi-ceph/070-remove-finalizers-on-module-delete" ) func main() { diff --git a/hooks/lib/__init__.py b/hooks/lib/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/hooks/lib/certificate/__init__.py b/hooks/lib/certificate/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/hooks/lib/certificate/certificate.py b/hooks/lib/certificate/certificate.py deleted file mode 100644 index 10a06619..00000000 --- a/hooks/lib/certificate/certificate.py +++ /dev/null @@ -1,265 +0,0 @@ -# -# Copyright 2023 Flant JSC -# -# 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. - -import random -import re -from OpenSSL import crypto -from ipaddress import ip_address -from datetime import datetime, timedelta -from lib.certificate.parse import parse_certificate, get_certificate_san - -class Certificate: - def __init__(self, cn: str, expire: int, key_size: int, algo: str) -> None: - self.key = crypto.PKey() - self.__with_key(algo=algo, size=key_size) - self.cert = crypto.X509() - self.cert.set_version(version=2) - self.cert.get_subject().CN = cn - self.cert.set_serial_number(random.getrandbits(64)) - self.cert.gmtime_adj_notBefore(0) - self.cert.gmtime_adj_notAfter(expire) - - def get_subject(self) -> crypto.X509Name: - return self.cert.get_subject() - - def __with_key(self, algo: str, size: int) -> None: - if algo == "rsa": - self.key.generate_key(crypto.TYPE_RSA, size) - elif algo == "dsa": - self.key.generate_key(crypto.TYPE_DSA, size) - else: - raise Exception(f"Algo {algo} is not support. Only [rsa, dsa]") - - def with_metadata(self, country: str = None, - state: str = None, - locality: str = None, - organisation_name: str = None, - organisational_unit_name: str = None): - """ - Adds subjects to certificate. - - :param country: Optional. The country of the entity. - :type country: :py:class:`str` - - :param state: Optional. The state or province of the entity. - :type state: :py:class:`str` - - :param locality: Optional. The locality of the entity - :type locality: :py:class:`str` - - :param organisation_name: Optional. The organization name of the entity. - :type organisation_name: :py:class:`str` - - :param organisational_unit_name: Optional. The organizational unit of the entity. - :type organisational_unit_name: :py:class:`str` - """ - - if country is not None: - self.cert.get_subject().C = country - if state is not None: - self.cert.get_subject().ST = state - if locality is not None: - self.cert.get_subject().L = locality - if organisation_name is not None: - self.cert.get_subject().O = organisation_name - if organisational_unit_name is not None: - self.cert.get_subject().OU = organisational_unit_name - return self - - def add_extension(self, type_name: str, - critical: bool, - value: str, - subject: crypto.X509 = None, - issuer: crypto.X509 = None): - """ - Adds extensions to certificate. - :param type_name: The name of the type of extension_ to create. - :type type_name: :py:class:`str` - - :param critical: A flag indicating whether this is a critical - extension. - :type critical: :py:class:`bool` - - :param value: The OpenSSL textual representation of the extension's - value. - :type value: :py:class:`str` - - :param subject: Optional X509 certificate to use as subject. - :type subject: :py:class:`crypto.X509` - - :param issuer: Optional X509 certificate to use as issuer. - :type issuer: :py:class:`crypto.X509` - """ - ext = crypto.X509Extension(type_name=str.encode(type_name), - critical=critical, - value=str.encode(value), - subject=subject, - issuer=issuer) - self.cert.add_extensions(extensions=[ext]) - return self - - def generate(self) -> (bytes, bytes): - """ - Generate certificate. - :return: (certificate, key) - :rtype: (:py:data:`bytes`, :py:data:`bytes`) - """ - pub = crypto.dump_certificate(crypto.FILETYPE_PEM, self.cert) - priv = crypto.dump_privatekey(crypto.FILETYPE_PEM, self.key) - return pub, priv - - -class CACertificateGenerator(Certificate): - """ - A class representing a generator CA certificate. - """ - def __sign(self) -> None: - self.cert.set_issuer(self.get_subject()) - self.cert.set_pubkey(self.key) - self.cert.sign(self.key, 'sha256') - - def generate(self) -> (bytes, bytes): - """ - Generate CA certificate. - :return: (ca crt, ca key) - :rtype: (:py:data:`bytes`, :py:data:`bytes`) - """ - self.add_extension(type_name="subjectKeyIdentifier", - critical=False, value="hash", subject=self.cert) - self.add_extension(type_name="authorityKeyIdentifier", - critical=False, value="keyid:always", issuer=self.cert) - self.add_extension(type_name="basicConstraints", - critical=False, value="CA:TRUE") - self.add_extension(type_name="keyUsage", critical=False, - value="keyCertSign, cRLSign, keyEncipherment") - self.__sign() - return super().generate() - - -class CertificateGenerator(Certificate): - """ - A class representing a generator certificate. - """ - def with_hosts(self, *hosts: str): - """ - This function is used to add subject alternative names to a certificate. - It takes a variable number of hosts as parameters, and based on the type of host (IP or DNS). - - :param hosts: Variable number of hosts to be added as subject alternative names to the certificate. - :type hosts: :py:class:`tuple` - """ - alt_names = [] - for h in hosts: - try: - ip_address(h) - alt_names.append(f"IP:{h}") - except ValueError: - if not is_valid_hostname(h): - continue - alt_names.append(f"DNS:{h}") - self.add_extension("subjectAltName", False, ", ".join(alt_names)) - return self - - def __sign(self, ca_subj: crypto.X509Name, ca_key: crypto.PKey) -> None: - self.cert.set_issuer(ca_subj) - self.cert.set_pubkey(self.key) - self.cert.sign(ca_key, 'sha256') - - def generate(self, ca_subj: crypto.X509Name, ca_key: crypto.PKey) -> (bytes, bytes): - """ - Generate certificate. - :param ca_subj: CA subject. - :type ca_subj: :py:class:`crypto.X509Name` - :param ca_key: CA Key. - :type ca_key: :py:class:`crypto.PKey` - :return: (certificate, key) - :rtype: (:py:data:`bytes`, :py:data:`bytes`) - """ - self.__sign(ca_subj, ca_key) - return super().generate() - -def is_valid_hostname(hostname: str) -> bool: - if len(hostname) > 255: - return False - hostname.rstrip(".") - allowed = re.compile("(?!-)[A-Z\d-]{1,63}(? bool: - """ - Check certificate - :param crt: Certificate - :type crt: :py:class:`crypto.X509` - :param cert_outdated_duration: certificate outdated duration - :type cert_outdated_duration: :py:class:`timedelta` - :return: - if timeNow > expire - cert_outdated_duration: - return True - return False - :rtype: :py:class:`bool` - """ - not_after = datetime.strptime( - crt.get_notAfter().decode('ascii'), '%Y%m%d%H%M%SZ') - if datetime.now() > not_after - cert_outdated_duration: - return True - return False - - -def is_outdated_ca(ca: str, cert_outdated_duration: timedelta) -> bool: - """ - Issue a new certificate if there is no CA in the secret. Without CA it is not possible to validate the certificate. - Check CA duration. - :param ca: Raw CA - :type ca: :py:class:`str` - :param cert_outdated_duration: certificate outdated duration - :type cert_outdated_duration: :py:class:`timedelta` - :rtype: :py:class:`bool` - """ - if len(ca) == 0: - return True - crt = parse_certificate(ca) - return cert_renew_deadline_exceeded(crt, cert_outdated_duration) - - -def is_irrelevant_cert(crt_data: str, sans: list, cert_outdated_duration: timedelta) -> bool: - """ - Check certificate duration and SANs list - :param crt_data: Raw certificate - :type crt_data: :py:class:`str` - :param sans: List of sans. - :type sans: :py:class:`list` - :param cert_outdated_duration: certificate outdated duration - :type cert_outdated_duration: :py:class:`timedelta` - :rtype: :py:class:`bool` - """ - if len(crt_data) == 0: - return True - crt = parse_certificate(crt_data) - if cert_renew_deadline_exceeded(crt, cert_outdated_duration): - return True - alt_names = [] - for san in sans: - try: - ip_address(san) - alt_names.append(f"IP Address:{san}") - except ValueError: - alt_names.append(f"DNS:{san}") - cert_sans = get_certificate_san(crt) - cert_sans.sort() - alt_names.sort() - if cert_sans != alt_names: - return True - return False \ No newline at end of file diff --git a/hooks/lib/certificate/parse.py b/hooks/lib/certificate/parse.py deleted file mode 100644 index fd88c0d8..00000000 --- a/hooks/lib/certificate/parse.py +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright 2023 Flant JSC -# -# 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 OpenSSL import crypto -from pprint import pprint - - -def parse_certificate(crt: str) -> crypto.X509: - return crypto.load_certificate(crypto.FILETYPE_PEM, crt) - - -def get_certificate_san(crt: crypto.X509) -> list[str]: - san = '' - ext_count = crt.get_extension_count() - for i in range(0, ext_count): - ext = crt.get_extension(i) - if 'subjectAltName' in str(ext.get_short_name()): - san = ext.__str__() - return san.split(', ') diff --git a/hooks/lib/hooks/__init__.py b/hooks/lib/hooks/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/hooks/lib/hooks/copy_custom_certificate.py b/hooks/lib/hooks/copy_custom_certificate.py deleted file mode 100644 index b3f3e835..00000000 --- a/hooks/lib/hooks/copy_custom_certificate.py +++ /dev/null @@ -1,84 +0,0 @@ -# -# Copyright 2023 Flant JSC -# -# 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 deckhouse import hook -from typing import Callable -from lib.module import module -from lib.hooks.hook import Hook - -class CopyCustomCertificatesHook(Hook): - CUSTOM_CERTIFICATES_SNAPSHOT_NAME = "custom_certificates" - def __init__(self, - module_name: str = None): - super().__init__(module_name=module_name) - self.queue = f"/modules/{self.module_name}/copy-custom-certificates" - - def generate_config(self) -> dict: - return { - "configVersion": "v1", - "beforeHelm": 10, - "kubernetes": [ - { - "name": self.CUSTOM_CERTIFICATES_SNAPSHOT_NAME, - "apiVersion": "v1", - "kind": "Secret", - "labelSelector": { - "matchExpressions": [ - { - "key": "owner", - "operator": "NotIn", - "values": ["helm"] - } - ] - }, - "namespace": { - "nameSelector": { - "matchNames": ["d8-system"] - } - }, - "includeSnapshotsFrom": [self.CUSTOM_CERTIFICATES_SNAPSHOT_NAME], - "jqFilter": '{"name": .metadata.name, "data": .data}', - "queue": self.queue, - "keepFullObjectsInMemory": False - }, - ] - } - - def reconcile(self) -> Callable[[hook.Context], None]: - def r(ctx: hook.Context) -> None: - custom_certificates = {} - for s in ctx.snapshots.get(self.CUSTOM_CERTIFICATES_SNAPSHOT_NAME, []): - custom_certificates[s["filterResult"]["name"]] = s["filterResult"]["data"] - if len(custom_certificates) == 0: - return - - https_mode = module.get_https_mode(module_name=self.module_name, - values=ctx.values) - path = f"{self.module_name}.internal.customCertificateData" - if https_mode != "CustomCertificate": - self.delete_value(path, ctx.values) - return - - raw_secret_name = module.get_values_first_defined(ctx.values, - f"{self.module_name}.https.customCertificate.secretName", - "global.modules.https.customCertificate.secretName") - secret_name = str(raw_secret_name or "") - secret_data = custom_certificates.get(secret_name) - if secret_data is None: - print( - f"Custom certificate secret name is configured, but secret d8-system/{secret_name} doesn't exist") - return - self.set_value(path, ctx.values, secret_data) - return r \ No newline at end of file diff --git a/hooks/lib/hooks/hook.py b/hooks/lib/hooks/hook.py deleted file mode 100644 index e412faec..00000000 --- a/hooks/lib/hooks/hook.py +++ /dev/null @@ -1,56 +0,0 @@ -# -# Copyright 2023 Flant JSC -# -# 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 deckhouse import hook -from typing import Callable -from lib.module import module -from lib.module import values as module_values -import yaml - -class Hook: - def __init__(self, module_name: str = None) -> None: - self.module_name = self.get_module_name(module_name) - - def generate_config(self): - pass - - @staticmethod - def get_value(path: str, values: dict, default=None): - return module_values.get_value(path, values, default) - - @staticmethod - def set_value(path: str, values: dict, value: str) -> None: - return module_values.set_value(path, values, value) - - @staticmethod - def delete_value(path: str, values: dict) -> None: - return module_values.delete_value(path, values) - - @staticmethod - def get_module_name(module_name: str) -> str: - if module_name is not None: - return module_name - return module.get_module_name() - - def reconcile(self) -> Callable[[hook.Context], None]: - def r(ctx: hook.Context) -> None: - pass - return r - - def run(self) -> None: - conf = self.generate_config() - if isinstance(conf, dict): - conf = yaml.dump(conf) - hook.run(func=self.reconcile(), config=conf) diff --git a/hooks/lib/hooks/internal_tls.py b/hooks/lib/hooks/internal_tls.py deleted file mode 100644 index 3b351c65..00000000 --- a/hooks/lib/hooks/internal_tls.py +++ /dev/null @@ -1,434 +0,0 @@ -# -# Copyright 2023 Flant JSC -# -# 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 deckhouse import hook -from datetime import timedelta -from OpenSSL import crypto -from typing import Callable -from lib.hooks.hook import Hook -import lib.utils as utils -import lib.certificate.certificate as certificate - -PUBLIC_DOMAIN_PREFIX = "%PUBLIC_DOMAIN%://" -CLUSTER_DOMAIN_PREFIX = "%CLUSTER_DOMAIN%://" - - -KEY_USAGES = { - 0: "digitalSignature", - 1: "nonRepudiation", - 2: "keyEncipherment", - 3: "dataEncipherment", - 4: "keyAgreement", - 5: "keyCertSign", - 6: "cRLSign", - 7: "encipherOnly", - 8: "decipherOnly" -} - -EXTENDED_KEY_USAGES = { - 0: "serverAuth", - 1: "clientAuth", - 2: "codeSigning", - 3: "emailProtection", - 4: "OCSPSigning" -} - -class TlsSecret: - def __init__(self, - cn: str, - name: str, - sansGenerator: Callable[[list[str]], Callable[[hook.Context], list[str]]], - values_path_prefix: str, - key_usages: list[str] = [KEY_USAGES[2], KEY_USAGES[5]], - extended_key_usages: list[str] = [EXTENDED_KEY_USAGES[0]]): - self.cn = cn - self.name = name - self.sansGenerator = sansGenerator - self.values_path_prefix = values_path_prefix - self.key_usages = key_usages - self.extended_key_usages = extended_key_usages - -class GenerateCertificateHook(Hook): - """ - Config for the hook that generates certificates. - """ - SNAPSHOT_SECRETS_NAME = "secrets" - SNAPSHOT_SECRETS_CHECK_NAME = "secretsCheck" - - def __init__(self, *tls_secrets: TlsSecret, - cn: str, - namespace: str, - module_name: str = None, - common_ca: bool = False, - before_hook_check: Callable[[hook.Context], bool] = None, - expire: int = 31536000, - key_size: int = 4096, - algo: str = "rsa", - cert_outdated_duration: timedelta = timedelta(days=30), - country: str = None, - state: str = None, - locality: str = None, - organisation_name: str = None, - organisational_unit_name: str = None) -> None: - super().__init__(module_name=module_name) - self.cn = cn - self.tls_secrets = tls_secrets - self.namespace = namespace - self.common_ca = common_ca - self.before_hook_check = before_hook_check - self.expire = expire - self.key_size = key_size - self.algo = algo - self.cert_outdated_duration = cert_outdated_duration - self.country = country - self.state = state - self.locality = locality - self.organisation_name = organisation_name - self.organisational_unit_name = organisational_unit_name - self.secret_names = [secret.name for secret in self.tls_secrets] - self.queue = f"/modules/{self.module_name}/generate-certs" - """ - :param module_name: Module name - :type module_name: :py:class:`str` - - :param cn: Certificate common Name. often it is module name - :type cn: :py:class:`str` - - :param sansGenerator: Function which returns list of domain to include into cert. Use default_sans - :type sansGenerator: :py:class:`function` - - :param namespace: Namespace for TLS secret. - :type namespace: :py:class:`str` - - :param tls_secret_name: TLS secret name. - Secret must be TLS secret type https://kubernetes.io/docs/concepts/configuration/secret/#tls-secrets. - CA certificate MUST set to ca.crt key. - :type tls_secret_name: :py:class:`str` - - :param values_path_prefix: Prefix full path to store CA certificate TLS private key and cert. - full paths will be - values_path_prefix + .`ca` - CA certificate - values_path_prefix + .`crt` - TLS private key - values_path_prefix + .`key` - TLS certificate - Example: values_path_prefix = 'virtualization.internal.dvcrCert' - Data in values store as plain text - :type values_path_prefix: :py:class:`str` - - :param key_usages: Optional. key_usages specifies valid usage contexts for keys. - :type key_usages: :py:class:`list` - - :param extended_key_usages: Optional. extended_key_usages specifies valid usage contexts for keys. - :type extended_key_usages: :py:class:`list` - - :param before_hook_check: Optional. Runs check function before hook execution. Function should return boolean 'continue' value - if return value is false - hook will stop its execution - if return value is true - hook will continue - :type before_hook_check: :py:class:`function` - - :param expire: Optional. Validity period of SSL certificates. - :type expire: :py:class:`int` - - :param key_size: Optional. Key Size. - :type key_size: :py:class:`int` - - :param algo: Optional. Key generation algorithm. Supports only rsa and dsa. - :type algo: :py:class:`str` - - :param cert_outdated_duration: Optional. (expire - cert_outdated_duration) is time to regenerate the certificate. - :type cert_outdated_duration: :py:class:`timedelta` - """ - - def generate_config(self) -> dict: - return { - "configVersion": "v1", - "beforeHelm": 5, - "kubernetes": [ - { - "name": self.SNAPSHOT_SECRETS_NAME, - "apiVersion": "v1", - "kind": "Secret", - "nameSelector": { - "matchNames": self.secret_names - }, - "namespace": { - "nameSelector": { - "matchNames": [self.namespace] - } - }, - "includeSnapshotsFrom": [self.SNAPSHOT_SECRETS_NAME], - "jqFilter": '{"name": .metadata.name, "data": .data}', - "queue": self.queue, - "keepFullObjectsInMemory": False - }, - ], - "schedule": [ - { - "name": self.SNAPSHOT_SECRETS_CHECK_NAME, - "crontab": "42 4 * * *" - } - ] - } - - def reconcile(self) -> Callable[[hook.Context], None]: - def r(ctx: hook.Context) -> None: - if self.before_hook_check is not None: - passed = self.before_hook_check(ctx) - if not passed: - return - - regenerate_all = False - secrets_from_snaps = {} - diff_secrets = [] - if len(ctx.snapshots.get(self.SNAPSHOT_SECRETS_NAME, [])) == 0: - regenerate_all = True - else: - for snap in ctx.snapshots[self.SNAPSHOT_SECRETS_NAME]: - secrets_from_snaps[snap["filterResult"]["name"]] = snap["filterResult"]["data"] - for secret in self.tls_secrets: - if secrets_from_snaps.get(secret.name) is None: - diff_secrets.append(secret.name) - - if self.common_ca and not regenerate_all: - if len(diff_secrets) > 0: - regenerate_all = True - else: - for secret in self.tls_secrets: - data = secrets_from_snaps[secret.name] - if self.is_outdated_ca(utils.base64_decode(data.get("ca.crt", ""))): - regenerate_all = True - break - sans = secret.sansGenerator(ctx) - if self.is_irrelevant_cert(utils.base64_decode(data.get("tls.crt", "")), sans): - regenerate_all = True - break - - if regenerate_all: - if self.common_ca: - ca = self.__get_ca_generator() - ca_crt, _ = ca.generate() - for secret in self.tls_secrets: - sans = secret.sansGenerator(ctx) - print(f"Generate new certififcates for secret {secret.name}.") - tls_data = self.generate_selfsigned_tls_data_with_ca(cn=secret.cn, - ca=ca, - ca_crt=ca_crt, - sans=sans, - key_usages=secret.key_usages, - extended_key_usages=secret.extended_key_usages) - self.set_value(secret.values_path_prefix, ctx.values, tls_data) - return - - for secret in self.tls_secrets: - sans = secret.sansGenerator(ctx) - print(f"Generate new certififcates for secret {secret.name}.") - tls_data = self.generate_selfsigned_tls_data(cn=secret.cn, - sans=sans, - key_usages=secret.key_usages, - extended_key_usages=secret.extended_key_usages) - self.set_value(secret.values_path_prefix, ctx.values, tls_data) - return - - for secret in self.tls_secrets: - data = secrets_from_snaps[secret.name] - sans = secret.sansGenerator(ctx) - cert_outdated = self.is_irrelevant_cert( - utils.base64_decode(data.get("tls.crt", "")), sans) - - tls_data = {} - if cert_outdated or data.get("tls.key", "") == "": - print(f"Certificates from secret {secret.name} is invalid. Generate new certififcates.") - tls_data = self.generate_selfsigned_tls_data(cn=secret.cn, - sans=sans, - key_usages=secret.key_usages, - extended_key_usages=secret.extended_key_usages) - else: - tls_data = { - "ca": data["ca.crt"], - "crt": data["tls.crt"], - "key": data["tls.key"] - } - self.set_value(secret.values_path_prefix, ctx.values, tls_data) - return r - - def __get_ca_generator(self) -> certificate.CACertificateGenerator: - return certificate.CACertificateGenerator(cn=f"{self.cn}", - expire=self.expire, - key_size=self.key_size, - algo=self.algo) - - def generate_selfsigned_tls_data_with_ca(self, - cn: str, - ca: certificate.CACertificateGenerator, - ca_crt: bytes, - sans: list[str], - key_usages: list[str], - extended_key_usages: list[str]) -> dict[str, str]: - """ - Generate self signed certificate. - :param cn: certificate common name. - :param ca: Ca certificate generator. - :type ca: :py:class:`certificate.CACertificateGenerator` - :param ca_crt: bytes. - :type ca_crt: :py:class:`bytes` - :param sans: List of sans. - :type sans: :py:class:`list` - :param key_usages: List of key_usages. - :type key_usages: :py:class:`list` - :param extended_key_usages: List of extended_key_usages. - :type extended_key_usages: :py:class:`list` - Example: { - "ca": "encoded in base64", - "crt": "encoded in base64", - "key": "encoded in base64" - } - :rtype: :py:class:`dict[str, str]` - """ - cert = certificate.CertificateGenerator(cn=cn, - expire=self.expire, - key_size=self.key_size, - algo=self.algo) - if len(key_usages) > 0: - key_usages = ", ".join(key_usages) - cert.add_extension(type_name="keyUsage", - critical=False, value=key_usages) - if len(extended_key_usages) > 0: - extended_key_usages = ", ".join(extended_key_usages) - cert.add_extension(type_name="extendedKeyUsage", - critical=False, value=extended_key_usages) - crt, key = cert.with_metadata(country=self.country, - state=self.state, - locality=self.locality, - organisation_name=self.organisation_name, - organisational_unit_name=self.organisational_unit_name - ).with_hosts(*sans).generate(ca_subj=ca.get_subject(), - ca_key=ca.key) - return {"ca": utils.base64_encode(ca_crt), - "crt": utils.base64_encode(crt), - "key": utils.base64_encode(key)} - - def generate_selfsigned_tls_data(self, - cn: str, - sans: list[str], - key_usages: list[str], - extended_key_usages: list[str]) -> dict[str, str]: - """ - Generate self signed certificate. - :param cn: certificate common name. - :param sans: List of sans. - :type sans: :py:class:`list` - :param key_usages: List of key_usages. - :type key_usages: :py:class:`list` - :param extended_key_usages: List of extended_key_usages. - :type extended_key_usages: :py:class:`list` - Example: { - "ca": "encoded in base64", - "crt": "encoded in base64", - "key": "encoded in base64" - } - :rtype: :py:class:`dict[str, str]` - """ - ca = self.__get_ca_generator() - ca_crt, _ = ca.generate() - return self.generate_selfsigned_tls_data_with_ca(cn=cn, - ca=ca, - ca_crt=ca_crt, - sans=sans, - key_usages=key_usages, - extended_key_usages=extended_key_usages) - - def is_irrelevant_cert(self, crt_data: str, sans: list) -> bool: - """ - Check certificate duration and SANs list - :param crt_data: Raw certificate - :type crt_data: :py:class:`str` - :param sans: List of sans. - :type sans: :py:class:`list` - :rtype: :py:class:`bool` - """ - return certificate.is_irrelevant_cert(crt_data, sans, self.cert_outdated_duration) - - def is_outdated_ca(self, ca: str) -> bool: - """ - Issue a new certificate if there is no CA in the secret. Without CA it is not possible to validate the certificate. - Check CA duration. - :param ca: Raw CA - :type ca: :py:class:`str` - :rtype: :py:class:`bool` - """ - return certificate.is_outdated_ca(ca, self.cert_outdated_duration) - - def cert_renew_deadline_exceeded(self, crt: crypto.X509) -> bool: - """ - Check certificate - :param crt: Certificate - :type crt: :py:class:`crypto.X509` - :return: - if timeNow > expire - cert_outdated_duration: - return True - return False - :rtype: :py:class:`bool` - """ - return certificate.cert_renew_deadline_exceeded(crt, self.cert_outdated_duration) - -def default_sans(sans: list[str]) -> Callable[[hook.Context], list[str]]: - """ - Generate list of sans for certificate - :param sans: List of alt names. - :type sans: :py:class:`list[str]` - cluster_domain_san(san) to generate sans with respect of cluster domain (e.g.: "app.default.svc" with "cluster.local" value will give: app.default.svc.cluster.local - - public_domain_san(san) - """ - def generate_sans(ctx: hook.Context) -> list[str]: - res = ["localhost", "127.0.0.1"] - public_domain = str(ctx.values["global"]["modules"].get( - "publicDomainTemplate", "")) - cluster_domain = str( - ctx.values["global"]["discovery"].get("clusterDomain", "")) - for san in sans: - san.startswith(PUBLIC_DOMAIN_PREFIX) - if san.startswith(PUBLIC_DOMAIN_PREFIX) and public_domain != "": - san = get_public_domain_san(san, public_domain) - elif san.startswith(CLUSTER_DOMAIN_PREFIX) and cluster_domain != "": - san = get_cluster_domain_san(san, cluster_domain) - res.append(san) - return res - return generate_sans - - -def cluster_domain_san(san: str) -> str: - """ - Create template to enrich specified san with a cluster domain - :param san: San. - :type sans: :py:class:`str` - """ - return CLUSTER_DOMAIN_PREFIX + san.rstrip('.') - - -def public_domain_san(san: str) -> str: - """ - Create template to enrich specified san with a public domain - :param san: San. - :type sans: :py:class:`str` - """ - return PUBLIC_DOMAIN_PREFIX + san.rstrip('.') - - -def get_public_domain_san(san: str, public_domain: str) -> str: - return f"{san.lstrip(PUBLIC_DOMAIN_PREFIX)}.{public_domain}" - - -def get_cluster_domain_san(san: str, cluster_domain: str) -> str: - return f"{san.lstrip(CLUSTER_DOMAIN_PREFIX)}.{cluster_domain}" diff --git a/hooks/lib/hooks/manage_tenant_secrets.py b/hooks/lib/hooks/manage_tenant_secrets.py deleted file mode 100644 index 36d817b4..00000000 --- a/hooks/lib/hooks/manage_tenant_secrets.py +++ /dev/null @@ -1,140 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2023 Flant JSC -# -# 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 deckhouse import hook -from typing import Callable -from lib.hooks.hook import Hook - -class ManageTenantSecretsHook(Hook): - POD_SNAPSHOT_NAME = "pods" - SECRETS_SNAPSHOT_NAME = "secrets" - NAMESPACE_SNAPSHOT_NAME = "namespaces" - - def __init__(self, - source_namespace: str, - source_secret_name: str, - pod_labels_to_follow: dict, - destination_secret_labels: dict = {}, - module_name: str = None): - super().__init__(module_name=module_name) - self.source_namespace = source_namespace - self.source_secret_name = source_secret_name - self.pod_labels_to_follow = pod_labels_to_follow - self.destination_secret_labels = destination_secret_labels - self.module_name = module_name - self.queue = f"/modules/{module_name}/manage-tenant-secrets" - - def generate_config(self) -> dict: - return { - "configVersion": "v1", - "kubernetes": [ - { - "name": self.POD_SNAPSHOT_NAME, - "apiVersion": "v1", - "kind": "Pod", - "includeSnapshotsFrom": [ - self.POD_SNAPSHOT_NAME, - self.SECRETS_SNAPSHOT_NAME, - self.NAMESPACE_SNAPSHOT_NAME - ], - "labelSelector": { - "matchLabels": self.pod_labels_to_follow - }, - "jqFilter": '{"namespace": .metadata.namespace}', - "queue": self.queue, - "keepFullObjectsInMemory": False - }, - { - "name": self.SECRETS_SNAPSHOT_NAME, - "apiVersion": "v1", - "kind": "Secret", - "includeSnapshotsFrom": [ - self.POD_SNAPSHOT_NAME, - self.SECRETS_SNAPSHOT_NAME, - self.NAMESPACE_SNAPSHOT_NAME - ], - "nameSelector": { - "matchNames": [self.source_secret_name] - }, - "jqFilter": '{"data": .data, "namespace": .metadata.namespace, "type": .type}', - "queue": self.queue, - "keepFullObjectsInMemory": False - }, - { - "name": self.NAMESPACE_SNAPSHOT_NAME, - "apiVersion": "v1", - "kind": "Secret", - "includeSnapshotsFrom": [ - self.POD_SNAPSHOT_NAME, - self.SECRETS_SNAPSHOT_NAME, - self.NAMESPACE_SNAPSHOT_NAME - ], - "jqFilter": '{"name": .metadata.name, "isTerminating": any(.metadata; .deletionTimestamp != null)}', - "queue": self.queue, - "keepFullObjectsInMemory": False - } - ] - } - - def generate_secret(self, namespace: str, data: dict, secret_type: str) -> dict: - return { - "apiVersion": "v1", - "kind": "Secret", - "metadata": { - "name": self.source_secret_name, - "namespace": namespace, - "labels": self.destination_secret_labels - }, - "data": data, - "type": secret_type - } - - def reconcile(self) -> Callable[[hook.Context], None]: - def r(ctx: hook.Context) -> None: - pod_namespaces = set([p["filterResult"]["namespace"] for p in ctx.snapshots.get(self.POD_SNAPSHOT_NAME, [])]) - secrets = ctx.snapshots.get(self.SECRETS_SNAPSHOT_NAME, []) - for ns in ctx.snapshots.get(self.NAMESPACE_SNAPSHOT_NAME, []): - if ns["filterResult"]["isTerminating"]: - pod_namespaces.discard(ns["filterResult"]["name"]) - data, secret_type, secrets_by_ns = "", "", {} - for s in secrets: - if s["filterResult"]["namespace"] == self.source_namespace: - data = s["filterResult"]["data"] - secret_type = s["filterResult"]["type"] - continue - secrets_by_ns[s["filterResult"]["namespace"]] = s["filterResult"]["data"] - - if len(data) == 0 or len(secret_type) == 0: - print(f"Registry secret {self.source_namespace}/{self.source_secret_name} not found. Skip") - return - - for ns in pod_namespaces: - secret_data = secrets_by_ns.get(ns, "") - if (secret_data != data) and (ns != self.source_namespace): - secret = self.generate_secret(namespace=ns, - data=data, - secret_type=secret_type) - print(f"Create secret {ns}/{self.source_secret_name}.") - ctx.kubernetes.create_or_update(secret) - for ns in secrets_by_ns: - if (ns in pod_namespaces) or (ns == self.source_namespace): - continue - print(f"Delete secret {ns}/{self.source_secret_name}.") - ctx.kubernetes.delete(kind="Secret", - namespace=ns, - name=self.source_secret_name) - return r - diff --git a/hooks/lib/module/__init__.py b/hooks/lib/module/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/hooks/lib/module/module.py b/hooks/lib/module/module.py deleted file mode 100644 index 6dd746c7..00000000 --- a/hooks/lib/module/module.py +++ /dev/null @@ -1,38 +0,0 @@ -# -# Copyright 2023 Flant JSC -# -# 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 lib.module import values as module_values -import re -import os - -def get_values_first_defined(values: dict, *keys): - return _get_first_defined(values, keys) - -def _get_first_defined(values: dict, keys: tuple): - for i in range(len(keys)): - if (val := module_values.get_value(path=keys[i], values=values)) is not None: - return val - return - -def get_https_mode(module_name: str, values: dict) -> str: - module_path = f"{module_name}.https.mode" - global_path = "global.modules.https.mode" - https_mode = get_values_first_defined(values, module_path, global_path) - if https_mode is not None: - return str(https_mode) - raise Exception("https mode is not defined") - -def get_module_name() -> str: - return "csi-ceph" \ No newline at end of file diff --git a/hooks/lib/module/values.py b/hooks/lib/module/values.py deleted file mode 100644 index 449e4441..00000000 --- a/hooks/lib/module/values.py +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2023 Flant JSC -# -# 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. - -def get_value(path: str, values: dict, default=None): - def get(keys: list, values: dict, default): - if len(keys) == 1: - if not isinstance(values, dict): - return default - return values.get(keys[0], default) - if not isinstance(values, dict) or values.get(keys[0]) is None: - return default - if values.get(keys[0]) is None: - return default - return get(keys[1:], values[keys[0]], default) - keys = path.lstrip(".").split(".") - return get(keys, values, default) - -def set_value(path: str, values: dict, value) -> None: - """ - Functions for save value to dict. - - Example: - path = "virtualization.internal.dvcr.cert" - values = {"virtualization": {"internal": {}}} - value = "{"ca": "ca", "crt"="tlscrt", "key"="tlskey"}" - - result values = {"virtualization": {"internal": {"dvcr": {"cert": {"ca": "ca", "crt":"tlscrt", "key":"tlskey"}}}}} - """ - def set(keys: list, values: dict, value): - if len(keys) == 1: - values[keys[0]] = value - return - if values.get(keys[0]) is None: - values[keys[0]] = {} - set(keys[1:], values[keys[0]], value) - keys = path.lstrip(".").split(".") - return set(keys, values, value) - -def delete_value(path: str, values: dict) -> None: - if get_value(path, values) is None: - return - keys = path.lstrip(".").split(".") - def delete(keys: list, values: dict) -> None: - if len(keys) == 1: - values.pop(keys[0]) - return - delete(keys[1:], values[keys[0]]) - return delete(keys, values) \ No newline at end of file diff --git a/hooks/lib/password_generator/__init__.py b/hooks/lib/password_generator/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/hooks/lib/password_generator/password_generator.py b/hooks/lib/password_generator/password_generator.py deleted file mode 100644 index df63ea82..00000000 --- a/hooks/lib/password_generator/password_generator.py +++ /dev/null @@ -1,77 +0,0 @@ -# -# Copyright 2023 Flant JSC -# -# 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. - -import random -import string - -def generate_random_string(length: int, letters: str) -> str: - return ''.join(random.choice(letters) for i in range(length)) - -SYMBOLS = "[]{}<>()=-_!@#$%^&*.," - -def num(length: int) -> str: - """ - Generates a random string of the given length out of numeric characters. - :param length: length of generate string. - :type length: :py:class:`int` - :rtype: :py:class:`str` - """ - return generate_random_string(length, string.digits) - -def alpha(length: int) -> str: - """ - Generates a random string of the given length out of alphabetic characters. - :param length: length of generate string. - :type length: :py:class:`int` - :rtype: :py:class:`str` - """ - return generate_random_string(length, string.ascii_letters) - -def symbols(length: int) -> str: - """ - Generates a random string of the given length out of symbols. - :param length: length of generate string. - :type length: :py:class:`int` - :rtype: :py:class:`str` - """ - return generate_random_string(length, SYMBOLS) - - -def alpha_num(length: int) -> str: - """ - Generates a random string of the given length out of alphanumeric characters. - :param length: length of generate string. - :type length: :py:class:`int` - :rtype: :py:class:`str` - """ - return generate_random_string(length, string.ascii_letters + string.digits) - -def alpha_num_lower_case(length: int) -> str: - """ - Generates a random string of the given length out of alphanumeric characters without UpperCase letters. - :param length: length of generate string. - :type length: :py:class:`int` - :rtype: :py:class:`str` - """ - return generate_random_string(length, string.ascii_lowercase + string.digits) - -def alpha_num_symbols(length: int) -> str: - """ - Generates a random string of the given length out of alphanumeric characters and symbols. - :param length: length of generate string. - :type length: :py:class:`int` - :rtype: :py:class:`str` - """ - return generate_random_string(length, string.ascii_letters + string.digits + SYMBOLS) diff --git a/hooks/lib/tests/__init__.py b/hooks/lib/tests/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/hooks/lib/tests/test_copy_custom_certificate.py b/hooks/lib/tests/test_copy_custom_certificate.py deleted file mode 100644 index c10e9c95..00000000 --- a/hooks/lib/tests/test_copy_custom_certificate.py +++ /dev/null @@ -1,110 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2023 Flant JSC -# -# 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 lib.tests import testing -from lib.hooks.copy_custom_certificate import CopyCustomCertificatesHook - - -MODULE_NAME = "test" -SECRET_NAME = "secretName" -SECRET_DATA = { - "ca.crt": "CACRT", - "tls.crt": "TLSCRT", - "tls.key": "TLSKEY" - } - -hook = CopyCustomCertificatesHook(module_name=MODULE_NAME) - -binding_context = [ - { - "binding": "binding", - "snapshots": { - hook.CUSTOM_CERTIFICATES_SNAPSHOT_NAME: [ - { - "filterResult": { - "name": SECRET_NAME, - "data": SECRET_DATA - } - }, - { - "filterResult": { - "name": "test", - "data": {} - } - } - ] - } - } -] - -values_add = { - "global": { - "modules": { - "https": { - "mode": "CustomCertificate", - "customCertificate": { - "secretName": "test" - } - } - } - }, - MODULE_NAME: { - "https": { - "customCertificate": { - "secretName": SECRET_NAME - } - }, - "internal": {} - } -} - - -values_delete = { - "global": { - "modules": { - "https": { - "mode": "CertManager" - } - } - }, - MODULE_NAME: { - "internal": { - "customCertificateData": SECRET_DATA - } - } -} - - -class TestCopyCustomCertificateAdd(testing.TestHook): - def setUp(self): - self.func = hook.reconcile() - self.bindind_context = binding_context - self.values = values_add - def test_copy_custom_certificate_adding(self): - self.hook_run() - self.assertGreater(len(self.values[MODULE_NAME]["internal"].get("customCertificateData", {})), 0) - self.assertEqual(self.values[MODULE_NAME]["internal"]["customCertificateData"], SECRET_DATA) - -class TestCopyCustomCertificateDelete(testing.TestHook): - def setUp(self): - self.func = hook.reconcile() - self.bindind_context = binding_context - self.values = values_delete - def test_copy_custom_certificate_deleting(self): - self.hook_run() - self.assertEqual(len(self.values[MODULE_NAME]["internal"].get("customCertificateData", {})), 0) - - diff --git a/hooks/lib/tests/test_internal_tls_test.py b/hooks/lib/tests/test_internal_tls_test.py deleted file mode 100644 index de842cdd..00000000 --- a/hooks/lib/tests/test_internal_tls_test.py +++ /dev/null @@ -1,159 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2023 Flant JSC -# -# 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 lib.tests import testing -from lib.hooks.internal_tls import GenerateCertificateHook, default_sans, TlsSecret -from lib.certificate import parse -import lib.utils as utils -from OpenSSL import crypto -from ipaddress import ip_address - -NAME = "test" -MODULE_NAME = NAME -NAMESPACE = NAME -SANS = [ - NAME, - f"{NAME}.{NAMESPACE}", - f"{NAME}.{NAMESPACE}.svc" -] - -hook_generate = GenerateCertificateHook( - TlsSecret( - name=NAME, - sansGenerator=default_sans(SANS), - values_path_prefix=f"{MODULE_NAME}.internal.dvcr.cert"), - module_name=MODULE_NAME, - cn=NAME, - namespace=NAMESPACE) - -hook_regenerate = GenerateCertificateHook( - TlsSecret( - name=NAME, - sansGenerator=default_sans(SANS), - values_path_prefix=f"{MODULE_NAME}.internal.dvcr.cert"), - module_name=MODULE_NAME, - cn=NAME, - namespace=NAMESPACE, - expire=0) - -binding_context = [ - { - "binding": "binding", - "snapshots": {} - } -] - -values = { - "global": { - "modules": { - "publicDomainTemplate": "example.com" - }, - "discovery": { - "clusterDomain": "cluster.local" - } - }, - MODULE_NAME: { - "internal": {} - } -} - -class TestCertificate(testing.TestHook): - secret_data = {} - sans_default = SANS + ["localhost", "127.0.0.1"] - - @staticmethod - def parse_certificate(crt: str) -> crypto.X509: - return parse.parse_certificate(utils.base64_decode(crt)) - - def check_data(self): - self.assertGreater(len(self.values[MODULE_NAME]["internal"].get("dvcr", {}).get("cert", {})), 0) - self.secret_data = self.values[MODULE_NAME]["internal"]["dvcr"]["cert"] - self.assertTrue(utils.is_base64(self.secret_data.get("ca", ""))) - self.assertTrue(utils.is_base64(self.secret_data.get("crt", ""))) - self.assertTrue(utils.is_base64(self.secret_data.get("key", ""))) - - def check_sans(self, crt: crypto.X509) -> bool: - sans_from_cert = parse.get_certificate_san(crt) - sans = [] - for san in self.sans_default: - try: - ip_address(san) - sans.append(f"IP Address:{san}") - except ValueError: - sans.append(f"DNS:{san}") - sans_from_cert.sort() - sans.sort() - self.assertEqual(sans_from_cert, sans) - - def verify_certificate(self, ca: crypto.X509, crt: crypto.X509) -> crypto.X509StoreContextError: - store = crypto.X509Store() - store.add_cert(ca) - ctx = crypto.X509StoreContext(store, crt) - try: - ctx.verify_certificate() - return None - except crypto.X509StoreContextError as e: - return e - -class TestGenerateCertificate(TestCertificate): - def setUp(self): - self.func = hook_generate.reconcile() - self.bindind_context = binding_context - self.values = values - def test_generate_certificate(self): - self.hook_run() - self.check_data() - ca = self.parse_certificate(self.secret_data["ca"]) - crt = self.parse_certificate(self.secret_data["crt"]) - if (e := self.verify_certificate(ca, crt)) is not None: - self.fail(f"Certificate is not verify. Raised an exception: {e} ") - self.check_sans(crt) - -class TestReGenerateCertificate(TestCertificate): - def setUp(self): - self.func = hook_regenerate.reconcile() - self.bindind_context = binding_context - self.values = values - self.hook_run() - self.bindind_context[0]["snapshots"] = { - hook_regenerate.SNAPSHOT_SECRETS_NAME : [ - { - "filterResult": { - "data": { - "ca.crt" : self.values[MODULE_NAME]["internal"]["dvcr"]["cert"]["ca"], - "tls.crt": self.values[MODULE_NAME]["internal"]["dvcr"]["cert"]["crt"], - "key.crt": self.values[MODULE_NAME]["internal"]["dvcr"]["cert"]["key"] - }, - "name": NAME - } - } - ] - } - self.func = hook_generate.reconcile() - - def test_regenerate_certificate(self): - self.check_data() - ca = self.parse_certificate(self.secret_data["ca"]) - crt = self.parse_certificate(self.secret_data["crt"]) - if self.verify_certificate(ca, crt) is None: - self.fail(f"certificate has not expired") - self.hook_run() - self.check_data() - ca = self.parse_certificate(self.secret_data["ca"]) - crt = self.parse_certificate(self.secret_data["crt"]) - if (e := self.verify_certificate(ca, crt)) is not None: - self.fail(f"Certificate is not verify. Raised an exception: {e} ") - self.check_sans(crt) diff --git a/hooks/lib/tests/test_manage_tenant_secrets.py b/hooks/lib/tests/test_manage_tenant_secrets.py deleted file mode 100644 index 8e770599..00000000 --- a/hooks/lib/tests/test_manage_tenant_secrets.py +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2023 Flant JSC -# -# 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 lib.tests import testing -from lib.hooks.manage_tenant_secrets import ManageTenantSecretsHook - -hook = ManageTenantSecretsHook(source_namespace="source_namespace", - source_secret_name="secret_name", - pod_labels_to_follow={"app": "test"}, - destination_secret_labels={"test":"test"}, - module_name="test") - -binding_context = [ - { - "binding": "binding", - "snapshots": { - hook.POD_SNAPSHOT_NAME: [ - { - "filterResult": { - "namespace": "pod-namespace1" ## Create secret - } - }, - { - "filterResult": { - "namespace": "pod-namespace2" ## Don't create secret, because ns has deletionTimestamp - } - } - ], - hook.SECRETS_SNAPSHOT_NAME: [ - { - "filterResult": { - "data": {"test": "test"}, - "namespace": "source_namespace", - "type": "Opaque" - } - }, - { - "filterResult": { - "data": {"test": "test"}, - "namespace": "pod-namespace3", ## Delete secret, because namespace pod-namespace3 hasn't pods - "type": "Opaque" - } - }, - ], - hook.NAMESPACE_SNAPSHOT_NAME: [ - { - "filterResult": { - "name": "source_namespace", - "isTerminating": False - } - }, - { - "filterResult": { - "name": "pod-namespace1", - "isTerminating": False - } - }, - { - "filterResult": { - "name": "pod-namespace2", - "isTerminating": True - } - }, - { - "filterResult": { - "name": "pod-namespace3", - "isTerminating": False - } - }, - ] - } - } -] - -class TestManageSecrets(testing.TestHook): - def setUp(self): - self.func = hook.reconcile() - self.bindind_context = binding_context - self.values = {} - def test_manage_secrets(self): - self.hook_run() - self.assertEqual(len(self.kube_resources), 1) - self.assertEqual(self.kube_resources[0]["kind"], "Secret") - self.assertEqual(self.kube_resources[0]["metadata"]["name"], "secret_name") - self.assertEqual(self.kube_resources[0]["metadata"]["namespace"], "pod-namespace1") - self.assertEqual(self.kube_resources[0]["type"], "Opaque") - self.assertEqual(self.kube_resources[0]["data"], {'test': 'test'}) - self.assertEqual(self.kube_resources[0]["metadata"]["labels"], {'test': 'test'}) - diff --git a/hooks/lib/tests/testing.py b/hooks/lib/tests/testing.py deleted file mode 100644 index f0257aa2..00000000 --- a/hooks/lib/tests/testing.py +++ /dev/null @@ -1,57 +0,0 @@ -# -# Copyright 2023 Flant JSC -# -# 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 deckhouse import hook -import unittest -import jsonpatch -import kubernetes_validate -import jsonschema - -class TestHook(unittest.TestCase): - kube_resources = [] - kube_version = "1.28" - def setUp(self): - self.bindind_context = [] - self.values = {} - self.func = None - - def tearDown(self): - pass - - def hook_run(self, validate_kube_resources: bool = True) -> None: - out = hook.testrun(func=self.func, - binding_context=self.bindind_context, - initial_values=self.values) - for patch in out.values_patches.data: - self.values = jsonpatch.apply_patch(self.values, [patch]) - - deletes = ("Delete", "DeleteInBackground", "DeleteNonCascading") - for kube_operation in out.kube_operations.data: - if kube_operation["operation"] in deletes: - continue - obj = kube_operation["object"] - if validate_kube_resources: - try: - ## TODO Validate CRD - kubernetes_validate.validate(obj, self.kube_version, strict=True) - self.kube_resources.append(obj) - except (kubernetes_validate.SchemaNotFoundError, - kubernetes_validate.InvalidSchemaError, - kubernetes_validate.ValidationError, - jsonschema.RefResolutionError) as e: - self.fail(f"Object is not valid. Raised an exception: {e} ") - else: - self.kube_resources.append(obj) - diff --git a/hooks/lib/utils.py b/hooks/lib/utils.py deleted file mode 100644 index a486efd5..00000000 --- a/hooks/lib/utils.py +++ /dev/null @@ -1,54 +0,0 @@ -# -# Copyright 2023 Flant JSC -# -# 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. - -import base64 -import os -import json - -def base64_encode(b: bytes) -> str: - return str(base64.b64encode(b), encoding='utf-8') - -def base64_decode(s: str) -> str: - return str(base64.b64decode(s), encoding="utf-8") - -def base64_encode_from_str(s: str) -> str: - return base64_encode(bytes(s, 'utf-8')) - -def json_load(path: str): - with open(path, "r", encoding="utf-8") as f: - data = json.load(f) - return data - -def get_dir_path() -> str: - return os.path.dirname(os.path.abspath(__file__)) - -def is_base64(s): - try: - base64_decode(s) - return True - except base64.binascii.Error: - return False - -def check_elem_in_list(l: list, elem) -> bool: - for i in l: - if i == elem: - return True - return False - -def find_index_in_list(l: list, elem) -> int: - for i in range(len(l)): - if l[i] == elem: - return i - return \ No newline at end of file diff --git a/hooks/remove_sc_and_secrets_on_module_delete.py b/hooks/remove_sc_and_secrets_on_module_delete.py deleted file mode 100755 index 13e3fab5..00000000 --- a/hooks/remove_sc_and_secrets_on_module_delete.py +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2024 Flant JSC -# -# 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. - -import os - -import yaml -import kubernetes -from deckhouse import hook - -config = """ -configVersion: v1 -afterDeleteHelm: 10 -""" - -namespace_name = 'd8-csi-ceph' -provisioner_names = ['cephfs.csi.ceph.com', 'rbd.csi.ceph.com'] - - -def main(ctx: hook.Context): - kubernetes.config.load_incluster_config() - secrets = kubernetes.client.CoreV1Api().list_namespaced_secret(namespace_name) - for item in secrets.items: - print(f"remove_sc_and_secrets.py: Removing finalizers from {item.metadata.name} secret") - - kubernetes.client.CoreV1Api().patch_namespaced_secret(name=item.metadata.name, - namespace=namespace_name, - body={"metadata": {"finalizers": None}}) - - sc_objects = kubernetes.client.StorageV1Api().list_storage_class() - for item in sc_objects.items: - if item.provisioner in provisioner_names: - print(f"remove_sc_and_secrets.py: Removing finalizers from {item.metadata.name} storage class") - kubernetes.client.StorageV1Api().patch_storage_class(name=item.metadata.name, - body={"metadata": {"finalizers": None}}) - print(f"remove_sc_and_secrets.py: Removing {item.metadata.name} storage class") - kubernetes.client.StorageV1Api().delete_storage_class(name=item.metadata.name) - - -if __name__ == "__main__": - hook.run(main, config=config) diff --git a/images/controller/src/cmd/main.go b/images/controller/cmd/main.go similarity index 94% rename from images/controller/src/cmd/main.go rename to images/controller/cmd/main.go index 02d31eeb..e1c105e9 100644 --- a/images/controller/src/cmd/main.go +++ b/images/controller/cmd/main.go @@ -22,12 +22,10 @@ import ( "os" goruntime "runtime" - "github.com/deckhouse/csi-ceph/api/v1alpha1" snapshotv1 "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumesnapshot/v1" v1 "k8s.io/api/core/v1" sv1 "k8s.io/api/storage/v1" extv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - "k8s.io/apimachinery/pkg/runtime" apiruntime "k8s.io/apimachinery/pkg/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" @@ -35,10 +33,11 @@ import ( "sigs.k8s.io/controller-runtime/pkg/healthz" "sigs.k8s.io/controller-runtime/pkg/manager" - "d8-controller/pkg/config" - "d8-controller/pkg/controller" - "d8-controller/pkg/kubutils" - "d8-controller/pkg/logger" + "github.com/deckhouse/csi-ceph/api/v1alpha1" + "github.com/deckhouse/csi-ceph/images/controller/pkg/config" + "github.com/deckhouse/csi-ceph/images/controller/pkg/controller" + "github.com/deckhouse/csi-ceph/images/controller/pkg/kubutils" + "github.com/deckhouse/csi-ceph/images/controller/pkg/logger" ) var ( diff --git a/images/controller/src/go.mod b/images/controller/go.mod similarity index 96% rename from images/controller/src/go.mod rename to images/controller/go.mod index cab63e66..23916810 100644 --- a/images/controller/src/go.mod +++ b/images/controller/go.mod @@ -1,4 +1,4 @@ -module d8-controller +module github.com/deckhouse/csi-ceph/images/controller go 1.23.6 @@ -17,7 +17,7 @@ require ( sigs.k8s.io/controller-runtime v0.20.3 ) -replace github.com/deckhouse/csi-ceph/api => ../../../api +replace github.com/deckhouse/csi-ceph/api => ../../api require ( github.com/beorn7/perks v1.0.1 // indirect diff --git a/images/controller/src/go.sum b/images/controller/go.sum similarity index 100% rename from images/controller/src/go.sum rename to images/controller/go.sum diff --git a/images/controller/src/pkg/config/config.go b/images/controller/pkg/config/config.go similarity index 97% rename from images/controller/src/pkg/config/config.go rename to images/controller/pkg/config/config.go index e8bbb273..cbe04eb4 100644 --- a/images/controller/src/pkg/config/config.go +++ b/images/controller/pkg/config/config.go @@ -18,7 +18,7 @@ import ( "os" "time" - "d8-controller/pkg/logger" + "github.com/deckhouse/csi-ceph/images/controller/pkg/logger" ) const ( diff --git a/images/controller/src/pkg/controller/ceph_cluster_authentication_watcher.go b/images/controller/pkg/controller/ceph_cluster_authentication_watcher.go similarity index 97% rename from images/controller/src/pkg/controller/ceph_cluster_authentication_watcher.go rename to images/controller/pkg/controller/ceph_cluster_authentication_watcher.go index 847bcd15..0888a0de 100644 --- a/images/controller/src/pkg/controller/ceph_cluster_authentication_watcher.go +++ b/images/controller/pkg/controller/ceph_cluster_authentication_watcher.go @@ -20,7 +20,6 @@ import ( "context" "fmt" - v1alpha1 "github.com/deckhouse/csi-ceph/api/v1alpha1" k8serr "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/util/workqueue" @@ -32,8 +31,9 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" "sigs.k8s.io/controller-runtime/pkg/source" - "d8-controller/pkg/config" - "d8-controller/pkg/logger" + v1alpha1 "github.com/deckhouse/csi-ceph/api/v1alpha1" + "github.com/deckhouse/csi-ceph/images/controller/pkg/config" + "github.com/deckhouse/csi-ceph/images/controller/pkg/logger" ) const ( diff --git a/images/controller/src/pkg/controller/ceph_cluster_connection_watcher.go b/images/controller/pkg/controller/ceph_cluster_connection_watcher.go similarity index 97% rename from images/controller/src/pkg/controller/ceph_cluster_connection_watcher.go rename to images/controller/pkg/controller/ceph_cluster_connection_watcher.go index 23da5bee..837ba947 100644 --- a/images/controller/src/pkg/controller/ceph_cluster_connection_watcher.go +++ b/images/controller/pkg/controller/ceph_cluster_connection_watcher.go @@ -22,7 +22,6 @@ import ( "reflect" "time" - v1alpha1 "github.com/deckhouse/csi-ceph/api/v1alpha1" corev1 "k8s.io/api/core/v1" k8serr "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" @@ -35,9 +34,10 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" "sigs.k8s.io/controller-runtime/pkg/source" - "d8-controller/pkg/config" - "d8-controller/pkg/internal" - "d8-controller/pkg/logger" + v1alpha1 "github.com/deckhouse/csi-ceph/api/v1alpha1" + "github.com/deckhouse/csi-ceph/images/controller/pkg/config" + "github.com/deckhouse/csi-ceph/images/controller/pkg/internal" + "github.com/deckhouse/csi-ceph/images/controller/pkg/logger" ) const ( diff --git a/images/controller/src/pkg/controller/ceph_cluster_connection_watcher_func.go b/images/controller/pkg/controller/ceph_cluster_connection_watcher_func.go similarity index 99% rename from images/controller/src/pkg/controller/ceph_cluster_connection_watcher_func.go rename to images/controller/pkg/controller/ceph_cluster_connection_watcher_func.go index 3598cc9a..96957dac 100644 --- a/images/controller/src/pkg/controller/ceph_cluster_connection_watcher_func.go +++ b/images/controller/pkg/controller/ceph_cluster_connection_watcher_func.go @@ -25,13 +25,13 @@ import ( "slices" "strings" - v1alpha1 "github.com/deckhouse/csi-ceph/api/v1alpha1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" - "d8-controller/pkg/internal" - "d8-controller/pkg/logger" + v1alpha1 "github.com/deckhouse/csi-ceph/api/v1alpha1" + "github.com/deckhouse/csi-ceph/images/controller/pkg/internal" + "github.com/deckhouse/csi-ceph/images/controller/pkg/logger" ) func validateCephClusterConnectionSpec(cephClusterConnection *v1alpha1.CephClusterConnection) (bool, string) { diff --git a/images/controller/src/pkg/controller/ceph_cluster_connection_watcher_test.go b/images/controller/pkg/controller/ceph_cluster_connection_watcher_test.go similarity index 99% rename from images/controller/src/pkg/controller/ceph_cluster_connection_watcher_test.go rename to images/controller/pkg/controller/ceph_cluster_connection_watcher_test.go index 95286b7b..236eaa96 100644 --- a/images/controller/src/pkg/controller/ceph_cluster_connection_watcher_test.go +++ b/images/controller/pkg/controller/ceph_cluster_connection_watcher_test.go @@ -20,7 +20,6 @@ import ( "context" "encoding/json" - v1alpha1 "github.com/deckhouse/csi-ceph/api/v1alpha1" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" @@ -28,9 +27,10 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" - "d8-controller/pkg/controller" - "d8-controller/pkg/internal" - "d8-controller/pkg/logger" + v1alpha1 "github.com/deckhouse/csi-ceph/api/v1alpha1" + "github.com/deckhouse/csi-ceph/images/controller/pkg/controller" + "github.com/deckhouse/csi-ceph/images/controller/pkg/internal" + "github.com/deckhouse/csi-ceph/images/controller/pkg/logger" ) var _ = Describe(controller.CephClusterConnectionCtrlName, func() { diff --git a/images/controller/src/pkg/controller/ceph_storage_class_watcher.go b/images/controller/pkg/controller/ceph_storage_class_watcher.go similarity index 98% rename from images/controller/src/pkg/controller/ceph_storage_class_watcher.go rename to images/controller/pkg/controller/ceph_storage_class_watcher.go index d1052d30..fc7a9dce 100644 --- a/images/controller/src/pkg/controller/ceph_storage_class_watcher.go +++ b/images/controller/pkg/controller/ceph_storage_class_watcher.go @@ -22,7 +22,6 @@ import ( "reflect" "time" - v1alpha1 "github.com/deckhouse/csi-ceph/api/v1alpha1" snapshotv1 "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumesnapshot/v1" v1 "k8s.io/api/storage/v1" k8serr "k8s.io/apimachinery/pkg/api/errors" @@ -36,9 +35,10 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" "sigs.k8s.io/controller-runtime/pkg/source" - "d8-controller/pkg/config" - "d8-controller/pkg/internal" - "d8-controller/pkg/logger" + v1alpha1 "github.com/deckhouse/csi-ceph/api/v1alpha1" + "github.com/deckhouse/csi-ceph/images/controller/pkg/config" + "github.com/deckhouse/csi-ceph/images/controller/pkg/internal" + "github.com/deckhouse/csi-ceph/images/controller/pkg/logger" ) const ( diff --git a/images/controller/src/pkg/controller/ceph_storage_class_watcher_func.go b/images/controller/pkg/controller/ceph_storage_class_watcher_func.go similarity index 99% rename from images/controller/src/pkg/controller/ceph_storage_class_watcher_func.go rename to images/controller/pkg/controller/ceph_storage_class_watcher_func.go index e6c036ff..0e107274 100644 --- a/images/controller/src/pkg/controller/ceph_storage_class_watcher_func.go +++ b/images/controller/pkg/controller/ceph_storage_class_watcher_func.go @@ -22,7 +22,6 @@ import ( "slices" "strings" - storagev1alpha1 "github.com/deckhouse/csi-ceph/api/v1alpha1" "github.com/google/go-cmp/cmp" snapshotv1 "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumesnapshot/v1" corev1 "k8s.io/api/core/v1" @@ -31,8 +30,9 @@ import ( "k8s.io/apimachinery/pkg/labels" "sigs.k8s.io/controller-runtime/pkg/client" - "d8-controller/pkg/internal" - "d8-controller/pkg/logger" + storagev1alpha1 "github.com/deckhouse/csi-ceph/api/v1alpha1" + "github.com/deckhouse/csi-ceph/images/controller/pkg/internal" + "github.com/deckhouse/csi-ceph/images/controller/pkg/logger" ) var ( diff --git a/images/controller/src/pkg/controller/ceph_storage_class_watcher_test.go b/images/controller/pkg/controller/ceph_storage_class_watcher_test.go similarity index 99% rename from images/controller/src/pkg/controller/ceph_storage_class_watcher_test.go rename to images/controller/pkg/controller/ceph_storage_class_watcher_test.go index 241f52d2..7c3b0f6d 100644 --- a/images/controller/src/pkg/controller/ceph_storage_class_watcher_test.go +++ b/images/controller/pkg/controller/ceph_storage_class_watcher_test.go @@ -19,7 +19,6 @@ package controller_test import ( "context" - v1alpha1 "github.com/deckhouse/csi-ceph/api/v1alpha1" snapshotv1 "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumesnapshot/v1" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -29,9 +28,10 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" - "d8-controller/pkg/controller" - "d8-controller/pkg/internal" - "d8-controller/pkg/logger" + v1alpha1 "github.com/deckhouse/csi-ceph/api/v1alpha1" + "github.com/deckhouse/csi-ceph/images/controller/pkg/controller" + "github.com/deckhouse/csi-ceph/images/controller/pkg/internal" + "github.com/deckhouse/csi-ceph/images/controller/pkg/logger" ) var _ = Describe(controller.CephStorageClassCtrlName, func() { diff --git a/images/controller/src/pkg/controller/common_func.go b/images/controller/pkg/controller/common_func.go similarity index 100% rename from images/controller/src/pkg/controller/common_func.go rename to images/controller/pkg/controller/common_func.go diff --git a/images/controller/src/pkg/controller/controller_suite_test.go b/images/controller/pkg/controller/controller_suite_test.go similarity index 99% rename from images/controller/src/pkg/controller/controller_suite_test.go rename to images/controller/pkg/controller/controller_suite_test.go index e1461d07..19512035 100644 --- a/images/controller/src/pkg/controller/controller_suite_test.go +++ b/images/controller/pkg/controller/controller_suite_test.go @@ -21,7 +21,6 @@ import ( "os" "testing" - v1alpha1 "github.com/deckhouse/csi-ceph/api/v1alpha1" snapshotv1 "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumesnapshot/v1" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -32,6 +31,8 @@ import ( clientgoscheme "k8s.io/client-go/kubernetes/scheme" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" + + v1alpha1 "github.com/deckhouse/csi-ceph/api/v1alpha1" ) func TestController(t *testing.T) { diff --git a/images/controller/src/pkg/internal/const.go b/images/controller/pkg/internal/const.go similarity index 100% rename from images/controller/src/pkg/internal/const.go rename to images/controller/pkg/internal/const.go diff --git a/images/controller/src/pkg/kubutils/kubernetes.go b/images/controller/pkg/kubutils/kubernetes.go similarity index 100% rename from images/controller/src/pkg/kubutils/kubernetes.go rename to images/controller/pkg/kubutils/kubernetes.go diff --git a/images/controller/src/pkg/logger/logger.go b/images/controller/pkg/logger/logger.go similarity index 100% rename from images/controller/src/pkg/logger/logger.go rename to images/controller/pkg/logger/logger.go diff --git a/images/controller/werf.inc.yaml b/images/controller/werf.inc.yaml index 4219a472..857e8ba2 100644 --- a/images/controller/werf.inc.yaml +++ b/images/controller/werf.inc.yaml @@ -1,16 +1,23 @@ --- image: {{ $.ImageName }}-src-artifact -from: {{ $.Root.BASE_ALT }} +from: {{ $.Root.BASE_ALT_P11 }} final: false + git: - add: / to: /src includePaths: - api - - images/controller/src + - images/{{ $.ImageName }} stageDependencies: install: - '**/*' + excludePaths: + - images/{{ $.ImageName }}/werf.yaml + +shell: + install: + - echo "src artifact" --- image: {{ $.ImageName }}-golang-artifact @@ -21,7 +28,7 @@ import: - image: {{ $.ImageName }}-src-artifact add: /src to: /src - before: setup + before: install mount: - fromPath: ~/go-pkg-cache @@ -29,9 +36,9 @@ mount: shell: setup: - - cd /src/images/controller/src/cmd - - GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags="-s -w" -o /controller - - chmod +x /controller + - cd /src/images/{{ $.ImageName }}/cmd + - GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags="-s -w" -o /{{ $.ImageName }} + - chmod +x /{{ $.ImageName }} --- image: {{ $.ImageName }}-distroless-artifact @@ -70,10 +77,10 @@ fromImage: {{ $.ImageName }}-distroless import: - image: {{ $.ImageName }}-golang-artifact - add: /controller - to: /controller + add: /{{ $.ImageName }} + to: /{{ $.ImageName }} before: setup docker: - ENTRYPOINT: ["/controller"] + ENTRYPOINT: ["/{{ $.ImageName }}"] USER: deckhouse:deckhouse diff --git a/images/csi-ceph/patches/0001-fix-gomod.patch b/images/csi-ceph/patches/0001-Modules-update.patch similarity index 75% rename from images/csi-ceph/patches/0001-fix-gomod.patch rename to images/csi-ceph/patches/0001-Modules-update.patch index 5e7c1f2f..93e4d6e2 100644 --- a/images/csi-ceph/patches/0001-fix-gomod.patch +++ b/images/csi-ceph/patches/0001-Modules-update.patch @@ -1,14 +1,19 @@ -From 5dcec45007f53897fe6047275f954b437a986400 Mon Sep 17 00:00:00 2001 +From f719930d9ab0fece8d1e0e6f1a9e3aa1b8eb91a9 Mon Sep 17 00:00:00 2001 From: "v.oleynikov" -Date: Thu, 6 Mar 2025 18:39:06 +0300 -Subject: [PATCH] Fix +Date: Sat, 22 Mar 2025 20:30:37 +0300 +Subject: [PATCH 1/2] Modules update --- - actions/retest/go.mod | 2 +- - actions/retest/go.sum | 4 +- + actions/retest/go.mod | 6 +- + actions/retest/go.sum | 5 +- .../retest/vendor/golang.org/x/net/LICENSE | 4 +- - actions/retest/vendor/modules.txt | 2 +- - api/go.mod | 4 +- + .../golang.org/x/net/context/context.go | 112 +- + .../vendor/golang.org/x/net/context/go17.go | 72 - + .../vendor/golang.org/x/net/context/go19.go | 20 - + .../golang.org/x/net/context/pre_go17.go | 300 - + .../golang.org/x/net/context/pre_go19.go | 109 - + actions/retest/vendor/modules.txt | 4 +- + api/go.mod | 8 +- api/go.sum | 8 +- api/vendor/golang.org/x/net/LICENSE | 4 +- .../golang.org/x/net/http/httpguts/httplex.go | 13 +- @@ -17,40 +22,25 @@ Subject: [PATCH] Fix .../golang.org/x/net/http2/config_go124.go | 61 + .../x/net/http2/config_pre_go124.go | 16 + api/vendor/golang.org/x/net/http2/frame.go | 17 +- - api/vendor/golang.org/x/net/http2/http2.go | 114 +- - api/vendor/golang.org/x/net/http2/server.go | 323 +- + api/vendor/golang.org/x/net/http2/http2.go | 131 +- + api/vendor/golang.org/x/net/http2/server.go | 434 +- api/vendor/golang.org/x/net/http2/testsync.go | 331 -- api/vendor/golang.org/x/net/http2/timer.go | 20 + - .../golang.org/x/net/http2/transport.go | 833 +-- + .../golang.org/x/net/http2/transport.go | 1112 ++-- .../golang.org/x/net/http2/unencrypted.go | 32 + - api/vendor/golang.org/x/net/http2/write.go | 10 + + api/vendor/golang.org/x/net/http2/write.go | 13 +- .../x/net/http2/writesched_priority.go | 4 +- + .../x/net/internal/httpcommon/ascii.go | 53 + + .../httpcommon}/headermap.go | 24 +- + .../x/net/internal/httpcommon/request.go | 467 ++ api/vendor/golang.org/x/text/LICENSE | 4 +- - api/vendor/modules.txt | 4 +- - go.mod | 30 +- - go.sum | 42 +- - .../go-jose/go-jose/v4/CHANGELOG.md | 24 + - .../go-jose/go-jose/v4/CONTRIBUTING.md | 6 - - .../github.com/go-jose/go-jose/v4/README.md | 10 +- - .../github.com/go-jose/go-jose/v4/crypter.go | 10 +- - vendor/github.com/go-jose/go-jose/v4/jwe.go | 5 +- - vendor/github.com/go-jose/go-jose/v4/jwk.go | 25 +- - vendor/github.com/go-jose/go-jose/v4/jws.go | 5 +- - .../github.com/go-jose/go-jose/v4/opaque.go | 3 + - .../github.com/go-jose/go-jose/v4/shared.go | 10 +- - .../github.com/go-jose/go-jose/v4/signing.go | 12 +- - .../testify/assert/assertion_compare.go | 35 +- - .../testify/assert/assertion_format.go | 34 +- - .../testify/assert/assertion_forward.go | 68 +- - .../testify/assert/assertion_order.go | 10 +- - .../stretchr/testify/assert/assertions.go | 157 +- - .../testify/assert/yaml/yaml_custom.go | 25 + - .../testify/assert/yaml/yaml_default.go | 37 + - .../stretchr/testify/assert/yaml/yaml_fail.go | 18 + - .../stretchr/testify/require/require.go | 432 +- - .../stretchr/testify/require/require.go.tmpl | 2 +- - .../testify/require/require_forward.go | 68 +- - .../stretchr/testify/require/requirements.go | 2 +- + api/vendor/modules.txt | 7 +- + go.mod | 18 +- + go.sum | 28 +- + vendor/github.com/golang-jwt/jwt/v5/README.md | 16 +- + .../github.com/golang-jwt/jwt/v5/SECURITY.md | 4 +- + vendor/github.com/golang-jwt/jwt/v5/parser.go | 36 +- + vendor/github.com/golang-jwt/jwt/v5/token.go | 2 +- .../golang.org/x/crypto/argon2/blamka_amd64.s | 2972 +++++++++- .../x/crypto/blake2b/blake2bAVX2_amd64.s | 5167 ++++++++++++++--- .../x/crypto/blake2b/blake2b_amd64.s | 1681 +++++- @@ -64,7 +54,13 @@ Subject: [PATCH] Fix vendor/golang.org/x/crypto/pkcs12/crypto.go | 2 +- .../x/crypto/salsa20/salsa/salsa20_amd64.s | 1742 +++--- vendor/golang.org/x/crypto/ssh/client_auth.go | 5 + - vendor/golang.org/x/crypto/ssh/server.go | 19 +- + vendor/golang.org/x/crypto/ssh/handshake.go | 61 +- + vendor/golang.org/x/crypto/ssh/server.go | 69 +- + vendor/golang.org/x/net/context/context.go | 112 +- + vendor/golang.org/x/net/context/go17.go | 72 - + vendor/golang.org/x/net/context/go19.go | 20 - + vendor/golang.org/x/net/context/pre_go17.go | 300 - + vendor/golang.org/x/net/context/pre_go19.go | 109 - vendor/golang.org/x/net/html/doc.go | 7 +- vendor/golang.org/x/net/html/doctype.go | 2 +- vendor/golang.org/x/net/html/foreign.go | 3 +- @@ -76,14 +72,18 @@ Subject: [PATCH] Fix vendor/golang.org/x/net/http2/config_go124.go | 61 + .../x/net/http2/config_pre_go124.go | 16 + vendor/golang.org/x/net/http2/frame.go | 4 +- - vendor/golang.org/x/net/http2/http2.go | 95 +- - vendor/golang.org/x/net/http2/server.go | 244 +- - vendor/golang.org/x/net/http2/transport.go | 516 +- + vendor/golang.org/x/net/http2/http2.go | 112 +- + vendor/golang.org/x/net/http2/server.go | 355 +- + vendor/golang.org/x/net/http2/transport.go | 833 ++- vendor/golang.org/x/net/http2/unencrypted.go | 32 + - vendor/golang.org/x/net/http2/write.go | 10 + + vendor/golang.org/x/net/http2/write.go | 13 +- + .../x/net/internal/httpcommon/ascii.go | 53 + + .../httpcommon}/headermap.go | 24 +- + .../x/net/internal/httpcommon/request.go | 467 ++ + vendor/golang.org/x/net/proxy/per_host.go | 8 +- .../golang.org/x/net/websocket/websocket.go | 2 +- .../golang.org/x/sys/cpu/asm_darwin_x86_gc.s | 17 + - vendor/golang.org/x/sys/cpu/cpu.go | 19 + + vendor/golang.org/x/sys/cpu/cpu.go | 22 + vendor/golang.org/x/sys/cpu/cpu_darwin_x86.go | 61 + vendor/golang.org/x/sys/cpu/cpu_gc_x86.go | 4 +- .../x/sys/cpu/{cpu_x86.s => cpu_gc_x86.s} | 2 +- @@ -93,9 +93,11 @@ Subject: [PATCH] Fix .../golang.org/x/sys/cpu/cpu_linux_riscv64.go | 137 + vendor/golang.org/x/sys/cpu/cpu_other_x86.go | 11 + vendor/golang.org/x/sys/cpu/cpu_riscv64.go | 11 +- - vendor/golang.org/x/sys/cpu/cpu_x86.go | 6 +- + vendor/golang.org/x/sys/cpu/cpu_x86.go | 27 +- .../x/sys/cpu/syscall_darwin_x86_gc.go | 98 + vendor/golang.org/x/sys/unix/README.md | 2 +- + vendor/golang.org/x/sys/unix/auxv.go | 36 + + .../golang.org/x/sys/unix/auxv_unsupported.go | 13 + vendor/golang.org/x/sys/unix/ioctl_linux.go | 96 + vendor/golang.org/x/sys/unix/mkerrors.sh | 17 +- vendor/golang.org/x/sys/unix/syscall_aix.go | 2 +- @@ -106,37 +108,50 @@ Subject: [PATCH] Fix .../x/sys/unix/syscall_linux_arm64.go | 2 + .../x/sys/unix/syscall_linux_loong64.go | 2 + .../x/sys/unix/syscall_linux_riscv64.go | 2 + + .../golang.org/x/sys/unix/syscall_solaris.go | 87 + .../x/sys/unix/syscall_zos_s390x.go | 104 +- .../golang.org/x/sys/unix/vgetrandom_linux.go | 13 + .../x/sys/unix/vgetrandom_unsupported.go | 11 + .../x/sys/unix/zerrors_darwin_amd64.go | 7 + .../x/sys/unix/zerrors_darwin_arm64.go | 7 + - vendor/golang.org/x/sys/unix/zerrors_linux.go | 44 +- - .../x/sys/unix/zerrors_linux_386.go | 25 + - .../x/sys/unix/zerrors_linux_amd64.go | 25 + - .../x/sys/unix/zerrors_linux_arm.go | 25 + - .../x/sys/unix/zerrors_linux_arm64.go | 26 + - .../x/sys/unix/zerrors_linux_loong64.go | 25 + - .../x/sys/unix/zerrors_linux_mips.go | 25 + - .../x/sys/unix/zerrors_linux_mips64.go | 25 + - .../x/sys/unix/zerrors_linux_mips64le.go | 25 + - .../x/sys/unix/zerrors_linux_mipsle.go | 25 + - .../x/sys/unix/zerrors_linux_ppc.go | 25 + - .../x/sys/unix/zerrors_linux_ppc64.go | 25 + - .../x/sys/unix/zerrors_linux_ppc64le.go | 25 + - .../x/sys/unix/zerrors_linux_riscv64.go | 25 + - .../x/sys/unix/zerrors_linux_s390x.go | 25 + - .../x/sys/unix/zerrors_linux_sparc64.go | 25 + + vendor/golang.org/x/sys/unix/zerrors_linux.go | 64 +- + .../x/sys/unix/zerrors_linux_386.go | 28 + + .../x/sys/unix/zerrors_linux_amd64.go | 28 + + .../x/sys/unix/zerrors_linux_arm.go | 28 + + .../x/sys/unix/zerrors_linux_arm64.go | 30 + + .../x/sys/unix/zerrors_linux_loong64.go | 28 + + .../x/sys/unix/zerrors_linux_mips.go | 28 + + .../x/sys/unix/zerrors_linux_mips64.go | 28 + + .../x/sys/unix/zerrors_linux_mips64le.go | 28 + + .../x/sys/unix/zerrors_linux_mipsle.go | 28 + + .../x/sys/unix/zerrors_linux_ppc.go | 28 + + .../x/sys/unix/zerrors_linux_ppc64.go | 28 + + .../x/sys/unix/zerrors_linux_ppc64le.go | 28 + + .../x/sys/unix/zerrors_linux_riscv64.go | 28 + + .../x/sys/unix/zerrors_linux_s390x.go | 28 + + .../x/sys/unix/zerrors_linux_sparc64.go | 28 + .../x/sys/unix/zerrors_zos_s390x.go | 2 + .../x/sys/unix/zsyscall_darwin_amd64.go | 20 + .../x/sys/unix/zsyscall_darwin_amd64.s | 5 + .../x/sys/unix/zsyscall_darwin_arm64.go | 20 + .../x/sys/unix/zsyscall_darwin_arm64.s | 5 + .../golang.org/x/sys/unix/zsyscall_linux.go | 27 +- - .../x/sys/unix/zsysnum_linux_amd64.go | 1 + - .../x/sys/unix/zsysnum_linux_arm64.go | 2 +- - .../x/sys/unix/zsysnum_linux_loong64.go | 2 + - .../x/sys/unix/zsysnum_linux_riscv64.go | 2 +- + .../x/sys/unix/zsyscall_solaris_amd64.go | 114 + + .../x/sys/unix/zsysnum_linux_386.go | 4 + + .../x/sys/unix/zsysnum_linux_amd64.go | 5 + + .../x/sys/unix/zsysnum_linux_arm.go | 4 + + .../x/sys/unix/zsysnum_linux_arm64.go | 6 +- + .../x/sys/unix/zsysnum_linux_loong64.go | 6 + + .../x/sys/unix/zsysnum_linux_mips.go | 4 + + .../x/sys/unix/zsysnum_linux_mips64.go | 4 + + .../x/sys/unix/zsysnum_linux_mips64le.go | 4 + + .../x/sys/unix/zsysnum_linux_mipsle.go | 4 + + .../x/sys/unix/zsysnum_linux_ppc.go | 4 + + .../x/sys/unix/zsysnum_linux_ppc64.go | 4 + + .../x/sys/unix/zsysnum_linux_ppc64le.go | 4 + + .../x/sys/unix/zsysnum_linux_riscv64.go | 6 +- + .../x/sys/unix/zsysnum_linux_s390x.go | 4 + + .../x/sys/unix/zsysnum_linux_sparc64.go | 4 + .../x/sys/unix/ztypes_darwin_amd64.go | 73 + .../x/sys/unix/ztypes_darwin_arm64.go | 73 + .../x/sys/unix/ztypes_freebsd_386.go | 1 + @@ -144,7 +159,7 @@ Subject: [PATCH] Fix .../x/sys/unix/ztypes_freebsd_arm.go | 1 + .../x/sys/unix/ztypes_freebsd_arm64.go | 1 + .../x/sys/unix/ztypes_freebsd_riscv64.go | 1 + - vendor/golang.org/x/sys/unix/ztypes_linux.go | 224 +- + vendor/golang.org/x/sys/unix/ztypes_linux.go | 228 +- .../x/sys/unix/ztypes_linux_riscv64.go | 33 + .../golang.org/x/sys/unix/ztypes_zos_s390x.go | 6 + .../golang.org/x/sys/windows/dll_windows.go | 13 +- @@ -154,80 +169,90 @@ Subject: [PATCH] Fix vendor/golang.org/x/term/README.md | 11 +- vendor/golang.org/x/term/term_windows.go | 1 + .../x/text/internal/catmsg/codec.go | 2 +- - .../apiserver/pkg/features/kube_features.go | 2 +- - .../apiserver/pkg/storage/cacher/cacher.go | 9 +- - .../kubernetes/pkg/features/kube_features.go | 5 +- - .../pkg/volume/util/atomic_writer.go | 3 +- - .../pkg/volume/util/atomic_writer_linux.go | 27 + - .../volume/util/atomic_writer_unsupported.go | 33 + - .../pkg/volume/util/device_util_linux.go | 7 +- - .../util/recyclerclient/recycler_client.go | 7 +- - .../k8s.io/kubernetes/pkg/volume/util/util.go | 38 - - .../debug/resource_usage_gatherer.go | 3 +- - .../e2e/framework/flake_reporting_util.go | 2 +- - .../test/e2e/framework/framework.go | 4 +- - .../test/e2e/framework/node/resource.go | 4 +- - .../test/e2e/framework/skipper/skipper.go | 5 +- - .../kubernetes/test/utils/density_utils.go | 3 +- - .../kubernetes/test/utils/deployment.go | 3 +- - .../kubernetes/test/utils/image/manifest.go | 4 +- - .../k8s.io/kubernetes/test/utils/runners.go | 6 +- - vendor/modules.txt | 31 +- - 169 files changed, 14432 insertions(+), 3815 deletions(-) + vendor/modules.txt | 19 +- + 166 files changed, 15546 insertions(+), 5267 deletions(-) + delete mode 100644 actions/retest/vendor/golang.org/x/net/context/go17.go + delete mode 100644 actions/retest/vendor/golang.org/x/net/context/go19.go + delete mode 100644 actions/retest/vendor/golang.org/x/net/context/pre_go17.go + delete mode 100644 actions/retest/vendor/golang.org/x/net/context/pre_go19.go create mode 100644 api/vendor/golang.org/x/net/http2/config.go create mode 100644 api/vendor/golang.org/x/net/http2/config_go124.go create mode 100644 api/vendor/golang.org/x/net/http2/config_pre_go124.go delete mode 100644 api/vendor/golang.org/x/net/http2/testsync.go create mode 100644 api/vendor/golang.org/x/net/http2/timer.go create mode 100644 api/vendor/golang.org/x/net/http2/unencrypted.go - create mode 100644 vendor/github.com/stretchr/testify/assert/yaml/yaml_custom.go - create mode 100644 vendor/github.com/stretchr/testify/assert/yaml/yaml_default.go - create mode 100644 vendor/github.com/stretchr/testify/assert/yaml/yaml_fail.go + create mode 100644 api/vendor/golang.org/x/net/internal/httpcommon/ascii.go + rename api/vendor/golang.org/x/net/{http2 => internal/httpcommon}/headermap.go (74%) + create mode 100644 api/vendor/golang.org/x/net/internal/httpcommon/request.go rename vendor/golang.org/x/crypto/chacha20/{chacha_ppc64le.go => chacha_ppc64x.go} (89%) rename vendor/golang.org/x/crypto/chacha20/{chacha_ppc64le.s => chacha_ppc64x.s} (76%) rename vendor/golang.org/x/crypto/internal/poly1305/{sum_ppc64le.go => sum_ppc64x.go} (95%) rename vendor/golang.org/x/crypto/internal/poly1305/{sum_ppc64le.s => sum_ppc64x.s} (89%) + delete mode 100644 vendor/golang.org/x/net/context/go17.go + delete mode 100644 vendor/golang.org/x/net/context/go19.go + delete mode 100644 vendor/golang.org/x/net/context/pre_go17.go + delete mode 100644 vendor/golang.org/x/net/context/pre_go19.go create mode 100644 vendor/golang.org/x/net/html/iter.go create mode 100644 vendor/golang.org/x/net/http2/config.go create mode 100644 vendor/golang.org/x/net/http2/config_go124.go create mode 100644 vendor/golang.org/x/net/http2/config_pre_go124.go create mode 100644 vendor/golang.org/x/net/http2/unencrypted.go + create mode 100644 vendor/golang.org/x/net/internal/httpcommon/ascii.go + rename vendor/golang.org/x/net/{http2 => internal/httpcommon}/headermap.go (74%) + create mode 100644 vendor/golang.org/x/net/internal/httpcommon/request.go create mode 100644 vendor/golang.org/x/sys/cpu/asm_darwin_x86_gc.s create mode 100644 vendor/golang.org/x/sys/cpu/cpu_darwin_x86.go rename vendor/golang.org/x/sys/cpu/{cpu_x86.s => cpu_gc_x86.s} (94%) create mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux_riscv64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_other_x86.go create mode 100644 vendor/golang.org/x/sys/cpu/syscall_darwin_x86_gc.go + create mode 100644 vendor/golang.org/x/sys/unix/auxv.go + create mode 100644 vendor/golang.org/x/sys/unix/auxv_unsupported.go create mode 100644 vendor/golang.org/x/sys/unix/vgetrandom_linux.go create mode 100644 vendor/golang.org/x/sys/unix/vgetrandom_unsupported.go - create mode 100644 vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer_linux.go - create mode 100644 vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer_unsupported.go diff --git a/actions/retest/go.mod b/actions/retest/go.mod -index 483bea4fa..999acd0cf 100644 +index 483bea4fa..cb57e2774 100644 --- a/actions/retest/go.mod +++ b/actions/retest/go.mod -@@ -10,7 +10,7 @@ require ( +@@ -1,6 +1,8 @@ + module github.com/ceph/ceph-csi/actions/retest + +-go 1.18 ++go 1.23.0 ++ ++toolchain go1.23.6 + + require ( + github.com/google/go-github v17.0.0+incompatible +@@ -10,7 +12,7 @@ require ( require ( github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-querystring v1.1.0 // indirect - golang.org/x/net v0.22.0 // indirect -+ golang.org/x/net v0.33.0 // indirect ++ golang.org/x/net v0.36.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.33.0 // indirect ) diff --git a/actions/retest/go.sum b/actions/retest/go.sum -index f20ccff1e..9e710ae8a 100644 +index f20ccff1e..45d4817ef 100644 --- a/actions/retest/go.sum +++ b/actions/retest/go.sum -@@ -11,8 +11,8 @@ github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD +@@ -5,14 +5,15 @@ github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu + github.com/google/go-cmp v0.5.2/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/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= ++github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= + github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY= + github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= + github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= -golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -+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/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA= ++golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I= golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -250,36 +275,726 @@ index 6a66aea5e..2a7cf70da 100644 contributors may be used to endorse or promote products derived from this software without specific prior written permission. +diff --git a/actions/retest/vendor/golang.org/x/net/context/context.go b/actions/retest/vendor/golang.org/x/net/context/context.go +index cf66309c4..db1c95fab 100644 +--- a/actions/retest/vendor/golang.org/x/net/context/context.go ++++ b/actions/retest/vendor/golang.org/x/net/context/context.go +@@ -3,29 +3,31 @@ + // license that can be found in the LICENSE file. + + // Package context defines the Context type, which carries deadlines, +-// cancelation signals, and other request-scoped values across API boundaries ++// cancellation signals, and other request-scoped values across API boundaries + // and between processes. + // As of Go 1.7 this package is available in the standard library under the +-// name context. https://golang.org/pkg/context. ++// name [context], and migrating to it can be done automatically with [go fix]. + // +-// Incoming requests to a server should create a Context, and outgoing calls to +-// servers should accept a Context. The chain of function calls between must +-// propagate the Context, optionally replacing it with a modified copy created +-// using WithDeadline, WithTimeout, WithCancel, or WithValue. ++// Incoming requests to a server should create a [Context], and outgoing ++// calls to servers should accept a Context. The chain of function ++// calls between them must propagate the Context, optionally replacing ++// it with a derived Context created using [WithCancel], [WithDeadline], ++// [WithTimeout], or [WithValue]. + // + // Programs that use Contexts should follow these rules to keep interfaces + // consistent across packages and enable static analysis tools to check context + // propagation: + // + // Do not store Contexts inside a struct type; instead, pass a Context +-// explicitly to each function that needs it. The Context should be the first ++// explicitly to each function that needs it. This is discussed further in ++// https://go.dev/blog/context-and-structs. The Context should be the first + // parameter, typically named ctx: + // + // func DoSomething(ctx context.Context, arg Arg) error { + // // ... use ctx ... + // } + // +-// Do not pass a nil Context, even if a function permits it. Pass context.TODO ++// Do not pass a nil [Context], even if a function permits it. Pass [context.TODO] + // if you are unsure about which Context to use. + // + // Use context Values only for request-scoped data that transits processes and +@@ -34,9 +36,30 @@ + // The same Context may be passed to functions running in different goroutines; + // Contexts are safe for simultaneous use by multiple goroutines. + // +-// See http://blog.golang.org/context for example code for a server that uses ++// See https://go.dev/blog/context for example code for a server that uses + // Contexts. +-package context // import "golang.org/x/net/context" ++// ++// [go fix]: https://go.dev/cmd/go#hdr-Update_packages_to_use_new_APIs ++package context ++ ++import ( ++ "context" // standard library's context, as of Go 1.7 ++ "time" ++) ++ ++// A Context carries a deadline, a cancellation signal, and other values across ++// API boundaries. ++// ++// Context's methods may be called by multiple goroutines simultaneously. ++type Context = context.Context ++ ++// Canceled is the error returned by [Context.Err] when the context is canceled ++// for some reason other than its deadline passing. ++var Canceled = context.Canceled ++ ++// DeadlineExceeded is the error returned by [Context.Err] when the context is canceled ++// due to its deadline passing. ++var DeadlineExceeded = context.DeadlineExceeded + + // Background returns a non-nil, empty Context. It is never canceled, has no + // values, and has no deadline. It is typically used by the main function, +@@ -49,8 +72,73 @@ func Background() Context { + // TODO returns a non-nil, empty Context. Code should use context.TODO when + // it's unclear which Context to use or it is not yet available (because the + // surrounding function has not yet been extended to accept a Context +-// parameter). TODO is recognized by static analysis tools that determine +-// whether Contexts are propagated correctly in a program. ++// parameter). + func TODO() Context { + return todo + } ++ ++var ( ++ background = context.Background() ++ todo = context.TODO() ++) ++ ++// A CancelFunc tells an operation to abandon its work. ++// A CancelFunc does not wait for the work to stop. ++// A CancelFunc may be called by multiple goroutines simultaneously. ++// After the first call, subsequent calls to a CancelFunc do nothing. ++type CancelFunc = context.CancelFunc ++ ++// WithCancel returns a derived context that points to the parent context ++// but has a new Done channel. The returned context's Done channel is closed ++// when the returned cancel function is called or when the parent context's ++// Done channel is closed, whichever happens first. ++// ++// Canceling this context releases resources associated with it, so code should ++// call cancel as soon as the operations running in this [Context] complete. ++func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { ++ return context.WithCancel(parent) ++} ++ ++// WithDeadline returns a derived context that points to the parent context ++// but has the deadline adjusted to be no later than d. If the parent's ++// deadline is already earlier than d, WithDeadline(parent, d) is semantically ++// equivalent to parent. The returned [Context.Done] channel is closed when ++// the deadline expires, when the returned cancel function is called, ++// or when the parent context's Done channel is closed, whichever happens first. ++// ++// Canceling this context releases resources associated with it, so code should ++// call cancel as soon as the operations running in this [Context] complete. ++func WithDeadline(parent Context, d time.Time) (Context, CancelFunc) { ++ return context.WithDeadline(parent, d) ++} ++ ++// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)). ++// ++// Canceling this context releases resources associated with it, so code should ++// call cancel as soon as the operations running in this [Context] complete: ++// ++// func slowOperationWithTimeout(ctx context.Context) (Result, error) { ++// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond) ++// defer cancel() // releases resources if slowOperation completes before timeout elapses ++// return slowOperation(ctx) ++// } ++func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) { ++ return context.WithTimeout(parent, timeout) ++} ++ ++// WithValue returns a derived context that points to the parent Context. ++// In the derived context, the value associated with key is val. ++// ++// Use context Values only for request-scoped data that transits processes and ++// APIs, not for passing optional parameters to functions. ++// ++// The provided key must be comparable and should not be of type ++// string or any other built-in type to avoid collisions between ++// packages using context. Users of WithValue should define their own ++// types for keys. To avoid allocating when assigning to an ++// interface{}, context keys often have concrete type ++// struct{}. Alternatively, exported context key variables' static ++// type should be a pointer or interface. ++func WithValue(parent Context, key, val interface{}) Context { ++ return context.WithValue(parent, key, val) ++} +diff --git a/actions/retest/vendor/golang.org/x/net/context/go17.go b/actions/retest/vendor/golang.org/x/net/context/go17.go +deleted file mode 100644 +index 0c1b86793..000000000 +--- a/actions/retest/vendor/golang.org/x/net/context/go17.go ++++ /dev/null +@@ -1,72 +0,0 @@ +-// Copyright 2016 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-//go:build go1.7 +- +-package context +- +-import ( +- "context" // standard library's context, as of Go 1.7 +- "time" +-) +- +-var ( +- todo = context.TODO() +- background = context.Background() +-) +- +-// Canceled is the error returned by Context.Err when the context is canceled. +-var Canceled = context.Canceled +- +-// DeadlineExceeded is the error returned by Context.Err when the context's +-// deadline passes. +-var DeadlineExceeded = context.DeadlineExceeded +- +-// WithCancel returns a copy of parent with a new Done channel. The returned +-// context's Done channel is closed when the returned cancel function is called +-// or when the parent context's Done channel is closed, whichever happens first. +-// +-// Canceling this context releases resources associated with it, so code should +-// call cancel as soon as the operations running in this Context complete. +-func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { +- ctx, f := context.WithCancel(parent) +- return ctx, f +-} +- +-// WithDeadline returns a copy of the parent context with the deadline adjusted +-// to be no later than d. If the parent's deadline is already earlier than d, +-// WithDeadline(parent, d) is semantically equivalent to parent. The returned +-// context's Done channel is closed when the deadline expires, when the returned +-// cancel function is called, or when the parent context's Done channel is +-// closed, whichever happens first. +-// +-// Canceling this context releases resources associated with it, so code should +-// call cancel as soon as the operations running in this Context complete. +-func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) { +- ctx, f := context.WithDeadline(parent, deadline) +- return ctx, f +-} +- +-// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)). +-// +-// Canceling this context releases resources associated with it, so code should +-// call cancel as soon as the operations running in this Context complete: +-// +-// func slowOperationWithTimeout(ctx context.Context) (Result, error) { +-// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond) +-// defer cancel() // releases resources if slowOperation completes before timeout elapses +-// return slowOperation(ctx) +-// } +-func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) { +- return WithDeadline(parent, time.Now().Add(timeout)) +-} +- +-// WithValue returns a copy of parent in which the value associated with key is +-// val. +-// +-// Use context Values only for request-scoped data that transits processes and +-// APIs, not for passing optional parameters to functions. +-func WithValue(parent Context, key interface{}, val interface{}) Context { +- return context.WithValue(parent, key, val) +-} +diff --git a/actions/retest/vendor/golang.org/x/net/context/go19.go b/actions/retest/vendor/golang.org/x/net/context/go19.go +deleted file mode 100644 +index e31e35a90..000000000 +--- a/actions/retest/vendor/golang.org/x/net/context/go19.go ++++ /dev/null +@@ -1,20 +0,0 @@ +-// Copyright 2017 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-//go:build go1.9 +- +-package context +- +-import "context" // standard library's context, as of Go 1.7 +- +-// A Context carries a deadline, a cancelation signal, and other values across +-// API boundaries. +-// +-// Context's methods may be called by multiple goroutines simultaneously. +-type Context = context.Context +- +-// A CancelFunc tells an operation to abandon its work. +-// A CancelFunc does not wait for the work to stop. +-// After the first call, subsequent calls to a CancelFunc do nothing. +-type CancelFunc = context.CancelFunc +diff --git a/actions/retest/vendor/golang.org/x/net/context/pre_go17.go b/actions/retest/vendor/golang.org/x/net/context/pre_go17.go +deleted file mode 100644 +index 065ff3dfa..000000000 +--- a/actions/retest/vendor/golang.org/x/net/context/pre_go17.go ++++ /dev/null +@@ -1,300 +0,0 @@ +-// Copyright 2014 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-//go:build !go1.7 +- +-package context +- +-import ( +- "errors" +- "fmt" +- "sync" +- "time" +-) +- +-// An emptyCtx is never canceled, has no values, and has no deadline. It is not +-// struct{}, since vars of this type must have distinct addresses. +-type emptyCtx int +- +-func (*emptyCtx) Deadline() (deadline time.Time, ok bool) { +- return +-} +- +-func (*emptyCtx) Done() <-chan struct{} { +- return nil +-} +- +-func (*emptyCtx) Err() error { +- return nil +-} +- +-func (*emptyCtx) Value(key interface{}) interface{} { +- return nil +-} +- +-func (e *emptyCtx) String() string { +- switch e { +- case background: +- return "context.Background" +- case todo: +- return "context.TODO" +- } +- return "unknown empty Context" +-} +- +-var ( +- background = new(emptyCtx) +- todo = new(emptyCtx) +-) +- +-// Canceled is the error returned by Context.Err when the context is canceled. +-var Canceled = errors.New("context canceled") +- +-// DeadlineExceeded is the error returned by Context.Err when the context's +-// deadline passes. +-var DeadlineExceeded = errors.New("context deadline exceeded") +- +-// WithCancel returns a copy of parent with a new Done channel. The returned +-// context's Done channel is closed when the returned cancel function is called +-// or when the parent context's Done channel is closed, whichever happens first. +-// +-// Canceling this context releases resources associated with it, so code should +-// call cancel as soon as the operations running in this Context complete. +-func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { +- c := newCancelCtx(parent) +- propagateCancel(parent, c) +- return c, func() { c.cancel(true, Canceled) } +-} +- +-// newCancelCtx returns an initialized cancelCtx. +-func newCancelCtx(parent Context) *cancelCtx { +- return &cancelCtx{ +- Context: parent, +- done: make(chan struct{}), +- } +-} +- +-// propagateCancel arranges for child to be canceled when parent is. +-func propagateCancel(parent Context, child canceler) { +- if parent.Done() == nil { +- return // parent is never canceled +- } +- if p, ok := parentCancelCtx(parent); ok { +- p.mu.Lock() +- if p.err != nil { +- // parent has already been canceled +- child.cancel(false, p.err) +- } else { +- if p.children == nil { +- p.children = make(map[canceler]bool) +- } +- p.children[child] = true +- } +- p.mu.Unlock() +- } else { +- go func() { +- select { +- case <-parent.Done(): +- child.cancel(false, parent.Err()) +- case <-child.Done(): +- } +- }() +- } +-} +- +-// parentCancelCtx follows a chain of parent references until it finds a +-// *cancelCtx. This function understands how each of the concrete types in this +-// package represents its parent. +-func parentCancelCtx(parent Context) (*cancelCtx, bool) { +- for { +- switch c := parent.(type) { +- case *cancelCtx: +- return c, true +- case *timerCtx: +- return c.cancelCtx, true +- case *valueCtx: +- parent = c.Context +- default: +- return nil, false +- } +- } +-} +- +-// removeChild removes a context from its parent. +-func removeChild(parent Context, child canceler) { +- p, ok := parentCancelCtx(parent) +- if !ok { +- return +- } +- p.mu.Lock() +- if p.children != nil { +- delete(p.children, child) +- } +- p.mu.Unlock() +-} +- +-// A canceler is a context type that can be canceled directly. The +-// implementations are *cancelCtx and *timerCtx. +-type canceler interface { +- cancel(removeFromParent bool, err error) +- Done() <-chan struct{} +-} +- +-// A cancelCtx can be canceled. When canceled, it also cancels any children +-// that implement canceler. +-type cancelCtx struct { +- Context +- +- done chan struct{} // closed by the first cancel call. +- +- mu sync.Mutex +- children map[canceler]bool // set to nil by the first cancel call +- err error // set to non-nil by the first cancel call +-} +- +-func (c *cancelCtx) Done() <-chan struct{} { +- return c.done +-} +- +-func (c *cancelCtx) Err() error { +- c.mu.Lock() +- defer c.mu.Unlock() +- return c.err +-} +- +-func (c *cancelCtx) String() string { +- return fmt.Sprintf("%v.WithCancel", c.Context) +-} +- +-// cancel closes c.done, cancels each of c's children, and, if +-// removeFromParent is true, removes c from its parent's children. +-func (c *cancelCtx) cancel(removeFromParent bool, err error) { +- if err == nil { +- panic("context: internal error: missing cancel error") +- } +- c.mu.Lock() +- if c.err != nil { +- c.mu.Unlock() +- return // already canceled +- } +- c.err = err +- close(c.done) +- for child := range c.children { +- // NOTE: acquiring the child's lock while holding parent's lock. +- child.cancel(false, err) +- } +- c.children = nil +- c.mu.Unlock() +- +- if removeFromParent { +- removeChild(c.Context, c) +- } +-} +- +-// WithDeadline returns a copy of the parent context with the deadline adjusted +-// to be no later than d. If the parent's deadline is already earlier than d, +-// WithDeadline(parent, d) is semantically equivalent to parent. The returned +-// context's Done channel is closed when the deadline expires, when the returned +-// cancel function is called, or when the parent context's Done channel is +-// closed, whichever happens first. +-// +-// Canceling this context releases resources associated with it, so code should +-// call cancel as soon as the operations running in this Context complete. +-func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) { +- if cur, ok := parent.Deadline(); ok && cur.Before(deadline) { +- // The current deadline is already sooner than the new one. +- return WithCancel(parent) +- } +- c := &timerCtx{ +- cancelCtx: newCancelCtx(parent), +- deadline: deadline, +- } +- propagateCancel(parent, c) +- d := deadline.Sub(time.Now()) +- if d <= 0 { +- c.cancel(true, DeadlineExceeded) // deadline has already passed +- return c, func() { c.cancel(true, Canceled) } +- } +- c.mu.Lock() +- defer c.mu.Unlock() +- if c.err == nil { +- c.timer = time.AfterFunc(d, func() { +- c.cancel(true, DeadlineExceeded) +- }) +- } +- return c, func() { c.cancel(true, Canceled) } +-} +- +-// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to +-// implement Done and Err. It implements cancel by stopping its timer then +-// delegating to cancelCtx.cancel. +-type timerCtx struct { +- *cancelCtx +- timer *time.Timer // Under cancelCtx.mu. +- +- deadline time.Time +-} +- +-func (c *timerCtx) Deadline() (deadline time.Time, ok bool) { +- return c.deadline, true +-} +- +-func (c *timerCtx) String() string { +- return fmt.Sprintf("%v.WithDeadline(%s [%s])", c.cancelCtx.Context, c.deadline, c.deadline.Sub(time.Now())) +-} +- +-func (c *timerCtx) cancel(removeFromParent bool, err error) { +- c.cancelCtx.cancel(false, err) +- if removeFromParent { +- // Remove this timerCtx from its parent cancelCtx's children. +- removeChild(c.cancelCtx.Context, c) +- } +- c.mu.Lock() +- if c.timer != nil { +- c.timer.Stop() +- c.timer = nil +- } +- c.mu.Unlock() +-} +- +-// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)). +-// +-// Canceling this context releases resources associated with it, so code should +-// call cancel as soon as the operations running in this Context complete: +-// +-// func slowOperationWithTimeout(ctx context.Context) (Result, error) { +-// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond) +-// defer cancel() // releases resources if slowOperation completes before timeout elapses +-// return slowOperation(ctx) +-// } +-func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) { +- return WithDeadline(parent, time.Now().Add(timeout)) +-} +- +-// WithValue returns a copy of parent in which the value associated with key is +-// val. +-// +-// Use context Values only for request-scoped data that transits processes and +-// APIs, not for passing optional parameters to functions. +-func WithValue(parent Context, key interface{}, val interface{}) Context { +- return &valueCtx{parent, key, val} +-} +- +-// A valueCtx carries a key-value pair. It implements Value for that key and +-// delegates all other calls to the embedded Context. +-type valueCtx struct { +- Context +- key, val interface{} +-} +- +-func (c *valueCtx) String() string { +- return fmt.Sprintf("%v.WithValue(%#v, %#v)", c.Context, c.key, c.val) +-} +- +-func (c *valueCtx) Value(key interface{}) interface{} { +- if c.key == key { +- return c.val +- } +- return c.Context.Value(key) +-} +diff --git a/actions/retest/vendor/golang.org/x/net/context/pre_go19.go b/actions/retest/vendor/golang.org/x/net/context/pre_go19.go +deleted file mode 100644 +index ec5a63803..000000000 +--- a/actions/retest/vendor/golang.org/x/net/context/pre_go19.go ++++ /dev/null +@@ -1,109 +0,0 @@ +-// Copyright 2014 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-//go:build !go1.9 +- +-package context +- +-import "time" +- +-// A Context carries a deadline, a cancelation signal, and other values across +-// API boundaries. +-// +-// Context's methods may be called by multiple goroutines simultaneously. +-type Context interface { +- // Deadline returns the time when work done on behalf of this context +- // should be canceled. Deadline returns ok==false when no deadline is +- // set. Successive calls to Deadline return the same results. +- Deadline() (deadline time.Time, ok bool) +- +- // Done returns a channel that's closed when work done on behalf of this +- // context should be canceled. Done may return nil if this context can +- // never be canceled. Successive calls to Done return the same value. +- // +- // WithCancel arranges for Done to be closed when cancel is called; +- // WithDeadline arranges for Done to be closed when the deadline +- // expires; WithTimeout arranges for Done to be closed when the timeout +- // elapses. +- // +- // Done is provided for use in select statements: +- // +- // // Stream generates values with DoSomething and sends them to out +- // // until DoSomething returns an error or ctx.Done is closed. +- // func Stream(ctx context.Context, out chan<- Value) error { +- // for { +- // v, err := DoSomething(ctx) +- // if err != nil { +- // return err +- // } +- // select { +- // case <-ctx.Done(): +- // return ctx.Err() +- // case out <- v: +- // } +- // } +- // } +- // +- // See http://blog.golang.org/pipelines for more examples of how to use +- // a Done channel for cancelation. +- Done() <-chan struct{} +- +- // Err returns a non-nil error value after Done is closed. Err returns +- // Canceled if the context was canceled or DeadlineExceeded if the +- // context's deadline passed. No other values for Err are defined. +- // After Done is closed, successive calls to Err return the same value. +- Err() error +- +- // Value returns the value associated with this context for key, or nil +- // if no value is associated with key. Successive calls to Value with +- // the same key returns the same result. +- // +- // Use context values only for request-scoped data that transits +- // processes and API boundaries, not for passing optional parameters to +- // functions. +- // +- // A key identifies a specific value in a Context. Functions that wish +- // to store values in Context typically allocate a key in a global +- // variable then use that key as the argument to context.WithValue and +- // Context.Value. A key can be any type that supports equality; +- // packages should define keys as an unexported type to avoid +- // collisions. +- // +- // Packages that define a Context key should provide type-safe accessors +- // for the values stores using that key: +- // +- // // Package user defines a User type that's stored in Contexts. +- // package user +- // +- // import "golang.org/x/net/context" +- // +- // // User is the type of value stored in the Contexts. +- // type User struct {...} +- // +- // // key is an unexported type for keys defined in this package. +- // // This prevents collisions with keys defined in other packages. +- // type key int +- // +- // // userKey is the key for user.User values in Contexts. It is +- // // unexported; clients use user.NewContext and user.FromContext +- // // instead of using this key directly. +- // var userKey key = 0 +- // +- // // NewContext returns a new Context that carries value u. +- // func NewContext(ctx context.Context, u *User) context.Context { +- // return context.WithValue(ctx, userKey, u) +- // } +- // +- // // FromContext returns the User value stored in ctx, if any. +- // func FromContext(ctx context.Context) (*User, bool) { +- // u, ok := ctx.Value(userKey).(*User) +- // return u, ok +- // } +- Value(key interface{}) interface{} +-} +- +-// A CancelFunc tells an operation to abandon its work. +-// A CancelFunc does not wait for the work to stop. +-// After the first call, subsequent calls to a CancelFunc do nothing. +-type CancelFunc func() diff --git a/actions/retest/vendor/modules.txt b/actions/retest/vendor/modules.txt -index 6025bf8e9..6218cac1d 100644 +index 6025bf8e9..5ba0874a8 100644 --- a/actions/retest/vendor/modules.txt +++ b/actions/retest/vendor/modules.txt -@@ -7,7 +7,7 @@ github.com/google/go-github/github +@@ -7,8 +7,8 @@ github.com/google/go-github/github # github.com/google/go-querystring v1.1.0 ## explicit; go 1.10 github.com/google/go-querystring/query -# golang.org/x/net v0.22.0 -+# golang.org/x/net v0.33.0 - ## explicit; go 1.18 +-## explicit; go 1.18 ++# golang.org/x/net v0.36.0 ++## explicit; go 1.23.0 golang.org/x/net/context # golang.org/x/oauth2 v0.18.0 + ## explicit; go 1.18 diff --git a/api/go.mod b/api/go.mod -index 93cd4daaa..49865ccb7 100644 +index 93cd4daaa..01221e0fe 100644 --- a/api/go.mod +++ b/api/go.mod -@@ -18,8 +18,8 @@ require ( +@@ -1,6 +1,8 @@ + module github.com/ceph/ceph-csi/api + +-go 1.22.0 ++go 1.23.0 ++ ++toolchain go1.23.6 + + require ( + github.com/ghodss/yaml v1.0.0 +@@ -18,8 +20,8 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - golang.org/x/net v0.23.0 // indirect - golang.org/x/text v0.14.0 // indirect -+ golang.org/x/net v0.33.0 // indirect -+ golang.org/x/text v0.21.0 // indirect ++ golang.org/x/net v0.36.0 // indirect ++ golang.org/x/text v0.22.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 diff --git a/api/go.sum b/api/go.sum -index ad5efc1fd..2cbb53b1b 100644 +index ad5efc1fd..5dbaf37d9 100644 --- a/api/go.sum +++ b/api/go.sum @@ -49,8 +49,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn @@ -288,8 +1003,8 @@ index ad5efc1fd..2cbb53b1b 100644 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -+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/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA= ++golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I= 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= @@ -299,8 +1014,8 @@ index ad5efc1fd..2cbb53b1b 100644 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -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/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= ++golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= 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= @@ -397,7 +1112,7 @@ index 780968d6c..e81b73e6a 100644 p.mu.Lock() diff --git a/api/vendor/golang.org/x/net/http2/config.go b/api/vendor/golang.org/x/net/http2/config.go new file mode 100644 -index 000000000..de58dfb8d +index 000000000..ca645d9a1 --- /dev/null +++ b/api/vendor/golang.org/x/net/http2/config.go @@ -0,0 +1,122 @@ @@ -463,7 +1178,7 @@ index 000000000..de58dfb8d + return conf +} + -+// configFromServer merges configuration settings from h2 and h2.t1.HTTP2 ++// configFromTransport merges configuration settings from h2 and h2.t1.HTTP2 +// (the net/http Transport). +func configFromTransport(h2 *Transport) http2Config { + conf := http2Config{ @@ -525,7 +1240,7 @@ index 000000000..de58dfb8d +} diff --git a/api/vendor/golang.org/x/net/http2/config_go124.go b/api/vendor/golang.org/x/net/http2/config_go124.go new file mode 100644 -index 000000000..e3784123c +index 000000000..5b516c55f --- /dev/null +++ b/api/vendor/golang.org/x/net/http2/config_go124.go @@ -0,0 +1,61 @@ @@ -544,7 +1259,7 @@ index 000000000..e3784123c + fillNetHTTPConfig(conf, srv.HTTP2) +} + -+// fillNetHTTPServerConfig sets fields in conf from tr.HTTP2. ++// fillNetHTTPTransportConfig sets fields in conf from tr.HTTP2. +func fillNetHTTPTransportConfig(conf *http2Config, tr *http.Transport) { + fillNetHTTPConfig(conf, tr.HTTP2) +} @@ -686,10 +1401,10 @@ index 43557ab7e..81faec7e7 100644 if invalid != nil { fr.errDetail = invalid diff --git a/api/vendor/golang.org/x/net/http2/http2.go b/api/vendor/golang.org/x/net/http2/http2.go -index 6f2df2818..c7601c909 100644 +index 6f2df2818..6c18ea230 100644 --- a/api/vendor/golang.org/x/net/http2/http2.go +++ b/api/vendor/golang.org/x/net/http2/http2.go -@@ -17,24 +17,28 @@ package http2 // import "golang.org/x/net/http2" +@@ -17,15 +17,18 @@ package http2 // import "golang.org/x/net/http2" import ( "bufio" @@ -709,31 +1424,33 @@ index 6f2df2818..c7601c909 100644 "golang.org/x/net/http/httpguts" ) - - var ( -- VerboseLogs bool -- logFrameWrites bool -- logFrameReads bool -- inTests bool -+ VerboseLogs bool -+ logFrameWrites bool -+ logFrameReads bool -+ inTests bool -+ disableExtendedConnectProtocol bool +@@ -35,6 +38,15 @@ var ( + logFrameWrites bool + logFrameReads bool + inTests bool ++ ++ // Enabling extended CONNECT by causes browsers to attempt to use ++ // WebSockets-over-HTTP/2. This results in problems when the server's websocket ++ // package doesn't support extended CONNECT. ++ // ++ // Disable extended CONNECT by default for now. ++ // ++ // Issue #71128. ++ disableExtendedConnectProtocol = true ) func init() { -@@ -47,6 +51,9 @@ func init() { +@@ -47,6 +59,9 @@ func init() { logFrameWrites = true logFrameReads = true } -+ if strings.Contains(e, "http2xconnect=0") { -+ disableExtendedConnectProtocol = true ++ if strings.Contains(e, "http2xconnect=1") { ++ disableExtendedConnectProtocol = false + } } const ( -@@ -138,6 +145,10 @@ func (s Setting) Valid() error { +@@ -138,6 +153,10 @@ func (s Setting) Valid() error { if s.Val < 16384 || s.Val > 1<<24-1 { return ConnectionError(ErrCodeProtocol) } @@ -744,7 +1461,7 @@ index 6f2df2818..c7601c909 100644 } return nil } -@@ -147,21 +158,23 @@ func (s Setting) Valid() error { +@@ -147,21 +166,23 @@ func (s Setting) Valid() error { type SettingID uint16 const ( @@ -780,7 +1497,7 @@ index 6f2df2818..c7601c909 100644 } func (s SettingID) String() string { -@@ -210,12 +223,6 @@ type stringWriter interface { +@@ -210,12 +231,6 @@ type stringWriter interface { WriteString(s string) (n int, err error) } @@ -793,7 +1510,7 @@ index 6f2df2818..c7601c909 100644 // A closeWaiter is like a sync.WaitGroup but only goes 1 to 0 (open to closed). type closeWaiter chan struct{} -@@ -241,13 +248,19 @@ func (cw closeWaiter) Wait() { +@@ -241,13 +256,19 @@ func (cw closeWaiter) Wait() { // Its buffered writer is lazily allocated as needed, to minimize // idle memory usage with many connections. type bufferedWriter struct { @@ -818,7 +1535,7 @@ index 6f2df2818..c7601c909 100644 } // bufWriterPoolBufferSize is the size of bufio.Writer's -@@ -274,7 +287,7 @@ func (w *bufferedWriter) Available() int { +@@ -274,7 +295,7 @@ func (w *bufferedWriter) Available() int { func (w *bufferedWriter) Write(p []byte) (n int, err error) { if w.bw == nil { bw := bufWriterPool.Get().(*bufio.Writer) @@ -827,7 +1544,7 @@ index 6f2df2818..c7601c909 100644 w.bw = bw } return w.bw.Write(p) -@@ -292,6 +305,38 @@ func (w *bufferedWriter) Flush() error { +@@ -292,6 +313,38 @@ func (w *bufferedWriter) Flush() error { return err } @@ -866,7 +1583,28 @@ index 6f2df2818..c7601c909 100644 func mustUint31(v int32) uint32 { if v < 0 || v > 2147483647 { panic("out of range") -@@ -383,3 +428,14 @@ func validPseudoPath(v string) bool { +@@ -362,24 +415,18 @@ func (s *sorter) SortStrings(ss []string) { + s.v = save + } + +-// validPseudoPath reports whether v is a valid :path pseudo-header +-// value. It must be either: +-// +-// - a non-empty string starting with '/' +-// - the string '*', for OPTIONS requests. +-// +-// For now this is only used a quick check for deciding when to clean +-// up Opaque URLs before sending requests from the Transport. +-// See golang.org/issue/16847 +-// +-// We used to enforce that the path also didn't start with "//", but +-// Google's GFE accepts such paths and Chrome sends them, so ignore +-// that part of the spec. See golang.org/issue/19103. +-func validPseudoPath(v string) bool { +- return (len(v) > 0 && v[0] == '/') || v == "*" +-} +- + // incomparable is a zero-width, non-comparable type. Adding it to a struct // makes that struct also non-comparable, and generally doesn't add // any size (as long as it's first). type incomparable [0]func() @@ -882,7 +1620,7 @@ index 6f2df2818..c7601c909 100644 + ContextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc) +} diff --git a/api/vendor/golang.org/x/net/http2/server.go b/api/vendor/golang.org/x/net/http2/server.go -index ce2e8b40e..b55547aec 100644 +index ce2e8b40e..b640deb0e 100644 --- a/api/vendor/golang.org/x/net/http2/server.go +++ b/api/vendor/golang.org/x/net/http2/server.go @@ -29,6 +29,7 @@ import ( @@ -893,7 +1631,11 @@ index ce2e8b40e..b55547aec 100644 "crypto/tls" "errors" "fmt" -@@ -52,10 +53,14 @@ import ( +@@ -49,13 +50,18 @@ import ( + + "golang.org/x/net/http/httpguts" + "golang.org/x/net/http2/hpack" ++ "golang.org/x/net/internal/httpcommon" ) const ( @@ -912,7 +1654,7 @@ index ce2e8b40e..b55547aec 100644 maxQueuedControlFrames = 10000 ) -@@ -127,6 +132,22 @@ type Server struct { +@@ -127,6 +133,22 @@ type Server struct { // If zero or negative, there is no timeout. IdleTimeout time.Duration @@ -935,19 +1677,19 @@ index ce2e8b40e..b55547aec 100644 // MaxUploadBufferPerConnection is the size of the initial flow // control window for each connections. The HTTP/2 spec does not // allow this to be smaller than 65535 or larger than 2^32-1. -@@ -154,57 +175,39 @@ type Server struct { +@@ -154,57 +176,39 @@ type Server struct { // so that we don't embed a Mutex in this struct, which will make the // struct non-copyable, which might break some callers. state *serverInternalState -} -- + -func (s *Server) initialConnRecvWindowSize() int32 { - if s.MaxUploadBufferPerConnection >= initialWindowSize { - return s.MaxUploadBufferPerConnection - } - return 1 << 20 -} - +- -func (s *Server) initialStreamRecvWindowSize() int32 { - if s.MaxUploadBufferPerStream > 0 { - return s.MaxUploadBufferPerStream @@ -1013,7 +1755,7 @@ index ce2e8b40e..b55547aec 100644 } type serverInternalState struct { -@@ -303,7 +306,7 @@ func ConfigureServer(s *http.Server, conf *Server) error { +@@ -303,7 +307,7 @@ func ConfigureServer(s *http.Server, conf *Server) error { if s.TLSNextProto == nil { s.TLSNextProto = map[string]func(*http.Server, *tls.Conn, http.Handler){} } @@ -1022,7 +1764,7 @@ index ce2e8b40e..b55547aec 100644 if testHookOnConn != nil { testHookOnConn() } -@@ -320,12 +323,31 @@ func ConfigureServer(s *http.Server, conf *Server) error { +@@ -320,12 +324,31 @@ func ConfigureServer(s *http.Server, conf *Server) error { ctx = bc.BaseContext() } conf.ServeConn(c, &ServeConnOpts{ @@ -1058,7 +1800,7 @@ index ce2e8b40e..b55547aec 100644 return nil } -@@ -400,16 +422,22 @@ func (o *ServeConnOpts) handler() http.Handler { +@@ -400,16 +423,22 @@ func (o *ServeConnOpts) handler() http.Handler { // // The opts parameter is optional. If nil, default values are used. func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) { @@ -1083,7 +1825,7 @@ index ce2e8b40e..b55547aec 100644 handler: opts.handler(), streams: make(map[uint32]*stream), readFrameCh: make(chan readFrameResult), -@@ -419,13 +447,19 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) { +@@ -419,13 +448,19 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) { bodyReadCh: make(chan bodyReadMsg), // buffering doesn't matter either way doneServing: make(chan struct{}), clientMaxStreams: math.MaxUint32, // Section 6.5.2: "Initially, there is no limit to this value" @@ -1104,7 +1846,7 @@ index ce2e8b40e..b55547aec 100644 s.state.registerConn(sc) defer s.state.unregisterConn(sc) -@@ -451,15 +485,15 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) { +@@ -451,15 +486,15 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) { sc.flow.add(initialWindowSize) sc.inflow.init(initialWindowSize) sc.hpackEncoder = hpack.NewEncoder(&sc.headerWriteBuf) @@ -1125,7 +1867,7 @@ index ce2e8b40e..b55547aec 100644 sc.framer = fr if tc, ok := c.(connectionStater); ok { -@@ -492,7 +526,7 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) { +@@ -492,7 +527,7 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) { // So for now, do nothing here again. } @@ -1134,7 +1876,7 @@ index ce2e8b40e..b55547aec 100644 // "Endpoints MAY choose to generate a connection error // (Section 5.4.1) of type INADEQUATE_SECURITY if one of // the prohibited cipher suites are negotiated." -@@ -529,7 +563,7 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) { +@@ -529,7 +564,7 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) { opts.UpgradeRequest = nil } @@ -1143,7 +1885,7 @@ index ce2e8b40e..b55547aec 100644 } func serverConnBaseContext(c net.Conn, opts *ServeConnOpts) (ctx context.Context, cancel func()) { -@@ -569,6 +603,7 @@ type serverConn struct { +@@ -569,6 +604,7 @@ type serverConn struct { tlsState *tls.ConnectionState // shared by all handlers, like net/http remoteAddrStr string writeSched WriteScheduler @@ -1151,7 +1893,7 @@ index ce2e8b40e..b55547aec 100644 // Everything following is owned by the serve loop; use serveG.check(): serveG goroutineLock // used to verify funcs are on serve() -@@ -588,6 +623,7 @@ type serverConn struct { +@@ -588,6 +624,7 @@ type serverConn struct { streams map[uint32]*stream unstartedHandlers []unstartedHandler initialStreamSendWindowSize int32 @@ -1159,7 +1901,7 @@ index ce2e8b40e..b55547aec 100644 maxFrameSize int32 peerMaxHeaderListSize uint32 // zero means unknown (default) canonHeader map[string]string // http2-lower-case -> Go-Canonical-Case -@@ -598,9 +634,14 @@ type serverConn struct { +@@ -598,9 +635,14 @@ type serverConn struct { inGoAway bool // we've started to or sent GOAWAY inFrameScheduleLoop bool // whether we're in the scheduleFrameWrite loop needToSendGoAway bool // we need to schedule a GOAWAY frame write @@ -1176,7 +1918,7 @@ index ce2e8b40e..b55547aec 100644 // Owned by the writeFrameAsync goroutine: headerWriteBuf bytes.Buffer -@@ -615,11 +656,7 @@ func (sc *serverConn) maxHeaderListSize() uint32 { +@@ -615,11 +657,7 @@ func (sc *serverConn) maxHeaderListSize() uint32 { if n <= 0 { n = http.DefaultMaxHeaderBytes } @@ -1189,7 +1931,7 @@ index ce2e8b40e..b55547aec 100644 } func (sc *serverConn) curOpenStreams() uint32 { -@@ -649,12 +686,12 @@ type stream struct { +@@ -649,12 +687,12 @@ type stream struct { flow outflow // limits writing from Handler to client inflow inflow // what the client is allowed to POST/etc to us state streamState @@ -1208,7 +1950,7 @@ index ce2e8b40e..b55547aec 100644 trailer http.Header // accumulated trailers reqTrailer http.Header // handler's Request.Trailer -@@ -732,11 +769,7 @@ func isClosedConnError(err error) bool { +@@ -732,11 +770,7 @@ func isClosedConnError(err error) bool { return false } @@ -1221,6 +1963,16 @@ index ce2e8b40e..b55547aec 100644 return true } +@@ -779,8 +813,7 @@ const maxCachedCanonicalHeadersKeysSize = 2048 + + func (sc *serverConn) canonicalHeader(v string) string { + sc.serveG.check() +- buildCommonHeaderMapsOnce() +- cv, ok := commonCanonHeader[v] ++ cv, ok := httpcommon.CachedCanonicalHeader(v) + if ok { + return cv + } @@ -815,8 +848,9 @@ type readFrameResult struct { // consumer is done with the frame. // It's run on its own goroutine. @@ -1487,53 +2239,169 @@ index ce2e8b40e..b55547aec 100644 } sc.streams[id] = st -@@ -2143,11 +2238,17 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res - scheme: f.PseudoValue("scheme"), - authority: f.PseudoValue("authority"), - path: f.PseudoValue("path"), -+ protocol: f.PseudoValue("protocol"), +@@ -2138,19 +2233,25 @@ func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream + func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*responseWriter, *http.Request, error) { + sc.serveG.check() + +- rp := requestParam{ +- method: f.PseudoValue("method"), +- scheme: f.PseudoValue("scheme"), +- authority: f.PseudoValue("authority"), +- path: f.PseudoValue("path"), ++ rp := httpcommon.ServerRequestParam{ ++ Method: f.PseudoValue("method"), ++ Scheme: f.PseudoValue("scheme"), ++ Authority: f.PseudoValue("authority"), ++ Path: f.PseudoValue("path"), ++ Protocol: f.PseudoValue("protocol"), + } + + // extended connect is disabled, so we should not see :protocol -+ if disableExtendedConnectProtocol && rp.protocol != "" { ++ if disableExtendedConnectProtocol && rp.Protocol != "" { + return nil, nil, sc.countError("bad_connect", streamError(f.StreamID, ErrCodeProtocol)) } - isConnect := rp.method == "CONNECT" +- isConnect := rp.method == "CONNECT" ++ isConnect := rp.Method == "CONNECT" if isConnect { - if rp.path != "" || rp.scheme != "" || rp.authority == "" { -+ if rp.protocol == "" && (rp.path != "" || rp.scheme != "" || rp.authority == "") { ++ if rp.Protocol == "" && (rp.Path != "" || rp.Scheme != "" || rp.Authority == "") { return nil, nil, sc.countError("bad_connect", streamError(f.StreamID, ErrCodeProtocol)) } - } else if rp.method == "" || rp.path == "" || (rp.scheme != "https" && rp.scheme != "http") { -@@ -2171,6 +2272,9 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res - if rp.authority == "" { - rp.authority = rp.header.Get("Host") +- } else if rp.method == "" || rp.path == "" || (rp.scheme != "https" && rp.scheme != "http") { ++ } else if rp.Method == "" || rp.Path == "" || (rp.Scheme != "https" && rp.Scheme != "http") { + // See 8.1.2.6 Malformed Requests and Responses: + // + // Malformed requests or responses that are detected +@@ -2164,12 +2265,16 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res + return nil, nil, sc.countError("bad_path_method", streamError(f.StreamID, ErrCodeProtocol)) } -+ if rp.protocol != "" { -+ rp.header.Set(":protocol", rp.protocol) + +- rp.header = make(http.Header) ++ header := make(http.Header) ++ rp.Header = header + for _, hf := range f.RegularFields() { +- rp.header.Add(sc.canonicalHeader(hf.Name), hf.Value) ++ header.Add(sc.canonicalHeader(hf.Name), hf.Value) + } ++ if rp.Authority == "" { ++ rp.Authority = header.Get("Host") + } +- if rp.authority == "" { +- rp.authority = rp.header.Get("Host") ++ if rp.Protocol != "" { ++ header.Set(":protocol", rp.Protocol) + } rw, req, err := sc.newWriterAndRequestNoBody(st, rp) - if err != nil { -@@ -2197,6 +2301,7 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res - type requestParam struct { - method string - scheme, authority, path string -+ protocol string - header http.Header +@@ -2178,7 +2283,7 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res + } + bodyOpen := !f.StreamEnded() + if bodyOpen { +- if vv, ok := rp.header["Content-Length"]; ok { ++ if vv, ok := rp.Header["Content-Length"]; ok { + if cl, err := strconv.ParseUint(vv[0], 10, 63); err == nil { + req.ContentLength = int64(cl) + } else { +@@ -2194,83 +2299,38 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res + return rw, req, nil } -@@ -2238,7 +2343,7 @@ func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp requestParam) (*r +-type requestParam struct { +- method string +- scheme, authority, path string +- header http.Header +-} +- +-func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp requestParam) (*responseWriter, *http.Request, error) { ++func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp httpcommon.ServerRequestParam) (*responseWriter, *http.Request, error) { + sc.serveG.check() - var url_ *url.URL - var requestURI string -- if rp.method == "CONNECT" { -+ if rp.method == "CONNECT" && rp.protocol == "" { - url_ = &url.URL{Host: rp.authority} - requestURI = rp.authority // mimic HTTP/1 server behavior - } else { -@@ -2342,6 +2447,7 @@ func (sc *serverConn) handlerDone() { + var tlsState *tls.ConnectionState // nil if not scheme https +- if rp.scheme == "https" { ++ if rp.Scheme == "https" { + tlsState = sc.tlsState + } + +- needsContinue := httpguts.HeaderValuesContainsToken(rp.header["Expect"], "100-continue") +- if needsContinue { +- rp.header.Del("Expect") +- } +- // Merge Cookie headers into one "; "-delimited value. +- if cookies := rp.header["Cookie"]; len(cookies) > 1 { +- rp.header.Set("Cookie", strings.Join(cookies, "; ")) +- } +- +- // Setup Trailers +- var trailer http.Header +- for _, v := range rp.header["Trailer"] { +- for _, key := range strings.Split(v, ",") { +- key = http.CanonicalHeaderKey(textproto.TrimString(key)) +- switch key { +- case "Transfer-Encoding", "Trailer", "Content-Length": +- // Bogus. (copy of http1 rules) +- // Ignore. +- default: +- if trailer == nil { +- trailer = make(http.Header) +- } +- trailer[key] = nil +- } +- } +- } +- delete(rp.header, "Trailer") +- +- var url_ *url.URL +- var requestURI string +- if rp.method == "CONNECT" { +- url_ = &url.URL{Host: rp.authority} +- requestURI = rp.authority // mimic HTTP/1 server behavior +- } else { +- var err error +- url_, err = url.ParseRequestURI(rp.path) +- if err != nil { +- return nil, nil, sc.countError("bad_path", streamError(st.id, ErrCodeProtocol)) +- } +- requestURI = rp.path ++ res := httpcommon.NewServerRequest(rp) ++ if res.InvalidReason != "" { ++ return nil, nil, sc.countError(res.InvalidReason, streamError(st.id, ErrCodeProtocol)) + } + + body := &requestBody{ + conn: sc, + stream: st, +- needsContinue: needsContinue, ++ needsContinue: res.NeedsContinue, + } +- req := &http.Request{ +- Method: rp.method, +- URL: url_, ++ req := (&http.Request{ ++ Method: rp.Method, ++ URL: res.URL, + RemoteAddr: sc.remoteAddrStr, +- Header: rp.header, +- RequestURI: requestURI, ++ Header: rp.Header, ++ RequestURI: res.RequestURI, + Proto: "HTTP/2.0", + ProtoMajor: 2, + ProtoMinor: 0, + TLS: tlsState, +- Host: rp.authority, ++ Host: rp.Authority, + Body: body, +- Trailer: trailer, +- } +- req = req.WithContext(st.ctx) +- ++ Trailer: res.Trailer, ++ }).WithContext(st.ctx) + rw := sc.newResponseWriter(st, req) + return rw, req, nil + } +@@ -2342,6 +2402,7 @@ func (sc *serverConn) handlerDone() { // Run on its own goroutine. func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler func(http.ResponseWriter, *http.Request)) { @@ -1541,7 +2409,7 @@ index ce2e8b40e..b55547aec 100644 defer sc.sendServeMsg(handlerDoneMsg) didPanic := true defer func() { -@@ -2638,7 +2744,7 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) { +@@ -2638,7 +2699,7 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) { var date string if _, ok := rws.snapHeader["Date"]; !ok { // TODO(bradfitz): be faster here, like net/http? measure. @@ -1550,7 +2418,7 @@ index ce2e8b40e..b55547aec 100644 } for _, v := range rws.snapHeader["Trailer"] { -@@ -2760,7 +2866,7 @@ func (rws *responseWriterState) promoteUndeclaredTrailers() { +@@ -2760,7 +2821,7 @@ func (rws *responseWriterState) promoteUndeclaredTrailers() { func (w *responseWriter) SetReadDeadline(deadline time.Time) error { st := w.rws.stream @@ -1559,7 +2427,7 @@ index ce2e8b40e..b55547aec 100644 // If we're setting a deadline in the past, reset the stream immediately // so writes after SetWriteDeadline returns will fail. st.onReadTimeout() -@@ -2776,9 +2882,9 @@ func (w *responseWriter) SetReadDeadline(deadline time.Time) error { +@@ -2776,9 +2837,9 @@ func (w *responseWriter) SetReadDeadline(deadline time.Time) error { if deadline.IsZero() { st.readDeadline = nil } else if st.readDeadline == nil { @@ -1571,7 +2439,7 @@ index ce2e8b40e..b55547aec 100644 } }) return nil -@@ -2786,7 +2892,7 @@ func (w *responseWriter) SetReadDeadline(deadline time.Time) error { +@@ -2786,7 +2847,7 @@ func (w *responseWriter) SetReadDeadline(deadline time.Time) error { func (w *responseWriter) SetWriteDeadline(deadline time.Time) error { st := w.rws.stream @@ -1580,7 +2448,7 @@ index ce2e8b40e..b55547aec 100644 // If we're setting a deadline in the past, reset the stream immediately // so writes after SetWriteDeadline returns will fail. st.onWriteTimeout() -@@ -2802,14 +2908,19 @@ func (w *responseWriter) SetWriteDeadline(deadline time.Time) error { +@@ -2802,14 +2863,19 @@ func (w *responseWriter) SetWriteDeadline(deadline time.Time) error { if deadline.IsZero() { st.writeDeadline = nil } else if st.writeDeadline == nil { @@ -1602,7 +2470,26 @@ index ce2e8b40e..b55547aec 100644 func (w *responseWriter) Flush() { w.FlushError() } -@@ -3256,7 +3367,7 @@ func (sc *serverConn) countError(name string, err error) error { +@@ -3159,12 +3225,12 @@ func (sc *serverConn) startPush(msg *startPushRequest) { + // we start in "half closed (remote)" for simplicity. + // See further comments at the definition of stateHalfClosedRemote. + promised := sc.newStream(promisedID, msg.parent.id, stateHalfClosedRemote) +- rw, req, err := sc.newWriterAndRequestNoBody(promised, requestParam{ +- method: msg.method, +- scheme: msg.url.Scheme, +- authority: msg.url.Host, +- path: msg.url.RequestURI(), +- header: cloneHeader(msg.header), // clone since handler runs concurrently with writing the PUSH_PROMISE ++ rw, req, err := sc.newWriterAndRequestNoBody(promised, httpcommon.ServerRequestParam{ ++ Method: msg.method, ++ Scheme: msg.url.Scheme, ++ Authority: msg.url.Host, ++ Path: msg.url.RequestURI(), ++ Header: cloneHeader(msg.header), // clone since handler runs concurrently with writing the PUSH_PROMISE + }) + if err != nil { + // Should not happen, since we've already validated msg.url. +@@ -3256,7 +3322,7 @@ func (sc *serverConn) countError(name string, err error) error { if sc == nil || sc.srv == nil { return err } @@ -1975,17 +2862,26 @@ index 000000000..0b1c17b81 + +func (t timeTimer) C() <-chan time.Time { return t.Timer.C } diff --git a/api/vendor/golang.org/x/net/http2/transport.go b/api/vendor/golang.org/x/net/http2/transport.go -index ce375c8c7..090d0e1bd 100644 +index ce375c8c7..f26356b9c 100644 --- a/api/vendor/golang.org/x/net/http2/transport.go +++ b/api/vendor/golang.org/x/net/http2/transport.go -@@ -25,7 +25,6 @@ import ( +@@ -25,8 +25,6 @@ import ( "net/http" "net/http/httptrace" "net/textproto" - "os" - "sort" +- "sort" "strconv" "strings" + "sync" +@@ -36,6 +34,7 @@ import ( + "golang.org/x/net/http/httpguts" + "golang.org/x/net/http2/hpack" + "golang.org/x/net/idna" ++ "golang.org/x/net/internal/httpcommon" + ) + + const ( @@ -185,42 +184,80 @@ type Transport struct { connPoolOnce sync.Once connPoolOrDef ClientConnPool // non-nil version of ConnPool @@ -2151,7 +3047,7 @@ index ce375c8c7..090d0e1bd 100644 singleUse bool // whether being used for a single http.Request getConnCalled bool // used by clientConnPool -@@ -312,31 +368,54 @@ type ClientConn struct { +@@ -312,31 +368,55 @@ type ClientConn struct { idleTimeout time.Duration // or 0 for never idleTimer timer @@ -2181,6 +3077,7 @@ index ce375c8c7..090d0e1bd 100644 + doNotReuse bool // whether conn is marked to not be reused for any future requests + closing bool + closed bool ++ closedOnIdle bool // true if conn was closed for idleness + seenSettings bool // true if we've seen a settings frame, false otherwise + seenSettingsChan chan struct{} // closed when seenSettings is true or frame reading fails + wantSettingsAck bool // we sent a SETTINGS frame and haven't heard back @@ -2230,7 +3127,7 @@ index ce375c8c7..090d0e1bd 100644 // reqHeaderMu is a 1-element semaphore channel controlling access to sending new requests. // Write to reqHeaderMu to lock it, read from it to unlock. -@@ -352,60 +431,6 @@ type ClientConn struct { +@@ -352,60 +432,6 @@ type ClientConn struct { werr error // first write error that has occurred hbuf bytes.Buffer // HPACK encoder writes into this henc *hpack.Encoder @@ -2291,7 +3188,7 @@ index ce375c8c7..090d0e1bd 100644 } // clientStream is the state for a single HTTP/2 stream. One of these -@@ -448,12 +473,12 @@ type clientStream struct { +@@ -448,12 +474,12 @@ type clientStream struct { sentHeaders bool // owned by clientConnReadLoop: @@ -2310,7 +3207,7 @@ index ce375c8c7..090d0e1bd 100644 trailer http.Header // accumulated trailers resTrailer *http.Header // client's Response.Trailer -@@ -487,7 +512,7 @@ func (cs *clientStream) abortStreamLocked(err error) { +@@ -487,7 +513,7 @@ func (cs *clientStream) abortStreamLocked(err error) { // TODO(dneil): Clean up tests where cs.cc.cond is nil. if cs.cc.cond != nil { // Wake up writeRequestBody if it is waiting on flow control. @@ -2319,7 +3216,7 @@ index ce375c8c7..090d0e1bd 100644 } } -@@ -497,7 +522,7 @@ func (cs *clientStream) abortRequestBodyWrite() { +@@ -497,7 +523,7 @@ func (cs *clientStream) abortRequestBodyWrite() { defer cc.mu.Unlock() if cs.reqBody != nil && cs.reqBodyClosed == nil { cs.closeReqBodyLocked() @@ -2328,7 +3225,7 @@ index ce375c8c7..090d0e1bd 100644 } } -@@ -507,13 +532,15 @@ func (cs *clientStream) closeReqBodyLocked() { +@@ -507,13 +533,15 @@ func (cs *clientStream) closeReqBodyLocked() { } cs.reqBodyClosed = make(chan struct{}) reqBodyClosed := cs.reqBodyClosed @@ -2346,7 +3243,7 @@ index ce375c8c7..090d0e1bd 100644 conn net.Conn timeout time.Duration err *error -@@ -523,22 +550,9 @@ func (sew stickyErrWriter) Write(p []byte) (n int, err error) { +@@ -523,22 +551,9 @@ func (sew stickyErrWriter) Write(p []byte) (n int, err error) { if *sew.err != nil { return 0, *sew.err } @@ -2372,7 +3269,7 @@ index ce375c8c7..090d0e1bd 100644 } // noCachedConnError is the concrete type of ErrNoCachedConn, which -@@ -569,6 +583,8 @@ type RoundTripOpt struct { +@@ -569,6 +584,8 @@ type RoundTripOpt struct { // no cached connection is available, RoundTripOpt // will return ErrNoCachedConn. OnlyCachedConn bool @@ -2381,7 +3278,7 @@ index ce375c8c7..090d0e1bd 100644 } func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) { -@@ -601,7 +617,14 @@ func authorityAddr(scheme string, authority string) (addr string) { +@@ -601,7 +618,14 @@ func authorityAddr(scheme string, authority string) (addr string) { // RoundTripOpt is like RoundTrip, but takes options. func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Response, error) { @@ -2397,7 +3294,7 @@ index ce375c8c7..090d0e1bd 100644 return nil, errors.New("http2: unsupported scheme") } -@@ -612,7 +635,7 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res +@@ -612,7 +636,7 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res t.vlogf("http2: Transport failed to get client conn for %s: %v", addr, err) return nil, err } @@ -2406,7 +3303,7 @@ index ce375c8c7..090d0e1bd 100644 traceGotConn(req, cc, reused) res, err := cc.RoundTrip(req) if err != nil && retry <= 6 { -@@ -626,21 +649,7 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res +@@ -626,21 +650,7 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res backoff := float64(uint(1) << (uint(retry) - 1)) backoff += backoff * (0.1 * mathrand.Float64()) d := time.Second * time.Duration(backoff) @@ -2429,7 +3326,7 @@ index ce375c8c7..090d0e1bd 100644 select { case <-tm.C(): t.vlogf("RoundTrip retrying after failure: %v", roundTripErr) -@@ -651,6 +660,22 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res +@@ -651,6 +661,22 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res } } } @@ -2452,7 +3349,7 @@ index ce375c8c7..090d0e1bd 100644 if err != nil { t.vlogf("RoundTrip failure: %v", err) return nil, err -@@ -669,9 +694,10 @@ func (t *Transport) CloseIdleConnections() { +@@ -669,9 +695,10 @@ func (t *Transport) CloseIdleConnections() { } var ( @@ -2466,7 +3363,7 @@ index ce375c8c7..090d0e1bd 100644 ) // shouldRetryRequest is called by RoundTrip when a request fails to get -@@ -725,8 +751,8 @@ func canRetryError(err error) bool { +@@ -725,8 +752,8 @@ func canRetryError(err error) bool { } func (t *Transport) dialClientConn(ctx context.Context, addr string, singleUse bool) (*ClientConn, error) { @@ -2477,7 +3374,7 @@ index ce375c8c7..090d0e1bd 100644 } host, _, err := net.SplitHostPort(addr) if err != nil { -@@ -736,7 +762,7 @@ func (t *Transport) dialClientConn(ctx context.Context, addr string, singleUse b +@@ -736,7 +763,7 @@ func (t *Transport) dialClientConn(ctx context.Context, addr string, singleUse b if err != nil { return nil, err } @@ -2486,7 +3383,7 @@ index ce375c8c7..090d0e1bd 100644 } func (t *Transport) newTLSConfig(host string) *tls.Config { -@@ -787,48 +813,38 @@ func (t *Transport) expectContinueTimeout() time.Duration { +@@ -787,48 +814,38 @@ func (t *Transport) expectContinueTimeout() time.Duration { return t.t1.ExpectContinueTimeout } @@ -2562,7 +3459,7 @@ index ce375c8c7..090d0e1bd 100644 } if VerboseLogs { t.vlogf("http2: Transport creating client conn %p to %v", cc, c.RemoteAddr()) -@@ -840,30 +856,25 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool, hooks *testSyncHoo +@@ -840,30 +857,25 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool, hooks *testSyncHoo // TODO: adjust this writer size to account for frame size + // MTU + crypto/tls record padding. cc.bw = bufio.NewWriter(stickyErrWriter{ @@ -2598,7 +3495,7 @@ index ce375c8c7..090d0e1bd 100644 if cs, ok := c.(connectionStater); ok { state := cs.ConnectionState() cc.tlsState = &state -@@ -871,11 +882,9 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool, hooks *testSyncHoo +@@ -871,11 +883,9 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool, hooks *testSyncHoo initialSettings := []Setting{ {ID: SettingEnablePush, Val: 0}, @@ -2612,7 +3509,7 @@ index ce375c8c7..090d0e1bd 100644 if max := t.maxHeaderListSize(); max != 0 { initialSettings = append(initialSettings, Setting{ID: SettingMaxHeaderListSize, Val: max}) } -@@ -885,23 +894,29 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool, hooks *testSyncHoo +@@ -885,23 +895,29 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool, hooks *testSyncHoo cc.bw.Write(clientPreface) cc.fr.WriteSettings(initialSettings...) @@ -2647,7 +3544,7 @@ index ce375c8c7..090d0e1bd 100644 defer cancel() cc.vlogf("http2: Transport sending health check") err := cc.Ping(ctx) -@@ -936,7 +951,20 @@ func (cc *ClientConn) setGoAway(f *GoAwayFrame) { +@@ -936,7 +952,20 @@ func (cc *ClientConn) setGoAway(f *GoAwayFrame) { } last := f.LastStreamID for streamID, cs := range cc.streams { @@ -2669,7 +3566,7 @@ index ce375c8c7..090d0e1bd 100644 cs.abortStreamLocked(errClientConnGotGoAway) } } -@@ -1013,7 +1041,7 @@ func (cc *ClientConn) State() ClientConnState { +@@ -1013,7 +1042,7 @@ func (cc *ClientConn) State() ClientConnState { return ClientConnState{ Closed: cc.closed, Closing: cc.closing || cc.singleUse || cc.doNotReuse || cc.goAway != nil, @@ -2678,7 +3575,7 @@ index ce375c8c7..090d0e1bd 100644 StreamsReserved: cc.streamsReserved, StreamsPending: cc.pendingRequests, LastIdle: cc.lastIdle, -@@ -1045,16 +1073,38 @@ func (cc *ClientConn) idleStateLocked() (st clientConnIdleState) { +@@ -1045,16 +1074,40 @@ func (cc *ClientConn) idleStateLocked() (st clientConnIdleState) { // writing it. maxConcurrentOkay = true } else { @@ -2699,10 +3596,12 @@ index ce375c8c7..090d0e1bd 100644 + + // If this connection has never been used for a request and is closed, + // then let it take a request (which will fail). ++ // If the conn was closed for idleness, we're racing the idle timer; ++ // don't try to use the conn. (Issue #70515.) + // + // This avoids a situation where an error early in a connection's lifetime + // goes unreported. -+ if cc.nextStreamID == 1 && cc.streamsReserved == 0 && cc.closed { ++ if cc.nextStreamID == 1 && cc.streamsReserved == 0 && cc.closed && !cc.closedOnIdle { + st.canTakeNewRequest = true + } + @@ -2718,7 +3617,7 @@ index ce375c8c7..090d0e1bd 100644 func (cc *ClientConn) canTakeNewRequestLocked() bool { st := cc.idleStateLocked() return st.canTakeNewRequest -@@ -1067,7 +1117,7 @@ func (cc *ClientConn) tooIdleLocked() bool { +@@ -1067,7 +1120,7 @@ func (cc *ClientConn) tooIdleLocked() bool { // times are compared based on their wall time. We don't want // to reuse a connection that's been sitting idle during // VM/laptop suspend if monotonic time was also frozen. @@ -2727,7 +3626,15 @@ index ce375c8c7..090d0e1bd 100644 } // onIdleTimeout is called from a time.AfterFunc goroutine. It will -@@ -1131,7 +1181,8 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error { +@@ -1105,6 +1158,7 @@ func (cc *ClientConn) closeIfIdle() { + return + } + cc.closed = true ++ cc.closedOnIdle = true + nextID := cc.nextStreamID + // TODO: do clients send GOAWAY too? maybe? Just Close: + cc.mu.Unlock() +@@ -1131,7 +1185,8 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error { // Wait for all in-flight streams to complete or connection to close done := make(chan struct{}) cancelled := false // guarded by cc.mu @@ -2737,7 +3644,7 @@ index ce375c8c7..090d0e1bd 100644 cc.mu.Lock() defer cc.mu.Unlock() for { -@@ -1143,9 +1194,9 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error { +@@ -1143,9 +1198,9 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error { if cancelled { break } @@ -2749,7 +3656,7 @@ index ce375c8c7..090d0e1bd 100644 shutdownEnterWaitStateHook() select { case <-done: -@@ -1155,7 +1206,7 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error { +@@ -1155,7 +1210,7 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error { cc.mu.Lock() // Free the goroutine above cancelled = true @@ -2758,7 +3665,7 @@ index ce375c8c7..090d0e1bd 100644 cc.mu.Unlock() return ctx.Err() } -@@ -1193,7 +1244,7 @@ func (cc *ClientConn) closeForError(err error) { +@@ -1193,7 +1248,7 @@ func (cc *ClientConn) closeForError(err error) { for _, cs := range cc.streams { cs.abortStreamLocked(err) } @@ -2767,7 +3674,54 @@ index ce375c8c7..090d0e1bd 100644 cc.mu.Unlock() cc.closeConn() } -@@ -1308,23 +1359,30 @@ func (cc *ClientConn) roundTrip(req *http.Request, streamf func(*clientStream)) +@@ -1220,23 +1275,6 @@ func (cc *ClientConn) closeForLostPing() { + // exported. At least they'll be DeepEqual for h1-vs-h2 comparisons tests. + var errRequestCanceled = errors.New("net/http: request canceled") + +-func commaSeparatedTrailers(req *http.Request) (string, error) { +- keys := make([]string, 0, len(req.Trailer)) +- for k := range req.Trailer { +- k = canonicalHeader(k) +- switch k { +- case "Transfer-Encoding", "Trailer", "Content-Length": +- return "", fmt.Errorf("invalid Trailer key %q", k) +- } +- keys = append(keys, k) +- } +- if len(keys) > 0 { +- sort.Strings(keys) +- return strings.Join(keys, ","), nil +- } +- return "", nil +-} +- + func (cc *ClientConn) responseHeaderTimeout() time.Duration { + if cc.t.t1 != nil { + return cc.t.t1.ResponseHeaderTimeout +@@ -1248,22 +1286,6 @@ func (cc *ClientConn) responseHeaderTimeout() time.Duration { + return 0 + } + +-// checkConnHeaders checks whether req has any invalid connection-level headers. +-// per RFC 7540 section 8.1.2.2: Connection-Specific Header Fields. +-// Certain headers are special-cased as okay but not transmitted later. +-func checkConnHeaders(req *http.Request) error { +- if v := req.Header.Get("Upgrade"); v != "" { +- return fmt.Errorf("http2: invalid Upgrade request header: %q", req.Header["Upgrade"]) +- } +- if vv := req.Header["Transfer-Encoding"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && vv[0] != "chunked") { +- return fmt.Errorf("http2: invalid Transfer-Encoding request header: %q", vv) +- } +- if vv := req.Header["Connection"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && !asciiEqualFold(vv[0], "close") && !asciiEqualFold(vv[0], "keep-alive")) { +- return fmt.Errorf("http2: invalid Connection request header: %q", vv) +- } +- return nil +-} +- + // actualContentLength returns a sanitized version of + // req.ContentLength, where 0 actually means zero (not unknown) and -1 + // means unknown. +@@ -1308,23 +1330,12 @@ func (cc *ClientConn) roundTrip(req *http.Request, streamf func(*clientStream)) respHeaderRecv: make(chan struct{}), donec: make(chan struct{}), } @@ -2775,25 +3729,7 @@ index ce375c8c7..090d0e1bd 100644 - cs.doRequest(req) - }) + -+ // TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere? -+ if !cc.t.disableCompression() && -+ req.Header.Get("Accept-Encoding") == "" && -+ req.Header.Get("Range") == "" && -+ !cs.isHead { -+ // Request gzip only, not deflate. Deflate is ambiguous and -+ // not as universally supported anyway. -+ // See: https://zlib.net/zlib_faq.html#faq39 -+ // -+ // Note that we don't request this for HEAD requests, -+ // due to a bug in nginx: -+ // http://trac.nginx.org/nginx/ticket/358 -+ // https://golang.org/issue/5522 -+ // -+ // We don't request gzip if the request is for a range, since -+ // auto-decoding a portion of a gzipped document will just fail -+ // anyway. See https://golang.org/issue/8923 -+ cs.requestedGzip = true -+ } ++ cs.requestedGzip = httpcommon.IsRequestGzip(req.Method, req.Header, cc.t.disableCompression()) + + go cs.doRequest(req, streamf) @@ -2813,7 +3749,7 @@ index ce375c8c7..090d0e1bd 100644 select { case <-cs.donec: return nil -@@ -1385,24 +1443,7 @@ func (cc *ClientConn) roundTrip(req *http.Request, streamf func(*clientStream)) +@@ -1385,24 +1396,7 @@ func (cc *ClientConn) roundTrip(req *http.Request, streamf func(*clientStream)) return err } @@ -2838,7 +3774,7 @@ index ce375c8c7..090d0e1bd 100644 select { case <-cs.respHeaderRecv: return handleResponseHeaders() -@@ -1432,11 +1473,14 @@ func (cc *ClientConn) roundTrip(req *http.Request, streamf func(*clientStream)) +@@ -1432,11 +1426,14 @@ func (cc *ClientConn) roundTrip(req *http.Request, streamf func(*clientStream)) // doRequest runs for the duration of the request lifetime. // // It sends the request and performs post-request cleanup (closing Request.Body, etc.). @@ -2855,7 +3791,7 @@ index ce375c8c7..090d0e1bd 100644 // writeRequest sends a request. // // It returns nil after the request is written, the response read, -@@ -1444,7 +1488,7 @@ func (cs *clientStream) doRequest(req *http.Request) { +@@ -1444,12 +1441,15 @@ func (cs *clientStream) doRequest(req *http.Request) { // // It returns non-nil if the request ends otherwise. // If the returned error is StreamError, the error Code may be used in resetting the stream. @@ -2864,20 +3800,17 @@ index ce375c8c7..090d0e1bd 100644 cc := cs.cc ctx := cs.ctx -@@ -1452,26 +1496,30 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) { - return err - } - +- if err := checkConnHeaders(req); err != nil { +- return err + // wait for setting frames to be received, a server can change this value later, + // but we just wait for the first settings frame + var isExtendedConnect bool + if req.Method == "CONNECT" && req.Header.Get(":protocol") != "" { + isExtendedConnect = true -+ } -+ + } + // Acquire the new-request lock by writing to reqHeaderMu. - // This lock guards the critical section covering allocating a new stream ID - // (requires mu) and creating the stream (requires wmu). +@@ -1458,20 +1458,17 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) { if cc.reqHeaderMu == nil { panic("RoundTrip on uninitialized ClientConn") // for tests } @@ -2908,7 +3841,7 @@ index ce375c8c7..090d0e1bd 100644 } select { case cc.reqHeaderMu <- struct{}{}: -@@ -1497,28 +1545,8 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) { +@@ -1497,28 +1494,8 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) { } cc.mu.Unlock() @@ -2939,7 +3872,7 @@ index ce375c8c7..090d0e1bd 100644 } continueTimeout := cc.t.expectContinueTimeout() -@@ -1581,7 +1609,7 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) { +@@ -1581,7 +1558,7 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) { var respHeaderTimer <-chan time.Time var respHeaderRecv chan struct{} if d := cc.responseHeaderTimeout(); d != 0 { @@ -2948,7 +3881,7 @@ index ce375c8c7..090d0e1bd 100644 defer timer.Stop() respHeaderTimer = timer.C() respHeaderRecv = cs.respHeaderRecv -@@ -1590,21 +1618,6 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) { +@@ -1590,21 +1567,6 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) { // or until the request is aborted (via context, error, or otherwise), // whichever comes first. for { @@ -2970,7 +3903,57 @@ index ce375c8c7..090d0e1bd 100644 select { case <-cs.peerClosed: return nil -@@ -1689,6 +1702,7 @@ func (cs *clientStream) cleanupWriteRequest(err error) { +@@ -1646,26 +1608,39 @@ func (cs *clientStream) encodeAndWriteHeaders(req *http.Request) error { + // we send: HEADERS{1}, CONTINUATION{0,} + DATA{0,} (DATA is + // sent by writeRequestBody below, along with any Trailers, + // again in form HEADERS{1}, CONTINUATION{0,}) +- trailers, err := commaSeparatedTrailers(req) +- if err != nil { +- return err +- } +- hasTrailers := trailers != "" +- contentLen := actualContentLength(req) +- hasBody := contentLen != 0 +- hdrs, err := cc.encodeHeaders(req, cs.requestedGzip, trailers, contentLen) ++ cc.hbuf.Reset() ++ res, err := encodeRequestHeaders(req, cs.requestedGzip, cc.peerMaxHeaderListSize, func(name, value string) { ++ cc.writeHeader(name, value) ++ }) + if err != nil { +- return err ++ return fmt.Errorf("http2: %w", err) + } ++ hdrs := cc.hbuf.Bytes() + + // Write the request. +- endStream := !hasBody && !hasTrailers ++ endStream := !res.HasBody && !res.HasTrailers + cs.sentHeaders = true + err = cc.writeHeaders(cs.ID, endStream, int(cc.maxFrameSize), hdrs) + traceWroteHeaders(cs.trace) + return err + } + ++func encodeRequestHeaders(req *http.Request, addGzipHeader bool, peerMaxHeaderListSize uint64, headerf func(name, value string)) (httpcommon.EncodeHeadersResult, error) { ++ return httpcommon.EncodeHeaders(req.Context(), httpcommon.EncodeHeadersParam{ ++ Request: httpcommon.Request{ ++ Header: req.Header, ++ Trailer: req.Trailer, ++ URL: req.URL, ++ Host: req.Host, ++ Method: req.Method, ++ ActualContentLength: actualContentLength(req), ++ }, ++ AddGzipHeader: addGzipHeader, ++ PeerMaxHeaderListSize: peerMaxHeaderListSize, ++ DefaultUserAgent: defaultUserAgent, ++ }, headerf) ++} ++ + // cleanupWriteRequest performs post-request tasks. + // + // If err (the result of writeRequest) is non-nil and the stream is not closed, +@@ -1689,6 +1664,7 @@ func (cs *clientStream) cleanupWriteRequest(err error) { cs.reqBodyClosed = make(chan struct{}) } bodyClosed := cs.reqBodyClosed @@ -2978,7 +3961,7 @@ index ce375c8c7..090d0e1bd 100644 cc.mu.Unlock() if mustCloseBody { cs.reqBody.Close() -@@ -1713,16 +1727,44 @@ func (cs *clientStream) cleanupWriteRequest(err error) { +@@ -1713,16 +1689,44 @@ func (cs *clientStream) cleanupWriteRequest(err error) { if cs.sentHeaders { if se, ok := err.(StreamError); ok { if se.Cause != errFromPeer { @@ -3026,7 +4009,7 @@ index ce375c8c7..090d0e1bd 100644 } cs.bufPipe.CloseWithError(errRequestCanceled) } -@@ -1744,16 +1786,21 @@ func (cs *clientStream) cleanupWriteRequest(err error) { +@@ -1744,16 +1748,21 @@ func (cs *clientStream) cleanupWriteRequest(err error) { // Must hold cc.mu. func (cc *ClientConn) awaitOpenSlotForStreamLocked(cs *clientStream) error { for { @@ -3051,52 +4034,233 @@ index ce375c8c7..090d0e1bd 100644 cc.pendingRequests-- select { case <-cs.abort: -@@ -2015,13 +2062,13 @@ func (cs *clientStream) awaitFlowControl(maxBytes int) (taken int32, err error) +@@ -2015,215 +2024,7 @@ func (cs *clientStream) awaitFlowControl(maxBytes int) (taken int32, err error) cs.flow.take(take) return take, nil } - cc.condWait() +- } +-} +- +-func validateHeaders(hdrs http.Header) string { +- for k, vv := range hdrs { +- if !httpguts.ValidHeaderFieldName(k) { +- return fmt.Sprintf("name %q", k) +- } +- for _, v := range vv { +- if !httpguts.ValidHeaderFieldValue(v) { +- // Don't include the value in the error, +- // because it may be sensitive. +- return fmt.Sprintf("value for header %q", k) +- } +- } +- } +- return "" +-} +- +-var errNilRequestURL = errors.New("http2: Request.URI is nil") +- +-// requires cc.wmu be held. +-func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trailers string, contentLength int64) ([]byte, error) { +- cc.hbuf.Reset() +- if req.URL == nil { +- return nil, errNilRequestURL +- } +- +- host := req.Host +- if host == "" { +- host = req.URL.Host +- } +- host, err := httpguts.PunycodeHostPort(host) +- if err != nil { +- return nil, err +- } +- if !httpguts.ValidHostHeader(host) { +- return nil, errors.New("http2: invalid Host header") +- } +- +- var path string +- if req.Method != "CONNECT" { +- path = req.URL.RequestURI() +- if !validPseudoPath(path) { +- orig := path +- path = strings.TrimPrefix(path, req.URL.Scheme+"://"+host) +- if !validPseudoPath(path) { +- if req.URL.Opaque != "" { +- return nil, fmt.Errorf("invalid request :path %q from URL.Opaque = %q", orig, req.URL.Opaque) +- } else { +- return nil, fmt.Errorf("invalid request :path %q", orig) +- } +- } +- } +- } +- +- // Check for any invalid headers+trailers and return an error before we +- // potentially pollute our hpack state. (We want to be able to +- // continue to reuse the hpack encoder for future requests) +- if err := validateHeaders(req.Header); err != "" { +- return nil, fmt.Errorf("invalid HTTP header %s", err) +- } +- if err := validateHeaders(req.Trailer); err != "" { +- return nil, fmt.Errorf("invalid HTTP trailer %s", err) +- } +- +- enumerateHeaders := func(f func(name, value string)) { +- // 8.1.2.3 Request Pseudo-Header Fields +- // The :path pseudo-header field includes the path and query parts of the +- // target URI (the path-absolute production and optionally a '?' character +- // followed by the query production, see Sections 3.3 and 3.4 of +- // [RFC3986]). +- f(":authority", host) +- m := req.Method +- if m == "" { +- m = http.MethodGet +- } +- f(":method", m) +- if req.Method != "CONNECT" { +- f(":path", path) +- f(":scheme", req.URL.Scheme) +- } +- if trailers != "" { +- f("trailer", trailers) +- } +- +- var didUA bool +- for k, vv := range req.Header { +- if asciiEqualFold(k, "host") || asciiEqualFold(k, "content-length") { +- // Host is :authority, already sent. +- // Content-Length is automatic, set below. +- continue +- } else if asciiEqualFold(k, "connection") || +- asciiEqualFold(k, "proxy-connection") || +- asciiEqualFold(k, "transfer-encoding") || +- asciiEqualFold(k, "upgrade") || +- asciiEqualFold(k, "keep-alive") { +- // Per 8.1.2.2 Connection-Specific Header +- // Fields, don't send connection-specific +- // fields. We have already checked if any +- // are error-worthy so just ignore the rest. +- continue +- } else if asciiEqualFold(k, "user-agent") { +- // Match Go's http1 behavior: at most one +- // User-Agent. If set to nil or empty string, +- // then omit it. Otherwise if not mentioned, +- // include the default (below). +- didUA = true +- if len(vv) < 1 { +- continue +- } +- vv = vv[:1] +- if vv[0] == "" { +- continue +- } +- } else if asciiEqualFold(k, "cookie") { +- // Per 8.1.2.5 To allow for better compression efficiency, the +- // Cookie header field MAY be split into separate header fields, +- // each with one or more cookie-pairs. +- for _, v := range vv { +- for { +- p := strings.IndexByte(v, ';') +- if p < 0 { +- break +- } +- f("cookie", v[:p]) +- p++ +- // strip space after semicolon if any. +- for p+1 <= len(v) && v[p] == ' ' { +- p++ +- } +- v = v[p:] +- } +- if len(v) > 0 { +- f("cookie", v) +- } +- } +- continue +- } +- +- for _, v := range vv { +- f(k, v) +- } +- } +- if shouldSendReqContentLength(req.Method, contentLength) { +- f("content-length", strconv.FormatInt(contentLength, 10)) +- } +- if addGzipHeader { +- f("accept-encoding", "gzip") +- } +- if !didUA { +- f("user-agent", defaultUserAgent) +- } +- } +- +- // Do a first pass over the headers counting bytes to ensure +- // we don't exceed cc.peerMaxHeaderListSize. This is done as a +- // separate pass before encoding the headers to prevent +- // modifying the hpack state. +- hlSize := uint64(0) +- enumerateHeaders(func(name, value string) { +- hf := hpack.HeaderField{Name: name, Value: value} +- hlSize += uint64(hf.Size()) +- }) +- +- if hlSize > cc.peerMaxHeaderListSize { +- return nil, errRequestHeaderListSize +- } +- +- trace := httptrace.ContextClientTrace(req.Context()) +- traceHeaders := traceHasWroteHeaderField(trace) +- +- // Header list size is ok. Write the headers. +- enumerateHeaders(func(name, value string) { +- name, ascii := lowerHeader(name) +- if !ascii { +- // Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header +- // field names have to be ASCII characters (just as in HTTP/1.x). +- return +- } +- cc.writeHeader(name, value) +- if traceHeaders { +- traceWroteHeaderField(trace, name, value) +- } +- }) +- +- return cc.hbuf.Bytes(), nil +-} +- +-// shouldSendReqContentLength reports whether the http2.Transport should send +-// a "content-length" request header. This logic is basically a copy of the net/http +-// transferWriter.shouldSendContentLength. +-// The contentLength is the corrected contentLength (so 0 means actually 0, not unknown). +-// -1 means unknown. +-func shouldSendReqContentLength(method string, contentLength int64) bool { +- if contentLength > 0 { +- return true +- } +- if contentLength < 0 { +- return false +- } +- // For zero bodies, whether we send a content-length depends on the method. +- // It also kinda doesn't matter for http2 either way, with END_STREAM. +- switch method { +- case "POST", "PUT", "PATCH": +- return true +- default: +- return false + cc.cond.Wait() } } - func validateHeaders(hdrs http.Header) string { - for k, vv := range hdrs { -- if !httpguts.ValidHeaderFieldName(k) { -+ if !httpguts.ValidHeaderFieldName(k) && k != ":protocol" { - return fmt.Sprintf("name %q", k) - } - for _, v := range vv { -@@ -2037,6 +2084,10 @@ func validateHeaders(hdrs http.Header) string { - - var errNilRequestURL = errors.New("http2: Request.URI is nil") - -+func isNormalConnect(req *http.Request) bool { -+ return req.Method == "CONNECT" && req.Header.Get(":protocol") == "" -+} -+ - // requires cc.wmu be held. - func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trailers string, contentLength int64) ([]byte, error) { - cc.hbuf.Reset() -@@ -2057,7 +2108,7 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail +@@ -2243,7 +2044,7 @@ func (cc *ClientConn) encodeTrailers(trailer http.Header) ([]byte, error) { } - var path string -- if req.Method != "CONNECT" { -+ if !isNormalConnect(req) { - path = req.URL.RequestURI() - if !validPseudoPath(path) { - orig := path -@@ -2094,7 +2145,7 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail - m = http.MethodGet - } - f(":method", m) -- if req.Method != "CONNECT" { -+ if !isNormalConnect(req) { - f(":path", path) - f(":scheme", req.URL.Scheme) - } -@@ -2275,7 +2326,7 @@ type resAndError struct { + for k, vv := range trailer { +- lowKey, ascii := lowerHeader(k) ++ lowKey, ascii := httpcommon.LowerHeader(k) + if !ascii { + // Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header + // field names have to be ASCII characters (just as in HTTP/1.x). +@@ -2275,7 +2076,7 @@ type resAndError struct { func (cc *ClientConn) addStreamLocked(cs *clientStream) { cs.flow.add(int32(cc.initialWindowSize)) cs.flow.setConnFlow(&cc.flow) @@ -3105,7 +4269,7 @@ index ce375c8c7..090d0e1bd 100644 cs.ID = cc.nextStreamID cc.nextStreamID += 2 cc.streams[cs.ID] = cs -@@ -2291,14 +2342,14 @@ func (cc *ClientConn) forgetStreamID(id uint32) { +@@ -2291,14 +2092,14 @@ func (cc *ClientConn) forgetStreamID(id uint32) { if len(cc.streams) != slen-1 { panic("forgetting unknown stream id") } @@ -3123,7 +4287,7 @@ index ce375c8c7..090d0e1bd 100644 closeOnIdle := cc.singleUse || cc.doNotReuse || cc.t.disableKeepAlives() || cc.goAway != nil if closeOnIdle && cc.streamsReserved == 0 && len(cc.streams) == 0 { -@@ -2320,6 +2371,7 @@ type clientConnReadLoop struct { +@@ -2320,6 +2121,7 @@ type clientConnReadLoop struct { // readLoop runs in its own goroutine and reads and dispatches frames. func (cc *ClientConn) readLoop() { @@ -3131,7 +4295,7 @@ index ce375c8c7..090d0e1bd 100644 rl := &clientConnReadLoop{cc: cc} defer rl.cleanup() cc.readerErr = rl.run() -@@ -2353,7 +2405,6 @@ func isEOFOrNetReadError(err error) bool { +@@ -2353,7 +2155,6 @@ func isEOFOrNetReadError(err error) bool { func (rl *clientConnReadLoop) cleanup() { cc := rl.cc @@ -3139,7 +4303,7 @@ index ce375c8c7..090d0e1bd 100644 defer cc.closeConn() defer close(cc.readerDone) -@@ -2377,6 +2428,24 @@ func (rl *clientConnReadLoop) cleanup() { +@@ -2377,6 +2178,27 @@ func (rl *clientConnReadLoop) cleanup() { } cc.closed = true @@ -3149,9 +4313,12 @@ index ce375c8c7..090d0e1bd 100644 + // This avoids a situation where new connections are constantly created, + // added to the pool, fail, and are removed from the pool, without any error + // being surfaced to the user. -+ const unusedWaitTime = 5 * time.Second ++ unusedWaitTime := 5 * time.Second ++ if cc.idleTimeout > 0 && unusedWaitTime > cc.idleTimeout { ++ unusedWaitTime = cc.idleTimeout ++ } + idleTime := cc.t.now().Sub(cc.lastActive) -+ if atomic.LoadUint32(&cc.atomicReused) == 0 && idleTime < unusedWaitTime { ++ if atomic.LoadUint32(&cc.atomicReused) == 0 && idleTime < unusedWaitTime && !cc.closedOnIdle { + cc.idleTimer = cc.t.afterFunc(unusedWaitTime-idleTime, func() { + cc.t.connPool().MarkDead(cc) + }) @@ -3164,16 +4331,24 @@ index ce375c8c7..090d0e1bd 100644 for _, cs := range cc.streams { select { case <-cs.peerClosed: -@@ -2386,7 +2455,7 @@ func (rl *clientConnReadLoop) cleanup() { +@@ -2386,8 +2208,15 @@ func (rl *clientConnReadLoop) cleanup() { cs.abortStreamLocked(err) } } - cc.condBroadcast() + cc.cond.Broadcast() cc.mu.Unlock() ++ ++ if !cc.seenSettings { ++ // If we have a pending request that wants extended CONNECT, ++ // let it continue and fail with the connection error. ++ cc.extendedConnectAllowed = true ++ close(cc.seenSettingsChan) ++ } } -@@ -2420,10 +2489,10 @@ func (cc *ClientConn) countReadFrameError(err error) { + // countReadFrameError calls Transport.CountError with a string +@@ -2420,10 +2249,10 @@ func (cc *ClientConn) countReadFrameError(err error) { func (rl *clientConnReadLoop) run() error { cc := rl.cc gotSettings := false @@ -3186,7 +4361,7 @@ index ce375c8c7..090d0e1bd 100644 } for { f, err := cc.fr.ReadFrame() -@@ -2434,7 +2503,7 @@ func (rl *clientConnReadLoop) run() error { +@@ -2434,7 +2263,7 @@ func (rl *clientConnReadLoop) run() error { cc.vlogf("http2: Transport readFrame error on conn %p: (%T) %v", cc, err, err) } if se, ok := err.(StreamError); ok { @@ -3195,16 +4370,7 @@ index ce375c8c7..090d0e1bd 100644 if se.Cause == nil { se.Cause = cc.fr.errDetail } -@@ -2480,13 +2549,16 @@ func (rl *clientConnReadLoop) run() error { - if VerboseLogs { - cc.vlogf("http2: Transport conn %p received error from processing frame %v: %v", cc, summarizeFrame(f), err) - } -+ if !cc.seenSettings { -+ close(cc.seenSettingsChan) -+ } - return err - } - } +@@ -2486,7 +2315,7 @@ func (rl *clientConnReadLoop) run() error { } func (rl *clientConnReadLoop) processHeaders(f *MetaHeadersFrame) error { @@ -3213,7 +4379,25 @@ index ce375c8c7..090d0e1bd 100644 if cs == nil { // We'd get here if we canceled a request while the // server had its response still in flight. So if this -@@ -2604,15 +2676,34 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra +@@ -2574,7 +2403,7 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra + Status: status + " " + http.StatusText(statusCode), + } + for _, hf := range regularFields { +- key := canonicalHeader(hf.Name) ++ key := httpcommon.CanonicalHeader(hf.Name) + if key == "Trailer" { + t := res.Trailer + if t == nil { +@@ -2582,7 +2411,7 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra + res.Trailer = t + } + foreachHeaderElement(hf.Value, func(v string) { +- t[canonicalHeader(v)] = nil ++ t[httpcommon.CanonicalHeader(v)] = nil + }) + } else { + vv := header[key] +@@ -2604,15 +2433,34 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra if f.StreamEnded() { return nil, errors.New("1xx informational response with END_STREAM flag") } @@ -3253,7 +4437,16 @@ index ce375c8c7..090d0e1bd 100644 } if statusCode == 100 { traceGot100Continue(cs.trace) -@@ -2796,7 +2887,7 @@ func (b transportResponseBody) Close() error { +@@ -2687,7 +2535,7 @@ func (rl *clientConnReadLoop) processTrailers(cs *clientStream, f *MetaHeadersFr + + trailer := make(http.Header) + for _, hf := range f.RegularFields() { +- key := canonicalHeader(hf.Name) ++ key := httpcommon.CanonicalHeader(hf.Name) + trailer[key] = append(trailer[key], hf.Value) + } + cs.trailer = trailer +@@ -2796,7 +2644,7 @@ func (b transportResponseBody) Close() error { func (rl *clientConnReadLoop) processData(f *DataFrame) error { cc := rl.cc @@ -3262,7 +4455,7 @@ index ce375c8c7..090d0e1bd 100644 data := f.Data() if cs == nil { cc.mu.Lock() -@@ -2931,9 +3022,22 @@ func (rl *clientConnReadLoop) endStreamError(cs *clientStream, err error) { +@@ -2931,9 +2779,22 @@ func (rl *clientConnReadLoop) endStreamError(cs *clientStream, err error) { cs.abortStream(err) } @@ -3286,7 +4479,7 @@ index ce375c8c7..090d0e1bd 100644 cs := rl.cc.streams[id] if cs != nil && !cs.readAborted { return cs -@@ -3021,12 +3125,27 @@ func (rl *clientConnReadLoop) processSettingsNoWrite(f *SettingsFrame) error { +@@ -3021,12 +2882,27 @@ func (rl *clientConnReadLoop) processSettingsNoWrite(f *SettingsFrame) error { for _, cs := range cc.streams { cs.flow.add(delta) } @@ -3315,7 +4508,7 @@ index ce375c8c7..090d0e1bd 100644 default: cc.vlogf("Unhandled Setting: %v", s) } -@@ -3044,6 +3163,7 @@ func (rl *clientConnReadLoop) processSettingsNoWrite(f *SettingsFrame) error { +@@ -3044,6 +2920,7 @@ func (rl *clientConnReadLoop) processSettingsNoWrite(f *SettingsFrame) error { // connection can establish to our default. cc.maxConcurrentStreams = defaultMaxConcurrentStreams } @@ -3323,7 +4516,7 @@ index ce375c8c7..090d0e1bd 100644 cc.seenSettings = true } -@@ -3052,7 +3172,7 @@ func (rl *clientConnReadLoop) processSettingsNoWrite(f *SettingsFrame) error { +@@ -3052,7 +2929,7 @@ func (rl *clientConnReadLoop) processSettingsNoWrite(f *SettingsFrame) error { func (rl *clientConnReadLoop) processWindowUpdate(f *WindowUpdateFrame) error { cc := rl.cc @@ -3332,7 +4525,7 @@ index ce375c8c7..090d0e1bd 100644 if f.StreamID != 0 && cs == nil { return nil } -@@ -3076,12 +3196,12 @@ func (rl *clientConnReadLoop) processWindowUpdate(f *WindowUpdateFrame) error { +@@ -3076,12 +2953,12 @@ func (rl *clientConnReadLoop) processWindowUpdate(f *WindowUpdateFrame) error { return ConnectionError(ErrCodeFlowControl) } @@ -3347,7 +4540,7 @@ index ce375c8c7..090d0e1bd 100644 if cs == nil { // TODO: return error if server tries to RST_STREAM an idle stream return nil -@@ -3120,7 +3240,8 @@ func (cc *ClientConn) Ping(ctx context.Context) error { +@@ -3120,7 +2997,8 @@ func (cc *ClientConn) Ping(ctx context.Context) error { } var pingError error errc := make(chan struct{}) @@ -3357,7 +4550,7 @@ index ce375c8c7..090d0e1bd 100644 cc.wmu.Lock() defer cc.wmu.Unlock() if pingError = cc.fr.WritePing(false, p); pingError != nil { -@@ -3131,20 +3252,7 @@ func (cc *ClientConn) Ping(ctx context.Context) error { +@@ -3131,20 +3009,7 @@ func (cc *ClientConn) Ping(ctx context.Context) error { close(errc) return } @@ -3379,7 +4572,7 @@ index ce375c8c7..090d0e1bd 100644 select { case <-c: return nil -@@ -3168,6 +3276,12 @@ func (rl *clientConnReadLoop) processPing(f *PingFrame) error { +@@ -3168,6 +3033,12 @@ func (rl *clientConnReadLoop) processPing(f *PingFrame) error { close(c) delete(cc.pings, f.Data) } @@ -3392,7 +4585,7 @@ index ce375c8c7..090d0e1bd 100644 return nil } cc := rl.cc -@@ -3190,13 +3304,20 @@ func (rl *clientConnReadLoop) processPushPromise(f *PushPromiseFrame) error { +@@ -3190,20 +3061,27 @@ func (rl *clientConnReadLoop) processPushPromise(f *PushPromiseFrame) error { return ConnectionError(ErrCodeProtocol) } @@ -3414,7 +4607,15 @@ index ce375c8c7..090d0e1bd 100644 cc.bw.Flush() cc.wmu.Unlock() } -@@ -3350,7 +3471,7 @@ func traceGotConn(req *http.Request, cc *ClientConn, reused bool) { + + var ( + errResponseHeaderListSize = errors.New("http2: response header list larger than advertised limit") +- errRequestHeaderListSize = errors.New("http2: request header list larger than peer's advertised limit") ++ errRequestHeaderListSize = httpcommon.ErrRequestHeaderListSize + ) + + func (cc *ClientConn) logf(format string, args ...interface{}) { +@@ -3350,7 +3228,7 @@ func traceGotConn(req *http.Request, cc *ClientConn, reused bool) { cc.mu.Lock() ci.WasIdle = len(cc.streams) == 0 && reused if ci.WasIdle && !cc.lastActive.IsZero() { @@ -3423,6 +4624,23 @@ index ce375c8c7..090d0e1bd 100644 } cc.mu.Unlock() +@@ -3387,16 +3265,6 @@ func traceFirstResponseByte(trace *httptrace.ClientTrace) { + } + } + +-func traceHasWroteHeaderField(trace *httptrace.ClientTrace) bool { +- return trace != nil && trace.WroteHeaderField != nil +-} +- +-func traceWroteHeaderField(trace *httptrace.ClientTrace, k, v string) { +- if trace != nil && trace.WroteHeaderField != nil { +- trace.WroteHeaderField(k, []string{v}) +- } +-} +- + func traceGot1xxResponseFunc(trace *httptrace.ClientTrace) func(int, textproto.MIMEHeader) error { + if trace != nil { + return trace.Got1xxResponse diff --git a/api/vendor/golang.org/x/net/http2/unencrypted.go b/api/vendor/golang.org/x/net/http2/unencrypted.go new file mode 100644 index 000000000..b2de21161 @@ -3462,10 +4680,18 @@ index 000000000..b2de21161 + return conner.UnencryptedNetConn(), nil +} diff --git a/api/vendor/golang.org/x/net/http2/write.go b/api/vendor/golang.org/x/net/http2/write.go -index 33f61398a..6ff6bee7e 100644 +index 33f61398a..fdb35b947 100644 --- a/api/vendor/golang.org/x/net/http2/write.go +++ b/api/vendor/golang.org/x/net/http2/write.go -@@ -131,6 +131,16 @@ func (se StreamError) writeFrame(ctx writeContext) error { +@@ -13,6 +13,7 @@ import ( + + "golang.org/x/net/http/httpguts" + "golang.org/x/net/http2/hpack" ++ "golang.org/x/net/internal/httpcommon" + ) + + // writeFramer is implemented by any type that is used to write frames. +@@ -131,6 +132,16 @@ func (se StreamError) writeFrame(ctx writeContext) error { func (se StreamError) staysWithinBuffer(max int) bool { return frameHeaderLen+4 <= max } @@ -3482,6 +4708,15 @@ index 33f61398a..6ff6bee7e 100644 type writePingAck struct{ pf *PingFrame } func (w writePingAck) writeFrame(ctx writeContext) error { +@@ -341,7 +352,7 @@ func encodeHeaders(enc *hpack.Encoder, h http.Header, keys []string) { + } + for _, k := range keys { + vv := h[k] +- k, ascii := lowerHeader(k) ++ k, ascii := httpcommon.LowerHeader(k) + if !ascii { + // Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header + // field names have to be ASCII characters (just as in HTTP/1.x). diff --git a/api/vendor/golang.org/x/net/http2/writesched_priority.go b/api/vendor/golang.org/x/net/http2/writesched_priority.go index 0a242c669..f6783339d 100644 --- a/api/vendor/golang.org/x/net/http2/writesched_priority.go @@ -3497,2676 +4732,927 @@ index 0a242c669..f6783339d 100644 } n.setParent(nil) delete(ws.nodes, n.id) -diff --git a/api/vendor/golang.org/x/text/LICENSE b/api/vendor/golang.org/x/text/LICENSE -index 6a66aea5e..2a7cf70da 100644 ---- a/api/vendor/golang.org/x/text/LICENSE -+++ b/api/vendor/golang.org/x/text/LICENSE -@@ -1,4 +1,4 @@ --Copyright (c) 2009 The Go Authors. All rights reserved. -+Copyright 2009 The Go Authors. +diff --git a/api/vendor/golang.org/x/net/internal/httpcommon/ascii.go b/api/vendor/golang.org/x/net/internal/httpcommon/ascii.go +new file mode 100644 +index 000000000..ed14da5af +--- /dev/null ++++ b/api/vendor/golang.org/x/net/internal/httpcommon/ascii.go +@@ -0,0 +1,53 @@ ++// Copyright 2025 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++package httpcommon ++ ++import "strings" ++ ++// The HTTP protocols are defined in terms of ASCII, not Unicode. This file ++// contains helper functions which may use Unicode-aware functions which would ++// otherwise be unsafe and could introduce vulnerabilities if used improperly. ++ ++// asciiEqualFold is strings.EqualFold, ASCII only. It reports whether s and t ++// are equal, ASCII-case-insensitively. ++func asciiEqualFold(s, t string) bool { ++ if len(s) != len(t) { ++ return false ++ } ++ for i := 0; i < len(s); i++ { ++ if lower(s[i]) != lower(t[i]) { ++ return false ++ } ++ } ++ return true ++} ++ ++// lower returns the ASCII lowercase version of b. ++func lower(b byte) byte { ++ if 'A' <= b && b <= 'Z' { ++ return b + ('a' - 'A') ++ } ++ return b ++} ++ ++// isASCIIPrint returns whether s is ASCII and printable according to ++// https://tools.ietf.org/html/rfc20#section-4.2. ++func isASCIIPrint(s string) bool { ++ for i := 0; i < len(s); i++ { ++ if s[i] < ' ' || s[i] > '~' { ++ return false ++ } ++ } ++ return true ++} ++ ++// asciiToLower returns the lowercase version of s if s is ASCII and printable, ++// and whether or not it was. ++func asciiToLower(s string) (lower string, ok bool) { ++ if !isASCIIPrint(s) { ++ return "", false ++ } ++ return strings.ToLower(s), true ++} +diff --git a/api/vendor/golang.org/x/net/http2/headermap.go b/api/vendor/golang.org/x/net/internal/httpcommon/headermap.go +similarity index 74% +rename from api/vendor/golang.org/x/net/http2/headermap.go +rename to api/vendor/golang.org/x/net/internal/httpcommon/headermap.go +index 149b3dd20..92483d8e4 100644 +--- a/api/vendor/golang.org/x/net/http2/headermap.go ++++ b/api/vendor/golang.org/x/net/internal/httpcommon/headermap.go +@@ -1,11 +1,11 @@ +-// Copyright 2014 The Go Authors. All rights reserved. ++// Copyright 2025 The Go Authors. All rights reserved. + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are -@@ -10,7 +10,7 @@ notice, this list of conditions and the following disclaimer. - copyright notice, this list of conditions and the following disclaimer - in the documentation and/or other materials provided with the - distribution. -- * Neither the name of Google Inc. nor the names of its -+ * Neither the name of Google LLC nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. +-package http2 ++package httpcommon -diff --git a/api/vendor/modules.txt b/api/vendor/modules.txt -index 915f80194..45f392b3b 100644 ---- a/api/vendor/modules.txt -+++ b/api/vendor/modules.txt -@@ -34,13 +34,13 @@ github.com/pmezard/go-difflib/difflib - ## explicit; go 1.17 - github.com/stretchr/testify/assert - github.com/stretchr/testify/require --# golang.org/x/net v0.23.0 -+# golang.org/x/net v0.33.0 - ## explicit; go 1.18 - golang.org/x/net/http/httpguts - golang.org/x/net/http2 - golang.org/x/net/http2/hpack - golang.org/x/net/idna --# golang.org/x/text v0.14.0 -+# golang.org/x/text v0.21.0 - ## explicit; go 1.18 - golang.org/x/text/secure/bidirule - golang.org/x/text/transform -diff --git a/go.mod b/go.mod -index 8dc814fdd..f354e1867 100644 ---- a/go.mod -+++ b/go.mod -@@ -24,21 +24,21 @@ require ( - github.com/onsi/gomega v1.34.1 - github.com/pkg/xattr v0.4.10 - github.com/prometheus/client_golang v1.19.1 -- github.com/stretchr/testify v1.9.0 -- golang.org/x/crypto v0.26.0 -- golang.org/x/net v0.28.0 -- golang.org/x/sys v0.24.0 -+ github.com/stretchr/testify v1.10.0 -+ golang.org/x/crypto v0.32.0 -+ golang.org/x/net v0.33.0 -+ golang.org/x/sys v0.29.0 - google.golang.org/grpc v1.65.0 - google.golang.org/protobuf v1.34.2 - // - // when updating k8s.io/kubernetes, make sure to update the replace section too - // -- k8s.io/api v0.30.3 -- k8s.io/apimachinery v0.30.3 -+ k8s.io/api v0.30.4 -+ k8s.io/apimachinery v0.30.4 - k8s.io/client-go v12.0.0+incompatible - k8s.io/cloud-provider v0.30.3 - k8s.io/klog/v2 v2.130.1 -- k8s.io/kubernetes v1.30.3 -+ k8s.io/kubernetes v1.30.10 - k8s.io/mount-utils v0.30.3 - k8s.io/pod-security-admission v0.30.3 - k8s.io/utils v0.0.0-20230726121419-3b25d923346b -@@ -82,7 +82,7 @@ require ( - github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/gemalto/flume v0.13.0 // indirect - github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 // indirect -- github.com/go-jose/go-jose/v4 v4.0.1 // indirect -+ github.com/go-jose/go-jose/v4 v4.0.5 // indirect - github.com/go-logr/logr v1.4.2 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.19.6 // indirect -@@ -158,9 +158,9 @@ require ( - go.uber.org/zap v1.26.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/oauth2 v0.20.0 // indirect -- golang.org/x/sync v0.8.0 // indirect -- golang.org/x/term v0.23.0 // indirect -- golang.org/x/text v0.17.0 // indirect -+ golang.org/x/sync v0.10.0 // indirect -+ golang.org/x/term v0.28.0 // indirect -+ golang.org/x/text v0.21.0 // indirect - golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.23.0 // indirect - gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect -@@ -172,11 +172,11 @@ require ( - gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.30.1 // indirect -- k8s.io/apiserver v0.30.3 // indirect -- k8s.io/component-base v0.30.3 // indirect -+ k8s.io/apiserver v0.30.4 // indirect -+ k8s.io/component-base v0.30.4 // indirect - k8s.io/component-helpers v0.30.3 // indirect - k8s.io/controller-manager v0.30.3 // indirect -- k8s.io/kms v0.30.3 // indirect -+ k8s.io/kms v0.30.4 // indirect - k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect - k8s.io/kubectl v0.0.0 // indirect - k8s.io/kubelet v0.0.0 // indirect -@@ -207,7 +207,7 @@ replace ( - k8s.io/api => k8s.io/api v0.30.3 - k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.30.3 - k8s.io/apimachinery => k8s.io/apimachinery v0.30.3 -- k8s.io/apiserver => k8s.io/apiserver v0.30.3 -+ k8s.io/apiserver => k8s.io/apiserver v0.30.4 - k8s.io/cli-runtime => k8s.io/cli-runtime v0.30.3 - k8s.io/client-go => k8s.io/client-go v0.30.3 - k8s.io/cloud-provider => k8s.io/cloud-provider v0.30.3 -diff --git a/go.sum b/go.sum -index 34d0b90ed..aa74c48b2 100644 ---- a/go.sum -+++ b/go.sum -@@ -993,8 +993,8 @@ github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9 - github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= - github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= - github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= --github.com/go-jose/go-jose/v4 v4.0.1 h1:QVEPDE3OluqXBQZDcnNvQrInro2h0e4eqNbnZSWqS6U= --github.com/go-jose/go-jose/v4 v4.0.1/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY= -+github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE= -+github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA= - 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-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -@@ -1586,8 +1586,9 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o - github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= - github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= - github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= --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/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= - github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= - github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -@@ -1720,8 +1721,8 @@ golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq - golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= - golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= - golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= --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/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -+golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= - golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= - golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= - golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -@@ -1872,8 +1873,8 @@ golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= - golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= - 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.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= --golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= -+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.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= -@@ -1931,8 +1932,8 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= - golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= - golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= - golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= --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.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -+golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= - golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= - 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= -@@ -2043,8 +2044,8 @@ golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= - golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= - golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= - golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= --golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= --golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -+golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -+golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= - golang.org/x/telemetry v0.0.0-20240208230135-b75ee8823808/go.mod h1:KG1lNk5ZFNssSZLrpVb4sMXKMpGwGXOxSG3rnu2gZQQ= - golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= - golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -@@ -2066,8 +2067,8 @@ golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= - golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= - golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= - golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= --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/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= -+golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= - 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= -@@ -2089,8 +2090,8 @@ golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= - golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= - golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= - golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= --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/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.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= - 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= -@@ -2567,8 +2568,8 @@ k8s.io/apiextensions-apiserver v0.30.3 h1:oChu5li2vsZHx2IvnGP3ah8Nj3KyqG3kRSaKmi - k8s.io/apiextensions-apiserver v0.30.3/go.mod h1:uhXxYDkMAvl6CJw4lrDN4CPbONkF3+XL9cacCT44kV4= - k8s.io/apimachinery v0.30.3 h1:q1laaWCmrszyQuSQCfNB8cFgCuDAoPszKY4ucAjDwHc= - k8s.io/apimachinery v0.30.3/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= --k8s.io/apiserver v0.30.3 h1:QZJndA9k2MjFqpnyYv/PH+9PE0SHhx3hBho4X0vE65g= --k8s.io/apiserver v0.30.3/go.mod h1:6Oa88y1CZqnzetd2JdepO0UXzQX4ZnOekx2/PtEjrOg= -+k8s.io/apiserver v0.30.4 h1:rHkGJhxd+m4jILrgkenwSmG4X0QXk6ecGuybzS/PQak= -+k8s.io/apiserver v0.30.4/go.mod h1:oyGAj9B9/0+I9huJyf4/8SMBF2mNh2bTMlu7703dkH8= - 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/cloud-provider v0.30.3 h1:SNWZmllTymOTzIPJuhtZH6il/qVi75dQARRQAm9k6VY= -@@ -2592,8 +2593,9 @@ k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= - k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= - k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= - k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= --k8s.io/kms v0.30.3 h1:NLg+oN45S2Y3U0WiLRzbS61AY/XrS5JBMZp531Z+Pho= - k8s.io/kms v0.30.3/go.mod h1:GrMurD0qk3G4yNgGcsCEmepqf9KyyIrTXYR2lyUOJC4= -+k8s.io/kms v0.30.4 h1:Je7wR5/m+w/E7Ef9R9RY1yeMU/C2GXIvhzRFfg8H5kQ= -+k8s.io/kms v0.30.4/go.mod h1:GrMurD0qk3G4yNgGcsCEmepqf9KyyIrTXYR2lyUOJC4= - k8s.io/kube-openapi v0.0.0-20180731170545-e3762e86a74c/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= - k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= - k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= -@@ -2602,8 +2604,8 @@ k8s.io/kubectl v0.30.3 h1:YIBBvMdTW0xcDpmrOBzcpUVsn+zOgjMYIu7kAq+yqiI= - k8s.io/kubectl v0.30.3/go.mod h1:IcR0I9RN2+zzTRUa1BzZCm4oM0NLOawE6RzlDvd1Fpo= - k8s.io/kubelet v0.30.3 h1:KvGWDdhzD0vEyDyGTCjsDc8D+0+lwRMw3fJbfQgF7ys= - k8s.io/kubelet v0.30.3/go.mod h1:D9or45Vkzcqg55CEiqZ8dVbwP3Ksj7DruEVRS9oq3Ys= --k8s.io/kubernetes v1.30.3 h1:A0qoXI1YQNzrQZiff33y5zWxYHFT/HeZRK98/sRDJI0= --k8s.io/kubernetes v1.30.3/go.mod h1:yPbIk3MhmhGigX62FLJm+CphNtjxqCvAIFQXup6RKS0= -+k8s.io/kubernetes v1.30.10 h1:/x/z+MTfPkKuEjMJwWdRVxNx7xB54GlGWpcFM6KDwZc= -+k8s.io/kubernetes v1.30.10/go.mod h1:DGWYRXHx5NhImLiR9FvIVBsOKxwKZOX6bPF/YP7TqHY= - k8s.io/mount-utils v0.29.3 h1:iEcqPP7Vv8UClH8nnMfovtmy/04fIloRW9JuSXykoZ0= - k8s.io/mount-utils v0.29.3/go.mod h1:9IWJTMe8tG0MYMLEp60xK9GYVeCdA3g4LowmnVi+t9Y= - k8s.io/pod-security-admission v0.30.3 h1:UDGZWR3ry/XrN/Ki/w7qrp49OwgQsKyh+6xWbexvJi8= -diff --git a/vendor/github.com/go-jose/go-jose/v4/CHANGELOG.md b/vendor/github.com/go-jose/go-jose/v4/CHANGELOG.md -index 28bdd2fc0..6f717dbd8 100644 ---- a/vendor/github.com/go-jose/go-jose/v4/CHANGELOG.md -+++ b/vendor/github.com/go-jose/go-jose/v4/CHANGELOG.md -@@ -1,3 +1,27 @@ -+# v4.0.4 -+ -+## Fixed -+ -+ - Reverted "Allow unmarshalling JSONWebKeySets with unsupported key types" as a -+ breaking change. See #136 / #137. -+ -+# v4.0.3 -+ -+## Changed -+ -+ - Allow unmarshalling JSONWebKeySets with unsupported key types (#130) -+ - Document that OpaqueKeyEncrypter can't be implemented (for now) (#129) -+ - Dependency updates -+ -+# v4.0.2 -+ -+## Changed -+ -+ - Improved documentation of Verify() to note that JSONWebKeySet is a supported -+ argument type (#104) -+ - Defined exported error values for missing x5c header and unsupported elliptic -+ curves error cases (#117) -+ - # v4.0.1 - - ## Fixed -diff --git a/vendor/github.com/go-jose/go-jose/v4/CONTRIBUTING.md b/vendor/github.com/go-jose/go-jose/v4/CONTRIBUTING.md -index b63e1f8fe..4b4805add 100644 ---- a/vendor/github.com/go-jose/go-jose/v4/CONTRIBUTING.md -+++ b/vendor/github.com/go-jose/go-jose/v4/CONTRIBUTING.md -@@ -7,9 +7,3 @@ When submitting code, please make every effort to follow existing conventions - and style in order to keep the code as readable as possible. Please also make - sure all tests pass by running `go test`, and format your code with `go fmt`. - We also recommend using `golint` and `errcheck`. -- --Before your code can be accepted into the project you must also sign the --Individual Contributor License Agreement. We use [cla-assistant.io][1] and you --will be prompted to sign once a pull request is opened. -- --[1]: https://cla-assistant.io/ -diff --git a/vendor/github.com/go-jose/go-jose/v4/README.md b/vendor/github.com/go-jose/go-jose/v4/README.md -index 79a7c5ecc..02b574954 100644 ---- a/vendor/github.com/go-jose/go-jose/v4/README.md -+++ b/vendor/github.com/go-jose/go-jose/v4/README.md -@@ -9,14 +9,6 @@ Package jose aims to provide an implementation of the Javascript Object Signing - and Encryption set of standards. This includes support for JSON Web Encryption, - JSON Web Signature, and JSON Web Token standards. - --**Disclaimer**: This library contains encryption software that is subject to --the U.S. Export Administration Regulations. You may not export, re-export, --transfer or download this code or any part of it in violation of any United --States law, directive or regulation. In particular this software may not be --exported or re-exported in any form or on any media to Iran, North Sudan, --Syria, Cuba, or North Korea, or to denied persons or entities mentioned on any --US maintained blocked list. -- - ## Overview - - The implementation follows the -@@ -109,6 +101,6 @@ allows attaching a key id. - - Examples can be found in the Godoc - reference for this package. The --[`jose-util`](https://github.com/go-jose/go-jose/tree/v4/jose-util) -+[`jose-util`](https://github.com/go-jose/go-jose/tree/main/jose-util) - subdirectory also contains a small command-line utility which might be useful - as an example as well. -diff --git a/vendor/github.com/go-jose/go-jose/v4/crypter.go b/vendor/github.com/go-jose/go-jose/v4/crypter.go -index aba08424c..d81b03b44 100644 ---- a/vendor/github.com/go-jose/go-jose/v4/crypter.go -+++ b/vendor/github.com/go-jose/go-jose/v4/crypter.go -@@ -459,7 +459,10 @@ func (obj JSONWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error) - return nil, fmt.Errorf("go-jose/go-jose: unsupported crit header") - } + import ( +- "net/http" ++ "net/textproto" + "sync" + ) -- key := tryJWKS(decryptionKey, obj.Header) -+ key, err := tryJWKS(decryptionKey, obj.Header) -+ if err != nil { -+ return nil, err -+ } - decrypter, err := newDecrypter(key) - if err != nil { - return nil, err -@@ -529,7 +532,10 @@ func (obj JSONWebEncryption) DecryptMulti(decryptionKey interface{}) (int, Heade - return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: unsupported crit header") +@@ -82,13 +82,15 @@ func buildCommonHeaderMaps() { + commonLowerHeader = make(map[string]string, len(common)) + commonCanonHeader = make(map[string]string, len(common)) + for _, v := range common { +- chk := http.CanonicalHeaderKey(v) ++ chk := textproto.CanonicalMIMEHeaderKey(v) + commonLowerHeader[chk] = v + commonCanonHeader[v] = chk } + } -- key := tryJWKS(decryptionKey, obj.Header) -+ key, err := tryJWKS(decryptionKey, obj.Header) -+ if err != nil { -+ return -1, Header{}, nil, err -+ } - decrypter, err := newDecrypter(key) - if err != nil { - return -1, Header{}, nil, err -diff --git a/vendor/github.com/go-jose/go-jose/v4/jwe.go b/vendor/github.com/go-jose/go-jose/v4/jwe.go -index 89f03ee3e..9f1322dcc 100644 ---- a/vendor/github.com/go-jose/go-jose/v4/jwe.go -+++ b/vendor/github.com/go-jose/go-jose/v4/jwe.go -@@ -288,10 +288,11 @@ func ParseEncryptedCompact( - keyAlgorithms []KeyAlgorithm, - contentEncryption []ContentEncryption, - ) (*JSONWebEncryption, error) { -- parts := strings.Split(input, ".") -- if len(parts) != 5 { -+ // Five parts is four separators -+ if strings.Count(input, ".") != 4 { - return nil, fmt.Errorf("go-jose/go-jose: compact JWE format must have five parts") - } -+ parts := strings.SplitN(input, ".", 5) +-func lowerHeader(v string) (lower string, ascii bool) { ++// LowerHeader returns the lowercase form of a header name, ++// used on the wire for HTTP/2 and HTTP/3 requests. ++func LowerHeader(v string) (lower string, ascii bool) { + buildCommonHeaderMapsOnce() + if s, ok := commonLowerHeader[v]; ok { + return s, true +@@ -96,10 +98,18 @@ func lowerHeader(v string) (lower string, ascii bool) { + return asciiToLower(v) + } - rawProtected, err := base64.RawURLEncoding.DecodeString(parts[0]) - if err != nil { -diff --git a/vendor/github.com/go-jose/go-jose/v4/jwk.go b/vendor/github.com/go-jose/go-jose/v4/jwk.go -index a565aaab2..9e57e93ba 100644 ---- a/vendor/github.com/go-jose/go-jose/v4/jwk.go -+++ b/vendor/github.com/go-jose/go-jose/v4/jwk.go -@@ -239,10 +239,10 @@ func (k *JSONWebKey) UnmarshalJSON(data []byte) (err error) { - keyPub = key - } - } else { -- err = fmt.Errorf("go-jose/go-jose: unknown curve %s'", raw.Crv) -+ return fmt.Errorf("go-jose/go-jose: unknown curve %s'", raw.Crv) - } - default: -- err = fmt.Errorf("go-jose/go-jose: unknown json web key type '%s'", raw.Kty) -+ return fmt.Errorf("go-jose/go-jose: unknown json web key type '%s'", raw.Kty) +-func canonicalHeader(v string) string { ++// CanonicalHeader canonicalizes a header name. (For example, "host" becomes "Host".) ++func CanonicalHeader(v string) string { + buildCommonHeaderMapsOnce() + if s, ok := commonCanonHeader[v]; ok { + return s } - - if err != nil { -@@ -779,7 +779,13 @@ func (key rawJSONWebKey) symmetricKey() ([]byte, error) { - return key.K.bytes(), nil +- return http.CanonicalHeaderKey(v) ++ return textproto.CanonicalMIMEHeaderKey(v) ++} ++ ++// CachedCanonicalHeader returns the canonical form of a well-known header name. ++func CachedCanonicalHeader(v string) (string, bool) { ++ buildCommonHeaderMapsOnce() ++ s, ok := commonCanonHeader[v] ++ return s, ok } - --func tryJWKS(key interface{}, headers ...Header) interface{} { +diff --git a/api/vendor/golang.org/x/net/internal/httpcommon/request.go b/api/vendor/golang.org/x/net/internal/httpcommon/request.go +new file mode 100644 +index 000000000..4b7055317 +--- /dev/null ++++ b/api/vendor/golang.org/x/net/internal/httpcommon/request.go +@@ -0,0 +1,467 @@ ++// Copyright 2025 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++package httpcommon ++ ++import ( ++ "context" ++ "errors" ++ "fmt" ++ "net/http/httptrace" ++ "net/textproto" ++ "net/url" ++ "sort" ++ "strconv" ++ "strings" ++ ++ "golang.org/x/net/http/httpguts" ++ "golang.org/x/net/http2/hpack" ++) ++ +var ( -+ // ErrJWKSKidNotFound is returned when a JWKS does not contain a JWK with a -+ // key ID which matches one in the provided tokens headers. -+ ErrJWKSKidNotFound = errors.New("go-jose/go-jose: JWK with matching kid not found in JWK Set") ++ ErrRequestHeaderListSize = errors.New("request header list larger than peer's advertised limit") +) + -+func tryJWKS(key interface{}, headers ...Header) (interface{}, error) { - var jwks JSONWebKeySet - - switch jwksType := key.(type) { -@@ -788,9 +794,11 @@ func tryJWKS(key interface{}, headers ...Header) interface{} { - case JSONWebKeySet: - jwks = jwksType - default: -- return key -+ // If the specified key is not a JWKS, return as is. -+ return key, nil - } - -+ // Determine the KID to search for from the headers. - var kid string - for _, header := range headers { - if header.KeyID != "" { -@@ -799,14 +807,17 @@ func tryJWKS(key interface{}, headers ...Header) interface{} { - } - } - -+ // If no KID is specified in the headers, reject. - if kid == "" { -- return key -+ return nil, ErrJWKSKidNotFound - } - -+ // Find the JWK with the matching KID. If no JWK with the specified KID is -+ // found, reject. - keys := jwks.Key(kid) - if len(keys) == 0 { -- return key -+ return nil, ErrJWKSKidNotFound - } - -- return keys[0].Key -+ return keys[0].Key, nil - } -diff --git a/vendor/github.com/go-jose/go-jose/v4/jws.go b/vendor/github.com/go-jose/go-jose/v4/jws.go -index 3a912301a..d09d8ba50 100644 ---- a/vendor/github.com/go-jose/go-jose/v4/jws.go -+++ b/vendor/github.com/go-jose/go-jose/v4/jws.go -@@ -327,10 +327,11 @@ func parseSignedCompact( - payload []byte, - signatureAlgorithms []SignatureAlgorithm, - ) (*JSONWebSignature, error) { -- parts := strings.Split(input, ".") -- if len(parts) != 3 { -+ // Three parts is two separators -+ if strings.Count(input, ".") != 2 { - return nil, fmt.Errorf("go-jose/go-jose: compact JWS format must have three parts") - } -+ parts := strings.SplitN(input, ".", 3) - - if parts[1] != "" && payload != nil { - return nil, fmt.Errorf("go-jose/go-jose: payload is not detached") -diff --git a/vendor/github.com/go-jose/go-jose/v4/opaque.go b/vendor/github.com/go-jose/go-jose/v4/opaque.go -index 68db085ef..429427232 100644 ---- a/vendor/github.com/go-jose/go-jose/v4/opaque.go -+++ b/vendor/github.com/go-jose/go-jose/v4/opaque.go -@@ -83,6 +83,9 @@ func (o *opaqueVerifier) verifyPayload(payload []byte, signature []byte, alg Sig - } - - // OpaqueKeyEncrypter is an interface that supports encrypting keys with an opaque key. -+// -+// Note: this cannot currently be implemented outside this package because of its -+// unexported method. - type OpaqueKeyEncrypter interface { - // KeyID returns the kid - KeyID() string -diff --git a/vendor/github.com/go-jose/go-jose/v4/shared.go b/vendor/github.com/go-jose/go-jose/v4/shared.go -index b485e43bd..1ec339612 100644 ---- a/vendor/github.com/go-jose/go-jose/v4/shared.go -+++ b/vendor/github.com/go-jose/go-jose/v4/shared.go -@@ -71,6 +71,12 @@ var ( - // ErrUnprotectedNonce indicates that while parsing a JWS or JWE object, a - // nonce header parameter was included in an unprotected header object. - ErrUnprotectedNonce = errors.New("go-jose/go-jose: Nonce parameter included in unprotected header") -+ -+ // ErrMissingX5cHeader indicates that the JWT header is missing x5c headers. -+ ErrMissingX5cHeader = errors.New("go-jose/go-jose: no x5c header present in message") -+ -+ // ErrUnsupportedEllipticCurve indicates unsupported or unknown elliptic curve has been found. -+ ErrUnsupportedEllipticCurve = errors.New("go-jose/go-jose: unsupported/unknown elliptic curve") - ) - - // Key management algorithms -@@ -199,7 +205,7 @@ type Header struct { - // not be validated with the given verify options. - func (h Header) Certificates(opts x509.VerifyOptions) ([][]*x509.Certificate, error) { - if len(h.certificates) == 0 { -- return nil, errors.New("go-jose/go-jose: no x5c header present in message") -+ return nil, ErrMissingX5cHeader - } - - leaf := h.certificates[0] -@@ -501,7 +507,7 @@ func curveName(crv elliptic.Curve) (string, error) { - case elliptic.P521(): - return "P-521", nil - default: -- return "", fmt.Errorf("go-jose/go-jose: unsupported/unknown elliptic curve") -+ return "", ErrUnsupportedEllipticCurve - } - } - -diff --git a/vendor/github.com/go-jose/go-jose/v4/signing.go b/vendor/github.com/go-jose/go-jose/v4/signing.go -index f0b0294f3..3dec0112b 100644 ---- a/vendor/github.com/go-jose/go-jose/v4/signing.go -+++ b/vendor/github.com/go-jose/go-jose/v4/signing.go -@@ -358,6 +358,8 @@ func (ctx *genericSigner) Options() SignerOptions { - // - *rsa.PublicKey - // - *JSONWebKey - // - JSONWebKey -+// - *JSONWebKeySet -+// - JSONWebKeySet - // - []byte (an HMAC key) - // - Any type that implements the OpaqueVerifier interface. - // -@@ -388,7 +390,10 @@ func (obj JSONWebSignature) UnsafePayloadWithoutVerification() []byte { - // The verificationKey argument must have one of the types allowed for the - // verificationKey argument of JSONWebSignature.Verify(). - func (obj JSONWebSignature) DetachedVerify(payload []byte, verificationKey interface{}) error { -- key := tryJWKS(verificationKey, obj.headers()...) -+ key, err := tryJWKS(verificationKey, obj.headers()...) -+ if err != nil { -+ return err -+ } - verifier, err := newVerifier(key) - if err != nil { - return err -@@ -453,7 +458,10 @@ func (obj JSONWebSignature) VerifyMulti(verificationKey interface{}) (int, Signa - // The verificationKey argument must have one of the types allowed for the - // verificationKey argument of JSONWebSignature.Verify(). - func (obj JSONWebSignature) DetachedVerifyMulti(payload []byte, verificationKey interface{}) (int, Signature, error) { -- key := tryJWKS(verificationKey, obj.headers()...) -+ key, err := tryJWKS(verificationKey, obj.headers()...) -+ if err != nil { -+ return -1, Signature{}, err -+ } - verifier, err := newVerifier(key) - if err != nil { - return -1, Signature{}, err -diff --git a/vendor/github.com/stretchr/testify/assert/assertion_compare.go b/vendor/github.com/stretchr/testify/assert/assertion_compare.go -index 4d4b4aad6..7e19eba09 100644 ---- a/vendor/github.com/stretchr/testify/assert/assertion_compare.go -+++ b/vendor/github.com/stretchr/testify/assert/assertion_compare.go -@@ -7,10 +7,13 @@ import ( - "time" - ) - --type CompareType int -+// Deprecated: CompareType has only ever been for internal use and has accidentally been published since v1.6.0. Do not use it. -+type CompareType = compareResult ++// Request is a subset of http.Request. ++// It'd be simpler to pass an *http.Request, of course, but we can't depend on net/http ++// without creating a dependency cycle. ++type Request struct { ++ URL *url.URL ++ Method string ++ Host string ++ Header map[string][]string ++ Trailer map[string][]string ++ ActualContentLength int64 // 0 means 0, -1 means unknown ++} + -+type compareResult int - - const ( -- compareLess CompareType = iota - 1 -+ compareLess compareResult = iota - 1 - compareEqual - compareGreater - ) -@@ -39,7 +42,7 @@ var ( - bytesType = reflect.TypeOf([]byte{}) - ) - --func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) { -+func compare(obj1, obj2 interface{}, kind reflect.Kind) (compareResult, bool) { - obj1Value := reflect.ValueOf(obj1) - obj2Value := reflect.ValueOf(obj2) - -@@ -325,7 +328,13 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) { - timeObj2 = obj2Value.Convert(timeType).Interface().(time.Time) - } - -- return compare(timeObj1.UnixNano(), timeObj2.UnixNano(), reflect.Int64) -+ if timeObj1.Before(timeObj2) { -+ return compareLess, true -+ } -+ if timeObj1.Equal(timeObj2) { -+ return compareEqual, true -+ } -+ return compareGreater, true - } - case reflect.Slice: - { -@@ -345,7 +354,7 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) { - bytesObj2 = obj2Value.Convert(bytesType).Interface().([]byte) - } - -- return CompareType(bytes.Compare(bytesObj1, bytesObj2)), true -+ return compareResult(bytes.Compare(bytesObj1, bytesObj2)), true - } - case reflect.Uintptr: - { -@@ -381,7 +390,7 @@ func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface - if h, ok := t.(tHelper); ok { - h.Helper() - } -- return compareTwoValues(t, e1, e2, []CompareType{compareGreater}, "\"%v\" is not greater than \"%v\"", msgAndArgs...) -+ return compareTwoValues(t, e1, e2, []compareResult{compareGreater}, "\"%v\" is not greater than \"%v\"", msgAndArgs...) - } - - // GreaterOrEqual asserts that the first element is greater than or equal to the second -@@ -394,7 +403,7 @@ func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...in - if h, ok := t.(tHelper); ok { - h.Helper() - } -- return compareTwoValues(t, e1, e2, []CompareType{compareGreater, compareEqual}, "\"%v\" is not greater than or equal to \"%v\"", msgAndArgs...) -+ return compareTwoValues(t, e1, e2, []compareResult{compareGreater, compareEqual}, "\"%v\" is not greater than or equal to \"%v\"", msgAndArgs...) - } - - // Less asserts that the first element is less than the second -@@ -406,7 +415,7 @@ func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) - if h, ok := t.(tHelper); ok { - h.Helper() - } -- return compareTwoValues(t, e1, e2, []CompareType{compareLess}, "\"%v\" is not less than \"%v\"", msgAndArgs...) -+ return compareTwoValues(t, e1, e2, []compareResult{compareLess}, "\"%v\" is not less than \"%v\"", msgAndArgs...) - } - - // LessOrEqual asserts that the first element is less than or equal to the second -@@ -419,7 +428,7 @@ func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...inter - if h, ok := t.(tHelper); ok { - h.Helper() - } -- return compareTwoValues(t, e1, e2, []CompareType{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs...) -+ return compareTwoValues(t, e1, e2, []compareResult{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs...) - } - - // Positive asserts that the specified element is positive -@@ -431,7 +440,7 @@ func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) bool { - h.Helper() - } - zero := reflect.Zero(reflect.TypeOf(e)) -- return compareTwoValues(t, e, zero.Interface(), []CompareType{compareGreater}, "\"%v\" is not positive", msgAndArgs...) -+ return compareTwoValues(t, e, zero.Interface(), []compareResult{compareGreater}, "\"%v\" is not positive", msgAndArgs...) - } - - // Negative asserts that the specified element is negative -@@ -443,10 +452,10 @@ func Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) bool { - h.Helper() - } - zero := reflect.Zero(reflect.TypeOf(e)) -- return compareTwoValues(t, e, zero.Interface(), []CompareType{compareLess}, "\"%v\" is not negative", msgAndArgs...) -+ return compareTwoValues(t, e, zero.Interface(), []compareResult{compareLess}, "\"%v\" is not negative", msgAndArgs...) - } - --func compareTwoValues(t TestingT, e1 interface{}, e2 interface{}, allowedComparesResults []CompareType, failMessage string, msgAndArgs ...interface{}) bool { -+func compareTwoValues(t TestingT, e1 interface{}, e2 interface{}, allowedComparesResults []compareResult, failMessage string, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } -@@ -469,7 +478,7 @@ func compareTwoValues(t TestingT, e1 interface{}, e2 interface{}, allowedCompare - return true - } - --func containsValue(values []CompareType, value CompareType) bool { -+func containsValue(values []compareResult, value compareResult) bool { - for _, v := range values { - if v == value { - return true -diff --git a/vendor/github.com/stretchr/testify/assert/assertion_format.go b/vendor/github.com/stretchr/testify/assert/assertion_format.go -index 3ddab109a..190634165 100644 ---- a/vendor/github.com/stretchr/testify/assert/assertion_format.go -+++ b/vendor/github.com/stretchr/testify/assert/assertion_format.go -@@ -104,8 +104,8 @@ func EqualExportedValuesf(t TestingT, expected interface{}, actual interface{}, - return EqualExportedValues(t, expected, actual, append([]interface{}{msg}, args...)...) - } - --// EqualValuesf asserts that two objects are equal or convertible to the same types --// and equal. -+// EqualValuesf asserts that two objects are equal or convertible to the larger -+// type and equal. - // - // assert.EqualValuesf(t, uint32(123), int32(123), "error message %s", "formatted") - func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { -@@ -186,7 +186,7 @@ func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick - // assert.EventuallyWithTf(t, func(c *assert.CollectT, "error message %s", "formatted") { - // // add assertions as needed; any assertion failure will fail the current tick - // assert.True(c, externalValue, "expected 'externalValue' to be true") --// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") -+// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") - func EventuallyWithTf(t TestingT, condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -568,6 +568,23 @@ func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, a - return NotContains(t, s, contains, append([]interface{}{msg}, args...)...) - } - -+// NotElementsMatchf asserts that the specified listA(array, slice...) is NOT equal to specified -+// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, -+// the number of appearances of each of them in both lists should not match. -+// This is an inverse of ElementsMatch. -+// -+// assert.NotElementsMatchf(t, [1, 1, 2, 3], [1, 1, 2, 3], "error message %s", "formatted") -> false -+// -+// assert.NotElementsMatchf(t, [1, 1, 2, 3], [1, 2, 3], "error message %s", "formatted") -> true -+// -+// assert.NotElementsMatchf(t, [1, 2, 3], [1, 2, 4], "error message %s", "formatted") -> true -+func NotElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) bool { -+ if h, ok := t.(tHelper); ok { -+ h.Helper() -+ } -+ return NotElementsMatch(t, listA, listB, append([]interface{}{msg}, args...)...) ++// EncodeHeadersParam is parameters to EncodeHeaders. ++type EncodeHeadersParam struct { ++ Request Request ++ ++ // AddGzipHeader indicates that an "accept-encoding: gzip" header should be ++ // added to the request. ++ AddGzipHeader bool ++ ++ // PeerMaxHeaderListSize, when non-zero, is the peer's MAX_HEADER_LIST_SIZE setting. ++ PeerMaxHeaderListSize uint64 ++ ++ // DefaultUserAgent is the User-Agent header to send when the request ++ // neither contains a User-Agent nor disables it. ++ DefaultUserAgent string +} + - // NotEmptyf asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either - // a slice or a channel with len == 0. - // -@@ -604,7 +621,16 @@ func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg s - return NotEqualValues(t, expected, actual, append([]interface{}{msg}, args...)...) - } - --// NotErrorIsf asserts that at none of the errors in err's chain matches target. -+// NotErrorAsf asserts that none of the errors in err's chain matches target, -+// but if so, sets target to that error value. -+func NotErrorAsf(t TestingT, err error, target interface{}, msg string, args ...interface{}) bool { -+ if h, ok := t.(tHelper); ok { -+ h.Helper() -+ } -+ return NotErrorAs(t, err, target, append([]interface{}{msg}, args...)...) ++// EncodeHeadersParam is the result of EncodeHeaders. ++type EncodeHeadersResult struct { ++ HasBody bool ++ HasTrailers bool +} + -+// NotErrorIsf asserts that none of the errors in err's chain matches target. - // This is a wrapper for errors.Is. - func NotErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { -diff --git a/vendor/github.com/stretchr/testify/assert/assertion_forward.go b/vendor/github.com/stretchr/testify/assert/assertion_forward.go -index a84e09bd4..21629087b 100644 ---- a/vendor/github.com/stretchr/testify/assert/assertion_forward.go -+++ b/vendor/github.com/stretchr/testify/assert/assertion_forward.go -@@ -186,8 +186,8 @@ func (a *Assertions) EqualExportedValuesf(expected interface{}, actual interface - return EqualExportedValuesf(a.t, expected, actual, msg, args...) - } - --// EqualValues asserts that two objects are equal or convertible to the same types --// and equal. -+// EqualValues asserts that two objects are equal or convertible to the larger -+// type and equal. - // - // a.EqualValues(uint32(123), int32(123)) - func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { -@@ -197,8 +197,8 @@ func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAn - return EqualValues(a.t, expected, actual, msgAndArgs...) - } - --// EqualValuesf asserts that two objects are equal or convertible to the same types --// and equal. -+// EqualValuesf asserts that two objects are equal or convertible to the larger -+// type and equal. - // - // a.EqualValuesf(uint32(123), int32(123), "error message %s", "formatted") - func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { -@@ -336,7 +336,7 @@ func (a *Assertions) Eventually(condition func() bool, waitFor time.Duration, ti - // a.EventuallyWithT(func(c *assert.CollectT) { - // // add assertions as needed; any assertion failure will fail the current tick - // assert.True(c, externalValue, "expected 'externalValue' to be true") --// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") -+// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") - func (a *Assertions) EventuallyWithT(condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() -@@ -361,7 +361,7 @@ func (a *Assertions) EventuallyWithT(condition func(collect *CollectT), waitFor - // a.EventuallyWithTf(func(c *assert.CollectT, "error message %s", "formatted") { - // // add assertions as needed; any assertion failure will fail the current tick - // assert.True(c, externalValue, "expected 'externalValue' to be true") --// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") -+// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") - func (a *Assertions) EventuallyWithTf(condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() -@@ -1128,6 +1128,40 @@ func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg strin - return NotContainsf(a.t, s, contains, msg, args...) - } - -+// NotElementsMatch asserts that the specified listA(array, slice...) is NOT equal to specified -+// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, -+// the number of appearances of each of them in both lists should not match. -+// This is an inverse of ElementsMatch. -+// -+// a.NotElementsMatch([1, 1, 2, 3], [1, 1, 2, 3]) -> false -+// -+// a.NotElementsMatch([1, 1, 2, 3], [1, 2, 3]) -> true -+// -+// a.NotElementsMatch([1, 2, 3], [1, 2, 4]) -> true -+func (a *Assertions) NotElementsMatch(listA interface{}, listB interface{}, msgAndArgs ...interface{}) bool { -+ if h, ok := a.t.(tHelper); ok { -+ h.Helper() ++// EncodeHeaders constructs request headers common to HTTP/2 and HTTP/3. ++// It validates a request and calls headerf with each pseudo-header and header ++// for the request. ++// The headerf function is called with the validated, canonicalized header name. ++func EncodeHeaders(ctx context.Context, param EncodeHeadersParam, headerf func(name, value string)) (res EncodeHeadersResult, _ error) { ++ req := param.Request ++ ++ // Check for invalid connection-level headers. ++ if err := checkConnHeaders(req.Header); err != nil { ++ return res, err + } -+ return NotElementsMatch(a.t, listA, listB, msgAndArgs...) -+} + -+// NotElementsMatchf asserts that the specified listA(array, slice...) is NOT equal to specified -+// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, -+// the number of appearances of each of them in both lists should not match. -+// This is an inverse of ElementsMatch. -+// -+// a.NotElementsMatchf([1, 1, 2, 3], [1, 1, 2, 3], "error message %s", "formatted") -> false -+// -+// a.NotElementsMatchf([1, 1, 2, 3], [1, 2, 3], "error message %s", "formatted") -> true -+// -+// a.NotElementsMatchf([1, 2, 3], [1, 2, 4], "error message %s", "formatted") -> true -+func (a *Assertions) NotElementsMatchf(listA interface{}, listB interface{}, msg string, args ...interface{}) bool { -+ if h, ok := a.t.(tHelper); ok { -+ h.Helper() ++ if req.URL == nil { ++ return res, errors.New("Request.URL is nil") + } -+ return NotElementsMatchf(a.t, listA, listB, msg, args...) -+} + - // NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either - // a slice or a channel with len == 0. - // -@@ -1200,7 +1234,25 @@ func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg str - return NotEqualf(a.t, expected, actual, msg, args...) - } - --// NotErrorIs asserts that at none of the errors in err's chain matches target. -+// NotErrorAs asserts that none of the errors in err's chain matches target, -+// but if so, sets target to that error value. -+func (a *Assertions) NotErrorAs(err error, target interface{}, msgAndArgs ...interface{}) bool { -+ if h, ok := a.t.(tHelper); ok { -+ h.Helper() ++ host := req.Host ++ if host == "" { ++ host = req.URL.Host ++ } ++ host, err := httpguts.PunycodeHostPort(host) ++ if err != nil { ++ return res, err ++ } ++ if !httpguts.ValidHostHeader(host) { ++ return res, errors.New("invalid Host header") + } -+ return NotErrorAs(a.t, err, target, msgAndArgs...) -+} + -+// NotErrorAsf asserts that none of the errors in err's chain matches target, -+// but if so, sets target to that error value. -+func (a *Assertions) NotErrorAsf(err error, target interface{}, msg string, args ...interface{}) bool { -+ if h, ok := a.t.(tHelper); ok { -+ h.Helper() ++ // isNormalConnect is true if this is a non-extended CONNECT request. ++ isNormalConnect := false ++ var protocol string ++ if vv := req.Header[":protocol"]; len(vv) > 0 { ++ protocol = vv[0] ++ } ++ if req.Method == "CONNECT" && protocol == "" { ++ isNormalConnect = true ++ } else if protocol != "" && req.Method != "CONNECT" { ++ return res, errors.New("invalid :protocol header in non-CONNECT request") + } -+ return NotErrorAsf(a.t, err, target, msg, args...) -+} + -+// NotErrorIs asserts that none of the errors in err's chain matches target. - // This is a wrapper for errors.Is. - func (a *Assertions) NotErrorIs(err error, target error, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { -@@ -1209,7 +1261,7 @@ func (a *Assertions) NotErrorIs(err error, target error, msgAndArgs ...interface - return NotErrorIs(a.t, err, target, msgAndArgs...) - } - --// NotErrorIsf asserts that at none of the errors in err's chain matches target. -+// NotErrorIsf asserts that none of the errors in err's chain matches target. - // This is a wrapper for errors.Is. - func (a *Assertions) NotErrorIsf(err error, target error, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { -diff --git a/vendor/github.com/stretchr/testify/assert/assertion_order.go b/vendor/github.com/stretchr/testify/assert/assertion_order.go -index 00df62a05..1d2f71824 100644 ---- a/vendor/github.com/stretchr/testify/assert/assertion_order.go -+++ b/vendor/github.com/stretchr/testify/assert/assertion_order.go -@@ -6,7 +6,7 @@ import ( - ) - - // isOrdered checks that collection contains orderable elements. --func isOrdered(t TestingT, object interface{}, allowedComparesResults []CompareType, failMessage string, msgAndArgs ...interface{}) bool { -+func isOrdered(t TestingT, object interface{}, allowedComparesResults []compareResult, failMessage string, msgAndArgs ...interface{}) bool { - objKind := reflect.TypeOf(object).Kind() - if objKind != reflect.Slice && objKind != reflect.Array { - return false -@@ -50,7 +50,7 @@ func isOrdered(t TestingT, object interface{}, allowedComparesResults []CompareT - // assert.IsIncreasing(t, []float{1, 2}) - // assert.IsIncreasing(t, []string{"a", "b"}) - func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { -- return isOrdered(t, object, []CompareType{compareLess}, "\"%v\" is not less than \"%v\"", msgAndArgs...) -+ return isOrdered(t, object, []compareResult{compareLess}, "\"%v\" is not less than \"%v\"", msgAndArgs...) - } - - // IsNonIncreasing asserts that the collection is not increasing -@@ -59,7 +59,7 @@ func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) boo - // assert.IsNonIncreasing(t, []float{2, 1}) - // assert.IsNonIncreasing(t, []string{"b", "a"}) - func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { -- return isOrdered(t, object, []CompareType{compareEqual, compareGreater}, "\"%v\" is not greater than or equal to \"%v\"", msgAndArgs...) -+ return isOrdered(t, object, []compareResult{compareEqual, compareGreater}, "\"%v\" is not greater than or equal to \"%v\"", msgAndArgs...) - } - - // IsDecreasing asserts that the collection is decreasing -@@ -68,7 +68,7 @@ func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) - // assert.IsDecreasing(t, []float{2, 1}) - // assert.IsDecreasing(t, []string{"b", "a"}) - func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { -- return isOrdered(t, object, []CompareType{compareGreater}, "\"%v\" is not greater than \"%v\"", msgAndArgs...) -+ return isOrdered(t, object, []compareResult{compareGreater}, "\"%v\" is not greater than \"%v\"", msgAndArgs...) - } - - // IsNonDecreasing asserts that the collection is not decreasing -@@ -77,5 +77,5 @@ func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) boo - // assert.IsNonDecreasing(t, []float{1, 2}) - // assert.IsNonDecreasing(t, []string{"a", "b"}) - func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { -- return isOrdered(t, object, []CompareType{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs...) -+ return isOrdered(t, object, []compareResult{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs...) - } -diff --git a/vendor/github.com/stretchr/testify/assert/assertions.go b/vendor/github.com/stretchr/testify/assert/assertions.go -index 0b7570f21..4e91332bb 100644 ---- a/vendor/github.com/stretchr/testify/assert/assertions.go -+++ b/vendor/github.com/stretchr/testify/assert/assertions.go -@@ -19,7 +19,9 @@ import ( - - "github.com/davecgh/go-spew/spew" - "github.com/pmezard/go-difflib/difflib" -- "gopkg.in/yaml.v3" -+ -+ // Wrapper around gopkg.in/yaml.v3 -+ "github.com/stretchr/testify/assert/yaml" - ) - - //go:generate sh -c "cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=assert -template=assertion_format.go.tmpl" -@@ -45,6 +47,10 @@ type BoolAssertionFunc func(TestingT, bool, ...interface{}) bool - // for table driven tests. - type ErrorAssertionFunc func(TestingT, error, ...interface{}) bool - -+// PanicAssertionFunc is a common function prototype when validating a panic value. Can be useful -+// for table driven tests. -+type PanicAssertionFunc = func(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool ++ // Validate the path, except for non-extended CONNECT requests which have no path. ++ var path string ++ if !isNormalConnect { ++ path = req.URL.RequestURI() ++ if !validPseudoPath(path) { ++ orig := path ++ path = strings.TrimPrefix(path, req.URL.Scheme+"://"+host) ++ if !validPseudoPath(path) { ++ if req.URL.Opaque != "" { ++ return res, fmt.Errorf("invalid request :path %q from URL.Opaque = %q", orig, req.URL.Opaque) ++ } else { ++ return res, fmt.Errorf("invalid request :path %q", orig) ++ } ++ } ++ } ++ } + - // Comparison is a custom function that returns true on success and false on failure - type Comparison func() (success bool) - -@@ -496,7 +502,13 @@ func Same(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) b - h.Helper() - } - -- if !samePointers(expected, actual) { -+ same, ok := samePointers(expected, actual) -+ if !ok { -+ return Fail(t, "Both arguments must be pointers", msgAndArgs...) ++ // Check for any invalid headers+trailers and return an error before we ++ // potentially pollute our hpack state. (We want to be able to ++ // continue to reuse the hpack encoder for future requests) ++ if err := validateHeaders(req.Header); err != "" { ++ return res, fmt.Errorf("invalid HTTP header %s", err) ++ } ++ if err := validateHeaders(req.Trailer); err != "" { ++ return res, fmt.Errorf("invalid HTTP trailer %s", err) + } + -+ if !same { -+ // both are pointers but not the same type & pointing to the same address - return Fail(t, fmt.Sprintf("Not same: \n"+ - "expected: %p %#v\n"+ - "actual : %p %#v", expected, expected, actual, actual), msgAndArgs...) -@@ -516,7 +528,13 @@ func NotSame(t TestingT, expected, actual interface{}, msgAndArgs ...interface{} - h.Helper() - } - -- if samePointers(expected, actual) { -+ same, ok := samePointers(expected, actual) -+ if !ok { -+ //fails when the arguments are not pointers -+ return !(Fail(t, "Both arguments must be pointers", msgAndArgs...)) ++ trailers, err := commaSeparatedTrailers(req.Trailer) ++ if err != nil { ++ return res, err + } + -+ if same { - return Fail(t, fmt.Sprintf( - "Expected and actual point to the same object: %p %#v", - expected, expected), msgAndArgs...) -@@ -524,21 +542,23 @@ func NotSame(t TestingT, expected, actual interface{}, msgAndArgs ...interface{} - return true - } - --// samePointers compares two generic interface objects and returns whether --// they point to the same object --func samePointers(first, second interface{}) bool { -+// samePointers checks if two generic interface objects are pointers of the same -+// type pointing to the same object. It returns two values: same indicating if -+// they are the same type and point to the same object, and ok indicating that -+// both inputs are pointers. -+func samePointers(first, second interface{}) (same bool, ok bool) { - firstPtr, secondPtr := reflect.ValueOf(first), reflect.ValueOf(second) - if firstPtr.Kind() != reflect.Ptr || secondPtr.Kind() != reflect.Ptr { -- return false -+ return false, false //not both are pointers - } - - firstType, secondType := reflect.TypeOf(first), reflect.TypeOf(second) - if firstType != secondType { -- return false -+ return false, true // both are pointers, but of different types - } - - // compare pointer addresses -- return first == second -+ return first == second, true - } - - // formatUnequalValues takes two values of arbitrary types and returns string -@@ -572,8 +592,8 @@ func truncatingFormat(data interface{}) string { - return value - } - --// EqualValues asserts that two objects are equal or convertible to the same types --// and equal. -+// EqualValues asserts that two objects are equal or convertible to the larger -+// type and equal. - // - // assert.EqualValues(t, uint32(123), int32(123)) - func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { -@@ -615,21 +635,6 @@ func EqualExportedValues(t TestingT, expected, actual interface{}, msgAndArgs .. - return Fail(t, fmt.Sprintf("Types expected to match exactly\n\t%v != %v", aType, bType), msgAndArgs...) - } - -- if aType.Kind() == reflect.Ptr { -- aType = aType.Elem() -- } -- if bType.Kind() == reflect.Ptr { -- bType = bType.Elem() -- } -- -- if aType.Kind() != reflect.Struct { -- return Fail(t, fmt.Sprintf("Types expected to both be struct or pointer to struct \n\t%v != %v", aType.Kind(), reflect.Struct), msgAndArgs...) -- } -- -- if bType.Kind() != reflect.Struct { -- return Fail(t, fmt.Sprintf("Types expected to both be struct or pointer to struct \n\t%v != %v", bType.Kind(), reflect.Struct), msgAndArgs...) -- } -- - expected = copyExportedFields(expected) - actual = copyExportedFields(actual) - -@@ -1170,6 +1175,39 @@ func formatListDiff(listA, listB interface{}, extraA, extraB []interface{}) stri - return msg.String() - } - -+// NotElementsMatch asserts that the specified listA(array, slice...) is NOT equal to specified -+// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, -+// the number of appearances of each of them in both lists should not match. -+// This is an inverse of ElementsMatch. -+// -+// assert.NotElementsMatch(t, [1, 1, 2, 3], [1, 1, 2, 3]) -> false -+// -+// assert.NotElementsMatch(t, [1, 1, 2, 3], [1, 2, 3]) -> true -+// -+// assert.NotElementsMatch(t, [1, 2, 3], [1, 2, 4]) -> true -+func NotElementsMatch(t TestingT, listA, listB interface{}, msgAndArgs ...interface{}) (ok bool) { -+ if h, ok := t.(tHelper); ok { -+ h.Helper() -+ } -+ if isEmpty(listA) && isEmpty(listB) { -+ return Fail(t, "listA and listB contain the same elements", msgAndArgs) -+ } -+ -+ if !isList(t, listA, msgAndArgs...) { -+ return Fail(t, "listA is not a list type", msgAndArgs...) -+ } -+ if !isList(t, listB, msgAndArgs...) { -+ return Fail(t, "listB is not a list type", msgAndArgs...) -+ } -+ -+ extraA, extraB := diffLists(listA, listB) -+ if len(extraA) == 0 && len(extraB) == 0 { -+ return Fail(t, "listA and listB contain the same elements", msgAndArgs) -+ } ++ enumerateHeaders := func(f func(name, value string)) { ++ // 8.1.2.3 Request Pseudo-Header Fields ++ // The :path pseudo-header field includes the path and query parts of the ++ // target URI (the path-absolute production and optionally a '?' character ++ // followed by the query production, see Sections 3.3 and 3.4 of ++ // [RFC3986]). ++ f(":authority", host) ++ m := req.Method ++ if m == "" { ++ m = "GET" ++ } ++ f(":method", m) ++ if !isNormalConnect { ++ f(":path", path) ++ f(":scheme", req.URL.Scheme) ++ } ++ if protocol != "" { ++ f(":protocol", protocol) ++ } ++ if trailers != "" { ++ f("trailer", trailers) ++ } + -+ return true -+} ++ var didUA bool ++ for k, vv := range req.Header { ++ if asciiEqualFold(k, "host") || asciiEqualFold(k, "content-length") { ++ // Host is :authority, already sent. ++ // Content-Length is automatic, set below. ++ continue ++ } else if asciiEqualFold(k, "connection") || ++ asciiEqualFold(k, "proxy-connection") || ++ asciiEqualFold(k, "transfer-encoding") || ++ asciiEqualFold(k, "upgrade") || ++ asciiEqualFold(k, "keep-alive") { ++ // Per 8.1.2.2 Connection-Specific Header ++ // Fields, don't send connection-specific ++ // fields. We have already checked if any ++ // are error-worthy so just ignore the rest. ++ continue ++ } else if asciiEqualFold(k, "user-agent") { ++ // Match Go's http1 behavior: at most one ++ // User-Agent. If set to nil or empty string, ++ // then omit it. Otherwise if not mentioned, ++ // include the default (below). ++ didUA = true ++ if len(vv) < 1 { ++ continue ++ } ++ vv = vv[:1] ++ if vv[0] == "" { ++ continue ++ } ++ } else if asciiEqualFold(k, "cookie") { ++ // Per 8.1.2.5 To allow for better compression efficiency, the ++ // Cookie header field MAY be split into separate header fields, ++ // each with one or more cookie-pairs. ++ for _, v := range vv { ++ for { ++ p := strings.IndexByte(v, ';') ++ if p < 0 { ++ break ++ } ++ f("cookie", v[:p]) ++ p++ ++ // strip space after semicolon if any. ++ for p+1 <= len(v) && v[p] == ' ' { ++ p++ ++ } ++ v = v[p:] ++ } ++ if len(v) > 0 { ++ f("cookie", v) ++ } ++ } ++ continue ++ } else if k == ":protocol" { ++ // :protocol pseudo-header was already sent above. ++ continue ++ } + - // Condition uses a Comparison to assert a complex condition. - func Condition(t TestingT, comp Comparison, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { -@@ -1488,6 +1526,9 @@ func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAnd - if err != nil { - return Fail(t, err.Error(), msgAndArgs...) - } -+ if math.IsNaN(actualEpsilon) { -+ return Fail(t, "relative error is NaN", msgAndArgs...) -+ } - if actualEpsilon > epsilon { - return Fail(t, fmt.Sprintf("Relative error is too high: %#v (expected)\n"+ - " < %#v (actual)", epsilon, actualEpsilon), msgAndArgs...) -@@ -1611,7 +1652,6 @@ func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...in - - // matchRegexp return true if a specified regexp matches a string. - func matchRegexp(rx interface{}, str interface{}) bool { -- - var r *regexp.Regexp - if rr, ok := rx.(*regexp.Regexp); ok { - r = rr -@@ -1619,7 +1659,14 @@ func matchRegexp(rx interface{}, str interface{}) bool { - r = regexp.MustCompile(fmt.Sprint(rx)) - } - -- return (r.FindStringIndex(fmt.Sprint(str)) != nil) -+ switch v := str.(type) { -+ case []byte: -+ return r.Match(v) -+ case string: -+ return r.MatchString(v) -+ default: -+ return r.MatchString(fmt.Sprint(v)) -+ } - - } - -@@ -1872,7 +1919,7 @@ var spewConfigStringerEnabled = spew.ConfigState{ - MaxDepth: 10, - } - --type tHelper interface { -+type tHelper = interface { - Helper() - } - -@@ -1911,6 +1958,9 @@ func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick t - - // CollectT implements the TestingT interface and collects all errors. - type CollectT struct { -+ // A slice of errors. Non-nil slice denotes a failure. -+ // If it's non-nil but len(c.errors) == 0, this is also a failure -+ // obtained by direct c.FailNow() call. - errors []error - } - -@@ -1919,9 +1969,10 @@ func (c *CollectT) Errorf(format string, args ...interface{}) { - c.errors = append(c.errors, fmt.Errorf(format, args...)) - } - --// FailNow panics. --func (*CollectT) FailNow() { -- panic("Assertion failed") -+// FailNow stops execution by calling runtime.Goexit. -+func (c *CollectT) FailNow() { -+ c.fail() -+ runtime.Goexit() - } - - // Deprecated: That was a method for internal usage that should not have been published. Now just panics. -@@ -1934,6 +1985,16 @@ func (*CollectT) Copy(TestingT) { - panic("Copy() is deprecated") - } - -+func (c *CollectT) fail() { -+ if !c.failed() { -+ c.errors = []error{} // Make it non-nil to mark a failure. ++ for _, v := range vv { ++ f(k, v) ++ } ++ } ++ if shouldSendReqContentLength(req.Method, req.ActualContentLength) { ++ f("content-length", strconv.FormatInt(req.ActualContentLength, 10)) ++ } ++ if param.AddGzipHeader { ++ f("accept-encoding", "gzip") ++ } ++ if !didUA { ++ f("user-agent", param.DefaultUserAgent) ++ } + } -+} + -+func (c *CollectT) failed() bool { -+ return c.errors != nil -+} ++ // Do a first pass over the headers counting bytes to ensure ++ // we don't exceed cc.peerMaxHeaderListSize. This is done as a ++ // separate pass before encoding the headers to prevent ++ // modifying the hpack state. ++ if param.PeerMaxHeaderListSize > 0 { ++ hlSize := uint64(0) ++ enumerateHeaders(func(name, value string) { ++ hf := hpack.HeaderField{Name: name, Value: value} ++ hlSize += uint64(hf.Size()) ++ }) + - // EventuallyWithT asserts that given condition will be met in waitFor time, - // periodically checking target function each tick. In contrast to Eventually, - // it supplies a CollectT to the condition function, so that the condition -@@ -1951,14 +2012,14 @@ func (*CollectT) Copy(TestingT) { - // assert.EventuallyWithT(t, func(c *assert.CollectT) { - // // add assertions as needed; any assertion failure will fail the current tick - // assert.True(c, externalValue, "expected 'externalValue' to be true") --// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") -+// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") - func EventuallyWithT(t TestingT, condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - - var lastFinishedTickErrs []error -- ch := make(chan []error, 1) -+ ch := make(chan *CollectT, 1) - - timer := time.NewTimer(waitFor) - defer timer.Stop() -@@ -1978,16 +2039,16 @@ func EventuallyWithT(t TestingT, condition func(collect *CollectT), waitFor time - go func() { - collect := new(CollectT) - defer func() { -- ch <- collect.errors -+ ch <- collect - }() - condition(collect) - }() -- case errs := <-ch: -- if len(errs) == 0 { -+ case collect := <-ch: -+ if !collect.failed() { - return true - } - // Keep the errors from the last ended condition, so that they can be copied to t if timeout is reached. -- lastFinishedTickErrs = errs -+ lastFinishedTickErrs = collect.errors - tick = ticker.C - } - } -@@ -2049,7 +2110,7 @@ func ErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool { - ), msgAndArgs...) - } - --// NotErrorIs asserts that at none of the errors in err's chain matches target. -+// NotErrorIs asserts that none of the errors in err's chain matches target. - // This is a wrapper for errors.Is. - func NotErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { -@@ -2090,6 +2151,24 @@ func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{ - ), msgAndArgs...) - } - -+// NotErrorAs asserts that none of the errors in err's chain matches target, -+// but if so, sets target to that error value. -+func NotErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{}) bool { -+ if h, ok := t.(tHelper); ok { -+ h.Helper() -+ } -+ if !errors.As(err, target) { -+ return true ++ if hlSize > param.PeerMaxHeaderListSize { ++ return res, ErrRequestHeaderListSize ++ } + } + -+ chain := buildErrorChainString(err) -+ -+ return Fail(t, fmt.Sprintf("Target error should not be in err chain:\n"+ -+ "found: %q\n"+ -+ "in chain: %s", target, chain, -+ ), msgAndArgs...) -+} ++ trace := httptrace.ContextClientTrace(ctx) + - func buildErrorChainString(err error) string { - if err == nil { - return "" -diff --git a/vendor/github.com/stretchr/testify/assert/yaml/yaml_custom.go b/vendor/github.com/stretchr/testify/assert/yaml/yaml_custom.go -new file mode 100644 -index 000000000..baa0cc7d7 ---- /dev/null -+++ b/vendor/github.com/stretchr/testify/assert/yaml/yaml_custom.go -@@ -0,0 +1,25 @@ -+//go:build testify_yaml_custom && !testify_yaml_fail && !testify_yaml_default -+// +build testify_yaml_custom,!testify_yaml_fail,!testify_yaml_default ++ // Header list size is ok. Write the headers. ++ enumerateHeaders(func(name, value string) { ++ name, ascii := LowerHeader(name) ++ if !ascii { ++ // Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header ++ // field names have to be ASCII characters (just as in HTTP/1.x). ++ return ++ } + -+// Package yaml is an implementation of YAML functions that calls a pluggable implementation. -+// -+// This implementation is selected with the testify_yaml_custom build tag. -+// -+// go test -tags testify_yaml_custom -+// -+// This implementation can be used at build time to replace the default implementation -+// to avoid linking with [gopkg.in/yaml.v3]. -+// -+// In your test package: -+// -+// import assertYaml "github.com/stretchr/testify/assert/yaml" -+// -+// func init() { -+// assertYaml.Unmarshal = func (in []byte, out interface{}) error { -+// // ... -+// return nil -+// } -+// } -+package yaml -+ -+var Unmarshal func(in []byte, out interface{}) error -diff --git a/vendor/github.com/stretchr/testify/assert/yaml/yaml_default.go b/vendor/github.com/stretchr/testify/assert/yaml/yaml_default.go -new file mode 100644 -index 000000000..b83c6cf64 ---- /dev/null -+++ b/vendor/github.com/stretchr/testify/assert/yaml/yaml_default.go -@@ -0,0 +1,37 @@ -+//go:build !testify_yaml_fail && !testify_yaml_custom -+// +build !testify_yaml_fail,!testify_yaml_custom ++ headerf(name, value) + -+// Package yaml is just an indirection to handle YAML deserialization. -+// -+// This package is just an indirection that allows the builder to override the -+// indirection with an alternative implementation of this package that uses -+// another implementation of YAML deserialization. This allows to not either not -+// use YAML deserialization at all, or to use another implementation than -+// [gopkg.in/yaml.v3] (for example for license compatibility reasons, see [PR #1120]). -+// -+// Alternative implementations are selected using build tags: -+// -+// - testify_yaml_fail: [Unmarshal] always fails with an error -+// - testify_yaml_custom: [Unmarshal] is a variable. Caller must initialize it -+// before calling any of [github.com/stretchr/testify/assert.YAMLEq] or -+// [github.com/stretchr/testify/assert.YAMLEqf]. -+// -+// Usage: -+// -+// go test -tags testify_yaml_fail -+// -+// You can check with "go list" which implementation is linked: -+// -+// go list -f '{{.Imports}}' github.com/stretchr/testify/assert/yaml -+// go list -tags testify_yaml_fail -f '{{.Imports}}' github.com/stretchr/testify/assert/yaml -+// go list -tags testify_yaml_custom -f '{{.Imports}}' github.com/stretchr/testify/assert/yaml -+// -+// [PR #1120]: https://github.com/stretchr/testify/pull/1120 -+package yaml -+ -+import goyaml "gopkg.in/yaml.v3" ++ if trace != nil && trace.WroteHeaderField != nil { ++ trace.WroteHeaderField(name, []string{value}) ++ } ++ }) + -+// Unmarshal is just a wrapper of [gopkg.in/yaml.v3.Unmarshal]. -+func Unmarshal(in []byte, out interface{}) error { -+ return goyaml.Unmarshal(in, out) ++ res.HasBody = req.ActualContentLength != 0 ++ res.HasTrailers = trailers != "" ++ return res, nil +} -diff --git a/vendor/github.com/stretchr/testify/assert/yaml/yaml_fail.go b/vendor/github.com/stretchr/testify/assert/yaml/yaml_fail.go -new file mode 100644 -index 000000000..e78f7dfe6 ---- /dev/null -+++ b/vendor/github.com/stretchr/testify/assert/yaml/yaml_fail.go -@@ -0,0 +1,18 @@ -+//go:build testify_yaml_fail && !testify_yaml_custom && !testify_yaml_default -+// +build testify_yaml_fail,!testify_yaml_custom,!testify_yaml_default + -+// Package yaml is an implementation of YAML functions that always fail. -+// -+// This implementation can be used at build time to replace the default implementation -+// to avoid linking with [gopkg.in/yaml.v3]: -+// -+// go test -tags testify_yaml_fail -+package yaml -+ -+import "errors" -+ -+var errNotImplemented = errors.New("YAML functions are not available (see https://pkg.go.dev/github.com/stretchr/testify/assert/yaml)") -+ -+func Unmarshal([]byte, interface{}) error { -+ return errNotImplemented -+} -diff --git a/vendor/github.com/stretchr/testify/require/require.go b/vendor/github.com/stretchr/testify/require/require.go -index 506a82f80..d8921950d 100644 ---- a/vendor/github.com/stretchr/testify/require/require.go -+++ b/vendor/github.com/stretchr/testify/require/require.go -@@ -34,9 +34,9 @@ func Conditionf(t TestingT, comp assert.Comparison, msg string, args ...interfac - // Contains asserts that the specified string, list(array, slice...) or map contains the - // specified substring or element. - // --// assert.Contains(t, "Hello World", "World") --// assert.Contains(t, ["Hello", "World"], "World") --// assert.Contains(t, {"Hello": "World"}, "Hello") -+// require.Contains(t, "Hello World", "World") -+// require.Contains(t, ["Hello", "World"], "World") -+// require.Contains(t, {"Hello": "World"}, "Hello") - func Contains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -50,9 +50,9 @@ func Contains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...int - // Containsf asserts that the specified string, list(array, slice...) or map contains the - // specified substring or element. - // --// assert.Containsf(t, "Hello World", "World", "error message %s", "formatted") --// assert.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted") --// assert.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted") -+// require.Containsf(t, "Hello World", "World", "error message %s", "formatted") -+// require.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted") -+// require.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted") - func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -91,7 +91,7 @@ func DirExistsf(t TestingT, path string, msg string, args ...interface{}) { - // listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, - // the number of appearances of each of them in both lists should match. - // --// assert.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2]) -+// require.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2]) - func ElementsMatch(t TestingT, listA interface{}, listB interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -106,7 +106,7 @@ func ElementsMatch(t TestingT, listA interface{}, listB interface{}, msgAndArgs - // listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, - // the number of appearances of each of them in both lists should match. - // --// assert.ElementsMatchf(t, [1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted") -+// require.ElementsMatchf(t, [1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted") - func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -120,7 +120,7 @@ func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string - // Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either - // a slice or a channel with len == 0. - // --// assert.Empty(t, obj) -+// require.Empty(t, obj) - func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -134,7 +134,7 @@ func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) { - // Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either - // a slice or a channel with len == 0. - // --// assert.Emptyf(t, obj, "error message %s", "formatted") -+// require.Emptyf(t, obj, "error message %s", "formatted") - func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -147,7 +147,7 @@ func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) { - - // Equal asserts that two objects are equal. - // --// assert.Equal(t, 123, 123) -+// require.Equal(t, 123, 123) - // - // Pointer variable equality is determined based on the equality of the - // referenced values (as opposed to the memory addresses). Function equality -@@ -166,7 +166,7 @@ func Equal(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...i - // and that it is equal to the provided error. - // - // actualObj, err := SomeFunction() --// assert.EqualError(t, err, expectedErrorString) -+// require.EqualError(t, err, expectedErrorString) - func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -181,7 +181,7 @@ func EqualError(t TestingT, theError error, errString string, msgAndArgs ...inte - // and that it is equal to the provided error. - // - // actualObj, err := SomeFunction() --// assert.EqualErrorf(t, err, expectedErrorString, "error message %s", "formatted") -+// require.EqualErrorf(t, err, expectedErrorString, "error message %s", "formatted") - func EqualErrorf(t TestingT, theError error, errString string, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -200,8 +200,8 @@ func EqualErrorf(t TestingT, theError error, errString string, msg string, args - // Exported int - // notExported int - // } --// assert.EqualExportedValues(t, S{1, 2}, S{1, 3}) => true --// assert.EqualExportedValues(t, S{1, 2}, S{2, 3}) => false -+// require.EqualExportedValues(t, S{1, 2}, S{1, 3}) => true -+// require.EqualExportedValues(t, S{1, 2}, S{2, 3}) => false - func EqualExportedValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -220,8 +220,8 @@ func EqualExportedValues(t TestingT, expected interface{}, actual interface{}, m - // Exported int - // notExported int - // } --// assert.EqualExportedValuesf(t, S{1, 2}, S{1, 3}, "error message %s", "formatted") => true --// assert.EqualExportedValuesf(t, S{1, 2}, S{2, 3}, "error message %s", "formatted") => false -+// require.EqualExportedValuesf(t, S{1, 2}, S{1, 3}, "error message %s", "formatted") => true -+// require.EqualExportedValuesf(t, S{1, 2}, S{2, 3}, "error message %s", "formatted") => false - func EqualExportedValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -232,10 +232,10 @@ func EqualExportedValuesf(t TestingT, expected interface{}, actual interface{}, - t.FailNow() - } - --// EqualValues asserts that two objects are equal or convertible to the same types --// and equal. -+// EqualValues asserts that two objects are equal or convertible to the larger -+// type and equal. - // --// assert.EqualValues(t, uint32(123), int32(123)) -+// require.EqualValues(t, uint32(123), int32(123)) - func EqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -246,10 +246,10 @@ func EqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArg - t.FailNow() - } - --// EqualValuesf asserts that two objects are equal or convertible to the same types --// and equal. -+// EqualValuesf asserts that two objects are equal or convertible to the larger -+// type and equal. - // --// assert.EqualValuesf(t, uint32(123), int32(123), "error message %s", "formatted") -+// require.EqualValuesf(t, uint32(123), int32(123), "error message %s", "formatted") - func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -262,7 +262,7 @@ func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg stri - - // Equalf asserts that two objects are equal. - // --// assert.Equalf(t, 123, 123, "error message %s", "formatted") -+// require.Equalf(t, 123, 123, "error message %s", "formatted") - // - // Pointer variable equality is determined based on the equality of the - // referenced values (as opposed to the memory addresses). Function equality -@@ -280,8 +280,8 @@ func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, ar - // Error asserts that a function returned an error (i.e. not `nil`). - // - // actualObj, err := SomeFunction() --// if assert.Error(t, err) { --// assert.Equal(t, expectedError, err) -+// if require.Error(t, err) { -+// require.Equal(t, expectedError, err) - // } - func Error(t TestingT, err error, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { -@@ -321,7 +321,7 @@ func ErrorAsf(t TestingT, err error, target interface{}, msg string, args ...int - // and that the error contains the specified substring. - // - // actualObj, err := SomeFunction() --// assert.ErrorContains(t, err, expectedErrorSubString) -+// require.ErrorContains(t, err, expectedErrorSubString) - func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -336,7 +336,7 @@ func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...in - // and that the error contains the specified substring. - // - // actualObj, err := SomeFunction() --// assert.ErrorContainsf(t, err, expectedErrorSubString, "error message %s", "formatted") -+// require.ErrorContainsf(t, err, expectedErrorSubString, "error message %s", "formatted") - func ErrorContainsf(t TestingT, theError error, contains string, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -374,8 +374,8 @@ func ErrorIsf(t TestingT, err error, target error, msg string, args ...interface - // Errorf asserts that a function returned an error (i.e. not `nil`). - // - // actualObj, err := SomeFunction() --// if assert.Errorf(t, err, "error message %s", "formatted") { --// assert.Equal(t, expectedErrorf, err) -+// if require.Errorf(t, err, "error message %s", "formatted") { -+// require.Equal(t, expectedErrorf, err) - // } - func Errorf(t TestingT, err error, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { -@@ -390,7 +390,7 @@ func Errorf(t TestingT, err error, msg string, args ...interface{}) { - // Eventually asserts that given condition will be met in waitFor time, - // periodically checking target function each tick. - // --// assert.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond) -+// require.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond) - func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -415,10 +415,10 @@ func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick t - // time.Sleep(8*time.Second) - // externalValue = true - // }() --// assert.EventuallyWithT(t, func(c *assert.CollectT) { -+// require.EventuallyWithT(t, func(c *require.CollectT) { - // // add assertions as needed; any assertion failure will fail the current tick --// assert.True(c, externalValue, "expected 'externalValue' to be true") --// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") -+// require.True(c, externalValue, "expected 'externalValue' to be true") -+// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") - func EventuallyWithT(t TestingT, condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -443,10 +443,10 @@ func EventuallyWithT(t TestingT, condition func(collect *assert.CollectT), waitF - // time.Sleep(8*time.Second) - // externalValue = true - // }() --// assert.EventuallyWithTf(t, func(c *assert.CollectT, "error message %s", "formatted") { -+// require.EventuallyWithTf(t, func(c *require.CollectT, "error message %s", "formatted") { - // // add assertions as needed; any assertion failure will fail the current tick --// assert.True(c, externalValue, "expected 'externalValue' to be true") --// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") -+// require.True(c, externalValue, "expected 'externalValue' to be true") -+// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") - func EventuallyWithTf(t TestingT, condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -460,7 +460,7 @@ func EventuallyWithTf(t TestingT, condition func(collect *assert.CollectT), wait - // Eventuallyf asserts that given condition will be met in waitFor time, - // periodically checking target function each tick. - // --// assert.Eventuallyf(t, func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") -+// require.Eventuallyf(t, func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") - func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -473,7 +473,7 @@ func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick - - // Exactly asserts that two objects are equal in value and type. - // --// assert.Exactly(t, int32(123), int64(123)) -+// require.Exactly(t, int32(123), int64(123)) - func Exactly(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -486,7 +486,7 @@ func Exactly(t TestingT, expected interface{}, actual interface{}, msgAndArgs .. - - // Exactlyf asserts that two objects are equal in value and type. - // --// assert.Exactlyf(t, int32(123), int64(123), "error message %s", "formatted") -+// require.Exactlyf(t, int32(123), int64(123), "error message %s", "formatted") - func Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -543,7 +543,7 @@ func Failf(t TestingT, failureMessage string, msg string, args ...interface{}) { - - // False asserts that the specified value is false. - // --// assert.False(t, myBool) -+// require.False(t, myBool) - func False(t TestingT, value bool, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -556,7 +556,7 @@ func False(t TestingT, value bool, msgAndArgs ...interface{}) { - - // Falsef asserts that the specified value is false. - // --// assert.Falsef(t, myBool, "error message %s", "formatted") -+// require.Falsef(t, myBool, "error message %s", "formatted") - func Falsef(t TestingT, value bool, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -593,9 +593,9 @@ func FileExistsf(t TestingT, path string, msg string, args ...interface{}) { - - // Greater asserts that the first element is greater than the second - // --// assert.Greater(t, 2, 1) --// assert.Greater(t, float64(2), float64(1)) --// assert.Greater(t, "b", "a") -+// require.Greater(t, 2, 1) -+// require.Greater(t, float64(2), float64(1)) -+// require.Greater(t, "b", "a") - func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -608,10 +608,10 @@ func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface - - // GreaterOrEqual asserts that the first element is greater than or equal to the second - // --// assert.GreaterOrEqual(t, 2, 1) --// assert.GreaterOrEqual(t, 2, 2) --// assert.GreaterOrEqual(t, "b", "a") --// assert.GreaterOrEqual(t, "b", "b") -+// require.GreaterOrEqual(t, 2, 1) -+// require.GreaterOrEqual(t, 2, 2) -+// require.GreaterOrEqual(t, "b", "a") -+// require.GreaterOrEqual(t, "b", "b") - func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -624,10 +624,10 @@ func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...in - - // GreaterOrEqualf asserts that the first element is greater than or equal to the second - // --// assert.GreaterOrEqualf(t, 2, 1, "error message %s", "formatted") --// assert.GreaterOrEqualf(t, 2, 2, "error message %s", "formatted") --// assert.GreaterOrEqualf(t, "b", "a", "error message %s", "formatted") --// assert.GreaterOrEqualf(t, "b", "b", "error message %s", "formatted") -+// require.GreaterOrEqualf(t, 2, 1, "error message %s", "formatted") -+// require.GreaterOrEqualf(t, 2, 2, "error message %s", "formatted") -+// require.GreaterOrEqualf(t, "b", "a", "error message %s", "formatted") -+// require.GreaterOrEqualf(t, "b", "b", "error message %s", "formatted") - func GreaterOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -640,9 +640,9 @@ func GreaterOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, arg - - // Greaterf asserts that the first element is greater than the second - // --// assert.Greaterf(t, 2, 1, "error message %s", "formatted") --// assert.Greaterf(t, float64(2), float64(1), "error message %s", "formatted") --// assert.Greaterf(t, "b", "a", "error message %s", "formatted") -+// require.Greaterf(t, 2, 1, "error message %s", "formatted") -+// require.Greaterf(t, float64(2), float64(1), "error message %s", "formatted") -+// require.Greaterf(t, "b", "a", "error message %s", "formatted") - func Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -656,7 +656,7 @@ func Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...in - // HTTPBodyContains asserts that a specified handler returns a - // body that contains a string. - // --// assert.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") -+// require.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") - // - // Returns whether the assertion was successful (true) or not (false). - func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) { -@@ -672,7 +672,7 @@ func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url s - // HTTPBodyContainsf asserts that a specified handler returns a - // body that contains a string. - // --// assert.HTTPBodyContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") -+// require.HTTPBodyContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") - // - // Returns whether the assertion was successful (true) or not (false). - func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) { -@@ -688,7 +688,7 @@ func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url - // HTTPBodyNotContains asserts that a specified handler returns a - // body that does not contain a string. - // --// assert.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") -+// require.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") - // - // Returns whether the assertion was successful (true) or not (false). - func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) { -@@ -704,7 +704,7 @@ func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, ur - // HTTPBodyNotContainsf asserts that a specified handler returns a - // body that does not contain a string. - // --// assert.HTTPBodyNotContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") -+// require.HTTPBodyNotContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") - // - // Returns whether the assertion was successful (true) or not (false). - func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) { -@@ -719,7 +719,7 @@ func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, u - - // HTTPError asserts that a specified handler returns an error status code. - // --// assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} -+// require.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} - // - // Returns whether the assertion was successful (true) or not (false). - func HTTPError(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { -@@ -734,7 +734,7 @@ func HTTPError(t TestingT, handler http.HandlerFunc, method string, url string, - - // HTTPErrorf asserts that a specified handler returns an error status code. - // --// assert.HTTPErrorf(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} -+// require.HTTPErrorf(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} - // - // Returns whether the assertion was successful (true) or not (false). - func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { -@@ -749,7 +749,7 @@ func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, - - // HTTPRedirect asserts that a specified handler returns a redirect status code. - // --// assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} -+// require.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} - // - // Returns whether the assertion was successful (true) or not (false). - func HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { -@@ -764,7 +764,7 @@ func HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url strin - - // HTTPRedirectf asserts that a specified handler returns a redirect status code. - // --// assert.HTTPRedirectf(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} -+// require.HTTPRedirectf(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} - // - // Returns whether the assertion was successful (true) or not (false). - func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { -@@ -779,7 +779,7 @@ func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url stri - - // HTTPStatusCode asserts that a specified handler returns a specified status code. - // --// assert.HTTPStatusCode(t, myHandler, "GET", "/notImplemented", nil, 501) -+// require.HTTPStatusCode(t, myHandler, "GET", "/notImplemented", nil, 501) - // - // Returns whether the assertion was successful (true) or not (false). - func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) { -@@ -794,7 +794,7 @@ func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method string, url str - - // HTTPStatusCodef asserts that a specified handler returns a specified status code. - // --// assert.HTTPStatusCodef(t, myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") -+// require.HTTPStatusCodef(t, myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") - // - // Returns whether the assertion was successful (true) or not (false). - func HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) { -@@ -809,7 +809,7 @@ func HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url st - - // HTTPSuccess asserts that a specified handler returns a success status code. - // --// assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) -+// require.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) - // - // Returns whether the assertion was successful (true) or not (false). - func HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { -@@ -824,7 +824,7 @@ func HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string - - // HTTPSuccessf asserts that a specified handler returns a success status code. - // --// assert.HTTPSuccessf(t, myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") -+// require.HTTPSuccessf(t, myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") - // - // Returns whether the assertion was successful (true) or not (false). - func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { -@@ -839,7 +839,7 @@ func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url strin - - // Implements asserts that an object is implemented by the specified interface. - // --// assert.Implements(t, (*MyInterface)(nil), new(MyObject)) -+// require.Implements(t, (*MyInterface)(nil), new(MyObject)) - func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -852,7 +852,7 @@ func Implements(t TestingT, interfaceObject interface{}, object interface{}, msg - - // Implementsf asserts that an object is implemented by the specified interface. - // --// assert.Implementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") -+// require.Implementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") - func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -865,7 +865,7 @@ func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, ms - - // InDelta asserts that the two numerals are within delta of each other. - // --// assert.InDelta(t, math.Pi, 22/7.0, 0.01) -+// require.InDelta(t, math.Pi, 22/7.0, 0.01) - func InDelta(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -922,7 +922,7 @@ func InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta f - - // InDeltaf asserts that the two numerals are within delta of each other. - // --// assert.InDeltaf(t, math.Pi, 22/7.0, 0.01, "error message %s", "formatted") -+// require.InDeltaf(t, math.Pi, 22/7.0, 0.01, "error message %s", "formatted") - func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -979,9 +979,9 @@ func InEpsilonf(t TestingT, expected interface{}, actual interface{}, epsilon fl - - // IsDecreasing asserts that the collection is decreasing - // --// assert.IsDecreasing(t, []int{2, 1, 0}) --// assert.IsDecreasing(t, []float{2, 1}) --// assert.IsDecreasing(t, []string{"b", "a"}) -+// require.IsDecreasing(t, []int{2, 1, 0}) -+// require.IsDecreasing(t, []float{2, 1}) -+// require.IsDecreasing(t, []string{"b", "a"}) - func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -994,9 +994,9 @@ func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { - - // IsDecreasingf asserts that the collection is decreasing - // --// assert.IsDecreasingf(t, []int{2, 1, 0}, "error message %s", "formatted") --// assert.IsDecreasingf(t, []float{2, 1}, "error message %s", "formatted") --// assert.IsDecreasingf(t, []string{"b", "a"}, "error message %s", "formatted") -+// require.IsDecreasingf(t, []int{2, 1, 0}, "error message %s", "formatted") -+// require.IsDecreasingf(t, []float{2, 1}, "error message %s", "formatted") -+// require.IsDecreasingf(t, []string{"b", "a"}, "error message %s", "formatted") - func IsDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1009,9 +1009,9 @@ func IsDecreasingf(t TestingT, object interface{}, msg string, args ...interface - - // IsIncreasing asserts that the collection is increasing - // --// assert.IsIncreasing(t, []int{1, 2, 3}) --// assert.IsIncreasing(t, []float{1, 2}) --// assert.IsIncreasing(t, []string{"a", "b"}) -+// require.IsIncreasing(t, []int{1, 2, 3}) -+// require.IsIncreasing(t, []float{1, 2}) -+// require.IsIncreasing(t, []string{"a", "b"}) - func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1024,9 +1024,9 @@ func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { - - // IsIncreasingf asserts that the collection is increasing - // --// assert.IsIncreasingf(t, []int{1, 2, 3}, "error message %s", "formatted") --// assert.IsIncreasingf(t, []float{1, 2}, "error message %s", "formatted") --// assert.IsIncreasingf(t, []string{"a", "b"}, "error message %s", "formatted") -+// require.IsIncreasingf(t, []int{1, 2, 3}, "error message %s", "formatted") -+// require.IsIncreasingf(t, []float{1, 2}, "error message %s", "formatted") -+// require.IsIncreasingf(t, []string{"a", "b"}, "error message %s", "formatted") - func IsIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1039,9 +1039,9 @@ func IsIncreasingf(t TestingT, object interface{}, msg string, args ...interface - - // IsNonDecreasing asserts that the collection is not decreasing - // --// assert.IsNonDecreasing(t, []int{1, 1, 2}) --// assert.IsNonDecreasing(t, []float{1, 2}) --// assert.IsNonDecreasing(t, []string{"a", "b"}) -+// require.IsNonDecreasing(t, []int{1, 1, 2}) -+// require.IsNonDecreasing(t, []float{1, 2}) -+// require.IsNonDecreasing(t, []string{"a", "b"}) - func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1054,9 +1054,9 @@ func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) - - // IsNonDecreasingf asserts that the collection is not decreasing - // --// assert.IsNonDecreasingf(t, []int{1, 1, 2}, "error message %s", "formatted") --// assert.IsNonDecreasingf(t, []float{1, 2}, "error message %s", "formatted") --// assert.IsNonDecreasingf(t, []string{"a", "b"}, "error message %s", "formatted") -+// require.IsNonDecreasingf(t, []int{1, 1, 2}, "error message %s", "formatted") -+// require.IsNonDecreasingf(t, []float{1, 2}, "error message %s", "formatted") -+// require.IsNonDecreasingf(t, []string{"a", "b"}, "error message %s", "formatted") - func IsNonDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1069,9 +1069,9 @@ func IsNonDecreasingf(t TestingT, object interface{}, msg string, args ...interf - - // IsNonIncreasing asserts that the collection is not increasing - // --// assert.IsNonIncreasing(t, []int{2, 1, 1}) --// assert.IsNonIncreasing(t, []float{2, 1}) --// assert.IsNonIncreasing(t, []string{"b", "a"}) -+// require.IsNonIncreasing(t, []int{2, 1, 1}) -+// require.IsNonIncreasing(t, []float{2, 1}) -+// require.IsNonIncreasing(t, []string{"b", "a"}) - func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1084,9 +1084,9 @@ func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) - - // IsNonIncreasingf asserts that the collection is not increasing - // --// assert.IsNonIncreasingf(t, []int{2, 1, 1}, "error message %s", "formatted") --// assert.IsNonIncreasingf(t, []float{2, 1}, "error message %s", "formatted") --// assert.IsNonIncreasingf(t, []string{"b", "a"}, "error message %s", "formatted") -+// require.IsNonIncreasingf(t, []int{2, 1, 1}, "error message %s", "formatted") -+// require.IsNonIncreasingf(t, []float{2, 1}, "error message %s", "formatted") -+// require.IsNonIncreasingf(t, []string{"b", "a"}, "error message %s", "formatted") - func IsNonIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1121,7 +1121,7 @@ func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg strin - - // JSONEq asserts that two JSON strings are equivalent. - // --// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) -+// require.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) - func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1134,7 +1134,7 @@ func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{ - - // JSONEqf asserts that two JSON strings are equivalent. - // --// assert.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") -+// require.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") - func JSONEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1148,7 +1148,7 @@ func JSONEqf(t TestingT, expected string, actual string, msg string, args ...int - // Len asserts that the specified object has specific length. - // Len also fails if the object has a type that len() not accept. - // --// assert.Len(t, mySlice, 3) -+// require.Len(t, mySlice, 3) - func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1162,7 +1162,7 @@ func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) - // Lenf asserts that the specified object has specific length. - // Lenf also fails if the object has a type that len() not accept. - // --// assert.Lenf(t, mySlice, 3, "error message %s", "formatted") -+// require.Lenf(t, mySlice, 3, "error message %s", "formatted") - func Lenf(t TestingT, object interface{}, length int, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1175,9 +1175,9 @@ func Lenf(t TestingT, object interface{}, length int, msg string, args ...interf - - // Less asserts that the first element is less than the second - // --// assert.Less(t, 1, 2) --// assert.Less(t, float64(1), float64(2)) --// assert.Less(t, "a", "b") -+// require.Less(t, 1, 2) -+// require.Less(t, float64(1), float64(2)) -+// require.Less(t, "a", "b") - func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1190,10 +1190,10 @@ func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) - - // LessOrEqual asserts that the first element is less than or equal to the second - // --// assert.LessOrEqual(t, 1, 2) --// assert.LessOrEqual(t, 2, 2) --// assert.LessOrEqual(t, "a", "b") --// assert.LessOrEqual(t, "b", "b") -+// require.LessOrEqual(t, 1, 2) -+// require.LessOrEqual(t, 2, 2) -+// require.LessOrEqual(t, "a", "b") -+// require.LessOrEqual(t, "b", "b") - func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1206,10 +1206,10 @@ func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...inter - - // LessOrEqualf asserts that the first element is less than or equal to the second - // --// assert.LessOrEqualf(t, 1, 2, "error message %s", "formatted") --// assert.LessOrEqualf(t, 2, 2, "error message %s", "formatted") --// assert.LessOrEqualf(t, "a", "b", "error message %s", "formatted") --// assert.LessOrEqualf(t, "b", "b", "error message %s", "formatted") -+// require.LessOrEqualf(t, 1, 2, "error message %s", "formatted") -+// require.LessOrEqualf(t, 2, 2, "error message %s", "formatted") -+// require.LessOrEqualf(t, "a", "b", "error message %s", "formatted") -+// require.LessOrEqualf(t, "b", "b", "error message %s", "formatted") - func LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1222,9 +1222,9 @@ func LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args . - - // Lessf asserts that the first element is less than the second - // --// assert.Lessf(t, 1, 2, "error message %s", "formatted") --// assert.Lessf(t, float64(1), float64(2), "error message %s", "formatted") --// assert.Lessf(t, "a", "b", "error message %s", "formatted") -+// require.Lessf(t, 1, 2, "error message %s", "formatted") -+// require.Lessf(t, float64(1), float64(2), "error message %s", "formatted") -+// require.Lessf(t, "a", "b", "error message %s", "formatted") - func Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1237,8 +1237,8 @@ func Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...inter - - // Negative asserts that the specified element is negative - // --// assert.Negative(t, -1) --// assert.Negative(t, -1.23) -+// require.Negative(t, -1) -+// require.Negative(t, -1.23) - func Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1251,8 +1251,8 @@ func Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) { - - // Negativef asserts that the specified element is negative - // --// assert.Negativef(t, -1, "error message %s", "formatted") --// assert.Negativef(t, -1.23, "error message %s", "formatted") -+// require.Negativef(t, -1, "error message %s", "formatted") -+// require.Negativef(t, -1.23, "error message %s", "formatted") - func Negativef(t TestingT, e interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1266,7 +1266,7 @@ func Negativef(t TestingT, e interface{}, msg string, args ...interface{}) { - // Never asserts that the given condition doesn't satisfy in waitFor time, - // periodically checking the target function each tick. - // --// assert.Never(t, func() bool { return false; }, time.Second, 10*time.Millisecond) -+// require.Never(t, func() bool { return false; }, time.Second, 10*time.Millisecond) - func Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1280,7 +1280,7 @@ func Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.D - // Neverf asserts that the given condition doesn't satisfy in waitFor time, - // periodically checking the target function each tick. - // --// assert.Neverf(t, func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") -+// require.Neverf(t, func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") - func Neverf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1293,7 +1293,7 @@ func Neverf(t TestingT, condition func() bool, waitFor time.Duration, tick time. - - // Nil asserts that the specified object is nil. - // --// assert.Nil(t, err) -+// require.Nil(t, err) - func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1306,7 +1306,7 @@ func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) { - - // Nilf asserts that the specified object is nil. - // --// assert.Nilf(t, err, "error message %s", "formatted") -+// require.Nilf(t, err, "error message %s", "formatted") - func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1344,8 +1344,8 @@ func NoDirExistsf(t TestingT, path string, msg string, args ...interface{}) { - // NoError asserts that a function returned no error (i.e. `nil`). - // - // actualObj, err := SomeFunction() --// if assert.NoError(t, err) { --// assert.Equal(t, expectedObj, actualObj) -+// if require.NoError(t, err) { -+// require.Equal(t, expectedObj, actualObj) - // } - func NoError(t TestingT, err error, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { -@@ -1360,8 +1360,8 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) { - // NoErrorf asserts that a function returned no error (i.e. `nil`). - // - // actualObj, err := SomeFunction() --// if assert.NoErrorf(t, err, "error message %s", "formatted") { --// assert.Equal(t, expectedObj, actualObj) -+// if require.NoErrorf(t, err, "error message %s", "formatted") { -+// require.Equal(t, expectedObj, actualObj) - // } - func NoErrorf(t TestingT, err error, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { -@@ -1400,9 +1400,9 @@ func NoFileExistsf(t TestingT, path string, msg string, args ...interface{}) { - // NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the - // specified substring or element. - // --// assert.NotContains(t, "Hello World", "Earth") --// assert.NotContains(t, ["Hello", "World"], "Earth") --// assert.NotContains(t, {"Hello": "World"}, "Earth") -+// require.NotContains(t, "Hello World", "Earth") -+// require.NotContains(t, ["Hello", "World"], "Earth") -+// require.NotContains(t, {"Hello": "World"}, "Earth") - func NotContains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1416,9 +1416,9 @@ func NotContains(t TestingT, s interface{}, contains interface{}, msgAndArgs ... - // NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the - // specified substring or element. - // --// assert.NotContainsf(t, "Hello World", "Earth", "error message %s", "formatted") --// assert.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted") --// assert.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted") -+// require.NotContainsf(t, "Hello World", "Earth", "error message %s", "formatted") -+// require.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted") -+// require.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted") - func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1429,11 +1429,51 @@ func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, a - t.FailNow() - } - -+// NotElementsMatch asserts that the specified listA(array, slice...) is NOT equal to specified -+// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, -+// the number of appearances of each of them in both lists should not match. -+// This is an inverse of ElementsMatch. -+// -+// require.NotElementsMatch(t, [1, 1, 2, 3], [1, 1, 2, 3]) -> false -+// -+// require.NotElementsMatch(t, [1, 1, 2, 3], [1, 2, 3]) -> true -+// -+// require.NotElementsMatch(t, [1, 2, 3], [1, 2, 4]) -> true -+func NotElementsMatch(t TestingT, listA interface{}, listB interface{}, msgAndArgs ...interface{}) { -+ if h, ok := t.(tHelper); ok { -+ h.Helper() -+ } -+ if assert.NotElementsMatch(t, listA, listB, msgAndArgs...) { -+ return ++// IsRequestGzip reports whether we should add an Accept-Encoding: gzip header ++// for a request. ++func IsRequestGzip(method string, header map[string][]string, disableCompression bool) bool { ++ // TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere? ++ if !disableCompression && ++ len(header["Accept-Encoding"]) == 0 && ++ len(header["Range"]) == 0 && ++ method != "HEAD" { ++ // Request gzip only, not deflate. Deflate is ambiguous and ++ // not as universally supported anyway. ++ // See: https://zlib.net/zlib_faq.html#faq39 ++ // ++ // Note that we don't request this for HEAD requests, ++ // due to a bug in nginx: ++ // http://trac.nginx.org/nginx/ticket/358 ++ // https://golang.org/issue/5522 ++ // ++ // We don't request gzip if the request is for a range, since ++ // auto-decoding a portion of a gzipped document will just fail ++ // anyway. See https://golang.org/issue/8923 ++ return true + } -+ t.FailNow() ++ return false +} + -+// NotElementsMatchf asserts that the specified listA(array, slice...) is NOT equal to specified -+// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, -+// the number of appearances of each of them in both lists should not match. -+// This is an inverse of ElementsMatch. ++// checkConnHeaders checks whether req has any invalid connection-level headers. +// -+// require.NotElementsMatchf(t, [1, 1, 2, 3], [1, 1, 2, 3], "error message %s", "formatted") -> false ++// https://www.rfc-editor.org/rfc/rfc9114.html#section-4.2-3 ++// https://www.rfc-editor.org/rfc/rfc9113.html#section-8.2.2-1 +// -+// require.NotElementsMatchf(t, [1, 1, 2, 3], [1, 2, 3], "error message %s", "formatted") -> true -+// -+// require.NotElementsMatchf(t, [1, 2, 3], [1, 2, 4], "error message %s", "formatted") -> true -+func NotElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) { -+ if h, ok := t.(tHelper); ok { -+ h.Helper() -+ } -+ if assert.NotElementsMatchf(t, listA, listB, msg, args...) { -+ return ++// Certain headers are special-cased as okay but not transmitted later. ++// For example, we allow "Transfer-Encoding: chunked", but drop the header when encoding. ++func checkConnHeaders(h map[string][]string) error { ++ if vv := h["Upgrade"]; len(vv) > 0 && (vv[0] != "" && vv[0] != "chunked") { ++ return fmt.Errorf("invalid Upgrade request header: %q", vv) + } -+ t.FailNow() -+} -+ - // NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either - // a slice or a channel with len == 0. - // --// if assert.NotEmpty(t, obj) { --// assert.Equal(t, "two", obj[1]) -+// if require.NotEmpty(t, obj) { -+// require.Equal(t, "two", obj[1]) - // } - func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { -@@ -1448,8 +1488,8 @@ func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) { - // NotEmptyf asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either - // a slice or a channel with len == 0. - // --// if assert.NotEmptyf(t, obj, "error message %s", "formatted") { --// assert.Equal(t, "two", obj[1]) -+// if require.NotEmptyf(t, obj, "error message %s", "formatted") { -+// require.Equal(t, "two", obj[1]) - // } - func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { -@@ -1463,7 +1503,7 @@ func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) - - // NotEqual asserts that the specified values are NOT equal. - // --// assert.NotEqual(t, obj1, obj2) -+// require.NotEqual(t, obj1, obj2) - // - // Pointer variable equality is determined based on the equality of the - // referenced values (as opposed to the memory addresses). -@@ -1479,7 +1519,7 @@ func NotEqual(t TestingT, expected interface{}, actual interface{}, msgAndArgs . - - // NotEqualValues asserts that two objects are not equal even when converted to the same type - // --// assert.NotEqualValues(t, obj1, obj2) -+// require.NotEqualValues(t, obj1, obj2) - func NotEqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1492,7 +1532,7 @@ func NotEqualValues(t TestingT, expected interface{}, actual interface{}, msgAnd - - // NotEqualValuesf asserts that two objects are not equal even when converted to the same type - // --// assert.NotEqualValuesf(t, obj1, obj2, "error message %s", "formatted") -+// require.NotEqualValuesf(t, obj1, obj2, "error message %s", "formatted") - func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1505,7 +1545,7 @@ func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg s - - // NotEqualf asserts that the specified values are NOT equal. - // --// assert.NotEqualf(t, obj1, obj2, "error message %s", "formatted") -+// require.NotEqualf(t, obj1, obj2, "error message %s", "formatted") - // - // Pointer variable equality is determined based on the equality of the - // referenced values (as opposed to the memory addresses). -@@ -1519,7 +1559,31 @@ func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, - t.FailNow() - } - --// NotErrorIs asserts that at none of the errors in err's chain matches target. -+// NotErrorAs asserts that none of the errors in err's chain matches target, -+// but if so, sets target to that error value. -+func NotErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{}) { -+ if h, ok := t.(tHelper); ok { -+ h.Helper() ++ if vv := h["Transfer-Encoding"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && vv[0] != "chunked") { ++ return fmt.Errorf("invalid Transfer-Encoding request header: %q", vv) + } -+ if assert.NotErrorAs(t, err, target, msgAndArgs...) { -+ return ++ if vv := h["Connection"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && !asciiEqualFold(vv[0], "close") && !asciiEqualFold(vv[0], "keep-alive")) { ++ return fmt.Errorf("invalid Connection request header: %q", vv) + } -+ t.FailNow() -+} -+ -+// NotErrorAsf asserts that none of the errors in err's chain matches target, -+// but if so, sets target to that error value. -+func NotErrorAsf(t TestingT, err error, target interface{}, msg string, args ...interface{}) { -+ if h, ok := t.(tHelper); ok { -+ h.Helper() -+ } -+ if assert.NotErrorAsf(t, err, target, msg, args...) { -+ return -+ } -+ t.FailNow() ++ return nil +} + -+// NotErrorIs asserts that none of the errors in err's chain matches target. - // This is a wrapper for errors.Is. - func NotErrorIs(t TestingT, err error, target error, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { -@@ -1531,7 +1595,7 @@ func NotErrorIs(t TestingT, err error, target error, msgAndArgs ...interface{}) - t.FailNow() - } - --// NotErrorIsf asserts that at none of the errors in err's chain matches target. -+// NotErrorIsf asserts that none of the errors in err's chain matches target. - // This is a wrapper for errors.Is. - func NotErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { -@@ -1545,7 +1609,7 @@ func NotErrorIsf(t TestingT, err error, target error, msg string, args ...interf - - // NotImplements asserts that an object does not implement the specified interface. - // --// assert.NotImplements(t, (*MyInterface)(nil), new(MyObject)) -+// require.NotImplements(t, (*MyInterface)(nil), new(MyObject)) - func NotImplements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1558,7 +1622,7 @@ func NotImplements(t TestingT, interfaceObject interface{}, object interface{}, - - // NotImplementsf asserts that an object does not implement the specified interface. - // --// assert.NotImplementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") -+// require.NotImplementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") - func NotImplementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1571,7 +1635,7 @@ func NotImplementsf(t TestingT, interfaceObject interface{}, object interface{}, - - // NotNil asserts that the specified object is not nil. - // --// assert.NotNil(t, err) -+// require.NotNil(t, err) - func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1584,7 +1648,7 @@ func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) { - - // NotNilf asserts that the specified object is not nil. - // --// assert.NotNilf(t, err, "error message %s", "formatted") -+// require.NotNilf(t, err, "error message %s", "formatted") - func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1597,7 +1661,7 @@ func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) { - - // NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. - // --// assert.NotPanics(t, func(){ RemainCalm() }) -+// require.NotPanics(t, func(){ RemainCalm() }) - func NotPanics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1610,7 +1674,7 @@ func NotPanics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { - - // NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic. - // --// assert.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted") -+// require.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted") - func NotPanicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1623,8 +1687,8 @@ func NotPanicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interfac - - // NotRegexp asserts that a specified regexp does not match a string. - // --// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") --// assert.NotRegexp(t, "^start", "it's not starting") -+// require.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") -+// require.NotRegexp(t, "^start", "it's not starting") - func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1637,8 +1701,8 @@ func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interf - - // NotRegexpf asserts that a specified regexp does not match a string. - // --// assert.NotRegexpf(t, regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted") --// assert.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted") -+// require.NotRegexpf(t, regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted") -+// require.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted") - func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1651,7 +1715,7 @@ func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args .. - - // NotSame asserts that two pointers do not reference the same object. - // --// assert.NotSame(t, ptr1, ptr2) -+// require.NotSame(t, ptr1, ptr2) - // - // Both arguments must be pointer variables. Pointer variable sameness is - // determined based on the equality of both type and value. -@@ -1667,7 +1731,7 @@ func NotSame(t TestingT, expected interface{}, actual interface{}, msgAndArgs .. - - // NotSamef asserts that two pointers do not reference the same object. - // --// assert.NotSamef(t, ptr1, ptr2, "error message %s", "formatted") -+// require.NotSamef(t, ptr1, ptr2, "error message %s", "formatted") - // - // Both arguments must be pointer variables. Pointer variable sameness is - // determined based on the equality of both type and value. -@@ -1685,8 +1749,8 @@ func NotSamef(t TestingT, expected interface{}, actual interface{}, msg string, - // contain all elements given in the specified subset list(array, slice...) or - // map. - // --// assert.NotSubset(t, [1, 3, 4], [1, 2]) --// assert.NotSubset(t, {"x": 1, "y": 2}, {"z": 3}) -+// require.NotSubset(t, [1, 3, 4], [1, 2]) -+// require.NotSubset(t, {"x": 1, "y": 2}, {"z": 3}) - func NotSubset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1701,8 +1765,8 @@ func NotSubset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...i - // contain all elements given in the specified subset list(array, slice...) or - // map. - // --// assert.NotSubsetf(t, [1, 3, 4], [1, 2], "error message %s", "formatted") --// assert.NotSubsetf(t, {"x": 1, "y": 2}, {"z": 3}, "error message %s", "formatted") -+// require.NotSubsetf(t, [1, 3, 4], [1, 2], "error message %s", "formatted") -+// require.NotSubsetf(t, {"x": 1, "y": 2}, {"z": 3}, "error message %s", "formatted") - func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1737,7 +1801,7 @@ func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) { - - // Panics asserts that the code inside the specified PanicTestFunc panics. - // --// assert.Panics(t, func(){ GoCrazy() }) -+// require.Panics(t, func(){ GoCrazy() }) - func Panics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1752,7 +1816,7 @@ func Panics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { - // panics, and that the recovered panic value is an error that satisfies the - // EqualError comparison. - // --// assert.PanicsWithError(t, "crazy error", func(){ GoCrazy() }) -+// require.PanicsWithError(t, "crazy error", func(){ GoCrazy() }) - func PanicsWithError(t TestingT, errString string, f assert.PanicTestFunc, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1767,7 +1831,7 @@ func PanicsWithError(t TestingT, errString string, f assert.PanicTestFunc, msgAn - // panics, and that the recovered panic value is an error that satisfies the - // EqualError comparison. - // --// assert.PanicsWithErrorf(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") -+// require.PanicsWithErrorf(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") - func PanicsWithErrorf(t TestingT, errString string, f assert.PanicTestFunc, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1781,7 +1845,7 @@ func PanicsWithErrorf(t TestingT, errString string, f assert.PanicTestFunc, msg - // PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that - // the recovered panic value equals the expected panic value. - // --// assert.PanicsWithValue(t, "crazy error", func(){ GoCrazy() }) -+// require.PanicsWithValue(t, "crazy error", func(){ GoCrazy() }) - func PanicsWithValue(t TestingT, expected interface{}, f assert.PanicTestFunc, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1795,7 +1859,7 @@ func PanicsWithValue(t TestingT, expected interface{}, f assert.PanicTestFunc, m - // PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that - // the recovered panic value equals the expected panic value. - // --// assert.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") -+// require.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") - func PanicsWithValuef(t TestingT, expected interface{}, f assert.PanicTestFunc, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1808,7 +1872,7 @@ func PanicsWithValuef(t TestingT, expected interface{}, f assert.PanicTestFunc, - - // Panicsf asserts that the code inside the specified PanicTestFunc panics. - // --// assert.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted") -+// require.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted") - func Panicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1821,8 +1885,8 @@ func Panicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{} - - // Positive asserts that the specified element is positive - // --// assert.Positive(t, 1) --// assert.Positive(t, 1.23) -+// require.Positive(t, 1) -+// require.Positive(t, 1.23) - func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1835,8 +1899,8 @@ func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) { - - // Positivef asserts that the specified element is positive - // --// assert.Positivef(t, 1, "error message %s", "formatted") --// assert.Positivef(t, 1.23, "error message %s", "formatted") -+// require.Positivef(t, 1, "error message %s", "formatted") -+// require.Positivef(t, 1.23, "error message %s", "formatted") - func Positivef(t TestingT, e interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1849,8 +1913,8 @@ func Positivef(t TestingT, e interface{}, msg string, args ...interface{}) { - - // Regexp asserts that a specified regexp matches a string. - // --// assert.Regexp(t, regexp.MustCompile("start"), "it's starting") --// assert.Regexp(t, "start...$", "it's not starting") -+// require.Regexp(t, regexp.MustCompile("start"), "it's starting") -+// require.Regexp(t, "start...$", "it's not starting") - func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1863,8 +1927,8 @@ func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface - - // Regexpf asserts that a specified regexp matches a string. - // --// assert.Regexpf(t, regexp.MustCompile("start"), "it's starting", "error message %s", "formatted") --// assert.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted") -+// require.Regexpf(t, regexp.MustCompile("start"), "it's starting", "error message %s", "formatted") -+// require.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted") - func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1877,7 +1941,7 @@ func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...in - - // Same asserts that two pointers reference the same object. - // --// assert.Same(t, ptr1, ptr2) -+// require.Same(t, ptr1, ptr2) - // - // Both arguments must be pointer variables. Pointer variable sameness is - // determined based on the equality of both type and value. -@@ -1893,7 +1957,7 @@ func Same(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...in - - // Samef asserts that two pointers reference the same object. - // --// assert.Samef(t, ptr1, ptr2, "error message %s", "formatted") -+// require.Samef(t, ptr1, ptr2, "error message %s", "formatted") - // - // Both arguments must be pointer variables. Pointer variable sameness is - // determined based on the equality of both type and value. -@@ -1910,8 +1974,8 @@ func Samef(t TestingT, expected interface{}, actual interface{}, msg string, arg - // Subset asserts that the specified list(array, slice...) or map contains all - // elements given in the specified subset list(array, slice...) or map. - // --// assert.Subset(t, [1, 2, 3], [1, 2]) --// assert.Subset(t, {"x": 1, "y": 2}, {"x": 1}) -+// require.Subset(t, [1, 2, 3], [1, 2]) -+// require.Subset(t, {"x": 1, "y": 2}, {"x": 1}) - func Subset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1925,8 +1989,8 @@ func Subset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...inte - // Subsetf asserts that the specified list(array, slice...) or map contains all - // elements given in the specified subset list(array, slice...) or map. - // --// assert.Subsetf(t, [1, 2, 3], [1, 2], "error message %s", "formatted") --// assert.Subsetf(t, {"x": 1, "y": 2}, {"x": 1}, "error message %s", "formatted") -+// require.Subsetf(t, [1, 2, 3], [1, 2], "error message %s", "formatted") -+// require.Subsetf(t, {"x": 1, "y": 2}, {"x": 1}, "error message %s", "formatted") - func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1939,7 +2003,7 @@ func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args - - // True asserts that the specified value is true. - // --// assert.True(t, myBool) -+// require.True(t, myBool) - func True(t TestingT, value bool, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1952,7 +2016,7 @@ func True(t TestingT, value bool, msgAndArgs ...interface{}) { - - // Truef asserts that the specified value is true. - // --// assert.Truef(t, myBool, "error message %s", "formatted") -+// require.Truef(t, myBool, "error message %s", "formatted") - func Truef(t TestingT, value bool, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1965,7 +2029,7 @@ func Truef(t TestingT, value bool, msg string, args ...interface{}) { - - // WithinDuration asserts that the two times are within duration delta of each other. - // --// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second) -+// require.WithinDuration(t, time.Now(), time.Now(), 10*time.Second) - func WithinDuration(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1978,7 +2042,7 @@ func WithinDuration(t TestingT, expected time.Time, actual time.Time, delta time - - // WithinDurationf asserts that the two times are within duration delta of each other. - // --// assert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") -+// require.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") - func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -1991,7 +2055,7 @@ func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta tim - - // WithinRange asserts that a time is within a time range (inclusive). - // --// assert.WithinRange(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second)) -+// require.WithinRange(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second)) - func WithinRange(t TestingT, actual time.Time, start time.Time, end time.Time, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -@@ -2004,7 +2068,7 @@ func WithinRange(t TestingT, actual time.Time, start time.Time, end time.Time, m - - // WithinRangef asserts that a time is within a time range (inclusive). - // --// assert.WithinRangef(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted") -+// require.WithinRangef(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted") - func WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() -diff --git a/vendor/github.com/stretchr/testify/require/require.go.tmpl b/vendor/github.com/stretchr/testify/require/require.go.tmpl -index 55e42ddeb..8b3283685 100644 ---- a/vendor/github.com/stretchr/testify/require/require.go.tmpl -+++ b/vendor/github.com/stretchr/testify/require/require.go.tmpl -@@ -1,4 +1,4 @@ --{{.Comment}} -+{{ replace .Comment "assert." "require."}} - func {{.DocInfo.Name}}(t TestingT, {{.Params}}) { - if h, ok := t.(tHelper); ok { h.Helper() } - if assert.{{.DocInfo.Name}}(t, {{.ForwardedParams}}) { return } -diff --git a/vendor/github.com/stretchr/testify/require/require_forward.go b/vendor/github.com/stretchr/testify/require/require_forward.go -index eee8310a5..1bd87304f 100644 ---- a/vendor/github.com/stretchr/testify/require/require_forward.go -+++ b/vendor/github.com/stretchr/testify/require/require_forward.go -@@ -187,8 +187,8 @@ func (a *Assertions) EqualExportedValuesf(expected interface{}, actual interface - EqualExportedValuesf(a.t, expected, actual, msg, args...) - } - --// EqualValues asserts that two objects are equal or convertible to the same types --// and equal. -+// EqualValues asserts that two objects are equal or convertible to the larger -+// type and equal. - // - // a.EqualValues(uint32(123), int32(123)) - func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) { -@@ -198,8 +198,8 @@ func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAn - EqualValues(a.t, expected, actual, msgAndArgs...) - } - --// EqualValuesf asserts that two objects are equal or convertible to the same types --// and equal. -+// EqualValuesf asserts that two objects are equal or convertible to the larger -+// type and equal. - // - // a.EqualValuesf(uint32(123), int32(123), "error message %s", "formatted") - func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) { -@@ -337,7 +337,7 @@ func (a *Assertions) Eventually(condition func() bool, waitFor time.Duration, ti - // a.EventuallyWithT(func(c *assert.CollectT) { - // // add assertions as needed; any assertion failure will fail the current tick - // assert.True(c, externalValue, "expected 'externalValue' to be true") --// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") -+// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") - func (a *Assertions) EventuallyWithT(condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() -@@ -362,7 +362,7 @@ func (a *Assertions) EventuallyWithT(condition func(collect *assert.CollectT), w - // a.EventuallyWithTf(func(c *assert.CollectT, "error message %s", "formatted") { - // // add assertions as needed; any assertion failure will fail the current tick - // assert.True(c, externalValue, "expected 'externalValue' to be true") --// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") -+// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") - func (a *Assertions) EventuallyWithTf(condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() -@@ -1129,6 +1129,40 @@ func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg strin - NotContainsf(a.t, s, contains, msg, args...) - } - -+// NotElementsMatch asserts that the specified listA(array, slice...) is NOT equal to specified -+// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, -+// the number of appearances of each of them in both lists should not match. -+// This is an inverse of ElementsMatch. -+// -+// a.NotElementsMatch([1, 1, 2, 3], [1, 1, 2, 3]) -> false -+// -+// a.NotElementsMatch([1, 1, 2, 3], [1, 2, 3]) -> true -+// -+// a.NotElementsMatch([1, 2, 3], [1, 2, 4]) -> true -+func (a *Assertions) NotElementsMatch(listA interface{}, listB interface{}, msgAndArgs ...interface{}) { -+ if h, ok := a.t.(tHelper); ok { -+ h.Helper() ++func commaSeparatedTrailers(trailer map[string][]string) (string, error) { ++ keys := make([]string, 0, len(trailer)) ++ for k := range trailer { ++ k = CanonicalHeader(k) ++ switch k { ++ case "Transfer-Encoding", "Trailer", "Content-Length": ++ return "", fmt.Errorf("invalid Trailer key %q", k) ++ } ++ keys = append(keys, k) ++ } ++ if len(keys) > 0 { ++ sort.Strings(keys) ++ return strings.Join(keys, ","), nil + } -+ NotElementsMatch(a.t, listA, listB, msgAndArgs...) ++ return "", nil +} + -+// NotElementsMatchf asserts that the specified listA(array, slice...) is NOT equal to specified -+// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, -+// the number of appearances of each of them in both lists should not match. -+// This is an inverse of ElementsMatch. ++// validPseudoPath reports whether v is a valid :path pseudo-header ++// value. It must be either: +// -+// a.NotElementsMatchf([1, 1, 2, 3], [1, 1, 2, 3], "error message %s", "formatted") -> false ++// - a non-empty string starting with '/' ++// - the string '*', for OPTIONS requests. +// -+// a.NotElementsMatchf([1, 1, 2, 3], [1, 2, 3], "error message %s", "formatted") -> true ++// For now this is only used a quick check for deciding when to clean ++// up Opaque URLs before sending requests from the Transport. ++// See golang.org/issue/16847 +// -+// a.NotElementsMatchf([1, 2, 3], [1, 2, 4], "error message %s", "formatted") -> true -+func (a *Assertions) NotElementsMatchf(listA interface{}, listB interface{}, msg string, args ...interface{}) { -+ if h, ok := a.t.(tHelper); ok { -+ h.Helper() ++// We used to enforce that the path also didn't start with "//", but ++// Google's GFE accepts such paths and Chrome sends them, so ignore ++// that part of the spec. See golang.org/issue/19103. ++func validPseudoPath(v string) bool { ++ return (len(v) > 0 && v[0] == '/') || v == "*" ++} ++ ++func validateHeaders(hdrs map[string][]string) string { ++ for k, vv := range hdrs { ++ if !httpguts.ValidHeaderFieldName(k) && k != ":protocol" { ++ return fmt.Sprintf("name %q", k) ++ } ++ for _, v := range vv { ++ if !httpguts.ValidHeaderFieldValue(v) { ++ // Don't include the value in the error, ++ // because it may be sensitive. ++ return fmt.Sprintf("value for header %q", k) ++ } ++ } + } -+ NotElementsMatchf(a.t, listA, listB, msg, args...) ++ return "" +} + - // NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either - // a slice or a channel with len == 0. - // -@@ -1201,7 +1235,25 @@ func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg str - NotEqualf(a.t, expected, actual, msg, args...) - } - --// NotErrorIs asserts that at none of the errors in err's chain matches target. -+// NotErrorAs asserts that none of the errors in err's chain matches target, -+// but if so, sets target to that error value. -+func (a *Assertions) NotErrorAs(err error, target interface{}, msgAndArgs ...interface{}) { -+ if h, ok := a.t.(tHelper); ok { -+ h.Helper() ++// shouldSendReqContentLength reports whether we should send ++// a "content-length" request header. This logic is basically a copy of the net/http ++// transferWriter.shouldSendContentLength. ++// The contentLength is the corrected contentLength (so 0 means actually 0, not unknown). ++// -1 means unknown. ++func shouldSendReqContentLength(method string, contentLength int64) bool { ++ if contentLength > 0 { ++ return true ++ } ++ if contentLength < 0 { ++ return false ++ } ++ // For zero bodies, whether we send a content-length depends on the method. ++ // It also kinda doesn't matter for http2 either way, with END_STREAM. ++ switch method { ++ case "POST", "PUT", "PATCH": ++ return true ++ default: ++ return false + } -+ NotErrorAs(a.t, err, target, msgAndArgs...) +} + -+// NotErrorAsf asserts that none of the errors in err's chain matches target, -+// but if so, sets target to that error value. -+func (a *Assertions) NotErrorAsf(err error, target interface{}, msg string, args ...interface{}) { -+ if h, ok := a.t.(tHelper); ok { -+ h.Helper() ++// ServerRequestParam is parameters to NewServerRequest. ++type ServerRequestParam struct { ++ Method string ++ Scheme, Authority, Path string ++ Protocol string ++ Header map[string][]string ++} ++ ++// ServerRequestResult is the result of NewServerRequest. ++type ServerRequestResult struct { ++ // Various http.Request fields. ++ URL *url.URL ++ RequestURI string ++ Trailer map[string][]string ++ ++ NeedsContinue bool // client provided an "Expect: 100-continue" header ++ ++ // If the request should be rejected, this is a short string suitable for passing ++ // to the http2 package's CountError function. ++ // It might be a bit odd to return errors this way rather than returing an error, ++ // but this ensures we don't forget to include a CountError reason. ++ InvalidReason string ++} ++ ++func NewServerRequest(rp ServerRequestParam) ServerRequestResult { ++ needsContinue := httpguts.HeaderValuesContainsToken(rp.Header["Expect"], "100-continue") ++ if needsContinue { ++ delete(rp.Header, "Expect") ++ } ++ // Merge Cookie headers into one "; "-delimited value. ++ if cookies := rp.Header["Cookie"]; len(cookies) > 1 { ++ rp.Header["Cookie"] = []string{strings.Join(cookies, "; ")} ++ } ++ ++ // Setup Trailers ++ var trailer map[string][]string ++ for _, v := range rp.Header["Trailer"] { ++ for _, key := range strings.Split(v, ",") { ++ key = textproto.CanonicalMIMEHeaderKey(textproto.TrimString(key)) ++ switch key { ++ case "Transfer-Encoding", "Trailer", "Content-Length": ++ // Bogus. (copy of http1 rules) ++ // Ignore. ++ default: ++ if trailer == nil { ++ trailer = make(map[string][]string) ++ } ++ trailer[key] = nil ++ } ++ } ++ } ++ delete(rp.Header, "Trailer") ++ ++ // "':authority' MUST NOT include the deprecated userinfo subcomponent ++ // for "http" or "https" schemed URIs." ++ // https://www.rfc-editor.org/rfc/rfc9113.html#section-8.3.1-2.3.8 ++ if strings.IndexByte(rp.Authority, '@') != -1 && (rp.Scheme == "http" || rp.Scheme == "https") { ++ return ServerRequestResult{ ++ InvalidReason: "userinfo_in_authority", ++ } ++ } ++ ++ var url_ *url.URL ++ var requestURI string ++ if rp.Method == "CONNECT" && rp.Protocol == "" { ++ url_ = &url.URL{Host: rp.Authority} ++ requestURI = rp.Authority // mimic HTTP/1 server behavior ++ } else { ++ var err error ++ url_, err = url.ParseRequestURI(rp.Path) ++ if err != nil { ++ return ServerRequestResult{ ++ InvalidReason: "bad_path", ++ } ++ } ++ requestURI = rp.Path ++ } ++ ++ return ServerRequestResult{ ++ URL: url_, ++ NeedsContinue: needsContinue, ++ RequestURI: requestURI, ++ Trailer: trailer, + } -+ NotErrorAsf(a.t, err, target, msg, args...) +} +diff --git a/api/vendor/golang.org/x/text/LICENSE b/api/vendor/golang.org/x/text/LICENSE +index 6a66aea5e..2a7cf70da 100644 +--- a/api/vendor/golang.org/x/text/LICENSE ++++ b/api/vendor/golang.org/x/text/LICENSE +@@ -1,4 +1,4 @@ +-Copyright (c) 2009 The Go Authors. All rights reserved. ++Copyright 2009 The Go Authors. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are +@@ -10,7 +10,7 @@ notice, this list of conditions and the following disclaimer. + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. +- * Neither the name of Google Inc. nor the names of its ++ * Neither the name of Google LLC nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +diff --git a/api/vendor/modules.txt b/api/vendor/modules.txt +index 915f80194..171176556 100644 +--- a/api/vendor/modules.txt ++++ b/api/vendor/modules.txt +@@ -34,13 +34,14 @@ github.com/pmezard/go-difflib/difflib + ## explicit; go 1.17 + github.com/stretchr/testify/assert + github.com/stretchr/testify/require +-# golang.org/x/net v0.23.0 +-## explicit; go 1.18 ++# golang.org/x/net v0.36.0 ++## explicit; go 1.23.0 + golang.org/x/net/http/httpguts + golang.org/x/net/http2 + golang.org/x/net/http2/hpack + golang.org/x/net/idna +-# golang.org/x/text v0.14.0 ++golang.org/x/net/internal/httpcommon ++# golang.org/x/text v0.22.0 + ## explicit; go 1.18 + golang.org/x/text/secure/bidirule + golang.org/x/text/transform +diff --git a/go.mod b/go.mod +index 8dc814fdd..8e7adad56 100644 +--- a/go.mod ++++ b/go.mod +@@ -1,6 +1,8 @@ + module github.com/ceph/ceph-csi + +-go 1.22.5 ++go 1.23.0 + -+// NotErrorIs asserts that none of the errors in err's chain matches target. - // This is a wrapper for errors.Is. - func (a *Assertions) NotErrorIs(err error, target error, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { -@@ -1210,7 +1262,7 @@ func (a *Assertions) NotErrorIs(err error, target error, msgAndArgs ...interface - NotErrorIs(a.t, err, target, msgAndArgs...) - } ++toolchain go1.23.6 + + require ( + github.com/IBM/keyprotect-go-client v0.15.1 +@@ -25,9 +27,9 @@ require ( + github.com/pkg/xattr v0.4.10 + github.com/prometheus/client_golang v1.19.1 + github.com/stretchr/testify v1.9.0 +- golang.org/x/crypto v0.26.0 +- golang.org/x/net v0.28.0 +- golang.org/x/sys v0.24.0 ++ golang.org/x/crypto v0.35.0 ++ golang.org/x/net v0.36.0 ++ golang.org/x/sys v0.30.0 + google.golang.org/grpc v1.65.0 + google.golang.org/protobuf v1.34.2 + // +@@ -90,7 +92,7 @@ require ( + github.com/go-openapi/swag v0.22.3 // indirect + github.com/go-task/slim-sprig/v3 v3.0.0 // indirect + github.com/gogo/protobuf v1.3.2 // indirect +- github.com/golang-jwt/jwt/v5 v5.2.1 // indirect ++ github.com/golang-jwt/jwt/v5 v5.2.2 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/google/cel-go v0.17.8 // indirect + github.com/google/gnostic-models v0.6.8 // indirect +@@ -158,9 +160,9 @@ require ( + go.uber.org/zap v1.26.0 // indirect + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + golang.org/x/oauth2 v0.20.0 // indirect +- golang.org/x/sync v0.8.0 // indirect +- golang.org/x/term v0.23.0 // indirect +- golang.org/x/text v0.17.0 // indirect ++ golang.org/x/sync v0.11.0 // indirect ++ golang.org/x/term v0.29.0 // indirect ++ golang.org/x/text v0.22.0 // indirect + golang.org/x/time v0.3.0 // indirect + golang.org/x/tools v0.23.0 // indirect + gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect +diff --git a/go.sum b/go.sum +index 34d0b90ed..efd718e3e 100644 +--- a/go.sum ++++ b/go.sum +@@ -1055,8 +1055,8 @@ github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzw + github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= + 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-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= +-github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= ++github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8= ++github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= + github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= + github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= + github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +@@ -1720,8 +1720,8 @@ golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq + golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= + golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= + golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +-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/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= ++golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= + golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= + golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= + golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +@@ -1872,8 +1872,8 @@ golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= + golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= + 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.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +-golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= ++golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA= ++golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I= + 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= +@@ -1931,8 +1931,8 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= + golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= + golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= + golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +-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-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= + 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= +@@ -2043,8 +2043,8 @@ golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= + golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= + golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= + golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +-golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +-golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= ++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/telemetry v0.0.0-20240208230135-b75ee8823808/go.mod h1:KG1lNk5ZFNssSZLrpVb4sMXKMpGwGXOxSG3rnu2gZQQ= + golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= + golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +@@ -2066,8 +2066,8 @@ golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= + golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= + golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= + golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +-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/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= ++golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= + 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= +@@ -2089,8 +2089,8 @@ golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= + golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= + golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= + golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +-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/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.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= + 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= +diff --git a/vendor/github.com/golang-jwt/jwt/v5/README.md b/vendor/github.com/golang-jwt/jwt/v5/README.md +index 964598a31..0bb636f22 100644 +--- a/vendor/github.com/golang-jwt/jwt/v5/README.md ++++ b/vendor/github.com/golang-jwt/jwt/v5/README.md +@@ -10,11 +10,11 @@ implementation of [JSON Web + Tokens](https://datatracker.ietf.org/doc/html/rfc7519). + + Starting with [v4.0.0](https://github.com/golang-jwt/jwt/releases/tag/v4.0.0) +-this project adds Go module support, but maintains backwards compatibility with ++this project adds Go module support, but maintains backward compatibility with + older `v3.x.y` tags and upstream `github.com/dgrijalva/jwt-go`. See the + [`MIGRATION_GUIDE.md`](./MIGRATION_GUIDE.md) for more information. Version + v5.0.0 introduces major improvements to the validation of tokens, but is not +-entirely backwards compatible. ++entirely backward compatible. + + > After the original author of the library suggested migrating the maintenance + > of `jwt-go`, a dedicated team of open source maintainers decided to clone the +@@ -24,7 +24,7 @@ entirely backwards compatible. + + + **SECURITY NOTICE:** Some older versions of Go have a security issue in the +-crypto/elliptic. Recommendation is to upgrade to at least 1.15 See issue ++crypto/elliptic. The recommendation is to upgrade to at least 1.15 See issue + [dgrijalva/jwt-go#216](https://github.com/dgrijalva/jwt-go/issues/216) for more + detail. + +@@ -32,7 +32,7 @@ detail. + what you + expect](https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/). + This library attempts to make it easy to do the right thing by requiring key +-types match the expected alg, but you should take the extra step to verify it in ++types to match the expected alg, but you should take the extra step to verify it in + your usage. See the examples provided. + + ### Supported Go versions +@@ -41,7 +41,7 @@ Our support of Go versions is aligned with Go's [version release + policy](https://golang.org/doc/devel/release#policy). So we will support a major + version of Go until there are two newer major releases. We no longer support + building jwt-go with unsupported Go versions, as these contain security +-vulnerabilities which will not be fixed. ++vulnerabilities that will not be fixed. + + ## What the heck is a JWT? + +@@ -117,7 +117,7 @@ notable differences: + + This library is considered production ready. Feedback and feature requests are + appreciated. The API should be considered stable. There should be very few +-backwards-incompatible changes outside of major version updates (and only with ++backward-incompatible changes outside of major version updates (and only with + good reason). + + This project uses [Semantic Versioning 2.0.0](http://semver.org). Accepted pull +@@ -125,8 +125,8 @@ requests will land on `main`. Periodically, versions will be tagged from + `main`. You can find all the releases on [the project releases + page](https://github.com/golang-jwt/jwt/releases). + +-**BREAKING CHANGES:*** A full list of breaking changes is available in +-`VERSION_HISTORY.md`. See `MIGRATION_GUIDE.md` for more information on updating ++**BREAKING CHANGES:** A full list of breaking changes is available in ++`VERSION_HISTORY.md`. See [`MIGRATION_GUIDE.md`](./MIGRATION_GUIDE.md) for more information on updating + your code. + + ## Extensions +diff --git a/vendor/github.com/golang-jwt/jwt/v5/SECURITY.md b/vendor/github.com/golang-jwt/jwt/v5/SECURITY.md +index b08402c34..2740597f1 100644 +--- a/vendor/github.com/golang-jwt/jwt/v5/SECURITY.md ++++ b/vendor/github.com/golang-jwt/jwt/v5/SECURITY.md +@@ -2,11 +2,11 @@ + + ## Supported Versions + +-As of February 2022 (and until this document is updated), the latest version `v4` is supported. ++As of November 2024 (and until this document is updated), the latest version `v5` is supported. In critical cases, we might supply back-ported patches for `v4`. + + ## Reporting a Vulnerability + +-If you think you found a vulnerability, and even if you are not sure, please report it to jwt-go-security@googlegroups.com or one of the other [golang-jwt maintainers](https://github.com/orgs/golang-jwt/people). Please try be explicit, describe steps to reproduce the security issue with code example(s). ++If you think you found a vulnerability, and even if you are not sure, please report it a [GitHub Security Advisory](https://github.com/golang-jwt/jwt/security/advisories/new). Please try be explicit, describe steps to reproduce the security issue with code example(s). + + You will receive a response within a timely manner. If the issue is confirmed, we will do our best to release a patch as soon as possible given the complexity of the problem. + +diff --git a/vendor/github.com/golang-jwt/jwt/v5/parser.go b/vendor/github.com/golang-jwt/jwt/v5/parser.go +index ecf99af78..054c7eb6f 100644 +--- a/vendor/github.com/golang-jwt/jwt/v5/parser.go ++++ b/vendor/github.com/golang-jwt/jwt/v5/parser.go +@@ -8,6 +8,8 @@ import ( + "strings" + ) + ++const tokenDelimiter = "." ++ + type Parser struct { + // If populated, only these methods will be considered valid. + validMethods []string +@@ -136,9 +138,10 @@ func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyf + // It's only ever useful in cases where you know the signature is valid (since it has already + // been or will be checked elsewhere in the stack) and you want to extract values from it. + func (p *Parser) ParseUnverified(tokenString string, claims Claims) (token *Token, parts []string, err error) { +- parts = strings.Split(tokenString, ".") +- if len(parts) != 3 { +- return nil, parts, newError("token contains an invalid number of segments", ErrTokenMalformed) ++ var ok bool ++ parts, ok = splitToken(tokenString) ++ if !ok { ++ return nil, nil, newError("token contains an invalid number of segments", ErrTokenMalformed) + } --// NotErrorIsf asserts that at none of the errors in err's chain matches target. -+// NotErrorIsf asserts that none of the errors in err's chain matches target. - // This is a wrapper for errors.Is. - func (a *Assertions) NotErrorIsf(err error, target error, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { -diff --git a/vendor/github.com/stretchr/testify/require/requirements.go b/vendor/github.com/stretchr/testify/require/requirements.go -index 91772dfeb..6b7ce929e 100644 ---- a/vendor/github.com/stretchr/testify/require/requirements.go -+++ b/vendor/github.com/stretchr/testify/require/requirements.go -@@ -6,7 +6,7 @@ type TestingT interface { - FailNow() + token = &Token{Raw: tokenString} +@@ -196,6 +199,33 @@ func (p *Parser) ParseUnverified(tokenString string, claims Claims) (token *Toke + return token, parts, nil } --type tHelper interface { -+type tHelper = interface { - Helper() ++// splitToken splits a token string into three parts: header, claims, and signature. It will only ++// return true if the token contains exactly two delimiters and three parts. In all other cases, it ++// will return nil parts and false. ++func splitToken(token string) ([]string, bool) { ++ parts := make([]string, 3) ++ header, remain, ok := strings.Cut(token, tokenDelimiter) ++ if !ok { ++ return nil, false ++ } ++ parts[0] = header ++ claims, remain, ok := strings.Cut(remain, tokenDelimiter) ++ if !ok { ++ return nil, false ++ } ++ parts[1] = claims ++ // One more cut to ensure the signature is the last part of the token and there are no more ++ // delimiters. This avoids an issue where malicious input could contain additional delimiters ++ // causing unecessary overhead parsing tokens. ++ signature, _, unexpected := strings.Cut(remain, tokenDelimiter) ++ if unexpected { ++ return nil, false ++ } ++ parts[2] = signature ++ ++ return parts, true ++} ++ + // DecodeSegment decodes a JWT specific base64url encoding. This function will + // take into account whether the [Parser] is configured with additional options, + // such as [WithStrictDecoding] or [WithPaddingAllowed]. +diff --git a/vendor/github.com/golang-jwt/jwt/v5/token.go b/vendor/github.com/golang-jwt/jwt/v5/token.go +index 352873a2d..9c7f4ab01 100644 +--- a/vendor/github.com/golang-jwt/jwt/v5/token.go ++++ b/vendor/github.com/golang-jwt/jwt/v5/token.go +@@ -75,7 +75,7 @@ func (t *Token) SignedString(key interface{}) (string, error) { } + // SigningString generates the signing string. This is the most expensive part +-// of the whole deal. Unless you need this for something special, just go ++// of the whole deal. Unless you need this for something special, just go + // straight for the SignedString. + func (t *Token) SigningString() (string, error) { + h, err := json.Marshal(t.Header) diff --git a/vendor/golang.org/x/crypto/argon2/blamka_amd64.s b/vendor/golang.org/x/crypto/argon2/blamka_amd64.s index 6713accac..c3895478e 100644 --- a/vendor/golang.org/x/crypto/argon2/blamka_amd64.s @@ -18424,11 +17910,181 @@ index b93961010..b86dde151 100644 // Manually unpack the prompt/echo pairs. rest := msg.Prompts +diff --git a/vendor/golang.org/x/crypto/ssh/handshake.go b/vendor/golang.org/x/crypto/ssh/handshake.go +index 56cdc7c21..c9202b05d 100644 +--- a/vendor/golang.org/x/crypto/ssh/handshake.go ++++ b/vendor/golang.org/x/crypto/ssh/handshake.go +@@ -25,6 +25,11 @@ const debugHandshake = false + // quickly. + const chanSize = 16 + ++// maxPendingPackets sets the maximum number of packets to queue while waiting ++// for KEX to complete. This limits the total pending data to maxPendingPackets ++// * maxPacket bytes, which is ~16.8MB. ++const maxPendingPackets = 64 ++ + // keyingTransport is a packet based transport that supports key + // changes. It need not be thread-safe. It should pass through + // msgNewKeys in both directions. +@@ -73,13 +78,22 @@ type handshakeTransport struct { + incoming chan []byte + readError error + +- mu sync.Mutex +- writeError error +- sentInitPacket []byte +- sentInitMsg *kexInitMsg +- pendingPackets [][]byte // Used when a key exchange is in progress. ++ mu sync.Mutex ++ // Condition for the above mutex. It is used to notify a completed key ++ // exchange or a write failure. Writes can wait for this condition while a ++ // key exchange is in progress. ++ writeCond *sync.Cond ++ writeError error ++ sentInitPacket []byte ++ sentInitMsg *kexInitMsg ++ // Used to queue writes when a key exchange is in progress. The length is ++ // limited by pendingPacketsSize. Once full, writes will block until the key ++ // exchange is completed or an error occurs. If not empty, it is emptied ++ // all at once when the key exchange is completed in kexLoop. ++ pendingPackets [][]byte + writePacketsLeft uint32 + writeBytesLeft int64 ++ userAuthComplete bool // whether the user authentication phase is complete + + // If the read loop wants to schedule a kex, it pings this + // channel, and the write loop will send out a kex +@@ -133,6 +147,7 @@ func newHandshakeTransport(conn keyingTransport, config *Config, clientVersion, + + config: config, + } ++ t.writeCond = sync.NewCond(&t.mu) + t.resetReadThresholds() + t.resetWriteThresholds() + +@@ -259,6 +274,7 @@ func (t *handshakeTransport) recordWriteError(err error) { + defer t.mu.Unlock() + if t.writeError == nil && err != nil { + t.writeError = err ++ t.writeCond.Broadcast() + } + } + +@@ -362,6 +378,8 @@ write: + } + } + t.pendingPackets = t.pendingPackets[:0] ++ // Unblock writePacket if waiting for KEX. ++ t.writeCond.Broadcast() + t.mu.Unlock() + } + +@@ -552,26 +570,44 @@ func (t *handshakeTransport) sendKexInit() error { + return nil + } + ++var errSendBannerPhase = errors.New("ssh: SendAuthBanner outside of authentication phase") ++ + func (t *handshakeTransport) writePacket(p []byte) error { ++ t.mu.Lock() ++ defer t.mu.Unlock() ++ + switch p[0] { + case msgKexInit: + return errors.New("ssh: only handshakeTransport can send kexInit") + case msgNewKeys: + return errors.New("ssh: only handshakeTransport can send newKeys") ++ case msgUserAuthBanner: ++ if t.userAuthComplete { ++ return errSendBannerPhase ++ } ++ case msgUserAuthSuccess: ++ t.userAuthComplete = true + } + +- t.mu.Lock() +- defer t.mu.Unlock() + if t.writeError != nil { + return t.writeError + } + + if t.sentInitMsg != nil { +- // Copy the packet so the writer can reuse the buffer. +- cp := make([]byte, len(p)) +- copy(cp, p) +- t.pendingPackets = append(t.pendingPackets, cp) +- return nil ++ if len(t.pendingPackets) < maxPendingPackets { ++ // Copy the packet so the writer can reuse the buffer. ++ cp := make([]byte, len(p)) ++ copy(cp, p) ++ t.pendingPackets = append(t.pendingPackets, cp) ++ return nil ++ } ++ for t.sentInitMsg != nil { ++ // Block and wait for KEX to complete or an error. ++ t.writeCond.Wait() ++ if t.writeError != nil { ++ return t.writeError ++ } ++ } + } + + if t.writeBytesLeft > 0 { +@@ -588,6 +624,7 @@ func (t *handshakeTransport) writePacket(p []byte) error { + + if err := t.pushPacket(p); err != nil { + t.writeError = err ++ t.writeCond.Broadcast() + } + + return nil diff --git a/vendor/golang.org/x/crypto/ssh/server.go b/vendor/golang.org/x/crypto/ssh/server.go -index 3ca9e89e2..5b5ccd96f 100644 +index 3ca9e89e2..1839ddc6a 100644 --- a/vendor/golang.org/x/crypto/ssh/server.go +++ b/vendor/golang.org/x/crypto/ssh/server.go -@@ -149,7 +149,7 @@ func (s *ServerConfig) AddHostKey(key Signer) { +@@ -59,6 +59,27 @@ type GSSAPIWithMICConfig struct { + Server GSSAPIServer + } + ++// SendAuthBanner implements [ServerPreAuthConn]. ++func (s *connection) SendAuthBanner(msg string) error { ++ return s.transport.writePacket(Marshal(&userAuthBannerMsg{ ++ Message: msg, ++ })) ++} ++ ++func (*connection) unexportedMethodForFutureProofing() {} ++ ++// ServerPreAuthConn is the interface available on an incoming server ++// connection before authentication has completed. ++type ServerPreAuthConn interface { ++ unexportedMethodForFutureProofing() // permits growing ServerPreAuthConn safely later, ala testing.TB ++ ++ ConnMetadata ++ ++ // SendAuthBanner sends a banner message to the client. ++ // It returns an error once the authentication phase has ended. ++ SendAuthBanner(string) error ++} ++ + // ServerConfig holds server specific configuration data. + type ServerConfig struct { + // Config contains configuration shared between client and server. +@@ -118,6 +139,12 @@ type ServerConfig struct { + // attempts. + AuthLogCallback func(conn ConnMetadata, method string, err error) + ++ // PreAuthConnCallback, if non-nil, is called upon receiving a new connection ++ // before any authentication has started. The provided ServerPreAuthConn ++ // can be used at any time before authentication is complete, including ++ // after this callback has returned. ++ PreAuthConnCallback func(ServerPreAuthConn) ++ + // ServerVersion is the version identification string to announce in + // the public handshake. + // If empty, a reasonable default is used. +@@ -149,7 +176,7 @@ func (s *ServerConfig) AddHostKey(key Signer) { } // cachedPubKey contains the results of querying whether a public key is @@ -18437,7 +18093,7 @@ index 3ca9e89e2..5b5ccd96f 100644 type cachedPubKey struct { user string pubKeyData []byte -@@ -157,7 +157,13 @@ type cachedPubKey struct { +@@ -157,7 +184,13 @@ type cachedPubKey struct { perms *Permissions } @@ -18452,7 +18108,7 @@ index 3ca9e89e2..5b5ccd96f 100644 // pubKeyCache caches tests for public keys. Since SSH clients // will query whether a public key is acceptable before attempting to -@@ -179,9 +185,10 @@ func (c *pubKeyCache) get(user string, pubKeyData []byte) (cachedPubKey, bool) { +@@ -179,9 +212,10 @@ func (c *pubKeyCache) get(user string, pubKeyData []byte) (cachedPubKey, bool) { // add adds the given tuple to the cache. func (c *pubKeyCache) add(candidate cachedPubKey) { @@ -18465,17 +18121,746 @@ index 3ca9e89e2..5b5ccd96f 100644 } // ServerConn is an authenticated SSH connection, as seen from the -@@ -510,8 +517,8 @@ userAuthLoop: +@@ -481,6 +515,10 @@ func (b *BannerError) Error() string { + } + + func (s *connection) serverAuthenticate(config *ServerConfig) (*Permissions, error) { ++ if config.PreAuthConnCallback != nil { ++ config.PreAuthConnCallback(s) ++ } ++ + sessionID := s.transport.getSessionID() + var cache pubKeyCache + var perms *Permissions +@@ -488,7 +526,7 @@ func (s *connection) serverAuthenticate(config *ServerConfig) (*Permissions, err + authFailures := 0 + noneAuthCount := 0 + var authErrs []error +- var displayedBanner bool ++ var calledBannerCallback bool + partialSuccessReturned := false + // Set the initial authentication callbacks from the config. They can be + // changed if a PartialSuccessError is returned. +@@ -510,8 +548,8 @@ userAuthLoop: if err := s.transport.writePacket(Marshal(discMsg)); err != nil { return nil, err } - -- return nil, discMsg -+ authErrs = append(authErrs, discMsg) -+ return nil, &ServerAuthError{Errors: authErrs} - } - - var userAuthReq userAuthRequestMsg +- return nil, discMsg ++ authErrs = append(authErrs, discMsg) ++ return nil, &ServerAuthError{Errors: authErrs} + } + + var userAuthReq userAuthRequestMsg +@@ -535,14 +573,10 @@ userAuthLoop: + + s.user = userAuthReq.User + +- if !displayedBanner && config.BannerCallback != nil { +- displayedBanner = true +- msg := config.BannerCallback(s) +- if msg != "" { +- bannerMsg := &userAuthBannerMsg{ +- Message: msg, +- } +- if err := s.transport.writePacket(Marshal(bannerMsg)); err != nil { ++ if !calledBannerCallback && config.BannerCallback != nil { ++ calledBannerCallback = true ++ if msg := config.BannerCallback(s); msg != "" { ++ if err := s.SendAuthBanner(msg); err != nil { + return nil, err + } + } +@@ -755,10 +789,7 @@ userAuthLoop: + var bannerErr *BannerError + if errors.As(authErr, &bannerErr) { + if bannerErr.Message != "" { +- bannerMsg := &userAuthBannerMsg{ +- Message: bannerErr.Message, +- } +- if err := s.transport.writePacket(Marshal(bannerMsg)); err != nil { ++ if err := s.SendAuthBanner(bannerErr.Message); err != nil { + return nil, err + } + } +diff --git a/vendor/golang.org/x/net/context/context.go b/vendor/golang.org/x/net/context/context.go +index cf66309c4..db1c95fab 100644 +--- a/vendor/golang.org/x/net/context/context.go ++++ b/vendor/golang.org/x/net/context/context.go +@@ -3,29 +3,31 @@ + // license that can be found in the LICENSE file. + + // Package context defines the Context type, which carries deadlines, +-// cancelation signals, and other request-scoped values across API boundaries ++// cancellation signals, and other request-scoped values across API boundaries + // and between processes. + // As of Go 1.7 this package is available in the standard library under the +-// name context. https://golang.org/pkg/context. ++// name [context], and migrating to it can be done automatically with [go fix]. + // +-// Incoming requests to a server should create a Context, and outgoing calls to +-// servers should accept a Context. The chain of function calls between must +-// propagate the Context, optionally replacing it with a modified copy created +-// using WithDeadline, WithTimeout, WithCancel, or WithValue. ++// Incoming requests to a server should create a [Context], and outgoing ++// calls to servers should accept a Context. The chain of function ++// calls between them must propagate the Context, optionally replacing ++// it with a derived Context created using [WithCancel], [WithDeadline], ++// [WithTimeout], or [WithValue]. + // + // Programs that use Contexts should follow these rules to keep interfaces + // consistent across packages and enable static analysis tools to check context + // propagation: + // + // Do not store Contexts inside a struct type; instead, pass a Context +-// explicitly to each function that needs it. The Context should be the first ++// explicitly to each function that needs it. This is discussed further in ++// https://go.dev/blog/context-and-structs. The Context should be the first + // parameter, typically named ctx: + // + // func DoSomething(ctx context.Context, arg Arg) error { + // // ... use ctx ... + // } + // +-// Do not pass a nil Context, even if a function permits it. Pass context.TODO ++// Do not pass a nil [Context], even if a function permits it. Pass [context.TODO] + // if you are unsure about which Context to use. + // + // Use context Values only for request-scoped data that transits processes and +@@ -34,9 +36,30 @@ + // The same Context may be passed to functions running in different goroutines; + // Contexts are safe for simultaneous use by multiple goroutines. + // +-// See http://blog.golang.org/context for example code for a server that uses ++// See https://go.dev/blog/context for example code for a server that uses + // Contexts. +-package context // import "golang.org/x/net/context" ++// ++// [go fix]: https://go.dev/cmd/go#hdr-Update_packages_to_use_new_APIs ++package context ++ ++import ( ++ "context" // standard library's context, as of Go 1.7 ++ "time" ++) ++ ++// A Context carries a deadline, a cancellation signal, and other values across ++// API boundaries. ++// ++// Context's methods may be called by multiple goroutines simultaneously. ++type Context = context.Context ++ ++// Canceled is the error returned by [Context.Err] when the context is canceled ++// for some reason other than its deadline passing. ++var Canceled = context.Canceled ++ ++// DeadlineExceeded is the error returned by [Context.Err] when the context is canceled ++// due to its deadline passing. ++var DeadlineExceeded = context.DeadlineExceeded + + // Background returns a non-nil, empty Context. It is never canceled, has no + // values, and has no deadline. It is typically used by the main function, +@@ -49,8 +72,73 @@ func Background() Context { + // TODO returns a non-nil, empty Context. Code should use context.TODO when + // it's unclear which Context to use or it is not yet available (because the + // surrounding function has not yet been extended to accept a Context +-// parameter). TODO is recognized by static analysis tools that determine +-// whether Contexts are propagated correctly in a program. ++// parameter). + func TODO() Context { + return todo + } ++ ++var ( ++ background = context.Background() ++ todo = context.TODO() ++) ++ ++// A CancelFunc tells an operation to abandon its work. ++// A CancelFunc does not wait for the work to stop. ++// A CancelFunc may be called by multiple goroutines simultaneously. ++// After the first call, subsequent calls to a CancelFunc do nothing. ++type CancelFunc = context.CancelFunc ++ ++// WithCancel returns a derived context that points to the parent context ++// but has a new Done channel. The returned context's Done channel is closed ++// when the returned cancel function is called or when the parent context's ++// Done channel is closed, whichever happens first. ++// ++// Canceling this context releases resources associated with it, so code should ++// call cancel as soon as the operations running in this [Context] complete. ++func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { ++ return context.WithCancel(parent) ++} ++ ++// WithDeadline returns a derived context that points to the parent context ++// but has the deadline adjusted to be no later than d. If the parent's ++// deadline is already earlier than d, WithDeadline(parent, d) is semantically ++// equivalent to parent. The returned [Context.Done] channel is closed when ++// the deadline expires, when the returned cancel function is called, ++// or when the parent context's Done channel is closed, whichever happens first. ++// ++// Canceling this context releases resources associated with it, so code should ++// call cancel as soon as the operations running in this [Context] complete. ++func WithDeadline(parent Context, d time.Time) (Context, CancelFunc) { ++ return context.WithDeadline(parent, d) ++} ++ ++// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)). ++// ++// Canceling this context releases resources associated with it, so code should ++// call cancel as soon as the operations running in this [Context] complete: ++// ++// func slowOperationWithTimeout(ctx context.Context) (Result, error) { ++// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond) ++// defer cancel() // releases resources if slowOperation completes before timeout elapses ++// return slowOperation(ctx) ++// } ++func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) { ++ return context.WithTimeout(parent, timeout) ++} ++ ++// WithValue returns a derived context that points to the parent Context. ++// In the derived context, the value associated with key is val. ++// ++// Use context Values only for request-scoped data that transits processes and ++// APIs, not for passing optional parameters to functions. ++// ++// The provided key must be comparable and should not be of type ++// string or any other built-in type to avoid collisions between ++// packages using context. Users of WithValue should define their own ++// types for keys. To avoid allocating when assigning to an ++// interface{}, context keys often have concrete type ++// struct{}. Alternatively, exported context key variables' static ++// type should be a pointer or interface. ++func WithValue(parent Context, key, val interface{}) Context { ++ return context.WithValue(parent, key, val) ++} +diff --git a/vendor/golang.org/x/net/context/go17.go b/vendor/golang.org/x/net/context/go17.go +deleted file mode 100644 +index 0c1b86793..000000000 +--- a/vendor/golang.org/x/net/context/go17.go ++++ /dev/null +@@ -1,72 +0,0 @@ +-// Copyright 2016 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-//go:build go1.7 +- +-package context +- +-import ( +- "context" // standard library's context, as of Go 1.7 +- "time" +-) +- +-var ( +- todo = context.TODO() +- background = context.Background() +-) +- +-// Canceled is the error returned by Context.Err when the context is canceled. +-var Canceled = context.Canceled +- +-// DeadlineExceeded is the error returned by Context.Err when the context's +-// deadline passes. +-var DeadlineExceeded = context.DeadlineExceeded +- +-// WithCancel returns a copy of parent with a new Done channel. The returned +-// context's Done channel is closed when the returned cancel function is called +-// or when the parent context's Done channel is closed, whichever happens first. +-// +-// Canceling this context releases resources associated with it, so code should +-// call cancel as soon as the operations running in this Context complete. +-func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { +- ctx, f := context.WithCancel(parent) +- return ctx, f +-} +- +-// WithDeadline returns a copy of the parent context with the deadline adjusted +-// to be no later than d. If the parent's deadline is already earlier than d, +-// WithDeadline(parent, d) is semantically equivalent to parent. The returned +-// context's Done channel is closed when the deadline expires, when the returned +-// cancel function is called, or when the parent context's Done channel is +-// closed, whichever happens first. +-// +-// Canceling this context releases resources associated with it, so code should +-// call cancel as soon as the operations running in this Context complete. +-func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) { +- ctx, f := context.WithDeadline(parent, deadline) +- return ctx, f +-} +- +-// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)). +-// +-// Canceling this context releases resources associated with it, so code should +-// call cancel as soon as the operations running in this Context complete: +-// +-// func slowOperationWithTimeout(ctx context.Context) (Result, error) { +-// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond) +-// defer cancel() // releases resources if slowOperation completes before timeout elapses +-// return slowOperation(ctx) +-// } +-func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) { +- return WithDeadline(parent, time.Now().Add(timeout)) +-} +- +-// WithValue returns a copy of parent in which the value associated with key is +-// val. +-// +-// Use context Values only for request-scoped data that transits processes and +-// APIs, not for passing optional parameters to functions. +-func WithValue(parent Context, key interface{}, val interface{}) Context { +- return context.WithValue(parent, key, val) +-} +diff --git a/vendor/golang.org/x/net/context/go19.go b/vendor/golang.org/x/net/context/go19.go +deleted file mode 100644 +index e31e35a90..000000000 +--- a/vendor/golang.org/x/net/context/go19.go ++++ /dev/null +@@ -1,20 +0,0 @@ +-// Copyright 2017 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-//go:build go1.9 +- +-package context +- +-import "context" // standard library's context, as of Go 1.7 +- +-// A Context carries a deadline, a cancelation signal, and other values across +-// API boundaries. +-// +-// Context's methods may be called by multiple goroutines simultaneously. +-type Context = context.Context +- +-// A CancelFunc tells an operation to abandon its work. +-// A CancelFunc does not wait for the work to stop. +-// After the first call, subsequent calls to a CancelFunc do nothing. +-type CancelFunc = context.CancelFunc +diff --git a/vendor/golang.org/x/net/context/pre_go17.go b/vendor/golang.org/x/net/context/pre_go17.go +deleted file mode 100644 +index 065ff3dfa..000000000 +--- a/vendor/golang.org/x/net/context/pre_go17.go ++++ /dev/null +@@ -1,300 +0,0 @@ +-// Copyright 2014 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-//go:build !go1.7 +- +-package context +- +-import ( +- "errors" +- "fmt" +- "sync" +- "time" +-) +- +-// An emptyCtx is never canceled, has no values, and has no deadline. It is not +-// struct{}, since vars of this type must have distinct addresses. +-type emptyCtx int +- +-func (*emptyCtx) Deadline() (deadline time.Time, ok bool) { +- return +-} +- +-func (*emptyCtx) Done() <-chan struct{} { +- return nil +-} +- +-func (*emptyCtx) Err() error { +- return nil +-} +- +-func (*emptyCtx) Value(key interface{}) interface{} { +- return nil +-} +- +-func (e *emptyCtx) String() string { +- switch e { +- case background: +- return "context.Background" +- case todo: +- return "context.TODO" +- } +- return "unknown empty Context" +-} +- +-var ( +- background = new(emptyCtx) +- todo = new(emptyCtx) +-) +- +-// Canceled is the error returned by Context.Err when the context is canceled. +-var Canceled = errors.New("context canceled") +- +-// DeadlineExceeded is the error returned by Context.Err when the context's +-// deadline passes. +-var DeadlineExceeded = errors.New("context deadline exceeded") +- +-// WithCancel returns a copy of parent with a new Done channel. The returned +-// context's Done channel is closed when the returned cancel function is called +-// or when the parent context's Done channel is closed, whichever happens first. +-// +-// Canceling this context releases resources associated with it, so code should +-// call cancel as soon as the operations running in this Context complete. +-func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { +- c := newCancelCtx(parent) +- propagateCancel(parent, c) +- return c, func() { c.cancel(true, Canceled) } +-} +- +-// newCancelCtx returns an initialized cancelCtx. +-func newCancelCtx(parent Context) *cancelCtx { +- return &cancelCtx{ +- Context: parent, +- done: make(chan struct{}), +- } +-} +- +-// propagateCancel arranges for child to be canceled when parent is. +-func propagateCancel(parent Context, child canceler) { +- if parent.Done() == nil { +- return // parent is never canceled +- } +- if p, ok := parentCancelCtx(parent); ok { +- p.mu.Lock() +- if p.err != nil { +- // parent has already been canceled +- child.cancel(false, p.err) +- } else { +- if p.children == nil { +- p.children = make(map[canceler]bool) +- } +- p.children[child] = true +- } +- p.mu.Unlock() +- } else { +- go func() { +- select { +- case <-parent.Done(): +- child.cancel(false, parent.Err()) +- case <-child.Done(): +- } +- }() +- } +-} +- +-// parentCancelCtx follows a chain of parent references until it finds a +-// *cancelCtx. This function understands how each of the concrete types in this +-// package represents its parent. +-func parentCancelCtx(parent Context) (*cancelCtx, bool) { +- for { +- switch c := parent.(type) { +- case *cancelCtx: +- return c, true +- case *timerCtx: +- return c.cancelCtx, true +- case *valueCtx: +- parent = c.Context +- default: +- return nil, false +- } +- } +-} +- +-// removeChild removes a context from its parent. +-func removeChild(parent Context, child canceler) { +- p, ok := parentCancelCtx(parent) +- if !ok { +- return +- } +- p.mu.Lock() +- if p.children != nil { +- delete(p.children, child) +- } +- p.mu.Unlock() +-} +- +-// A canceler is a context type that can be canceled directly. The +-// implementations are *cancelCtx and *timerCtx. +-type canceler interface { +- cancel(removeFromParent bool, err error) +- Done() <-chan struct{} +-} +- +-// A cancelCtx can be canceled. When canceled, it also cancels any children +-// that implement canceler. +-type cancelCtx struct { +- Context +- +- done chan struct{} // closed by the first cancel call. +- +- mu sync.Mutex +- children map[canceler]bool // set to nil by the first cancel call +- err error // set to non-nil by the first cancel call +-} +- +-func (c *cancelCtx) Done() <-chan struct{} { +- return c.done +-} +- +-func (c *cancelCtx) Err() error { +- c.mu.Lock() +- defer c.mu.Unlock() +- return c.err +-} +- +-func (c *cancelCtx) String() string { +- return fmt.Sprintf("%v.WithCancel", c.Context) +-} +- +-// cancel closes c.done, cancels each of c's children, and, if +-// removeFromParent is true, removes c from its parent's children. +-func (c *cancelCtx) cancel(removeFromParent bool, err error) { +- if err == nil { +- panic("context: internal error: missing cancel error") +- } +- c.mu.Lock() +- if c.err != nil { +- c.mu.Unlock() +- return // already canceled +- } +- c.err = err +- close(c.done) +- for child := range c.children { +- // NOTE: acquiring the child's lock while holding parent's lock. +- child.cancel(false, err) +- } +- c.children = nil +- c.mu.Unlock() +- +- if removeFromParent { +- removeChild(c.Context, c) +- } +-} +- +-// WithDeadline returns a copy of the parent context with the deadline adjusted +-// to be no later than d. If the parent's deadline is already earlier than d, +-// WithDeadline(parent, d) is semantically equivalent to parent. The returned +-// context's Done channel is closed when the deadline expires, when the returned +-// cancel function is called, or when the parent context's Done channel is +-// closed, whichever happens first. +-// +-// Canceling this context releases resources associated with it, so code should +-// call cancel as soon as the operations running in this Context complete. +-func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) { +- if cur, ok := parent.Deadline(); ok && cur.Before(deadline) { +- // The current deadline is already sooner than the new one. +- return WithCancel(parent) +- } +- c := &timerCtx{ +- cancelCtx: newCancelCtx(parent), +- deadline: deadline, +- } +- propagateCancel(parent, c) +- d := deadline.Sub(time.Now()) +- if d <= 0 { +- c.cancel(true, DeadlineExceeded) // deadline has already passed +- return c, func() { c.cancel(true, Canceled) } +- } +- c.mu.Lock() +- defer c.mu.Unlock() +- if c.err == nil { +- c.timer = time.AfterFunc(d, func() { +- c.cancel(true, DeadlineExceeded) +- }) +- } +- return c, func() { c.cancel(true, Canceled) } +-} +- +-// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to +-// implement Done and Err. It implements cancel by stopping its timer then +-// delegating to cancelCtx.cancel. +-type timerCtx struct { +- *cancelCtx +- timer *time.Timer // Under cancelCtx.mu. +- +- deadline time.Time +-} +- +-func (c *timerCtx) Deadline() (deadline time.Time, ok bool) { +- return c.deadline, true +-} +- +-func (c *timerCtx) String() string { +- return fmt.Sprintf("%v.WithDeadline(%s [%s])", c.cancelCtx.Context, c.deadline, c.deadline.Sub(time.Now())) +-} +- +-func (c *timerCtx) cancel(removeFromParent bool, err error) { +- c.cancelCtx.cancel(false, err) +- if removeFromParent { +- // Remove this timerCtx from its parent cancelCtx's children. +- removeChild(c.cancelCtx.Context, c) +- } +- c.mu.Lock() +- if c.timer != nil { +- c.timer.Stop() +- c.timer = nil +- } +- c.mu.Unlock() +-} +- +-// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)). +-// +-// Canceling this context releases resources associated with it, so code should +-// call cancel as soon as the operations running in this Context complete: +-// +-// func slowOperationWithTimeout(ctx context.Context) (Result, error) { +-// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond) +-// defer cancel() // releases resources if slowOperation completes before timeout elapses +-// return slowOperation(ctx) +-// } +-func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) { +- return WithDeadline(parent, time.Now().Add(timeout)) +-} +- +-// WithValue returns a copy of parent in which the value associated with key is +-// val. +-// +-// Use context Values only for request-scoped data that transits processes and +-// APIs, not for passing optional parameters to functions. +-func WithValue(parent Context, key interface{}, val interface{}) Context { +- return &valueCtx{parent, key, val} +-} +- +-// A valueCtx carries a key-value pair. It implements Value for that key and +-// delegates all other calls to the embedded Context. +-type valueCtx struct { +- Context +- key, val interface{} +-} +- +-func (c *valueCtx) String() string { +- return fmt.Sprintf("%v.WithValue(%#v, %#v)", c.Context, c.key, c.val) +-} +- +-func (c *valueCtx) Value(key interface{}) interface{} { +- if c.key == key { +- return c.val +- } +- return c.Context.Value(key) +-} +diff --git a/vendor/golang.org/x/net/context/pre_go19.go b/vendor/golang.org/x/net/context/pre_go19.go +deleted file mode 100644 +index ec5a63803..000000000 +--- a/vendor/golang.org/x/net/context/pre_go19.go ++++ /dev/null +@@ -1,109 +0,0 @@ +-// Copyright 2014 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-//go:build !go1.9 +- +-package context +- +-import "time" +- +-// A Context carries a deadline, a cancelation signal, and other values across +-// API boundaries. +-// +-// Context's methods may be called by multiple goroutines simultaneously. +-type Context interface { +- // Deadline returns the time when work done on behalf of this context +- // should be canceled. Deadline returns ok==false when no deadline is +- // set. Successive calls to Deadline return the same results. +- Deadline() (deadline time.Time, ok bool) +- +- // Done returns a channel that's closed when work done on behalf of this +- // context should be canceled. Done may return nil if this context can +- // never be canceled. Successive calls to Done return the same value. +- // +- // WithCancel arranges for Done to be closed when cancel is called; +- // WithDeadline arranges for Done to be closed when the deadline +- // expires; WithTimeout arranges for Done to be closed when the timeout +- // elapses. +- // +- // Done is provided for use in select statements: +- // +- // // Stream generates values with DoSomething and sends them to out +- // // until DoSomething returns an error or ctx.Done is closed. +- // func Stream(ctx context.Context, out chan<- Value) error { +- // for { +- // v, err := DoSomething(ctx) +- // if err != nil { +- // return err +- // } +- // select { +- // case <-ctx.Done(): +- // return ctx.Err() +- // case out <- v: +- // } +- // } +- // } +- // +- // See http://blog.golang.org/pipelines for more examples of how to use +- // a Done channel for cancelation. +- Done() <-chan struct{} +- +- // Err returns a non-nil error value after Done is closed. Err returns +- // Canceled if the context was canceled or DeadlineExceeded if the +- // context's deadline passed. No other values for Err are defined. +- // After Done is closed, successive calls to Err return the same value. +- Err() error +- +- // Value returns the value associated with this context for key, or nil +- // if no value is associated with key. Successive calls to Value with +- // the same key returns the same result. +- // +- // Use context values only for request-scoped data that transits +- // processes and API boundaries, not for passing optional parameters to +- // functions. +- // +- // A key identifies a specific value in a Context. Functions that wish +- // to store values in Context typically allocate a key in a global +- // variable then use that key as the argument to context.WithValue and +- // Context.Value. A key can be any type that supports equality; +- // packages should define keys as an unexported type to avoid +- // collisions. +- // +- // Packages that define a Context key should provide type-safe accessors +- // for the values stores using that key: +- // +- // // Package user defines a User type that's stored in Contexts. +- // package user +- // +- // import "golang.org/x/net/context" +- // +- // // User is the type of value stored in the Contexts. +- // type User struct {...} +- // +- // // key is an unexported type for keys defined in this package. +- // // This prevents collisions with keys defined in other packages. +- // type key int +- // +- // // userKey is the key for user.User values in Contexts. It is +- // // unexported; clients use user.NewContext and user.FromContext +- // // instead of using this key directly. +- // var userKey key = 0 +- // +- // // NewContext returns a new Context that carries value u. +- // func NewContext(ctx context.Context, u *User) context.Context { +- // return context.WithValue(ctx, userKey, u) +- // } +- // +- // // FromContext returns the User value stored in ctx, if any. +- // func FromContext(ctx context.Context) (*User, bool) { +- // u, ok := ctx.Value(userKey).(*User) +- // return u, ok +- // } +- Value(key interface{}) interface{} +-} +- +-// A CancelFunc tells an operation to abandon its work. +-// A CancelFunc does not wait for the work to stop. +-// After the first call, subsequent calls to a CancelFunc do nothing. +-type CancelFunc func() diff --git a/vendor/golang.org/x/net/html/doc.go b/vendor/golang.org/x/net/html/doc.go index 3a7e5ab17..885c4c593 100644 --- a/vendor/golang.org/x/net/html/doc.go @@ -18671,7 +19056,7 @@ index 780968d6c..e81b73e6a 100644 p.mu.Lock() diff --git a/vendor/golang.org/x/net/http2/config.go b/vendor/golang.org/x/net/http2/config.go new file mode 100644 -index 000000000..de58dfb8d +index 000000000..ca645d9a1 --- /dev/null +++ b/vendor/golang.org/x/net/http2/config.go @@ -0,0 +1,122 @@ @@ -18737,7 +19122,7 @@ index 000000000..de58dfb8d + return conf +} + -+// configFromServer merges configuration settings from h2 and h2.t1.HTTP2 ++// configFromTransport merges configuration settings from h2 and h2.t1.HTTP2 +// (the net/http Transport). +func configFromTransport(h2 *Transport) http2Config { + conf := http2Config{ @@ -18799,7 +19184,7 @@ index 000000000..de58dfb8d +} diff --git a/vendor/golang.org/x/net/http2/config_go124.go b/vendor/golang.org/x/net/http2/config_go124.go new file mode 100644 -index 000000000..e3784123c +index 000000000..5b516c55f --- /dev/null +++ b/vendor/golang.org/x/net/http2/config_go124.go @@ -0,0 +1,61 @@ @@ -18818,7 +19203,7 @@ index 000000000..e3784123c + fillNetHTTPConfig(conf, srv.HTTP2) +} + -+// fillNetHTTPServerConfig sets fields in conf from tr.HTTP2. ++// fillNetHTTPTransportConfig sets fields in conf from tr.HTTP2. +func fillNetHTTPTransportConfig(conf *http2Config, tr *http.Transport) { + fillNetHTTPConfig(conf, tr.HTTP2) +} @@ -18909,7 +19294,7 @@ index 105c3b279..81faec7e7 100644 for _, hf2 := range pf[:i] { if hf.Name == hf2.Name { diff --git a/vendor/golang.org/x/net/http2/http2.go b/vendor/golang.org/x/net/http2/http2.go -index 003e649f3..c7601c909 100644 +index 003e649f3..6c18ea230 100644 --- a/vendor/golang.org/x/net/http2/http2.go +++ b/vendor/golang.org/x/net/http2/http2.go @@ -19,8 +19,9 @@ import ( @@ -18923,33 +19308,33 @@ index 003e649f3..c7601c909 100644 "net/http" "os" "sort" -@@ -33,10 +34,11 @@ import ( - ) - - var ( -- VerboseLogs bool -- logFrameWrites bool -- logFrameReads bool -- inTests bool -+ VerboseLogs bool -+ logFrameWrites bool -+ logFrameReads bool -+ inTests bool -+ disableExtendedConnectProtocol bool +@@ -37,6 +38,15 @@ var ( + logFrameWrites bool + logFrameReads bool + inTests bool ++ ++ // Enabling extended CONNECT by causes browsers to attempt to use ++ // WebSockets-over-HTTP/2. This results in problems when the server's websocket ++ // package doesn't support extended CONNECT. ++ // ++ // Disable extended CONNECT by default for now. ++ // ++ // Issue #71128. ++ disableExtendedConnectProtocol = true ) func init() { -@@ -49,6 +51,9 @@ func init() { +@@ -49,6 +59,9 @@ func init() { logFrameWrites = true logFrameReads = true } -+ if strings.Contains(e, "http2xconnect=0") { -+ disableExtendedConnectProtocol = true ++ if strings.Contains(e, "http2xconnect=1") { ++ disableExtendedConnectProtocol = false + } } const ( -@@ -140,6 +145,10 @@ func (s Setting) Valid() error { +@@ -140,6 +153,10 @@ func (s Setting) Valid() error { if s.Val < 16384 || s.Val > 1<<24-1 { return ConnectionError(ErrCodeProtocol) } @@ -18960,7 +19345,7 @@ index 003e649f3..c7601c909 100644 } return nil } -@@ -149,21 +158,23 @@ func (s Setting) Valid() error { +@@ -149,21 +166,23 @@ func (s Setting) Valid() error { type SettingID uint16 const ( @@ -18996,7 +19381,7 @@ index 003e649f3..c7601c909 100644 } func (s SettingID) String() string { -@@ -237,13 +248,19 @@ func (cw closeWaiter) Wait() { +@@ -237,13 +256,19 @@ func (cw closeWaiter) Wait() { // Its buffered writer is lazily allocated as needed, to minimize // idle memory usage with many connections. type bufferedWriter struct { @@ -19021,7 +19406,7 @@ index 003e649f3..c7601c909 100644 } // bufWriterPoolBufferSize is the size of bufio.Writer's -@@ -270,7 +287,7 @@ func (w *bufferedWriter) Available() int { +@@ -270,7 +295,7 @@ func (w *bufferedWriter) Available() int { func (w *bufferedWriter) Write(p []byte) (n int, err error) { if w.bw == nil { bw := bufWriterPool.Get().(*bufio.Writer) @@ -19030,7 +19415,7 @@ index 003e649f3..c7601c909 100644 w.bw = bw } return w.bw.Write(p) -@@ -288,6 +305,38 @@ func (w *bufferedWriter) Flush() error { +@@ -288,6 +313,38 @@ func (w *bufferedWriter) Flush() error { return err } @@ -19069,8 +19454,32 @@ index 003e649f3..c7601c909 100644 func mustUint31(v int32) uint32 { if v < 0 || v > 2147483647 { panic("out of range") +@@ -358,23 +415,6 @@ func (s *sorter) SortStrings(ss []string) { + s.v = save + } + +-// validPseudoPath reports whether v is a valid :path pseudo-header +-// value. It must be either: +-// +-// - a non-empty string starting with '/' +-// - the string '*', for OPTIONS requests. +-// +-// For now this is only used a quick check for deciding when to clean +-// up Opaque URLs before sending requests from the Transport. +-// See golang.org/issue/16847 +-// +-// We used to enforce that the path also didn't start with "//", but +-// Google's GFE accepts such paths and Chrome sends them, so ignore +-// that part of the spec. See golang.org/issue/19103. +-func validPseudoPath(v string) bool { +- return (len(v) > 0 && v[0] == '/') || v == "*" +-} +- + // incomparable is a zero-width, non-comparable type. Adding it to a struct + // makes that struct also non-comparable, and generally doesn't add + // any size (as long as it's first). diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go -index 6c349f3ec..b55547aec 100644 +index 6c349f3ec..b640deb0e 100644 --- a/vendor/golang.org/x/net/http2/server.go +++ b/vendor/golang.org/x/net/http2/server.go @@ -29,6 +29,7 @@ import ( @@ -19081,7 +19490,11 @@ index 6c349f3ec..b55547aec 100644 "crypto/tls" "errors" "fmt" -@@ -52,10 +53,14 @@ import ( +@@ -49,13 +50,18 @@ import ( + + "golang.org/x/net/http/httpguts" + "golang.org/x/net/http2/hpack" ++ "golang.org/x/net/internal/httpcommon" ) const ( @@ -19100,7 +19513,7 @@ index 6c349f3ec..b55547aec 100644 maxQueuedControlFrames = 10000 ) -@@ -127,6 +132,22 @@ type Server struct { +@@ -127,6 +133,22 @@ type Server struct { // If zero or negative, there is no timeout. IdleTimeout time.Duration @@ -19123,7 +19536,7 @@ index 6c349f3ec..b55547aec 100644 // MaxUploadBufferPerConnection is the size of the initial flow // control window for each connections. The HTTP/2 spec does not // allow this to be smaller than 65535 or larger than 2^32-1. -@@ -189,57 +210,6 @@ func (s *Server) afterFunc(d time.Duration, f func()) timer { +@@ -189,57 +211,6 @@ func (s *Server) afterFunc(d time.Duration, f func()) timer { return timeTimer{time.AfterFunc(d, f)} } @@ -19181,7 +19594,7 @@ index 6c349f3ec..b55547aec 100644 type serverInternalState struct { mu sync.Mutex activeConns map[*serverConn]struct{} -@@ -336,7 +306,7 @@ func ConfigureServer(s *http.Server, conf *Server) error { +@@ -336,7 +307,7 @@ func ConfigureServer(s *http.Server, conf *Server) error { if s.TLSNextProto == nil { s.TLSNextProto = map[string]func(*http.Server, *tls.Conn, http.Handler){} } @@ -19190,7 +19603,7 @@ index 6c349f3ec..b55547aec 100644 if testHookOnConn != nil { testHookOnConn() } -@@ -353,12 +323,31 @@ func ConfigureServer(s *http.Server, conf *Server) error { +@@ -353,12 +324,31 @@ func ConfigureServer(s *http.Server, conf *Server) error { ctx = bc.BaseContext() } conf.ServeConn(c, &ServeConnOpts{ @@ -19226,7 +19639,7 @@ index 6c349f3ec..b55547aec 100644 return nil } -@@ -440,13 +429,15 @@ func (s *Server) serveConn(c net.Conn, opts *ServeConnOpts, newf func(*serverCon +@@ -440,13 +430,15 @@ func (s *Server) serveConn(c net.Conn, opts *ServeConnOpts, newf func(*serverCon baseCtx, cancel := serverConnBaseContext(c, opts) defer cancel() @@ -19244,7 +19657,7 @@ index 6c349f3ec..b55547aec 100644 handler: opts.handler(), streams: make(map[uint32]*stream), readFrameCh: make(chan readFrameResult), -@@ -456,9 +447,12 @@ func (s *Server) serveConn(c net.Conn, opts *ServeConnOpts, newf func(*serverCon +@@ -456,9 +448,12 @@ func (s *Server) serveConn(c net.Conn, opts *ServeConnOpts, newf func(*serverCon bodyReadCh: make(chan bodyReadMsg), // buffering doesn't matter either way doneServing: make(chan struct{}), clientMaxStreams: math.MaxUint32, // Section 6.5.2: "Initially, there is no limit to this value" @@ -19258,7 +19671,7 @@ index 6c349f3ec..b55547aec 100644 serveG: newGoroutineLock(), pushEnabled: true, sawClientPreface: opts.SawClientPreface, -@@ -491,15 +485,15 @@ func (s *Server) serveConn(c net.Conn, opts *ServeConnOpts, newf func(*serverCon +@@ -491,15 +486,15 @@ func (s *Server) serveConn(c net.Conn, opts *ServeConnOpts, newf func(*serverCon sc.flow.add(initialWindowSize) sc.inflow.init(initialWindowSize) sc.hpackEncoder = hpack.NewEncoder(&sc.headerWriteBuf) @@ -19279,7 +19692,7 @@ index 6c349f3ec..b55547aec 100644 sc.framer = fr if tc, ok := c.(connectionStater); ok { -@@ -532,7 +526,7 @@ func (s *Server) serveConn(c net.Conn, opts *ServeConnOpts, newf func(*serverCon +@@ -532,7 +527,7 @@ func (s *Server) serveConn(c net.Conn, opts *ServeConnOpts, newf func(*serverCon // So for now, do nothing here again. } @@ -19288,7 +19701,7 @@ index 6c349f3ec..b55547aec 100644 // "Endpoints MAY choose to generate a connection error // (Section 5.4.1) of type INADEQUATE_SECURITY if one of // the prohibited cipher suites are negotiated." -@@ -569,7 +563,7 @@ func (s *Server) serveConn(c net.Conn, opts *ServeConnOpts, newf func(*serverCon +@@ -569,7 +564,7 @@ func (s *Server) serveConn(c net.Conn, opts *ServeConnOpts, newf func(*serverCon opts.UpgradeRequest = nil } @@ -19297,7 +19710,7 @@ index 6c349f3ec..b55547aec 100644 } func serverConnBaseContext(c net.Conn, opts *ServeConnOpts) (ctx context.Context, cancel func()) { -@@ -609,6 +603,7 @@ type serverConn struct { +@@ -609,6 +604,7 @@ type serverConn struct { tlsState *tls.ConnectionState // shared by all handlers, like net/http remoteAddrStr string writeSched WriteScheduler @@ -19305,7 +19718,7 @@ index 6c349f3ec..b55547aec 100644 // Everything following is owned by the serve loop; use serveG.check(): serveG goroutineLock // used to verify funcs are on serve() -@@ -628,6 +623,7 @@ type serverConn struct { +@@ -628,6 +624,7 @@ type serverConn struct { streams map[uint32]*stream unstartedHandlers []unstartedHandler initialStreamSendWindowSize int32 @@ -19313,7 +19726,7 @@ index 6c349f3ec..b55547aec 100644 maxFrameSize int32 peerMaxHeaderListSize uint32 // zero means unknown (default) canonHeader map[string]string // http2-lower-case -> Go-Canonical-Case -@@ -638,9 +634,14 @@ type serverConn struct { +@@ -638,9 +635,14 @@ type serverConn struct { inGoAway bool // we've started to or sent GOAWAY inFrameScheduleLoop bool // whether we're in the scheduleFrameWrite loop needToSendGoAway bool // we need to schedule a GOAWAY frame write @@ -19328,7 +19741,7 @@ index 6c349f3ec..b55547aec 100644 // Owned by the writeFrameAsync goroutine: headerWriteBuf bytes.Buffer -@@ -655,11 +656,7 @@ func (sc *serverConn) maxHeaderListSize() uint32 { +@@ -655,11 +657,7 @@ func (sc *serverConn) maxHeaderListSize() uint32 { if n <= 0 { n = http.DefaultMaxHeaderBytes } @@ -19341,6 +19754,16 @@ index 6c349f3ec..b55547aec 100644 } func (sc *serverConn) curOpenStreams() uint32 { +@@ -815,8 +813,7 @@ const maxCachedCanonicalHeadersKeysSize = 2048 + + func (sc *serverConn) canonicalHeader(v string) string { + sc.serveG.check() +- buildCommonHeaderMapsOnce() +- cv, ok := commonCanonHeader[v] ++ cv, ok := httpcommon.CachedCanonicalHeader(v) + if ok { + return cv + } @@ -923,7 +920,7 @@ func (sc *serverConn) notePanic() { } } @@ -19518,53 +19941,169 @@ index 6c349f3ec..b55547aec 100644 if sc.hs.WriteTimeout > 0 { st.writeDeadline = sc.srv.afterFunc(sc.hs.WriteTimeout, st.onWriteTimeout) } -@@ -2187,11 +2238,17 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res - scheme: f.PseudoValue("scheme"), - authority: f.PseudoValue("authority"), - path: f.PseudoValue("path"), -+ protocol: f.PseudoValue("protocol"), -+ } -+ -+ // extended connect is disabled, so we should not see :protocol -+ if disableExtendedConnectProtocol && rp.protocol != "" { -+ return nil, nil, sc.countError("bad_connect", streamError(f.StreamID, ErrCodeProtocol)) +@@ -2182,19 +2233,25 @@ func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream + func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*responseWriter, *http.Request, error) { + sc.serveG.check() + +- rp := requestParam{ +- method: f.PseudoValue("method"), +- scheme: f.PseudoValue("scheme"), +- authority: f.PseudoValue("authority"), +- path: f.PseudoValue("path"), ++ rp := httpcommon.ServerRequestParam{ ++ Method: f.PseudoValue("method"), ++ Scheme: f.PseudoValue("scheme"), ++ Authority: f.PseudoValue("authority"), ++ Path: f.PseudoValue("path"), ++ Protocol: f.PseudoValue("protocol"), } - isConnect := rp.method == "CONNECT" +- isConnect := rp.method == "CONNECT" ++ // extended connect is disabled, so we should not see :protocol ++ if disableExtendedConnectProtocol && rp.Protocol != "" { ++ return nil, nil, sc.countError("bad_connect", streamError(f.StreamID, ErrCodeProtocol)) ++ } ++ ++ isConnect := rp.Method == "CONNECT" if isConnect { - if rp.path != "" || rp.scheme != "" || rp.authority == "" { -+ if rp.protocol == "" && (rp.path != "" || rp.scheme != "" || rp.authority == "") { ++ if rp.Protocol == "" && (rp.Path != "" || rp.Scheme != "" || rp.Authority == "") { return nil, nil, sc.countError("bad_connect", streamError(f.StreamID, ErrCodeProtocol)) } - } else if rp.method == "" || rp.path == "" || (rp.scheme != "https" && rp.scheme != "http") { -@@ -2215,6 +2272,9 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res - if rp.authority == "" { - rp.authority = rp.header.Get("Host") +- } else if rp.method == "" || rp.path == "" || (rp.scheme != "https" && rp.scheme != "http") { ++ } else if rp.Method == "" || rp.Path == "" || (rp.Scheme != "https" && rp.Scheme != "http") { + // See 8.1.2.6 Malformed Requests and Responses: + // + // Malformed requests or responses that are detected +@@ -2208,12 +2265,16 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res + return nil, nil, sc.countError("bad_path_method", streamError(f.StreamID, ErrCodeProtocol)) } -+ if rp.protocol != "" { -+ rp.header.Set(":protocol", rp.protocol) + +- rp.header = make(http.Header) ++ header := make(http.Header) ++ rp.Header = header + for _, hf := range f.RegularFields() { +- rp.header.Add(sc.canonicalHeader(hf.Name), hf.Value) ++ header.Add(sc.canonicalHeader(hf.Name), hf.Value) + } ++ if rp.Authority == "" { ++ rp.Authority = header.Get("Host") + } +- if rp.authority == "" { +- rp.authority = rp.header.Get("Host") ++ if rp.Protocol != "" { ++ header.Set(":protocol", rp.Protocol) + } rw, req, err := sc.newWriterAndRequestNoBody(st, rp) - if err != nil { -@@ -2241,6 +2301,7 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res - type requestParam struct { - method string - scheme, authority, path string -+ protocol string - header http.Header +@@ -2222,7 +2283,7 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res + } + bodyOpen := !f.StreamEnded() + if bodyOpen { +- if vv, ok := rp.header["Content-Length"]; ok { ++ if vv, ok := rp.Header["Content-Length"]; ok { + if cl, err := strconv.ParseUint(vv[0], 10, 63); err == nil { + req.ContentLength = int64(cl) + } else { +@@ -2238,83 +2299,38 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res + return rw, req, nil } -@@ -2282,7 +2343,7 @@ func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp requestParam) (*r +-type requestParam struct { +- method string +- scheme, authority, path string +- header http.Header +-} +- +-func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp requestParam) (*responseWriter, *http.Request, error) { ++func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp httpcommon.ServerRequestParam) (*responseWriter, *http.Request, error) { + sc.serveG.check() + + var tlsState *tls.ConnectionState // nil if not scheme https +- if rp.scheme == "https" { ++ if rp.Scheme == "https" { + tlsState = sc.tlsState + } - var url_ *url.URL - var requestURI string +- needsContinue := httpguts.HeaderValuesContainsToken(rp.header["Expect"], "100-continue") +- if needsContinue { +- rp.header.Del("Expect") +- } +- // Merge Cookie headers into one "; "-delimited value. +- if cookies := rp.header["Cookie"]; len(cookies) > 1 { +- rp.header.Set("Cookie", strings.Join(cookies, "; ")) +- } +- +- // Setup Trailers +- var trailer http.Header +- for _, v := range rp.header["Trailer"] { +- for _, key := range strings.Split(v, ",") { +- key = http.CanonicalHeaderKey(textproto.TrimString(key)) +- switch key { +- case "Transfer-Encoding", "Trailer", "Content-Length": +- // Bogus. (copy of http1 rules) +- // Ignore. +- default: +- if trailer == nil { +- trailer = make(http.Header) +- } +- trailer[key] = nil +- } +- } +- } +- delete(rp.header, "Trailer") +- +- var url_ *url.URL +- var requestURI string - if rp.method == "CONNECT" { -+ if rp.method == "CONNECT" && rp.protocol == "" { - url_ = &url.URL{Host: rp.authority} - requestURI = rp.authority // mimic HTTP/1 server behavior - } else { -@@ -2855,6 +2916,11 @@ func (w *responseWriter) SetWriteDeadline(deadline time.Time) error { +- url_ = &url.URL{Host: rp.authority} +- requestURI = rp.authority // mimic HTTP/1 server behavior +- } else { +- var err error +- url_, err = url.ParseRequestURI(rp.path) +- if err != nil { +- return nil, nil, sc.countError("bad_path", streamError(st.id, ErrCodeProtocol)) +- } +- requestURI = rp.path ++ res := httpcommon.NewServerRequest(rp) ++ if res.InvalidReason != "" { ++ return nil, nil, sc.countError(res.InvalidReason, streamError(st.id, ErrCodeProtocol)) + } + + body := &requestBody{ + conn: sc, + stream: st, +- needsContinue: needsContinue, ++ needsContinue: res.NeedsContinue, + } +- req := &http.Request{ +- Method: rp.method, +- URL: url_, ++ req := (&http.Request{ ++ Method: rp.Method, ++ URL: res.URL, + RemoteAddr: sc.remoteAddrStr, +- Header: rp.header, +- RequestURI: requestURI, ++ Header: rp.Header, ++ RequestURI: res.RequestURI, + Proto: "HTTP/2.0", + ProtoMajor: 2, + ProtoMinor: 0, + TLS: tlsState, +- Host: rp.authority, ++ Host: rp.Authority, + Body: body, +- Trailer: trailer, +- } +- req = req.WithContext(st.ctx) +- ++ Trailer: res.Trailer, ++ }).WithContext(st.ctx) + rw := sc.newResponseWriter(st, req) + return rw, req, nil + } +@@ -2855,6 +2871,11 @@ func (w *responseWriter) SetWriteDeadline(deadline time.Time) error { return nil } @@ -19576,7 +20115,26 @@ index 6c349f3ec..b55547aec 100644 func (w *responseWriter) Flush() { w.FlushError() } -@@ -3301,7 +3367,7 @@ func (sc *serverConn) countError(name string, err error) error { +@@ -3204,12 +3225,12 @@ func (sc *serverConn) startPush(msg *startPushRequest) { + // we start in "half closed (remote)" for simplicity. + // See further comments at the definition of stateHalfClosedRemote. + promised := sc.newStream(promisedID, msg.parent.id, stateHalfClosedRemote) +- rw, req, err := sc.newWriterAndRequestNoBody(promised, requestParam{ +- method: msg.method, +- scheme: msg.url.Scheme, +- authority: msg.url.Host, +- path: msg.url.RequestURI(), +- header: cloneHeader(msg.header), // clone since handler runs concurrently with writing the PUSH_PROMISE ++ rw, req, err := sc.newWriterAndRequestNoBody(promised, httpcommon.ServerRequestParam{ ++ Method: msg.method, ++ Scheme: msg.url.Scheme, ++ Authority: msg.url.Host, ++ Path: msg.url.RequestURI(), ++ Header: cloneHeader(msg.header), // clone since handler runs concurrently with writing the PUSH_PROMISE + }) + if err != nil { + // Should not happen, since we've already validated msg.url. +@@ -3301,7 +3322,7 @@ func (sc *serverConn) countError(name string, err error) error { if sc == nil || sc.srv == nil { return err } @@ -19586,17 +20144,26 @@ index 6c349f3ec..b55547aec 100644 return err } diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go -index 61f511f97..090d0e1bd 100644 +index 61f511f97..f26356b9c 100644 --- a/vendor/golang.org/x/net/http2/transport.go +++ b/vendor/golang.org/x/net/http2/transport.go -@@ -25,7 +25,6 @@ import ( +@@ -25,8 +25,6 @@ import ( "net/http" "net/http/httptrace" "net/textproto" - "os" - "sort" +- "sort" "strconv" "strings" + "sync" +@@ -36,6 +34,7 @@ import ( + "golang.org/x/net/http/httpguts" + "golang.org/x/net/http2/hpack" + "golang.org/x/net/idna" ++ "golang.org/x/net/internal/httpcommon" + ) + + const ( @@ -203,6 +202,20 @@ func (t *Transport) markNewGoroutine() { } } @@ -19732,7 +20299,7 @@ index 61f511f97..090d0e1bd 100644 singleUse bool // whether being used for a single http.Request getConnCalled bool // used by clientConnPool -@@ -350,31 +368,54 @@ type ClientConn struct { +@@ -350,31 +368,55 @@ type ClientConn struct { idleTimeout time.Duration // or 0 for never idleTimer timer @@ -19762,6 +20329,7 @@ index 61f511f97..090d0e1bd 100644 + doNotReuse bool // whether conn is marked to not be reused for any future requests + closing bool + closed bool ++ closedOnIdle bool // true if conn was closed for idleness + seenSettings bool // true if we've seen a settings frame, false otherwise + seenSettingsChan chan struct{} // closed when seenSettings is true or frame reading fails + wantSettingsAck bool // we sent a SETTINGS frame and haven't heard back @@ -19811,7 +20379,7 @@ index 61f511f97..090d0e1bd 100644 // reqHeaderMu is a 1-element semaphore channel controlling access to sending new requests. // Write to reqHeaderMu to lock it, read from it to unlock. -@@ -432,12 +473,12 @@ type clientStream struct { +@@ -432,12 +474,12 @@ type clientStream struct { sentHeaders bool // owned by clientConnReadLoop: @@ -19830,7 +20398,7 @@ index 61f511f97..090d0e1bd 100644 trailer http.Header // accumulated trailers resTrailer *http.Header // client's Response.Trailer -@@ -499,6 +540,7 @@ func (cs *clientStream) closeReqBodyLocked() { +@@ -499,6 +541,7 @@ func (cs *clientStream) closeReqBodyLocked() { } type stickyErrWriter struct { @@ -19838,7 +20406,7 @@ index 61f511f97..090d0e1bd 100644 conn net.Conn timeout time.Duration err *error -@@ -508,22 +550,9 @@ func (sew stickyErrWriter) Write(p []byte) (n int, err error) { +@@ -508,22 +551,9 @@ func (sew stickyErrWriter) Write(p []byte) (n int, err error) { if *sew.err != nil { return 0, *sew.err } @@ -19864,7 +20432,7 @@ index 61f511f97..090d0e1bd 100644 } // noCachedConnError is the concrete type of ErrNoCachedConn, which -@@ -554,6 +583,8 @@ type RoundTripOpt struct { +@@ -554,6 +584,8 @@ type RoundTripOpt struct { // no cached connection is available, RoundTripOpt // will return ErrNoCachedConn. OnlyCachedConn bool @@ -19873,7 +20441,7 @@ index 61f511f97..090d0e1bd 100644 } func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) { -@@ -586,7 +617,14 @@ func authorityAddr(scheme string, authority string) (addr string) { +@@ -586,7 +618,14 @@ func authorityAddr(scheme string, authority string) (addr string) { // RoundTripOpt is like RoundTrip, but takes options. func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Response, error) { @@ -19889,7 +20457,7 @@ index 61f511f97..090d0e1bd 100644 return nil, errors.New("http2: unsupported scheme") } -@@ -597,7 +635,7 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res +@@ -597,7 +636,7 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res t.vlogf("http2: Transport failed to get client conn for %s: %v", addr, err) return nil, err } @@ -19898,7 +20466,7 @@ index 61f511f97..090d0e1bd 100644 traceGotConn(req, cc, reused) res, err := cc.RoundTrip(req) if err != nil && retry <= 6 { -@@ -622,6 +660,22 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res +@@ -622,6 +661,22 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res } } } @@ -19921,7 +20489,7 @@ index 61f511f97..090d0e1bd 100644 if err != nil { t.vlogf("RoundTrip failure: %v", err) return nil, err -@@ -640,9 +694,10 @@ func (t *Transport) CloseIdleConnections() { +@@ -640,9 +695,10 @@ func (t *Transport) CloseIdleConnections() { } var ( @@ -19935,7 +20503,7 @@ index 61f511f97..090d0e1bd 100644 ) // shouldRetryRequest is called by RoundTrip when a request fails to get -@@ -758,44 +813,38 @@ func (t *Transport) expectContinueTimeout() time.Duration { +@@ -758,44 +814,38 @@ func (t *Transport) expectContinueTimeout() time.Duration { return t.t1.ExpectContinueTimeout } @@ -20002,7 +20570,7 @@ index 61f511f97..090d0e1bd 100644 } if VerboseLogs { t.vlogf("http2: Transport creating client conn %p to %v", cc, c.RemoteAddr()) -@@ -807,24 +856,23 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro +@@ -807,24 +857,23 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro // TODO: adjust this writer size to account for frame size + // MTU + crypto/tls record padding. cc.bw = bufio.NewWriter(stickyErrWriter{ @@ -20032,7 +20600,7 @@ index 61f511f97..090d0e1bd 100644 cc.peerMaxHeaderTableSize = initialHeaderTableSize if cs, ok := c.(connectionStater); ok { -@@ -834,11 +882,9 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro +@@ -834,11 +883,9 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro initialSettings := []Setting{ {ID: SettingEnablePush, Val: 0}, @@ -20046,7 +20614,7 @@ index 61f511f97..090d0e1bd 100644 if max := t.maxHeaderListSize(); max != 0 { initialSettings = append(initialSettings, Setting{ID: SettingMaxHeaderListSize, Val: max}) } -@@ -848,8 +894,8 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro +@@ -848,8 +895,8 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro cc.bw.Write(clientPreface) cc.fr.WriteSettings(initialSettings...) @@ -20057,7 +20625,7 @@ index 61f511f97..090d0e1bd 100644 cc.bw.Flush() if cc.werr != nil { cc.Close() -@@ -867,7 +913,7 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro +@@ -867,7 +914,7 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro } func (cc *ClientConn) healthCheck() { @@ -20066,7 +20634,7 @@ index 61f511f97..090d0e1bd 100644 // We don't need to periodically ping in the health check, because the readLoop of ClientConn will // trigger the healthCheck again if there is no frame received. ctx, cancel := cc.t.contextWithTimeout(context.Background(), pingTimeout) -@@ -995,7 +1041,7 @@ func (cc *ClientConn) State() ClientConnState { +@@ -995,7 +1042,7 @@ func (cc *ClientConn) State() ClientConnState { return ClientConnState{ Closed: cc.closed, Closing: cc.closing || cc.singleUse || cc.doNotReuse || cc.goAway != nil, @@ -20075,7 +20643,7 @@ index 61f511f97..090d0e1bd 100644 StreamsReserved: cc.streamsReserved, StreamsPending: cc.pendingRequests, LastIdle: cc.lastIdle, -@@ -1027,16 +1073,38 @@ func (cc *ClientConn) idleStateLocked() (st clientConnIdleState) { +@@ -1027,16 +1074,40 @@ func (cc *ClientConn) idleStateLocked() (st clientConnIdleState) { // writing it. maxConcurrentOkay = true } else { @@ -20096,10 +20664,12 @@ index 61f511f97..090d0e1bd 100644 + + // If this connection has never been used for a request and is closed, + // then let it take a request (which will fail). ++ // If the conn was closed for idleness, we're racing the idle timer; ++ // don't try to use the conn. (Issue #70515.) + // + // This avoids a situation where an error early in a connection's lifetime + // goes unreported. -+ if cc.nextStreamID == 1 && cc.streamsReserved == 0 && cc.closed { ++ if cc.nextStreamID == 1 && cc.streamsReserved == 0 && cc.closed && !cc.closedOnIdle { + st.canTakeNewRequest = true + } + @@ -20115,7 +20685,7 @@ index 61f511f97..090d0e1bd 100644 func (cc *ClientConn) canTakeNewRequestLocked() bool { st := cc.idleStateLocked() return st.canTakeNewRequest -@@ -1049,7 +1117,7 @@ func (cc *ClientConn) tooIdleLocked() bool { +@@ -1049,7 +1120,7 @@ func (cc *ClientConn) tooIdleLocked() bool { // times are compared based on their wall time. We don't want // to reuse a connection that's been sitting idle during // VM/laptop suspend if monotonic time was also frozen. @@ -20123,8 +20693,90 @@ index 61f511f97..090d0e1bd 100644 + return cc.idleTimeout != 0 && !cc.lastIdle.IsZero() && cc.t.timeSince(cc.lastIdle.Round(0)) > cc.idleTimeout } - // onIdleTimeout is called from a time.AfterFunc goroutine. It will -@@ -1411,6 +1479,8 @@ func (cs *clientStream) doRequest(req *http.Request, streamf func(*clientStream) + // onIdleTimeout is called from a time.AfterFunc goroutine. It will +@@ -1087,6 +1158,7 @@ func (cc *ClientConn) closeIfIdle() { + return + } + cc.closed = true ++ cc.closedOnIdle = true + nextID := cc.nextStreamID + // TODO: do clients send GOAWAY too? maybe? Just Close: + cc.mu.Unlock() +@@ -1203,23 +1275,6 @@ func (cc *ClientConn) closeForLostPing() { + // exported. At least they'll be DeepEqual for h1-vs-h2 comparisons tests. + var errRequestCanceled = errors.New("net/http: request canceled") + +-func commaSeparatedTrailers(req *http.Request) (string, error) { +- keys := make([]string, 0, len(req.Trailer)) +- for k := range req.Trailer { +- k = canonicalHeader(k) +- switch k { +- case "Transfer-Encoding", "Trailer", "Content-Length": +- return "", fmt.Errorf("invalid Trailer key %q", k) +- } +- keys = append(keys, k) +- } +- if len(keys) > 0 { +- sort.Strings(keys) +- return strings.Join(keys, ","), nil +- } +- return "", nil +-} +- + func (cc *ClientConn) responseHeaderTimeout() time.Duration { + if cc.t.t1 != nil { + return cc.t.t1.ResponseHeaderTimeout +@@ -1231,22 +1286,6 @@ func (cc *ClientConn) responseHeaderTimeout() time.Duration { + return 0 + } + +-// checkConnHeaders checks whether req has any invalid connection-level headers. +-// per RFC 7540 section 8.1.2.2: Connection-Specific Header Fields. +-// Certain headers are special-cased as okay but not transmitted later. +-func checkConnHeaders(req *http.Request) error { +- if v := req.Header.Get("Upgrade"); v != "" { +- return fmt.Errorf("http2: invalid Upgrade request header: %q", req.Header["Upgrade"]) +- } +- if vv := req.Header["Transfer-Encoding"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && vv[0] != "chunked") { +- return fmt.Errorf("http2: invalid Transfer-Encoding request header: %q", vv) +- } +- if vv := req.Header["Connection"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && !asciiEqualFold(vv[0], "close") && !asciiEqualFold(vv[0], "keep-alive")) { +- return fmt.Errorf("http2: invalid Connection request header: %q", vv) +- } +- return nil +-} +- + // actualContentLength returns a sanitized version of + // req.ContentLength, where 0 actually means zero (not unknown) and -1 + // means unknown. +@@ -1292,25 +1331,7 @@ func (cc *ClientConn) roundTrip(req *http.Request, streamf func(*clientStream)) + donec: make(chan struct{}), + } + +- // TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere? +- if !cc.t.disableCompression() && +- req.Header.Get("Accept-Encoding") == "" && +- req.Header.Get("Range") == "" && +- !cs.isHead { +- // Request gzip only, not deflate. Deflate is ambiguous and +- // not as universally supported anyway. +- // See: https://zlib.net/zlib_faq.html#faq39 +- // +- // Note that we don't request this for HEAD requests, +- // due to a bug in nginx: +- // http://trac.nginx.org/nginx/ticket/358 +- // https://golang.org/issue/5522 +- // +- // We don't request gzip if the request is for a range, since +- // auto-decoding a portion of a gzipped document will just fail +- // anyway. See https://golang.org/issue/8923 +- cs.requestedGzip = true +- } ++ cs.requestedGzip = httpcommon.IsRequestGzip(req.Method, req.Header, cc.t.disableCompression()) + + go cs.doRequest(req, streamf) + +@@ -1411,6 +1432,8 @@ func (cs *clientStream) doRequest(req *http.Request, streamf func(*clientStream) cs.cleanupWriteRequest(err) } @@ -20133,20 +20785,21 @@ index 61f511f97..090d0e1bd 100644 // writeRequest sends a request. // // It returns nil after the request is written, the response read, -@@ -1426,12 +1496,31 @@ func (cs *clientStream) writeRequest(req *http.Request, streamf func(*clientStre - return err - } +@@ -1422,8 +1445,11 @@ func (cs *clientStream) writeRequest(req *http.Request, streamf func(*clientStre + cc := cs.cc + ctx := cs.ctx +- if err := checkConnHeaders(req); err != nil { +- return err + // wait for setting frames to be received, a server can change this value later, + // but we just wait for the first settings frame + var isExtendedConnect bool + if req.Method == "CONNECT" && req.Header.Get(":protocol") != "" { + isExtendedConnect = true -+ } -+ + } + // Acquire the new-request lock by writing to reqHeaderMu. - // This lock guards the critical section covering allocating a new stream ID - // (requires mu) and creating the stream (requires wmu). +@@ -1432,6 +1458,18 @@ func (cs *clientStream) writeRequest(req *http.Request, streamf func(*clientStre if cc.reqHeaderMu == nil { panic("RoundTrip on uninitialized ClientConn") // for tests } @@ -20165,7 +20818,57 @@ index 61f511f97..090d0e1bd 100644 select { case cc.reqHeaderMu <- struct{}{}: case <-cs.reqCancel: -@@ -1613,6 +1702,7 @@ func (cs *clientStream) cleanupWriteRequest(err error) { +@@ -1570,26 +1608,39 @@ func (cs *clientStream) encodeAndWriteHeaders(req *http.Request) error { + // we send: HEADERS{1}, CONTINUATION{0,} + DATA{0,} (DATA is + // sent by writeRequestBody below, along with any Trailers, + // again in form HEADERS{1}, CONTINUATION{0,}) +- trailers, err := commaSeparatedTrailers(req) +- if err != nil { +- return err +- } +- hasTrailers := trailers != "" +- contentLen := actualContentLength(req) +- hasBody := contentLen != 0 +- hdrs, err := cc.encodeHeaders(req, cs.requestedGzip, trailers, contentLen) ++ cc.hbuf.Reset() ++ res, err := encodeRequestHeaders(req, cs.requestedGzip, cc.peerMaxHeaderListSize, func(name, value string) { ++ cc.writeHeader(name, value) ++ }) + if err != nil { +- return err ++ return fmt.Errorf("http2: %w", err) + } ++ hdrs := cc.hbuf.Bytes() + + // Write the request. +- endStream := !hasBody && !hasTrailers ++ endStream := !res.HasBody && !res.HasTrailers + cs.sentHeaders = true + err = cc.writeHeaders(cs.ID, endStream, int(cc.maxFrameSize), hdrs) + traceWroteHeaders(cs.trace) + return err + } + ++func encodeRequestHeaders(req *http.Request, addGzipHeader bool, peerMaxHeaderListSize uint64, headerf func(name, value string)) (httpcommon.EncodeHeadersResult, error) { ++ return httpcommon.EncodeHeaders(req.Context(), httpcommon.EncodeHeadersParam{ ++ Request: httpcommon.Request{ ++ Header: req.Header, ++ Trailer: req.Trailer, ++ URL: req.URL, ++ Host: req.Host, ++ Method: req.Method, ++ ActualContentLength: actualContentLength(req), ++ }, ++ AddGzipHeader: addGzipHeader, ++ PeerMaxHeaderListSize: peerMaxHeaderListSize, ++ DefaultUserAgent: defaultUserAgent, ++ }, headerf) ++} ++ + // cleanupWriteRequest performs post-request tasks. + // + // If err (the result of writeRequest) is non-nil and the stream is not closed, +@@ -1613,6 +1664,7 @@ func (cs *clientStream) cleanupWriteRequest(err error) { cs.reqBodyClosed = make(chan struct{}) } bodyClosed := cs.reqBodyClosed @@ -20173,7 +20876,7 @@ index 61f511f97..090d0e1bd 100644 cc.mu.Unlock() if mustCloseBody { cs.reqBody.Close() -@@ -1637,16 +1727,44 @@ func (cs *clientStream) cleanupWriteRequest(err error) { +@@ -1637,16 +1689,44 @@ func (cs *clientStream) cleanupWriteRequest(err error) { if cs.sentHeaders { if se, ok := err.(StreamError); ok { if se.Cause != errFromPeer { @@ -20221,7 +20924,7 @@ index 61f511f97..090d0e1bd 100644 } cs.bufPipe.CloseWithError(errRequestCanceled) } -@@ -1668,12 +1786,17 @@ func (cs *clientStream) cleanupWriteRequest(err error) { +@@ -1668,12 +1748,17 @@ func (cs *clientStream) cleanupWriteRequest(err error) { // Must hold cc.mu. func (cc *ClientConn) awaitOpenSlotForStreamLocked(cs *clientStream) error { for { @@ -20241,45 +20944,231 @@ index 61f511f97..090d0e1bd 100644 return nil } cc.pendingRequests++ -@@ -1945,7 +2068,7 @@ func (cs *clientStream) awaitFlowControl(maxBytes int) (taken int32, err error) +@@ -1943,214 +2028,6 @@ func (cs *clientStream) awaitFlowControl(maxBytes int) (taken int32, err error) + } + } - func validateHeaders(hdrs http.Header) string { - for k, vv := range hdrs { +-func validateHeaders(hdrs http.Header) string { +- for k, vv := range hdrs { - if !httpguts.ValidHeaderFieldName(k) { -+ if !httpguts.ValidHeaderFieldName(k) && k != ":protocol" { - return fmt.Sprintf("name %q", k) - } - for _, v := range vv { -@@ -1961,6 +2084,10 @@ func validateHeaders(hdrs http.Header) string { - - var errNilRequestURL = errors.New("http2: Request.URI is nil") - -+func isNormalConnect(req *http.Request) bool { -+ return req.Method == "CONNECT" && req.Header.Get(":protocol") == "" -+} -+ +- return fmt.Sprintf("name %q", k) +- } +- for _, v := range vv { +- if !httpguts.ValidHeaderFieldValue(v) { +- // Don't include the value in the error, +- // because it may be sensitive. +- return fmt.Sprintf("value for header %q", k) +- } +- } +- } +- return "" +-} +- +-var errNilRequestURL = errors.New("http2: Request.URI is nil") +- +-// requires cc.wmu be held. +-func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trailers string, contentLength int64) ([]byte, error) { +- cc.hbuf.Reset() +- if req.URL == nil { +- return nil, errNilRequestURL +- } +- +- host := req.Host +- if host == "" { +- host = req.URL.Host +- } +- host, err := httpguts.PunycodeHostPort(host) +- if err != nil { +- return nil, err +- } +- if !httpguts.ValidHostHeader(host) { +- return nil, errors.New("http2: invalid Host header") +- } +- +- var path string +- if req.Method != "CONNECT" { +- path = req.URL.RequestURI() +- if !validPseudoPath(path) { +- orig := path +- path = strings.TrimPrefix(path, req.URL.Scheme+"://"+host) +- if !validPseudoPath(path) { +- if req.URL.Opaque != "" { +- return nil, fmt.Errorf("invalid request :path %q from URL.Opaque = %q", orig, req.URL.Opaque) +- } else { +- return nil, fmt.Errorf("invalid request :path %q", orig) +- } +- } +- } +- } +- +- // Check for any invalid headers+trailers and return an error before we +- // potentially pollute our hpack state. (We want to be able to +- // continue to reuse the hpack encoder for future requests) +- if err := validateHeaders(req.Header); err != "" { +- return nil, fmt.Errorf("invalid HTTP header %s", err) +- } +- if err := validateHeaders(req.Trailer); err != "" { +- return nil, fmt.Errorf("invalid HTTP trailer %s", err) +- } +- +- enumerateHeaders := func(f func(name, value string)) { +- // 8.1.2.3 Request Pseudo-Header Fields +- // The :path pseudo-header field includes the path and query parts of the +- // target URI (the path-absolute production and optionally a '?' character +- // followed by the query production, see Sections 3.3 and 3.4 of +- // [RFC3986]). +- f(":authority", host) +- m := req.Method +- if m == "" { +- m = http.MethodGet +- } +- f(":method", m) +- if req.Method != "CONNECT" { +- f(":path", path) +- f(":scheme", req.URL.Scheme) +- } +- if trailers != "" { +- f("trailer", trailers) +- } +- +- var didUA bool +- for k, vv := range req.Header { +- if asciiEqualFold(k, "host") || asciiEqualFold(k, "content-length") { +- // Host is :authority, already sent. +- // Content-Length is automatic, set below. +- continue +- } else if asciiEqualFold(k, "connection") || +- asciiEqualFold(k, "proxy-connection") || +- asciiEqualFold(k, "transfer-encoding") || +- asciiEqualFold(k, "upgrade") || +- asciiEqualFold(k, "keep-alive") { +- // Per 8.1.2.2 Connection-Specific Header +- // Fields, don't send connection-specific +- // fields. We have already checked if any +- // are error-worthy so just ignore the rest. +- continue +- } else if asciiEqualFold(k, "user-agent") { +- // Match Go's http1 behavior: at most one +- // User-Agent. If set to nil or empty string, +- // then omit it. Otherwise if not mentioned, +- // include the default (below). +- didUA = true +- if len(vv) < 1 { +- continue +- } +- vv = vv[:1] +- if vv[0] == "" { +- continue +- } +- } else if asciiEqualFold(k, "cookie") { +- // Per 8.1.2.5 To allow for better compression efficiency, the +- // Cookie header field MAY be split into separate header fields, +- // each with one or more cookie-pairs. +- for _, v := range vv { +- for { +- p := strings.IndexByte(v, ';') +- if p < 0 { +- break +- } +- f("cookie", v[:p]) +- p++ +- // strip space after semicolon if any. +- for p+1 <= len(v) && v[p] == ' ' { +- p++ +- } +- v = v[p:] +- } +- if len(v) > 0 { +- f("cookie", v) +- } +- } +- continue +- } +- +- for _, v := range vv { +- f(k, v) +- } +- } +- if shouldSendReqContentLength(req.Method, contentLength) { +- f("content-length", strconv.FormatInt(contentLength, 10)) +- } +- if addGzipHeader { +- f("accept-encoding", "gzip") +- } +- if !didUA { +- f("user-agent", defaultUserAgent) +- } +- } +- +- // Do a first pass over the headers counting bytes to ensure +- // we don't exceed cc.peerMaxHeaderListSize. This is done as a +- // separate pass before encoding the headers to prevent +- // modifying the hpack state. +- hlSize := uint64(0) +- enumerateHeaders(func(name, value string) { +- hf := hpack.HeaderField{Name: name, Value: value} +- hlSize += uint64(hf.Size()) +- }) +- +- if hlSize > cc.peerMaxHeaderListSize { +- return nil, errRequestHeaderListSize +- } +- +- trace := httptrace.ContextClientTrace(req.Context()) +- traceHeaders := traceHasWroteHeaderField(trace) +- +- // Header list size is ok. Write the headers. +- enumerateHeaders(func(name, value string) { +- name, ascii := lowerHeader(name) +- if !ascii { +- // Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header +- // field names have to be ASCII characters (just as in HTTP/1.x). +- return +- } +- cc.writeHeader(name, value) +- if traceHeaders { +- traceWroteHeaderField(trace, name, value) +- } +- }) +- +- return cc.hbuf.Bytes(), nil +-} +- +-// shouldSendReqContentLength reports whether the http2.Transport should send +-// a "content-length" request header. This logic is basically a copy of the net/http +-// transferWriter.shouldSendContentLength. +-// The contentLength is the corrected contentLength (so 0 means actually 0, not unknown). +-// -1 means unknown. +-func shouldSendReqContentLength(method string, contentLength int64) bool { +- if contentLength > 0 { +- return true +- } +- if contentLength < 0 { +- return false +- } +- // For zero bodies, whether we send a content-length depends on the method. +- // It also kinda doesn't matter for http2 either way, with END_STREAM. +- switch method { +- case "POST", "PUT", "PATCH": +- return true +- default: +- return false +- } +-} +- // requires cc.wmu be held. - func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trailers string, contentLength int64) ([]byte, error) { + func (cc *ClientConn) encodeTrailers(trailer http.Header) ([]byte, error) { cc.hbuf.Reset() -@@ -1981,7 +2108,7 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail +@@ -2167,7 +2044,7 @@ func (cc *ClientConn) encodeTrailers(trailer http.Header) ([]byte, error) { } - var path string -- if req.Method != "CONNECT" { -+ if !isNormalConnect(req) { - path = req.URL.RequestURI() - if !validPseudoPath(path) { - orig := path -@@ -2018,7 +2145,7 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail - m = http.MethodGet - } - f(":method", m) -- if req.Method != "CONNECT" { -+ if !isNormalConnect(req) { - f(":path", path) - f(":scheme", req.URL.Scheme) - } -@@ -2199,7 +2326,7 @@ type resAndError struct { + for k, vv := range trailer { +- lowKey, ascii := lowerHeader(k) ++ lowKey, ascii := httpcommon.LowerHeader(k) + if !ascii { + // Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header + // field names have to be ASCII characters (just as in HTTP/1.x). +@@ -2199,7 +2076,7 @@ type resAndError struct { func (cc *ClientConn) addStreamLocked(cs *clientStream) { cs.flow.add(int32(cc.initialWindowSize)) cs.flow.setConnFlow(&cc.flow) @@ -20288,7 +21177,7 @@ index 61f511f97..090d0e1bd 100644 cs.ID = cc.nextStreamID cc.nextStreamID += 2 cc.streams[cs.ID] = cs -@@ -2215,10 +2342,10 @@ func (cc *ClientConn) forgetStreamID(id uint32) { +@@ -2215,10 +2092,10 @@ func (cc *ClientConn) forgetStreamID(id uint32) { if len(cc.streams) != slen-1 { panic("forgetting unknown stream id") } @@ -20301,7 +21190,7 @@ index 61f511f97..090d0e1bd 100644 } // Wake up writeRequestBody via clientStream.awaitFlowControl and // wake up RoundTrip if there is a pending request. -@@ -2278,7 +2405,6 @@ func isEOFOrNetReadError(err error) bool { +@@ -2278,7 +2155,6 @@ func isEOFOrNetReadError(err error) bool { func (rl *clientConnReadLoop) cleanup() { cc := rl.cc @@ -20309,7 +21198,7 @@ index 61f511f97..090d0e1bd 100644 defer cc.closeConn() defer close(cc.readerDone) -@@ -2302,6 +2428,24 @@ func (rl *clientConnReadLoop) cleanup() { +@@ -2302,6 +2178,27 @@ func (rl *clientConnReadLoop) cleanup() { } cc.closed = true @@ -20319,9 +21208,12 @@ index 61f511f97..090d0e1bd 100644 + // This avoids a situation where new connections are constantly created, + // added to the pool, fail, and are removed from the pool, without any error + // being surfaced to the user. -+ const unusedWaitTime = 5 * time.Second ++ unusedWaitTime := 5 * time.Second ++ if cc.idleTimeout > 0 && unusedWaitTime > cc.idleTimeout { ++ unusedWaitTime = cc.idleTimeout ++ } + idleTime := cc.t.now().Sub(cc.lastActive) -+ if atomic.LoadUint32(&cc.atomicReused) == 0 && idleTime < unusedWaitTime { ++ if atomic.LoadUint32(&cc.atomicReused) == 0 && idleTime < unusedWaitTime && !cc.closedOnIdle { + cc.idleTimer = cc.t.afterFunc(unusedWaitTime-idleTime, func() { + cc.t.connPool().MarkDead(cc) + }) @@ -20334,7 +21226,21 @@ index 61f511f97..090d0e1bd 100644 for _, cs := range cc.streams { select { case <-cs.peerClosed: -@@ -2345,7 +2489,7 @@ func (cc *ClientConn) countReadFrameError(err error) { +@@ -2313,6 +2210,13 @@ func (rl *clientConnReadLoop) cleanup() { + } + cc.cond.Broadcast() + cc.mu.Unlock() ++ ++ if !cc.seenSettings { ++ // If we have a pending request that wants extended CONNECT, ++ // let it continue and fail with the connection error. ++ cc.extendedConnectAllowed = true ++ close(cc.seenSettingsChan) ++ } + } + + // countReadFrameError calls Transport.CountError with a string +@@ -2345,7 +2249,7 @@ func (cc *ClientConn) countReadFrameError(err error) { func (rl *clientConnReadLoop) run() error { cc := rl.cc gotSettings := false @@ -20343,7 +21249,7 @@ index 61f511f97..090d0e1bd 100644 var t timer if readIdleTimeout != 0 { t = cc.t.afterFunc(readIdleTimeout, cc.healthCheck) -@@ -2359,7 +2503,7 @@ func (rl *clientConnReadLoop) run() error { +@@ -2359,7 +2263,7 @@ func (rl *clientConnReadLoop) run() error { cc.vlogf("http2: Transport readFrame error on conn %p: (%T) %v", cc, err, err) } if se, ok := err.(StreamError); ok { @@ -20352,16 +21258,7 @@ index 61f511f97..090d0e1bd 100644 if se.Cause == nil { se.Cause = cc.fr.errDetail } -@@ -2405,13 +2549,16 @@ func (rl *clientConnReadLoop) run() error { - if VerboseLogs { - cc.vlogf("http2: Transport conn %p received error from processing frame %v: %v", cc, summarizeFrame(f), err) - } -+ if !cc.seenSettings { -+ close(cc.seenSettingsChan) -+ } - return err - } - } +@@ -2411,7 +2315,7 @@ func (rl *clientConnReadLoop) run() error { } func (rl *clientConnReadLoop) processHeaders(f *MetaHeadersFrame) error { @@ -20370,7 +21267,25 @@ index 61f511f97..090d0e1bd 100644 if cs == nil { // We'd get here if we canceled a request while the // server had its response still in flight. So if this -@@ -2529,15 +2676,34 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra +@@ -2499,7 +2403,7 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra + Status: status + " " + http.StatusText(statusCode), + } + for _, hf := range regularFields { +- key := canonicalHeader(hf.Name) ++ key := httpcommon.CanonicalHeader(hf.Name) + if key == "Trailer" { + t := res.Trailer + if t == nil { +@@ -2507,7 +2411,7 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra + res.Trailer = t + } + foreachHeaderElement(hf.Value, func(v string) { +- t[canonicalHeader(v)] = nil ++ t[httpcommon.CanonicalHeader(v)] = nil + }) + } else { + vv := header[key] +@@ -2529,15 +2433,34 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra if f.StreamEnded() { return nil, errors.New("1xx informational response with END_STREAM flag") } @@ -20410,7 +21325,16 @@ index 61f511f97..090d0e1bd 100644 } if statusCode == 100 { traceGot100Continue(cs.trace) -@@ -2721,7 +2887,7 @@ func (b transportResponseBody) Close() error { +@@ -2612,7 +2535,7 @@ func (rl *clientConnReadLoop) processTrailers(cs *clientStream, f *MetaHeadersFr + + trailer := make(http.Header) + for _, hf := range f.RegularFields() { +- key := canonicalHeader(hf.Name) ++ key := httpcommon.CanonicalHeader(hf.Name) + trailer[key] = append(trailer[key], hf.Value) + } + cs.trailer = trailer +@@ -2721,7 +2644,7 @@ func (b transportResponseBody) Close() error { func (rl *clientConnReadLoop) processData(f *DataFrame) error { cc := rl.cc @@ -20419,7 +21343,7 @@ index 61f511f97..090d0e1bd 100644 data := f.Data() if cs == nil { cc.mu.Lock() -@@ -2856,9 +3022,22 @@ func (rl *clientConnReadLoop) endStreamError(cs *clientStream, err error) { +@@ -2856,9 +2779,22 @@ func (rl *clientConnReadLoop) endStreamError(cs *clientStream, err error) { cs.abortStream(err) } @@ -20443,7 +21367,7 @@ index 61f511f97..090d0e1bd 100644 cs := rl.cc.streams[id] if cs != nil && !cs.readAborted { return cs -@@ -2952,6 +3131,21 @@ func (rl *clientConnReadLoop) processSettingsNoWrite(f *SettingsFrame) error { +@@ -2952,6 +2888,21 @@ func (rl *clientConnReadLoop) processSettingsNoWrite(f *SettingsFrame) error { case SettingHeaderTableSize: cc.henc.SetMaxDynamicTableSize(s.Val) cc.peerMaxHeaderTableSize = s.Val @@ -20465,7 +21389,7 @@ index 61f511f97..090d0e1bd 100644 default: cc.vlogf("Unhandled Setting: %v", s) } -@@ -2969,6 +3163,7 @@ func (rl *clientConnReadLoop) processSettingsNoWrite(f *SettingsFrame) error { +@@ -2969,6 +2920,7 @@ func (rl *clientConnReadLoop) processSettingsNoWrite(f *SettingsFrame) error { // connection can establish to our default. cc.maxConcurrentStreams = defaultMaxConcurrentStreams } @@ -20473,7 +21397,7 @@ index 61f511f97..090d0e1bd 100644 cc.seenSettings = true } -@@ -2977,7 +3172,7 @@ func (rl *clientConnReadLoop) processSettingsNoWrite(f *SettingsFrame) error { +@@ -2977,7 +2929,7 @@ func (rl *clientConnReadLoop) processSettingsNoWrite(f *SettingsFrame) error { func (rl *clientConnReadLoop) processWindowUpdate(f *WindowUpdateFrame) error { cc := rl.cc @@ -20482,7 +21406,7 @@ index 61f511f97..090d0e1bd 100644 if f.StreamID != 0 && cs == nil { return nil } -@@ -3006,7 +3201,7 @@ func (rl *clientConnReadLoop) processWindowUpdate(f *WindowUpdateFrame) error { +@@ -3006,7 +2958,7 @@ func (rl *clientConnReadLoop) processWindowUpdate(f *WindowUpdateFrame) error { } func (rl *clientConnReadLoop) processResetStream(f *RSTStreamFrame) error { @@ -20491,7 +21415,7 @@ index 61f511f97..090d0e1bd 100644 if cs == nil { // TODO: return error if server tries to RST_STREAM an idle stream return nil -@@ -3081,6 +3276,12 @@ func (rl *clientConnReadLoop) processPing(f *PingFrame) error { +@@ -3081,6 +3033,12 @@ func (rl *clientConnReadLoop) processPing(f *PingFrame) error { close(c) delete(cc.pings, f.Data) } @@ -20504,7 +21428,7 @@ index 61f511f97..090d0e1bd 100644 return nil } cc := rl.cc -@@ -3103,13 +3304,20 @@ func (rl *clientConnReadLoop) processPushPromise(f *PushPromiseFrame) error { +@@ -3103,20 +3061,27 @@ func (rl *clientConnReadLoop) processPushPromise(f *PushPromiseFrame) error { return ConnectionError(ErrCodeProtocol) } @@ -20526,74 +21450,742 @@ index 61f511f97..090d0e1bd 100644 cc.bw.Flush() cc.wmu.Unlock() } -@@ -3263,7 +3471,7 @@ func traceGotConn(req *http.Request, cc *ClientConn, reused bool) { + + var ( + errResponseHeaderListSize = errors.New("http2: response header list larger than advertised limit") +- errRequestHeaderListSize = errors.New("http2: request header list larger than peer's advertised limit") ++ errRequestHeaderListSize = httpcommon.ErrRequestHeaderListSize + ) + + func (cc *ClientConn) logf(format string, args ...interface{}) { +@@ -3263,7 +3228,7 @@ func traceGotConn(req *http.Request, cc *ClientConn, reused bool) { cc.mu.Lock() ci.WasIdle = len(cc.streams) == 0 && reused if ci.WasIdle && !cc.lastActive.IsZero() { - ci.IdleTime = time.Since(cc.lastActive) + ci.IdleTime = cc.t.timeSince(cc.lastActive) } - cc.mu.Unlock() + cc.mu.Unlock() + +@@ -3300,16 +3265,6 @@ func traceFirstResponseByte(trace *httptrace.ClientTrace) { + } + } + +-func traceHasWroteHeaderField(trace *httptrace.ClientTrace) bool { +- return trace != nil && trace.WroteHeaderField != nil +-} +- +-func traceWroteHeaderField(trace *httptrace.ClientTrace, k, v string) { +- if trace != nil && trace.WroteHeaderField != nil { +- trace.WroteHeaderField(k, []string{v}) +- } +-} +- + func traceGot1xxResponseFunc(trace *httptrace.ClientTrace) func(int, textproto.MIMEHeader) error { + if trace != nil { + return trace.Got1xxResponse +diff --git a/vendor/golang.org/x/net/http2/unencrypted.go b/vendor/golang.org/x/net/http2/unencrypted.go +new file mode 100644 +index 000000000..b2de21161 +--- /dev/null ++++ b/vendor/golang.org/x/net/http2/unencrypted.go +@@ -0,0 +1,32 @@ ++// Copyright 2024 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++package http2 ++ ++import ( ++ "crypto/tls" ++ "errors" ++ "net" ++) ++ ++const nextProtoUnencryptedHTTP2 = "unencrypted_http2" ++ ++// unencryptedNetConnFromTLSConn retrieves a net.Conn wrapped in a *tls.Conn. ++// ++// TLSNextProto functions accept a *tls.Conn. ++// ++// When passing an unencrypted HTTP/2 connection to a TLSNextProto function, ++// we pass a *tls.Conn with an underlying net.Conn containing the unencrypted connection. ++// To be extra careful about mistakes (accidentally dropping TLS encryption in a place ++// where we want it), the tls.Conn contains a net.Conn with an UnencryptedNetConn method ++// that returns the actual connection we want to use. ++func unencryptedNetConnFromTLSConn(tc *tls.Conn) (net.Conn, error) { ++ conner, ok := tc.NetConn().(interface { ++ UnencryptedNetConn() net.Conn ++ }) ++ if !ok { ++ return nil, errors.New("http2: TLS conn unexpectedly found in unencrypted handoff") ++ } ++ return conner.UnencryptedNetConn(), nil ++} +diff --git a/vendor/golang.org/x/net/http2/write.go b/vendor/golang.org/x/net/http2/write.go +index 33f61398a..fdb35b947 100644 +--- a/vendor/golang.org/x/net/http2/write.go ++++ b/vendor/golang.org/x/net/http2/write.go +@@ -13,6 +13,7 @@ import ( + + "golang.org/x/net/http/httpguts" + "golang.org/x/net/http2/hpack" ++ "golang.org/x/net/internal/httpcommon" + ) + + // writeFramer is implemented by any type that is used to write frames. +@@ -131,6 +132,16 @@ func (se StreamError) writeFrame(ctx writeContext) error { + + func (se StreamError) staysWithinBuffer(max int) bool { return frameHeaderLen+4 <= max } + ++type writePing struct { ++ data [8]byte ++} ++ ++func (w writePing) writeFrame(ctx writeContext) error { ++ return ctx.Framer().WritePing(false, w.data) ++} ++ ++func (w writePing) staysWithinBuffer(max int) bool { return frameHeaderLen+len(w.data) <= max } ++ + type writePingAck struct{ pf *PingFrame } + + func (w writePingAck) writeFrame(ctx writeContext) error { +@@ -341,7 +352,7 @@ func encodeHeaders(enc *hpack.Encoder, h http.Header, keys []string) { + } + for _, k := range keys { + vv := h[k] +- k, ascii := lowerHeader(k) ++ k, ascii := httpcommon.LowerHeader(k) + if !ascii { + // Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header + // field names have to be ASCII characters (just as in HTTP/1.x). +diff --git a/vendor/golang.org/x/net/internal/httpcommon/ascii.go b/vendor/golang.org/x/net/internal/httpcommon/ascii.go +new file mode 100644 +index 000000000..ed14da5af +--- /dev/null ++++ b/vendor/golang.org/x/net/internal/httpcommon/ascii.go +@@ -0,0 +1,53 @@ ++// Copyright 2025 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++package httpcommon ++ ++import "strings" ++ ++// The HTTP protocols are defined in terms of ASCII, not Unicode. This file ++// contains helper functions which may use Unicode-aware functions which would ++// otherwise be unsafe and could introduce vulnerabilities if used improperly. ++ ++// asciiEqualFold is strings.EqualFold, ASCII only. It reports whether s and t ++// are equal, ASCII-case-insensitively. ++func asciiEqualFold(s, t string) bool { ++ if len(s) != len(t) { ++ return false ++ } ++ for i := 0; i < len(s); i++ { ++ if lower(s[i]) != lower(t[i]) { ++ return false ++ } ++ } ++ return true ++} ++ ++// lower returns the ASCII lowercase version of b. ++func lower(b byte) byte { ++ if 'A' <= b && b <= 'Z' { ++ return b + ('a' - 'A') ++ } ++ return b ++} ++ ++// isASCIIPrint returns whether s is ASCII and printable according to ++// https://tools.ietf.org/html/rfc20#section-4.2. ++func isASCIIPrint(s string) bool { ++ for i := 0; i < len(s); i++ { ++ if s[i] < ' ' || s[i] > '~' { ++ return false ++ } ++ } ++ return true ++} ++ ++// asciiToLower returns the lowercase version of s if s is ASCII and printable, ++// and whether or not it was. ++func asciiToLower(s string) (lower string, ok bool) { ++ if !isASCIIPrint(s) { ++ return "", false ++ } ++ return strings.ToLower(s), true ++} +diff --git a/vendor/golang.org/x/net/http2/headermap.go b/vendor/golang.org/x/net/internal/httpcommon/headermap.go +similarity index 74% +rename from vendor/golang.org/x/net/http2/headermap.go +rename to vendor/golang.org/x/net/internal/httpcommon/headermap.go +index 149b3dd20..92483d8e4 100644 +--- a/vendor/golang.org/x/net/http2/headermap.go ++++ b/vendor/golang.org/x/net/internal/httpcommon/headermap.go +@@ -1,11 +1,11 @@ +-// Copyright 2014 The Go Authors. All rights reserved. ++// Copyright 2025 The Go Authors. All rights reserved. + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-package http2 ++package httpcommon + + import ( +- "net/http" ++ "net/textproto" + "sync" + ) + +@@ -82,13 +82,15 @@ func buildCommonHeaderMaps() { + commonLowerHeader = make(map[string]string, len(common)) + commonCanonHeader = make(map[string]string, len(common)) + for _, v := range common { +- chk := http.CanonicalHeaderKey(v) ++ chk := textproto.CanonicalMIMEHeaderKey(v) + commonLowerHeader[chk] = v + commonCanonHeader[v] = chk + } + } -diff --git a/vendor/golang.org/x/net/http2/unencrypted.go b/vendor/golang.org/x/net/http2/unencrypted.go +-func lowerHeader(v string) (lower string, ascii bool) { ++// LowerHeader returns the lowercase form of a header name, ++// used on the wire for HTTP/2 and HTTP/3 requests. ++func LowerHeader(v string) (lower string, ascii bool) { + buildCommonHeaderMapsOnce() + if s, ok := commonLowerHeader[v]; ok { + return s, true +@@ -96,10 +98,18 @@ func lowerHeader(v string) (lower string, ascii bool) { + return asciiToLower(v) + } + +-func canonicalHeader(v string) string { ++// CanonicalHeader canonicalizes a header name. (For example, "host" becomes "Host".) ++func CanonicalHeader(v string) string { + buildCommonHeaderMapsOnce() + if s, ok := commonCanonHeader[v]; ok { + return s + } +- return http.CanonicalHeaderKey(v) ++ return textproto.CanonicalMIMEHeaderKey(v) ++} ++ ++// CachedCanonicalHeader returns the canonical form of a well-known header name. ++func CachedCanonicalHeader(v string) (string, bool) { ++ buildCommonHeaderMapsOnce() ++ s, ok := commonCanonHeader[v] ++ return s, ok + } +diff --git a/vendor/golang.org/x/net/internal/httpcommon/request.go b/vendor/golang.org/x/net/internal/httpcommon/request.go new file mode 100644 -index 000000000..b2de21161 +index 000000000..4b7055317 --- /dev/null -+++ b/vendor/golang.org/x/net/http2/unencrypted.go -@@ -0,0 +1,32 @@ -+// Copyright 2024 The Go Authors. All rights reserved. ++++ b/vendor/golang.org/x/net/internal/httpcommon/request.go +@@ -0,0 +1,467 @@ ++// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + -+package http2 ++package httpcommon + +import ( -+ "crypto/tls" ++ "context" + "errors" -+ "net" ++ "fmt" ++ "net/http/httptrace" ++ "net/textproto" ++ "net/url" ++ "sort" ++ "strconv" ++ "strings" ++ ++ "golang.org/x/net/http/httpguts" ++ "golang.org/x/net/http2/hpack" +) + -+const nextProtoUnencryptedHTTP2 = "unencrypted_http2" ++var ( ++ ErrRequestHeaderListSize = errors.New("request header list larger than peer's advertised limit") ++) + -+// unencryptedNetConnFromTLSConn retrieves a net.Conn wrapped in a *tls.Conn. ++// Request is a subset of http.Request. ++// It'd be simpler to pass an *http.Request, of course, but we can't depend on net/http ++// without creating a dependency cycle. ++type Request struct { ++ URL *url.URL ++ Method string ++ Host string ++ Header map[string][]string ++ Trailer map[string][]string ++ ActualContentLength int64 // 0 means 0, -1 means unknown ++} ++ ++// EncodeHeadersParam is parameters to EncodeHeaders. ++type EncodeHeadersParam struct { ++ Request Request ++ ++ // AddGzipHeader indicates that an "accept-encoding: gzip" header should be ++ // added to the request. ++ AddGzipHeader bool ++ ++ // PeerMaxHeaderListSize, when non-zero, is the peer's MAX_HEADER_LIST_SIZE setting. ++ PeerMaxHeaderListSize uint64 ++ ++ // DefaultUserAgent is the User-Agent header to send when the request ++ // neither contains a User-Agent nor disables it. ++ DefaultUserAgent string ++} ++ ++// EncodeHeadersParam is the result of EncodeHeaders. ++type EncodeHeadersResult struct { ++ HasBody bool ++ HasTrailers bool ++} ++ ++// EncodeHeaders constructs request headers common to HTTP/2 and HTTP/3. ++// It validates a request and calls headerf with each pseudo-header and header ++// for the request. ++// The headerf function is called with the validated, canonicalized header name. ++func EncodeHeaders(ctx context.Context, param EncodeHeadersParam, headerf func(name, value string)) (res EncodeHeadersResult, _ error) { ++ req := param.Request ++ ++ // Check for invalid connection-level headers. ++ if err := checkConnHeaders(req.Header); err != nil { ++ return res, err ++ } ++ ++ if req.URL == nil { ++ return res, errors.New("Request.URL is nil") ++ } ++ ++ host := req.Host ++ if host == "" { ++ host = req.URL.Host ++ } ++ host, err := httpguts.PunycodeHostPort(host) ++ if err != nil { ++ return res, err ++ } ++ if !httpguts.ValidHostHeader(host) { ++ return res, errors.New("invalid Host header") ++ } ++ ++ // isNormalConnect is true if this is a non-extended CONNECT request. ++ isNormalConnect := false ++ var protocol string ++ if vv := req.Header[":protocol"]; len(vv) > 0 { ++ protocol = vv[0] ++ } ++ if req.Method == "CONNECT" && protocol == "" { ++ isNormalConnect = true ++ } else if protocol != "" && req.Method != "CONNECT" { ++ return res, errors.New("invalid :protocol header in non-CONNECT request") ++ } ++ ++ // Validate the path, except for non-extended CONNECT requests which have no path. ++ var path string ++ if !isNormalConnect { ++ path = req.URL.RequestURI() ++ if !validPseudoPath(path) { ++ orig := path ++ path = strings.TrimPrefix(path, req.URL.Scheme+"://"+host) ++ if !validPseudoPath(path) { ++ if req.URL.Opaque != "" { ++ return res, fmt.Errorf("invalid request :path %q from URL.Opaque = %q", orig, req.URL.Opaque) ++ } else { ++ return res, fmt.Errorf("invalid request :path %q", orig) ++ } ++ } ++ } ++ } ++ ++ // Check for any invalid headers+trailers and return an error before we ++ // potentially pollute our hpack state. (We want to be able to ++ // continue to reuse the hpack encoder for future requests) ++ if err := validateHeaders(req.Header); err != "" { ++ return res, fmt.Errorf("invalid HTTP header %s", err) ++ } ++ if err := validateHeaders(req.Trailer); err != "" { ++ return res, fmt.Errorf("invalid HTTP trailer %s", err) ++ } ++ ++ trailers, err := commaSeparatedTrailers(req.Trailer) ++ if err != nil { ++ return res, err ++ } ++ ++ enumerateHeaders := func(f func(name, value string)) { ++ // 8.1.2.3 Request Pseudo-Header Fields ++ // The :path pseudo-header field includes the path and query parts of the ++ // target URI (the path-absolute production and optionally a '?' character ++ // followed by the query production, see Sections 3.3 and 3.4 of ++ // [RFC3986]). ++ f(":authority", host) ++ m := req.Method ++ if m == "" { ++ m = "GET" ++ } ++ f(":method", m) ++ if !isNormalConnect { ++ f(":path", path) ++ f(":scheme", req.URL.Scheme) ++ } ++ if protocol != "" { ++ f(":protocol", protocol) ++ } ++ if trailers != "" { ++ f("trailer", trailers) ++ } ++ ++ var didUA bool ++ for k, vv := range req.Header { ++ if asciiEqualFold(k, "host") || asciiEqualFold(k, "content-length") { ++ // Host is :authority, already sent. ++ // Content-Length is automatic, set below. ++ continue ++ } else if asciiEqualFold(k, "connection") || ++ asciiEqualFold(k, "proxy-connection") || ++ asciiEqualFold(k, "transfer-encoding") || ++ asciiEqualFold(k, "upgrade") || ++ asciiEqualFold(k, "keep-alive") { ++ // Per 8.1.2.2 Connection-Specific Header ++ // Fields, don't send connection-specific ++ // fields. We have already checked if any ++ // are error-worthy so just ignore the rest. ++ continue ++ } else if asciiEqualFold(k, "user-agent") { ++ // Match Go's http1 behavior: at most one ++ // User-Agent. If set to nil or empty string, ++ // then omit it. Otherwise if not mentioned, ++ // include the default (below). ++ didUA = true ++ if len(vv) < 1 { ++ continue ++ } ++ vv = vv[:1] ++ if vv[0] == "" { ++ continue ++ } ++ } else if asciiEqualFold(k, "cookie") { ++ // Per 8.1.2.5 To allow for better compression efficiency, the ++ // Cookie header field MAY be split into separate header fields, ++ // each with one or more cookie-pairs. ++ for _, v := range vv { ++ for { ++ p := strings.IndexByte(v, ';') ++ if p < 0 { ++ break ++ } ++ f("cookie", v[:p]) ++ p++ ++ // strip space after semicolon if any. ++ for p+1 <= len(v) && v[p] == ' ' { ++ p++ ++ } ++ v = v[p:] ++ } ++ if len(v) > 0 { ++ f("cookie", v) ++ } ++ } ++ continue ++ } else if k == ":protocol" { ++ // :protocol pseudo-header was already sent above. ++ continue ++ } ++ ++ for _, v := range vv { ++ f(k, v) ++ } ++ } ++ if shouldSendReqContentLength(req.Method, req.ActualContentLength) { ++ f("content-length", strconv.FormatInt(req.ActualContentLength, 10)) ++ } ++ if param.AddGzipHeader { ++ f("accept-encoding", "gzip") ++ } ++ if !didUA { ++ f("user-agent", param.DefaultUserAgent) ++ } ++ } ++ ++ // Do a first pass over the headers counting bytes to ensure ++ // we don't exceed cc.peerMaxHeaderListSize. This is done as a ++ // separate pass before encoding the headers to prevent ++ // modifying the hpack state. ++ if param.PeerMaxHeaderListSize > 0 { ++ hlSize := uint64(0) ++ enumerateHeaders(func(name, value string) { ++ hf := hpack.HeaderField{Name: name, Value: value} ++ hlSize += uint64(hf.Size()) ++ }) ++ ++ if hlSize > param.PeerMaxHeaderListSize { ++ return res, ErrRequestHeaderListSize ++ } ++ } ++ ++ trace := httptrace.ContextClientTrace(ctx) ++ ++ // Header list size is ok. Write the headers. ++ enumerateHeaders(func(name, value string) { ++ name, ascii := LowerHeader(name) ++ if !ascii { ++ // Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header ++ // field names have to be ASCII characters (just as in HTTP/1.x). ++ return ++ } ++ ++ headerf(name, value) ++ ++ if trace != nil && trace.WroteHeaderField != nil { ++ trace.WroteHeaderField(name, []string{value}) ++ } ++ }) ++ ++ res.HasBody = req.ActualContentLength != 0 ++ res.HasTrailers = trailers != "" ++ return res, nil ++} ++ ++// IsRequestGzip reports whether we should add an Accept-Encoding: gzip header ++// for a request. ++func IsRequestGzip(method string, header map[string][]string, disableCompression bool) bool { ++ // TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere? ++ if !disableCompression && ++ len(header["Accept-Encoding"]) == 0 && ++ len(header["Range"]) == 0 && ++ method != "HEAD" { ++ // Request gzip only, not deflate. Deflate is ambiguous and ++ // not as universally supported anyway. ++ // See: https://zlib.net/zlib_faq.html#faq39 ++ // ++ // Note that we don't request this for HEAD requests, ++ // due to a bug in nginx: ++ // http://trac.nginx.org/nginx/ticket/358 ++ // https://golang.org/issue/5522 ++ // ++ // We don't request gzip if the request is for a range, since ++ // auto-decoding a portion of a gzipped document will just fail ++ // anyway. See https://golang.org/issue/8923 ++ return true ++ } ++ return false ++} ++ ++// checkConnHeaders checks whether req has any invalid connection-level headers. +// -+// TLSNextProto functions accept a *tls.Conn. ++// https://www.rfc-editor.org/rfc/rfc9114.html#section-4.2-3 ++// https://www.rfc-editor.org/rfc/rfc9113.html#section-8.2.2-1 +// -+// When passing an unencrypted HTTP/2 connection to a TLSNextProto function, -+// we pass a *tls.Conn with an underlying net.Conn containing the unencrypted connection. -+// To be extra careful about mistakes (accidentally dropping TLS encryption in a place -+// where we want it), the tls.Conn contains a net.Conn with an UnencryptedNetConn method -+// that returns the actual connection we want to use. -+func unencryptedNetConnFromTLSConn(tc *tls.Conn) (net.Conn, error) { -+ conner, ok := tc.NetConn().(interface { -+ UnencryptedNetConn() net.Conn -+ }) -+ if !ok { -+ return nil, errors.New("http2: TLS conn unexpectedly found in unencrypted handoff") ++// Certain headers are special-cased as okay but not transmitted later. ++// For example, we allow "Transfer-Encoding: chunked", but drop the header when encoding. ++func checkConnHeaders(h map[string][]string) error { ++ if vv := h["Upgrade"]; len(vv) > 0 && (vv[0] != "" && vv[0] != "chunked") { ++ return fmt.Errorf("invalid Upgrade request header: %q", vv) + } -+ return conner.UnencryptedNetConn(), nil ++ if vv := h["Transfer-Encoding"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && vv[0] != "chunked") { ++ return fmt.Errorf("invalid Transfer-Encoding request header: %q", vv) ++ } ++ if vv := h["Connection"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && !asciiEqualFold(vv[0], "close") && !asciiEqualFold(vv[0], "keep-alive")) { ++ return fmt.Errorf("invalid Connection request header: %q", vv) ++ } ++ return nil +} -diff --git a/vendor/golang.org/x/net/http2/write.go b/vendor/golang.org/x/net/http2/write.go -index 33f61398a..6ff6bee7e 100644 ---- a/vendor/golang.org/x/net/http2/write.go -+++ b/vendor/golang.org/x/net/http2/write.go -@@ -131,6 +131,16 @@ func (se StreamError) writeFrame(ctx writeContext) error { - - func (se StreamError) staysWithinBuffer(max int) bool { return frameHeaderLen+4 <= max } - -+type writePing struct { -+ data [8]byte ++ ++func commaSeparatedTrailers(trailer map[string][]string) (string, error) { ++ keys := make([]string, 0, len(trailer)) ++ for k := range trailer { ++ k = CanonicalHeader(k) ++ switch k { ++ case "Transfer-Encoding", "Trailer", "Content-Length": ++ return "", fmt.Errorf("invalid Trailer key %q", k) ++ } ++ keys = append(keys, k) ++ } ++ if len(keys) > 0 { ++ sort.Strings(keys) ++ return strings.Join(keys, ","), nil ++ } ++ return "", nil +} + -+func (w writePing) writeFrame(ctx writeContext) error { -+ return ctx.Framer().WritePing(false, w.data) ++// validPseudoPath reports whether v is a valid :path pseudo-header ++// value. It must be either: ++// ++// - a non-empty string starting with '/' ++// - the string '*', for OPTIONS requests. ++// ++// For now this is only used a quick check for deciding when to clean ++// up Opaque URLs before sending requests from the Transport. ++// See golang.org/issue/16847 ++// ++// We used to enforce that the path also didn't start with "//", but ++// Google's GFE accepts such paths and Chrome sends them, so ignore ++// that part of the spec. See golang.org/issue/19103. ++func validPseudoPath(v string) bool { ++ return (len(v) > 0 && v[0] == '/') || v == "*" +} + -+func (w writePing) staysWithinBuffer(max int) bool { return frameHeaderLen+len(w.data) <= max } ++func validateHeaders(hdrs map[string][]string) string { ++ for k, vv := range hdrs { ++ if !httpguts.ValidHeaderFieldName(k) && k != ":protocol" { ++ return fmt.Sprintf("name %q", k) ++ } ++ for _, v := range vv { ++ if !httpguts.ValidHeaderFieldValue(v) { ++ // Don't include the value in the error, ++ // because it may be sensitive. ++ return fmt.Sprintf("value for header %q", k) ++ } ++ } ++ } ++ return "" ++} + - type writePingAck struct{ pf *PingFrame } ++// shouldSendReqContentLength reports whether we should send ++// a "content-length" request header. This logic is basically a copy of the net/http ++// transferWriter.shouldSendContentLength. ++// The contentLength is the corrected contentLength (so 0 means actually 0, not unknown). ++// -1 means unknown. ++func shouldSendReqContentLength(method string, contentLength int64) bool { ++ if contentLength > 0 { ++ return true ++ } ++ if contentLength < 0 { ++ return false ++ } ++ // For zero bodies, whether we send a content-length depends on the method. ++ // It also kinda doesn't matter for http2 either way, with END_STREAM. ++ switch method { ++ case "POST", "PUT", "PATCH": ++ return true ++ default: ++ return false ++ } ++} ++ ++// ServerRequestParam is parameters to NewServerRequest. ++type ServerRequestParam struct { ++ Method string ++ Scheme, Authority, Path string ++ Protocol string ++ Header map[string][]string ++} ++ ++// ServerRequestResult is the result of NewServerRequest. ++type ServerRequestResult struct { ++ // Various http.Request fields. ++ URL *url.URL ++ RequestURI string ++ Trailer map[string][]string ++ ++ NeedsContinue bool // client provided an "Expect: 100-continue" header ++ ++ // If the request should be rejected, this is a short string suitable for passing ++ // to the http2 package's CountError function. ++ // It might be a bit odd to return errors this way rather than returing an error, ++ // but this ensures we don't forget to include a CountError reason. ++ InvalidReason string ++} ++ ++func NewServerRequest(rp ServerRequestParam) ServerRequestResult { ++ needsContinue := httpguts.HeaderValuesContainsToken(rp.Header["Expect"], "100-continue") ++ if needsContinue { ++ delete(rp.Header, "Expect") ++ } ++ // Merge Cookie headers into one "; "-delimited value. ++ if cookies := rp.Header["Cookie"]; len(cookies) > 1 { ++ rp.Header["Cookie"] = []string{strings.Join(cookies, "; ")} ++ } ++ ++ // Setup Trailers ++ var trailer map[string][]string ++ for _, v := range rp.Header["Trailer"] { ++ for _, key := range strings.Split(v, ",") { ++ key = textproto.CanonicalMIMEHeaderKey(textproto.TrimString(key)) ++ switch key { ++ case "Transfer-Encoding", "Trailer", "Content-Length": ++ // Bogus. (copy of http1 rules) ++ // Ignore. ++ default: ++ if trailer == nil { ++ trailer = make(map[string][]string) ++ } ++ trailer[key] = nil ++ } ++ } ++ } ++ delete(rp.Header, "Trailer") ++ ++ // "':authority' MUST NOT include the deprecated userinfo subcomponent ++ // for "http" or "https" schemed URIs." ++ // https://www.rfc-editor.org/rfc/rfc9113.html#section-8.3.1-2.3.8 ++ if strings.IndexByte(rp.Authority, '@') != -1 && (rp.Scheme == "http" || rp.Scheme == "https") { ++ return ServerRequestResult{ ++ InvalidReason: "userinfo_in_authority", ++ } ++ } ++ ++ var url_ *url.URL ++ var requestURI string ++ if rp.Method == "CONNECT" && rp.Protocol == "" { ++ url_ = &url.URL{Host: rp.Authority} ++ requestURI = rp.Authority // mimic HTTP/1 server behavior ++ } else { ++ var err error ++ url_, err = url.ParseRequestURI(rp.Path) ++ if err != nil { ++ return ServerRequestResult{ ++ InvalidReason: "bad_path", ++ } ++ } ++ requestURI = rp.Path ++ } ++ ++ return ServerRequestResult{ ++ URL: url_, ++ NeedsContinue: needsContinue, ++ RequestURI: requestURI, ++ Trailer: trailer, ++ } ++} +diff --git a/vendor/golang.org/x/net/proxy/per_host.go b/vendor/golang.org/x/net/proxy/per_host.go +index d7d4b8b6e..32bdf435e 100644 +--- a/vendor/golang.org/x/net/proxy/per_host.go ++++ b/vendor/golang.org/x/net/proxy/per_host.go +@@ -7,6 +7,7 @@ package proxy + import ( + "context" + "net" ++ "net/netip" + "strings" + ) - func (w writePingAck) writeFrame(ctx writeContext) error { +@@ -57,7 +58,8 @@ func (p *PerHost) DialContext(ctx context.Context, network, addr string) (c net. + } + + func (p *PerHost) dialerForRequest(host string) Dialer { +- if ip := net.ParseIP(host); ip != nil { ++ if nip, err := netip.ParseAddr(host); err == nil { ++ ip := net.IP(nip.AsSlice()) + for _, net := range p.bypassNetworks { + if net.Contains(ip) { + return p.bypass +@@ -108,8 +110,8 @@ func (p *PerHost) AddFromString(s string) { + } + continue + } +- if ip := net.ParseIP(host); ip != nil { +- p.AddIP(ip) ++ if nip, err := netip.ParseAddr(host); err == nil { ++ p.AddIP(net.IP(nip.AsSlice())) + continue + } + if strings.HasPrefix(host, "*.") { diff --git a/vendor/golang.org/x/net/websocket/websocket.go b/vendor/golang.org/x/net/websocket/websocket.go index 923a5780e..ac76165ce 100644 --- a/vendor/golang.org/x/net/websocket/websocket.go @@ -20631,10 +22223,20 @@ index 000000000..ec2acfe54 +GLOBL ·libc_sysctlbyname_trampoline_addr(SB), RODATA, $8 +DATA ·libc_sysctlbyname_trampoline_addr(SB)/8, $libc_sysctlbyname_trampoline<>(SB) diff --git a/vendor/golang.org/x/sys/cpu/cpu.go b/vendor/golang.org/x/sys/cpu/cpu.go -index ec07aab05..02609d5b2 100644 +index ec07aab05..9c105f23a 100644 --- a/vendor/golang.org/x/sys/cpu/cpu.go +++ b/vendor/golang.org/x/sys/cpu/cpu.go -@@ -201,6 +201,25 @@ var S390X struct { +@@ -72,6 +72,9 @@ var X86 struct { + HasSSSE3 bool // Supplemental streaming SIMD extension 3 + HasSSE41 bool // Streaming SIMD extension 4 and 4.1 + HasSSE42 bool // Streaming SIMD extension 4 and 4.2 ++ HasAVXIFMA bool // Advanced vector extension Integer Fused Multiply Add ++ HasAVXVNNI bool // Advanced vector extension Vector Neural Network Instructions ++ HasAVXVNNIInt8 bool // Advanced vector extension Vector Neural Network Int8 instructions + _ CacheLinePad + } + +@@ -201,6 +204,25 @@ var S390X struct { _ CacheLinePad } @@ -20979,10 +22581,20 @@ index 7f0c79c00..aca3199c9 100644 + } +} diff --git a/vendor/golang.org/x/sys/cpu/cpu_x86.go b/vendor/golang.org/x/sys/cpu/cpu_x86.go -index c29f5e4c5..600a68078 100644 +index c29f5e4c5..1e642f330 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_x86.go +++ b/vendor/golang.org/x/sys/cpu/cpu_x86.go -@@ -92,10 +92,8 @@ func archInit() { +@@ -53,6 +53,9 @@ func initOptions() { + {Name: "sse41", Feature: &X86.HasSSE41}, + {Name: "sse42", Feature: &X86.HasSSE42}, + {Name: "ssse3", Feature: &X86.HasSSSE3}, ++ {Name: "avxifma", Feature: &X86.HasAVXIFMA}, ++ {Name: "avxvnni", Feature: &X86.HasAVXVNNI}, ++ {Name: "avxvnniint8", Feature: &X86.HasAVXVNNIInt8}, + + // These capabilities should always be enabled on amd64: + {Name: "sse2", Feature: &X86.HasSSE2, Required: runtime.GOARCH == "amd64"}, +@@ -92,10 +95,8 @@ func archInit() { osSupportsAVX = isSet(1, eax) && isSet(2, eax) if runtime.GOOS == "darwin" { @@ -20995,6 +22607,43 @@ index c29f5e4c5..600a68078 100644 } else { // Check if OPMASK and ZMM registers have OS support. osSupportsAVX512 = osSupportsAVX && isSet(5, eax) && isSet(6, eax) && isSet(7, eax) +@@ -108,7 +109,7 @@ func archInit() { + return + } + +- _, ebx7, ecx7, edx7 := cpuid(7, 0) ++ eax7, ebx7, ecx7, edx7 := cpuid(7, 0) + X86.HasBMI1 = isSet(3, ebx7) + X86.HasAVX2 = isSet(5, ebx7) && osSupportsAVX + X86.HasBMI2 = isSet(8, ebx7) +@@ -136,14 +137,24 @@ func archInit() { + X86.HasAVX512VAES = isSet(9, ecx7) + X86.HasAVX512VBMI2 = isSet(6, ecx7) + X86.HasAVX512BITALG = isSet(12, ecx7) +- +- eax71, _, _, _ := cpuid(7, 1) +- X86.HasAVX512BF16 = isSet(5, eax71) + } + + X86.HasAMXTile = isSet(24, edx7) + X86.HasAMXInt8 = isSet(25, edx7) + X86.HasAMXBF16 = isSet(22, edx7) ++ ++ // These features depend on the second level of extended features. ++ if eax7 >= 1 { ++ eax71, _, _, edx71 := cpuid(7, 1) ++ if X86.HasAVX512 { ++ X86.HasAVX512BF16 = isSet(5, eax71) ++ } ++ if X86.HasAVX { ++ X86.HasAVXIFMA = isSet(23, eax71) ++ X86.HasAVXVNNI = isSet(4, eax71) ++ X86.HasAVXVNNIInt8 = isSet(4, edx71) ++ } ++ } + } + + func isSet(bitpos uint, value uint32) bool { diff --git a/vendor/golang.org/x/sys/cpu/syscall_darwin_x86_gc.go b/vendor/golang.org/x/sys/cpu/syscall_darwin_x86_gc.go new file mode 100644 index 000000000..4d0888b0c @@ -21098,20 +22747,81 @@ index 000000000..4d0888b0c +// Implemented in the runtime package (runtime/sys_darwin.go) +func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) + -+//go:linkname syscall_syscall6 syscall.syscall6 -diff --git a/vendor/golang.org/x/sys/unix/README.md b/vendor/golang.org/x/sys/unix/README.md -index 7d3c060e1..6e08a76a7 100644 ---- a/vendor/golang.org/x/sys/unix/README.md -+++ b/vendor/golang.org/x/sys/unix/README.md -@@ -156,7 +156,7 @@ from the generated architecture-specific files listed below, and merge these - into a common file for each OS. - - The merge is performed in the following steps: --1. Construct the set of common code that is idential in all architecture-specific files. -+1. Construct the set of common code that is identical in all architecture-specific files. - 2. Write this common code to the merged file. - 3. Remove the common code from all architecture-specific files. - ++//go:linkname syscall_syscall6 syscall.syscall6 +diff --git a/vendor/golang.org/x/sys/unix/README.md b/vendor/golang.org/x/sys/unix/README.md +index 7d3c060e1..6e08a76a7 100644 +--- a/vendor/golang.org/x/sys/unix/README.md ++++ b/vendor/golang.org/x/sys/unix/README.md +@@ -156,7 +156,7 @@ from the generated architecture-specific files listed below, and merge these + into a common file for each OS. + + The merge is performed in the following steps: +-1. Construct the set of common code that is idential in all architecture-specific files. ++1. Construct the set of common code that is identical in all architecture-specific files. + 2. Write this common code to the merged file. + 3. Remove the common code from all architecture-specific files. + +diff --git a/vendor/golang.org/x/sys/unix/auxv.go b/vendor/golang.org/x/sys/unix/auxv.go +new file mode 100644 +index 000000000..37a82528f +--- /dev/null ++++ b/vendor/golang.org/x/sys/unix/auxv.go +@@ -0,0 +1,36 @@ ++// Copyright 2025 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++//go:build go1.21 && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos) ++ ++package unix ++ ++import ( ++ "syscall" ++ "unsafe" ++) ++ ++//go:linkname runtime_getAuxv runtime.getAuxv ++func runtime_getAuxv() []uintptr ++ ++// Auxv returns the ELF auxiliary vector as a sequence of key/value pairs. ++// The returned slice is always a fresh copy, owned by the caller. ++// It returns an error on non-ELF platforms, or if the auxiliary vector cannot be accessed, ++// which happens in some locked-down environments and build modes. ++func Auxv() ([][2]uintptr, error) { ++ vec := runtime_getAuxv() ++ vecLen := len(vec) ++ ++ if vecLen == 0 { ++ return nil, syscall.ENOENT ++ } ++ ++ if vecLen%2 != 0 { ++ return nil, syscall.EINVAL ++ } ++ ++ result := make([]uintptr, vecLen) ++ copy(result, vec) ++ return unsafe.Slice((*[2]uintptr)(unsafe.Pointer(&result[0])), vecLen/2), nil ++} +diff --git a/vendor/golang.org/x/sys/unix/auxv_unsupported.go b/vendor/golang.org/x/sys/unix/auxv_unsupported.go +new file mode 100644 +index 000000000..1200487f2 +--- /dev/null ++++ b/vendor/golang.org/x/sys/unix/auxv_unsupported.go +@@ -0,0 +1,13 @@ ++// Copyright 2025 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++//go:build !go1.21 && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos) ++ ++package unix ++ ++import "syscall" ++ ++func Auxv() ([][2]uintptr, error) { ++ return nil, syscall.ENOTSUP ++} diff --git a/vendor/golang.org/x/sys/unix/ioctl_linux.go b/vendor/golang.org/x/sys/unix/ioctl_linux.go index dbe680eab..7ca4fa12a 100644 --- a/vendor/golang.org/x/sys/unix/ioctl_linux.go @@ -21497,6 +23207,101 @@ index 6f5a28894..8cf3670bd 100644 } + +const SYS_FSTATAT = SYS_NEWFSTATAT +diff --git a/vendor/golang.org/x/sys/unix/syscall_solaris.go b/vendor/golang.org/x/sys/unix/syscall_solaris.go +index 21974af06..abc395547 100644 +--- a/vendor/golang.org/x/sys/unix/syscall_solaris.go ++++ b/vendor/golang.org/x/sys/unix/syscall_solaris.go +@@ -1102,3 +1102,90 @@ func (s *Strioctl) SetInt(i int) { + func IoctlSetStrioctlRetInt(fd int, req int, s *Strioctl) (int, error) { + return ioctlPtrRet(fd, req, unsafe.Pointer(s)) + } ++ ++// Ucred Helpers ++// See ucred(3c) and getpeerucred(3c) ++ ++//sys getpeerucred(fd uintptr, ucred *uintptr) (err error) ++//sys ucredFree(ucred uintptr) = ucred_free ++//sys ucredGet(pid int) (ucred uintptr, err error) = ucred_get ++//sys ucredGeteuid(ucred uintptr) (uid int) = ucred_geteuid ++//sys ucredGetegid(ucred uintptr) (gid int) = ucred_getegid ++//sys ucredGetruid(ucred uintptr) (uid int) = ucred_getruid ++//sys ucredGetrgid(ucred uintptr) (gid int) = ucred_getrgid ++//sys ucredGetsuid(ucred uintptr) (uid int) = ucred_getsuid ++//sys ucredGetsgid(ucred uintptr) (gid int) = ucred_getsgid ++//sys ucredGetpid(ucred uintptr) (pid int) = ucred_getpid ++ ++// Ucred is an opaque struct that holds user credentials. ++type Ucred struct { ++ ucred uintptr ++} ++ ++// We need to ensure that ucredFree is called on the underlying ucred ++// when the Ucred is garbage collected. ++func ucredFinalizer(u *Ucred) { ++ ucredFree(u.ucred) ++} ++ ++func GetPeerUcred(fd uintptr) (*Ucred, error) { ++ var ucred uintptr ++ err := getpeerucred(fd, &ucred) ++ if err != nil { ++ return nil, err ++ } ++ result := &Ucred{ ++ ucred: ucred, ++ } ++ // set the finalizer on the result so that the ucred will be freed ++ runtime.SetFinalizer(result, ucredFinalizer) ++ return result, nil ++} ++ ++func UcredGet(pid int) (*Ucred, error) { ++ ucred, err := ucredGet(pid) ++ if err != nil { ++ return nil, err ++ } ++ result := &Ucred{ ++ ucred: ucred, ++ } ++ // set the finalizer on the result so that the ucred will be freed ++ runtime.SetFinalizer(result, ucredFinalizer) ++ return result, nil ++} ++ ++func (u *Ucred) Geteuid() int { ++ defer runtime.KeepAlive(u) ++ return ucredGeteuid(u.ucred) ++} ++ ++func (u *Ucred) Getruid() int { ++ defer runtime.KeepAlive(u) ++ return ucredGetruid(u.ucred) ++} ++ ++func (u *Ucred) Getsuid() int { ++ defer runtime.KeepAlive(u) ++ return ucredGetsuid(u.ucred) ++} ++ ++func (u *Ucred) Getegid() int { ++ defer runtime.KeepAlive(u) ++ return ucredGetegid(u.ucred) ++} ++ ++func (u *Ucred) Getrgid() int { ++ defer runtime.KeepAlive(u) ++ return ucredGetrgid(u.ucred) ++} ++ ++func (u *Ucred) Getsgid() int { ++ defer runtime.KeepAlive(u) ++ return ucredGetsgid(u.ucred) ++} ++ ++func (u *Ucred) Getpid() int { ++ defer runtime.KeepAlive(u) ++ return ucredGetpid(u.ucred) ++} diff --git a/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go b/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go index 312ae6ac1..7bf5c04bb 100644 --- a/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go @@ -21710,7 +23515,7 @@ index c8068a7a1..4a55a4005 100644 SCM_RIGHTS = 0x1 SCM_TIMESTAMP = 0x2 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go -index 01a70b246..6ebc48b3f 100644 +index 01a70b246..4f432bfe8 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -321,6 +321,9 @@ const ( @@ -21746,7 +23551,43 @@ index 01a70b246..6ebc48b3f 100644 FALLOC_FL_COLLAPSE_RANGE = 0x8 FALLOC_FL_INSERT_RANGE = 0x20 FALLOC_FL_KEEP_SIZE = 0x1 -@@ -1798,6 +1804,8 @@ const ( +@@ -1239,6 +1245,7 @@ const ( + FAN_REPORT_DFID_NAME = 0xc00 + FAN_REPORT_DFID_NAME_TARGET = 0x1e00 + FAN_REPORT_DIR_FID = 0x400 ++ FAN_REPORT_FD_ERROR = 0x2000 + FAN_REPORT_FID = 0x200 + FAN_REPORT_NAME = 0x800 + FAN_REPORT_PIDFD = 0x80 +@@ -1324,8 +1331,10 @@ const ( + FUSE_SUPER_MAGIC = 0x65735546 + FUTEXFS_SUPER_MAGIC = 0xbad1dea + F_ADD_SEALS = 0x409 ++ F_CREATED_QUERY = 0x404 + F_DUPFD = 0x0 + F_DUPFD_CLOEXEC = 0x406 ++ F_DUPFD_QUERY = 0x403 + F_EXLCK = 0x4 + F_GETFD = 0x1 + F_GETFL = 0x3 +@@ -1545,6 +1554,7 @@ const ( + IPPROTO_ROUTING = 0x2b + IPPROTO_RSVP = 0x2e + IPPROTO_SCTP = 0x84 ++ IPPROTO_SMC = 0x100 + IPPROTO_TCP = 0x6 + IPPROTO_TP = 0x1d + IPPROTO_UDP = 0x11 +@@ -1617,6 +1627,8 @@ const ( + IPV6_UNICAST_IF = 0x4c + IPV6_USER_FLOW = 0xe + IPV6_V6ONLY = 0x1a ++ IPV6_VERSION = 0x60 ++ IPV6_VERSION_MASK = 0xf0 + IPV6_XFRM_POLICY = 0x23 + IP_ADD_MEMBERSHIP = 0x23 + IP_ADD_SOURCE_MEMBERSHIP = 0x27 +@@ -1798,6 +1810,8 @@ const ( LANDLOCK_ACCESS_NET_BIND_TCP = 0x1 LANDLOCK_ACCESS_NET_CONNECT_TCP = 0x2 LANDLOCK_CREATE_RULESET_VERSION = 0x1 @@ -21755,7 +23596,15 @@ index 01a70b246..6ebc48b3f 100644 LINUX_REBOOT_CMD_CAD_OFF = 0x0 LINUX_REBOOT_CMD_CAD_ON = 0x89abcdef LINUX_REBOOT_CMD_HALT = 0xcdef0123 -@@ -1922,6 +1930,8 @@ const ( +@@ -1859,6 +1873,7 @@ const ( + MADV_UNMERGEABLE = 0xd + MADV_WILLNEED = 0x3 + MADV_WIPEONFORK = 0x12 ++ MAP_DROPPABLE = 0x8 + MAP_FILE = 0x0 + MAP_FIXED = 0x10 + MAP_FIXED_NOREPLACE = 0x100000 +@@ -1922,6 +1937,8 @@ const ( MNT_EXPIRE = 0x4 MNT_FORCE = 0x1 MNT_ID_REQ_SIZE_VER0 = 0x18 @@ -21764,7 +23613,31 @@ index 01a70b246..6ebc48b3f 100644 MODULE_INIT_COMPRESSED_FILE = 0x4 MODULE_INIT_IGNORE_MODVERSIONS = 0x1 MODULE_INIT_IGNORE_VERMAGIC = 0x2 -@@ -2187,7 +2197,7 @@ const ( +@@ -1957,6 +1974,7 @@ const ( + MSG_PEEK = 0x2 + MSG_PROXY = 0x10 + MSG_RST = 0x1000 ++ MSG_SOCK_DEVMEM = 0x2000000 + MSG_SYN = 0x400 + MSG_TRUNC = 0x20 + MSG_TRYHARD = 0x4 +@@ -2073,6 +2091,7 @@ const ( + NFC_ATR_REQ_MAXSIZE = 0x40 + NFC_ATR_RES_GB_MAXSIZE = 0x2f + NFC_ATR_RES_MAXSIZE = 0x40 ++ NFC_ATS_MAXSIZE = 0x14 + NFC_COMM_ACTIVE = 0x0 + NFC_COMM_PASSIVE = 0x1 + NFC_DEVICE_NAME_MAXSIZE = 0x8 +@@ -2153,6 +2172,7 @@ const ( + NFNL_SUBSYS_QUEUE = 0x3 + NFNL_SUBSYS_ULOG = 0x4 + NFS_SUPER_MAGIC = 0x6969 ++ NFT_BITWISE_BOOL = 0x0 + NFT_CHAIN_FLAGS = 0x7 + NFT_CHAIN_MAXNAMELEN = 0x100 + NFT_CT_MAX = 0x17 +@@ -2187,7 +2207,7 @@ const ( NFT_REG_SIZE = 0x10 NFT_REJECT_ICMPX_MAX = 0x3 NFT_RT_MAX = 0x4 @@ -21773,7 +23646,7 @@ index 01a70b246..6ebc48b3f 100644 NFT_SET_MAXNAMELEN = 0x100 NFT_SOCKET_MAX = 0x3 NFT_TABLE_F_MASK = 0x7 -@@ -2356,9 +2366,11 @@ const ( +@@ -2356,9 +2376,11 @@ const ( PERF_MEM_LVLNUM_IO = 0xa PERF_MEM_LVLNUM_L1 = 0x1 PERF_MEM_LVLNUM_L2 = 0x2 @@ -21785,7 +23658,7 @@ index 01a70b246..6ebc48b3f 100644 PERF_MEM_LVLNUM_NA = 0xf PERF_MEM_LVLNUM_PMEM = 0xe PERF_MEM_LVLNUM_RAM = 0xd -@@ -2431,6 +2443,7 @@ const ( +@@ -2431,6 +2453,7 @@ const ( PRIO_PGRP = 0x1 PRIO_PROCESS = 0x0 PRIO_USER = 0x2 @@ -21793,7 +23666,50 @@ index 01a70b246..6ebc48b3f 100644 PROC_SUPER_MAGIC = 0x9fa0 PROT_EXEC = 0x4 PROT_GROWSDOWN = 0x1000000 -@@ -2620,6 +2633,28 @@ const ( +@@ -2478,6 +2501,7 @@ const ( + PR_GET_PDEATHSIG = 0x2 + PR_GET_SECCOMP = 0x15 + PR_GET_SECUREBITS = 0x1b ++ PR_GET_SHADOW_STACK_STATUS = 0x4a + PR_GET_SPECULATION_CTRL = 0x34 + PR_GET_TAGGED_ADDR_CTRL = 0x38 + PR_GET_THP_DISABLE = 0x2a +@@ -2486,6 +2510,7 @@ const ( + PR_GET_TIMING = 0xd + PR_GET_TSC = 0x19 + PR_GET_UNALIGN = 0x5 ++ PR_LOCK_SHADOW_STACK_STATUS = 0x4c + PR_MCE_KILL = 0x21 + PR_MCE_KILL_CLEAR = 0x0 + PR_MCE_KILL_DEFAULT = 0x2 +@@ -2512,6 +2537,8 @@ const ( + PR_PAC_GET_ENABLED_KEYS = 0x3d + PR_PAC_RESET_KEYS = 0x36 + PR_PAC_SET_ENABLED_KEYS = 0x3c ++ PR_PMLEN_MASK = 0x7f000000 ++ PR_PMLEN_SHIFT = 0x18 + PR_PPC_DEXCR_CTRL_CLEAR = 0x4 + PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC = 0x10 + PR_PPC_DEXCR_CTRL_EDITABLE = 0x1 +@@ -2579,6 +2606,7 @@ const ( + PR_SET_PTRACER = 0x59616d61 + PR_SET_SECCOMP = 0x16 + PR_SET_SECUREBITS = 0x1c ++ PR_SET_SHADOW_STACK_STATUS = 0x4b + PR_SET_SPECULATION_CTRL = 0x35 + PR_SET_SYSCALL_USER_DISPATCH = 0x3b + PR_SET_TAGGED_ADDR_CTRL = 0x37 +@@ -2589,6 +2617,9 @@ const ( + PR_SET_UNALIGN = 0x6 + PR_SET_VMA = 0x53564d41 + PR_SET_VMA_ANON_NAME = 0x0 ++ PR_SHADOW_STACK_ENABLE = 0x1 ++ PR_SHADOW_STACK_PUSH = 0x4 ++ PR_SHADOW_STACK_WRITE = 0x2 + PR_SME_GET_VL = 0x40 + PR_SME_SET_VL = 0x3f + PR_SME_SET_VL_ONEXEC = 0x40000 +@@ -2620,6 +2651,28 @@ const ( PR_UNALIGN_NOPRINT = 0x1 PR_UNALIGN_SIGBUS = 0x2 PSTOREFS_MAGIC = 0x6165676c @@ -21822,7 +23738,23 @@ index 01a70b246..6ebc48b3f 100644 PTRACE_ATTACH = 0x10 PTRACE_CONT = 0x7 PTRACE_DETACH = 0x11 -@@ -2933,15 +2968,17 @@ const ( +@@ -2876,7 +2929,6 @@ const ( + RTM_NEWNEXTHOP = 0x68 + RTM_NEWNEXTHOPBUCKET = 0x74 + RTM_NEWNSID = 0x58 +- RTM_NEWNVLAN = 0x70 + RTM_NEWPREFIX = 0x34 + RTM_NEWQDISC = 0x24 + RTM_NEWROUTE = 0x18 +@@ -2885,6 +2937,7 @@ const ( + RTM_NEWTCLASS = 0x28 + RTM_NEWTFILTER = 0x2c + RTM_NEWTUNNEL = 0x78 ++ RTM_NEWVLAN = 0x70 + RTM_NR_FAMILIES = 0x1b + RTM_NR_MSGTYPES = 0x6c + RTM_SETDCB = 0x4f +@@ -2933,15 +2986,17 @@ const ( RUSAGE_SELF = 0x0 RUSAGE_THREAD = 0x1 RWF_APPEND = 0x10 @@ -21841,7 +23773,7 @@ index 01a70b246..6ebc48b3f 100644 SCHED_FIFO = 0x1 SCHED_FLAG_ALL = 0x7f SCHED_FLAG_DL_OVERRUN = 0x4 -@@ -3210,6 +3247,7 @@ const ( +@@ -3210,6 +3265,7 @@ const ( STATX_ATTR_MOUNT_ROOT = 0x2000 STATX_ATTR_NODUMP = 0x40 STATX_ATTR_VERITY = 0x100000 @@ -21849,7 +23781,7 @@ index 01a70b246..6ebc48b3f 100644 STATX_BASIC_STATS = 0x7ff STATX_BLOCKS = 0x400 STATX_BTIME = 0x800 -@@ -3226,6 +3264,7 @@ const ( +@@ -3226,6 +3282,7 @@ const ( STATX_SUBVOL = 0x8000 STATX_TYPE = 0x1 STATX_UID = 0x8 @@ -21857,7 +23789,7 @@ index 01a70b246..6ebc48b3f 100644 STATX__RESERVED = 0x80000000 SYNC_FILE_RANGE_WAIT_AFTER = 0x4 SYNC_FILE_RANGE_WAIT_BEFORE = 0x1 -@@ -3624,6 +3663,7 @@ const ( +@@ -3624,6 +3681,7 @@ const ( XDP_UMEM_PGOFF_COMPLETION_RING = 0x180000000 XDP_UMEM_PGOFF_FILL_RING = 0x100000000 XDP_UMEM_REG = 0x4 @@ -21866,10 +23798,10 @@ index 01a70b246..6ebc48b3f 100644 XDP_UMEM_UNALIGNED_CHUNK_FLAG = 0x1 XDP_USE_NEED_WAKEUP = 0x8 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go -index 684a5168d..c0d45e320 100644 +index 684a5168d..75207613c 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go -@@ -109,6 +109,7 @@ const ( +@@ -109,12 +109,15 @@ const ( HIDIOCGRAWINFO = 0x80084803 HIDIOCGRDESC = 0x90044802 HIDIOCGRDESCSIZE = 0x80044801 @@ -21877,7 +23809,15 @@ index 684a5168d..c0d45e320 100644 HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 -@@ -153,9 +154,14 @@ const ( + IN_CLOEXEC = 0x80000 + IN_NONBLOCK = 0x800 + IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 ++ IPV6_FLOWINFO_MASK = 0xffffff0f ++ IPV6_FLOWLABEL_MASK = 0xffff0f00 + ISIG = 0x1 + IUCLC = 0x200 + IXOFF = 0x1000 +@@ -153,9 +156,14 @@ const ( NFDBITS = 0x20 NLDLY = 0x100 NOFLSH = 0x80 @@ -21892,7 +23832,7 @@ index 684a5168d..c0d45e320 100644 NS_GET_USERNS = 0xb701 OLCUC = 0x2 ONLCR = 0x4 -@@ -232,6 +238,20 @@ const ( +@@ -232,6 +240,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x7434 PPPIOCXFERUNIT = 0x744e PR_SET_PTRACER_ANY = 0xffffffff @@ -21913,7 +23853,7 @@ index 684a5168d..c0d45e320 100644 PTRACE_GETFPREGS = 0xe PTRACE_GETFPXREGS = 0x12 PTRACE_GET_THREAD_AREA = 0x19 -@@ -278,6 +298,8 @@ const ( +@@ -278,10 +300,13 @@ const ( RTC_WIE_ON = 0x700f RTC_WKALM_RD = 0x80287010 RTC_WKALM_SET = 0x4028700f @@ -21922,7 +23862,12 @@ index 684a5168d..c0d45e320 100644 SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a -@@ -316,6 +338,9 @@ const ( + SCM_TIMESTAMPNS = 0x23 ++ SCM_TS_OPT_ID = 0x51 + SCM_TXTIME = 0x3d + SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 +@@ -316,6 +341,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 @@ -21933,10 +23878,10 @@ index 684a5168d..c0d45e320 100644 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go -index 61d74b592..c731d24f0 100644 +index 61d74b592..c68acda53 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go -@@ -109,6 +109,7 @@ const ( +@@ -109,12 +109,15 @@ const ( HIDIOCGRAWINFO = 0x80084803 HIDIOCGRDESC = 0x90044802 HIDIOCGRDESCSIZE = 0x80044801 @@ -21944,7 +23889,15 @@ index 61d74b592..c731d24f0 100644 HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 -@@ -153,9 +154,14 @@ const ( + IN_CLOEXEC = 0x80000 + IN_NONBLOCK = 0x800 + IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 ++ IPV6_FLOWINFO_MASK = 0xffffff0f ++ IPV6_FLOWLABEL_MASK = 0xffff0f00 + ISIG = 0x1 + IUCLC = 0x200 + IXOFF = 0x1000 +@@ -153,9 +156,14 @@ const ( NFDBITS = 0x40 NLDLY = 0x100 NOFLSH = 0x80 @@ -21959,7 +23912,7 @@ index 61d74b592..c731d24f0 100644 NS_GET_USERNS = 0xb701 OLCUC = 0x2 ONLCR = 0x4 -@@ -232,6 +238,20 @@ const ( +@@ -232,6 +240,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x7434 PPPIOCXFERUNIT = 0x744e PR_SET_PTRACER_ANY = 0xffffffffffffffff @@ -21980,7 +23933,7 @@ index 61d74b592..c731d24f0 100644 PTRACE_ARCH_PRCTL = 0x1e PTRACE_GETFPREGS = 0xe PTRACE_GETFPXREGS = 0x12 -@@ -279,6 +299,8 @@ const ( +@@ -279,10 +301,13 @@ const ( RTC_WIE_ON = 0x700f RTC_WKALM_RD = 0x80287010 RTC_WKALM_SET = 0x4028700f @@ -21989,7 +23942,12 @@ index 61d74b592..c731d24f0 100644 SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a -@@ -317,6 +339,9 @@ const ( + SCM_TIMESTAMPNS = 0x23 ++ SCM_TS_OPT_ID = 0x51 + SCM_TXTIME = 0x3d + SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 +@@ -317,6 +342,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 @@ -22000,10 +23958,10 @@ index 61d74b592..c731d24f0 100644 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go -index a28c9e3e8..680018a4a 100644 +index a28c9e3e8..a8c607ab8 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go -@@ -108,6 +108,7 @@ const ( +@@ -108,12 +108,15 @@ const ( HIDIOCGRAWINFO = 0x80084803 HIDIOCGRDESC = 0x90044802 HIDIOCGRDESCSIZE = 0x80044801 @@ -22011,7 +23969,15 @@ index a28c9e3e8..680018a4a 100644 HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 -@@ -150,9 +151,14 @@ const ( + IN_CLOEXEC = 0x80000 + IN_NONBLOCK = 0x800 + IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 ++ IPV6_FLOWINFO_MASK = 0xffffff0f ++ IPV6_FLOWLABEL_MASK = 0xffff0f00 + ISIG = 0x1 + IUCLC = 0x200 + IXOFF = 0x1000 +@@ -150,9 +153,14 @@ const ( NFDBITS = 0x20 NLDLY = 0x100 NOFLSH = 0x80 @@ -22026,7 +23992,7 @@ index a28c9e3e8..680018a4a 100644 NS_GET_USERNS = 0xb701 OLCUC = 0x2 ONLCR = 0x4 -@@ -229,6 +235,20 @@ const ( +@@ -229,6 +237,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x7434 PPPIOCXFERUNIT = 0x744e PR_SET_PTRACER_ANY = 0xffffffff @@ -22047,7 +24013,7 @@ index a28c9e3e8..680018a4a 100644 PTRACE_GETCRUNCHREGS = 0x19 PTRACE_GETFDPIC = 0x1f PTRACE_GETFDPIC_EXEC = 0x0 -@@ -284,6 +304,8 @@ const ( +@@ -284,10 +306,13 @@ const ( RTC_WIE_ON = 0x700f RTC_WKALM_RD = 0x80287010 RTC_WKALM_SET = 0x4028700f @@ -22056,7 +24022,12 @@ index a28c9e3e8..680018a4a 100644 SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a -@@ -322,6 +344,9 @@ const ( + SCM_TIMESTAMPNS = 0x23 ++ SCM_TS_OPT_ID = 0x51 + SCM_TXTIME = 0x3d + SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 +@@ -322,6 +347,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 @@ -22067,10 +24038,14 @@ index a28c9e3e8..680018a4a 100644 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go -index ab5d1fe8e..a63909f30 100644 +index ab5d1fe8e..18563dd8d 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go -@@ -112,6 +112,7 @@ const ( +@@ -109,15 +109,19 @@ const ( + F_SETOWN = 0x8 + F_UNLCK = 0x2 + F_WRLCK = 0x1 ++ GCS_MAGIC = 0x47435300 HIDIOCGRAWINFO = 0x80084803 HIDIOCGRDESC = 0x90044802 HIDIOCGRDESCSIZE = 0x80044801 @@ -22078,7 +24053,15 @@ index ab5d1fe8e..a63909f30 100644 HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 -@@ -154,9 +155,14 @@ const ( + IN_CLOEXEC = 0x80000 + IN_NONBLOCK = 0x800 + IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 ++ IPV6_FLOWINFO_MASK = 0xffffff0f ++ IPV6_FLOWLABEL_MASK = 0xffff0f00 + ISIG = 0x1 + IUCLC = 0x200 + IXOFF = 0x1000 +@@ -154,9 +158,14 @@ const ( NFDBITS = 0x40 NLDLY = 0x100 NOFLSH = 0x80 @@ -22093,7 +24076,7 @@ index ab5d1fe8e..a63909f30 100644 NS_GET_USERNS = 0xb701 OLCUC = 0x2 ONLCR = 0x4 -@@ -200,6 +206,7 @@ const ( +@@ -200,6 +209,7 @@ const ( PERF_EVENT_IOC_SET_BPF = 0x40042408 PERF_EVENT_IOC_SET_FILTER = 0x40082406 PERF_EVENT_IOC_SET_OUTPUT = 0x2405 @@ -22101,7 +24084,7 @@ index ab5d1fe8e..a63909f30 100644 PPPIOCATTACH = 0x4004743d PPPIOCATTCHAN = 0x40047438 PPPIOCBRIDGECHAN = 0x40047435 -@@ -235,6 +242,20 @@ const ( +@@ -235,6 +245,20 @@ const ( PROT_BTI = 0x10 PROT_MTE = 0x20 PR_SET_PTRACER_ANY = 0xffffffffffffffff @@ -22122,7 +24105,7 @@ index ab5d1fe8e..a63909f30 100644 PTRACE_PEEKMTETAGS = 0x21 PTRACE_POKEMTETAGS = 0x22 PTRACE_SYSEMU = 0x1f -@@ -275,6 +296,8 @@ const ( +@@ -275,10 +299,13 @@ const ( RTC_WIE_ON = 0x700f RTC_WKALM_RD = 0x80287010 RTC_WKALM_SET = 0x4028700f @@ -22131,7 +24114,12 @@ index ab5d1fe8e..a63909f30 100644 SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a -@@ -313,6 +336,9 @@ const ( + SCM_TIMESTAMPNS = 0x23 ++ SCM_TS_OPT_ID = 0x51 + SCM_TXTIME = 0x3d + SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 +@@ -313,6 +340,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 @@ -22142,10 +24130,10 @@ index ab5d1fe8e..a63909f30 100644 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go -index c523090e7..9b0a2573f 100644 +index c523090e7..22912cdaa 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go -@@ -109,6 +109,7 @@ const ( +@@ -109,12 +109,15 @@ const ( HIDIOCGRAWINFO = 0x80084803 HIDIOCGRDESC = 0x90044802 HIDIOCGRDESCSIZE = 0x80044801 @@ -22153,7 +24141,15 @@ index c523090e7..9b0a2573f 100644 HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 -@@ -154,9 +155,14 @@ const ( + IN_CLOEXEC = 0x80000 + IN_NONBLOCK = 0x800 + IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 ++ IPV6_FLOWINFO_MASK = 0xffffff0f ++ IPV6_FLOWLABEL_MASK = 0xffff0f00 + ISIG = 0x1 + IUCLC = 0x200 + IXOFF = 0x1000 +@@ -154,9 +157,14 @@ const ( NFDBITS = 0x40 NLDLY = 0x100 NOFLSH = 0x80 @@ -22168,7 +24164,7 @@ index c523090e7..9b0a2573f 100644 NS_GET_USERNS = 0xb701 OLCUC = 0x2 ONLCR = 0x4 -@@ -233,6 +239,20 @@ const ( +@@ -233,6 +241,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x7434 PPPIOCXFERUNIT = 0x744e PR_SET_PTRACER_ANY = 0xffffffffffffffff @@ -22189,7 +24185,7 @@ index c523090e7..9b0a2573f 100644 PTRACE_SYSEMU = 0x1f PTRACE_SYSEMU_SINGLESTEP = 0x20 RLIMIT_AS = 0x9 -@@ -271,6 +291,8 @@ const ( +@@ -271,10 +293,13 @@ const ( RTC_WIE_ON = 0x700f RTC_WKALM_RD = 0x80287010 RTC_WKALM_SET = 0x4028700f @@ -22198,7 +24194,12 @@ index c523090e7..9b0a2573f 100644 SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a -@@ -309,6 +331,9 @@ const ( + SCM_TIMESTAMPNS = 0x23 ++ SCM_TS_OPT_ID = 0x51 + SCM_TXTIME = 0x3d + SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 +@@ -309,6 +334,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 @@ -22209,10 +24210,10 @@ index c523090e7..9b0a2573f 100644 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go -index 01e6ea780..958e6e064 100644 +index 01e6ea780..29344eb37 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go -@@ -108,6 +108,7 @@ const ( +@@ -108,12 +108,15 @@ const ( HIDIOCGRAWINFO = 0x40084803 HIDIOCGRDESC = 0x50044802 HIDIOCGRDESCSIZE = 0x40044801 @@ -22220,7 +24221,15 @@ index 01e6ea780..958e6e064 100644 HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x100 -@@ -150,9 +151,14 @@ const ( + IN_CLOEXEC = 0x80000 + IN_NONBLOCK = 0x80 + IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 ++ IPV6_FLOWINFO_MASK = 0xfffffff ++ IPV6_FLOWLABEL_MASK = 0xfffff + ISIG = 0x1 + IUCLC = 0x200 + IXOFF = 0x1000 +@@ -150,9 +153,14 @@ const ( NFDBITS = 0x20 NLDLY = 0x100 NOFLSH = 0x80 @@ -22235,7 +24244,7 @@ index 01e6ea780..958e6e064 100644 NS_GET_USERNS = 0x2000b701 OLCUC = 0x2 ONLCR = 0x4 -@@ -229,6 +235,20 @@ const ( +@@ -229,6 +237,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x20007434 PPPIOCXFERUNIT = 0x2000744e PR_SET_PTRACER_ANY = 0xffffffff @@ -22256,7 +24265,7 @@ index 01e6ea780..958e6e064 100644 PTRACE_GETFPREGS = 0xe PTRACE_GET_THREAD_AREA = 0x19 PTRACE_GET_THREAD_AREA_3264 = 0xc4 -@@ -277,6 +297,8 @@ const ( +@@ -277,10 +299,13 @@ const ( RTC_WIE_ON = 0x2000700f RTC_WKALM_RD = 0x40287010 RTC_WKALM_SET = 0x8028700f @@ -22265,7 +24274,12 @@ index 01e6ea780..958e6e064 100644 SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a -@@ -315,6 +337,9 @@ const ( + SCM_TIMESTAMPNS = 0x23 ++ SCM_TS_OPT_ID = 0x51 + SCM_TXTIME = 0x3d + SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 +@@ -315,6 +340,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 @@ -22276,10 +24290,10 @@ index 01e6ea780..958e6e064 100644 SO_DONTROUTE = 0x10 SO_ERROR = 0x1007 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go -index 7aa610b1e..50c7f25bd 100644 +index 7aa610b1e..20d51fb96 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go -@@ -108,6 +108,7 @@ const ( +@@ -108,12 +108,15 @@ const ( HIDIOCGRAWINFO = 0x40084803 HIDIOCGRDESC = 0x50044802 HIDIOCGRDESCSIZE = 0x40044801 @@ -22287,7 +24301,15 @@ index 7aa610b1e..50c7f25bd 100644 HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x100 -@@ -150,9 +151,14 @@ const ( + IN_CLOEXEC = 0x80000 + IN_NONBLOCK = 0x80 + IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 ++ IPV6_FLOWINFO_MASK = 0xfffffff ++ IPV6_FLOWLABEL_MASK = 0xfffff + ISIG = 0x1 + IUCLC = 0x200 + IXOFF = 0x1000 +@@ -150,9 +153,14 @@ const ( NFDBITS = 0x40 NLDLY = 0x100 NOFLSH = 0x80 @@ -22302,7 +24324,7 @@ index 7aa610b1e..50c7f25bd 100644 NS_GET_USERNS = 0x2000b701 OLCUC = 0x2 ONLCR = 0x4 -@@ -229,6 +235,20 @@ const ( +@@ -229,6 +237,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x20007434 PPPIOCXFERUNIT = 0x2000744e PR_SET_PTRACER_ANY = 0xffffffffffffffff @@ -22323,7 +24345,7 @@ index 7aa610b1e..50c7f25bd 100644 PTRACE_GETFPREGS = 0xe PTRACE_GET_THREAD_AREA = 0x19 PTRACE_GET_THREAD_AREA_3264 = 0xc4 -@@ -277,6 +297,8 @@ const ( +@@ -277,10 +299,13 @@ const ( RTC_WIE_ON = 0x2000700f RTC_WKALM_RD = 0x40287010 RTC_WKALM_SET = 0x8028700f @@ -22332,7 +24354,12 @@ index 7aa610b1e..50c7f25bd 100644 SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a -@@ -315,6 +337,9 @@ const ( + SCM_TIMESTAMPNS = 0x23 ++ SCM_TS_OPT_ID = 0x51 + SCM_TXTIME = 0x3d + SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 +@@ -315,6 +340,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 @@ -22343,10 +24370,10 @@ index 7aa610b1e..50c7f25bd 100644 SO_DONTROUTE = 0x10 SO_ERROR = 0x1007 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go -index 92af771b4..ced21d66d 100644 +index 92af771b4..321b60902 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go -@@ -108,6 +108,7 @@ const ( +@@ -108,12 +108,15 @@ const ( HIDIOCGRAWINFO = 0x40084803 HIDIOCGRDESC = 0x50044802 HIDIOCGRDESCSIZE = 0x40044801 @@ -22354,7 +24381,15 @@ index 92af771b4..ced21d66d 100644 HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x100 -@@ -150,9 +151,14 @@ const ( + IN_CLOEXEC = 0x80000 + IN_NONBLOCK = 0x80 + IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 ++ IPV6_FLOWINFO_MASK = 0xffffff0f ++ IPV6_FLOWLABEL_MASK = 0xffff0f00 + ISIG = 0x1 + IUCLC = 0x200 + IXOFF = 0x1000 +@@ -150,9 +153,14 @@ const ( NFDBITS = 0x40 NLDLY = 0x100 NOFLSH = 0x80 @@ -22369,7 +24404,7 @@ index 92af771b4..ced21d66d 100644 NS_GET_USERNS = 0x2000b701 OLCUC = 0x2 ONLCR = 0x4 -@@ -229,6 +235,20 @@ const ( +@@ -229,6 +237,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x20007434 PPPIOCXFERUNIT = 0x2000744e PR_SET_PTRACER_ANY = 0xffffffffffffffff @@ -22390,7 +24425,7 @@ index 92af771b4..ced21d66d 100644 PTRACE_GETFPREGS = 0xe PTRACE_GET_THREAD_AREA = 0x19 PTRACE_GET_THREAD_AREA_3264 = 0xc4 -@@ -277,6 +297,8 @@ const ( +@@ -277,10 +299,13 @@ const ( RTC_WIE_ON = 0x2000700f RTC_WKALM_RD = 0x40287010 RTC_WKALM_SET = 0x8028700f @@ -22399,7 +24434,12 @@ index 92af771b4..ced21d66d 100644 SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a -@@ -315,6 +337,9 @@ const ( + SCM_TIMESTAMPNS = 0x23 ++ SCM_TS_OPT_ID = 0x51 + SCM_TXTIME = 0x3d + SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 +@@ -315,6 +340,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 @@ -22410,10 +24450,10 @@ index 92af771b4..ced21d66d 100644 SO_DONTROUTE = 0x10 SO_ERROR = 0x1007 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go -index b27ef5e6f..226c04419 100644 +index b27ef5e6f..9bacdf1e2 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go -@@ -108,6 +108,7 @@ const ( +@@ -108,12 +108,15 @@ const ( HIDIOCGRAWINFO = 0x40084803 HIDIOCGRDESC = 0x50044802 HIDIOCGRDESCSIZE = 0x40044801 @@ -22421,7 +24461,15 @@ index b27ef5e6f..226c04419 100644 HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x100 -@@ -150,9 +151,14 @@ const ( + IN_CLOEXEC = 0x80000 + IN_NONBLOCK = 0x80 + IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 ++ IPV6_FLOWINFO_MASK = 0xffffff0f ++ IPV6_FLOWLABEL_MASK = 0xffff0f00 + ISIG = 0x1 + IUCLC = 0x200 + IXOFF = 0x1000 +@@ -150,9 +153,14 @@ const ( NFDBITS = 0x20 NLDLY = 0x100 NOFLSH = 0x80 @@ -22436,7 +24484,7 @@ index b27ef5e6f..226c04419 100644 NS_GET_USERNS = 0x2000b701 OLCUC = 0x2 ONLCR = 0x4 -@@ -229,6 +235,20 @@ const ( +@@ -229,6 +237,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x20007434 PPPIOCXFERUNIT = 0x2000744e PR_SET_PTRACER_ANY = 0xffffffff @@ -22457,7 +24505,7 @@ index b27ef5e6f..226c04419 100644 PTRACE_GETFPREGS = 0xe PTRACE_GET_THREAD_AREA = 0x19 PTRACE_GET_THREAD_AREA_3264 = 0xc4 -@@ -277,6 +297,8 @@ const ( +@@ -277,10 +299,13 @@ const ( RTC_WIE_ON = 0x2000700f RTC_WKALM_RD = 0x40287010 RTC_WKALM_SET = 0x8028700f @@ -22466,7 +24514,12 @@ index b27ef5e6f..226c04419 100644 SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a -@@ -315,6 +337,9 @@ const ( + SCM_TIMESTAMPNS = 0x23 ++ SCM_TS_OPT_ID = 0x51 + SCM_TXTIME = 0x3d + SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 +@@ -315,6 +340,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 @@ -22477,10 +24530,10 @@ index b27ef5e6f..226c04419 100644 SO_DONTROUTE = 0x10 SO_ERROR = 0x1007 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go -index 237a2cefb..3122737cd 100644 +index 237a2cefb..c22427261 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go -@@ -108,6 +108,7 @@ const ( +@@ -108,12 +108,15 @@ const ( HIDIOCGRAWINFO = 0x40084803 HIDIOCGRDESC = 0x50044802 HIDIOCGRDESCSIZE = 0x40044801 @@ -22488,7 +24541,15 @@ index 237a2cefb..3122737cd 100644 HUPCL = 0x4000 ICANON = 0x100 IEXTEN = 0x400 -@@ -152,9 +153,14 @@ const ( + IN_CLOEXEC = 0x80000 + IN_NONBLOCK = 0x800 + IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 ++ IPV6_FLOWINFO_MASK = 0xfffffff ++ IPV6_FLOWLABEL_MASK = 0xfffff + ISIG = 0x80 + IUCLC = 0x1000 + IXOFF = 0x400 +@@ -152,9 +155,14 @@ const ( NL3 = 0x300 NLDLY = 0x300 NOFLSH = 0x80000000 @@ -22503,7 +24564,7 @@ index 237a2cefb..3122737cd 100644 NS_GET_USERNS = 0x2000b701 OLCUC = 0x4 ONLCR = 0x2 -@@ -232,6 +238,20 @@ const ( +@@ -232,6 +240,20 @@ const ( PPPIOCXFERUNIT = 0x2000744e PROT_SAO = 0x10 PR_SET_PTRACER_ANY = 0xffffffff @@ -22524,7 +24585,7 @@ index 237a2cefb..3122737cd 100644 PTRACE_GETEVRREGS = 0x14 PTRACE_GETFPREGS = 0xe PTRACE_GETREGS64 = 0x16 -@@ -332,6 +352,8 @@ const ( +@@ -332,10 +354,13 @@ const ( RTC_WIE_ON = 0x2000700f RTC_WKALM_RD = 0x40287010 RTC_WKALM_SET = 0x8028700f @@ -22533,7 +24594,12 @@ index 237a2cefb..3122737cd 100644 SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a -@@ -370,6 +392,9 @@ const ( + SCM_TIMESTAMPNS = 0x23 ++ SCM_TS_OPT_ID = 0x51 + SCM_TXTIME = 0x3d + SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 +@@ -370,6 +395,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 @@ -22544,10 +24610,10 @@ index 237a2cefb..3122737cd 100644 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go -index 4a5c555a3..eb5d3467e 100644 +index 4a5c555a3..6270c8ee1 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go -@@ -108,6 +108,7 @@ const ( +@@ -108,12 +108,15 @@ const ( HIDIOCGRAWINFO = 0x40084803 HIDIOCGRDESC = 0x50044802 HIDIOCGRDESCSIZE = 0x40044801 @@ -22555,7 +24621,15 @@ index 4a5c555a3..eb5d3467e 100644 HUPCL = 0x4000 ICANON = 0x100 IEXTEN = 0x400 -@@ -152,9 +153,14 @@ const ( + IN_CLOEXEC = 0x80000 + IN_NONBLOCK = 0x800 + IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 ++ IPV6_FLOWINFO_MASK = 0xfffffff ++ IPV6_FLOWLABEL_MASK = 0xfffff + ISIG = 0x80 + IUCLC = 0x1000 + IXOFF = 0x400 +@@ -152,9 +155,14 @@ const ( NL3 = 0x300 NLDLY = 0x300 NOFLSH = 0x80000000 @@ -22570,7 +24644,7 @@ index 4a5c555a3..eb5d3467e 100644 NS_GET_USERNS = 0x2000b701 OLCUC = 0x4 ONLCR = 0x2 -@@ -232,6 +238,20 @@ const ( +@@ -232,6 +240,20 @@ const ( PPPIOCXFERUNIT = 0x2000744e PROT_SAO = 0x10 PR_SET_PTRACER_ANY = 0xffffffffffffffff @@ -22591,7 +24665,7 @@ index 4a5c555a3..eb5d3467e 100644 PTRACE_GETEVRREGS = 0x14 PTRACE_GETFPREGS = 0xe PTRACE_GETREGS64 = 0x16 -@@ -336,6 +356,8 @@ const ( +@@ -336,10 +358,13 @@ const ( RTC_WIE_ON = 0x2000700f RTC_WKALM_RD = 0x40287010 RTC_WKALM_SET = 0x8028700f @@ -22600,7 +24674,12 @@ index 4a5c555a3..eb5d3467e 100644 SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a -@@ -374,6 +396,9 @@ const ( + SCM_TIMESTAMPNS = 0x23 ++ SCM_TS_OPT_ID = 0x51 + SCM_TXTIME = 0x3d + SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 +@@ -374,6 +399,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 @@ -22611,10 +24690,10 @@ index 4a5c555a3..eb5d3467e 100644 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go -index a02fb49a5..e921ebc60 100644 +index a02fb49a5..9966c1941 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go -@@ -108,6 +108,7 @@ const ( +@@ -108,12 +108,15 @@ const ( HIDIOCGRAWINFO = 0x40084803 HIDIOCGRDESC = 0x50044802 HIDIOCGRDESCSIZE = 0x40044801 @@ -22622,7 +24701,15 @@ index a02fb49a5..e921ebc60 100644 HUPCL = 0x4000 ICANON = 0x100 IEXTEN = 0x400 -@@ -152,9 +153,14 @@ const ( + IN_CLOEXEC = 0x80000 + IN_NONBLOCK = 0x800 + IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 ++ IPV6_FLOWINFO_MASK = 0xffffff0f ++ IPV6_FLOWLABEL_MASK = 0xffff0f00 + ISIG = 0x80 + IUCLC = 0x1000 + IXOFF = 0x400 +@@ -152,9 +155,14 @@ const ( NL3 = 0x300 NLDLY = 0x300 NOFLSH = 0x80000000 @@ -22637,7 +24724,7 @@ index a02fb49a5..e921ebc60 100644 NS_GET_USERNS = 0x2000b701 OLCUC = 0x4 ONLCR = 0x2 -@@ -232,6 +238,20 @@ const ( +@@ -232,6 +240,20 @@ const ( PPPIOCXFERUNIT = 0x2000744e PROT_SAO = 0x10 PR_SET_PTRACER_ANY = 0xffffffffffffffff @@ -22658,7 +24745,7 @@ index a02fb49a5..e921ebc60 100644 PTRACE_GETEVRREGS = 0x14 PTRACE_GETFPREGS = 0xe PTRACE_GETREGS64 = 0x16 -@@ -336,6 +356,8 @@ const ( +@@ -336,10 +358,13 @@ const ( RTC_WIE_ON = 0x2000700f RTC_WKALM_RD = 0x40287010 RTC_WKALM_SET = 0x8028700f @@ -22667,7 +24754,12 @@ index a02fb49a5..e921ebc60 100644 SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a -@@ -374,6 +396,9 @@ const ( + SCM_TIMESTAMPNS = 0x23 ++ SCM_TS_OPT_ID = 0x51 + SCM_TXTIME = 0x3d + SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 +@@ -374,6 +399,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 @@ -22678,10 +24770,10 @@ index a02fb49a5..e921ebc60 100644 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go -index e26a7c61b..38ba81c55 100644 +index e26a7c61b..848e5fcc4 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go -@@ -108,6 +108,7 @@ const ( +@@ -108,12 +108,15 @@ const ( HIDIOCGRAWINFO = 0x80084803 HIDIOCGRDESC = 0x90044802 HIDIOCGRDESCSIZE = 0x80044801 @@ -22689,7 +24781,15 @@ index e26a7c61b..38ba81c55 100644 HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 -@@ -150,9 +151,14 @@ const ( + IN_CLOEXEC = 0x80000 + IN_NONBLOCK = 0x800 + IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 ++ IPV6_FLOWINFO_MASK = 0xffffff0f ++ IPV6_FLOWLABEL_MASK = 0xffff0f00 + ISIG = 0x1 + IUCLC = 0x200 + IXOFF = 0x1000 +@@ -150,9 +153,14 @@ const ( NFDBITS = 0x40 NLDLY = 0x100 NOFLSH = 0x80 @@ -22704,7 +24804,7 @@ index e26a7c61b..38ba81c55 100644 NS_GET_USERNS = 0xb701 OLCUC = 0x2 ONLCR = 0x4 -@@ -229,6 +235,20 @@ const ( +@@ -229,6 +237,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x7434 PPPIOCXFERUNIT = 0x744e PR_SET_PTRACER_ANY = 0xffffffffffffffff @@ -22725,7 +24825,7 @@ index e26a7c61b..38ba81c55 100644 PTRACE_GETFDPIC = 0x21 PTRACE_GETFDPIC_EXEC = 0x0 PTRACE_GETFDPIC_INTERP = 0x1 -@@ -268,6 +288,8 @@ const ( +@@ -268,10 +290,13 @@ const ( RTC_WIE_ON = 0x700f RTC_WKALM_RD = 0x80287010 RTC_WKALM_SET = 0x4028700f @@ -22734,7 +24834,12 @@ index e26a7c61b..38ba81c55 100644 SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a -@@ -306,6 +328,9 @@ const ( + SCM_TIMESTAMPNS = 0x23 ++ SCM_TS_OPT_ID = 0x51 + SCM_TXTIME = 0x3d + SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 +@@ -306,6 +331,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 @@ -22745,10 +24850,10 @@ index e26a7c61b..38ba81c55 100644 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go -index c48f7c210..71f040097 100644 +index c48f7c210..669b2adb8 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go -@@ -108,6 +108,7 @@ const ( +@@ -108,12 +108,15 @@ const ( HIDIOCGRAWINFO = 0x80084803 HIDIOCGRDESC = 0x90044802 HIDIOCGRDESCSIZE = 0x80044801 @@ -22756,7 +24861,15 @@ index c48f7c210..71f040097 100644 HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 -@@ -150,9 +151,14 @@ const ( + IN_CLOEXEC = 0x80000 + IN_NONBLOCK = 0x800 + IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 ++ IPV6_FLOWINFO_MASK = 0xfffffff ++ IPV6_FLOWLABEL_MASK = 0xfffff + ISIG = 0x1 + IUCLC = 0x200 + IXOFF = 0x1000 +@@ -150,9 +153,14 @@ const ( NFDBITS = 0x40 NLDLY = 0x100 NOFLSH = 0x80 @@ -22771,7 +24884,7 @@ index c48f7c210..71f040097 100644 NS_GET_USERNS = 0xb701 OLCUC = 0x2 ONLCR = 0x4 -@@ -229,6 +235,20 @@ const ( +@@ -229,6 +237,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x7434 PPPIOCXFERUNIT = 0x744e PR_SET_PTRACER_ANY = 0xffffffffffffffff @@ -22792,7 +24905,7 @@ index c48f7c210..71f040097 100644 PTRACE_DISABLE_TE = 0x5010 PTRACE_ENABLE_TE = 0x5009 PTRACE_GET_LAST_BREAK = 0x5006 -@@ -340,6 +360,8 @@ const ( +@@ -340,10 +362,13 @@ const ( RTC_WIE_ON = 0x700f RTC_WKALM_RD = 0x80287010 RTC_WKALM_SET = 0x4028700f @@ -22801,7 +24914,12 @@ index c48f7c210..71f040097 100644 SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a -@@ -378,6 +400,9 @@ const ( + SCM_TIMESTAMPNS = 0x23 ++ SCM_TS_OPT_ID = 0x51 + SCM_TXTIME = 0x3d + SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 +@@ -378,6 +403,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 @@ -22812,10 +24930,10 @@ index c48f7c210..71f040097 100644 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go -index ad4b9aace..c44a31332 100644 +index ad4b9aace..4834e5751 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go -@@ -112,6 +112,7 @@ const ( +@@ -112,12 +112,15 @@ const ( HIDIOCGRAWINFO = 0x40084803 HIDIOCGRDESC = 0x50044802 HIDIOCGRDESCSIZE = 0x40044801 @@ -22823,7 +24941,15 @@ index ad4b9aace..c44a31332 100644 HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 -@@ -155,9 +156,14 @@ const ( + IN_CLOEXEC = 0x400000 + IN_NONBLOCK = 0x4000 + IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 ++ IPV6_FLOWINFO_MASK = 0xfffffff ++ IPV6_FLOWLABEL_MASK = 0xfffff + ISIG = 0x1 + IUCLC = 0x200 + IXOFF = 0x1000 +@@ -155,9 +158,14 @@ const ( NFDBITS = 0x40 NLDLY = 0x100 NOFLSH = 0x80 @@ -22838,7 +24964,7 @@ index ad4b9aace..c44a31332 100644 NS_GET_USERNS = 0x2000b701 OLCUC = 0x2 ONLCR = 0x4 -@@ -234,6 +240,20 @@ const ( +@@ -234,6 +242,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x20007434 PPPIOCXFERUNIT = 0x2000744e PR_SET_PTRACER_ANY = 0xffffffffffffffff @@ -22859,7 +24985,7 @@ index ad4b9aace..c44a31332 100644 PTRACE_GETFPAREGS = 0x14 PTRACE_GETFPREGS = 0xe PTRACE_GETFPREGS64 = 0x19 -@@ -331,6 +351,8 @@ const ( +@@ -331,10 +353,13 @@ const ( RTC_WIE_ON = 0x2000700f RTC_WKALM_RD = 0x40287010 RTC_WKALM_SET = 0x8028700f @@ -22868,7 +24994,12 @@ index ad4b9aace..c44a31332 100644 SCM_TIMESTAMPING = 0x23 SCM_TIMESTAMPING_OPT_STATS = 0x38 SCM_TIMESTAMPING_PKTINFO = 0x3c -@@ -417,6 +439,9 @@ const ( + SCM_TIMESTAMPNS = 0x21 ++ SCM_TS_OPT_ID = 0x5a + SCM_TXTIME = 0x3f + SCM_WIFI_STATUS = 0x25 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 +@@ -417,6 +442,9 @@ const ( SO_CNX_ADVICE = 0x37 SO_COOKIE = 0x3b SO_DETACH_REUSEPORT_BPF = 0x47 @@ -23030,8 +25161,167 @@ index 1bc1a5adb..5cc1e8eb2 100644 func Getrusage(who int, rusage *Rusage) (err error) { _, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0) if e1 != 0 { +diff --git a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go +index 829b87feb..c6545413c 100644 +--- a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go ++++ b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go +@@ -141,6 +141,16 @@ import ( + //go:cgo_import_dynamic libc_getpeername getpeername "libsocket.so" + //go:cgo_import_dynamic libc_setsockopt setsockopt "libsocket.so" + //go:cgo_import_dynamic libc_recvfrom recvfrom "libsocket.so" ++//go:cgo_import_dynamic libc_getpeerucred getpeerucred "libc.so" ++//go:cgo_import_dynamic libc_ucred_get ucred_get "libc.so" ++//go:cgo_import_dynamic libc_ucred_geteuid ucred_geteuid "libc.so" ++//go:cgo_import_dynamic libc_ucred_getegid ucred_getegid "libc.so" ++//go:cgo_import_dynamic libc_ucred_getruid ucred_getruid "libc.so" ++//go:cgo_import_dynamic libc_ucred_getrgid ucred_getrgid "libc.so" ++//go:cgo_import_dynamic libc_ucred_getsuid ucred_getsuid "libc.so" ++//go:cgo_import_dynamic libc_ucred_getsgid ucred_getsgid "libc.so" ++//go:cgo_import_dynamic libc_ucred_getpid ucred_getpid "libc.so" ++//go:cgo_import_dynamic libc_ucred_free ucred_free "libc.so" + //go:cgo_import_dynamic libc_port_create port_create "libc.so" + //go:cgo_import_dynamic libc_port_associate port_associate "libc.so" + //go:cgo_import_dynamic libc_port_dissociate port_dissociate "libc.so" +@@ -280,6 +290,16 @@ import ( + //go:linkname procgetpeername libc_getpeername + //go:linkname procsetsockopt libc_setsockopt + //go:linkname procrecvfrom libc_recvfrom ++//go:linkname procgetpeerucred libc_getpeerucred ++//go:linkname procucred_get libc_ucred_get ++//go:linkname procucred_geteuid libc_ucred_geteuid ++//go:linkname procucred_getegid libc_ucred_getegid ++//go:linkname procucred_getruid libc_ucred_getruid ++//go:linkname procucred_getrgid libc_ucred_getrgid ++//go:linkname procucred_getsuid libc_ucred_getsuid ++//go:linkname procucred_getsgid libc_ucred_getsgid ++//go:linkname procucred_getpid libc_ucred_getpid ++//go:linkname procucred_free libc_ucred_free + //go:linkname procport_create libc_port_create + //go:linkname procport_associate libc_port_associate + //go:linkname procport_dissociate libc_port_dissociate +@@ -420,6 +440,16 @@ var ( + procgetpeername, + procsetsockopt, + procrecvfrom, ++ procgetpeerucred, ++ procucred_get, ++ procucred_geteuid, ++ procucred_getegid, ++ procucred_getruid, ++ procucred_getrgid, ++ procucred_getsuid, ++ procucred_getsgid, ++ procucred_getpid, ++ procucred_free, + procport_create, + procport_associate, + procport_dissociate, +@@ -2029,6 +2059,90 @@ func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Sockl + + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + ++func getpeerucred(fd uintptr, ucred *uintptr) (err error) { ++ _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procgetpeerucred)), 2, uintptr(fd), uintptr(unsafe.Pointer(ucred)), 0, 0, 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func ucredGet(pid int) (ucred uintptr, err error) { ++ r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procucred_get)), 1, uintptr(pid), 0, 0, 0, 0, 0) ++ ucred = uintptr(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func ucredGeteuid(ucred uintptr) (uid int) { ++ r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_geteuid)), 1, uintptr(ucred), 0, 0, 0, 0, 0) ++ uid = int(r0) ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func ucredGetegid(ucred uintptr) (gid int) { ++ r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getegid)), 1, uintptr(ucred), 0, 0, 0, 0, 0) ++ gid = int(r0) ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func ucredGetruid(ucred uintptr) (uid int) { ++ r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getruid)), 1, uintptr(ucred), 0, 0, 0, 0, 0) ++ uid = int(r0) ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func ucredGetrgid(ucred uintptr) (gid int) { ++ r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getrgid)), 1, uintptr(ucred), 0, 0, 0, 0, 0) ++ gid = int(r0) ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func ucredGetsuid(ucred uintptr) (uid int) { ++ r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getsuid)), 1, uintptr(ucred), 0, 0, 0, 0, 0) ++ uid = int(r0) ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func ucredGetsgid(ucred uintptr) (gid int) { ++ r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getsgid)), 1, uintptr(ucred), 0, 0, 0, 0, 0) ++ gid = int(r0) ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func ucredGetpid(ucred uintptr) (pid int) { ++ r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getpid)), 1, uintptr(ucred), 0, 0, 0, 0, 0) ++ pid = int(r0) ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func ucredFree(ucred uintptr) { ++ sysvicall6(uintptr(unsafe.Pointer(&procucred_free)), 1, uintptr(ucred), 0, 0, 0, 0, 0) ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ + func port_create() (n int, err error) { + r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procport_create)), 0, 0, 0, 0, 0, 0, 0) + n = int(r0) +diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go +index 524b0820c..c79aaff30 100644 +--- a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go ++++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go +@@ -458,4 +458,8 @@ const ( + SYS_LSM_SET_SELF_ATTR = 460 + SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ++ SYS_SETXATTRAT = 463 ++ SYS_GETXATTRAT = 464 ++ SYS_LISTXATTRAT = 465 ++ SYS_REMOVEXATTRAT = 466 + ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go -index d3e38f681..f485dbf45 100644 +index d3e38f681..5eb450695 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go @@ -341,6 +341,7 @@ const ( @@ -23042,8 +25332,30 @@ index d3e38f681..f485dbf45 100644 SYS_PIDFD_SEND_SIGNAL = 424 SYS_IO_URING_SETUP = 425 SYS_IO_URING_ENTER = 426 +@@ -380,4 +381,8 @@ const ( + SYS_LSM_SET_SELF_ATTR = 460 + SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ++ SYS_SETXATTRAT = 463 ++ SYS_GETXATTRAT = 464 ++ SYS_LISTXATTRAT = 465 ++ SYS_REMOVEXATTRAT = 466 + ) +diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go +index 70b35bf3b..05e502974 100644 +--- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go ++++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go +@@ -422,4 +422,8 @@ const ( + SYS_LSM_SET_SELF_ATTR = 460 + SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ++ SYS_SETXATTRAT = 463 ++ SYS_GETXATTRAT = 464 ++ SYS_LISTXATTRAT = 465 ++ SYS_REMOVEXATTRAT = 466 + ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go -index 6c778c232..1893e2fe8 100644 +index 6c778c232..38c53ec51 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go @@ -85,7 +85,7 @@ const ( @@ -23055,8 +25367,17 @@ index 6c778c232..1893e2fe8 100644 SYS_FSTAT = 80 SYS_SYNC = 81 SYS_FSYNC = 82 +@@ -325,4 +325,8 @@ const ( + SYS_LSM_SET_SELF_ATTR = 460 + SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ++ SYS_SETXATTRAT = 463 ++ SYS_GETXATTRAT = 464 ++ SYS_LISTXATTRAT = 465 ++ SYS_REMOVEXATTRAT = 466 + ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go -index 37281cf51..16a4017da 100644 +index 37281cf51..31d2e71a1 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go @@ -84,6 +84,8 @@ const ( @@ -23068,8 +25389,108 @@ index 37281cf51..16a4017da 100644 SYS_SYNC = 81 SYS_FSYNC = 82 SYS_FDATASYNC = 83 +@@ -319,4 +321,8 @@ const ( + SYS_LSM_SET_SELF_ATTR = 460 + SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ++ SYS_SETXATTRAT = 463 ++ SYS_GETXATTRAT = 464 ++ SYS_LISTXATTRAT = 465 ++ SYS_REMOVEXATTRAT = 466 + ) +diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go +index 7e567f1ef..f4184a336 100644 +--- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go ++++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go +@@ -442,4 +442,8 @@ const ( + SYS_LSM_SET_SELF_ATTR = 4460 + SYS_LSM_LIST_MODULES = 4461 + SYS_MSEAL = 4462 ++ SYS_SETXATTRAT = 4463 ++ SYS_GETXATTRAT = 4464 ++ SYS_LISTXATTRAT = 4465 ++ SYS_REMOVEXATTRAT = 4466 + ) +diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go +index 38ae55e5e..05b996227 100644 +--- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go ++++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go +@@ -372,4 +372,8 @@ const ( + SYS_LSM_SET_SELF_ATTR = 5460 + SYS_LSM_LIST_MODULES = 5461 + SYS_MSEAL = 5462 ++ SYS_SETXATTRAT = 5463 ++ SYS_GETXATTRAT = 5464 ++ SYS_LISTXATTRAT = 5465 ++ SYS_REMOVEXATTRAT = 5466 + ) +diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go +index 55e92e60a..43a256e9e 100644 +--- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go ++++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go +@@ -372,4 +372,8 @@ const ( + SYS_LSM_SET_SELF_ATTR = 5460 + SYS_LSM_LIST_MODULES = 5461 + SYS_MSEAL = 5462 ++ SYS_SETXATTRAT = 5463 ++ SYS_GETXATTRAT = 5464 ++ SYS_LISTXATTRAT = 5465 ++ SYS_REMOVEXATTRAT = 5466 + ) +diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go +index 60658d6a0..eea5ddfc2 100644 +--- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go ++++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go +@@ -442,4 +442,8 @@ const ( + SYS_LSM_SET_SELF_ATTR = 4460 + SYS_LSM_LIST_MODULES = 4461 + SYS_MSEAL = 4462 ++ SYS_SETXATTRAT = 4463 ++ SYS_GETXATTRAT = 4464 ++ SYS_LISTXATTRAT = 4465 ++ SYS_REMOVEXATTRAT = 4466 + ) +diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go +index e203e8a7e..0d777bfbb 100644 +--- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go ++++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go +@@ -449,4 +449,8 @@ const ( + SYS_LSM_SET_SELF_ATTR = 460 + SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ++ SYS_SETXATTRAT = 463 ++ SYS_GETXATTRAT = 464 ++ SYS_LISTXATTRAT = 465 ++ SYS_REMOVEXATTRAT = 466 + ) +diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go +index 5944b97d5..b44636502 100644 +--- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go ++++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go +@@ -421,4 +421,8 @@ const ( + SYS_LSM_SET_SELF_ATTR = 460 + SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ++ SYS_SETXATTRAT = 463 ++ SYS_GETXATTRAT = 464 ++ SYS_LISTXATTRAT = 465 ++ SYS_REMOVEXATTRAT = 466 + ) +diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go +index c66d416da..0c7d21c18 100644 +--- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go ++++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go +@@ -421,4 +421,8 @@ const ( + SYS_LSM_SET_SELF_ATTR = 460 + SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ++ SYS_SETXATTRAT = 463 ++ SYS_GETXATTRAT = 464 ++ SYS_LISTXATTRAT = 465 ++ SYS_REMOVEXATTRAT = 466 + ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go -index 9889f6a55..a5459e766 100644 +index 9889f6a55..840539169 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go @@ -84,7 +84,7 @@ const ( @@ -23081,6 +25502,41 @@ index 9889f6a55..a5459e766 100644 SYS_FSTAT = 80 SYS_SYNC = 81 SYS_FSYNC = 82 +@@ -326,4 +326,8 @@ const ( + SYS_LSM_SET_SELF_ATTR = 460 + SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ++ SYS_SETXATTRAT = 463 ++ SYS_GETXATTRAT = 464 ++ SYS_LISTXATTRAT = 465 ++ SYS_REMOVEXATTRAT = 466 + ) +diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go +index 01d86825b..fcf1b790d 100644 +--- a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go ++++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go +@@ -387,4 +387,8 @@ const ( + SYS_LSM_SET_SELF_ATTR = 460 + SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ++ SYS_SETXATTRAT = 463 ++ SYS_GETXATTRAT = 464 ++ SYS_LISTXATTRAT = 465 ++ SYS_REMOVEXATTRAT = 466 + ) +diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go +index 7b703e77c..52d15b5f9 100644 +--- a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go ++++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go +@@ -400,4 +400,8 @@ const ( + SYS_LSM_SET_SELF_ATTR = 460 + SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ++ SYS_SETXATTRAT = 463 ++ SYS_GETXATTRAT = 464 ++ SYS_LISTXATTRAT = 465 ++ SYS_REMOVEXATTRAT = 466 + ) diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go index 091d107f3..17c53bd9b 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go @@ -23376,7 +25832,7 @@ index cc986c790..b5d17414f 100644 type CapRights struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go -index 7f1961b90..5537148dc 100644 +index 7f1961b90..a46abe647 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -87,31 +87,35 @@ type StatxTimestamp struct { @@ -23740,7 +26196,7 @@ index 7f1961b90..5537148dc 100644 NL80211_ATTR_MAC_MASK = 0xd7 NL80211_ATTR_MAX_AP_ASSOC_STA = 0xca - NL80211_ATTR_MAX = 0x14a -+ NL80211_ATTR_MAX = 0x14c ++ NL80211_ATTR_MAX = 0x14d NL80211_ATTR_MAX_CRIT_PROT_DURATION = 0xb4 NL80211_ATTR_MAX_CSA_COUNTERS = 0xce NL80211_ATTR_MAX_MATCH_SETS = 0x85 @@ -23753,6 +26209,21 @@ index 7f1961b90..5537148dc 100644 NL80211_FREQUENCY_ATTR_MAX_TX_POWER = 0x6 NL80211_FREQUENCY_ATTR_NO_10MHZ = 0x11 NL80211_FREQUENCY_ATTR_NO_160MHZ = 0xc +@@ -5381,7 +5519,7 @@ const ( + NL80211_MNTR_FLAG_CONTROL = 0x3 + NL80211_MNTR_FLAG_COOK_FRAMES = 0x5 + NL80211_MNTR_FLAG_FCSFAIL = 0x1 +- NL80211_MNTR_FLAG_MAX = 0x6 ++ NL80211_MNTR_FLAG_MAX = 0x7 + NL80211_MNTR_FLAG_OTHER_BSS = 0x4 + NL80211_MNTR_FLAG_PLCPFAIL = 0x2 + NL80211_MPATH_FLAG_ACTIVE = 0x1 +@@ -6036,3 +6174,5 @@ type SockDiagReq struct { + Family uint8 + Protocol uint8 + } ++ ++const RTM_NEWNVLAN = 0x70 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go index 15adc0414..ad05b51a6 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go @@ -24353,489 +26824,59 @@ index 49c9fc978..547802b0f 100644 // encoding language of "pt". func (d *Decoder) Language() language.Tag { return d.tag } -diff --git a/vendor/k8s.io/apiserver/pkg/features/kube_features.go b/vendor/k8s.io/apiserver/pkg/features/kube_features.go -index bae04d954..31c4d9021 100644 ---- a/vendor/k8s.io/apiserver/pkg/features/kube_features.go -+++ b/vendor/k8s.io/apiserver/pkg/features/kube_features.go -@@ -335,7 +335,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS - - APIServerTracing: {Default: true, PreRelease: featuregate.Beta}, - -- APIServingWithRoutine: {Default: true, PreRelease: featuregate.Beta}, -+ APIServingWithRoutine: {Default: false, PreRelease: featuregate.Alpha}, - - ValidatingAdmissionPolicy: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.32 - -diff --git a/vendor/k8s.io/apiserver/pkg/storage/cacher/cacher.go b/vendor/k8s.io/apiserver/pkg/storage/cacher/cacher.go -index 1e6cc4d02..7579ac37e 100644 ---- a/vendor/k8s.io/apiserver/pkg/storage/cacher/cacher.go -+++ b/vendor/k8s.io/apiserver/pkg/storage/cacher/cacher.go -@@ -51,7 +51,8 @@ import ( - ) - - var ( -- emptyFunc = func(bool) {} -+ emptyFunc = func(bool) {} -+ coreNamespaceResource = schema.GroupResource{Group: "", Resource: "namespaces"} - ) - - const ( -@@ -549,6 +550,12 @@ func (c *Cacher) Watch(ctx context.Context, key string, opts storage.ListOptions - scope.name = selectorName - } - -+ // for request like '/api/v1/watch/namespaces/*', set scope.namespace to empty. -+ // namespaces don't populate metadata.namespace in ObjFields. -+ if c.groupResource == coreNamespaceResource && len(scope.namespace) > 0 && scope.namespace == scope.name { -+ scope.namespace = "" -+ } -+ - triggerValue, triggerSupported := "", false - if c.indexedTrigger != nil { - for _, field := range pred.IndexFields { -diff --git a/vendor/k8s.io/kubernetes/pkg/features/kube_features.go b/vendor/k8s.io/kubernetes/pkg/features/kube_features.go -index bfd01e1e0..86d136919 100644 ---- a/vendor/k8s.io/kubernetes/pkg/features/kube_features.go -+++ b/vendor/k8s.io/kubernetes/pkg/features/kube_features.go -@@ -541,7 +541,8 @@ const ( - // alpha: v1.27 - // beta: v1.30 - // -- // Enables querying logs of node services using the /logs endpoint -+ // Enables querying logs of node services using the /logs endpoint. Enabling this feature has security implications. -+ // The recommendation is to enable it on a need basis for debugging purposes and disabling otherwise. - NodeLogQuery featuregate.Feature = "NodeLogQuery" - - // owner: @xing-yang @sonasingh46 -@@ -1267,7 +1268,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS - - genericfeatures.APIServerTracing: {Default: true, PreRelease: featuregate.Beta}, - -- genericfeatures.APIServingWithRoutine: {Default: true, PreRelease: featuregate.Beta}, -+ genericfeatures.APIServingWithRoutine: {Default: false, PreRelease: featuregate.Alpha}, - - genericfeatures.ConsistentListFromCache: {Default: false, PreRelease: featuregate.Alpha}, - -diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer.go b/vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer.go -index 3ac4dcffe..a6837fa65 100644 ---- a/vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer.go -+++ b/vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer.go -@@ -444,7 +444,8 @@ func (w *AtomicWriter) writePayloadToDir(payload map[string]FileProjection, dir - if fileProjection.FsUser == nil { - continue - } -- if err := os.Chown(fullPath, int(*fileProjection.FsUser), -1); err != nil { -+ -+ if err := w.chown(fullPath, int(*fileProjection.FsUser), -1); err != nil { - klog.Errorf("%s: unable to change file %s with owner %v: %v", w.logContext, fullPath, int(*fileProjection.FsUser), err) - return err - } -diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer_linux.go b/vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer_linux.go -new file mode 100644 -index 000000000..c12a0f4cd ---- /dev/null -+++ b/vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer_linux.go -@@ -0,0 +1,27 @@ -+//go:build linux -+// +build linux -+ -+/* -+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 util -+ -+import "os" -+ -+// chown changes the numeric uid and gid of the named file. -+func (w *AtomicWriter) chown(name string, uid, gid int) error { -+ return os.Chown(name, uid, gid) -+} -diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer_unsupported.go b/vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer_unsupported.go -new file mode 100644 -index 000000000..cdfb83e63 ---- /dev/null -+++ b/vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer_unsupported.go -@@ -0,0 +1,33 @@ -+//go:build !linux -+// +build !linux -+ -+/* -+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 util -+ -+import ( -+ "runtime" -+ -+ "k8s.io/klog/v2" -+) -+ -+// chown changes the numeric uid and gid of the named file. -+// This is a no-op on unsupported platforms. -+func (w *AtomicWriter) chown(name string, uid, _ /* gid */ int) error { -+ klog.Warningf("%s: skipping change of Linux owner %v for file %s; unsupported on %s", w.logContext, uid, name, runtime.GOOS) -+ return nil -+} -diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/device_util_linux.go b/vendor/k8s.io/kubernetes/pkg/volume/util/device_util_linux.go -index 66ac77835..18cbec072 100644 ---- a/vendor/k8s.io/kubernetes/pkg/volume/util/device_util_linux.go -+++ b/vendor/k8s.io/kubernetes/pkg/volume/util/device_util_linux.go -@@ -31,8 +31,13 @@ import ( - "k8s.io/klog/v2" - ) - --// FindMultipathDeviceForDevice given a device name like /dev/sdx, find the devicemapper parent -+// FindMultipathDeviceForDevice given a device name like /dev/sdx, find the devicemapper parent. If called with a device -+// already resolved to devicemapper, do nothing. - func (handler *deviceHandler) FindMultipathDeviceForDevice(device string) string { -+ if strings.HasPrefix(device, "/dev/dm-") { -+ return device -+ } -+ - io := handler.getIo - disk, err := findDeviceForPath(device, io) - if err != nil { -diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/recyclerclient/recycler_client.go b/vendor/k8s.io/kubernetes/pkg/volume/util/recyclerclient/recycler_client.go -index b7197dbdf..e438ba21e 100644 ---- a/vendor/k8s.io/kubernetes/pkg/volume/util/recyclerclient/recycler_client.go -+++ b/vendor/k8s.io/kubernetes/pkg/volume/util/recyclerclient/recycler_client.go -@@ -18,11 +18,12 @@ package recyclerclient - - import ( - "context" -+ "errors" - "fmt" - "sync" - - "k8s.io/api/core/v1" -- "k8s.io/apimachinery/pkg/api/errors" -+ apierrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/fields" - "k8s.io/apimachinery/pkg/watch" -@@ -72,7 +73,7 @@ func internalRecycleVolumeByWatchingPodUntilCompletion(pvName string, pod *v1.Po - // Start the pod - _, err = recyclerClient.CreatePod(pod) - if err != nil { -- if errors.IsAlreadyExists(err) { -+ if apierrors.IsAlreadyExists(err) { - deleteErr := recyclerClient.DeletePod(pod.Name, pod.Namespace) - if deleteErr != nil { - return fmt.Errorf("failed to delete old recycler pod %s/%s: %s", pod.Namespace, pod.Name, deleteErr) -@@ -128,7 +129,7 @@ func waitForPod(pod *v1.Pod, recyclerClient recyclerClient, podCh <-chan watch.E - } - if pod.Status.Phase == v1.PodFailed { - if pod.Status.Message != "" { -- return fmt.Errorf(pod.Status.Message) -+ return errors.New(pod.Status.Message) - } - return fmt.Errorf("pod failed, pod.Status.Message unknown") - } -diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/util.go b/vendor/k8s.io/kubernetes/pkg/volume/util/util.go -index 601dc6460..d1691cd80 100644 ---- a/vendor/k8s.io/kubernetes/pkg/volume/util/util.go -+++ b/vendor/k8s.io/kubernetes/pkg/volume/util/util.go -@@ -575,44 +575,6 @@ func IsLocalEphemeralVolume(volume v1.Volume) bool { - volume.ConfigMap != nil - } - --// GetLocalPersistentVolumeNodeNames returns the node affinity node name(s) for --// local PersistentVolumes. nil is returned if the PV does not have any --// specific node affinity node selector terms and match expressions. --// PersistentVolume with node affinity has select and match expressions --// in the form of: --// --// nodeAffinity: --// required: --// nodeSelectorTerms: --// - matchExpressions: --// - key: kubernetes.io/hostname --// operator: In --// values: --// - --// - --func GetLocalPersistentVolumeNodeNames(pv *v1.PersistentVolume) []string { -- if pv == nil || pv.Spec.NodeAffinity == nil || pv.Spec.NodeAffinity.Required == nil { -- return nil -- } -- -- var result sets.Set[string] -- for _, term := range pv.Spec.NodeAffinity.Required.NodeSelectorTerms { -- var nodes sets.Set[string] -- for _, matchExpr := range term.MatchExpressions { -- if matchExpr.Key == v1.LabelHostname && matchExpr.Operator == v1.NodeSelectorOpIn { -- if nodes == nil { -- nodes = sets.New(matchExpr.Values...) -- } else { -- nodes = nodes.Intersection(sets.New(matchExpr.Values...)) -- } -- } -- } -- result = result.Union(nodes) -- } -- -- return sets.List(result) --} -- - // GetPodVolumeNames returns names of volumes that are used in a pod, - // either as filesystem mount or raw block device, together with list - // of all SELinux contexts of all containers that use the volumes. -diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/debug/resource_usage_gatherer.go b/vendor/k8s.io/kubernetes/test/e2e/framework/debug/resource_usage_gatherer.go -index 9c6537ed9..7e6875b49 100644 ---- a/vendor/k8s.io/kubernetes/test/e2e/framework/debug/resource_usage_gatherer.go -+++ b/vendor/k8s.io/kubernetes/test/e2e/framework/debug/resource_usage_gatherer.go -@@ -21,6 +21,7 @@ import ( - "bytes" - "context" - "encoding/json" -+ "errors" - "fmt" - "math" - "regexp" -@@ -595,7 +596,7 @@ func (g *ContainerResourceGatherer) StopAndSummarize(percentiles []int, constrai - } - } - if len(violatedConstraints) > 0 { -- return &summary, fmt.Errorf(strings.Join(violatedConstraints, "\n")) -+ return &summary, errors.New(strings.Join(violatedConstraints, "\n")) - } - return &summary, nil - } -diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/flake_reporting_util.go b/vendor/k8s.io/kubernetes/test/e2e/framework/flake_reporting_util.go -index 36d9baa98..103345fb6 100644 ---- a/vendor/k8s.io/kubernetes/test/e2e/framework/flake_reporting_util.go -+++ b/vendor/k8s.io/kubernetes/test/e2e/framework/flake_reporting_util.go -@@ -57,7 +57,7 @@ func (f *FlakeReport) RecordFlakeIfError(err error, optionalDescription ...inter - if desc != "" { - msg = fmt.Sprintf("%v (Description: %v)", msg, desc) - } -- Logf(msg) -+ Logf("%s", msg) - f.lock.Lock() - defer f.lock.Unlock() - f.Flakes = append(f.Flakes, msg) -diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/framework.go b/vendor/k8s.io/kubernetes/test/e2e/framework/framework.go -index 954becb63..7ece76bae 100644 ---- a/vendor/k8s.io/kubernetes/test/e2e/framework/framework.go -+++ b/vendor/k8s.io/kubernetes/test/e2e/framework/framework.go -@@ -311,7 +311,7 @@ func printSummaries(summaries []TestDataSummary, testBaseName string) { - switch TestContext.OutputPrintType { - case "hr": - if TestContext.ReportDir == "" { -- Logf(summaries[i].PrintHumanReadable()) -+ Logf("%s", summaries[i].PrintHumanReadable()) - } else { - // TODO: learn to extract test name and append it to the kind instead of timestamp. - filePath := path.Join(TestContext.ReportDir, summaries[i].SummaryKind()+"_"+testBaseName+"_"+now.Format(time.RFC3339)+".txt") -@@ -393,7 +393,7 @@ func (f *Framework) AfterEach(ctx context.Context) { - for namespaceKey, namespaceErr := range nsDeletionErrors { - messages = append(messages, fmt.Sprintf("Couldn't delete ns: %q: %s (%#v)", namespaceKey, namespaceErr, namespaceErr)) - } -- Failf(strings.Join(messages, ",")) -+ Fail(strings.Join(messages, ",")) - } - }() - -diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/node/resource.go b/vendor/k8s.io/kubernetes/test/e2e/framework/node/resource.go -index a57473bab..a7750399c 100644 ---- a/vendor/k8s.io/kubernetes/test/e2e/framework/node/resource.go -+++ b/vendor/k8s.io/kubernetes/test/e2e/framework/node/resource.go -@@ -128,7 +128,7 @@ func isNodeConditionSetAsExpected(node *v1.Node, conditionType v1.NodeConditionT - conditionType, node.Name, cond.Status == v1.ConditionTrue, taints) - } - if !silent { -- framework.Logf(msg) -+ framework.Logf("%s", msg) - } - return false - } -@@ -822,6 +822,6 @@ func verifyThatTaintIsGone(ctx context.Context, c clientset.Interface, nodeName - // TODO use wrapper methods in expect.go after removing core e2e dependency on node - gomega.ExpectWithOffset(2, err).NotTo(gomega.HaveOccurred()) - if taintExists(nodeUpdated.Spec.Taints, taint) { -- framework.Failf("Failed removing taint " + taint.ToString() + " of the node " + nodeName) -+ framework.Fail("Failed removing taint " + taint.ToString() + " of the node " + nodeName) - } - } -diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/skipper/skipper.go b/vendor/k8s.io/kubernetes/test/e2e/framework/skipper/skipper.go -index 4a509b90a..169f5995e 100644 ---- a/vendor/k8s.io/kubernetes/test/e2e/framework/skipper/skipper.go -+++ b/vendor/k8s.io/kubernetes/test/e2e/framework/skipper/skipper.go -@@ -46,10 +46,13 @@ func Skipf(format string, args ...interface{}) { - panic("unreachable") - } - -+// Skip is an alias for ginkgo.Skip. -+var Skip = ginkgo.Skip -+ - // SkipUnlessAtLeast skips if the value is less than the minValue. - func SkipUnlessAtLeast(value int, minValue int, message string) { - if value < minValue { -- skipInternalf(1, message) -+ skipInternalf(1, "%s", message) - } - } - -diff --git a/vendor/k8s.io/kubernetes/test/utils/density_utils.go b/vendor/k8s.io/kubernetes/test/utils/density_utils.go -index 23917ad9f..e0747c489 100644 ---- a/vendor/k8s.io/kubernetes/test/utils/density_utils.go -+++ b/vendor/k8s.io/kubernetes/test/utils/density_utils.go -@@ -18,6 +18,7 @@ package utils - - import ( - "context" -+ "errors" - "fmt" - "strings" - "time" -@@ -99,7 +100,7 @@ func VerifyLabelsRemoved(c clientset.Interface, nodeName string, labelKeys []str - } - for _, labelKey := range labelKeys { - if node.Labels != nil && len(node.Labels[labelKey]) != 0 { -- return fmt.Errorf("Failed removing label " + labelKey + " of the node " + nodeName) -+ return errors.New("Failed removing label " + labelKey + " of the node " + nodeName) - } - } - return nil -diff --git a/vendor/k8s.io/kubernetes/test/utils/deployment.go b/vendor/k8s.io/kubernetes/test/utils/deployment.go -index 60f20751a..3c287b0b7 100644 ---- a/vendor/k8s.io/kubernetes/test/utils/deployment.go -+++ b/vendor/k8s.io/kubernetes/test/utils/deployment.go -@@ -18,6 +18,7 @@ package utils - - import ( - "context" -+ "errors" - "fmt" - "time" - -@@ -226,7 +227,7 @@ func WaitForDeploymentRevisionAndImage(c clientset.Interface, ns, deploymentName - }) - if wait.Interrupted(err) { - LogReplicaSetsOfDeployment(deployment, nil, newRS, logf) -- err = fmt.Errorf(reason) -+ err = errors.New(reason) - } - if newRS == nil { - return fmt.Errorf("deployment %q failed to create new replica set", deploymentName) -diff --git a/vendor/k8s.io/kubernetes/test/utils/image/manifest.go b/vendor/k8s.io/kubernetes/test/utils/image/manifest.go -index 9fae113f4..9372e7d18 100644 ---- a/vendor/k8s.io/kubernetes/test/utils/image/manifest.go -+++ b/vendor/k8s.io/kubernetes/test/utils/image/manifest.go -@@ -237,8 +237,8 @@ func initImageConfigs(list RegistryList) (map[ImageID]Config, map[ImageID]Config - configs[BusyBox] = Config{list.PromoterE2eRegistry, "busybox", "1.36.1-1"} - configs[CudaVectorAdd] = Config{list.PromoterE2eRegistry, "cuda-vector-add", "1.0"} - configs[CudaVectorAdd2] = Config{list.PromoterE2eRegistry, "cuda-vector-add", "2.3"} -- configs[DistrolessIptables] = Config{list.BuildImageRegistry, "distroless-iptables", "v0.5.6"} -- configs[Etcd] = Config{list.GcEtcdRegistry, "etcd", "3.5.12-0"} -+ configs[DistrolessIptables] = Config{list.BuildImageRegistry, "distroless-iptables", "v0.5.13"} -+ configs[Etcd] = Config{list.GcEtcdRegistry, "etcd", "3.5.15-0"} - configs[Httpd] = Config{list.PromoterE2eRegistry, "httpd", "2.4.38-4"} - configs[HttpdNew] = Config{list.PromoterE2eRegistry, "httpd", "2.4.39-4"} - configs[InvalidRegistryImage] = Config{list.InvalidRegistry, "alpine", "3.1"} -diff --git a/vendor/k8s.io/kubernetes/test/utils/runners.go b/vendor/k8s.io/kubernetes/test/utils/runners.go -index 3fb9b58dc..f5fa5c2a0 100644 ---- a/vendor/k8s.io/kubernetes/test/utils/runners.go -+++ b/vendor/k8s.io/kubernetes/test/utils/runners.go -@@ -825,7 +825,7 @@ func (config *RCConfig) start(ctx context.Context) error { - *config.CreatedPods = startupStatus.Created - } - if !config.Silent { -- config.RCConfigLog(startupStatus.String(config.Name)) -+ config.RCConfigLog("%s", startupStatus.String(config.Name)) - } - - if config.PodStatusFile != nil { -@@ -849,8 +849,8 @@ func (config *RCConfig) start(ctx context.Context) error { - if podDeletionsCount > config.MaxAllowedPodDeletions { - // Number of pods which disappeared is over threshold - err := fmt.Errorf("%d pods disappeared for %s: %v", podDeletionsCount, config.Name, strings.Join(deletedPods, ", ")) -- config.RCConfigLog(err.Error()) -- config.RCConfigLog(diff.String(sets.NewString())) -+ config.RCConfigLog("%s", err.Error()) -+ config.RCConfigLog("%s", diff.String(sets.NewString())) - return err - } - diff --git a/vendor/modules.txt b/vendor/modules.txt -index 7ef495b0d..cfed46c3c 100644 +index 7ef495b0d..d2a16b08b 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt -@@ -279,7 +279,7 @@ github.com/gemalto/kmip-go/ttlv - # github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 - ## explicit - github.com/ghodss/yaml --# github.com/go-jose/go-jose/v4 v4.0.1 -+# github.com/go-jose/go-jose/v4 v4.0.5 - ## explicit; go 1.21 - github.com/go-jose/go-jose/v4 - github.com/go-jose/go-jose/v4/cipher -@@ -611,9 +611,10 @@ github.com/spf13/pflag - # github.com/stoewer/go-strcase v1.2.0 - ## explicit; go 1.11 - github.com/stoewer/go-strcase --# github.com/stretchr/testify v1.9.0 -+# github.com/stretchr/testify v1.10.0 - ## explicit; go 1.17 - github.com/stretchr/testify/assert -+github.com/stretchr/testify/assert/yaml - github.com/stretchr/testify/require - # go.etcd.io/etcd/api/v3 v3.5.10 - ## explicit; go 1.20 -@@ -709,7 +710,7 @@ go.uber.org/zap/internal/pool +@@ -311,7 +311,7 @@ github.com/gogo/protobuf/gogoproto + github.com/gogo/protobuf/proto + github.com/gogo/protobuf/protoc-gen-gogo/descriptor + github.com/gogo/protobuf/sortkeys +-# github.com/golang-jwt/jwt/v5 v5.2.1 ++# github.com/golang-jwt/jwt/v5 v5.2.2 + ## explicit; go 1.18 + github.com/golang-jwt/jwt/v5 + # github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da +@@ -709,8 +709,8 @@ go.uber.org/zap/internal/pool go.uber.org/zap/internal/stacktrace go.uber.org/zap/zapcore go.uber.org/zap/zapgrpc -# golang.org/x/crypto v0.26.0 -+# golang.org/x/crypto v0.32.0 - ## explicit; go 1.20 +-## explicit; go 1.20 ++# golang.org/x/crypto v0.35.0 ++## explicit; go 1.23.0 golang.org/x/crypto/argon2 golang.org/x/crypto/blake2b -@@ -734,7 +735,7 @@ golang.org/x/crypto/ssh/internal/bcrypt_pbkdf + golang.org/x/crypto/blowfish +@@ -734,8 +734,8 @@ golang.org/x/crypto/ssh/internal/bcrypt_pbkdf golang.org/x/exp/constraints golang.org/x/exp/maps golang.org/x/exp/slices -# golang.org/x/net v0.28.0 -+# golang.org/x/net v0.33.0 - ## explicit; go 1.18 +-## explicit; go 1.18 ++# golang.org/x/net v0.36.0 ++## explicit; go 1.23.0 golang.org/x/net/context golang.org/x/net/html + golang.org/x/net/html/atom +@@ -744,6 +744,7 @@ golang.org/x/net/http/httpguts + golang.org/x/net/http2 + golang.org/x/net/http2/hpack + golang.org/x/net/idna ++golang.org/x/net/internal/httpcommon + golang.org/x/net/internal/socks + golang.org/x/net/internal/timeseries + golang.org/x/net/proxy @@ -753,20 +754,20 @@ golang.org/x/net/websocket ## explicit; go 1.18 golang.org/x/oauth2 golang.org/x/oauth2/internal -# golang.org/x/sync v0.8.0 -+# golang.org/x/sync v0.10.0 ++# golang.org/x/sync v0.11.0 ## explicit; go 1.18 golang.org/x/sync/singleflight -# golang.org/x/sys v0.24.0 -+# golang.org/x/sys v0.29.0 ++# golang.org/x/sys v0.30.0 ## explicit; go 1.18 golang.org/x/sys/cpu golang.org/x/sys/plan9 @@ -24843,77 +26884,14 @@ index 7ef495b0d..cfed46c3c 100644 golang.org/x/sys/windows golang.org/x/sys/windows/registry -# golang.org/x/term v0.23.0 -+# golang.org/x/term v0.28.0 ++# golang.org/x/term v0.29.0 ## explicit; go 1.18 golang.org/x/term -# golang.org/x/text v0.17.0 -+# golang.org/x/text v0.21.0 ++# golang.org/x/text v0.22.0 ## explicit; go 1.18 golang.org/x/text/cases golang.org/x/text/encoding -@@ -932,7 +933,7 @@ gopkg.in/yaml.v2 - # gopkg.in/yaml.v3 v3.0.1 - ## explicit - gopkg.in/yaml.v3 --# k8s.io/api v0.30.3 => k8s.io/api v0.30.3 -+# k8s.io/api v0.30.4 => k8s.io/api v0.30.3 - ## explicit; go 1.22.0 - k8s.io/api/admission/v1 - k8s.io/api/admission/v1beta1 -@@ -995,7 +996,7 @@ k8s.io/api/storagemigration/v1alpha1 - k8s.io/apiextensions-apiserver/pkg/apis/apiextensions - k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1 - k8s.io/apiextensions-apiserver/pkg/features --# k8s.io/apimachinery v0.30.3 => k8s.io/apimachinery v0.30.3 -+# k8s.io/apimachinery v0.30.4 => k8s.io/apimachinery v0.30.3 - ## explicit; go 1.22.0 - k8s.io/apimachinery/pkg/api/equality - k8s.io/apimachinery/pkg/api/errors -@@ -1059,7 +1060,7 @@ k8s.io/apimachinery/pkg/watch - k8s.io/apimachinery/third_party/forked/golang/json - k8s.io/apimachinery/third_party/forked/golang/netutil - k8s.io/apimachinery/third_party/forked/golang/reflect --# k8s.io/apiserver v0.30.3 => k8s.io/apiserver v0.30.3 -+# k8s.io/apiserver v0.30.4 => k8s.io/apiserver v0.30.4 - ## explicit; go 1.22.0 - k8s.io/apiserver/pkg/admission - k8s.io/apiserver/pkg/admission/configuration -@@ -1556,7 +1557,7 @@ k8s.io/cloud-provider/names - k8s.io/cloud-provider/options - k8s.io/cloud-provider/volume - k8s.io/cloud-provider/volume/helpers --# k8s.io/component-base v0.30.3 => k8s.io/component-base v0.30.3 -+# k8s.io/component-base v0.30.4 => k8s.io/component-base v0.30.3 - ## explicit; go 1.22.0 - k8s.io/component-base/cli/flag - k8s.io/component-base/config -@@ -1608,7 +1609,7 @@ k8s.io/klog/v2/internal/severity - k8s.io/klog/v2/internal/sloghandler - k8s.io/klog/v2/internal/verbosity - k8s.io/klog/v2/textlogger --# k8s.io/kms v0.30.3 -+# k8s.io/kms v0.30.4 - ## explicit; go 1.22.0 - k8s.io/kms/apis/v1beta1 - k8s.io/kms/apis/v2 -@@ -1643,7 +1644,7 @@ k8s.io/kubectl/pkg/util/podutils - ## explicit; go 1.22.0 - k8s.io/kubelet/pkg/apis - k8s.io/kubelet/pkg/apis/stats/v1alpha1 --# k8s.io/kubernetes v1.30.3 -+# k8s.io/kubernetes v1.30.10 - ## explicit; go 1.22.0 - k8s.io/kubernetes/pkg/api/legacyscheme - k8s.io/kubernetes/pkg/api/service -@@ -1802,7 +1803,7 @@ sigs.k8s.io/yaml/goyaml.v2 - # k8s.io/api => k8s.io/api v0.30.3 - # k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.30.3 - # k8s.io/apimachinery => k8s.io/apimachinery v0.30.3 --# k8s.io/apiserver => k8s.io/apiserver v0.30.3 -+# k8s.io/apiserver => k8s.io/apiserver v0.30.4 - # k8s.io/cli-runtime => k8s.io/cli-runtime v0.30.3 - # k8s.io/client-go => k8s.io/client-go v0.30.3 - # k8s.io/cloud-provider => k8s.io/cloud-provider v0.30.3 -- 2.43.0 diff --git a/images/csi-ceph/patches/0002-Modules-update.patch b/images/csi-ceph/patches/0002-Modules-update.patch new file mode 100644 index 00000000..48105794 --- /dev/null +++ b/images/csi-ceph/patches/0002-Modules-update.patch @@ -0,0 +1,2985 @@ +From c24820cebe118a445ba93ac2750db77ac3fb1f7e Mon Sep 17 00:00:00 2001 +From: "v.oleynikov" +Date: Sat, 22 Mar 2025 20:34:15 +0300 +Subject: [PATCH 2/2] Modules update + +--- + go.mod | 6 +- + go.sum | 11 +- + .../go-jose/go-jose/v4/CHANGELOG.md | 24 + + .../go-jose/go-jose/v4/CONTRIBUTING.md | 6 - + .../github.com/go-jose/go-jose/v4/README.md | 10 +- + .../github.com/go-jose/go-jose/v4/crypter.go | 10 +- + vendor/github.com/go-jose/go-jose/v4/jwe.go | 5 +- + vendor/github.com/go-jose/go-jose/v4/jwk.go | 25 +- + vendor/github.com/go-jose/go-jose/v4/jws.go | 5 +- + .../github.com/go-jose/go-jose/v4/opaque.go | 3 + + .../github.com/go-jose/go-jose/v4/shared.go | 10 +- + .../github.com/go-jose/go-jose/v4/signing.go | 12 +- + .../testify/assert/assertion_compare.go | 35 +- + .../testify/assert/assertion_format.go | 34 +- + .../testify/assert/assertion_forward.go | 68 ++- + .../testify/assert/assertion_order.go | 10 +- + .../stretchr/testify/assert/assertions.go | 157 +++++-- + .../testify/assert/yaml/yaml_custom.go | 25 + + .../testify/assert/yaml/yaml_default.go | 37 ++ + .../stretchr/testify/assert/yaml/yaml_fail.go | 18 + + .../stretchr/testify/require/require.go | 432 ++++++++++-------- + .../stretchr/testify/require/require.go.tmpl | 2 +- + .../testify/require/require_forward.go | 68 ++- + .../stretchr/testify/require/requirements.go | 2 +- + .../kubernetes/pkg/features/kube_features.go | 5 +- + .../pkg/volume/util/atomic_writer.go | 3 +- + .../pkg/volume/util/atomic_writer_linux.go | 27 ++ + .../volume/util/atomic_writer_unsupported.go | 33 ++ + .../pkg/volume/util/device_util_linux.go | 7 +- + .../util/recyclerclient/recycler_client.go | 7 +- + .../k8s.io/kubernetes/pkg/volume/util/util.go | 38 -- + .../debug/resource_usage_gatherer.go | 3 +- + .../e2e/framework/flake_reporting_util.go | 2 +- + .../test/e2e/framework/framework.go | 4 +- + .../test/e2e/framework/node/resource.go | 4 +- + .../test/e2e/framework/skipper/skipper.go | 5 +- + .../kubernetes/test/utils/density_utils.go | 3 +- + .../kubernetes/test/utils/deployment.go | 3 +- + .../kubernetes/test/utils/image/manifest.go | 4 +- + .../k8s.io/kubernetes/test/utils/runners.go | 6 +- + vendor/modules.txt | 9 +- + 41 files changed, 812 insertions(+), 366 deletions(-) + create mode 100644 vendor/github.com/stretchr/testify/assert/yaml/yaml_custom.go + create mode 100644 vendor/github.com/stretchr/testify/assert/yaml/yaml_default.go + create mode 100644 vendor/github.com/stretchr/testify/assert/yaml/yaml_fail.go + create mode 100644 vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer_linux.go + create mode 100644 vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer_unsupported.go + +diff --git a/go.mod b/go.mod +index 8e7adad56..ed3273c91 100644 +--- a/go.mod ++++ b/go.mod +@@ -26,7 +26,7 @@ require ( + github.com/onsi/gomega v1.34.1 + github.com/pkg/xattr v0.4.10 + github.com/prometheus/client_golang v1.19.1 +- github.com/stretchr/testify v1.9.0 ++ github.com/stretchr/testify v1.10.0 + golang.org/x/crypto v0.35.0 + golang.org/x/net v0.36.0 + golang.org/x/sys v0.30.0 +@@ -40,7 +40,7 @@ require ( + k8s.io/client-go v12.0.0+incompatible + k8s.io/cloud-provider v0.30.3 + k8s.io/klog/v2 v2.130.1 +- k8s.io/kubernetes v1.30.3 ++ k8s.io/kubernetes v1.30.10 + k8s.io/mount-utils v0.30.3 + k8s.io/pod-security-admission v0.30.3 + k8s.io/utils v0.0.0-20230726121419-3b25d923346b +@@ -84,7 +84,7 @@ require ( + github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/gemalto/flume v0.13.0 // indirect + github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 // indirect +- github.com/go-jose/go-jose/v4 v4.0.1 // indirect ++ github.com/go-jose/go-jose/v4 v4.0.5 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-openapi/jsonpointer v0.19.6 // indirect +diff --git a/go.sum b/go.sum +index efd718e3e..8f1342b39 100644 +--- a/go.sum ++++ b/go.sum +@@ -993,8 +993,8 @@ github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9 + github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= + github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= + github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= +-github.com/go-jose/go-jose/v4 v4.0.1 h1:QVEPDE3OluqXBQZDcnNvQrInro2h0e4eqNbnZSWqS6U= +-github.com/go-jose/go-jose/v4 v4.0.1/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY= ++github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE= ++github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA= + 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-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +@@ -1586,8 +1586,9 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o + github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= + github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= + github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +-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/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= + github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= + github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +@@ -2602,8 +2603,8 @@ k8s.io/kubectl v0.30.3 h1:YIBBvMdTW0xcDpmrOBzcpUVsn+zOgjMYIu7kAq+yqiI= + k8s.io/kubectl v0.30.3/go.mod h1:IcR0I9RN2+zzTRUa1BzZCm4oM0NLOawE6RzlDvd1Fpo= + k8s.io/kubelet v0.30.3 h1:KvGWDdhzD0vEyDyGTCjsDc8D+0+lwRMw3fJbfQgF7ys= + k8s.io/kubelet v0.30.3/go.mod h1:D9or45Vkzcqg55CEiqZ8dVbwP3Ksj7DruEVRS9oq3Ys= +-k8s.io/kubernetes v1.30.3 h1:A0qoXI1YQNzrQZiff33y5zWxYHFT/HeZRK98/sRDJI0= +-k8s.io/kubernetes v1.30.3/go.mod h1:yPbIk3MhmhGigX62FLJm+CphNtjxqCvAIFQXup6RKS0= ++k8s.io/kubernetes v1.30.10 h1:/x/z+MTfPkKuEjMJwWdRVxNx7xB54GlGWpcFM6KDwZc= ++k8s.io/kubernetes v1.30.10/go.mod h1:DGWYRXHx5NhImLiR9FvIVBsOKxwKZOX6bPF/YP7TqHY= + k8s.io/mount-utils v0.29.3 h1:iEcqPP7Vv8UClH8nnMfovtmy/04fIloRW9JuSXykoZ0= + k8s.io/mount-utils v0.29.3/go.mod h1:9IWJTMe8tG0MYMLEp60xK9GYVeCdA3g4LowmnVi+t9Y= + k8s.io/pod-security-admission v0.30.3 h1:UDGZWR3ry/XrN/Ki/w7qrp49OwgQsKyh+6xWbexvJi8= +diff --git a/vendor/github.com/go-jose/go-jose/v4/CHANGELOG.md b/vendor/github.com/go-jose/go-jose/v4/CHANGELOG.md +index 28bdd2fc0..6f717dbd8 100644 +--- a/vendor/github.com/go-jose/go-jose/v4/CHANGELOG.md ++++ b/vendor/github.com/go-jose/go-jose/v4/CHANGELOG.md +@@ -1,3 +1,27 @@ ++# v4.0.4 ++ ++## Fixed ++ ++ - Reverted "Allow unmarshalling JSONWebKeySets with unsupported key types" as a ++ breaking change. See #136 / #137. ++ ++# v4.0.3 ++ ++## Changed ++ ++ - Allow unmarshalling JSONWebKeySets with unsupported key types (#130) ++ - Document that OpaqueKeyEncrypter can't be implemented (for now) (#129) ++ - Dependency updates ++ ++# v4.0.2 ++ ++## Changed ++ ++ - Improved documentation of Verify() to note that JSONWebKeySet is a supported ++ argument type (#104) ++ - Defined exported error values for missing x5c header and unsupported elliptic ++ curves error cases (#117) ++ + # v4.0.1 + + ## Fixed +diff --git a/vendor/github.com/go-jose/go-jose/v4/CONTRIBUTING.md b/vendor/github.com/go-jose/go-jose/v4/CONTRIBUTING.md +index b63e1f8fe..4b4805add 100644 +--- a/vendor/github.com/go-jose/go-jose/v4/CONTRIBUTING.md ++++ b/vendor/github.com/go-jose/go-jose/v4/CONTRIBUTING.md +@@ -7,9 +7,3 @@ When submitting code, please make every effort to follow existing conventions + and style in order to keep the code as readable as possible. Please also make + sure all tests pass by running `go test`, and format your code with `go fmt`. + We also recommend using `golint` and `errcheck`. +- +-Before your code can be accepted into the project you must also sign the +-Individual Contributor License Agreement. We use [cla-assistant.io][1] and you +-will be prompted to sign once a pull request is opened. +- +-[1]: https://cla-assistant.io/ +diff --git a/vendor/github.com/go-jose/go-jose/v4/README.md b/vendor/github.com/go-jose/go-jose/v4/README.md +index 79a7c5ecc..02b574954 100644 +--- a/vendor/github.com/go-jose/go-jose/v4/README.md ++++ b/vendor/github.com/go-jose/go-jose/v4/README.md +@@ -9,14 +9,6 @@ Package jose aims to provide an implementation of the Javascript Object Signing + and Encryption set of standards. This includes support for JSON Web Encryption, + JSON Web Signature, and JSON Web Token standards. + +-**Disclaimer**: This library contains encryption software that is subject to +-the U.S. Export Administration Regulations. You may not export, re-export, +-transfer or download this code or any part of it in violation of any United +-States law, directive or regulation. In particular this software may not be +-exported or re-exported in any form or on any media to Iran, North Sudan, +-Syria, Cuba, or North Korea, or to denied persons or entities mentioned on any +-US maintained blocked list. +- + ## Overview + + The implementation follows the +@@ -109,6 +101,6 @@ allows attaching a key id. + + Examples can be found in the Godoc + reference for this package. The +-[`jose-util`](https://github.com/go-jose/go-jose/tree/v4/jose-util) ++[`jose-util`](https://github.com/go-jose/go-jose/tree/main/jose-util) + subdirectory also contains a small command-line utility which might be useful + as an example as well. +diff --git a/vendor/github.com/go-jose/go-jose/v4/crypter.go b/vendor/github.com/go-jose/go-jose/v4/crypter.go +index aba08424c..d81b03b44 100644 +--- a/vendor/github.com/go-jose/go-jose/v4/crypter.go ++++ b/vendor/github.com/go-jose/go-jose/v4/crypter.go +@@ -459,7 +459,10 @@ func (obj JSONWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error) + return nil, fmt.Errorf("go-jose/go-jose: unsupported crit header") + } + +- key := tryJWKS(decryptionKey, obj.Header) ++ key, err := tryJWKS(decryptionKey, obj.Header) ++ if err != nil { ++ return nil, err ++ } + decrypter, err := newDecrypter(key) + if err != nil { + return nil, err +@@ -529,7 +532,10 @@ func (obj JSONWebEncryption) DecryptMulti(decryptionKey interface{}) (int, Heade + return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: unsupported crit header") + } + +- key := tryJWKS(decryptionKey, obj.Header) ++ key, err := tryJWKS(decryptionKey, obj.Header) ++ if err != nil { ++ return -1, Header{}, nil, err ++ } + decrypter, err := newDecrypter(key) + if err != nil { + return -1, Header{}, nil, err +diff --git a/vendor/github.com/go-jose/go-jose/v4/jwe.go b/vendor/github.com/go-jose/go-jose/v4/jwe.go +index 89f03ee3e..9f1322dcc 100644 +--- a/vendor/github.com/go-jose/go-jose/v4/jwe.go ++++ b/vendor/github.com/go-jose/go-jose/v4/jwe.go +@@ -288,10 +288,11 @@ func ParseEncryptedCompact( + keyAlgorithms []KeyAlgorithm, + contentEncryption []ContentEncryption, + ) (*JSONWebEncryption, error) { +- parts := strings.Split(input, ".") +- if len(parts) != 5 { ++ // Five parts is four separators ++ if strings.Count(input, ".") != 4 { + return nil, fmt.Errorf("go-jose/go-jose: compact JWE format must have five parts") + } ++ parts := strings.SplitN(input, ".", 5) + + rawProtected, err := base64.RawURLEncoding.DecodeString(parts[0]) + if err != nil { +diff --git a/vendor/github.com/go-jose/go-jose/v4/jwk.go b/vendor/github.com/go-jose/go-jose/v4/jwk.go +index a565aaab2..9e57e93ba 100644 +--- a/vendor/github.com/go-jose/go-jose/v4/jwk.go ++++ b/vendor/github.com/go-jose/go-jose/v4/jwk.go +@@ -239,10 +239,10 @@ func (k *JSONWebKey) UnmarshalJSON(data []byte) (err error) { + keyPub = key + } + } else { +- err = fmt.Errorf("go-jose/go-jose: unknown curve %s'", raw.Crv) ++ return fmt.Errorf("go-jose/go-jose: unknown curve %s'", raw.Crv) + } + default: +- err = fmt.Errorf("go-jose/go-jose: unknown json web key type '%s'", raw.Kty) ++ return fmt.Errorf("go-jose/go-jose: unknown json web key type '%s'", raw.Kty) + } + + if err != nil { +@@ -779,7 +779,13 @@ func (key rawJSONWebKey) symmetricKey() ([]byte, error) { + return key.K.bytes(), nil + } + +-func tryJWKS(key interface{}, headers ...Header) interface{} { ++var ( ++ // ErrJWKSKidNotFound is returned when a JWKS does not contain a JWK with a ++ // key ID which matches one in the provided tokens headers. ++ ErrJWKSKidNotFound = errors.New("go-jose/go-jose: JWK with matching kid not found in JWK Set") ++) ++ ++func tryJWKS(key interface{}, headers ...Header) (interface{}, error) { + var jwks JSONWebKeySet + + switch jwksType := key.(type) { +@@ -788,9 +794,11 @@ func tryJWKS(key interface{}, headers ...Header) interface{} { + case JSONWebKeySet: + jwks = jwksType + default: +- return key ++ // If the specified key is not a JWKS, return as is. ++ return key, nil + } + ++ // Determine the KID to search for from the headers. + var kid string + for _, header := range headers { + if header.KeyID != "" { +@@ -799,14 +807,17 @@ func tryJWKS(key interface{}, headers ...Header) interface{} { + } + } + ++ // If no KID is specified in the headers, reject. + if kid == "" { +- return key ++ return nil, ErrJWKSKidNotFound + } + ++ // Find the JWK with the matching KID. If no JWK with the specified KID is ++ // found, reject. + keys := jwks.Key(kid) + if len(keys) == 0 { +- return key ++ return nil, ErrJWKSKidNotFound + } + +- return keys[0].Key ++ return keys[0].Key, nil + } +diff --git a/vendor/github.com/go-jose/go-jose/v4/jws.go b/vendor/github.com/go-jose/go-jose/v4/jws.go +index 3a912301a..d09d8ba50 100644 +--- a/vendor/github.com/go-jose/go-jose/v4/jws.go ++++ b/vendor/github.com/go-jose/go-jose/v4/jws.go +@@ -327,10 +327,11 @@ func parseSignedCompact( + payload []byte, + signatureAlgorithms []SignatureAlgorithm, + ) (*JSONWebSignature, error) { +- parts := strings.Split(input, ".") +- if len(parts) != 3 { ++ // Three parts is two separators ++ if strings.Count(input, ".") != 2 { + return nil, fmt.Errorf("go-jose/go-jose: compact JWS format must have three parts") + } ++ parts := strings.SplitN(input, ".", 3) + + if parts[1] != "" && payload != nil { + return nil, fmt.Errorf("go-jose/go-jose: payload is not detached") +diff --git a/vendor/github.com/go-jose/go-jose/v4/opaque.go b/vendor/github.com/go-jose/go-jose/v4/opaque.go +index 68db085ef..429427232 100644 +--- a/vendor/github.com/go-jose/go-jose/v4/opaque.go ++++ b/vendor/github.com/go-jose/go-jose/v4/opaque.go +@@ -83,6 +83,9 @@ func (o *opaqueVerifier) verifyPayload(payload []byte, signature []byte, alg Sig + } + + // OpaqueKeyEncrypter is an interface that supports encrypting keys with an opaque key. ++// ++// Note: this cannot currently be implemented outside this package because of its ++// unexported method. + type OpaqueKeyEncrypter interface { + // KeyID returns the kid + KeyID() string +diff --git a/vendor/github.com/go-jose/go-jose/v4/shared.go b/vendor/github.com/go-jose/go-jose/v4/shared.go +index b485e43bd..1ec339612 100644 +--- a/vendor/github.com/go-jose/go-jose/v4/shared.go ++++ b/vendor/github.com/go-jose/go-jose/v4/shared.go +@@ -71,6 +71,12 @@ var ( + // ErrUnprotectedNonce indicates that while parsing a JWS or JWE object, a + // nonce header parameter was included in an unprotected header object. + ErrUnprotectedNonce = errors.New("go-jose/go-jose: Nonce parameter included in unprotected header") ++ ++ // ErrMissingX5cHeader indicates that the JWT header is missing x5c headers. ++ ErrMissingX5cHeader = errors.New("go-jose/go-jose: no x5c header present in message") ++ ++ // ErrUnsupportedEllipticCurve indicates unsupported or unknown elliptic curve has been found. ++ ErrUnsupportedEllipticCurve = errors.New("go-jose/go-jose: unsupported/unknown elliptic curve") + ) + + // Key management algorithms +@@ -199,7 +205,7 @@ type Header struct { + // not be validated with the given verify options. + func (h Header) Certificates(opts x509.VerifyOptions) ([][]*x509.Certificate, error) { + if len(h.certificates) == 0 { +- return nil, errors.New("go-jose/go-jose: no x5c header present in message") ++ return nil, ErrMissingX5cHeader + } + + leaf := h.certificates[0] +@@ -501,7 +507,7 @@ func curveName(crv elliptic.Curve) (string, error) { + case elliptic.P521(): + return "P-521", nil + default: +- return "", fmt.Errorf("go-jose/go-jose: unsupported/unknown elliptic curve") ++ return "", ErrUnsupportedEllipticCurve + } + } + +diff --git a/vendor/github.com/go-jose/go-jose/v4/signing.go b/vendor/github.com/go-jose/go-jose/v4/signing.go +index f0b0294f3..3dec0112b 100644 +--- a/vendor/github.com/go-jose/go-jose/v4/signing.go ++++ b/vendor/github.com/go-jose/go-jose/v4/signing.go +@@ -358,6 +358,8 @@ func (ctx *genericSigner) Options() SignerOptions { + // - *rsa.PublicKey + // - *JSONWebKey + // - JSONWebKey ++// - *JSONWebKeySet ++// - JSONWebKeySet + // - []byte (an HMAC key) + // - Any type that implements the OpaqueVerifier interface. + // +@@ -388,7 +390,10 @@ func (obj JSONWebSignature) UnsafePayloadWithoutVerification() []byte { + // The verificationKey argument must have one of the types allowed for the + // verificationKey argument of JSONWebSignature.Verify(). + func (obj JSONWebSignature) DetachedVerify(payload []byte, verificationKey interface{}) error { +- key := tryJWKS(verificationKey, obj.headers()...) ++ key, err := tryJWKS(verificationKey, obj.headers()...) ++ if err != nil { ++ return err ++ } + verifier, err := newVerifier(key) + if err != nil { + return err +@@ -453,7 +458,10 @@ func (obj JSONWebSignature) VerifyMulti(verificationKey interface{}) (int, Signa + // The verificationKey argument must have one of the types allowed for the + // verificationKey argument of JSONWebSignature.Verify(). + func (obj JSONWebSignature) DetachedVerifyMulti(payload []byte, verificationKey interface{}) (int, Signature, error) { +- key := tryJWKS(verificationKey, obj.headers()...) ++ key, err := tryJWKS(verificationKey, obj.headers()...) ++ if err != nil { ++ return -1, Signature{}, err ++ } + verifier, err := newVerifier(key) + if err != nil { + return -1, Signature{}, err +diff --git a/vendor/github.com/stretchr/testify/assert/assertion_compare.go b/vendor/github.com/stretchr/testify/assert/assertion_compare.go +index 4d4b4aad6..7e19eba09 100644 +--- a/vendor/github.com/stretchr/testify/assert/assertion_compare.go ++++ b/vendor/github.com/stretchr/testify/assert/assertion_compare.go +@@ -7,10 +7,13 @@ import ( + "time" + ) + +-type CompareType int ++// Deprecated: CompareType has only ever been for internal use and has accidentally been published since v1.6.0. Do not use it. ++type CompareType = compareResult ++ ++type compareResult int + + const ( +- compareLess CompareType = iota - 1 ++ compareLess compareResult = iota - 1 + compareEqual + compareGreater + ) +@@ -39,7 +42,7 @@ var ( + bytesType = reflect.TypeOf([]byte{}) + ) + +-func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) { ++func compare(obj1, obj2 interface{}, kind reflect.Kind) (compareResult, bool) { + obj1Value := reflect.ValueOf(obj1) + obj2Value := reflect.ValueOf(obj2) + +@@ -325,7 +328,13 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) { + timeObj2 = obj2Value.Convert(timeType).Interface().(time.Time) + } + +- return compare(timeObj1.UnixNano(), timeObj2.UnixNano(), reflect.Int64) ++ if timeObj1.Before(timeObj2) { ++ return compareLess, true ++ } ++ if timeObj1.Equal(timeObj2) { ++ return compareEqual, true ++ } ++ return compareGreater, true + } + case reflect.Slice: + { +@@ -345,7 +354,7 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) { + bytesObj2 = obj2Value.Convert(bytesType).Interface().([]byte) + } + +- return CompareType(bytes.Compare(bytesObj1, bytesObj2)), true ++ return compareResult(bytes.Compare(bytesObj1, bytesObj2)), true + } + case reflect.Uintptr: + { +@@ -381,7 +390,7 @@ func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface + if h, ok := t.(tHelper); ok { + h.Helper() + } +- return compareTwoValues(t, e1, e2, []CompareType{compareGreater}, "\"%v\" is not greater than \"%v\"", msgAndArgs...) ++ return compareTwoValues(t, e1, e2, []compareResult{compareGreater}, "\"%v\" is not greater than \"%v\"", msgAndArgs...) + } + + // GreaterOrEqual asserts that the first element is greater than or equal to the second +@@ -394,7 +403,7 @@ func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...in + if h, ok := t.(tHelper); ok { + h.Helper() + } +- return compareTwoValues(t, e1, e2, []CompareType{compareGreater, compareEqual}, "\"%v\" is not greater than or equal to \"%v\"", msgAndArgs...) ++ return compareTwoValues(t, e1, e2, []compareResult{compareGreater, compareEqual}, "\"%v\" is not greater than or equal to \"%v\"", msgAndArgs...) + } + + // Less asserts that the first element is less than the second +@@ -406,7 +415,7 @@ func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) + if h, ok := t.(tHelper); ok { + h.Helper() + } +- return compareTwoValues(t, e1, e2, []CompareType{compareLess}, "\"%v\" is not less than \"%v\"", msgAndArgs...) ++ return compareTwoValues(t, e1, e2, []compareResult{compareLess}, "\"%v\" is not less than \"%v\"", msgAndArgs...) + } + + // LessOrEqual asserts that the first element is less than or equal to the second +@@ -419,7 +428,7 @@ func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...inter + if h, ok := t.(tHelper); ok { + h.Helper() + } +- return compareTwoValues(t, e1, e2, []CompareType{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs...) ++ return compareTwoValues(t, e1, e2, []compareResult{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs...) + } + + // Positive asserts that the specified element is positive +@@ -431,7 +440,7 @@ func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) bool { + h.Helper() + } + zero := reflect.Zero(reflect.TypeOf(e)) +- return compareTwoValues(t, e, zero.Interface(), []CompareType{compareGreater}, "\"%v\" is not positive", msgAndArgs...) ++ return compareTwoValues(t, e, zero.Interface(), []compareResult{compareGreater}, "\"%v\" is not positive", msgAndArgs...) + } + + // Negative asserts that the specified element is negative +@@ -443,10 +452,10 @@ func Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) bool { + h.Helper() + } + zero := reflect.Zero(reflect.TypeOf(e)) +- return compareTwoValues(t, e, zero.Interface(), []CompareType{compareLess}, "\"%v\" is not negative", msgAndArgs...) ++ return compareTwoValues(t, e, zero.Interface(), []compareResult{compareLess}, "\"%v\" is not negative", msgAndArgs...) + } + +-func compareTwoValues(t TestingT, e1 interface{}, e2 interface{}, allowedComparesResults []CompareType, failMessage string, msgAndArgs ...interface{}) bool { ++func compareTwoValues(t TestingT, e1 interface{}, e2 interface{}, allowedComparesResults []compareResult, failMessage string, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } +@@ -469,7 +478,7 @@ func compareTwoValues(t TestingT, e1 interface{}, e2 interface{}, allowedCompare + return true + } + +-func containsValue(values []CompareType, value CompareType) bool { ++func containsValue(values []compareResult, value compareResult) bool { + for _, v := range values { + if v == value { + return true +diff --git a/vendor/github.com/stretchr/testify/assert/assertion_format.go b/vendor/github.com/stretchr/testify/assert/assertion_format.go +index 3ddab109a..190634165 100644 +--- a/vendor/github.com/stretchr/testify/assert/assertion_format.go ++++ b/vendor/github.com/stretchr/testify/assert/assertion_format.go +@@ -104,8 +104,8 @@ func EqualExportedValuesf(t TestingT, expected interface{}, actual interface{}, + return EqualExportedValues(t, expected, actual, append([]interface{}{msg}, args...)...) + } + +-// EqualValuesf asserts that two objects are equal or convertible to the same types +-// and equal. ++// EqualValuesf asserts that two objects are equal or convertible to the larger ++// type and equal. + // + // assert.EqualValuesf(t, uint32(123), int32(123), "error message %s", "formatted") + func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { +@@ -186,7 +186,7 @@ func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick + // assert.EventuallyWithTf(t, func(c *assert.CollectT, "error message %s", "formatted") { + // // add assertions as needed; any assertion failure will fail the current tick + // assert.True(c, externalValue, "expected 'externalValue' to be true") +-// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") ++// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") + func EventuallyWithTf(t TestingT, condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -568,6 +568,23 @@ func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, a + return NotContains(t, s, contains, append([]interface{}{msg}, args...)...) + } + ++// NotElementsMatchf asserts that the specified listA(array, slice...) is NOT equal to specified ++// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, ++// the number of appearances of each of them in both lists should not match. ++// This is an inverse of ElementsMatch. ++// ++// assert.NotElementsMatchf(t, [1, 1, 2, 3], [1, 1, 2, 3], "error message %s", "formatted") -> false ++// ++// assert.NotElementsMatchf(t, [1, 1, 2, 3], [1, 2, 3], "error message %s", "formatted") -> true ++// ++// assert.NotElementsMatchf(t, [1, 2, 3], [1, 2, 4], "error message %s", "formatted") -> true ++func NotElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) bool { ++ if h, ok := t.(tHelper); ok { ++ h.Helper() ++ } ++ return NotElementsMatch(t, listA, listB, append([]interface{}{msg}, args...)...) ++} ++ + // NotEmptyf asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either + // a slice or a channel with len == 0. + // +@@ -604,7 +621,16 @@ func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg s + return NotEqualValues(t, expected, actual, append([]interface{}{msg}, args...)...) + } + +-// NotErrorIsf asserts that at none of the errors in err's chain matches target. ++// NotErrorAsf asserts that none of the errors in err's chain matches target, ++// but if so, sets target to that error value. ++func NotErrorAsf(t TestingT, err error, target interface{}, msg string, args ...interface{}) bool { ++ if h, ok := t.(tHelper); ok { ++ h.Helper() ++ } ++ return NotErrorAs(t, err, target, append([]interface{}{msg}, args...)...) ++} ++ ++// NotErrorIsf asserts that none of the errors in err's chain matches target. + // This is a wrapper for errors.Is. + func NotErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { +diff --git a/vendor/github.com/stretchr/testify/assert/assertion_forward.go b/vendor/github.com/stretchr/testify/assert/assertion_forward.go +index a84e09bd4..21629087b 100644 +--- a/vendor/github.com/stretchr/testify/assert/assertion_forward.go ++++ b/vendor/github.com/stretchr/testify/assert/assertion_forward.go +@@ -186,8 +186,8 @@ func (a *Assertions) EqualExportedValuesf(expected interface{}, actual interface + return EqualExportedValuesf(a.t, expected, actual, msg, args...) + } + +-// EqualValues asserts that two objects are equal or convertible to the same types +-// and equal. ++// EqualValues asserts that two objects are equal or convertible to the larger ++// type and equal. + // + // a.EqualValues(uint32(123), int32(123)) + func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { +@@ -197,8 +197,8 @@ func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAn + return EqualValues(a.t, expected, actual, msgAndArgs...) + } + +-// EqualValuesf asserts that two objects are equal or convertible to the same types +-// and equal. ++// EqualValuesf asserts that two objects are equal or convertible to the larger ++// type and equal. + // + // a.EqualValuesf(uint32(123), int32(123), "error message %s", "formatted") + func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { +@@ -336,7 +336,7 @@ func (a *Assertions) Eventually(condition func() bool, waitFor time.Duration, ti + // a.EventuallyWithT(func(c *assert.CollectT) { + // // add assertions as needed; any assertion failure will fail the current tick + // assert.True(c, externalValue, "expected 'externalValue' to be true") +-// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") ++// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") + func (a *Assertions) EventuallyWithT(condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() +@@ -361,7 +361,7 @@ func (a *Assertions) EventuallyWithT(condition func(collect *CollectT), waitFor + // a.EventuallyWithTf(func(c *assert.CollectT, "error message %s", "formatted") { + // // add assertions as needed; any assertion failure will fail the current tick + // assert.True(c, externalValue, "expected 'externalValue' to be true") +-// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") ++// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") + func (a *Assertions) EventuallyWithTf(condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() +@@ -1128,6 +1128,40 @@ func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg strin + return NotContainsf(a.t, s, contains, msg, args...) + } + ++// NotElementsMatch asserts that the specified listA(array, slice...) is NOT equal to specified ++// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, ++// the number of appearances of each of them in both lists should not match. ++// This is an inverse of ElementsMatch. ++// ++// a.NotElementsMatch([1, 1, 2, 3], [1, 1, 2, 3]) -> false ++// ++// a.NotElementsMatch([1, 1, 2, 3], [1, 2, 3]) -> true ++// ++// a.NotElementsMatch([1, 2, 3], [1, 2, 4]) -> true ++func (a *Assertions) NotElementsMatch(listA interface{}, listB interface{}, msgAndArgs ...interface{}) bool { ++ if h, ok := a.t.(tHelper); ok { ++ h.Helper() ++ } ++ return NotElementsMatch(a.t, listA, listB, msgAndArgs...) ++} ++ ++// NotElementsMatchf asserts that the specified listA(array, slice...) is NOT equal to specified ++// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, ++// the number of appearances of each of them in both lists should not match. ++// This is an inverse of ElementsMatch. ++// ++// a.NotElementsMatchf([1, 1, 2, 3], [1, 1, 2, 3], "error message %s", "formatted") -> false ++// ++// a.NotElementsMatchf([1, 1, 2, 3], [1, 2, 3], "error message %s", "formatted") -> true ++// ++// a.NotElementsMatchf([1, 2, 3], [1, 2, 4], "error message %s", "formatted") -> true ++func (a *Assertions) NotElementsMatchf(listA interface{}, listB interface{}, msg string, args ...interface{}) bool { ++ if h, ok := a.t.(tHelper); ok { ++ h.Helper() ++ } ++ return NotElementsMatchf(a.t, listA, listB, msg, args...) ++} ++ + // NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either + // a slice or a channel with len == 0. + // +@@ -1200,7 +1234,25 @@ func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg str + return NotEqualf(a.t, expected, actual, msg, args...) + } + +-// NotErrorIs asserts that at none of the errors in err's chain matches target. ++// NotErrorAs asserts that none of the errors in err's chain matches target, ++// but if so, sets target to that error value. ++func (a *Assertions) NotErrorAs(err error, target interface{}, msgAndArgs ...interface{}) bool { ++ if h, ok := a.t.(tHelper); ok { ++ h.Helper() ++ } ++ return NotErrorAs(a.t, err, target, msgAndArgs...) ++} ++ ++// NotErrorAsf asserts that none of the errors in err's chain matches target, ++// but if so, sets target to that error value. ++func (a *Assertions) NotErrorAsf(err error, target interface{}, msg string, args ...interface{}) bool { ++ if h, ok := a.t.(tHelper); ok { ++ h.Helper() ++ } ++ return NotErrorAsf(a.t, err, target, msg, args...) ++} ++ ++// NotErrorIs asserts that none of the errors in err's chain matches target. + // This is a wrapper for errors.Is. + func (a *Assertions) NotErrorIs(err error, target error, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { +@@ -1209,7 +1261,7 @@ func (a *Assertions) NotErrorIs(err error, target error, msgAndArgs ...interface + return NotErrorIs(a.t, err, target, msgAndArgs...) + } + +-// NotErrorIsf asserts that at none of the errors in err's chain matches target. ++// NotErrorIsf asserts that none of the errors in err's chain matches target. + // This is a wrapper for errors.Is. + func (a *Assertions) NotErrorIsf(err error, target error, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { +diff --git a/vendor/github.com/stretchr/testify/assert/assertion_order.go b/vendor/github.com/stretchr/testify/assert/assertion_order.go +index 00df62a05..1d2f71824 100644 +--- a/vendor/github.com/stretchr/testify/assert/assertion_order.go ++++ b/vendor/github.com/stretchr/testify/assert/assertion_order.go +@@ -6,7 +6,7 @@ import ( + ) + + // isOrdered checks that collection contains orderable elements. +-func isOrdered(t TestingT, object interface{}, allowedComparesResults []CompareType, failMessage string, msgAndArgs ...interface{}) bool { ++func isOrdered(t TestingT, object interface{}, allowedComparesResults []compareResult, failMessage string, msgAndArgs ...interface{}) bool { + objKind := reflect.TypeOf(object).Kind() + if objKind != reflect.Slice && objKind != reflect.Array { + return false +@@ -50,7 +50,7 @@ func isOrdered(t TestingT, object interface{}, allowedComparesResults []CompareT + // assert.IsIncreasing(t, []float{1, 2}) + // assert.IsIncreasing(t, []string{"a", "b"}) + func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { +- return isOrdered(t, object, []CompareType{compareLess}, "\"%v\" is not less than \"%v\"", msgAndArgs...) ++ return isOrdered(t, object, []compareResult{compareLess}, "\"%v\" is not less than \"%v\"", msgAndArgs...) + } + + // IsNonIncreasing asserts that the collection is not increasing +@@ -59,7 +59,7 @@ func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) boo + // assert.IsNonIncreasing(t, []float{2, 1}) + // assert.IsNonIncreasing(t, []string{"b", "a"}) + func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { +- return isOrdered(t, object, []CompareType{compareEqual, compareGreater}, "\"%v\" is not greater than or equal to \"%v\"", msgAndArgs...) ++ return isOrdered(t, object, []compareResult{compareEqual, compareGreater}, "\"%v\" is not greater than or equal to \"%v\"", msgAndArgs...) + } + + // IsDecreasing asserts that the collection is decreasing +@@ -68,7 +68,7 @@ func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) + // assert.IsDecreasing(t, []float{2, 1}) + // assert.IsDecreasing(t, []string{"b", "a"}) + func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { +- return isOrdered(t, object, []CompareType{compareGreater}, "\"%v\" is not greater than \"%v\"", msgAndArgs...) ++ return isOrdered(t, object, []compareResult{compareGreater}, "\"%v\" is not greater than \"%v\"", msgAndArgs...) + } + + // IsNonDecreasing asserts that the collection is not decreasing +@@ -77,5 +77,5 @@ func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) boo + // assert.IsNonDecreasing(t, []float{1, 2}) + // assert.IsNonDecreasing(t, []string{"a", "b"}) + func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { +- return isOrdered(t, object, []CompareType{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs...) ++ return isOrdered(t, object, []compareResult{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs...) + } +diff --git a/vendor/github.com/stretchr/testify/assert/assertions.go b/vendor/github.com/stretchr/testify/assert/assertions.go +index 0b7570f21..4e91332bb 100644 +--- a/vendor/github.com/stretchr/testify/assert/assertions.go ++++ b/vendor/github.com/stretchr/testify/assert/assertions.go +@@ -19,7 +19,9 @@ import ( + + "github.com/davecgh/go-spew/spew" + "github.com/pmezard/go-difflib/difflib" +- "gopkg.in/yaml.v3" ++ ++ // Wrapper around gopkg.in/yaml.v3 ++ "github.com/stretchr/testify/assert/yaml" + ) + + //go:generate sh -c "cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=assert -template=assertion_format.go.tmpl" +@@ -45,6 +47,10 @@ type BoolAssertionFunc func(TestingT, bool, ...interface{}) bool + // for table driven tests. + type ErrorAssertionFunc func(TestingT, error, ...interface{}) bool + ++// PanicAssertionFunc is a common function prototype when validating a panic value. Can be useful ++// for table driven tests. ++type PanicAssertionFunc = func(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool ++ + // Comparison is a custom function that returns true on success and false on failure + type Comparison func() (success bool) + +@@ -496,7 +502,13 @@ func Same(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) b + h.Helper() + } + +- if !samePointers(expected, actual) { ++ same, ok := samePointers(expected, actual) ++ if !ok { ++ return Fail(t, "Both arguments must be pointers", msgAndArgs...) ++ } ++ ++ if !same { ++ // both are pointers but not the same type & pointing to the same address + return Fail(t, fmt.Sprintf("Not same: \n"+ + "expected: %p %#v\n"+ + "actual : %p %#v", expected, expected, actual, actual), msgAndArgs...) +@@ -516,7 +528,13 @@ func NotSame(t TestingT, expected, actual interface{}, msgAndArgs ...interface{} + h.Helper() + } + +- if samePointers(expected, actual) { ++ same, ok := samePointers(expected, actual) ++ if !ok { ++ //fails when the arguments are not pointers ++ return !(Fail(t, "Both arguments must be pointers", msgAndArgs...)) ++ } ++ ++ if same { + return Fail(t, fmt.Sprintf( + "Expected and actual point to the same object: %p %#v", + expected, expected), msgAndArgs...) +@@ -524,21 +542,23 @@ func NotSame(t TestingT, expected, actual interface{}, msgAndArgs ...interface{} + return true + } + +-// samePointers compares two generic interface objects and returns whether +-// they point to the same object +-func samePointers(first, second interface{}) bool { ++// samePointers checks if two generic interface objects are pointers of the same ++// type pointing to the same object. It returns two values: same indicating if ++// they are the same type and point to the same object, and ok indicating that ++// both inputs are pointers. ++func samePointers(first, second interface{}) (same bool, ok bool) { + firstPtr, secondPtr := reflect.ValueOf(first), reflect.ValueOf(second) + if firstPtr.Kind() != reflect.Ptr || secondPtr.Kind() != reflect.Ptr { +- return false ++ return false, false //not both are pointers + } + + firstType, secondType := reflect.TypeOf(first), reflect.TypeOf(second) + if firstType != secondType { +- return false ++ return false, true // both are pointers, but of different types + } + + // compare pointer addresses +- return first == second ++ return first == second, true + } + + // formatUnequalValues takes two values of arbitrary types and returns string +@@ -572,8 +592,8 @@ func truncatingFormat(data interface{}) string { + return value + } + +-// EqualValues asserts that two objects are equal or convertible to the same types +-// and equal. ++// EqualValues asserts that two objects are equal or convertible to the larger ++// type and equal. + // + // assert.EqualValues(t, uint32(123), int32(123)) + func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { +@@ -615,21 +635,6 @@ func EqualExportedValues(t TestingT, expected, actual interface{}, msgAndArgs .. + return Fail(t, fmt.Sprintf("Types expected to match exactly\n\t%v != %v", aType, bType), msgAndArgs...) + } + +- if aType.Kind() == reflect.Ptr { +- aType = aType.Elem() +- } +- if bType.Kind() == reflect.Ptr { +- bType = bType.Elem() +- } +- +- if aType.Kind() != reflect.Struct { +- return Fail(t, fmt.Sprintf("Types expected to both be struct or pointer to struct \n\t%v != %v", aType.Kind(), reflect.Struct), msgAndArgs...) +- } +- +- if bType.Kind() != reflect.Struct { +- return Fail(t, fmt.Sprintf("Types expected to both be struct or pointer to struct \n\t%v != %v", bType.Kind(), reflect.Struct), msgAndArgs...) +- } +- + expected = copyExportedFields(expected) + actual = copyExportedFields(actual) + +@@ -1170,6 +1175,39 @@ func formatListDiff(listA, listB interface{}, extraA, extraB []interface{}) stri + return msg.String() + } + ++// NotElementsMatch asserts that the specified listA(array, slice...) is NOT equal to specified ++// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, ++// the number of appearances of each of them in both lists should not match. ++// This is an inverse of ElementsMatch. ++// ++// assert.NotElementsMatch(t, [1, 1, 2, 3], [1, 1, 2, 3]) -> false ++// ++// assert.NotElementsMatch(t, [1, 1, 2, 3], [1, 2, 3]) -> true ++// ++// assert.NotElementsMatch(t, [1, 2, 3], [1, 2, 4]) -> true ++func NotElementsMatch(t TestingT, listA, listB interface{}, msgAndArgs ...interface{}) (ok bool) { ++ if h, ok := t.(tHelper); ok { ++ h.Helper() ++ } ++ if isEmpty(listA) && isEmpty(listB) { ++ return Fail(t, "listA and listB contain the same elements", msgAndArgs) ++ } ++ ++ if !isList(t, listA, msgAndArgs...) { ++ return Fail(t, "listA is not a list type", msgAndArgs...) ++ } ++ if !isList(t, listB, msgAndArgs...) { ++ return Fail(t, "listB is not a list type", msgAndArgs...) ++ } ++ ++ extraA, extraB := diffLists(listA, listB) ++ if len(extraA) == 0 && len(extraB) == 0 { ++ return Fail(t, "listA and listB contain the same elements", msgAndArgs) ++ } ++ ++ return true ++} ++ + // Condition uses a Comparison to assert a complex condition. + func Condition(t TestingT, comp Comparison, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { +@@ -1488,6 +1526,9 @@ func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAnd + if err != nil { + return Fail(t, err.Error(), msgAndArgs...) + } ++ if math.IsNaN(actualEpsilon) { ++ return Fail(t, "relative error is NaN", msgAndArgs...) ++ } + if actualEpsilon > epsilon { + return Fail(t, fmt.Sprintf("Relative error is too high: %#v (expected)\n"+ + " < %#v (actual)", epsilon, actualEpsilon), msgAndArgs...) +@@ -1611,7 +1652,6 @@ func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...in + + // matchRegexp return true if a specified regexp matches a string. + func matchRegexp(rx interface{}, str interface{}) bool { +- + var r *regexp.Regexp + if rr, ok := rx.(*regexp.Regexp); ok { + r = rr +@@ -1619,7 +1659,14 @@ func matchRegexp(rx interface{}, str interface{}) bool { + r = regexp.MustCompile(fmt.Sprint(rx)) + } + +- return (r.FindStringIndex(fmt.Sprint(str)) != nil) ++ switch v := str.(type) { ++ case []byte: ++ return r.Match(v) ++ case string: ++ return r.MatchString(v) ++ default: ++ return r.MatchString(fmt.Sprint(v)) ++ } + + } + +@@ -1872,7 +1919,7 @@ var spewConfigStringerEnabled = spew.ConfigState{ + MaxDepth: 10, + } + +-type tHelper interface { ++type tHelper = interface { + Helper() + } + +@@ -1911,6 +1958,9 @@ func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick t + + // CollectT implements the TestingT interface and collects all errors. + type CollectT struct { ++ // A slice of errors. Non-nil slice denotes a failure. ++ // If it's non-nil but len(c.errors) == 0, this is also a failure ++ // obtained by direct c.FailNow() call. + errors []error + } + +@@ -1919,9 +1969,10 @@ func (c *CollectT) Errorf(format string, args ...interface{}) { + c.errors = append(c.errors, fmt.Errorf(format, args...)) + } + +-// FailNow panics. +-func (*CollectT) FailNow() { +- panic("Assertion failed") ++// FailNow stops execution by calling runtime.Goexit. ++func (c *CollectT) FailNow() { ++ c.fail() ++ runtime.Goexit() + } + + // Deprecated: That was a method for internal usage that should not have been published. Now just panics. +@@ -1934,6 +1985,16 @@ func (*CollectT) Copy(TestingT) { + panic("Copy() is deprecated") + } + ++func (c *CollectT) fail() { ++ if !c.failed() { ++ c.errors = []error{} // Make it non-nil to mark a failure. ++ } ++} ++ ++func (c *CollectT) failed() bool { ++ return c.errors != nil ++} ++ + // EventuallyWithT asserts that given condition will be met in waitFor time, + // periodically checking target function each tick. In contrast to Eventually, + // it supplies a CollectT to the condition function, so that the condition +@@ -1951,14 +2012,14 @@ func (*CollectT) Copy(TestingT) { + // assert.EventuallyWithT(t, func(c *assert.CollectT) { + // // add assertions as needed; any assertion failure will fail the current tick + // assert.True(c, externalValue, "expected 'externalValue' to be true") +-// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") ++// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") + func EventuallyWithT(t TestingT, condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + var lastFinishedTickErrs []error +- ch := make(chan []error, 1) ++ ch := make(chan *CollectT, 1) + + timer := time.NewTimer(waitFor) + defer timer.Stop() +@@ -1978,16 +2039,16 @@ func EventuallyWithT(t TestingT, condition func(collect *CollectT), waitFor time + go func() { + collect := new(CollectT) + defer func() { +- ch <- collect.errors ++ ch <- collect + }() + condition(collect) + }() +- case errs := <-ch: +- if len(errs) == 0 { ++ case collect := <-ch: ++ if !collect.failed() { + return true + } + // Keep the errors from the last ended condition, so that they can be copied to t if timeout is reached. +- lastFinishedTickErrs = errs ++ lastFinishedTickErrs = collect.errors + tick = ticker.C + } + } +@@ -2049,7 +2110,7 @@ func ErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool { + ), msgAndArgs...) + } + +-// NotErrorIs asserts that at none of the errors in err's chain matches target. ++// NotErrorIs asserts that none of the errors in err's chain matches target. + // This is a wrapper for errors.Is. + func NotErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { +@@ -2090,6 +2151,24 @@ func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{ + ), msgAndArgs...) + } + ++// NotErrorAs asserts that none of the errors in err's chain matches target, ++// but if so, sets target to that error value. ++func NotErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{}) bool { ++ if h, ok := t.(tHelper); ok { ++ h.Helper() ++ } ++ if !errors.As(err, target) { ++ return true ++ } ++ ++ chain := buildErrorChainString(err) ++ ++ return Fail(t, fmt.Sprintf("Target error should not be in err chain:\n"+ ++ "found: %q\n"+ ++ "in chain: %s", target, chain, ++ ), msgAndArgs...) ++} ++ + func buildErrorChainString(err error) string { + if err == nil { + return "" +diff --git a/vendor/github.com/stretchr/testify/assert/yaml/yaml_custom.go b/vendor/github.com/stretchr/testify/assert/yaml/yaml_custom.go +new file mode 100644 +index 000000000..baa0cc7d7 +--- /dev/null ++++ b/vendor/github.com/stretchr/testify/assert/yaml/yaml_custom.go +@@ -0,0 +1,25 @@ ++//go:build testify_yaml_custom && !testify_yaml_fail && !testify_yaml_default ++// +build testify_yaml_custom,!testify_yaml_fail,!testify_yaml_default ++ ++// Package yaml is an implementation of YAML functions that calls a pluggable implementation. ++// ++// This implementation is selected with the testify_yaml_custom build tag. ++// ++// go test -tags testify_yaml_custom ++// ++// This implementation can be used at build time to replace the default implementation ++// to avoid linking with [gopkg.in/yaml.v3]. ++// ++// In your test package: ++// ++// import assertYaml "github.com/stretchr/testify/assert/yaml" ++// ++// func init() { ++// assertYaml.Unmarshal = func (in []byte, out interface{}) error { ++// // ... ++// return nil ++// } ++// } ++package yaml ++ ++var Unmarshal func(in []byte, out interface{}) error +diff --git a/vendor/github.com/stretchr/testify/assert/yaml/yaml_default.go b/vendor/github.com/stretchr/testify/assert/yaml/yaml_default.go +new file mode 100644 +index 000000000..b83c6cf64 +--- /dev/null ++++ b/vendor/github.com/stretchr/testify/assert/yaml/yaml_default.go +@@ -0,0 +1,37 @@ ++//go:build !testify_yaml_fail && !testify_yaml_custom ++// +build !testify_yaml_fail,!testify_yaml_custom ++ ++// Package yaml is just an indirection to handle YAML deserialization. ++// ++// This package is just an indirection that allows the builder to override the ++// indirection with an alternative implementation of this package that uses ++// another implementation of YAML deserialization. This allows to not either not ++// use YAML deserialization at all, or to use another implementation than ++// [gopkg.in/yaml.v3] (for example for license compatibility reasons, see [PR #1120]). ++// ++// Alternative implementations are selected using build tags: ++// ++// - testify_yaml_fail: [Unmarshal] always fails with an error ++// - testify_yaml_custom: [Unmarshal] is a variable. Caller must initialize it ++// before calling any of [github.com/stretchr/testify/assert.YAMLEq] or ++// [github.com/stretchr/testify/assert.YAMLEqf]. ++// ++// Usage: ++// ++// go test -tags testify_yaml_fail ++// ++// You can check with "go list" which implementation is linked: ++// ++// go list -f '{{.Imports}}' github.com/stretchr/testify/assert/yaml ++// go list -tags testify_yaml_fail -f '{{.Imports}}' github.com/stretchr/testify/assert/yaml ++// go list -tags testify_yaml_custom -f '{{.Imports}}' github.com/stretchr/testify/assert/yaml ++// ++// [PR #1120]: https://github.com/stretchr/testify/pull/1120 ++package yaml ++ ++import goyaml "gopkg.in/yaml.v3" ++ ++// Unmarshal is just a wrapper of [gopkg.in/yaml.v3.Unmarshal]. ++func Unmarshal(in []byte, out interface{}) error { ++ return goyaml.Unmarshal(in, out) ++} +diff --git a/vendor/github.com/stretchr/testify/assert/yaml/yaml_fail.go b/vendor/github.com/stretchr/testify/assert/yaml/yaml_fail.go +new file mode 100644 +index 000000000..e78f7dfe6 +--- /dev/null ++++ b/vendor/github.com/stretchr/testify/assert/yaml/yaml_fail.go +@@ -0,0 +1,18 @@ ++//go:build testify_yaml_fail && !testify_yaml_custom && !testify_yaml_default ++// +build testify_yaml_fail,!testify_yaml_custom,!testify_yaml_default ++ ++// Package yaml is an implementation of YAML functions that always fail. ++// ++// This implementation can be used at build time to replace the default implementation ++// to avoid linking with [gopkg.in/yaml.v3]: ++// ++// go test -tags testify_yaml_fail ++package yaml ++ ++import "errors" ++ ++var errNotImplemented = errors.New("YAML functions are not available (see https://pkg.go.dev/github.com/stretchr/testify/assert/yaml)") ++ ++func Unmarshal([]byte, interface{}) error { ++ return errNotImplemented ++} +diff --git a/vendor/github.com/stretchr/testify/require/require.go b/vendor/github.com/stretchr/testify/require/require.go +index 506a82f80..d8921950d 100644 +--- a/vendor/github.com/stretchr/testify/require/require.go ++++ b/vendor/github.com/stretchr/testify/require/require.go +@@ -34,9 +34,9 @@ func Conditionf(t TestingT, comp assert.Comparison, msg string, args ...interfac + // Contains asserts that the specified string, list(array, slice...) or map contains the + // specified substring or element. + // +-// assert.Contains(t, "Hello World", "World") +-// assert.Contains(t, ["Hello", "World"], "World") +-// assert.Contains(t, {"Hello": "World"}, "Hello") ++// require.Contains(t, "Hello World", "World") ++// require.Contains(t, ["Hello", "World"], "World") ++// require.Contains(t, {"Hello": "World"}, "Hello") + func Contains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -50,9 +50,9 @@ func Contains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...int + // Containsf asserts that the specified string, list(array, slice...) or map contains the + // specified substring or element. + // +-// assert.Containsf(t, "Hello World", "World", "error message %s", "formatted") +-// assert.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted") +-// assert.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted") ++// require.Containsf(t, "Hello World", "World", "error message %s", "formatted") ++// require.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted") ++// require.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted") + func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -91,7 +91,7 @@ func DirExistsf(t TestingT, path string, msg string, args ...interface{}) { + // listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, + // the number of appearances of each of them in both lists should match. + // +-// assert.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2]) ++// require.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2]) + func ElementsMatch(t TestingT, listA interface{}, listB interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -106,7 +106,7 @@ func ElementsMatch(t TestingT, listA interface{}, listB interface{}, msgAndArgs + // listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, + // the number of appearances of each of them in both lists should match. + // +-// assert.ElementsMatchf(t, [1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted") ++// require.ElementsMatchf(t, [1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted") + func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -120,7 +120,7 @@ func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string + // Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either + // a slice or a channel with len == 0. + // +-// assert.Empty(t, obj) ++// require.Empty(t, obj) + func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -134,7 +134,7 @@ func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) { + // Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either + // a slice or a channel with len == 0. + // +-// assert.Emptyf(t, obj, "error message %s", "formatted") ++// require.Emptyf(t, obj, "error message %s", "formatted") + func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -147,7 +147,7 @@ func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) { + + // Equal asserts that two objects are equal. + // +-// assert.Equal(t, 123, 123) ++// require.Equal(t, 123, 123) + // + // Pointer variable equality is determined based on the equality of the + // referenced values (as opposed to the memory addresses). Function equality +@@ -166,7 +166,7 @@ func Equal(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...i + // and that it is equal to the provided error. + // + // actualObj, err := SomeFunction() +-// assert.EqualError(t, err, expectedErrorString) ++// require.EqualError(t, err, expectedErrorString) + func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -181,7 +181,7 @@ func EqualError(t TestingT, theError error, errString string, msgAndArgs ...inte + // and that it is equal to the provided error. + // + // actualObj, err := SomeFunction() +-// assert.EqualErrorf(t, err, expectedErrorString, "error message %s", "formatted") ++// require.EqualErrorf(t, err, expectedErrorString, "error message %s", "formatted") + func EqualErrorf(t TestingT, theError error, errString string, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -200,8 +200,8 @@ func EqualErrorf(t TestingT, theError error, errString string, msg string, args + // Exported int + // notExported int + // } +-// assert.EqualExportedValues(t, S{1, 2}, S{1, 3}) => true +-// assert.EqualExportedValues(t, S{1, 2}, S{2, 3}) => false ++// require.EqualExportedValues(t, S{1, 2}, S{1, 3}) => true ++// require.EqualExportedValues(t, S{1, 2}, S{2, 3}) => false + func EqualExportedValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -220,8 +220,8 @@ func EqualExportedValues(t TestingT, expected interface{}, actual interface{}, m + // Exported int + // notExported int + // } +-// assert.EqualExportedValuesf(t, S{1, 2}, S{1, 3}, "error message %s", "formatted") => true +-// assert.EqualExportedValuesf(t, S{1, 2}, S{2, 3}, "error message %s", "formatted") => false ++// require.EqualExportedValuesf(t, S{1, 2}, S{1, 3}, "error message %s", "formatted") => true ++// require.EqualExportedValuesf(t, S{1, 2}, S{2, 3}, "error message %s", "formatted") => false + func EqualExportedValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -232,10 +232,10 @@ func EqualExportedValuesf(t TestingT, expected interface{}, actual interface{}, + t.FailNow() + } + +-// EqualValues asserts that two objects are equal or convertible to the same types +-// and equal. ++// EqualValues asserts that two objects are equal or convertible to the larger ++// type and equal. + // +-// assert.EqualValues(t, uint32(123), int32(123)) ++// require.EqualValues(t, uint32(123), int32(123)) + func EqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -246,10 +246,10 @@ func EqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArg + t.FailNow() + } + +-// EqualValuesf asserts that two objects are equal or convertible to the same types +-// and equal. ++// EqualValuesf asserts that two objects are equal or convertible to the larger ++// type and equal. + // +-// assert.EqualValuesf(t, uint32(123), int32(123), "error message %s", "formatted") ++// require.EqualValuesf(t, uint32(123), int32(123), "error message %s", "formatted") + func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -262,7 +262,7 @@ func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg stri + + // Equalf asserts that two objects are equal. + // +-// assert.Equalf(t, 123, 123, "error message %s", "formatted") ++// require.Equalf(t, 123, 123, "error message %s", "formatted") + // + // Pointer variable equality is determined based on the equality of the + // referenced values (as opposed to the memory addresses). Function equality +@@ -280,8 +280,8 @@ func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, ar + // Error asserts that a function returned an error (i.e. not `nil`). + // + // actualObj, err := SomeFunction() +-// if assert.Error(t, err) { +-// assert.Equal(t, expectedError, err) ++// if require.Error(t, err) { ++// require.Equal(t, expectedError, err) + // } + func Error(t TestingT, err error, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { +@@ -321,7 +321,7 @@ func ErrorAsf(t TestingT, err error, target interface{}, msg string, args ...int + // and that the error contains the specified substring. + // + // actualObj, err := SomeFunction() +-// assert.ErrorContains(t, err, expectedErrorSubString) ++// require.ErrorContains(t, err, expectedErrorSubString) + func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -336,7 +336,7 @@ func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...in + // and that the error contains the specified substring. + // + // actualObj, err := SomeFunction() +-// assert.ErrorContainsf(t, err, expectedErrorSubString, "error message %s", "formatted") ++// require.ErrorContainsf(t, err, expectedErrorSubString, "error message %s", "formatted") + func ErrorContainsf(t TestingT, theError error, contains string, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -374,8 +374,8 @@ func ErrorIsf(t TestingT, err error, target error, msg string, args ...interface + // Errorf asserts that a function returned an error (i.e. not `nil`). + // + // actualObj, err := SomeFunction() +-// if assert.Errorf(t, err, "error message %s", "formatted") { +-// assert.Equal(t, expectedErrorf, err) ++// if require.Errorf(t, err, "error message %s", "formatted") { ++// require.Equal(t, expectedErrorf, err) + // } + func Errorf(t TestingT, err error, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { +@@ -390,7 +390,7 @@ func Errorf(t TestingT, err error, msg string, args ...interface{}) { + // Eventually asserts that given condition will be met in waitFor time, + // periodically checking target function each tick. + // +-// assert.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond) ++// require.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond) + func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -415,10 +415,10 @@ func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick t + // time.Sleep(8*time.Second) + // externalValue = true + // }() +-// assert.EventuallyWithT(t, func(c *assert.CollectT) { ++// require.EventuallyWithT(t, func(c *require.CollectT) { + // // add assertions as needed; any assertion failure will fail the current tick +-// assert.True(c, externalValue, "expected 'externalValue' to be true") +-// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") ++// require.True(c, externalValue, "expected 'externalValue' to be true") ++// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") + func EventuallyWithT(t TestingT, condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -443,10 +443,10 @@ func EventuallyWithT(t TestingT, condition func(collect *assert.CollectT), waitF + // time.Sleep(8*time.Second) + // externalValue = true + // }() +-// assert.EventuallyWithTf(t, func(c *assert.CollectT, "error message %s", "formatted") { ++// require.EventuallyWithTf(t, func(c *require.CollectT, "error message %s", "formatted") { + // // add assertions as needed; any assertion failure will fail the current tick +-// assert.True(c, externalValue, "expected 'externalValue' to be true") +-// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") ++// require.True(c, externalValue, "expected 'externalValue' to be true") ++// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") + func EventuallyWithTf(t TestingT, condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -460,7 +460,7 @@ func EventuallyWithTf(t TestingT, condition func(collect *assert.CollectT), wait + // Eventuallyf asserts that given condition will be met in waitFor time, + // periodically checking target function each tick. + // +-// assert.Eventuallyf(t, func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") ++// require.Eventuallyf(t, func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") + func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -473,7 +473,7 @@ func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick + + // Exactly asserts that two objects are equal in value and type. + // +-// assert.Exactly(t, int32(123), int64(123)) ++// require.Exactly(t, int32(123), int64(123)) + func Exactly(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -486,7 +486,7 @@ func Exactly(t TestingT, expected interface{}, actual interface{}, msgAndArgs .. + + // Exactlyf asserts that two objects are equal in value and type. + // +-// assert.Exactlyf(t, int32(123), int64(123), "error message %s", "formatted") ++// require.Exactlyf(t, int32(123), int64(123), "error message %s", "formatted") + func Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -543,7 +543,7 @@ func Failf(t TestingT, failureMessage string, msg string, args ...interface{}) { + + // False asserts that the specified value is false. + // +-// assert.False(t, myBool) ++// require.False(t, myBool) + func False(t TestingT, value bool, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -556,7 +556,7 @@ func False(t TestingT, value bool, msgAndArgs ...interface{}) { + + // Falsef asserts that the specified value is false. + // +-// assert.Falsef(t, myBool, "error message %s", "formatted") ++// require.Falsef(t, myBool, "error message %s", "formatted") + func Falsef(t TestingT, value bool, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -593,9 +593,9 @@ func FileExistsf(t TestingT, path string, msg string, args ...interface{}) { + + // Greater asserts that the first element is greater than the second + // +-// assert.Greater(t, 2, 1) +-// assert.Greater(t, float64(2), float64(1)) +-// assert.Greater(t, "b", "a") ++// require.Greater(t, 2, 1) ++// require.Greater(t, float64(2), float64(1)) ++// require.Greater(t, "b", "a") + func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -608,10 +608,10 @@ func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface + + // GreaterOrEqual asserts that the first element is greater than or equal to the second + // +-// assert.GreaterOrEqual(t, 2, 1) +-// assert.GreaterOrEqual(t, 2, 2) +-// assert.GreaterOrEqual(t, "b", "a") +-// assert.GreaterOrEqual(t, "b", "b") ++// require.GreaterOrEqual(t, 2, 1) ++// require.GreaterOrEqual(t, 2, 2) ++// require.GreaterOrEqual(t, "b", "a") ++// require.GreaterOrEqual(t, "b", "b") + func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -624,10 +624,10 @@ func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...in + + // GreaterOrEqualf asserts that the first element is greater than or equal to the second + // +-// assert.GreaterOrEqualf(t, 2, 1, "error message %s", "formatted") +-// assert.GreaterOrEqualf(t, 2, 2, "error message %s", "formatted") +-// assert.GreaterOrEqualf(t, "b", "a", "error message %s", "formatted") +-// assert.GreaterOrEqualf(t, "b", "b", "error message %s", "formatted") ++// require.GreaterOrEqualf(t, 2, 1, "error message %s", "formatted") ++// require.GreaterOrEqualf(t, 2, 2, "error message %s", "formatted") ++// require.GreaterOrEqualf(t, "b", "a", "error message %s", "formatted") ++// require.GreaterOrEqualf(t, "b", "b", "error message %s", "formatted") + func GreaterOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -640,9 +640,9 @@ func GreaterOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, arg + + // Greaterf asserts that the first element is greater than the second + // +-// assert.Greaterf(t, 2, 1, "error message %s", "formatted") +-// assert.Greaterf(t, float64(2), float64(1), "error message %s", "formatted") +-// assert.Greaterf(t, "b", "a", "error message %s", "formatted") ++// require.Greaterf(t, 2, 1, "error message %s", "formatted") ++// require.Greaterf(t, float64(2), float64(1), "error message %s", "formatted") ++// require.Greaterf(t, "b", "a", "error message %s", "formatted") + func Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -656,7 +656,7 @@ func Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...in + // HTTPBodyContains asserts that a specified handler returns a + // body that contains a string. + // +-// assert.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") ++// require.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") + // + // Returns whether the assertion was successful (true) or not (false). + func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) { +@@ -672,7 +672,7 @@ func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url s + // HTTPBodyContainsf asserts that a specified handler returns a + // body that contains a string. + // +-// assert.HTTPBodyContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") ++// require.HTTPBodyContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") + // + // Returns whether the assertion was successful (true) or not (false). + func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) { +@@ -688,7 +688,7 @@ func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url + // HTTPBodyNotContains asserts that a specified handler returns a + // body that does not contain a string. + // +-// assert.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") ++// require.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") + // + // Returns whether the assertion was successful (true) or not (false). + func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) { +@@ -704,7 +704,7 @@ func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, ur + // HTTPBodyNotContainsf asserts that a specified handler returns a + // body that does not contain a string. + // +-// assert.HTTPBodyNotContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") ++// require.HTTPBodyNotContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") + // + // Returns whether the assertion was successful (true) or not (false). + func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) { +@@ -719,7 +719,7 @@ func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, u + + // HTTPError asserts that a specified handler returns an error status code. + // +-// assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} ++// require.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} + // + // Returns whether the assertion was successful (true) or not (false). + func HTTPError(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { +@@ -734,7 +734,7 @@ func HTTPError(t TestingT, handler http.HandlerFunc, method string, url string, + + // HTTPErrorf asserts that a specified handler returns an error status code. + // +-// assert.HTTPErrorf(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} ++// require.HTTPErrorf(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} + // + // Returns whether the assertion was successful (true) or not (false). + func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { +@@ -749,7 +749,7 @@ func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, + + // HTTPRedirect asserts that a specified handler returns a redirect status code. + // +-// assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} ++// require.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} + // + // Returns whether the assertion was successful (true) or not (false). + func HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { +@@ -764,7 +764,7 @@ func HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url strin + + // HTTPRedirectf asserts that a specified handler returns a redirect status code. + // +-// assert.HTTPRedirectf(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} ++// require.HTTPRedirectf(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} + // + // Returns whether the assertion was successful (true) or not (false). + func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { +@@ -779,7 +779,7 @@ func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url stri + + // HTTPStatusCode asserts that a specified handler returns a specified status code. + // +-// assert.HTTPStatusCode(t, myHandler, "GET", "/notImplemented", nil, 501) ++// require.HTTPStatusCode(t, myHandler, "GET", "/notImplemented", nil, 501) + // + // Returns whether the assertion was successful (true) or not (false). + func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) { +@@ -794,7 +794,7 @@ func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method string, url str + + // HTTPStatusCodef asserts that a specified handler returns a specified status code. + // +-// assert.HTTPStatusCodef(t, myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") ++// require.HTTPStatusCodef(t, myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") + // + // Returns whether the assertion was successful (true) or not (false). + func HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) { +@@ -809,7 +809,7 @@ func HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url st + + // HTTPSuccess asserts that a specified handler returns a success status code. + // +-// assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) ++// require.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) + // + // Returns whether the assertion was successful (true) or not (false). + func HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { +@@ -824,7 +824,7 @@ func HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string + + // HTTPSuccessf asserts that a specified handler returns a success status code. + // +-// assert.HTTPSuccessf(t, myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") ++// require.HTTPSuccessf(t, myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") + // + // Returns whether the assertion was successful (true) or not (false). + func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { +@@ -839,7 +839,7 @@ func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url strin + + // Implements asserts that an object is implemented by the specified interface. + // +-// assert.Implements(t, (*MyInterface)(nil), new(MyObject)) ++// require.Implements(t, (*MyInterface)(nil), new(MyObject)) + func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -852,7 +852,7 @@ func Implements(t TestingT, interfaceObject interface{}, object interface{}, msg + + // Implementsf asserts that an object is implemented by the specified interface. + // +-// assert.Implementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") ++// require.Implementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") + func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -865,7 +865,7 @@ func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, ms + + // InDelta asserts that the two numerals are within delta of each other. + // +-// assert.InDelta(t, math.Pi, 22/7.0, 0.01) ++// require.InDelta(t, math.Pi, 22/7.0, 0.01) + func InDelta(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -922,7 +922,7 @@ func InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta f + + // InDeltaf asserts that the two numerals are within delta of each other. + // +-// assert.InDeltaf(t, math.Pi, 22/7.0, 0.01, "error message %s", "formatted") ++// require.InDeltaf(t, math.Pi, 22/7.0, 0.01, "error message %s", "formatted") + func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -979,9 +979,9 @@ func InEpsilonf(t TestingT, expected interface{}, actual interface{}, epsilon fl + + // IsDecreasing asserts that the collection is decreasing + // +-// assert.IsDecreasing(t, []int{2, 1, 0}) +-// assert.IsDecreasing(t, []float{2, 1}) +-// assert.IsDecreasing(t, []string{"b", "a"}) ++// require.IsDecreasing(t, []int{2, 1, 0}) ++// require.IsDecreasing(t, []float{2, 1}) ++// require.IsDecreasing(t, []string{"b", "a"}) + func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -994,9 +994,9 @@ func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { + + // IsDecreasingf asserts that the collection is decreasing + // +-// assert.IsDecreasingf(t, []int{2, 1, 0}, "error message %s", "formatted") +-// assert.IsDecreasingf(t, []float{2, 1}, "error message %s", "formatted") +-// assert.IsDecreasingf(t, []string{"b", "a"}, "error message %s", "formatted") ++// require.IsDecreasingf(t, []int{2, 1, 0}, "error message %s", "formatted") ++// require.IsDecreasingf(t, []float{2, 1}, "error message %s", "formatted") ++// require.IsDecreasingf(t, []string{"b", "a"}, "error message %s", "formatted") + func IsDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1009,9 +1009,9 @@ func IsDecreasingf(t TestingT, object interface{}, msg string, args ...interface + + // IsIncreasing asserts that the collection is increasing + // +-// assert.IsIncreasing(t, []int{1, 2, 3}) +-// assert.IsIncreasing(t, []float{1, 2}) +-// assert.IsIncreasing(t, []string{"a", "b"}) ++// require.IsIncreasing(t, []int{1, 2, 3}) ++// require.IsIncreasing(t, []float{1, 2}) ++// require.IsIncreasing(t, []string{"a", "b"}) + func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1024,9 +1024,9 @@ func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { + + // IsIncreasingf asserts that the collection is increasing + // +-// assert.IsIncreasingf(t, []int{1, 2, 3}, "error message %s", "formatted") +-// assert.IsIncreasingf(t, []float{1, 2}, "error message %s", "formatted") +-// assert.IsIncreasingf(t, []string{"a", "b"}, "error message %s", "formatted") ++// require.IsIncreasingf(t, []int{1, 2, 3}, "error message %s", "formatted") ++// require.IsIncreasingf(t, []float{1, 2}, "error message %s", "formatted") ++// require.IsIncreasingf(t, []string{"a", "b"}, "error message %s", "formatted") + func IsIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1039,9 +1039,9 @@ func IsIncreasingf(t TestingT, object interface{}, msg string, args ...interface + + // IsNonDecreasing asserts that the collection is not decreasing + // +-// assert.IsNonDecreasing(t, []int{1, 1, 2}) +-// assert.IsNonDecreasing(t, []float{1, 2}) +-// assert.IsNonDecreasing(t, []string{"a", "b"}) ++// require.IsNonDecreasing(t, []int{1, 1, 2}) ++// require.IsNonDecreasing(t, []float{1, 2}) ++// require.IsNonDecreasing(t, []string{"a", "b"}) + func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1054,9 +1054,9 @@ func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) + + // IsNonDecreasingf asserts that the collection is not decreasing + // +-// assert.IsNonDecreasingf(t, []int{1, 1, 2}, "error message %s", "formatted") +-// assert.IsNonDecreasingf(t, []float{1, 2}, "error message %s", "formatted") +-// assert.IsNonDecreasingf(t, []string{"a", "b"}, "error message %s", "formatted") ++// require.IsNonDecreasingf(t, []int{1, 1, 2}, "error message %s", "formatted") ++// require.IsNonDecreasingf(t, []float{1, 2}, "error message %s", "formatted") ++// require.IsNonDecreasingf(t, []string{"a", "b"}, "error message %s", "formatted") + func IsNonDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1069,9 +1069,9 @@ func IsNonDecreasingf(t TestingT, object interface{}, msg string, args ...interf + + // IsNonIncreasing asserts that the collection is not increasing + // +-// assert.IsNonIncreasing(t, []int{2, 1, 1}) +-// assert.IsNonIncreasing(t, []float{2, 1}) +-// assert.IsNonIncreasing(t, []string{"b", "a"}) ++// require.IsNonIncreasing(t, []int{2, 1, 1}) ++// require.IsNonIncreasing(t, []float{2, 1}) ++// require.IsNonIncreasing(t, []string{"b", "a"}) + func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1084,9 +1084,9 @@ func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) + + // IsNonIncreasingf asserts that the collection is not increasing + // +-// assert.IsNonIncreasingf(t, []int{2, 1, 1}, "error message %s", "formatted") +-// assert.IsNonIncreasingf(t, []float{2, 1}, "error message %s", "formatted") +-// assert.IsNonIncreasingf(t, []string{"b", "a"}, "error message %s", "formatted") ++// require.IsNonIncreasingf(t, []int{2, 1, 1}, "error message %s", "formatted") ++// require.IsNonIncreasingf(t, []float{2, 1}, "error message %s", "formatted") ++// require.IsNonIncreasingf(t, []string{"b", "a"}, "error message %s", "formatted") + func IsNonIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1121,7 +1121,7 @@ func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg strin + + // JSONEq asserts that two JSON strings are equivalent. + // +-// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) ++// require.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) + func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1134,7 +1134,7 @@ func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{ + + // JSONEqf asserts that two JSON strings are equivalent. + // +-// assert.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") ++// require.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") + func JSONEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1148,7 +1148,7 @@ func JSONEqf(t TestingT, expected string, actual string, msg string, args ...int + // Len asserts that the specified object has specific length. + // Len also fails if the object has a type that len() not accept. + // +-// assert.Len(t, mySlice, 3) ++// require.Len(t, mySlice, 3) + func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1162,7 +1162,7 @@ func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) + // Lenf asserts that the specified object has specific length. + // Lenf also fails if the object has a type that len() not accept. + // +-// assert.Lenf(t, mySlice, 3, "error message %s", "formatted") ++// require.Lenf(t, mySlice, 3, "error message %s", "formatted") + func Lenf(t TestingT, object interface{}, length int, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1175,9 +1175,9 @@ func Lenf(t TestingT, object interface{}, length int, msg string, args ...interf + + // Less asserts that the first element is less than the second + // +-// assert.Less(t, 1, 2) +-// assert.Less(t, float64(1), float64(2)) +-// assert.Less(t, "a", "b") ++// require.Less(t, 1, 2) ++// require.Less(t, float64(1), float64(2)) ++// require.Less(t, "a", "b") + func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1190,10 +1190,10 @@ func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) + + // LessOrEqual asserts that the first element is less than or equal to the second + // +-// assert.LessOrEqual(t, 1, 2) +-// assert.LessOrEqual(t, 2, 2) +-// assert.LessOrEqual(t, "a", "b") +-// assert.LessOrEqual(t, "b", "b") ++// require.LessOrEqual(t, 1, 2) ++// require.LessOrEqual(t, 2, 2) ++// require.LessOrEqual(t, "a", "b") ++// require.LessOrEqual(t, "b", "b") + func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1206,10 +1206,10 @@ func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...inter + + // LessOrEqualf asserts that the first element is less than or equal to the second + // +-// assert.LessOrEqualf(t, 1, 2, "error message %s", "formatted") +-// assert.LessOrEqualf(t, 2, 2, "error message %s", "formatted") +-// assert.LessOrEqualf(t, "a", "b", "error message %s", "formatted") +-// assert.LessOrEqualf(t, "b", "b", "error message %s", "formatted") ++// require.LessOrEqualf(t, 1, 2, "error message %s", "formatted") ++// require.LessOrEqualf(t, 2, 2, "error message %s", "formatted") ++// require.LessOrEqualf(t, "a", "b", "error message %s", "formatted") ++// require.LessOrEqualf(t, "b", "b", "error message %s", "formatted") + func LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1222,9 +1222,9 @@ func LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args . + + // Lessf asserts that the first element is less than the second + // +-// assert.Lessf(t, 1, 2, "error message %s", "formatted") +-// assert.Lessf(t, float64(1), float64(2), "error message %s", "formatted") +-// assert.Lessf(t, "a", "b", "error message %s", "formatted") ++// require.Lessf(t, 1, 2, "error message %s", "formatted") ++// require.Lessf(t, float64(1), float64(2), "error message %s", "formatted") ++// require.Lessf(t, "a", "b", "error message %s", "formatted") + func Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1237,8 +1237,8 @@ func Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...inter + + // Negative asserts that the specified element is negative + // +-// assert.Negative(t, -1) +-// assert.Negative(t, -1.23) ++// require.Negative(t, -1) ++// require.Negative(t, -1.23) + func Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1251,8 +1251,8 @@ func Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) { + + // Negativef asserts that the specified element is negative + // +-// assert.Negativef(t, -1, "error message %s", "formatted") +-// assert.Negativef(t, -1.23, "error message %s", "formatted") ++// require.Negativef(t, -1, "error message %s", "formatted") ++// require.Negativef(t, -1.23, "error message %s", "formatted") + func Negativef(t TestingT, e interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1266,7 +1266,7 @@ func Negativef(t TestingT, e interface{}, msg string, args ...interface{}) { + // Never asserts that the given condition doesn't satisfy in waitFor time, + // periodically checking the target function each tick. + // +-// assert.Never(t, func() bool { return false; }, time.Second, 10*time.Millisecond) ++// require.Never(t, func() bool { return false; }, time.Second, 10*time.Millisecond) + func Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1280,7 +1280,7 @@ func Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.D + // Neverf asserts that the given condition doesn't satisfy in waitFor time, + // periodically checking the target function each tick. + // +-// assert.Neverf(t, func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") ++// require.Neverf(t, func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") + func Neverf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1293,7 +1293,7 @@ func Neverf(t TestingT, condition func() bool, waitFor time.Duration, tick time. + + // Nil asserts that the specified object is nil. + // +-// assert.Nil(t, err) ++// require.Nil(t, err) + func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1306,7 +1306,7 @@ func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) { + + // Nilf asserts that the specified object is nil. + // +-// assert.Nilf(t, err, "error message %s", "formatted") ++// require.Nilf(t, err, "error message %s", "formatted") + func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1344,8 +1344,8 @@ func NoDirExistsf(t TestingT, path string, msg string, args ...interface{}) { + // NoError asserts that a function returned no error (i.e. `nil`). + // + // actualObj, err := SomeFunction() +-// if assert.NoError(t, err) { +-// assert.Equal(t, expectedObj, actualObj) ++// if require.NoError(t, err) { ++// require.Equal(t, expectedObj, actualObj) + // } + func NoError(t TestingT, err error, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { +@@ -1360,8 +1360,8 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) { + // NoErrorf asserts that a function returned no error (i.e. `nil`). + // + // actualObj, err := SomeFunction() +-// if assert.NoErrorf(t, err, "error message %s", "formatted") { +-// assert.Equal(t, expectedObj, actualObj) ++// if require.NoErrorf(t, err, "error message %s", "formatted") { ++// require.Equal(t, expectedObj, actualObj) + // } + func NoErrorf(t TestingT, err error, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { +@@ -1400,9 +1400,9 @@ func NoFileExistsf(t TestingT, path string, msg string, args ...interface{}) { + // NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the + // specified substring or element. + // +-// assert.NotContains(t, "Hello World", "Earth") +-// assert.NotContains(t, ["Hello", "World"], "Earth") +-// assert.NotContains(t, {"Hello": "World"}, "Earth") ++// require.NotContains(t, "Hello World", "Earth") ++// require.NotContains(t, ["Hello", "World"], "Earth") ++// require.NotContains(t, {"Hello": "World"}, "Earth") + func NotContains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1416,9 +1416,9 @@ func NotContains(t TestingT, s interface{}, contains interface{}, msgAndArgs ... + // NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the + // specified substring or element. + // +-// assert.NotContainsf(t, "Hello World", "Earth", "error message %s", "formatted") +-// assert.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted") +-// assert.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted") ++// require.NotContainsf(t, "Hello World", "Earth", "error message %s", "formatted") ++// require.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted") ++// require.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted") + func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1429,11 +1429,51 @@ func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, a + t.FailNow() + } + ++// NotElementsMatch asserts that the specified listA(array, slice...) is NOT equal to specified ++// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, ++// the number of appearances of each of them in both lists should not match. ++// This is an inverse of ElementsMatch. ++// ++// require.NotElementsMatch(t, [1, 1, 2, 3], [1, 1, 2, 3]) -> false ++// ++// require.NotElementsMatch(t, [1, 1, 2, 3], [1, 2, 3]) -> true ++// ++// require.NotElementsMatch(t, [1, 2, 3], [1, 2, 4]) -> true ++func NotElementsMatch(t TestingT, listA interface{}, listB interface{}, msgAndArgs ...interface{}) { ++ if h, ok := t.(tHelper); ok { ++ h.Helper() ++ } ++ if assert.NotElementsMatch(t, listA, listB, msgAndArgs...) { ++ return ++ } ++ t.FailNow() ++} ++ ++// NotElementsMatchf asserts that the specified listA(array, slice...) is NOT equal to specified ++// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, ++// the number of appearances of each of them in both lists should not match. ++// This is an inverse of ElementsMatch. ++// ++// require.NotElementsMatchf(t, [1, 1, 2, 3], [1, 1, 2, 3], "error message %s", "formatted") -> false ++// ++// require.NotElementsMatchf(t, [1, 1, 2, 3], [1, 2, 3], "error message %s", "formatted") -> true ++// ++// require.NotElementsMatchf(t, [1, 2, 3], [1, 2, 4], "error message %s", "formatted") -> true ++func NotElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) { ++ if h, ok := t.(tHelper); ok { ++ h.Helper() ++ } ++ if assert.NotElementsMatchf(t, listA, listB, msg, args...) { ++ return ++ } ++ t.FailNow() ++} ++ + // NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either + // a slice or a channel with len == 0. + // +-// if assert.NotEmpty(t, obj) { +-// assert.Equal(t, "two", obj[1]) ++// if require.NotEmpty(t, obj) { ++// require.Equal(t, "two", obj[1]) + // } + func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { +@@ -1448,8 +1488,8 @@ func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) { + // NotEmptyf asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either + // a slice or a channel with len == 0. + // +-// if assert.NotEmptyf(t, obj, "error message %s", "formatted") { +-// assert.Equal(t, "two", obj[1]) ++// if require.NotEmptyf(t, obj, "error message %s", "formatted") { ++// require.Equal(t, "two", obj[1]) + // } + func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { +@@ -1463,7 +1503,7 @@ func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) + + // NotEqual asserts that the specified values are NOT equal. + // +-// assert.NotEqual(t, obj1, obj2) ++// require.NotEqual(t, obj1, obj2) + // + // Pointer variable equality is determined based on the equality of the + // referenced values (as opposed to the memory addresses). +@@ -1479,7 +1519,7 @@ func NotEqual(t TestingT, expected interface{}, actual interface{}, msgAndArgs . + + // NotEqualValues asserts that two objects are not equal even when converted to the same type + // +-// assert.NotEqualValues(t, obj1, obj2) ++// require.NotEqualValues(t, obj1, obj2) + func NotEqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1492,7 +1532,7 @@ func NotEqualValues(t TestingT, expected interface{}, actual interface{}, msgAnd + + // NotEqualValuesf asserts that two objects are not equal even when converted to the same type + // +-// assert.NotEqualValuesf(t, obj1, obj2, "error message %s", "formatted") ++// require.NotEqualValuesf(t, obj1, obj2, "error message %s", "formatted") + func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1505,7 +1545,7 @@ func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg s + + // NotEqualf asserts that the specified values are NOT equal. + // +-// assert.NotEqualf(t, obj1, obj2, "error message %s", "formatted") ++// require.NotEqualf(t, obj1, obj2, "error message %s", "formatted") + // + // Pointer variable equality is determined based on the equality of the + // referenced values (as opposed to the memory addresses). +@@ -1519,7 +1559,31 @@ func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, + t.FailNow() + } + +-// NotErrorIs asserts that at none of the errors in err's chain matches target. ++// NotErrorAs asserts that none of the errors in err's chain matches target, ++// but if so, sets target to that error value. ++func NotErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{}) { ++ if h, ok := t.(tHelper); ok { ++ h.Helper() ++ } ++ if assert.NotErrorAs(t, err, target, msgAndArgs...) { ++ return ++ } ++ t.FailNow() ++} ++ ++// NotErrorAsf asserts that none of the errors in err's chain matches target, ++// but if so, sets target to that error value. ++func NotErrorAsf(t TestingT, err error, target interface{}, msg string, args ...interface{}) { ++ if h, ok := t.(tHelper); ok { ++ h.Helper() ++ } ++ if assert.NotErrorAsf(t, err, target, msg, args...) { ++ return ++ } ++ t.FailNow() ++} ++ ++// NotErrorIs asserts that none of the errors in err's chain matches target. + // This is a wrapper for errors.Is. + func NotErrorIs(t TestingT, err error, target error, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { +@@ -1531,7 +1595,7 @@ func NotErrorIs(t TestingT, err error, target error, msgAndArgs ...interface{}) + t.FailNow() + } + +-// NotErrorIsf asserts that at none of the errors in err's chain matches target. ++// NotErrorIsf asserts that none of the errors in err's chain matches target. + // This is a wrapper for errors.Is. + func NotErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { +@@ -1545,7 +1609,7 @@ func NotErrorIsf(t TestingT, err error, target error, msg string, args ...interf + + // NotImplements asserts that an object does not implement the specified interface. + // +-// assert.NotImplements(t, (*MyInterface)(nil), new(MyObject)) ++// require.NotImplements(t, (*MyInterface)(nil), new(MyObject)) + func NotImplements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1558,7 +1622,7 @@ func NotImplements(t TestingT, interfaceObject interface{}, object interface{}, + + // NotImplementsf asserts that an object does not implement the specified interface. + // +-// assert.NotImplementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") ++// require.NotImplementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") + func NotImplementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1571,7 +1635,7 @@ func NotImplementsf(t TestingT, interfaceObject interface{}, object interface{}, + + // NotNil asserts that the specified object is not nil. + // +-// assert.NotNil(t, err) ++// require.NotNil(t, err) + func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1584,7 +1648,7 @@ func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) { + + // NotNilf asserts that the specified object is not nil. + // +-// assert.NotNilf(t, err, "error message %s", "formatted") ++// require.NotNilf(t, err, "error message %s", "formatted") + func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1597,7 +1661,7 @@ func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) { + + // NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. + // +-// assert.NotPanics(t, func(){ RemainCalm() }) ++// require.NotPanics(t, func(){ RemainCalm() }) + func NotPanics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1610,7 +1674,7 @@ func NotPanics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { + + // NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic. + // +-// assert.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted") ++// require.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted") + func NotPanicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1623,8 +1687,8 @@ func NotPanicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interfac + + // NotRegexp asserts that a specified regexp does not match a string. + // +-// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") +-// assert.NotRegexp(t, "^start", "it's not starting") ++// require.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") ++// require.NotRegexp(t, "^start", "it's not starting") + func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1637,8 +1701,8 @@ func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interf + + // NotRegexpf asserts that a specified regexp does not match a string. + // +-// assert.NotRegexpf(t, regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted") +-// assert.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted") ++// require.NotRegexpf(t, regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted") ++// require.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted") + func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1651,7 +1715,7 @@ func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args .. + + // NotSame asserts that two pointers do not reference the same object. + // +-// assert.NotSame(t, ptr1, ptr2) ++// require.NotSame(t, ptr1, ptr2) + // + // Both arguments must be pointer variables. Pointer variable sameness is + // determined based on the equality of both type and value. +@@ -1667,7 +1731,7 @@ func NotSame(t TestingT, expected interface{}, actual interface{}, msgAndArgs .. + + // NotSamef asserts that two pointers do not reference the same object. + // +-// assert.NotSamef(t, ptr1, ptr2, "error message %s", "formatted") ++// require.NotSamef(t, ptr1, ptr2, "error message %s", "formatted") + // + // Both arguments must be pointer variables. Pointer variable sameness is + // determined based on the equality of both type and value. +@@ -1685,8 +1749,8 @@ func NotSamef(t TestingT, expected interface{}, actual interface{}, msg string, + // contain all elements given in the specified subset list(array, slice...) or + // map. + // +-// assert.NotSubset(t, [1, 3, 4], [1, 2]) +-// assert.NotSubset(t, {"x": 1, "y": 2}, {"z": 3}) ++// require.NotSubset(t, [1, 3, 4], [1, 2]) ++// require.NotSubset(t, {"x": 1, "y": 2}, {"z": 3}) + func NotSubset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1701,8 +1765,8 @@ func NotSubset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...i + // contain all elements given in the specified subset list(array, slice...) or + // map. + // +-// assert.NotSubsetf(t, [1, 3, 4], [1, 2], "error message %s", "formatted") +-// assert.NotSubsetf(t, {"x": 1, "y": 2}, {"z": 3}, "error message %s", "formatted") ++// require.NotSubsetf(t, [1, 3, 4], [1, 2], "error message %s", "formatted") ++// require.NotSubsetf(t, {"x": 1, "y": 2}, {"z": 3}, "error message %s", "formatted") + func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1737,7 +1801,7 @@ func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) { + + // Panics asserts that the code inside the specified PanicTestFunc panics. + // +-// assert.Panics(t, func(){ GoCrazy() }) ++// require.Panics(t, func(){ GoCrazy() }) + func Panics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1752,7 +1816,7 @@ func Panics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { + // panics, and that the recovered panic value is an error that satisfies the + // EqualError comparison. + // +-// assert.PanicsWithError(t, "crazy error", func(){ GoCrazy() }) ++// require.PanicsWithError(t, "crazy error", func(){ GoCrazy() }) + func PanicsWithError(t TestingT, errString string, f assert.PanicTestFunc, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1767,7 +1831,7 @@ func PanicsWithError(t TestingT, errString string, f assert.PanicTestFunc, msgAn + // panics, and that the recovered panic value is an error that satisfies the + // EqualError comparison. + // +-// assert.PanicsWithErrorf(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") ++// require.PanicsWithErrorf(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") + func PanicsWithErrorf(t TestingT, errString string, f assert.PanicTestFunc, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1781,7 +1845,7 @@ func PanicsWithErrorf(t TestingT, errString string, f assert.PanicTestFunc, msg + // PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that + // the recovered panic value equals the expected panic value. + // +-// assert.PanicsWithValue(t, "crazy error", func(){ GoCrazy() }) ++// require.PanicsWithValue(t, "crazy error", func(){ GoCrazy() }) + func PanicsWithValue(t TestingT, expected interface{}, f assert.PanicTestFunc, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1795,7 +1859,7 @@ func PanicsWithValue(t TestingT, expected interface{}, f assert.PanicTestFunc, m + // PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that + // the recovered panic value equals the expected panic value. + // +-// assert.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") ++// require.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") + func PanicsWithValuef(t TestingT, expected interface{}, f assert.PanicTestFunc, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1808,7 +1872,7 @@ func PanicsWithValuef(t TestingT, expected interface{}, f assert.PanicTestFunc, + + // Panicsf asserts that the code inside the specified PanicTestFunc panics. + // +-// assert.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted") ++// require.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted") + func Panicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1821,8 +1885,8 @@ func Panicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{} + + // Positive asserts that the specified element is positive + // +-// assert.Positive(t, 1) +-// assert.Positive(t, 1.23) ++// require.Positive(t, 1) ++// require.Positive(t, 1.23) + func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1835,8 +1899,8 @@ func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) { + + // Positivef asserts that the specified element is positive + // +-// assert.Positivef(t, 1, "error message %s", "formatted") +-// assert.Positivef(t, 1.23, "error message %s", "formatted") ++// require.Positivef(t, 1, "error message %s", "formatted") ++// require.Positivef(t, 1.23, "error message %s", "formatted") + func Positivef(t TestingT, e interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1849,8 +1913,8 @@ func Positivef(t TestingT, e interface{}, msg string, args ...interface{}) { + + // Regexp asserts that a specified regexp matches a string. + // +-// assert.Regexp(t, regexp.MustCompile("start"), "it's starting") +-// assert.Regexp(t, "start...$", "it's not starting") ++// require.Regexp(t, regexp.MustCompile("start"), "it's starting") ++// require.Regexp(t, "start...$", "it's not starting") + func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1863,8 +1927,8 @@ func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface + + // Regexpf asserts that a specified regexp matches a string. + // +-// assert.Regexpf(t, regexp.MustCompile("start"), "it's starting", "error message %s", "formatted") +-// assert.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted") ++// require.Regexpf(t, regexp.MustCompile("start"), "it's starting", "error message %s", "formatted") ++// require.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted") + func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1877,7 +1941,7 @@ func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...in + + // Same asserts that two pointers reference the same object. + // +-// assert.Same(t, ptr1, ptr2) ++// require.Same(t, ptr1, ptr2) + // + // Both arguments must be pointer variables. Pointer variable sameness is + // determined based on the equality of both type and value. +@@ -1893,7 +1957,7 @@ func Same(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...in + + // Samef asserts that two pointers reference the same object. + // +-// assert.Samef(t, ptr1, ptr2, "error message %s", "formatted") ++// require.Samef(t, ptr1, ptr2, "error message %s", "formatted") + // + // Both arguments must be pointer variables. Pointer variable sameness is + // determined based on the equality of both type and value. +@@ -1910,8 +1974,8 @@ func Samef(t TestingT, expected interface{}, actual interface{}, msg string, arg + // Subset asserts that the specified list(array, slice...) or map contains all + // elements given in the specified subset list(array, slice...) or map. + // +-// assert.Subset(t, [1, 2, 3], [1, 2]) +-// assert.Subset(t, {"x": 1, "y": 2}, {"x": 1}) ++// require.Subset(t, [1, 2, 3], [1, 2]) ++// require.Subset(t, {"x": 1, "y": 2}, {"x": 1}) + func Subset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1925,8 +1989,8 @@ func Subset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...inte + // Subsetf asserts that the specified list(array, slice...) or map contains all + // elements given in the specified subset list(array, slice...) or map. + // +-// assert.Subsetf(t, [1, 2, 3], [1, 2], "error message %s", "formatted") +-// assert.Subsetf(t, {"x": 1, "y": 2}, {"x": 1}, "error message %s", "formatted") ++// require.Subsetf(t, [1, 2, 3], [1, 2], "error message %s", "formatted") ++// require.Subsetf(t, {"x": 1, "y": 2}, {"x": 1}, "error message %s", "formatted") + func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1939,7 +2003,7 @@ func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args + + // True asserts that the specified value is true. + // +-// assert.True(t, myBool) ++// require.True(t, myBool) + func True(t TestingT, value bool, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1952,7 +2016,7 @@ func True(t TestingT, value bool, msgAndArgs ...interface{}) { + + // Truef asserts that the specified value is true. + // +-// assert.Truef(t, myBool, "error message %s", "formatted") ++// require.Truef(t, myBool, "error message %s", "formatted") + func Truef(t TestingT, value bool, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1965,7 +2029,7 @@ func Truef(t TestingT, value bool, msg string, args ...interface{}) { + + // WithinDuration asserts that the two times are within duration delta of each other. + // +-// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second) ++// require.WithinDuration(t, time.Now(), time.Now(), 10*time.Second) + func WithinDuration(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1978,7 +2042,7 @@ func WithinDuration(t TestingT, expected time.Time, actual time.Time, delta time + + // WithinDurationf asserts that the two times are within duration delta of each other. + // +-// assert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") ++// require.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") + func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -1991,7 +2055,7 @@ func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta tim + + // WithinRange asserts that a time is within a time range (inclusive). + // +-// assert.WithinRange(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second)) ++// require.WithinRange(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second)) + func WithinRange(t TestingT, actual time.Time, start time.Time, end time.Time, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +@@ -2004,7 +2068,7 @@ func WithinRange(t TestingT, actual time.Time, start time.Time, end time.Time, m + + // WithinRangef asserts that a time is within a time range (inclusive). + // +-// assert.WithinRangef(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted") ++// require.WithinRangef(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted") + func WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() +diff --git a/vendor/github.com/stretchr/testify/require/require.go.tmpl b/vendor/github.com/stretchr/testify/require/require.go.tmpl +index 55e42ddeb..8b3283685 100644 +--- a/vendor/github.com/stretchr/testify/require/require.go.tmpl ++++ b/vendor/github.com/stretchr/testify/require/require.go.tmpl +@@ -1,4 +1,4 @@ +-{{.Comment}} ++{{ replace .Comment "assert." "require."}} + func {{.DocInfo.Name}}(t TestingT, {{.Params}}) { + if h, ok := t.(tHelper); ok { h.Helper() } + if assert.{{.DocInfo.Name}}(t, {{.ForwardedParams}}) { return } +diff --git a/vendor/github.com/stretchr/testify/require/require_forward.go b/vendor/github.com/stretchr/testify/require/require_forward.go +index eee8310a5..1bd87304f 100644 +--- a/vendor/github.com/stretchr/testify/require/require_forward.go ++++ b/vendor/github.com/stretchr/testify/require/require_forward.go +@@ -187,8 +187,8 @@ func (a *Assertions) EqualExportedValuesf(expected interface{}, actual interface + EqualExportedValuesf(a.t, expected, actual, msg, args...) + } + +-// EqualValues asserts that two objects are equal or convertible to the same types +-// and equal. ++// EqualValues asserts that two objects are equal or convertible to the larger ++// type and equal. + // + // a.EqualValues(uint32(123), int32(123)) + func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) { +@@ -198,8 +198,8 @@ func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAn + EqualValues(a.t, expected, actual, msgAndArgs...) + } + +-// EqualValuesf asserts that two objects are equal or convertible to the same types +-// and equal. ++// EqualValuesf asserts that two objects are equal or convertible to the larger ++// type and equal. + // + // a.EqualValuesf(uint32(123), int32(123), "error message %s", "formatted") + func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) { +@@ -337,7 +337,7 @@ func (a *Assertions) Eventually(condition func() bool, waitFor time.Duration, ti + // a.EventuallyWithT(func(c *assert.CollectT) { + // // add assertions as needed; any assertion failure will fail the current tick + // assert.True(c, externalValue, "expected 'externalValue' to be true") +-// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") ++// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") + func (a *Assertions) EventuallyWithT(condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { + if h, ok := a.t.(tHelper); ok { + h.Helper() +@@ -362,7 +362,7 @@ func (a *Assertions) EventuallyWithT(condition func(collect *assert.CollectT), w + // a.EventuallyWithTf(func(c *assert.CollectT, "error message %s", "formatted") { + // // add assertions as needed; any assertion failure will fail the current tick + // assert.True(c, externalValue, "expected 'externalValue' to be true") +-// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") ++// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") + func (a *Assertions) EventuallyWithTf(condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { + if h, ok := a.t.(tHelper); ok { + h.Helper() +@@ -1129,6 +1129,40 @@ func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg strin + NotContainsf(a.t, s, contains, msg, args...) + } + ++// NotElementsMatch asserts that the specified listA(array, slice...) is NOT equal to specified ++// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, ++// the number of appearances of each of them in both lists should not match. ++// This is an inverse of ElementsMatch. ++// ++// a.NotElementsMatch([1, 1, 2, 3], [1, 1, 2, 3]) -> false ++// ++// a.NotElementsMatch([1, 1, 2, 3], [1, 2, 3]) -> true ++// ++// a.NotElementsMatch([1, 2, 3], [1, 2, 4]) -> true ++func (a *Assertions) NotElementsMatch(listA interface{}, listB interface{}, msgAndArgs ...interface{}) { ++ if h, ok := a.t.(tHelper); ok { ++ h.Helper() ++ } ++ NotElementsMatch(a.t, listA, listB, msgAndArgs...) ++} ++ ++// NotElementsMatchf asserts that the specified listA(array, slice...) is NOT equal to specified ++// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, ++// the number of appearances of each of them in both lists should not match. ++// This is an inverse of ElementsMatch. ++// ++// a.NotElementsMatchf([1, 1, 2, 3], [1, 1, 2, 3], "error message %s", "formatted") -> false ++// ++// a.NotElementsMatchf([1, 1, 2, 3], [1, 2, 3], "error message %s", "formatted") -> true ++// ++// a.NotElementsMatchf([1, 2, 3], [1, 2, 4], "error message %s", "formatted") -> true ++func (a *Assertions) NotElementsMatchf(listA interface{}, listB interface{}, msg string, args ...interface{}) { ++ if h, ok := a.t.(tHelper); ok { ++ h.Helper() ++ } ++ NotElementsMatchf(a.t, listA, listB, msg, args...) ++} ++ + // NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either + // a slice or a channel with len == 0. + // +@@ -1201,7 +1235,25 @@ func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg str + NotEqualf(a.t, expected, actual, msg, args...) + } + +-// NotErrorIs asserts that at none of the errors in err's chain matches target. ++// NotErrorAs asserts that none of the errors in err's chain matches target, ++// but if so, sets target to that error value. ++func (a *Assertions) NotErrorAs(err error, target interface{}, msgAndArgs ...interface{}) { ++ if h, ok := a.t.(tHelper); ok { ++ h.Helper() ++ } ++ NotErrorAs(a.t, err, target, msgAndArgs...) ++} ++ ++// NotErrorAsf asserts that none of the errors in err's chain matches target, ++// but if so, sets target to that error value. ++func (a *Assertions) NotErrorAsf(err error, target interface{}, msg string, args ...interface{}) { ++ if h, ok := a.t.(tHelper); ok { ++ h.Helper() ++ } ++ NotErrorAsf(a.t, err, target, msg, args...) ++} ++ ++// NotErrorIs asserts that none of the errors in err's chain matches target. + // This is a wrapper for errors.Is. + func (a *Assertions) NotErrorIs(err error, target error, msgAndArgs ...interface{}) { + if h, ok := a.t.(tHelper); ok { +@@ -1210,7 +1262,7 @@ func (a *Assertions) NotErrorIs(err error, target error, msgAndArgs ...interface + NotErrorIs(a.t, err, target, msgAndArgs...) + } + +-// NotErrorIsf asserts that at none of the errors in err's chain matches target. ++// NotErrorIsf asserts that none of the errors in err's chain matches target. + // This is a wrapper for errors.Is. + func (a *Assertions) NotErrorIsf(err error, target error, msg string, args ...interface{}) { + if h, ok := a.t.(tHelper); ok { +diff --git a/vendor/github.com/stretchr/testify/require/requirements.go b/vendor/github.com/stretchr/testify/require/requirements.go +index 91772dfeb..6b7ce929e 100644 +--- a/vendor/github.com/stretchr/testify/require/requirements.go ++++ b/vendor/github.com/stretchr/testify/require/requirements.go +@@ -6,7 +6,7 @@ type TestingT interface { + FailNow() + } + +-type tHelper interface { ++type tHelper = interface { + Helper() + } + +diff --git a/vendor/k8s.io/kubernetes/pkg/features/kube_features.go b/vendor/k8s.io/kubernetes/pkg/features/kube_features.go +index bfd01e1e0..86d136919 100644 +--- a/vendor/k8s.io/kubernetes/pkg/features/kube_features.go ++++ b/vendor/k8s.io/kubernetes/pkg/features/kube_features.go +@@ -541,7 +541,8 @@ const ( + // alpha: v1.27 + // beta: v1.30 + // +- // Enables querying logs of node services using the /logs endpoint ++ // Enables querying logs of node services using the /logs endpoint. Enabling this feature has security implications. ++ // The recommendation is to enable it on a need basis for debugging purposes and disabling otherwise. + NodeLogQuery featuregate.Feature = "NodeLogQuery" + + // owner: @xing-yang @sonasingh46 +@@ -1267,7 +1268,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS + + genericfeatures.APIServerTracing: {Default: true, PreRelease: featuregate.Beta}, + +- genericfeatures.APIServingWithRoutine: {Default: true, PreRelease: featuregate.Beta}, ++ genericfeatures.APIServingWithRoutine: {Default: false, PreRelease: featuregate.Alpha}, + + genericfeatures.ConsistentListFromCache: {Default: false, PreRelease: featuregate.Alpha}, + +diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer.go b/vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer.go +index 3ac4dcffe..a6837fa65 100644 +--- a/vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer.go ++++ b/vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer.go +@@ -444,7 +444,8 @@ func (w *AtomicWriter) writePayloadToDir(payload map[string]FileProjection, dir + if fileProjection.FsUser == nil { + continue + } +- if err := os.Chown(fullPath, int(*fileProjection.FsUser), -1); err != nil { ++ ++ if err := w.chown(fullPath, int(*fileProjection.FsUser), -1); err != nil { + klog.Errorf("%s: unable to change file %s with owner %v: %v", w.logContext, fullPath, int(*fileProjection.FsUser), err) + return err + } +diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer_linux.go b/vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer_linux.go +new file mode 100644 +index 000000000..c12a0f4cd +--- /dev/null ++++ b/vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer_linux.go +@@ -0,0 +1,27 @@ ++//go:build linux ++// +build linux ++ ++/* ++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 util ++ ++import "os" ++ ++// chown changes the numeric uid and gid of the named file. ++func (w *AtomicWriter) chown(name string, uid, gid int) error { ++ return os.Chown(name, uid, gid) ++} +diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer_unsupported.go b/vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer_unsupported.go +new file mode 100644 +index 000000000..cdfb83e63 +--- /dev/null ++++ b/vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer_unsupported.go +@@ -0,0 +1,33 @@ ++//go:build !linux ++// +build !linux ++ ++/* ++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 util ++ ++import ( ++ "runtime" ++ ++ "k8s.io/klog/v2" ++) ++ ++// chown changes the numeric uid and gid of the named file. ++// This is a no-op on unsupported platforms. ++func (w *AtomicWriter) chown(name string, uid, _ /* gid */ int) error { ++ klog.Warningf("%s: skipping change of Linux owner %v for file %s; unsupported on %s", w.logContext, uid, name, runtime.GOOS) ++ return nil ++} +diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/device_util_linux.go b/vendor/k8s.io/kubernetes/pkg/volume/util/device_util_linux.go +index 66ac77835..18cbec072 100644 +--- a/vendor/k8s.io/kubernetes/pkg/volume/util/device_util_linux.go ++++ b/vendor/k8s.io/kubernetes/pkg/volume/util/device_util_linux.go +@@ -31,8 +31,13 @@ import ( + "k8s.io/klog/v2" + ) + +-// FindMultipathDeviceForDevice given a device name like /dev/sdx, find the devicemapper parent ++// FindMultipathDeviceForDevice given a device name like /dev/sdx, find the devicemapper parent. If called with a device ++// already resolved to devicemapper, do nothing. + func (handler *deviceHandler) FindMultipathDeviceForDevice(device string) string { ++ if strings.HasPrefix(device, "/dev/dm-") { ++ return device ++ } ++ + io := handler.getIo + disk, err := findDeviceForPath(device, io) + if err != nil { +diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/recyclerclient/recycler_client.go b/vendor/k8s.io/kubernetes/pkg/volume/util/recyclerclient/recycler_client.go +index b7197dbdf..e438ba21e 100644 +--- a/vendor/k8s.io/kubernetes/pkg/volume/util/recyclerclient/recycler_client.go ++++ b/vendor/k8s.io/kubernetes/pkg/volume/util/recyclerclient/recycler_client.go +@@ -18,11 +18,12 @@ package recyclerclient + + import ( + "context" ++ "errors" + "fmt" + "sync" + + "k8s.io/api/core/v1" +- "k8s.io/apimachinery/pkg/api/errors" ++ apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/watch" +@@ -72,7 +73,7 @@ func internalRecycleVolumeByWatchingPodUntilCompletion(pvName string, pod *v1.Po + // Start the pod + _, err = recyclerClient.CreatePod(pod) + if err != nil { +- if errors.IsAlreadyExists(err) { ++ if apierrors.IsAlreadyExists(err) { + deleteErr := recyclerClient.DeletePod(pod.Name, pod.Namespace) + if deleteErr != nil { + return fmt.Errorf("failed to delete old recycler pod %s/%s: %s", pod.Namespace, pod.Name, deleteErr) +@@ -128,7 +129,7 @@ func waitForPod(pod *v1.Pod, recyclerClient recyclerClient, podCh <-chan watch.E + } + if pod.Status.Phase == v1.PodFailed { + if pod.Status.Message != "" { +- return fmt.Errorf(pod.Status.Message) ++ return errors.New(pod.Status.Message) + } + return fmt.Errorf("pod failed, pod.Status.Message unknown") + } +diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/util.go b/vendor/k8s.io/kubernetes/pkg/volume/util/util.go +index 601dc6460..d1691cd80 100644 +--- a/vendor/k8s.io/kubernetes/pkg/volume/util/util.go ++++ b/vendor/k8s.io/kubernetes/pkg/volume/util/util.go +@@ -575,44 +575,6 @@ func IsLocalEphemeralVolume(volume v1.Volume) bool { + volume.ConfigMap != nil + } + +-// GetLocalPersistentVolumeNodeNames returns the node affinity node name(s) for +-// local PersistentVolumes. nil is returned if the PV does not have any +-// specific node affinity node selector terms and match expressions. +-// PersistentVolume with node affinity has select and match expressions +-// in the form of: +-// +-// nodeAffinity: +-// required: +-// nodeSelectorTerms: +-// - matchExpressions: +-// - key: kubernetes.io/hostname +-// operator: In +-// values: +-// - +-// - +-func GetLocalPersistentVolumeNodeNames(pv *v1.PersistentVolume) []string { +- if pv == nil || pv.Spec.NodeAffinity == nil || pv.Spec.NodeAffinity.Required == nil { +- return nil +- } +- +- var result sets.Set[string] +- for _, term := range pv.Spec.NodeAffinity.Required.NodeSelectorTerms { +- var nodes sets.Set[string] +- for _, matchExpr := range term.MatchExpressions { +- if matchExpr.Key == v1.LabelHostname && matchExpr.Operator == v1.NodeSelectorOpIn { +- if nodes == nil { +- nodes = sets.New(matchExpr.Values...) +- } else { +- nodes = nodes.Intersection(sets.New(matchExpr.Values...)) +- } +- } +- } +- result = result.Union(nodes) +- } +- +- return sets.List(result) +-} +- + // GetPodVolumeNames returns names of volumes that are used in a pod, + // either as filesystem mount or raw block device, together with list + // of all SELinux contexts of all containers that use the volumes. +diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/debug/resource_usage_gatherer.go b/vendor/k8s.io/kubernetes/test/e2e/framework/debug/resource_usage_gatherer.go +index 9c6537ed9..7e6875b49 100644 +--- a/vendor/k8s.io/kubernetes/test/e2e/framework/debug/resource_usage_gatherer.go ++++ b/vendor/k8s.io/kubernetes/test/e2e/framework/debug/resource_usage_gatherer.go +@@ -21,6 +21,7 @@ import ( + "bytes" + "context" + "encoding/json" ++ "errors" + "fmt" + "math" + "regexp" +@@ -595,7 +596,7 @@ func (g *ContainerResourceGatherer) StopAndSummarize(percentiles []int, constrai + } + } + if len(violatedConstraints) > 0 { +- return &summary, fmt.Errorf(strings.Join(violatedConstraints, "\n")) ++ return &summary, errors.New(strings.Join(violatedConstraints, "\n")) + } + return &summary, nil + } +diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/flake_reporting_util.go b/vendor/k8s.io/kubernetes/test/e2e/framework/flake_reporting_util.go +index 36d9baa98..103345fb6 100644 +--- a/vendor/k8s.io/kubernetes/test/e2e/framework/flake_reporting_util.go ++++ b/vendor/k8s.io/kubernetes/test/e2e/framework/flake_reporting_util.go +@@ -57,7 +57,7 @@ func (f *FlakeReport) RecordFlakeIfError(err error, optionalDescription ...inter + if desc != "" { + msg = fmt.Sprintf("%v (Description: %v)", msg, desc) + } +- Logf(msg) ++ Logf("%s", msg) + f.lock.Lock() + defer f.lock.Unlock() + f.Flakes = append(f.Flakes, msg) +diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/framework.go b/vendor/k8s.io/kubernetes/test/e2e/framework/framework.go +index 954becb63..7ece76bae 100644 +--- a/vendor/k8s.io/kubernetes/test/e2e/framework/framework.go ++++ b/vendor/k8s.io/kubernetes/test/e2e/framework/framework.go +@@ -311,7 +311,7 @@ func printSummaries(summaries []TestDataSummary, testBaseName string) { + switch TestContext.OutputPrintType { + case "hr": + if TestContext.ReportDir == "" { +- Logf(summaries[i].PrintHumanReadable()) ++ Logf("%s", summaries[i].PrintHumanReadable()) + } else { + // TODO: learn to extract test name and append it to the kind instead of timestamp. + filePath := path.Join(TestContext.ReportDir, summaries[i].SummaryKind()+"_"+testBaseName+"_"+now.Format(time.RFC3339)+".txt") +@@ -393,7 +393,7 @@ func (f *Framework) AfterEach(ctx context.Context) { + for namespaceKey, namespaceErr := range nsDeletionErrors { + messages = append(messages, fmt.Sprintf("Couldn't delete ns: %q: %s (%#v)", namespaceKey, namespaceErr, namespaceErr)) + } +- Failf(strings.Join(messages, ",")) ++ Fail(strings.Join(messages, ",")) + } + }() + +diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/node/resource.go b/vendor/k8s.io/kubernetes/test/e2e/framework/node/resource.go +index a57473bab..a7750399c 100644 +--- a/vendor/k8s.io/kubernetes/test/e2e/framework/node/resource.go ++++ b/vendor/k8s.io/kubernetes/test/e2e/framework/node/resource.go +@@ -128,7 +128,7 @@ func isNodeConditionSetAsExpected(node *v1.Node, conditionType v1.NodeConditionT + conditionType, node.Name, cond.Status == v1.ConditionTrue, taints) + } + if !silent { +- framework.Logf(msg) ++ framework.Logf("%s", msg) + } + return false + } +@@ -822,6 +822,6 @@ func verifyThatTaintIsGone(ctx context.Context, c clientset.Interface, nodeName + // TODO use wrapper methods in expect.go after removing core e2e dependency on node + gomega.ExpectWithOffset(2, err).NotTo(gomega.HaveOccurred()) + if taintExists(nodeUpdated.Spec.Taints, taint) { +- framework.Failf("Failed removing taint " + taint.ToString() + " of the node " + nodeName) ++ framework.Fail("Failed removing taint " + taint.ToString() + " of the node " + nodeName) + } + } +diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/skipper/skipper.go b/vendor/k8s.io/kubernetes/test/e2e/framework/skipper/skipper.go +index 4a509b90a..169f5995e 100644 +--- a/vendor/k8s.io/kubernetes/test/e2e/framework/skipper/skipper.go ++++ b/vendor/k8s.io/kubernetes/test/e2e/framework/skipper/skipper.go +@@ -46,10 +46,13 @@ func Skipf(format string, args ...interface{}) { + panic("unreachable") + } + ++// Skip is an alias for ginkgo.Skip. ++var Skip = ginkgo.Skip ++ + // SkipUnlessAtLeast skips if the value is less than the minValue. + func SkipUnlessAtLeast(value int, minValue int, message string) { + if value < minValue { +- skipInternalf(1, message) ++ skipInternalf(1, "%s", message) + } + } + +diff --git a/vendor/k8s.io/kubernetes/test/utils/density_utils.go b/vendor/k8s.io/kubernetes/test/utils/density_utils.go +index 23917ad9f..e0747c489 100644 +--- a/vendor/k8s.io/kubernetes/test/utils/density_utils.go ++++ b/vendor/k8s.io/kubernetes/test/utils/density_utils.go +@@ -18,6 +18,7 @@ package utils + + import ( + "context" ++ "errors" + "fmt" + "strings" + "time" +@@ -99,7 +100,7 @@ func VerifyLabelsRemoved(c clientset.Interface, nodeName string, labelKeys []str + } + for _, labelKey := range labelKeys { + if node.Labels != nil && len(node.Labels[labelKey]) != 0 { +- return fmt.Errorf("Failed removing label " + labelKey + " of the node " + nodeName) ++ return errors.New("Failed removing label " + labelKey + " of the node " + nodeName) + } + } + return nil +diff --git a/vendor/k8s.io/kubernetes/test/utils/deployment.go b/vendor/k8s.io/kubernetes/test/utils/deployment.go +index 60f20751a..3c287b0b7 100644 +--- a/vendor/k8s.io/kubernetes/test/utils/deployment.go ++++ b/vendor/k8s.io/kubernetes/test/utils/deployment.go +@@ -18,6 +18,7 @@ package utils + + import ( + "context" ++ "errors" + "fmt" + "time" + +@@ -226,7 +227,7 @@ func WaitForDeploymentRevisionAndImage(c clientset.Interface, ns, deploymentName + }) + if wait.Interrupted(err) { + LogReplicaSetsOfDeployment(deployment, nil, newRS, logf) +- err = fmt.Errorf(reason) ++ err = errors.New(reason) + } + if newRS == nil { + return fmt.Errorf("deployment %q failed to create new replica set", deploymentName) +diff --git a/vendor/k8s.io/kubernetes/test/utils/image/manifest.go b/vendor/k8s.io/kubernetes/test/utils/image/manifest.go +index 9fae113f4..9372e7d18 100644 +--- a/vendor/k8s.io/kubernetes/test/utils/image/manifest.go ++++ b/vendor/k8s.io/kubernetes/test/utils/image/manifest.go +@@ -237,8 +237,8 @@ func initImageConfigs(list RegistryList) (map[ImageID]Config, map[ImageID]Config + configs[BusyBox] = Config{list.PromoterE2eRegistry, "busybox", "1.36.1-1"} + configs[CudaVectorAdd] = Config{list.PromoterE2eRegistry, "cuda-vector-add", "1.0"} + configs[CudaVectorAdd2] = Config{list.PromoterE2eRegistry, "cuda-vector-add", "2.3"} +- configs[DistrolessIptables] = Config{list.BuildImageRegistry, "distroless-iptables", "v0.5.6"} +- configs[Etcd] = Config{list.GcEtcdRegistry, "etcd", "3.5.12-0"} ++ configs[DistrolessIptables] = Config{list.BuildImageRegistry, "distroless-iptables", "v0.5.13"} ++ configs[Etcd] = Config{list.GcEtcdRegistry, "etcd", "3.5.15-0"} + configs[Httpd] = Config{list.PromoterE2eRegistry, "httpd", "2.4.38-4"} + configs[HttpdNew] = Config{list.PromoterE2eRegistry, "httpd", "2.4.39-4"} + configs[InvalidRegistryImage] = Config{list.InvalidRegistry, "alpine", "3.1"} +diff --git a/vendor/k8s.io/kubernetes/test/utils/runners.go b/vendor/k8s.io/kubernetes/test/utils/runners.go +index 3fb9b58dc..f5fa5c2a0 100644 +--- a/vendor/k8s.io/kubernetes/test/utils/runners.go ++++ b/vendor/k8s.io/kubernetes/test/utils/runners.go +@@ -825,7 +825,7 @@ func (config *RCConfig) start(ctx context.Context) error { + *config.CreatedPods = startupStatus.Created + } + if !config.Silent { +- config.RCConfigLog(startupStatus.String(config.Name)) ++ config.RCConfigLog("%s", startupStatus.String(config.Name)) + } + + if config.PodStatusFile != nil { +@@ -849,8 +849,8 @@ func (config *RCConfig) start(ctx context.Context) error { + if podDeletionsCount > config.MaxAllowedPodDeletions { + // Number of pods which disappeared is over threshold + err := fmt.Errorf("%d pods disappeared for %s: %v", podDeletionsCount, config.Name, strings.Join(deletedPods, ", ")) +- config.RCConfigLog(err.Error()) +- config.RCConfigLog(diff.String(sets.NewString())) ++ config.RCConfigLog("%s", err.Error()) ++ config.RCConfigLog("%s", diff.String(sets.NewString())) + return err + } + +diff --git a/vendor/modules.txt b/vendor/modules.txt +index d2a16b08b..f871b7f27 100644 +--- a/vendor/modules.txt ++++ b/vendor/modules.txt +@@ -200,7 +200,7 @@ github.com/cenkalti/backoff/v3 + ## explicit; go 1.18 + github.com/cenkalti/backoff/v4 + # github.com/ceph/ceph-csi/api v0.0.0-00010101000000-000000000000 => ./api +-## explicit; go 1.22.0 ++## explicit; go 1.23.0 + github.com/ceph/ceph-csi/api/deploy/kubernetes + github.com/ceph/ceph-csi/api/deploy/kubernetes/cephfs + github.com/ceph/ceph-csi/api/deploy/kubernetes/nfs +@@ -279,7 +279,7 @@ github.com/gemalto/kmip-go/ttlv + # github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 + ## explicit + github.com/ghodss/yaml +-# github.com/go-jose/go-jose/v4 v4.0.1 ++# github.com/go-jose/go-jose/v4 v4.0.5 + ## explicit; go 1.21 + github.com/go-jose/go-jose/v4 + github.com/go-jose/go-jose/v4/cipher +@@ -611,9 +611,10 @@ github.com/spf13/pflag + # github.com/stoewer/go-strcase v1.2.0 + ## explicit; go 1.11 + github.com/stoewer/go-strcase +-# github.com/stretchr/testify v1.9.0 ++# github.com/stretchr/testify v1.10.0 + ## explicit; go 1.17 + github.com/stretchr/testify/assert ++github.com/stretchr/testify/assert/yaml + github.com/stretchr/testify/require + # go.etcd.io/etcd/api/v3 v3.5.10 + ## explicit; go 1.20 +@@ -1644,7 +1645,7 @@ k8s.io/kubectl/pkg/util/podutils + ## explicit; go 1.22.0 + k8s.io/kubelet/pkg/apis + k8s.io/kubelet/pkg/apis/stats/v1alpha1 +-# k8s.io/kubernetes v1.30.3 ++# k8s.io/kubernetes v1.30.10 + ## explicit; go 1.22.0 + k8s.io/kubernetes/pkg/api/legacyscheme + k8s.io/kubernetes/pkg/api/service +-- +2.43.0 + diff --git a/images/webhooks/src/cmd/main.go b/images/webhooks/cmd/main.go similarity index 97% rename from images/webhooks/src/cmd/main.go rename to images/webhooks/cmd/main.go index ffacb7b1..7d69f11c 100644 --- a/images/webhooks/src/cmd/main.go +++ b/images/webhooks/cmd/main.go @@ -26,7 +26,7 @@ import ( kwhlogrus "github.com/slok/kubewebhook/v2/pkg/log/logrus" storagev1 "k8s.io/api/storage/v1" - "webhooks/handlers" + "github.com/deckhouse/csi-ceph/images/webhooks/handlers" ) type config struct { diff --git a/images/webhooks/src/go.mod b/images/webhooks/go.mod similarity index 95% rename from images/webhooks/src/go.mod rename to images/webhooks/go.mod index b4286409..4ee7e574 100644 --- a/images/webhooks/src/go.mod +++ b/images/webhooks/go.mod @@ -1,4 +1,4 @@ -module webhooks +module github.com/deckhouse/csi-ceph/images/webhooks go 1.23.6 diff --git a/images/webhooks/src/go.sum b/images/webhooks/go.sum similarity index 100% rename from images/webhooks/src/go.sum rename to images/webhooks/go.sum diff --git a/images/webhooks/src/handlers/func.go b/images/webhooks/handlers/func.go similarity index 100% rename from images/webhooks/src/handlers/func.go rename to images/webhooks/handlers/func.go diff --git a/images/webhooks/src/handlers/scValidator.go b/images/webhooks/handlers/scValidator.go similarity index 100% rename from images/webhooks/src/handlers/scValidator.go rename to images/webhooks/handlers/scValidator.go diff --git a/images/webhooks/werf.inc.yaml b/images/webhooks/werf.inc.yaml index fbc1b279..857e8ba2 100644 --- a/images/webhooks/werf.inc.yaml +++ b/images/webhooks/werf.inc.yaml @@ -1,16 +1,23 @@ --- image: {{ $.ImageName }}-src-artifact -from: {{ $.Root.BASE_ALT }} +from: {{ $.Root.BASE_ALT_P11 }} final: false + git: - add: / to: /src includePaths: - api - - images/webhooks/src + - images/{{ $.ImageName }} stageDependencies: install: - '**/*' + excludePaths: + - images/{{ $.ImageName }}/werf.yaml + +shell: + install: + - echo "src artifact" --- image: {{ $.ImageName }}-golang-artifact @@ -21,7 +28,7 @@ import: - image: {{ $.ImageName }}-src-artifact add: /src to: /src - before: setup + before: install mount: - fromPath: ~/go-pkg-cache @@ -29,9 +36,9 @@ mount: shell: setup: - - cd /src/images/webhooks/src/cmd - - GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags="-s -w" -o /webhooks - - chmod +x /webhooks + - cd /src/images/{{ $.ImageName }}/cmd + - GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags="-s -w" -o /{{ $.ImageName }} + - chmod +x /{{ $.ImageName }} --- image: {{ $.ImageName }}-distroless-artifact @@ -70,10 +77,10 @@ fromImage: {{ $.ImageName }}-distroless import: - image: {{ $.ImageName }}-golang-artifact - add: /webhooks - to: /webhooks + add: /{{ $.ImageName }} + to: /{{ $.ImageName }} before: setup docker: - ENTRYPOINT: ["/webhooks"] + ENTRYPOINT: ["/{{ $.ImageName }}"] USER: deckhouse:deckhouse diff --git a/templates/webhooks/secret.yaml b/templates/webhooks/secret.yaml index b25f5cf2..b5a122fe 100644 --- a/templates/webhooks/secret.yaml +++ b/templates/webhooks/secret.yaml @@ -7,6 +7,6 @@ metadata: {{- include "helm_lib_module_labels" (list . (dict "app" "webhooks")) | nindent 2 }} type: kubernetes.io/tls data: - ca.crt: {{ .Values.csiCeph.internal.customWebhookCert.ca }} - tls.crt: {{ .Values.csiCeph.internal.customWebhookCert.crt }} - tls.key: {{ .Values.csiCeph.internal.customWebhookCert.key }} + ca.crt: {{ .Values.csiCeph.internal.customWebhookCert.ca | b64enc | quote }} + tls.crt: {{ .Values.csiCeph.internal.customWebhookCert.crt | b64enc | quote }} + tls.key: {{ .Values.csiCeph.internal.customWebhookCert.key | b64enc | quote }} diff --git a/templates/webhooks/webhook.yaml b/templates/webhooks/webhook.yaml index 915424f0..177515e6 100644 --- a/templates/webhooks/webhook.yaml +++ b/templates/webhooks/webhook.yaml @@ -16,8 +16,7 @@ webhooks: namespace: "d8-{{ .Chart.Name }}" name: "webhooks" path: "/sc-validate" - caBundle: | - {{ .Values.csiCeph.internal.customWebhookCert.ca }} + caBundle: {{ .Values.csiCeph.internal.customWebhookCert.ca | b64enc | quote }} admissionReviewVersions: ["v1", "v1beta1"] sideEffects: None timeoutSeconds: 5 From 81e1bf0ba076f6e6eec32f5791b795dc4db2afa0 Mon Sep 17 00:00:00 2001 From: "v.oleynikov" Date: Mon, 31 Mar 2025 14:51:21 +0300 Subject: [PATCH 2/6] [internal] switch from python to go hooks and some images refactoring Signed-off-by: v.oleynikov --- .../remove-sc-and-secrets-on-module-delete.go | 107 +++++++++--------- hooks/go/go.mod | 4 +- hooks/go/go.sum | 8 +- 3 files changed, 60 insertions(+), 59 deletions(-) diff --git a/hooks/go/030-remove-sc-and-secrets-on-module-delete/remove-sc-and-secrets-on-module-delete.go b/hooks/go/030-remove-sc-and-secrets-on-module-delete/remove-sc-and-secrets-on-module-delete.go index 4655164a..c4bef1bb 100644 --- a/hooks/go/030-remove-sc-and-secrets-on-module-delete/remove-sc-and-secrets-on-module-delete.go +++ b/hooks/go/030-remove-sc-and-secrets-on-module-delete/remove-sc-and-secrets-on-module-delete.go @@ -2,6 +2,7 @@ package hooks_common import ( "context" + "errors" "fmt" snapv1 "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumesnapshot/v1" @@ -20,6 +21,19 @@ import ( "github.com/deckhouse/sds-common-lib/kubeclient" ) + +func removeFinalizers(ctx context.Context, cl client.Client, obj client.Object, logger pkg.Logger) error { + logger.Info(fmt.Sprintf("[remove-sc-and-secrets-on-module-delete]: Removing finalizers from %s %s\n", obj.GetObjectKind().GroupVersionKind().Kind, obj.GetName())) + + patch := client.MergeFrom(obj.DeepCopyObject().(client.Object)) + obj.SetFinalizers(nil) + + if err := cl.Patch(ctx, obj, patch); err != nil { + return fmt.Errorf("failed to patch %s %s: %w", obj.GetObjectKind().GroupVersionKind().Kind, obj.GetName(), err) + } + return nil +} + var _ = registry.RegisterFunc(configRemoveScAndSecretsOnModuleDelete, handlerRemoveScAndSecretsOnModuleDelete) var configRemoveScAndSecretsOnModuleDelete = &pkg.HookConfig{ @@ -28,7 +42,9 @@ var configRemoveScAndSecretsOnModuleDelete = &pkg.HookConfig{ func handlerRemoveScAndSecretsOnModuleDelete(ctx context.Context, input *pkg.HookInput) error { input.Logger.Info("[remove-sc-and-secrets-on-module-delete]: Started removing SC and Secrets on module delete") - cl, err := kubeclient.NewKubeClient("", + var resultErr error + + cl, err := kubeclient.New("", v1alpha1.AddToScheme, clientgoscheme.AddToScheme, extv1.AddToScheme, @@ -36,81 +52,66 @@ func handlerRemoveScAndSecretsOnModuleDelete(ctx context.Context, input *pkg.Hoo sv1.AddToScheme, snapv1.AddToScheme) if err != nil { - input.Logger.Error(fmt.Sprintf("Failed to initialize kube client: %v", err)) - return err + return fmt.Errorf("failed to initialize kube client: %w", err) } secretList := &corev1.SecretList{} - err = cl.List(ctx, secretList, client.InNamespace(consts.ModuleNamespace)) - if err != nil { - input.Logger.Error(fmt.Sprintf("[remove-sc-and-secrets-on-module-delete]: Failed to list secrets: %v", err)) - return err + if err := cl.List(ctx, secretList, client.InNamespace(consts.ModuleNamespace)); err != nil { + resultErr = errors.Join(resultErr, fmt.Errorf("[remove-sc-and-secrets-on-module-delete]: failed to list secrets: %w", err)) + return resultErr } for _, secret := range secretList.Items { input.Logger.Info(fmt.Sprintf("[remove-sc-and-secrets-on-module-delete]: Removing finalizers from %s secret\n", secret.Name)) - patch := client.MergeFrom(secret.DeepCopy()) - secret.ObjectMeta.Finalizers = nil - - err = cl.Patch(ctx, &secret, patch) - if err != nil { - input.Logger.Error(fmt.Sprintf("[remove-sc-and-secrets-on-module-delete]: Failed to patch secret %s: %v", secret.Name, err)) - return err + if err := removeFinalizers(ctx, cl, &secret, input.Logger); err != nil { + resultErr = errors.Join(resultErr, fmt.Errorf("[remove-sc-and-secrets-on-module-delete]: failed to patch secret %s: %w", secret.Name, err)) + continue } } configMapList := &corev1.ConfigMapList{} - err = cl.List(ctx, configMapList, client.InNamespace(consts.ModuleNamespace)) - if err != nil { - input.Logger.Error(fmt.Sprintf("[remove-sc-and-secrets-on-module-delete]: Failed to list configmaps: %v", err)) - return err + if err := cl.List(ctx, configMapList, client.InNamespace(consts.ModuleNamespace)); err != nil { + return errors.Join(resultErr, fmt.Errorf("[remove-sc-and-secrets-on-module-delete]: failed to list configmaps: %w", err)) } + for _, configMap := range configMapList.Items { input.Logger.Info(fmt.Sprintf("[remove-sc-and-secrets-on-module-delete]: Removing finalizers from %s configmap\n", configMap.Name)) - patch := client.MergeFrom(configMap.DeepCopy()) - configMap.ObjectMeta.Finalizers = nil - - err = cl.Patch(ctx, &configMap, patch) - if err != nil { - input.Logger.Error(fmt.Sprintf("[remove-sc-and-secrets-on-module-delete]: Failed to patch configmap %s: %v", configMap.Name, err)) - return err + if err := removeFinalizers(ctx, cl, &configMap, input.Logger); err != nil { + resultErr = errors.Join(resultErr, fmt.Errorf("[remove-sc-and-secrets-on-module-delete]: Failed to patch configmap %s: %w", configMap.Name, err)) + continue } } - scList := &storagev1.StorageClassList{} - err = cl.List(ctx, scList) - if err != nil { - input.Logger.Error(fmt.Sprintf("[remove-sc-and-secrets-on-module-delete]: Failed to list storage classes: %v", err)) - return err - } + for _, provisioner := range consts.AllowedProvisioners { + scList := &storagev1.StorageClassList{} + if err := cl.List(ctx, scList); err != nil { + resultErr = errors.Join(resultErr, fmt.Errorf("[remove-sc-and-secrets-on-module-delete]: Failed to list storage classes: %w", err)) + return resultErr + } - for _, sc := range scList.Items { - for _, provisioner := range consts.AllowedProvisioners { - if sc.Provisioner == provisioner { - input.Logger.Info(fmt.Sprintf("[remove-sc-and-secrets-on-module-delete]: Removing finalizers from %s storage class\n", sc.Name)) - - patch := client.MergeFrom(sc.DeepCopy()) - sc.ObjectMeta.Finalizers = nil - - err = cl.Patch(ctx, &sc, patch) - if err != nil { - input.Logger.Error(fmt.Sprintf("[remove-sc-and-secrets-on-module-delete]: Failed to patch storage class %s: %v", sc.Name, err)) - return err - } - - input.Logger.Info(fmt.Sprintf("[remove-sc-and-secrets-on-module-delete]: Removing %s storage class\n", sc.Name)) - err = cl.Delete(ctx, &sc) - if err != nil { - input.Logger.Error(fmt.Sprintf("[remove-sc-and-secrets-on-module-delete]: Failed to delete storage class %s: %v", sc.Name, err)) - return err - } + for _, sc := range scList.Items { + if sc.Provisioner != provisioner { + continue + } + input.Logger.Info(fmt.Sprintf("[remove-sc-and-secrets-on-module-delete]: Removing finalizers from %s storage class\n", sc.Name)) + + if err := removeFinalizers(ctx, cl, &sc, input.Logger); err != nil { + resultErr = errors.Join(resultErr, fmt.Errorf("[remove-sc-and-secrets-on-module-delete]: Failed to patch storage class %s: %w", sc.Name, err)) + continue + } + + input.Logger.Info(fmt.Sprintf("[remove-sc-and-secrets-on-module-delete]: Removing %s storage class\n", sc.Name)) + if err := cl.Delete(ctx, &sc); err != nil { + resultErr = errors.Join(resultErr, fmt.Errorf("[remove-sc-and-secrets-on-module-delete]: Failed to delete storage class %s: %w", sc.Name, err)) + continue } } } - input.Logger.Info("[remove-sc-and-secrets-on-module-delete]: Stoped removing SC and Secrets on module delete\n") + input.Logger.Info("[remove-sc-and-secrets-on-module-delete]: Stoped removing SC, ConfigMaps and Secrets on module delete\n") - return nil + return resultErr } + diff --git a/hooks/go/go.mod b/hooks/go/go.mod index 3b821b2f..a984676c 100644 --- a/hooks/go/go.mod +++ b/hooks/go/go.mod @@ -5,14 +5,14 @@ go 1.23.6 require ( github.com/deckhouse/csi-ceph/api v0.0.0-20250207141553-9b2c9a45ba22 github.com/deckhouse/module-sdk v0.2.0 - github.com/deckhouse/sds-common-lib v0.0.0-20250322050030-9c6b017469ce + github.com/deckhouse/sds-common-lib v0.0.0-20250331104837-4ed70c9f1a83 github.com/google/go-cmp v0.7.0 github.com/kubernetes-csi/external-snapshotter/client/v8 v8.2.0 k8s.io/api v0.32.3 k8s.io/apiextensions-apiserver v0.32.2 k8s.io/apimachinery v0.32.3 k8s.io/client-go v0.32.3 - sigs.k8s.io/controller-runtime v0.20.3 + sigs.k8s.io/controller-runtime v0.20.4 ) require ( diff --git a/hooks/go/go.sum b/hooks/go/go.sum index 73dc08de..c35d2ca8 100644 --- a/hooks/go/go.sum +++ b/hooks/go/go.sum @@ -19,8 +19,8 @@ github.com/deckhouse/deckhouse/pkg/log v0.0.0-20250320042525-77d066cf8f00 h1:KRh github.com/deckhouse/deckhouse/pkg/log v0.0.0-20250320042525-77d066cf8f00/go.mod h1:pbAxTSDcPmwyl3wwKDcEB3qdxHnRxqTV+J0K+sha8bw= github.com/deckhouse/module-sdk v0.2.0 h1:MOK03UZ88T7T52bk+lmAz0bRJiljtN5ysq7y8FjEF3s= github.com/deckhouse/module-sdk v0.2.0/go.mod h1:fbs0X7myE8zrPKxs3eoIoFWf68E7r1tZ64uJfYJCsKc= -github.com/deckhouse/sds-common-lib v0.0.0-20250322050030-9c6b017469ce h1:aXWbHqtY7pE7SiunSYED7XfT0bDPZpOSIEWeHzjufvU= -github.com/deckhouse/sds-common-lib v0.0.0-20250322050030-9c6b017469ce/go.mod h1:HEYiROA+n+p/pljW8k25mp+oS7fij9fIWdKzyeLan9s= +github.com/deckhouse/sds-common-lib v0.0.0-20250331104837-4ed70c9f1a83 h1:TLrWAauXH4AdROgCwpTnTZqSxgAF+NMYpeIm+e9ZaqA= +github.com/deckhouse/sds-common-lib v0.0.0-20250331104837-4ed70c9f1a83/go.mod h1:Ap+s6LamZwRMAuzhMVJkmsvQpI1O4yxgFgsTu7QQ5qI= github.com/docker/cli v28.0.2+incompatible h1:cRPZ77FK3/IXTAIQQj1vmhlxiLS5m+MIUDwS6f57lrE= github.com/docker/cli v28.0.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= @@ -326,8 +326,8 @@ k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUy k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8= k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0= k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/controller-runtime v0.20.3 h1:I6Ln8JfQjHH7JbtCD2HCYHoIzajoRxPNuvhvcDbZgkI= -sigs.k8s.io/controller-runtime v0.20.3/go.mod h1:xg2XB0K5ShQzAgsoujxuKN4LNXR2LfwwHsPj7Iaw+XY= +sigs.k8s.io/controller-runtime v0.20.4 h1:X3c+Odnxz+iPTRobG4tp092+CvBU9UK0t/bRf+n0DGU= +sigs.k8s.io/controller-runtime v0.20.4/go.mod h1:xg2XB0K5ShQzAgsoujxuKN4LNXR2LfwwHsPj7Iaw+XY= sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= From 39fb92dd9866bcc40046ac9ed186e819ebb633fa Mon Sep 17 00:00:00 2001 From: "v.oleynikov" Date: Mon, 31 Mar 2025 15:08:13 +0300 Subject: [PATCH 3/6] [internal] switch from python to go hooks and some images refactoring Signed-off-by: v.oleynikov --- templates/webhooks/deployment.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/templates/webhooks/deployment.yaml b/templates/webhooks/deployment.yaml index d62669db..2f7e961e 100644 --- a/templates/webhooks/deployment.yaml +++ b/templates/webhooks/deployment.yaml @@ -41,6 +41,8 @@ spec: app: webhooks template: metadata: + annotations: + checksum/ca: {{ .Values.csiYadroTatlinUnified.internal.customWebhookCert.ca | sha256sum | quote }} labels: app: webhooks spec: From e2de131e83fe36d4903e64893a94e44fed27a903 Mon Sep 17 00:00:00 2001 From: "v.oleynikov" Date: Mon, 31 Mar 2025 15:08:30 +0300 Subject: [PATCH 4/6] [internal] switch from python to go hooks and some images refactoring Signed-off-by: v.oleynikov --- templates/webhooks/deployment.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/webhooks/deployment.yaml b/templates/webhooks/deployment.yaml index 2f7e961e..74b12405 100644 --- a/templates/webhooks/deployment.yaml +++ b/templates/webhooks/deployment.yaml @@ -42,7 +42,7 @@ spec: template: metadata: annotations: - checksum/ca: {{ .Values.csiYadroTatlinUnified.internal.customWebhookCert.ca | sha256sum | quote }} + checksum/ca: {{ .Values.csiCeph.internal.customWebhookCert.ca | sha256sum | quote }} labels: app: webhooks spec: From c4b16794226dbd0b562f5a288e74c1d7490ad3e3 Mon Sep 17 00:00:00 2001 From: "v.oleynikov" Date: Mon, 31 Mar 2025 15:28:57 +0300 Subject: [PATCH 5/6] Signed-off-by: v.oleynikov --- .golangci.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index f7970cae..68e61f42 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -26,14 +26,12 @@ linters: - gci - gocritic - gofmt - # - goimports - gosimple - govet - ineffassign - misspell - revive - staticcheck - # - structcheck - typecheck - unconvert - unparam From f633a5f805eb2bd5816904b3fbffec7ccf158e33 Mon Sep 17 00:00:00 2001 From: "v.oleynikov" Date: Mon, 31 Mar 2025 15:30:11 +0300 Subject: [PATCH 6/6] [internal] switch from python to go hooks and some images refactoring Signed-off-by: v.oleynikov --- module.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/module.yaml b/module.yaml index 0c1c1df7..d3d2221b 100644 --- a/module.yaml +++ b/module.yaml @@ -1,2 +1,3 @@ +name: csi-ceph weight: 920 description: "CSI Ceph"